def get_offset_end(vid, hashtable, check_if_missing=False): an = analyzer() match = matcher() start_time = -1 end_time = -1 t_hop = an.n_hop / float(an.target_sr) rslts, dur, nhash = match.match_file(an, hashtable, vid, 1) # The number does not matter... for (tophitid, nhashaligned, aligntime, nhashraw, rank, min_time, max_time) in rslts: end_time = max_time * t_hop start_time = min_time * t_hop LOG.info( 'Match %s rank %s aligntime %s theme song %s started at %s (%s) in ended at %s (%s)' % (tophitid, rank, aligntime, hashtable.names[tophitid], start_time, to_time(start_time), end_time, to_time(end_time))) if len(rslts): best = rslts[0] end_time = best[6] * t_hop start_time = best[5] * t_hop LOG.debug('Best match was %s', hashtable.names[best[0]]) return start_time, end_time LOG.debug('no result just returning -1') return start_time, end_time
def get_hashtable(): LOG.debug('Getting hashtable') from bw_plex.audfprint.hash_table import HashTable # Patch HashTable. try: import cPickle as pickle except ImportError: import pickle import gzip def load(self, name=None): if name is None: self.__filename = name self.load_pkl(name) return self def save(self, name=None, params=None, file_object=None): LOG.debug('Saving HashTable') # Merge in any provided params if params: for key in params: self.params[key] = params[key] if file_object: f = file_object self.__filename = f.name else: if name is None: f = self.__filename else: self.__filename = f = name f = gzip.open(f, 'wb') pickle.dump(self, f, pickle.HIGHEST_PROTOCOL) self.dirty = False return self HashTable.save = save HashTable.load = load if os.path.exists(FP_HASHES): LOG.info('Loading existing files in db') HT = HashTable(FP_HASHES) HT.__filename = FP_HASHES else: LOG.info('Creating new hashtable db') HT = HashTable() HT.__filename = FP_HASHES HT.save(FP_HASHES) HT.load(FP_HASHES) return HT
def inner(): try: func() except plexapi.exceptions.BadRequest: try: LOG.info( 'Failed to reach the client directly, trying via server.' ) correct_client.proxyThroughServer() func() except: # pragma: no cover correct_client.proxyThroughServer(value=False) raise
def inner(): try: func() except (plexapi.exceptions.BadRequest, requests.exceptions.ConnectionError, requests.exceptions.Timeout, requests.exceptions.TooManyRedirects, requests.exceptions.HTTPError): try: LOG.info( 'Failed to reach the client directly, trying via server.' ) correct_client.proxyThroughServer() func() except: # pragma: no cover correct_client.proxyThroughServer(value=False) raise
def get_hashtable(): LOG.debug('Getting hashtable') from bw_plex.audfprint.hash_table import HashTable # Patch HashTable. try: import cPickle as pickle except ImportError: import pickle import gzip def load(self, name=None): if name is None: self.__filename = name self.load_pkl(name) LOG.debug('Files in the hashtable') for n in self.names: LOG.debug(n) return self def save(self, name=None, params=None, file_object=None): LOG.debug('Saving HashTable') # Merge in any provided params if params: for key in params: self.params[key] = params[key] if file_object: f = file_object self.__filename = f.name else: if name is None: f = self.__filename else: self.__filename = f = name f = gzip.open(f, 'wb') pickle.dump(self, f, pickle.HIGHEST_PROTOCOL) self.dirty = False return self def has_theme(self, media, add_if_missing=True): """Cheaper way to lookup stuff.""" th = bool(self.get_theme(media)) if th is False and add_if_missing is True: th = download_theme(media, self) if th: return True return False def get_theme(self, media): if media.TYPE == 'show': name = media.title rk = media.ratingKey else: rk = media.grandparentRatingKey name = media.grandparentTitle d = self.get_themes().get(rk, []) LOG.debug('%s has %s themes', name, len(d)) return d def get_themes(self): d = defaultdict(list) for n in self.names: try: rk = os.path.basename(n).split('__')[1] d[int(rk)].append(n) except (IndexError, TypeError): LOG.exception('Some crap happend with', n) return d HashTable.save = save HashTable.load = load HashTable.has_theme = has_theme HashTable.get_themes = get_themes HashTable.get_theme = get_theme if os.path.exists(FP_HASHES): LOG.info('Loading existing files in db') HT = HashTable(FP_HASHES) HT.__filename = FP_HASHES else: LOG.info('Creating new hashtable db') HT = HashTable() HT.__filename = FP_HASHES HT.save(FP_HASHES) HT.load(FP_HASHES) return HT
def client_action(offset=None, sessionkey=None, action='jump'): # pragma: no cover """Seek the client to the offset. Args: offset(int): Default None sessionkey(int): So we made sure we control the correct client. Returns: None """ global JUMP_LIST LOG.info('Called client_action with %s %s %s %s', offset, to_time(offset), sessionkey, action) def proxy_on_fail(func): import plexapi @wraps(func) def inner(): try: func() except plexapi.exceptions.BadRequest: try: LOG.info( 'Failed to reach the client directly, trying via server.' ) correct_client.proxyThroughServer() func() except: # pragma: no cover correct_client.proxyThroughServer(value=False) raise if offset == -1: return conf_clients = CONFIG.get('general', {}).get('clients', []) conf_users = CONFIG.get('general', {}).get('users', []) correct_client = None clients = PMS.clients() for media in PMS.sessions(): # Find the client.. This client does not have the correct address # or 'protocolCapabilities' so we have to get the correct one. # or we can proxy thru the server.. if sessionkey and int(sessionkey) == media.sessionKey: client = media.players[0] user = media.usernames[0] LOG.info('client %s %s', client.title, (media.viewOffset / 1000)) # Check that this client is allowed. if conf_clients and client.title not in conf_clients: LOG.info('Client %s is not whitelisted', client.title) return # Check that this user is allowed. if conf_users and user not in conf_users: LOG.info('User %s is not whitelisted', user) return # To stop processing. from func task if we have used to much time.. # This will not work if/when credits etc are added. Need a better way. # if offset <= media.viewOffset / 1000: # LOG.debug('Didnt jump because of offset') # return for c in clients: LOG.info('%s %s' % (c.machineIdentifier, client.machineIdentifier)) # So we got the correct client.. if c.machineIdentifier == client.machineIdentifier: # Plex web sometimes add loopback.. if '127.0.0.1' in c._baseurl: c._baseurl = c._baseurl.replace( '127.0.0.1', client.address) correct_client = c break if correct_client: try: LOG.info('Connectiong to %s', correct_client.title) correct_client.connect() except requests.exceptions.ConnectionError: LOG.exception('Cant connect to %s', client.title) return if action != 'stop': if ignore_ratingkey( media, CONFIG['general'].get('ignore_intro_ratingkeys')): LOG.info( 'Didnt send seek command this show, season or episode is ignored' ) return # PMP seems to be really picky about timeline calls, if we dont # it returns 406 errors after 90 sec. if correct_client.product == 'Plex Media Player': correct_client.sendCommand('timeline/poll', wait=0) proxy_on_fail(correct_client.seekTo(int(offset * 1000))) LOG.info('Jumped %s %s to %s %s', user, client.title, offset, media._prettyfilename()) else: if not ignore_ratingkey( media, CONFIG['general'].get('ignore_intro_ratingkeys')): proxy_on_fail(correct_client.stop()) # We might need to login on pms as the user.. # urs_pms = users_pms(PMS, user) # new_media = urs_pms.fetchItem(int(media.ratingkey)) # new_media.markWatched() # LOG.debug('Stopped playback on %s and marked %s as watched.', client.title, media._prettyfilename()) # Check if we just start the next ep instantly. if CONFIG['tv'].get( 'check_credits_start_next_ep') is True: nxt = find_next( media) # This is always false for movies. if nxt: LOG.info('Start playback on %s with %s', user, nxt._prettyfilename()) proxy_on_fail(correct_client.playMedia(nxt)) else: LOG.info('Didnt find the correct client.') # Some clients needs some time.. # time.sleep(0.2) # client.play() # JUMP_LIST.remove(sessionkey) # time.sleep(1) return
from bw_plex.credits import find_credits from bw_plex.db import session_scope, Processed import bw_plex.edl as edl from bw_plex.misc import (analyzer, convert_and_trim, choose, find_next, find_offset_ffmpeg, get_offset_end, get_pms, get_hashtable, has_recap, to_sec, to_time, download_theme, ignore_ratingkey) IN_PROG = [] JUMP_LIST = [] SHOWS = {} HT = None is_64bit = struct.calcsize('P') * 8 if not is_64bit: # pragma: no cover LOG.info('You not using a python 64 bit version.') def log_exception(func): @wraps(func) def inner(*args, **kwargs): try: if kwargs: return func(*args, **kwargs) else: return func(*args) except: # pragma: no cover err = "There was an exception in " err += func.__name__ LOG.exception(err)