Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
croneter committed Mar 11, 2016
2 parents e439e79 + 21e95fa commit a360663
Show file tree
Hide file tree
Showing 10 changed files with 495 additions and 86 deletions.
2 changes: 1 addition & 1 deletion addon.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.plexkodiconnect"
name="PlexKodiConnect"
version="1.0.7"
version="1.0.8"
provider-name="croneter">
<requires>
<import addon="xbmc.python" version="2.1.0"/>
Expand Down
5 changes: 5 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
version 1.0.8
- Redesigned fast incremential sync
- Workaround to sync Kodi time with PMS time
- Fix library sync key error

version 1.0.7
- Fix userclient
- Fix KeyError in library sync
Expand Down
42 changes: 6 additions & 36 deletions resources/lib/PlexAPI.py
Original file line number Diff line number Diff line change
Expand Up @@ -1476,36 +1476,6 @@ def getPartNumber(self):
"""
return self.part

def DateToKodi(self, stamp):
"""
converts a Unix time stamp (seconds passed sinceJanuary 1 1970) to a
propper, human-readable time stamp used by Kodi
Output: Y-m-d h:m:s = 2009-04-05 23:16:04
"""
# DATEFORMAT = xbmc.getRegion('dateshort')
# TIMEFORMAT = xbmc.getRegion('meridiem')
# date_time = time.localtime(stamp)
# if DATEFORMAT[1] == 'd':
# localdate = time.strftime('%d-%m-%Y', date_time)
# elif DATEFORMAT[1] == 'm':
# localdate = time.strftime('%m-%d-%Y', date_time)
# else:
# localdate = time.strftime('%Y-%m-%d', date_time)
# if TIMEFORMAT != '/':
# localtime = time.strftime('%I:%M%p', date_time)
# else:
# localtime = time.strftime('%H:%M', date_time)
# return localtime + ' ' + localdate
try:
# DATEFORMAT = xbmc.getRegion('dateshort')
# TIMEFORMAT = xbmc.getRegion('meridiem')
date_time = time.localtime(float(stamp))
localdate = time.strftime('%Y-%m-%d %H:%M:%S', date_time)
except:
localdate = None
return localdate

def getType(self):
"""
Returns the type of media, e.g. 'movie' or 'clip' for trailers
Expand Down Expand Up @@ -1543,7 +1513,7 @@ def getDateCreated(self):
"""
Returns the date when this library item was created
"""
return self.DateToKodi(self.item.attrib.get('addedAt', None))
return utils.DateToKodi(self.item.attrib.get('addedAt', None))

def getUserData(self):
"""
Expand Down Expand Up @@ -1576,7 +1546,7 @@ def getUserData(self):
played = True

try:
lastPlayedDate = self.DateToKodi(int(item['lastViewedAt']))
lastPlayedDate = utils.DateToKodi(int(item['lastViewedAt']))
except:
lastPlayedDate = None

Expand Down Expand Up @@ -1851,10 +1821,10 @@ def getEpisodeDetails(self):
]
"""
item = self.item.attrib
key = item['grandparentRatingKey']
title = item['grandparentTitle']
season = item['parentIndex']
episode = item['index']
key = item.get('grandparentRatingKey')
title = item.get('grandparentTitle')
season = item.get('parentIndex')
episode = item.get('index')
return key, title, season, episode

def addPlexHeadersToUrl(self, url, arguments={}):
Expand Down
20 changes: 20 additions & 0 deletions resources/lib/PlexFunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from ast import literal_eval
from urlparse import urlparse, parse_qs
import re
import time

from xbmcaddon import Addon

Expand Down Expand Up @@ -371,3 +372,22 @@ def PMSHttpsEnabled(url):
# couldn't get an xml - switch to http traffic
logMsg('PMSHttpsEnabled', 'PMS on %s talks HTTPS' % url, 1)
return False


def scrobble(ratingKey, state):
"""
Tells the PMS to set an item's watched state to state="watched" or
state="unwatched"
"""
args = {
'key': ratingKey,
'identifier': 'com.plexapp.plugins.library'
}
if state == "watched":
url = "{server}/:/scrobble?" + urlencode(args)
elif state == "unwatched":
url = "{server}/:/unscrobble?" + urlencode(args)
else:
return
downloadutils.DownloadUtils().downloadUrl(url, type="GET")
logMsg("Toggled watched state for Plex item %s" % ratingKey, 1)
33 changes: 33 additions & 0 deletions resources/lib/embydb_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,22 @@ def removeView(self, viewid):
))
self.embycursor.execute(query, (viewid,))

def getItem_byFileId(self, fileId):
"""
Returns the Plex itemId by using the Kodi fileId
"""
query = ' '.join((
"SELECT emby_id",
"FROM emby",
"WHERE kodi_fileid = ?"
))
try:
self.embycursor.execute(query, (fileId,))
item = self.embycursor.fetchone()[0]
return item
except:
return None

