From 14e9cf5d6a7677ed64fff616abda81097b94689a Mon Sep 17 00:00:00 2001 From: da3dsoul Date: Tue, 22 Aug 2017 01:23:54 -0400 Subject: [PATCH 01/16] check for relative paths --- Contents/Code/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Contents/Code/__init__.py b/Contents/Code/__init__.py index e526a6c..b55646d 100644 --- a/Contents/Code/__init__.py +++ b/Contents/Code/__init__.py @@ -156,6 +156,9 @@ def Update(self, metadata, media, lang, force, movie): if len(series['art']['thumb']) and Prefs['customThumbs']: for art in series['art']['thumb']: + if ':' in art['url']: + urlparts = urllib.parse.urlparse(art['url']) + art['url'] = art['url'].replace("{scheme}://{host}:{port}/".format(scheme=urlparts.scheme, host=urlparts.hostname, port=urlparts.port), '') episodeObj.thumbs[art['url']] = Proxy.Media(HTTP.Request("http://{host}:{port}{relativeURL}".format(host=Prefs['Hostname'], port=Prefs['Port'], relativeURL=art['url'])).content, art['index']) links = HttpReq("api/links/serie?id=%s" % aid) @@ -174,6 +177,9 @@ def metadata_add(self, meta, images): valid = list() for art in images: + if ':' in art['url']: + urlparts = urllib.parse.urlparse(art['url']) + art['url'] = art['url'].replace("{scheme}://{host}:{port}/".format(scheme=urlparts.scheme, host=urlparts.hostname, port=urlparts.port), '') Log("[metadata_add] :: Adding metadata %s (index %d)" % (art['url'], art['index'])) meta[art['url']] = Proxy.Media(HTTP.Request("http://{host}:{port}{relativeURL}".format(host=Prefs['Hostname'], port=Prefs['Port'], relativeURL=art['url'])).content, art['index']) valid.append(art['url']) From 264bd53150e658cb685ae4477a0140f977cb3013 Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Sun, 8 Oct 2017 01:54:47 +1100 Subject: [PATCH 02/16] Update so air dates work properly --- Contents/Code/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Contents/Code/__init__.py b/Contents/Code/__init__.py index b55646d..2d76559 100644 --- a/Contents/Code/__init__.py +++ b/Contents/Code/__init__.py @@ -135,6 +135,8 @@ def Update(self, metadata, media, lang, force, movie): Log('Assumed tv rating to be: %s' % metadata.content_rating) + if series['air'] != '1/01/0001 12:00:00 AM' and series['air'] != '0001-01-01': + metadata.originally_available_at = datetime.strptime(series['air'], "%Y-%m-%d").date() if not movie: for ep in series['eps']: @@ -152,7 +154,7 @@ def Update(self, metadata, media, lang, force, movie): episodeObj.summary = ep['summary'] if ep['air'] != '1/01/0001 12:00:00 AM' and ep['air'] != '0001-01-01': - episodeObj.originally_available_at = datetime.strptime(ep['air'], "%d/%m/%Y %H:%M:%S %p").date() + episodeObj.originally_available_at = datetime.strptime(ep['air'], "%Y-%m-%d").date() if len(series['art']['thumb']) and Prefs['customThumbs']: for art in series['art']['thumb']: From 61f54f9ce03bbca3c7cfbe25d049e4b4f5c0d9c6 Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Mon, 9 Oct 2017 22:34:49 +1100 Subject: [PATCH 03/16] Make the code re-try on 401 --- Contents/Code/__init__.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Contents/Code/__init__.py b/Contents/Code/__init__.py index 2d76559..ee83e4f 100644 --- a/Contents/Code/__init__.py +++ b/Contents/Code/__init__.py @@ -55,8 +55,14 @@ def HttpReq(url, authenticate=True): if authenticate: api_string = '&apikey=%s' % GetApiKey() - return JSON.ObjectFromString( - HTTP.Request('http://%s:%s/%s%s' % (Prefs['Hostname'], Prefs['Port'], url, api_string)).content) + try: + return JSON.ObjectFromString( + HTTP.Request('http://%s:%s/%s%s' % (Prefs['Hostname'], Prefs['Port'], url, api_string)).content) + except urllib.error.HTTPError, e: + if e.code == 401: + API_KEY = '' + return HttpReq(url, authenticate) + raise e class ShokoCommonAgent: From 1c1ba7b6813e14b1808862d0aa033524c2fc7b87 Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Mon, 16 Oct 2017 12:45:54 +1100 Subject: [PATCH 04/16] Fix intermittent loss of auth --- Contents/Code/__init__.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Contents/Code/__init__.py b/Contents/Code/__init__.py index ee83e4f..ab106d4 100644 --- a/Contents/Code/__init__.py +++ b/Contents/Code/__init__.py @@ -6,6 +6,7 @@ import threading import urllib import copy +from urllib2 import HTTPError from datetime import datetime from lxml import etree import tags as TagBlacklist @@ -49,7 +50,7 @@ def HttpPost(url, postdata): data=postdata).content) -def HttpReq(url, authenticate=True): +def HttpReq(url, authenticate=True, retry=True): Log("Requesting: %s" % url) api_string = '' if authenticate: @@ -58,11 +59,13 @@ def HttpReq(url, authenticate=True): try: return JSON.ObjectFromString( HTTP.Request('http://%s:%s/%s%s' % (Prefs['Hostname'], Prefs['Port'], url, api_string)).content) - except urllib.error.HTTPError, e: - if e.code == 401: - API_KEY = '' - return HttpReq(url, authenticate) - raise e + except HTTPError, e: + if not retry: + raise e + + API_KEY = '' + return HttpReq(url, authenticate, False) + class ShokoCommonAgent: From 8fade71286177808330adc1686d343a58bdd175f Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Mon, 16 Oct 2017 12:47:14 +1100 Subject: [PATCH 05/16] Fix up episode numbers in special seasons --- Contents/Resources/Series/Shoko Series Scanner.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Contents/Resources/Series/Shoko Series Scanner.py b/Contents/Resources/Series/Shoko Series Scanner.py index e56bf95..d40ebd3 100644 --- a/Contents/Resources/Series/Shoko Series Scanner.py +++ b/Contents/Resources/Series/Shoko Series Scanner.py @@ -120,11 +120,7 @@ def Scan(path, files, mediaList, subdirs, language=None, root=None): Log.info('season number: %s', seasonNumber) - episodeNumber = int(episode_data['epnumber']) - if episode_data['eptype'] != 'Episode': - episodeNumber = str("%s%d" % (episode_data['eptype'][0], episode_data['epnumber'])) - Log.info('episode number: %s', episodeNumber) vid = Media.Episode(showTitle, int(seasonNumber), episodeNumber) From 284262127bf501465c761f184299fa948d874776 Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Fri, 20 Oct 2017 13:16:23 +1100 Subject: [PATCH 06/16] Hacks around when api fucks up --- Contents/Code/__init__.py | 3 ++- Contents/Resources/Series/Shoko Series Scanner.py | 14 +++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Contents/Code/__init__.py b/Contents/Code/__init__.py index ab106d4..03eb368 100644 --- a/Contents/Code/__init__.py +++ b/Contents/Code/__init__.py @@ -51,6 +51,7 @@ def HttpPost(url, postdata): def HttpReq(url, authenticate=True, retry=True): + global API_KEY Log("Requesting: %s" % url) api_string = '' if authenticate: @@ -59,7 +60,7 @@ def HttpReq(url, authenticate=True, retry=True): try: return JSON.ObjectFromString( HTTP.Request('http://%s:%s/%s%s' % (Prefs['Hostname'], Prefs['Port'], url, api_string)).content) - except HTTPError, e: + except Exception, e: if not retry: raise e diff --git a/Contents/Resources/Series/Shoko Series Scanner.py b/Contents/Resources/Series/Shoko Series Scanner.py index d40ebd3..a16a700 100644 --- a/Contents/Resources/Series/Shoko Series Scanner.py +++ b/Contents/Resources/Series/Shoko Series Scanner.py @@ -58,7 +58,8 @@ def HttpPost(url, postdata): return json.load(urllib2.urlopen(req, postdata)) -def HttpReq(url, authenticate=True): +def HttpReq(url, authenticate=True, retry=True): + global API_KEY Log.info("Requesting: %s", url) api_string = '' if authenticate: @@ -66,8 +67,15 @@ def HttpReq(url, authenticate=True): myheaders = {'Accept': 'application/json'} - req = urllib2.Request('http://%s:%s/%s%s' % (Prefs['Hostname'], Prefs['Port'], url, api_string), headers=myheaders) - return json.load(urllib2.urlopen(req)) + try: + req = urllib2.Request('http://%s:%s/%s%s' % (Prefs['Hostname'], Prefs['Port'], url, api_string), headers=myheaders) + return json.load(urllib2.urlopen(req)) + except Exception, e: + if not retry: + raise e + + API_KEY = '' + return HttpReq(url, authenticate, False) def GetApiKey(): From e583ee4960403ea24a370e2741a9ae6d59b26858 Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Mon, 30 Oct 2017 02:12:48 +1100 Subject: [PATCH 07/16] Add support for movies. --- .gitmodules | 3 - Contents/Code/__init__.py | 37 +++-- Contents/Code/tags | 1 - .../Resources/Movies/Shoko Movie Scanner.py | 143 ++++++++++++++++++ .../Resources/Series/Shoko Series Scanner.py | 7 +- 5 files changed, 172 insertions(+), 19 deletions(-) delete mode 100644 .gitmodules delete mode 160000 Contents/Code/tags create mode 100644 Contents/Resources/Movies/Shoko Movie Scanner.py diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 1c39344..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "tags"] - path = Contents/Code/tags - url = https://github.com/bigretromike/nakamori.tags.git diff --git a/Contents/Code/__init__.py b/Contents/Code/__init__.py index 03eb368..be56681 100644 --- a/Contents/Code/__init__.py +++ b/Contents/Code/__init__.py @@ -9,7 +9,6 @@ from urllib2 import HTTPError from datetime import datetime from lxml import etree -import tags as TagBlacklist API_KEY = '' PLEX_HOST = '' @@ -71,7 +70,7 @@ def HttpReq(url, authenticate=True, retry=True): class ShokoCommonAgent: def Search(self, results, media, lang, manual, movie): - name = media.show + name = ( media.title if movie else media.show ) # http://127.0.0.1:8111/api/serie/search?query=Clannad&level=1&apikey=d422dfd2-bdc3-4219-b3bb-08b85aa65579 @@ -92,16 +91,7 @@ def Update(self, metadata, media, lang, force, movie): # http://127.0.0.1:8111/api/ep/getbyfilename?apikey=d422dfd2-bdc3-4219-b3bb-08b85aa65579&filename=%5Bjoseole99%5D%20Clannad%20-%2001%20(1280x720%20Blu-ray%20H264)%20%5B8E128DF5%5D.mkv # episode_data = HttpReq("api/ep/getbyfilename?apikey=%s&filename=%s" % (GetApiKey(), urllib.quote(media.filename))) - series = HttpReq("api/serie?id=%s&level=3&allpics=1" % aid) - # build metadata on the TV show. - metadata.summary = try_get(series, 'summary') - metadata.title = series['name'] - metadata.rating = float(series['rating']) - - tags = [] - for tag in series['tags']: - tags.append(tag['tag']) flags = 0 flags = flags | Prefs['hideMiscTags'] << 0 #0b00001 : Hide AniDB Internal Tags @@ -110,7 +100,21 @@ def Update(self, metadata, media, lang, force, movie): flags = flags | Prefs['hideUsefulMiscTags'] << 3 #0b01000 : Hide Useful Miscellaneous Tags flags = flags | Prefs['hideSpoilerTags'] << 4 #0b10000 : Hide Plot Spoiler Tags - TagBlacklist.processTags(flags, tags) + + series = HttpReq("api/serie?id=%s&level=3&allpics=1&tagfilter=%d" % (aid, flags)) + + # build metadata on the TV show. + metadata.summary = try_get(series, 'summary') + metadata.title = series['name'] + metadata.rating = float(series['rating']) + year = try_get(series, "year", None) + + if year: + metadata.year = int(year) + + tags = [] + for tag in series['tags']: + tags.append(tag['tag']) metadata.genres = tags @@ -148,6 +152,15 @@ def Update(self, metadata, media, lang, force, movie): if series['air'] != '1/01/0001 12:00:00 AM' and series['air'] != '0001-01-01': metadata.originally_available_at = datetime.strptime(series['air'], "%Y-%m-%d").date() + metadata.roles.clear() + for role in series['roles']: + meta_role = metadata.roles.new() + Log(role['character']) + meta_role.name = role['staff'] + meta_role.role = role['character'] + meta_role.photo = "http://{host}:{port}{relativeURL}".format(host=Prefs['Hostname'], port=Prefs['Port'], relativeURL=role['staff_image']) + + if not movie: for ep in series['eps']: if ep['eptype'] != "Episode": diff --git a/Contents/Code/tags b/Contents/Code/tags deleted file mode 160000 index fdac0c4..0000000 --- a/Contents/Code/tags +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fdac0c4ee1a7c8d0c1de9fcce62c9ef1983f6e70 diff --git a/Contents/Resources/Movies/Shoko Movie Scanner.py b/Contents/Resources/Movies/Shoko Movie Scanner.py new file mode 100644 index 0000000..9dc01c6 --- /dev/null +++ b/Contents/Resources/Movies/Shoko Movie Scanner.py @@ -0,0 +1,143 @@ +import re, os, os.path, json +import Media, VideoFiles, Stack, Utils + +import urllib2, urllib + +Prefs = { + 'Hostname': '127.0.0.1', + 'Port': 8111, + 'Username': 'Default', + 'Password': '', + 'IncludeOther': True +} + +API_KEY = '' + +### Log + LOG_PATH calculated once for all calls ### +import logging, logging.handlers # +RootLogger = logging.getLogger('main') +RootHandler = None +RootFormatting = logging.Formatter('%(message)s') #%(asctime)-15s %(levelname)s - +RootLogger.setLevel(logging.DEBUG) +Log = RootLogger + +FileListLogger = logging.getLogger('FileListLogger') +FileListHandler = None +FileListFormatting = logging.Formatter('%(message)s') +FileListLogger.setLevel(logging.DEBUG) +LogFileList = FileListLogger.info + +def set_logging(instance, filename): + global RootLogger, RootHandler, RootFormatting, FileListLogger, FileListHandler, FileListFormatting + logger, handler, formatting, backup_count = [RootLogger, RootHandler, RootFormatting, 9] if instance=="Root" else [FileListLogger, FileListHandler, FileListFormatting, 1] + if handler: logger.removeHandler(handler) + handler = logging.handlers.RotatingFileHandler(os.path.join(LOG_PATH, filename), maxBytes=10*1024*1024, backupCount=backup_count) #handler = logging.FileHandler(os.path.join(LOG_PATH, filename), mode) + #handler.setFormatter(formatting) + handler.setLevel(logging.DEBUG) + logger.addHandler(handler) + if instance=="Root": RootHandler = handler + else: FileListHandler = handler + +### Check config files on boot up then create library variables ### #platform = xxx if callable(getattr(sys,'platform')) else "" +import inspect +LOG_PATH = os.path.abspath(os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), "..", "..", "Logs")) +if not os.path.isdir(LOG_PATH): + path_location = { 'Windows': '%LOCALAPPDATA%\\Plex Media Server', + 'MacOSX': '$HOME/Library/Application Support/Plex Media Server', + 'Linux': '$PLEX_HOME/Library/Application Support/Plex Media Server' } + try: path = os.path.expandvars(path_location[Platform.OS.lower()] if Platform.OS.lower() in path_location else '~') # Platform.OS: Windows, MacOSX, or Linux + except: pass #os.makedirs(LOG_PATH) # User folder on MacOS-X +LOG_FILE_LIBRARY = LOG_FILE = 'Shoko Metadata Scanner.log' # Log filename library will include the library name, LOG_FILE not and serve as reference +set_logging("Root", LOG_FILE_LIBRARY) + + +def HttpPost(url, postdata): + myheaders = {'Content-Type': 'application/json'} + + req = urllib2.Request('http://%s:%s/%s' % (Prefs['Hostname'], Prefs['Port'], url), headers=myheaders) + return json.load(urllib2.urlopen(req, postdata)) + + +def HttpReq(url, authenticate=True): + Log.info("Requesting: %s", url) + api_string = '' + if authenticate: + api_string = '&apikey=%s' % GetApiKey() + + myheaders = {'Accept': 'application/json'} + + req = urllib2.Request('http://%s:%s/%s%s' % (Prefs['Hostname'], Prefs['Port'], url, api_string), headers=myheaders) + return json.load(urllib2.urlopen(req)) + + +def GetApiKey(): + global API_KEY + + if not API_KEY: + data = '{"user":"%s", "pass":"%s", "device":"%s"}' % ( + Prefs['Username'], Prefs['Password'] if Prefs['Password'] != None else '', 'Shoko Series Scanner For Plex') + resp = HttpPost('api/auth', data)['apikey'] + Log.info( "Got API KEY: %s", resp) + API_KEY = resp + return resp + + return API_KEY + + +def Scan(path, files, mediaList, subdirs, language=None, root=None): + try: + Log.debug('path: %s', path) + Log.debug('files: %s', files) + Log.debug('mediaList: %s', mediaList) + Log.debug('subdirs: %s', subdirs) + Log.debug('language: %s', language) + Log.info('root: %s', root) + + # Scan for video files. + VideoFiles.Scan(path, files, mediaList, subdirs, root) + + for idx, file in enumerate(files): + Log.info('file: %s', file) + # http://127.0.0.1:8111/api/ep/getbyfilename?apikey=d422dfd2-bdc3-4219-b3bb-08b85aa65579&filename=%5Bjoseole99%5D%20Clannad%20-%2001%20(1280x720%20Blu-ray%20H264)%20%5B8E128DF5%5D.mkv + + episode_data = HttpReq("api/ep/getbyfilename?filename=%s" % (urllib.quote(os.path.basename(file)))) + if len(episode_data) == 0: continue + if (try_get(episode_data, "code", 200) == 404): continue + + series_data = HttpReq("api/serie/fromep?id=%d&nocast=1¬ag=1" % episode_data['id']) + if (series_data["ismovie"] == 0) continue + showTitle = series_data['name'].encode("utf-8") #no idea why I need to do this. + Log.info('show title: %s', showTitle) + + seasonNumber = 0 + seasonStr = try_get(episode_data, 'season', None) + if seasonStr == None: + if episode_data['eptype'] == 'Episode': seasonNumber = 1 + if episode_data['eptype'] == 'Credits': seasonNumber = -1 #season -1 for OP/ED + else: + seasonNumber = seasonStr.split('x')[0] + + if seasonNumber <= 0 and Prefs['IncludeOther'] == False: continue #Ignore this by choice. + + + Log.info('season number: %s', seasonNumber) + episodeNumber = int(episode_data['epnumber']) + Log.info('episode number: %s', episodeNumber) + + vid = Media.Episode(showTitle, int(seasonNumber), episodeNumber) + Log.info('vid: %s', vid) + vid.parts.append(file) + mediaList.append(vid) + + Log.info('stack media') + Stack.Scan(path, files, mediaList, subdirs) + Log.debug('media list %s', mediaList) + except Exception as e: + Log.error("Error in Scan: '%s'" % e) + + +def try_get(arr, idx, default=""): + try: + return arr[idx] + except: + return default diff --git a/Contents/Resources/Series/Shoko Series Scanner.py b/Contents/Resources/Series/Shoko Series Scanner.py index a16a700..6c10ae8 100644 --- a/Contents/Resources/Series/Shoko Series Scanner.py +++ b/Contents/Resources/Series/Shoko Series Scanner.py @@ -109,10 +109,11 @@ def Scan(path, files, mediaList, subdirs, language=None, root=None): # http://127.0.0.1:8111/api/ep/getbyfilename?apikey=d422dfd2-bdc3-4219-b3bb-08b85aa65579&filename=%5Bjoseole99%5D%20Clannad%20-%2001%20(1280x720%20Blu-ray%20H264)%20%5B8E128DF5%5D.mkv episode_data = HttpReq("api/ep/getbyfilename?filename=%s" % (urllib.quote(os.path.basename(file)))) - if len(episode_data) == 0: break - if (try_get(episode_data, "code", 200) == 404): break + if len(episode_data) == 0: continue + if (try_get(episode_data, "code", 200) == 404): continue series_data = HttpReq("api/serie/fromep?id=%d&nocast=1¬ag=1" % episode_data['id']) + if (series_data["ismovie"] == 1) continue # Ignore movies in preference for Shoko Movie Scanner showTitle = series_data['name'].encode("utf-8") #no idea why I need to do this. Log.info('show title: %s', showTitle) @@ -124,7 +125,7 @@ def Scan(path, files, mediaList, subdirs, language=None, root=None): else: seasonNumber = seasonStr.split('x')[0] - if seasonNumber <= 0 and Prefs['IncludeOther'] == False: break #Ignore this by choice. + if seasonNumber <= 0 and Prefs['IncludeOther'] == False: continue #Ignore this by choice. Log.info('season number: %s', seasonNumber) From 279098121f82f3bd207cf9b9cd4c82db660423d5 Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Mon, 30 Oct 2017 02:23:21 +1100 Subject: [PATCH 08/16] Missed a spot --- .../Resources/Movies/Shoko Movie Scanner.py | 135 ++++++------------ 1 file changed, 47 insertions(+), 88 deletions(-) diff --git a/Contents/Resources/Movies/Shoko Movie Scanner.py b/Contents/Resources/Movies/Shoko Movie Scanner.py index 9dc01c6..a22853c 100644 --- a/Contents/Resources/Movies/Shoko Movie Scanner.py +++ b/Contents/Resources/Movies/Shoko Movie Scanner.py @@ -13,42 +13,17 @@ API_KEY = '' -### Log + LOG_PATH calculated once for all calls ### -import logging, logging.handlers # -RootLogger = logging.getLogger('main') -RootHandler = None -RootFormatting = logging.Formatter('%(message)s') #%(asctime)-15s %(levelname)s - -RootLogger.setLevel(logging.DEBUG) -Log = RootLogger - -FileListLogger = logging.getLogger('FileListLogger') -FileListHandler = None -FileListFormatting = logging.Formatter('%(message)s') -FileListLogger.setLevel(logging.DEBUG) -LogFileList = FileListLogger.info - -def set_logging(instance, filename): - global RootLogger, RootHandler, RootFormatting, FileListLogger, FileListHandler, FileListFormatting - logger, handler, formatting, backup_count = [RootLogger, RootHandler, RootFormatting, 9] if instance=="Root" else [FileListLogger, FileListHandler, FileListFormatting, 1] - if handler: logger.removeHandler(handler) - handler = logging.handlers.RotatingFileHandler(os.path.join(LOG_PATH, filename), maxBytes=10*1024*1024, backupCount=backup_count) #handler = logging.FileHandler(os.path.join(LOG_PATH, filename), mode) - #handler.setFormatter(formatting) - handler.setLevel(logging.DEBUG) - logger.addHandler(handler) - if instance=="Root": RootHandler = handler - else: FileListHandler = handler - -### Check config files on boot up then create library variables ### #platform = xxx if callable(getattr(sys,'platform')) else "" -import inspect -LOG_PATH = os.path.abspath(os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), "..", "..", "Logs")) -if not os.path.isdir(LOG_PATH): - path_location = { 'Windows': '%LOCALAPPDATA%\\Plex Media Server', - 'MacOSX': '$HOME/Library/Application Support/Plex Media Server', - 'Linux': '$PLEX_HOME/Library/Application Support/Plex Media Server' } - try: path = os.path.expandvars(path_location[Platform.OS.lower()] if Platform.OS.lower() in path_location else '~') # Platform.OS: Windows, MacOSX, or Linux - except: pass #os.makedirs(LOG_PATH) # User folder on MacOS-X -LOG_FILE_LIBRARY = LOG_FILE = 'Shoko Metadata Scanner.log' # Log filename library will include the library name, LOG_FILE not and serve as reference -set_logging("Root", LOG_FILE_LIBRARY) +def log(methodName, message, *args): + ''' + Create a log message given the message and arguments + ''' + logMsg = message + # Replace the arguments in the string + if args: + logMsg = message % args + + logMsg = methodName + ' :: ' + logMsg + print logMsg def HttpPost(url, postdata): @@ -59,7 +34,7 @@ def HttpPost(url, postdata): def HttpReq(url, authenticate=True): - Log.info("Requesting: %s", url) + log('HttpReq' ,"Requesting: %s", url) api_string = '' if authenticate: api_string = '&apikey=%s' % GetApiKey() @@ -77,7 +52,7 @@ def GetApiKey(): data = '{"user":"%s", "pass":"%s", "device":"%s"}' % ( Prefs['Username'], Prefs['Password'] if Prefs['Password'] != None else '', 'Shoko Series Scanner For Plex') resp = HttpPost('api/auth', data)['apikey'] - Log.info( "Got API KEY: %s", resp) + log('GetApiKey', "Got API KEY: %s", resp) API_KEY = resp return resp @@ -85,59 +60,43 @@ def GetApiKey(): def Scan(path, files, mediaList, subdirs, language=None, root=None): - try: - Log.debug('path: %s', path) - Log.debug('files: %s', files) - Log.debug('mediaList: %s', mediaList) - Log.debug('subdirs: %s', subdirs) - Log.debug('language: %s', language) - Log.info('root: %s', root) - - # Scan for video files. - VideoFiles.Scan(path, files, mediaList, subdirs, root) - - for idx, file in enumerate(files): - Log.info('file: %s', file) - # http://127.0.0.1:8111/api/ep/getbyfilename?apikey=d422dfd2-bdc3-4219-b3bb-08b85aa65579&filename=%5Bjoseole99%5D%20Clannad%20-%2001%20(1280x720%20Blu-ray%20H264)%20%5B8E128DF5%5D.mkv - - episode_data = HttpReq("api/ep/getbyfilename?filename=%s" % (urllib.quote(os.path.basename(file)))) - if len(episode_data) == 0: continue - if (try_get(episode_data, "code", 200) == 404): continue - - series_data = HttpReq("api/serie/fromep?id=%d&nocast=1¬ag=1" % episode_data['id']) - if (series_data["ismovie"] == 0) continue - showTitle = series_data['name'].encode("utf-8") #no idea why I need to do this. - Log.info('show title: %s', showTitle) - - seasonNumber = 0 - seasonStr = try_get(episode_data, 'season', None) - if seasonStr == None: - if episode_data['eptype'] == 'Episode': seasonNumber = 1 - if episode_data['eptype'] == 'Credits': seasonNumber = -1 #season -1 for OP/ED - else: - seasonNumber = seasonStr.split('x')[0] - - if seasonNumber <= 0 and Prefs['IncludeOther'] == False: continue #Ignore this by choice. - - - Log.info('season number: %s', seasonNumber) - episodeNumber = int(episode_data['epnumber']) - Log.info('episode number: %s', episodeNumber) - - vid = Media.Episode(showTitle, int(seasonNumber), episodeNumber) - Log.info('vid: %s', vid) - vid.parts.append(file) - mediaList.append(vid) - - Log.info('stack media') - Stack.Scan(path, files, mediaList, subdirs) - Log.debug('media list %s', mediaList) - except Exception as e: - Log.error("Error in Scan: '%s'" % e) + log('Scan', 'path: %s', path) + log('Scan', 'files: %s', files) + log('Scan', 'mediaList: %s', mediaList) + log('Scan', 'subdirs: %s', subdirs) + log('Scan', 'language: %s', language) + log('Scan', 'root: %s', root) + + # Scan for video files. + VideoFiles.Scan(path, files, mediaList, subdirs, root) + + for idx, file in enumerate(files): + log('Scan', 'file: %s', file) + # http://127.0.0.1:8111/api/ep/getbyfilename?apikey=d422dfd2-bdc3-4219-b3bb-08b85aa65579&filename=%5Bjoseole99%5D%20Clannad%20-%2001%20(1280x720%20Blu-ray%20H264)%20%5B8E128DF5%5D.mkv + + episode_data = HttpReq("api/ep/getbyfilename?filename=%s" % (urllib.quote(os.path.basename(file)))) + if len(episode_data) == 0: continue + if (try_get(episode_data, "code", 200) == 404): continue + + series_data = HttpReq("api/serie/fromep?id=%d&nocast=1¬ag=1" % episode_data['id']) + showTitle = series_data['name'].encode("utf-8") #no idea why I need to do this. + log('Scan', 'show title: %s', showTitle) + + seasonYear = episode_data['year'] + log('Scan', 'season year: %s', seasonYear) + + vid = Media.Movie(showTitle, int(seasonYear)) + log('Scan', 'vid: %s', vid) + vid.parts.append(file) + mediaList.append(vid) + + log('Scan', 'stack media') + Stack.Scan(path, files, mediaList, subdirs) + log('Scan', 'media list %s', mediaList) def try_get(arr, idx, default=""): try: return arr[idx] except: - return default + return default \ No newline at end of file From 63810b83c28d9fedd74ecd160c7d72d2d5745a05 Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Mon, 30 Oct 2017 02:32:17 +1100 Subject: [PATCH 09/16] It'd help if I didn't delete that line. --- Contents/Resources/Movies/Shoko Movie Scanner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Contents/Resources/Movies/Shoko Movie Scanner.py b/Contents/Resources/Movies/Shoko Movie Scanner.py index a22853c..0c7db2f 100644 --- a/Contents/Resources/Movies/Shoko Movie Scanner.py +++ b/Contents/Resources/Movies/Shoko Movie Scanner.py @@ -79,6 +79,7 @@ def Scan(path, files, mediaList, subdirs, language=None, root=None): if (try_get(episode_data, "code", 200) == 404): continue series_data = HttpReq("api/serie/fromep?id=%d&nocast=1¬ag=1" % episode_data['id']) + if (series_data["ismovie"] == 1) continue showTitle = series_data['name'].encode("utf-8") #no idea why I need to do this. log('Scan', 'show title: %s', showTitle) From d4e7871233c1c107f816836440db8c3909297267 Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Mon, 30 Oct 2017 02:35:27 +1100 Subject: [PATCH 10/16] Eventually I'll like this language enough to not have these trivial typos in it. --- Contents/Resources/Movies/Shoko Movie Scanner.py | 3 ++- Contents/Resources/Series/Shoko Series Scanner.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Contents/Resources/Movies/Shoko Movie Scanner.py b/Contents/Resources/Movies/Shoko Movie Scanner.py index 0c7db2f..118e356 100644 --- a/Contents/Resources/Movies/Shoko Movie Scanner.py +++ b/Contents/Resources/Movies/Shoko Movie Scanner.py @@ -79,7 +79,8 @@ def Scan(path, files, mediaList, subdirs, language=None, root=None): if (try_get(episode_data, "code", 200) == 404): continue series_data = HttpReq("api/serie/fromep?id=%d&nocast=1¬ag=1" % episode_data['id']) - if (series_data["ismovie"] == 1) continue + if (series_data["ismovie"] == 1): + continue showTitle = series_data['name'].encode("utf-8") #no idea why I need to do this. log('Scan', 'show title: %s', showTitle) diff --git a/Contents/Resources/Series/Shoko Series Scanner.py b/Contents/Resources/Series/Shoko Series Scanner.py index 6c10ae8..81b5d95 100644 --- a/Contents/Resources/Series/Shoko Series Scanner.py +++ b/Contents/Resources/Series/Shoko Series Scanner.py @@ -113,7 +113,8 @@ def Scan(path, files, mediaList, subdirs, language=None, root=None): if (try_get(episode_data, "code", 200) == 404): continue series_data = HttpReq("api/serie/fromep?id=%d&nocast=1¬ag=1" % episode_data['id']) - if (series_data["ismovie"] == 1) continue # Ignore movies in preference for Shoko Movie Scanner + if (series_data["ismovie"] == 1): + continue # Ignore movies in preference for Shoko Movie Scanner showTitle = series_data['name'].encode("utf-8") #no idea why I need to do this. Log.info('show title: %s', showTitle) From b05ceaeb16479e621e59e8fae353260478edb51e Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Mon, 30 Oct 2017 02:38:21 +1100 Subject: [PATCH 11/16] yea no --- Contents/Resources/Movies/Shoko Movie Scanner.py | 10 +++++----- Contents/Resources/Series/Shoko Series Scanner.py | 9 ++++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Contents/Resources/Movies/Shoko Movie Scanner.py b/Contents/Resources/Movies/Shoko Movie Scanner.py index 118e356..c83b274 100644 --- a/Contents/Resources/Movies/Shoko Movie Scanner.py +++ b/Contents/Resources/Movies/Shoko Movie Scanner.py @@ -4,7 +4,7 @@ import urllib2, urllib Prefs = { - 'Hostname': '127.0.0.1', + 'Hostname': '192.168.1.3', 'Port': 8111, 'Username': 'Default', 'Password': '', @@ -75,12 +75,12 @@ def Scan(path, files, mediaList, subdirs, language=None, root=None): # http://127.0.0.1:8111/api/ep/getbyfilename?apikey=d422dfd2-bdc3-4219-b3bb-08b85aa65579&filename=%5Bjoseole99%5D%20Clannad%20-%2001%20(1280x720%20Blu-ray%20H264)%20%5B8E128DF5%5D.mkv episode_data = HttpReq("api/ep/getbyfilename?filename=%s" % (urllib.quote(os.path.basename(file)))) - if len(episode_data) == 0: continue - if (try_get(episode_data, "code", 200) == 404): continue + if len(episode_data) == 0: break + if (try_get(episode_data, "code", 200) == 404): break series_data = HttpReq("api/serie/fromep?id=%d&nocast=1¬ag=1" % episode_data['id']) - if (series_data["ismovie"] == 1): - continue + if (series_data["ismovie"] == 0): + continue showTitle = series_data['name'].encode("utf-8") #no idea why I need to do this. log('Scan', 'show title: %s', showTitle) diff --git a/Contents/Resources/Series/Shoko Series Scanner.py b/Contents/Resources/Series/Shoko Series Scanner.py index 81b5d95..ea1bc13 100644 --- a/Contents/Resources/Series/Shoko Series Scanner.py +++ b/Contents/Resources/Series/Shoko Series Scanner.py @@ -109,12 +109,11 @@ def Scan(path, files, mediaList, subdirs, language=None, root=None): # http://127.0.0.1:8111/api/ep/getbyfilename?apikey=d422dfd2-bdc3-4219-b3bb-08b85aa65579&filename=%5Bjoseole99%5D%20Clannad%20-%2001%20(1280x720%20Blu-ray%20H264)%20%5B8E128DF5%5D.mkv episode_data = HttpReq("api/ep/getbyfilename?filename=%s" % (urllib.quote(os.path.basename(file)))) - if len(episode_data) == 0: continue - if (try_get(episode_data, "code", 200) == 404): continue + if len(episode_data) == 0: break + if (try_get(episode_data, "code", 200) == 404): break series_data = HttpReq("api/serie/fromep?id=%d&nocast=1¬ag=1" % episode_data['id']) - if (series_data["ismovie"] == 1): - continue # Ignore movies in preference for Shoko Movie Scanner + if (series_data["ismovie"] == 1) break # Ignore movies in preference for Shoko Movie Scanner showTitle = series_data['name'].encode("utf-8") #no idea why I need to do this. Log.info('show title: %s', showTitle) @@ -126,7 +125,7 @@ def Scan(path, files, mediaList, subdirs, language=None, root=None): else: seasonNumber = seasonStr.split('x')[0] - if seasonNumber <= 0 and Prefs['IncludeOther'] == False: continue #Ignore this by choice. + if seasonNumber <= 0 and Prefs['IncludeOther'] == False: break #Ignore this by choice. Log.info('season number: %s', seasonNumber) From c6fd3b9ce3aee2a940cc0431e7a122fa32d926d8 Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Mon, 30 Oct 2017 02:38:53 +1100 Subject: [PATCH 12/16] Fix. --- Contents/Resources/Movies/Shoko Movie Scanner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Contents/Resources/Movies/Shoko Movie Scanner.py b/Contents/Resources/Movies/Shoko Movie Scanner.py index c83b274..70f683f 100644 --- a/Contents/Resources/Movies/Shoko Movie Scanner.py +++ b/Contents/Resources/Movies/Shoko Movie Scanner.py @@ -4,7 +4,7 @@ import urllib2, urllib Prefs = { - 'Hostname': '192.168.1.3', + 'Hostname': '127.0.0.1', 'Port': 8111, 'Username': 'Default', 'Password': '', From 190050a7100c4f255e9b5c63f06b32cecf08eff9 Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Wed, 1 Nov 2017 01:55:47 +1100 Subject: [PATCH 13/16] Did I mention 2 am coding? This one took a few days to find. --- Contents/Resources/Series/Shoko Series Scanner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Contents/Resources/Series/Shoko Series Scanner.py b/Contents/Resources/Series/Shoko Series Scanner.py index ea1bc13..06231a3 100644 --- a/Contents/Resources/Series/Shoko Series Scanner.py +++ b/Contents/Resources/Series/Shoko Series Scanner.py @@ -82,7 +82,7 @@ def GetApiKey(): global API_KEY if not API_KEY: - data = '{"user":"%s", "pass":"%s", "device":"%s"}' % ( + data = '{"user":"%s", "pass":"%s", "device":"%s"}' % ( Prefs['Username'], Prefs['Password'] if Prefs['Password'] != None else '', 'Shoko Series Scanner For Plex') resp = HttpPost('api/auth', data)['apikey'] Log.info( "Got API KEY: %s", resp) @@ -113,7 +113,7 @@ def Scan(path, files, mediaList, subdirs, language=None, root=None): if (try_get(episode_data, "code", 200) == 404): break series_data = HttpReq("api/serie/fromep?id=%d&nocast=1¬ag=1" % episode_data['id']) - if (series_data["ismovie"] == 1) break # Ignore movies in preference for Shoko Movie Scanner + if (series_data["ismovie"] == 1): break # Ignore movies in preference for Shoko Movie Scanner showTitle = series_data['name'].encode("utf-8") #no idea why I need to do this. Log.info('show title: %s', showTitle) From 5f50fdddf372a0b11f7758b78d1af7584b7159cd Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Thu, 2 Nov 2017 02:07:24 +1100 Subject: [PATCH 14/16] Update Shoko Series Scanner.py --- Contents/Resources/Series/Shoko Series Scanner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Contents/Resources/Series/Shoko Series Scanner.py b/Contents/Resources/Series/Shoko Series Scanner.py index 06231a3..076a376 100644 --- a/Contents/Resources/Series/Shoko Series Scanner.py +++ b/Contents/Resources/Series/Shoko Series Scanner.py @@ -82,7 +82,7 @@ def GetApiKey(): global API_KEY if not API_KEY: - data = '{"user":"%s", "pass":"%s", "device":"%s"}' % ( + data = '{"user":"%s", "pass":"%s", "device":"%s"}' % ( Prefs['Username'], Prefs['Password'] if Prefs['Password'] != None else '', 'Shoko Series Scanner For Plex') resp = HttpPost('api/auth', data)['apikey'] Log.info( "Got API KEY: %s", resp) From 0a999d1c25437d9ad2e20ef37bed2982a079e41d Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Fri, 3 Nov 2017 19:50:24 +1100 Subject: [PATCH 15/16] Remove erroring code --- Contents/Code/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Contents/Code/__init__.py b/Contents/Code/__init__.py index be56681..c2e7bf0 100644 --- a/Contents/Code/__init__.py +++ b/Contents/Code/__init__.py @@ -109,8 +109,8 @@ def Update(self, metadata, media, lang, force, movie): metadata.rating = float(series['rating']) year = try_get(series, "year", None) - if year: - metadata.year = int(year) + #if year: + # metadata.year = int(year) tags = [] for tag in series['tags']: From 9382f16f7c15471b397c089cfc49c71ee3e19a71 Mon Sep 17 00:00:00 2001 From: Cayde Dixon Date: Wed, 8 Nov 2017 20:28:59 +1100 Subject: [PATCH 16/16] Fix tags on latest daily --- Contents/Code/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Contents/Code/__init__.py b/Contents/Code/__init__.py index c2e7bf0..4ac5505 100644 --- a/Contents/Code/__init__.py +++ b/Contents/Code/__init__.py @@ -114,7 +114,7 @@ def Update(self, metadata, media, lang, force, movie): tags = [] for tag in series['tags']: - tags.append(tag['tag']) + tags.append(tag) metadata.genres = tags