def query(self, searchurl, langs): kodi.log(__name__, "Search URL - %s" % searchurl,kodi.LOGINFO) socket.setdefaulttimeout(10) request = urllib2.Request(searchurl, headers=self.req_headers) request.add_header('Pragma', 'no-cache') page = urllib2.build_opener().open(request) content = page.read() content = content.replace("The safer, easier way", "The safer, easier way \" />") soup = BeautifulSoup(content) for langs_html in soup("td", {"class": "language"}): try: fulllanguage = str(langs_html).split('class="language">')[1].split('<a')[0].replace("\n", "") # noinspection PyBroadException try: lang = self.languagehelper.get_ISO_639_2(srt_lang) except: lang = '' statustd = langs_html.findNext("td") status = statustd.find("b").string.strip() if status == "Completed" and lang != '' and (lang in langs): return SubtitleResult.AVAILABLE except Exception as ex: kodi.log(__name__, "ERROR IN BS: %s" % str(ex)) pass return SubtitleResult.NOT_AVAILABLE
def get_cached_subtitle(self, item): created = 0 now = time.time() limit_found = self.settings.get_cache_found_timeout() limit_not_found = self.settings.get_cache_not_found_timeout() sql = 'SELECT timestamp, subtitle FROM subtitle_cache WHERE year = ? AND season = ? AND episode = ? AND tvshow = ? AND title = ? AND filename = ?' rows = self.__execute(sql, (item['year'], item['season'], item['episode'], item['tvshow'], item['title'], item['filename'])) if rows: created = float(rows[0][0]) subtitle_present = int(rows[0][1]) createddate = time.ctime(created) age = now - created if age < limit_not_found and subtitle_present < 1: kodi.log(__name__, 'DB Cache: Item: %s, Cache Hit: True, created: %s, age: %s hour, limit: False' % (item, createddate, (now - created)/ 3600), kodi.LOGDEBUG) return subtitle_present elif age < limit_found and subtitle_present == 1: kodi.log(__name__, 'DB Cache: Item: %s, Cache Hit: True, created: %s, age: %s days, limit: False' % (item, createddate, (now - created)/ 3600/ 24), kodi.LOGDEBUG) return subtitle_present elif age >= limit_found and subtitle_present == 1: kodi.log(__name__, 'DB Cache: Item: %s, Cache Hit: True, created: %s, age: %s days, limit: True' % (item, createddate, (now - created)/ 3600/ 24), kodi.LOGDEBUG) self.delete_cached_subtitle(item) else: kodi.log(__name__, 'DB Cache: Item: %s, Cache Hit: True, created: %s, age: %s, limit: True' % (item, createddate, (now - created)/ 3600), kodi.LOGDEBUG) self.delete_cached_subtitle(item) else: kodi.log(__name__, 'DB Cache: Item: %s, Cache Hit: False' % (item), kodi.LOGDEBUG) return -1
def searchsubtitles( self, item): try: if len(item['tvshow']) > 1: title = item['tvshow'] else: title = item['title'] langs= [] for lang in item['3let_language']: lan = self.languagehelper.get_podnapisi_code(lang) langs.append(lan) if title: #todo fix language translation, get new list with correct translation url = self.search_url % (title.replace(" ","+"), ','.join(langs), str(item['year']), str(item['season']), str(item['episode']) ) kodi.log( __name__ ,"Search URL - %s" % (url)) subtitles = self.__fetch(url) if subtitles: return SubtitleResult.AVAILABLE return SubtitleResult.NOT_AVAILABLE except: kodi.log(__name__, "failed to connect to Podnapisi service for subtitle search", kodi.LOGNOTICE) return SubtitleResult.NOT_AVAILABLE
def __execute(self, sql, params=None): if params is None: params = [] rows = None sql = self.__format(sql) tries = 1 while True: try: cur = self.db.cursor() # kodi.log(__name__, 'Running: %s with %s' % (sql, params), kodi.LOGDEBUG) cur.execute(sql, params) if sql[:6].upper() == 'SELECT' or sql[:4].upper() == 'SHOW': rows = cur.fetchall() cur.close() self.db.commit() return rows except OperationalError as e: if tries < MAX_TRIES: tries += 1 kodi.log(__name__, 'Retrying (%s/%s) SQL: %s Error: %s' % (tries, MAX_TRIES, sql, e), kodi.LOGWARNING) self.db = None self.__connect_to_db() elif any(s for s in ['no such table', 'no such column'] if s in str(e)): self.db.rollback() raise DatabaseRecoveryError(e) else: raise except DatabaseError as e: self.db.rollback() raise DatabaseRecoveryError(e)
def query(self, searchurl, langs): kodi.log(__name__, "Search URL - %s" % searchurl, kodi.LOGINFO) socket.setdefaulttimeout(10) request = urllib2.Request(searchurl, headers=self.req_headers) request.add_header('Pragma', 'no-cache') page = urllib2.build_opener().open(request) content = page.read() content = content.replace("The safer, easier way", "The safer, easier way \" />") soup = BeautifulSoup(content) for langs_html in soup("td", {"class": "language"}): try: fulllanguage = str(langs_html).split( 'class="language">')[1].split('<a')[0].replace("\n", "") # noinspection PyBroadException try: lang = self.languagehelper.get_ISO_639_2(srt_lang) except: lang = '' statustd = langs_html.findNext("td") status = statustd.find("b").string.strip() if status == "Completed" and lang != '' and (lang in langs): return SubtitleResult.AVAILABLE except Exception as ex: kodi.log(__name__, "ERROR IN BS: %s" % str(ex)) pass return SubtitleResult.NOT_AVAILABLE
def searchsubtitles(self, item): # noinspection PyBroadException try: if item['tvshow']: tvshow_id = self.__get_tvshow_id(item['tvshow']) return self.__get_subtitles(tvshow_id, item['season'], item['episode'], item['3let_language']) else: return SubtitleResult.NOT_AVAILABLE except Exception as e: kodi.log(__name__, 'failed to connect to Addic7ed service for subtitle search (%s)' % e, kodi.LOGNOTICE) return SubtitleResult.NOT_AVAILABLE
def cache_thread(self): kodi.log(__name__, 'Start running cache service.', kodi.LOGNOTICE) monitor = xbmc.Monitor() with Setting() as setting: wait_time = setting.get_cache_not_found_timeout() while not kodi.abort_requested(): with DBConnection() as db: db.cleanup_subtitle_cache() # Sleep/wait for abort for wait_time seconds if kodi.wait_for_abort(wait_time): # Abort was requested while waiting. We should exit break
def set_gui_params(self, params,skinsupport): if(self.notification_method == NotificationMethod.AUTO): self.set_property('skinsubtitlechecker.skinsupport', str(skinsupport)) if (skinsupport == True): kodi.log(__name__, 'notification set by skin to skin support') else: kodi.log(__name__, 'notification set by skin to Pop-up ') self.set_property('skinsubtitlechecker.search_text', params.get('searchreturnvalue', '')) self.set_property('skinsubtitlechecker.present_text', params.get('availabereturnvalue', '')) self.set_property('skinsubtitlechecker.not_present_text', params.get('notavailablereturnvalue', '')) self.videoitem.set_parameter_listitem(params,self.language.language_iso_639_2)
def cache_thread(self): kodi.log(__name__, 'Start running cache service.', kodi.LOGNOTICE) monitor = xbmc.Monitor() with Setting() as setting: wait_time = setting.get_cache_not_found_timeout() while not kodi.abort_requested(): with DBConnection() as db: db.cleanup_subtitle_cache() # Sleep/wait for abort for wait_time seconds if kodi.wait_for_abort(wait_time): # Abort was requested while waiting. We should exit break
def provider_thread(self): kodi.log(__name__, 'Start running provider cache service.', kodi.LOGNOTICE) with Setting() as setting: wait_time = setting.get_provider_search_interval() while not kodi.abort_requested(): # check providers addons = kodi.get_addons() # update provider cache with DBConnection() as db: db.update_cached_providers(addons) # Sleep/wait for abort for wait_time seconds if kodi.wait_for_abort(self.wait_time): # Abort was requested while waiting. We should exit break
def searchsubtitles(self, item): # noinspection PyBroadException try: if item['tvshow']: return self.query_tv_show(item['tvshow'], item['season'], item['episode'], item['3let_language']) elif item['title']: return self.query_film(item['title'], item['year'], item['3let_language']) else: return self.search_filename(item['filename'], item['3let_language']) except: kodi.log(__name__, "failed to connect to Addic7ed service for subtitle search", kodi.LOGNOTICE) return SubtitleResult.NOT_AVAILABLE
def provider_thread(self): kodi.log(__name__, 'Start running provider cache service.', kodi.LOGNOTICE) with Setting() as setting: wait_time = setting.get_provider_search_interval() while not kodi.abort_requested(): # check providers addons = kodi.get_addons() # update provider cache with DBConnection() as db: db.update_cached_providers(addons) # Sleep/wait for abort for wait_time seconds if kodi.wait_for_abort(self.wait_time): # Abort was requested while waiting. We should exit break
def subtitle_search(self): self.init_run_backend() skin_poll_time = self.setting.get_polling_interval() notification_poll_time = self.setting.get_notification_delay() skinsupport = self.gui.get_skin_support() while not kodi.abort_requested(): if self.gui.subtitlecheck_needed(): self.check_subtitle() skinsupport = self.gui.get_skin_support() else: if (skinsupport): kodi.sleep(skin_poll_time) else: kodi.sleep(notification_poll_time) kodi.log(__name__, 'back-end stopped.', kodi.LOGNOTICE) self.gui.reset_running_backend()
def subtitle_search(self): self.init_run_backend() skin_poll_time = self.setting.get_polling_interval() notification_poll_time = self.setting.get_notification_delay() skinsupport = self.gui.get_skin_support() while not kodi.abort_requested(): if self.gui.subtitlecheck_needed(): self.check_subtitle() skinsupport = self.gui.get_skin_support() else: if(skinsupport): kodi.sleep(skin_poll_time) else: kodi.sleep(notification_poll_time) kodi.log(__name__, 'back-end stopped.', kodi.LOGNOTICE) self.gui.reset_running_backend()
def searchsubtitles(self, item): # noinspection PyBroadException try: if item['tvshow']: tvshow_id = self.__get_tvshow_id(item['tvshow']) return self.__get_subtitles(tvshow_id, item['season'], item['episode'], item['3let_language']) else: return SubtitleResult.NOT_AVAILABLE except Exception as e: kodi.log( __name__, 'failed to connect to Addic7ed service for subtitle search (%s)' % e, kodi.LOGNOTICE) return SubtitleResult.NOT_AVAILABLE
def __get_cached_url(self, url): kodi.log(__name__, 'Fetching Cached URL: %s' % url, kodi.LOGDEBUG) req = urllib2.Request(url) host = BASE_URL.replace('http://', '') req.add_header('User-Agent', USER_AGENT) req.add_header('Host', host) req.add_header('Referer', BASE_URL) try: response = urllib2.urlopen(req, timeout=10) html = response.read() html = self.__cleanse_title(html) except Exception as e: kodi.log(__name__, 'Failed to connect to URL %s: (%s)' % (url, e), kodi.LOGDEBUG) return '' return html
def execute(self): if self.action == 'runfromgui': kodi.log(__name__, 'Running from GUI, no action.') elif self.action == 'flushcache': self.execute_flush_subtitle_cache() elif self.action == 'flushproviders': self.execute_flush_provider_cache() elif self.action == 'updateproviders': self.update_providers() elif self.gui.is_running_backend(): # don't run if already in back-end kodi.log(__name__, 'Running in background detected, no action.') elif self.action == 'backend': # run in back-end if parameter was set self.run_backend() else: self.run_once()
def __get_cached_url(self, url): kodi.log(__name__, 'Fetching Cached URL: %s' % url, kodi.LOGDEBUG) req = urllib2.Request(url) host = BASE_URL.replace('http://', '') req.add_header('User-Agent', USER_AGENT) req.add_header('Host', host) req.add_header('Referer', BASE_URL) try: response = urllib2.urlopen(req, timeout=10) html = response.read() html = self.__cleanse_title(html) except Exception as e: kodi.log(__name__, 'Failed to connect to URL %s: (%s)' % (url, e), kodi.LOGDEBUG) return '' return html
def search_filename(self, filename, languages): title, year = kodi.get_clean_movie_title(filename) kodi.log(__name__, "clean title: \"%s\" (%s)" % (title, year)) try: yearval = int(year) except ValueError: yearval = 0 if title and yearval > 1900: return self.query_film(title, year, languages) else: match = re.search(r'\WS(?P<season>\d\d)E(?P<episode>\d\d)', title, flags=re.IGNORECASE) if match is not None: tvshow = string.strip(title[:match.start('season')-1]) season = string.lstrip(match.group('season'), '0') episode = string.lstrip(match.group('episode'), '0') return self.query_tv_show(tvshow, season, episode, languages) else: return SubtitleResult.NOT_AVAILABLE
def searchsubtitles(self, item): # noinspection PyBroadException try: if item['tvshow']: return self.query_tv_show(item['tvshow'], item['season'], item['episode'], item['3let_language']) elif item['title']: return self.query_film(item['title'], item['year'], item['3let_language']) else: return self.search_filename(item['filename'], item['3let_language']) except: kodi.log( __name__, "failed to connect to Addic7ed service for subtitle search", kodi.LOGNOTICE) return SubtitleResult.NOT_AVAILABLE
def search_filename(self, filename, languages): title, year = kodi.get_clean_movie_title(filename) kodi.log(__name__, "clean title: \"%s\" (%s)" % (title, year)) try: yearval = int(year) except ValueError: yearval = 0 if title and yearval > 1900: return self.query_film(title, year, languages) else: match = re.search(r'\WS(?P<season>\d\d)E(?P<episode>\d\d)', title, flags=re.IGNORECASE) if match is not None: tvshow = string.strip(title[:match.start('season') - 1]) season = string.lstrip(match.group('season'), '0') episode = string.lstrip(match.group('episode'), '0') return self.query_tv_show(tvshow, season, episode, languages) else: return SubtitleResult.NOT_AVAILABLE
def searchsubtitles( self, item): try: server = xmlrpclib.Server( self.base_url, verbose=0 ) setting =Setting() login = server.LogIn(setting.get_setting( "OSuser" ), setting.get_setting( "OSpass" ), "en", "%s_v%s" %(__scriptname__.replace(" ","_"),kodi.get_version())) osdb_token = login[ "token" ] if ( osdb_token ) : searchlist = [] if len(item['tvshow']) > 0: OS_search_string = ("%s S%.2dE%.2d" % (item['tvshow'], int(item['season']), int(item['episode']),) ).replace(" ","+") else: OS_search_string = item['title'].replace(" ","+") kodi.log( __name__ , "Search String [ %s ]" % (OS_search_string,)) searchlist = [{'sublanguageid':",".join(item['3let_language']), 'query' :OS_search_string }] search = server.SearchSubtitles( osdb_token, searchlist ) server.__close() if search["data"]: return SubtitleResult.AVAILABLE return SubtitleResult.NOT_AVAILABLE except Exception as e: kodi.log(__name__, "failed to connect to Opensubtitles service for subtitle search", kodi.LOGNOTICE) kodi.log(__name__, "Opensubtitles error:" + str(e)) return SubtitleResult.NOT_AVAILABLE
def set_subtitle_properties(self, subtitle_present): if subtitle_present == SubtitleResult.SEARCH: self.set_property('skinsubtitlechecker.available', self.get_search_text()) elif subtitle_present == SubtitleResult.AVAILABLE: kodi.log(__name__, 'subtitle found.') self.set_property('skinsubtitlechecker.available', self.get_present_text()) elif subtitle_present == SubtitleResult.NOT_AVAILABLE: kodi.log(__name__, 'no subtitle found') self.set_property('skinsubtitlechecker.available', self.get_not_present_text()) else: kodi.log(__name__, 'no subtitle search for item') self.reset_property('skinsubtitlechecker.available') self.set_language_properties(subtitle_present)
def perform_search(self, name, item, result_queue): if name == 'opensubtitle': with OSDBServer()as osdbserver: kodi.log(__name__, 'start search Opensubtitle.') result_queue.put(osdbserver.searchsubtitles(item)) elif name == 'addic7ed': with Adic7edServer()as adic7edserver: kodi.log(__name__, 'start search Addic7ed.') result_queue.put(adic7edserver.searchsubtitles(item)) elif name == 'addic7ed_tvshows': if item['tvshow']: with Adic7edServer_TVShows()as adic7edserver_tvshows: kodi.log(__name__, 'start search Addic7ed TV shows.') result_queue.put(adic7edserver_tvshows.searchsubtitles(item)) else: result_queue.put(SubtitleResult.NOT_AVAILABLE) elif name == 'podnapisi': with PNServer()as pnserver: kodi.log(__name__, 'start search Podnapisi.') result_queue.put(pnserver.searchsubtitles(item))
def perform_search(self, name, item, result_queue): if name == 'opensubtitle': with OSDBServer() as osdbserver: kodi.log(__name__, 'start search Opensubtitle.') result_queue.put(osdbserver.searchsubtitles(item)) elif name == 'addic7ed': with Adic7edServer() as adic7edserver: kodi.log(__name__, 'start search Addic7ed.') result_queue.put(adic7edserver.searchsubtitles(item)) elif name == 'addic7ed_tvshows': if item['tvshow']: with Adic7edServer_TVShows() as adic7edserver_tvshows: kodi.log(__name__, 'start search Addic7ed TV shows.') result_queue.put( adic7edserver_tvshows.searchsubtitles(item)) else: result_queue.put(SubtitleResult.NOT_AVAILABLE) elif name == 'podnapisi': with PNServer() as pnserver: kodi.log(__name__, 'start search Podnapisi.') result_queue.put(pnserver.searchsubtitles(item))
def __init_vars(self): self.window = kodi.get_window(10025) # MyVideoNav.xml (videos) self.dialogwindow = kodi.get_window(12003) # DialogVideoInfo.xml (movieinformation) self.language = Language() self.videoitem = VideoItem() with Setting() as settings: self.notification_method = settings.get_notification_method() self.notification_duration = settings.get_notification_duration() if (self.notification_method == NotificationMethod.AUTO): self.set_property('skinsubtitlechecker.skinsupport', str(False)) kodi.log(__name__, 'Skin support set to Auto') elif(NotificationMethod.POPUP): self.set_property('skinsubtitlechecker.skinsupport', str(False)) kodi.log(__name__, 'Skin support set to Pop-up') else: self.set_property('skinsubtitlechecker.skinsupport', str(True)) kodi.log(__name__, 'notification set to skin support')
def searchsubtitles(self, item): try: server = xmlrpclib.Server(self.base_url, verbose=0) setting = Setting() login = server.LogIn( setting.get_setting("OSuser"), setting.get_setting("OSpass"), "en", "%s_v%s" % (__scriptname__.replace(" ", "_"), kodi.get_version())) osdb_token = login["token"] if (osdb_token): searchlist = [] if len(item['tvshow']) > 0: OS_search_string = ("%s S%.2dE%.2d" % ( item['tvshow'], int(item['season']), int(item['episode']), )).replace(" ", "+") else: OS_search_string = item['title'].replace(" ", "+") kodi.log(__name__, "Search String [ %s ]" % (OS_search_string, )) searchlist = [{ 'sublanguageid': ",".join(item['3let_language']), 'query': OS_search_string }] search = server.SearchSubtitles(osdb_token, searchlist) server.__close() if search["data"]: return SubtitleResult.AVAILABLE return SubtitleResult.NOT_AVAILABLE except Exception as e: kodi.log( __name__, "failed to connect to Opensubtitles service for subtitle search", kodi.LOGNOTICE) kodi.log(__name__, "Opensubtitles error:" + str(e)) return SubtitleResult.NOT_AVAILABLE
def clean_up_gui(self, exc_type, exc_value, traceback): # noinspection PyBroadException try: # call explicit the exit function of the gui class, it is not used # within with statement self.gui.__exit__(exc_type, exc_value, traceback) self.gui = None del self.gui except: # database is not yet set pass def clean_up_subtitlechecker(self, exc_type, exc_value, traceback): # noinspection PyBroadException try: # call explicit the exit function of the videoitem class, it is not # used within with statement self.subtitlechecker.__exit__(exc_type, exc_value, traceback) self.subtitlechecker = None del self.subtitlechecker except: # database is not yet set pass if __name__ == "__main__": with Main() as subtitlechecker: subtitlechecker.execute() kodi.log(__name__, 'script finished.')
def get_dialogvideoinfo_property(self, name): propvalue = self.dialogwindow.getProperty(name) kodi.log(__name__,'get videolibray property %s = %s' % (name, propvalue)) return propvalue
def get_videolibrary_property(self, name): propvalue = self.window.getProperty(name) kodi.log(__name__,'videolibray property %s = %s' % (name, propvalue)) return propvalue
def run_once(self): kodi.log(__name__, 'Execute once.') self.check_subtitle()
def __init_database(self): # intended to be a common method for creating a db from scratch kodi.log(__name__, 'Building Subtitle checker Database', kodi.LOGDEBUG) self.__execute('PRAGMA journal_mode=WAL') self.__update_database()
def execute_flush_provider_cache(self): kodi.log(__name__, 'Flush provider cache.', kodi.LOGNOTICE) with DBConnection() as db: db.flush_provider_cache()
def __init__(self): kodi.log(__name__, "version %s started" % kodi.get_version(), kodi.LOGNOTICE) self._init_vars()
def __init__(self): kodi.log(__name__, "version %s started" % kodi.get_version(), kodi.LOGNOTICE) self.__init_vars() self.__parse_argv()
def __parse_argv(self): self.params = kodi.get_params(sys.argv,1) kodi.log(__name__, "params: %s" % self.params) self.__set_action_from_params() skinsupport = self.action=='backend' or self.action=='runonce' self.gui.set_gui_params(self.params,skinsupport)
def execute_flush_subtitle_cache(self): kodi.log(__name__, 'Flush subtitle cache.', kodi.LOGNOTICE) with DBConnection() as db: db.flush_subtitle_cache()
def store_cache(self, item, subtitle_present): if subtitle_present != SubtitleResult.SEARCH and subtitle_present != SubtitleResult.HIDE: kodi.log(__name__, 'cache item') self.db.cache_subtitle(item, subtitle_present)
def search_cache(self, item): kodi.log(__name__, 'start search local cache.') return self.db.get_cached_subtitle(item)
def clean_up_gui(self, exc_type, exc_value, traceback): # noinspection PyBroadException try: # call explicit the exit function of the gui class, it is not used # within with statement self.gui.__exit__(exc_type, exc_value, traceback) self.gui = None del self.gui except: # database is not yet set pass def clean_up_subtitlechecker(self, exc_type, exc_value, traceback): # noinspection PyBroadException try: # call explicit the exit function of the videoitem class, it is not # used within with statement self.subtitlechecker.__exit__(exc_type, exc_value, traceback) self.subtitlechecker = None del self.subtitlechecker except: # database is not yet set pass if __name__ == "__main__": with Service() as service: service.run() kodi.log(__name__, 'cache service finished.')
def init_run_backend(self): kodi.log(__name__, 'Start running background.', kodi.LOGNOTICE) self.gui.set_running_backend() self.gui.show_subtitle(SubtitleResult.HIDE)
def store_cache(self, item, subtitle_present): if subtitle_present != SubtitleResult.SEARCH and subtitle_present != SubtitleResult.HIDE: kodi.log(__name__, 'cache item') self.db.cache_subtitle(item, subtitle_present)
pass def clean_up_gui(self, exc_type, exc_value, traceback): # noinspection PyBroadException try: # call explicit the exit function of the gui class, it is not used # within with statement self.gui.__exit__(exc_type, exc_value, traceback) self.gui = None del self.gui except: # database is not yet set pass def clean_up_subtitlechecker(self, exc_type, exc_value, traceback): # noinspection PyBroadException try: # call explicit the exit function of the videoitem class, it is not # used within with statement self.subtitlechecker.__exit__(exc_type, exc_value, traceback) self.subtitlechecker = None del self.subtitlechecker except: # database is not yet set pass if __name__ == "__main__": with Service() as service: service.run() kodi.log(__name__, 'cache service finished.')
def init_run_backend(self): kodi.log(__name__, 'Start running background.', kodi.LOGNOTICE) self.gui.set_running_backend() self.gui.show_subtitle(SubtitleResult.HIDE)
def set_videolibrary_property(self, name, value): kodi.log(__name__,'set videolibray property %s with %s' % (name, value)) self.window.setProperty(name, value)
def set_dialogvideoinfo_property(self, name, value): kodi.log(__name__,'set video dialog property %s with %s' % (name, value)) self.dialogwindow.setProperty(name, value)
def update_providers(self): kodi.log(__name__, 'Update providers.', kodi.LOGNOTICE)