def get_tv_library_local( library_name = 'TV Shows' ): fullURL, token = core.checkServerCredentials( doLocal=True ) library_names = list( core.get_libraries( token = token ).values( ) ) assert( library_name in library_names ) # tvdata = core.get_library_data( library_name, token = token, num_threads = cpu_count( ) ) return tvdata
def get_tvdata(tvlibraryname, fullURL, token, doCheck=True): if doCheck: try: all_libraries = core.get_libraries(token=token, fullURL=fullURL, do_full=True) except: return return_error_raw( "Error, bad token or URL may have been given.") key_found = list( filter(lambda key: all_libraries[key][0] == tvlibraryname, all_libraries)) if key_found is None: return return_error_raw("Error, %s library does not exist." % tvlibraryname) key_found = min(key_found) if all_libraries[key_found][1] != 'show': return return_error_raw("Error, %s library is not a TV library." % tvlibraryname) # ## now get data tvdata = core.get_library_data(tvlibraryname, token=token, fullURL=fullURL) return tvdata, 'SUCCESS'
def main(): time0 = time.time() parser = ArgumentParser() parser.add_argument('--noverify', dest='do_verify', action='store_false', default=True, help='If chosen, do not verify the SSL connection.') parser.add_argument('--local', dest='do_local', action='store_true', default=False, help='Check for locally running plex server.') parser.add_argument('--info', dest='do_info', action='store_true', default=False, help='If chosen, run with INFO logging mode.') args = parser.parse_args() logger = logging.getLogger() if args.do_info: logger.setLevel(logging.INFO) # ## function to do the processing step = 0 print('%d, started on %s' % (step, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p'))) # ## get plex server token dat = core.checkServerCredentials(doLocal=args.do_local, verify=args.do_verify) if dat is None: step += 1 print('\n'.join([ '%d, error, could not access local Plex server in %0.3f seconds. Exiting...' % (step, time.time() - time0), '%d, finished on %s.' % (step + 1, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p')) ])) return fullURL, token = dat # ## first find out which libraries are the TV show ones library_dict = core.get_libraries(token, fullURL=fullURL, do_full=True) if library_dict is None: step += 1 print('\n'.join([ '%d, error, could not access libraries in plex server in %0.3f seconds. Exiting...' % (step, time.time() - time0), '%d, finished on %s.' % (step + 1, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p')) ])) return # valid_keys = list( filter(lambda key: library_dict[key][-1] == 'show', library_dict)) if len(valid_keys) == 0: step += 1 print('\n'.join([ '%d, Error, could not find a TV show library in %0.3f seconds. Exiting...' % (time.time() - time0, step), '%d, finished on %s.' % (step + 1, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p')) ])) return tvlib_title = library_dict[max(valid_keys)][0] step += 1 nowdate = datetime.datetime.now().date() print('%d, found TV library: %s.' % (step, tvlib_title)) # ## now get the future TV shows tvdata = core.get_library_data(tvlib_title, token=token, fullURL=fullURL) showsToExclude = tv.get_shows_to_exclude(tvdata) if len(showsToExclude) != 0: step += 1 print('%d, excluding these TV shows: %s.' % (step, '; '.join(showsToExclude))) future_shows_dict = tv.get_future_info_shows(tvdata, verify=args.do_verify, showsToExclude=showsToExclude, fromDate=nowdate) for show in future_shows_dict: tdelta = future_shows_dict[show]['start_date'] - nowdate future_shows_dict[show]['days_to_new_season'] = tdelta.days if len(future_shows_dict) == 0: step += 1 print('%d, found no TV shows with new seasons.' % step) print('%d, finished on %s.' % (step + 1, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p'))) return step += 1 print( '%d, Found %d TV shows with new seasons after %s, in %0.3f seconds.' % (step, len(future_shows_dict), nowdate.strftime('%B %d, %Y'), time.time() - time0)) print('\n') all_new_show_data = list( map( lambda show: (show, future_shows_dict[show]['max_last_season'], future_shows_dict[show]['min_next_season'], future_shows_dict[ show]['start_date'].strftime('%B %d, %Y'), future_shows_dict[ show]['days_to_new_season']), sorted(future_shows_dict, key=lambda shw: (future_shows_dict[shw]['start_date'], shw)))) print('%s\n' % tabulate.tabulate(all_new_show_data, headers=[ 'SHOW', 'LAST SEASON', 'NEXT SEASON', 'AIR DATE', 'DAYS TO NEW SEASON' ])) step += 1 print('\n'.join([ '%d, processed everything in %0.3f seconds.' % (step, time.time() - time0), '%d, finished everything on %s.' % (step + 1, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p')) ]))
def main(): time0 = time.time() default_time = 1000 default_iters = 2 default_num_threads = 2 * multiprocessing.cpu_count() # parser = ArgumentParser() parser.add_argument( '--maxtime', dest='maxtime_in_secs', type=int, action='store', default=default_time, help=' '.join([ 'The maximum amount of time to spend (in seconds),', 'per candidate magnet link,', 'trying to download a TV show.', 'Default is %d seconds.' % default_time ])) parser.add_argument( '--num', dest='num_iters', type=int, action='store', default=default_iters, help=' '.join([ 'The maximum number of different magnet links to try', 'before giving up. Default is %d.' % default_iters ])) parser.add_argument( '--token', dest='token', type=str, action='store', help='Optional argument. If chosen, user provided Plex access token.') parser.add_argument( '--debuglevel', dest='debug_level', action='store', type=str, default='None', choices=['None', 'info', 'debug'], help= 'Choose the debug level for the system logger. Default is None (no logging). Can be one of None (no logging), info, or debug.' ) parser.add_argument( '--numthreads', dest='numthreads', type=int, action='store', default=default_num_threads, help= 'Number of threads over which to search for TV shows in my library. Default is %d.' % default_num_threads) parser.add_argument( '--nomax', dest='do_restrict_maxsize', action='store_false', default=True, help='If chosen, do not restrict maximum size of downloaded file.') parser.add_argument( '--nomin', dest='do_restrict_minsize', action='store_false', default=True, help='If chosen, do not restrict minimum size of downloaded file.') parser.add_argument( '--raw', dest='do_raw', action='store_true', default=False, help='If chosen, then use the raw string to specify TV show torrents.') args = parser.parse_args() # logger = logging.getLogger() if args.debug_level == 'info': logger.setLevel(logging.INFO) if args.debug_level == 'debug': logger.setLevel(logging.DEBUG) assert (args.maxtime_in_secs >= 60), 'error, max time must be >= 60 seconds.' assert (args.num_iters >= 1), 'error, must have a positive number of maximum iterations.' step = 0 print('%d, started on %s' % (step, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p'))) step += 1 # ## get plex server token dat = core.checkServerCredentials(doLocal=True) if dat is None: print('\n'.join([ '%d, error, could not access local Plex server in %0.3f seconds. Exiting...' % (step, time.time() - time0), finish_statement(step) ])) return fullURL, token = dat if args.token is not None: token = args.token # ## first find out which libraries are the TV show ones library_dict = core.get_libraries(token, fullURL=fullURL, do_full=True) if library_dict is None: print('\n'.join([ '%d, error, could not access libraries in plex server in %0.3f seconds. Exiting...' % (step, time.time() - time0), finish_statement(step) ])) return # valid_keys = list( filter(lambda key: library_dict[key][-1] == 'show', library_dict)) if len(valid_keys) == 0: print('\n'.join([ '%d, Error, could not find a TV show library in %0.3f seconds. Exiting...' % (time.time() - time0, step), finish_statement(step) ])) return tvlib_title = library_dict[max(valid_keys)][0] print('%d, found TV library: %s.' % (step, tvlib_title)) step += 1 # ## now get the TV shows time0 = time.time() tvdata = core.get_library_data(tvlib_title, token=token, num_threads=args.numthreads) print('%d, found %d shows in the TV library, in %0.3f seconds.' % (step, len(tvdata), time.time() - time0)) step += 1 showsToExclude = tv.get_shows_to_exclude(tvdata) if len(showsToExclude) != 0: print('%d, excluding these TV shows: %s.' % (step, '; '.join(showsToExclude))) step += 1 tvdb_token = get_token() if tvdb_token is None: print('\n'.join([ '%d, error, could not access the TVDB API server in %0.3f seconds. Exiting...' % (step, time.time() - time0) ])) return toGet = tv.get_remaining_episodes(tvdata, showSpecials=False, showsToExclude=showsToExclude, num_threads=args.numthreads) if len(toGet) == 0: print('\n'.join([ '%d, no episodes to download in %0.3f seconds. Exiting...' % (step, time.time() - time0), finish_statement(step) ])) return print('%d, took %0.3f seconds to get list of %d episodes to download.' % (step, time.time() - time0, sum(map(lambda tvshow: len(toGet[tvshow]['episodes']), toGet)))) step += 1 # ## now download these episodes tvTorUnits, newdirs = tv.create_tvTorUnits( toGet, restrictMaxSize=args.do_restrict_maxsize, restrictMinSize=args.do_restrict_minsize, do_raw=args.do_raw) print('%d, here are the %d episodes to get: %s.' % (step, len(tvTorUnits), ', '.join( map(lambda tvTorUnit: tvTorUnit['torFname'], tvTorUnits)))) step += 1 tv.download_batched_tvtorrent_shows(tvTorUnits, newdirs=newdirs, maxtime_in_secs=args.maxtime_in_secs, num_iters=args.num_iters) print('\n'.join([ '%d, everything done in %0.3f seconds.' % (step, time.time() - time0), finish_statement(step) ]))
def main(): time0 = time.time() parser = ArgumentParser() parser.add_argument( '--years', dest='s_years', action='store', type=str, help='Give a list of years as a string, such as "1980,1981". Optional.' ) parser.add_argument('--local', dest='do_local', action='store_true', default=False, help='Check for locally running plex server.') parser.add_argument( '--dirname', dest='dirname', action='store', type=str, default=os.getcwd(), help='Directory into which to store those plots. Default is %s.' % os.getcwd()) parser.add_argument('--noverify', dest='do_verify', action='store_false', default=True, help='If chosen, do not verify SSL connections.') args = parser.parse_args() # ## function to do the processing step = 0 print('%d, started on %s' % (step, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p'))) if args.s_years is not None: try: years = sorted( set(map(lambda tok: int(tok), args.s_years.split(',')))) except: step += 1 print('%d, did not give a valid set of years.' % step) years = [] else: years = [] # ## get plex server token dat = core.checkServerCredentials(doLocal=args.do_local, verify=args.do_verify) if dat is None: step += 1 print('\n'.join([ '%d, error, could not access local Plex server in %0.3f seconds. Exiting...' % (step, time.time() - time0), '%d, finished on %s.' % (step + 1, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p')) ])) return fullURL, token = dat # ## first find out which libraries are the TV show ones library_dict = core.get_libraries(token, fullURL=fullURL, do_full=True) if library_dict is None: step += 1 print('\n'.join([ '%d, error, could not access libraries in plex server in %0.3f seconds. Exiting...' % (step, time.time() - time0), '%d, finished on %s.' % (step + 1, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p')) ])) return # valid_keys = list( filter(lambda key: library_dict[key][-1] == 'show', library_dict)) if len(valid_keys) == 0: step += 1 print('\n'.join([ '%d, Error, could not find a TV show library in %0.3f seconds. Exiting...' % (time.time() - time0, step), '%d, finished on %s.' % (step + 1, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p')) ])) return tvlib_title = library_dict[max(valid_keys)][0] step += 1 print('%d, found TV library: %s.' % (step, tvlib_title)) # ## now get the TV shows tvdata = core.get_library_data(tvlib_title, token=token, fullURL=fullURL, num_threads=16) showsToExclude = tv.get_shows_to_exclude(tvdata) if len(showsToExclude) != 0: step += 1 print('%d, excluding these TV shows: %s.' % (step, '; '.join(showsToExclude))) # ## now actual meat of the computation tvdata_date_dict = tv.get_tvdata_ordered_by_date(tvdata) min_year = min(tvdata_date_dict.keys()).year max_year = max(tvdata_date_dict.keys()).year possible_years_set = set(map(lambda date: date.year, tvdata_date_dict)) step += 1 if len(years) == 0: years = sorted(possible_years_set) print('%d, no years specified. We will use %s total: %s.' % (step, _print_years(len(years)), ', '.join( map(lambda year: '%d' % year, years)))) else: cand_years = sorted(set(years) & possible_years_set) if len(cand_years) == 0: print('\n'.join([ '%d, no intersection between the %s chosen (%s) and the %d years in the library.' % (step, _print_years(len(years)), ', '.join( lambda yr: '%d' % year, years), len(possible_years_set)), 'Instead, we will use %s total: %s.' % (_print_years(len(possible_years_set)), ', '.join( map(lambda year: '%d' % year, sorted(possible_years_set)))) ])) years = sorted(possible_years_set) else: print('%d, we found %s to use: %s.' % (step, _print_years(len(cand_years)), ', '.join( map(lambda year: '%d' % year, cand_years)))) years = cand_years step += 1 print('%d, started processing %s of TV shows after %0.3f seconds.' % (step, _print_years(len(years)), time.time() - time0)) manager = Manager() shared_step = manager.Value('step', step) num_procced = manager.Value('nump', 0) lock = manager.RLock() pool = Pool(processes=cpu_count()) def _process_year(year): tv.create_plot_year_tvdata(tvdata_date_dict, year, shouldPlot=True, dirname=args.dirname) lock.acquire() shared_step.value += 1 num_procced.value += 1 print( '%d, finished processing year = %d (%02d / %02d) in %0.3f seconds.' % (shared_step.value, year, num_procced.value, len(years), time.time() - time0)) lock.release() _ = list(pool.map(_process_year, years)) step = shared_step.value + 1 print('\n'.join([ '%d, processed all %s in %0.3f seconds.' % (step, _print_years(len(years)), time.time() - time0), '%d, finished everything on %s.' % (step + 1, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p')) ]))
def run(self): self.progress_dialog.show() time0 = self.progress_dialog.t0 final_data_out = {} mytxt = '0, started loading in data on %s.' % ( datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p')) logging.info(mytxt) self.emitString.emit(mytxt) # libraries_dict = core.get_libraries(self.token, fullURL=self.fullURL, do_full=True) if not any( map(lambda value: 'show' in value[-1], libraries_dict.values())): raise ValueError('Error, could not find TV shows.') library_name = max( map( lambda key: libraries_dict[key][0], filter(lambda key: libraries_dict[key][1] == 'show', libraries_dict))) final_data_out['library_name'] = library_name mytxt = '1, found TV library in %0.3f seconds.' % (time.time() - time0) logging.info(mytxt) self.emitString.emit(mytxt) # if self.tvdata_on_plex is None: self.tvdata_on_plex = core.get_library_data( library_name, fullURL=self.fullURL, token=self.token, num_threads=self.num_threads) if self.tvdata_on_plex is None: raise ValueError('Error, could not find TV shows on the server.') mytxt = '2, loaded TV data from Plex server in %0.3f seconds.' % ( time.time() - time0) logging.info(mytxt) self.emitString.emit(mytxt) # ## using a stupid-ass pattern to shave some seconds off... manager = Manager() shared_list = manager.list() myLock = manager.RLock() myStage = manager.Value('stage', 2) # def _process_didend(): if self.didend is not None: shared_list.append(('didend', self.didend)) return didEnd = tv.get_all_series_didend(self.tvdata_on_plex, verify=self.verify, tvdb_token=self.tvdb_token) myLock.acquire() myStage.value += 1 mytxt = '%d, added information on whether shows ended in %0.3f seconds.' % ( myStage.value, time.time() - time0) logging.info(mytxt) self.emitString.emit(mytxt) myLock.release() shared_list.append(('didend', didEnd)) def _process_missing(): if self.toGet is not None: shared_list.append(('toGet', self.toGet)) return toGet = tv.get_remaining_episodes( self.tvdata_on_plex, showSpecials=False, showsToExclude=self.showsToExclude, verify=self.verify, token=self.tvdb_token) myLock.acquire() myStage.value += 1 mytxt = '%d, found missing episodes in %0.3f seconds.' % ( myStage.value, time.time() - time0) logging.info(mytxt) self.emitString.emit(mytxt) myLock.release() shared_list.append(('toGet', toGet)) def _process_plot_tvshowstats(): tvdata_date_dict = tv.get_tvdata_ordered_by_date( self.tvdata_on_plex) years_have = set(map(lambda date: date.year, tvdata_date_dict)) with multiprocessing.Pool( processes=multiprocessing.cpu_count()) as pool: figdictdata = dict( pool.map( lambda year: (year, tv.create_plot_year_tvdata( tvdata_date_dict, year, shouldPlot=False)), years_have)) myLock.acquire() myStage.value += 1 mytxt = '%d, made plots of tv shows added in %d years in %0.3f seconds.' % ( myStage.value, len(years_have), time.time() - time0) logging.info(mytxt) self.emitString.emit(mytxt) myLock.release() shared_list.append(('plotYears', figdictdata)) jobs = [ Process(target=_process_didend), Process(target=_process_missing) ] # Process( target = _process_plot_tvshowstats ) ] for process in jobs: process.start() for process in jobs: process.join() # final_data = dict(shared_list) assert (set(final_data) == set(['didend', 'toGet'])) didend = final_data['didend'] toGet = final_data['toGet'] for seriesName in self.tvdata_on_plex: self.tvdata_on_plex[seriesName]['didEnd'] = didend[seriesName] final_data_out['tvdata_on_plex'] = self.tvdata_on_plex mytxt = '%d, finished loading in all data on %s.' % ( myStage.value + 1, datetime.datetime.now().strftime('%B %d, %Y @ %I:%M:%S %p')) logging.info(mytxt) self.emitString.emit(mytxt) missing_eps = dict( map( lambda seriesName: (seriesName, toGet[seriesName]['episodes']), set(self.tvdata_on_plex) & set(toGet) - set(self.showsToExclude))) final_data_out['missing_eps'] = missing_eps self.finalData.emit(final_data_out) self.stopDialog.emit() # now stop everything