def getItem_byId(self, embyid):

embycursor = self.embycursor
Expand Down Expand Up @@ -183,6 +199,23 @@ def getItem_byView(self, mediafolderid):

return items

def getPlexId(self, kodiid):
"""
Returns the Plex ID usind the Kodiid. Result:
(Plex Id, Parent's Plex Id)
"""
query = ' '.join((
"SELECT emby_id, parent_id",
"FROM emby",
"WHERE kodi_id = ?"
))
try:
self.embycursor.execute(query, (kodiid))
item = self.embycursor.fetchone()
return item
except:
return None

def getItem_byKodiId(self, kodiid, mediatype):

embycursor = self.embycursor
Expand Down
17 changes: 10 additions & 7 deletions resources/lib/itemtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,12 @@ def contentPop(self, name, time=5000):
time=time,
sound=False)

def updateUserdata(self, xml):
def updateUserdata(self, xml, viewtag=None, viewid=None):
"""
Updates the Kodi watched state of the item from PMS. Also retrieves
Plex resume points for movies in progress.
viewtag and viewid only serve as dummies
"""
for mediaitem in xml:
API = PlexAPI.API(mediaitem)
Expand Down Expand Up @@ -1256,12 +1258,13 @@ def run_add_updateEpisode(self, item, viewtag=None, viewid=None):
seriesId, seriesName, season, episode = API.getEpisodeDetails()

if season is None:
if item.get('AbsoluteEpisodeNumber'):
# Anime scenario
season = 1
episode = item['AbsoluteEpisodeNumber']
else:
season = -1
season = -1
# if item.get('AbsoluteEpisodeNumber'):
# # Anime scenario
# season = 1
# episode = item['AbsoluteEpisodeNumber']
# else:
# season = -1

# Specials ordering within season
if item.get('AirsAfterSeasonNumber'):
Expand Down
64 changes: 63 additions & 1 deletion resources/lib/kodidb_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class GetKodiDB():
do stuff with kodi_db
Parameters:
itemType: itemtype for Kodi DB, e.g. 'video'
itemType: itemtype for Kodi DB, e.g. 'video', 'music'
On exiting "with" (no matter what), commits get automatically committed
and the db gets closed
Expand Down Expand Up @@ -701,6 +701,68 @@ def addStreams(self, fileid, streamdetails, runtime):
)
cursor.execute(query, (fileid, 2, subtitletrack))

def getResumes(self):
"""
VIDEOS
Returns all Kodi idFile that have a resume point set (not unwatched
ones or items that have already been completely watched)
"""
cursor = self.cursor

query = ' '.join((
"SELECT idFile",
"FROM bookmark"
))
try:
rows = cursor.execute(query)
except:
return []
ids = []
for row in rows:
ids.append(row[0])
return ids

def getUnplayedMusicItems(self):
"""
MUSIC
Returns all Kodi Item idFile that have not yet been completely played
"""
query = ' '.join((
"SELECT idPath",
"FROM song",
"WHERE iTimesPlayed IS NULL OR iTimesPlayed = ''"
))
try:
rows = self.cursor.execute(query)
except:
return []
ids = []
for row in rows:
ids.append(row[0])
return ids

def getUnplayedItems(self):
"""
VIDEOS
Returns all Kodi Item idFile that have not yet been completely played
"""
query = ' '.join((
"SELECT idFile",
"FROM files",
"WHERE playCount IS NULL OR playCount = ''"
))
try:
rows = self.cursor.execute(query)
except:
return []
ids = []
for row in rows:
ids.append(row[0])
return ids

def addPlaystate(self, fileid, resume_seconds, total_seconds, playcount, dateplayed):

cursor = self.cursor
Expand Down
14 changes: 4 additions & 10 deletions resources/lib/kodimonitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
import embydb_functions as embydb
import playbackutils as pbutils
import utils

from urllib import urlencode
from PlexFunctions import scrobble

###############################################################################

Expand Down Expand Up @@ -144,16 +143,11 @@ def onNotification(self, sender, method, data):
utils.window('emby_skipWatched%s' % itemid, clear=True)
else:
# notify the server
args = {'key': itemid,
'identifier': 'com.plexapp.plugins.library'}
if playcount != 0:
url = "{server}/:/scrobble?" + urlencode(args)
doUtils.downloadUrl(url, type="GET")
self.logMsg("Mark as watched for itemid: %s" % itemid, 1)
scrobble(itemid, 'watched')
else:
url = "{server}/:/unscrobble?" + urlencode(args)
doUtils.downloadUrl(url, type="GET")
self.logMsg("Mark as unwatched for itemid: %s" % itemid, 1)
scrobble(itemid, 'unwatched')

finally:
embycursor.close()

Expand Down
Loading

0 comments on commit a360663

Please sign in to comment.