def configure(self, cache_file, log_file): region.configure('dogpile.cache.dbm', arguments={'filename': cache_file}) refiner_manager.register('release = release_refiner:refine') if addon.getSetting('subliminal.debug') == 'true': logger = logging.getLogger('subliminal') logger.setLevel(level=logging.DEBUG) logger.addHandler(logging.FileHandler(log_file, 'a'))
def subliminal(ctx, addic7ed, legendastv, opensubtitles, subscenter, cache_dir, debug): """Subtitles, faster than your thoughts.""" # create cache directory try: os.makedirs(cache_dir) except OSError: if not os.path.isdir(cache_dir): raise # configure cache region.configure('dogpile.cache.dbm', expiration_time=timedelta(days=30), arguments={'filename': os.path.join(cache_dir, cache_file), 'lock_factory': MutexLock}) # configure logging if debug: handler = logging.StreamHandler() handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT)) logging.getLogger('subliminal').addHandler(handler) logging.getLogger('subliminal').setLevel(logging.DEBUG) # provider configs ctx.obj = {'provider_configs': {}} if addic7ed: ctx.obj['provider_configs']['addic7ed'] = {'username': addic7ed[0], 'password': addic7ed[1]} if legendastv: ctx.obj['provider_configs']['legendastv'] = {'username': legendastv[0], 'password': legendastv[1]} if opensubtitles: ctx.obj['provider_configs']['opensubtitles'] = {'username': opensubtitles[0], 'password': opensubtitles[1]} if subscenter: ctx.obj['provider_configs']['subscenter'] = {'username': subscenter[0], 'password': subscenter[1]}
def subliminal(ctx, addic7ed, legendastv, opensubtitles, subscenter, cache_dir, debug): """Subtitles, faster than your thoughts.""" # create cache directory try: os.makedirs(cache_dir) except OSError: if not os.path.isdir(cache_dir): raise # configure cache region.configure( "dogpile.cache.dbm", expiration_time=timedelta(days=30), arguments={"filename": os.path.join(cache_dir, cache_file), "lock_factory": MutexLock}, ) # configure logging if debug: handler = logging.StreamHandler() # TODO: change format to something nicer (use colorlogs + funcName) handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT)) logging.getLogger("subliminal").addHandler(handler) logging.getLogger("subliminal").setLevel(logging.DEBUG) # provider configs ctx.obj = {"provider_configs": {}} if addic7ed: ctx.obj["provider_configs"]["addic7ed"] = {"username": addic7ed[0], "password": addic7ed[1]} if legendastv: ctx.obj["provider_configs"]["legendastv"] = {"username": legendastv[0], "password": legendastv[1]} if opensubtitles: ctx.obj["provider_configs"]["opensubtitles"] = {"username": opensubtitles[0], "password": opensubtitles[1]} if subscenter: ctx.obj["provider_configs"]["subscenter"] = {"username": subscenter[0], "password": subscenter[1]}
def subliminal(ctx, addic7ed, legendastv, opensubtitles, cache_dir, debug): """Subtitles, faster than your thoughts.""" # create cache directory try: os.makedirs(cache_dir) except OSError: if not os.path.isdir(cache_dir): raise # configure cache region.configure('dogpile.cache.dbm', expiration_time=timedelta(days=30), arguments={'filename': os.path.join(cache_dir, cache_file), 'lock_factory': MutexLock}) # configure logging if debug: handler = logging.StreamHandler() handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT)) logging.getLogger('subliminal').addHandler(handler) logging.getLogger('subliminal').setLevel(logging.DEBUG) # provider configs ctx.obj = {'provider_configs': {}} if addic7ed: ctx.obj['provider_configs']['addic7ed'] = {'username': addic7ed[0], 'password': addic7ed[1]} if legendastv: ctx.obj['provider_configs']['legendastv'] = {'username': legendastv[0], 'password': legendastv[1]} if opensubtitles: ctx.obj['provider_configs']['opensubtitles'] = {'username': opensubtitles[0], 'password': opensubtitles[1]}
def __init__(self): # create cache and config directories try: os.makedirs(dirs.user_cache_dir) except OSError as e: if not os.path.isdir(dirs.user_cache_dir): raise try: os.makedirs(dirs.user_config_dir) except OSError as e: if not os.path.isdir(dirs.user_config_dir): raise # open config file self.config = Config(os.path.join(dirs.user_config_dir, config_file)) self.config.read() # configure cache region.configure('dogpile.cache.dbm', expiration_time=timedelta(days=30), arguments={ 'filename': os.path.join(dirs.user_cache_dir, cache_file), 'lock_factory': MutexLock })
def initialize_db(): log.info("Initializing Subliminal cache...") region.configure('dogpile.cache.dbm', expiration_time=timedelta(days=30), arguments={ 'filename': 'cachefile.dbm', 'lock_factory': MutexLock })
def init_cache(): """ # init cache for subtitles database query and stuff. """ if not os.path.isfile('cachefile.dbm.db'): print("Create subtitles cache data") region.configure('dogpile.cache.dbm', arguments={'filename': 'cachefile.dbm'}, replace_existing_backend=True)
def download_subtitles(directory): name = 'dogpile.cache.dbm' cache_file = get_cache_file(name) region.configure('dogpile.cache.dbm', arguments={'filename': cache_file}) videos = scan_videos(directory) subtitles = download_best_subtitles(videos, {babelfish.Language('eng')}) for video in videos: save_subtitles(video, subtitles[video], single=True)
def download_subtitles(directory): if not directory: directory = os.getcwd() logger.info('Downloading subtitles for videos in {}'.format(directory)) backend = 'dogpile.cache.dbm' cache_file = u.get_cache_file('subliminal.cache') region.configure(backend, arguments={'filename': cache_file}) videos = scan_videos(directory) subtitles = download_best_subtitles(videos, {babelfish.Language('eng')}) for video in videos: save_subtitles(video, subtitles[video], single=True)
def init_cache(): cache_dir = 'cache' try: os.makedirs(cache_dir) except OSError: if not os.path.isdir(cache_dir): raise region.configure('dogpile.cache.dbm', expiration_time=timedelta(days=90), arguments={ 'filename': os.path.join(cache_dir, 'cachefile.dbm'), 'lock_factory': MutexLock })
def __init__(self): # create app directory try: os.makedirs(app_dir) except OSError: if not os.path.isdir(app_dir): raise # open config file self.config = Config(os.path.join(app_dir, config_file)) self.config.read() # configure cache region.configure('dogpile.cache.dbm', expiration_time=timedelta(days=30), arguments={'filename': os.path.join(app_dir, cache_file), 'lock_factory': MutexLock})
def search(path, languages): # configure the cache region.configure('dogpile.cache.dbm', arguments={'filename': 'cachefile.dbm'}) # scan for videos newer than 2 weeks and their existing subtitles in a folder videos = set(scan_videos(path, age=timedelta(weeks=2))) # download best subtitles subtitles = download_best_subtitles(videos, languages) # save them to disk, next to the video for v in videos: _logger.debug('Saving {} ...'.format(v)) save_subtitles(v, subtitles[v])
def run(self, scan_path, scan_age, languages, *args, **kwargs): if not os.path.isdir(scan_path): raise IOError('Path \'%s\' doesn\'t exist!' % scan_path) if not scan_age >= 1: raise ValueError('\'scan_age\' must by at least 1!') if not len(languages) >= 1: raise ValueError('\'languages\' list can\'t be empty!') __tree_dict = lambda: defaultdict(__tree_dict) result = __tree_dict() age = timedelta(weeks=scan_age) languages = set([Language(l) for l in languages]) scan_start = datetime.now() videos = [] ignored_videos = [] if not region.is_configured: region.configure('dogpile.cache.dbm', expiration_time=timedelta(days=30), arguments={'filename': 'subliminal.dbm', 'lock_factory': MutexLock}) # scan videos scanned_videos = scan_videos(scan_path, age=age) for video in scanned_videos: video.subtitle_languages |= set(search_external_subtitles(video.name).values()) if check_video(video, languages=languages, age=age, undefined=False): refine(video) if languages - video.subtitle_languages: videos.append(video) else: ignored_videos.append(video) else: ignored_videos.append(video) if videos: result['videos']['collected'] = [os.path.split(v.name)[1] for v in videos] if ignored_videos: result['videos']['ignored'] = [os.path.split(v.name)[1] for v in ignored_videos] scan_end = datetime.now() result['meta']['start'] = scan_start.isoformat() result['meta']['end'] = scan_end.isoformat() result['meta']['duration'] = str(scan_end - scan_start) return result
def main(argv, log_path='.\logs', config=None): if not os.path.isdir(log_path): os.makedirs(log_path) logging.basicConfig(handlers=[RotatingFileHandler(os.path.join(log_path, 'substuff.log'), maxBytes=100000, backupCount=10)], level=logging.INFO, format="[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d] %(message)s", datefmt='%Y-%m-%dT%H:%M:%S') supported_extensions = ['.mkv', '.mp4', '.avi', '.mpg', '.mpeg'] if not argv: logging.error("Error, no directory supplied") sys.exit(1) if not os.path.isdir(argv[1]): sys.exit("Error, {f} is not a directory".format(f=argv[1])) global WDIR WDIR = argv[1] cache_dir = os.path.join(os.getenv('HOME'), '.subliminal') if not os.path.exists(cache_dir): os.makedirs(cache_dir) cache_file = os.path.join(cache_dir, 'subliminal.cachefile.dbm') # configure the cache region.configure('dogpile.cache.dbm', arguments={'filename': cache_file}, replace_existing_backend=True) file_list = [] for root, dirs, files in os.walk(WDIR): for name in files: (basename, ext) = os.path.splitext(name) if ext in supported_extensions: if ext == '.mkv': (raw_track_info, track_id) = get_mkv_track_id(os.path.join(root, name)) else: raw_track_info = None track_id = None srt_full_path = os.path.join(root, basename + ".srt") srt_exists = os.path.isfile(srt_full_path) file_list.append({'filename': name, 'basename': basename, 'extension': ext, 'dir': root, 'full_path': os.path.join(root, name), 'srt_track_id': track_id, 'srt_full_path': srt_full_path, 'srt_exists': srt_exists, 'raw_info': raw_track_info }) extract_subs(file_list, config)
def scanme(paths, config): logging.info('scanme: %s' % paths) # configure cache region.configure('dogpile.cache.dbm', expiration_time=timedelta(days=30), # @UndefinedVariable arguments={'filename': cachefile_file, 'lock_factory': MutexLock}) # scan videos #videos = scan_videos([p for p in paths if os.path.exists(p)],# subtitles=True, # embedded_subtitles=True, age=timedelta(days=config.get('Task').as_int('age'))) videos = scan_videos(paths, age=timedelta(days=config.get('Task').as_int('age'))) logging.info(videos) # guess videos videos.extend([Video.fromname(p) for p in paths if not os.path.exists(p)]) logging.info(videos) # download best subtitles languageset=set(Language(language) for language in config['General']['languages']) single=True if not config.get('General').as_bool('single') or len(languageset) > 1: single=False hearing_impaired=False if config.get('General').as_bool('hearing_impaired'): hearing_impaired=True providers = config['General']['providers'] rv = {} for provider in providers: sec = config.get(provider) if sec != None: rv[provider] = {k: v for k, v in config.get(provider).items()} subtitles = download_best_subtitles(videos, languageset, min_score=config.get('General').as_int('min_score'), providers=providers, provider_configs=rv, hearing_impaired=hearing_impaired, only_one=single) # save them to disk, next to the video for v in videos: save_subtitles(v, subtitles[v]) logging.debug(subtitles) logging.info('Scan Done!') return subtitles
def subliminal(ctx, addic7ed, cache_dir, debug): """Subtitles, faster than your thoughts.""" # create cache directory os.makedirs(cache_dir, exist_ok=True) # configure cache region.configure('dogpile.cache.dbm', expiration_time=timedelta(days=30), arguments={'filename': os.path.join(cache_dir, subliminal_cache), 'lock_factory': MutexLock}) # configure logging if debug: handler = logging.StreamHandler() handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT)) logging.getLogger('subliminal').addHandler(handler) logging.getLogger('subliminal').setLevel(logging.DEBUG) # provider configs ctx.obj = {'provider_configs': {}} if addic7ed: ctx.obj['provider_configs']['addic7ed'] = {'username': addic7ed[0], 'password': addic7ed[1]}
def download_subtitles(self=None): logger.msg("Searching for subtitles") from datetime import timedelta from babelfish import Language from subliminal import download_best_subtitles, region, save_subtitles, scan_videos config = Configuration() # configure the cache region.configure('dogpile.cache.dbm', arguments={'filename': 'cachefile.dbm'}) # scan for videos newer than 2 weeks and their existing subtitles in a folder videos = scan_videos(config.base_download_path, age=timedelta(days=1)) # download best subtitles subtitles = download_best_subtitles(videos, {Language('spa')}, only_one=True) # save them to disk, next to the video for v in videos: save_subtitles(v, subtitles[v], single=True)
def main(argv): supported_extensions = ['.mkv', '.mp4', '.avi', '.mpg', '.mpeg'] if not argv: print("Error, no directory supplied") sys.exit(1) if not os.path.isdir(argv[1]): sys.exit("Error, {f} is not a directory".format(f=argv[1])) global WDIR WDIR = argv[1] cache_dir = os.path.join(os.getenv('HOME'), '.subliminal') if not os.path.exists(cache_dir): os.makedirs(cache_dir) cache_file = os.path.join(cache_dir, 'subliminal.cachefile.dbm') # configure the cache region.configure('dogpile.cache.dbm', arguments={'filename': cache_file}) file_list = [] for root, dirs, files in os.walk(WDIR): for name in files: (basename, ext) = os.path.splitext(name) if ext in supported_extensions: if ext == '.mkv': (raw_track_info, track_id) = get_mkv_track_id(os.path.join(root, name)) else: raw_track_info = None track_id = None srt_full_path = os.path.join(root, basename + ".srt") srt_exists = os.path.isfile(srt_full_path) file_list.append({ 'filename': name, 'basename': basename, 'extension': ext, 'dir': root, 'full_path': os.path.join(root, name), 'srt_track_id': track_id, 'srt_full_path': srt_full_path, 'srt_exists': srt_exists, 'raw_info': raw_track_info }) extract_subs(file_list)
def main(argv): supported_extensions = ['.mkv', '.mp4', '.avi', '.mpg', '.mpeg'] if not argv: print("Error, no directory supplied") sys.exit(1) if not os.path.isdir(argv[1]): sys.exit("Error, {f} is not a directory".format(f=argv[1])) global WDIR WDIR = argv[1] cache_dir = os.path.join(os.getenv('HOME'), '.subliminal') if not os.path.exists(cache_dir): os.makedirs(cache_dir) cache_file = os.path.join(cache_dir, 'subliminal.cachefile.dbm') # configure the cache region.configure('dogpile.cache.dbm', arguments={'filename': cache_file}) file_list = [] for root, dirs, files in os.walk(WDIR): for name in files: (basename, ext) = os.path.splitext(name) if ext in supported_extensions: if ext == '.mkv': (raw_track_info, track_id) = get_mkv_track_id(os.path.join(root, name)) else: raw_track_info = None track_id = None srt_full_path = os.path.join(root, basename + ".srt") srt_exists = os.path.isfile(srt_full_path) file_list.append({'filename': name, 'basename': basename, 'extension': ext, 'dir': root, 'full_path': os.path.join(root, name), 'srt_track_id': track_id, 'srt_full_path': srt_full_path, 'srt_exists': srt_exists, 'raw_info': raw_track_info }) extract_subs(file_list)
def fetchsubs(): from datetime import timedelta from babelfish import Language from subliminal import download_best_subtitles, region, save_subtitles, scan_videos # configure the cache try: region.configure('dogpile.cache.dbm', arguments={'filename': '/tmp/cachefile.dbm'}) except IOError: region.configure('dogpile.cache.dbm', arguments={'filename': 'cachefile.dbm'}) # scan for videos newer than 2 weeks and their existing subtitles in a folder videos = scan_videos(env["incoming_location"], age=timedelta(days=14)) # download best subtitles subtitles = download_best_subtitles(videos, {Language('eng')}) # save them to disk, next to the video for v in videos: print('%s - sub found.' % v) save_subtitles(v, subtitles[v], single=True)
def main(): """ Main function """ file_path, download_subs, show_omdb_info = get_args() video_file = Video.fromname(file_path) # Display the short info short_info = short_details(video_file) print(short_info) # If -i flag is set show the info from the omdb api if show_omdb_info is True: spinner = Spinner() spinner.start() omdb_details(video_file.title, video_file.year) spinner.stop() # If -d flag is set download the best matching subtitles if download_subs is True: spinner = Spinner() spinner.start() # Set the cache region.configure('dogpile.cache.dbm', arguments={'filename': 'cachefile.dbm'}) # Download subtitles in serbian and english best_subtitles = download_best_subtitles([video_file], {Language('eng'),\ Language('srp')}, providers=None) spinner.stop() print(best_subtitles[video_file]) best_subtitle_sr = best_subtitles[video_file][0] best_subtitle_en = best_subtitles[video_file][1] # Save the 2 subtitle files save_subtitles(video_file, [best_subtitle_sr]) save_subtitles(video_file, [best_subtitle_en])
def downloadSub(myFile, lang, path, verbose): cli = False print "--- Trying to download..." origWD = os.getcwd() # current working directory os.chdir(path) # change working directory to where the videos are if cli == True: # old subliminal: #if call(["subliminal", "-q", "-l", lang, "--", myFile]): # try to download the subtitles # new subliminal if call(["subliminal", "download", "-l", lang, "--", myFile]): # try to download the subtitles print "*** Could not find %s subtitles" % langName(lang).lower() subDownloads = foundLang("%s - not found" % lang) else: print "--- Downloaded %s subtitles" % langName(lang).lower() subDownloads = foundLang(lang) # sending language code to be added # subName = "%s.%s.%s" % (os.path.splitext(myFile)[0], lang, "srt") else: video = Video.fromname(myFile) if verbose: print "--- Checking subtititles for \n %s" % video # configure the cache #region.configure('dogpile.cache.dbm', arguments={'filename': 'cachefile.dbm'}) my_region = region.configure('dogpile.cache.memory', arguments={'filename': 'cachefile.dbm'}, replace_existing_backend=True) if verbose: print "--- Searching for best subtitle..." #best_subtitles = download_best_subtitles([video], {lang}, providers=['podnapisi']) best_subtitles = download_best_subtitles([video], {lang}, providers=['podnapisi', 'opensubtitles', 'addic7ed']) #best_subtitles = download_best_subtitles([video], {lang}) try: best_subtitle = best_subtitles[video][0] except: print "*** Could not find %s subtitles" % langName(lang).lower() subDownloads = foundLang("%s - not found" % lang) else: print "--- Downloaded %s subtitles" % langName(lang).lower() #if verbose: # print "--- Score for this subtitle is %s" % compute_score(best_subtitle, video) subDownloads = foundLang(lang) # sending language code to be added if verbose: print "--- Saving subtitles..." save_subtitles(video, [best_subtitle]) os.chdir(origWD) # change working directory back return subDownloads
def __init__(self): GObject.threads_init() Gtk.Window.__init__(self) # Initial configuration self.set_resizable(False) self.set_title("Subliminal Minimal GUI") self.region = region.configure('dogpile.cache.memory') self.config = SafeConfigParser() # Widget creation and initial config notebook = Gtk.Notebook() self.single_sub_tab = SingleSubTab() self.add(notebook) notebook.append_page(self.single_sub_tab, Gtk.Label("Single Sub")) self.connect("delete-event", Gtk.main_quit) self.parse_default_config()
def init(): region.configure('dogpile.cache.dbm', arguments={'filename': 'cachefilesrt.dbm'})
x = 'n' while x != 'y': index = randint(0, countGS - 1) print("Launching " + str(stashnames[index])) findGenre(stashnames[index]) print("\n\n......Good enough? Y/N\n") x = str(getch(), 'utf-8') print( "\n=================================================================================\n" ) if x.lower() == 'y': if dlSub == True: print("\n\nGetting subtitles..Please Wait..\n\n") try: region.configure('dogpile.cache.dbm', arguments={'filename': 'cachefile.dbm'}) videos = Video.fromname(stash[index]) subtitles = download_best_subtitles([videos], {Language('eng')}) best_subtitle = subtitles[videos][0] save_subtitles(videos, [best_subtitle]) print("\nSubtitle downloaded.\n") except: print("\nCould not get subtitle :\\\n") os.startfile(stash[index]) elif x.lower() == 'n': print("Moving on...\n") else: print("\nWut? wut? i'll just assume it wasn't of your taste sire.\n")
def run(self, scan_path, scan_age, languages, encoding, min_score, providers, provider_configs, max_workers, plex_url=None, plex_token=None, *args, **kwargs): if not os.path.isdir(scan_path): raise IOError('Path \'%s\' doesn\'t exist!' % scan_path) if not scan_age >= 1: raise ValueError('\'scan_age\' must by at least 1!') if not len(languages) >= 1: raise ValueError('\'languages\' list can\'t be empty!') if not providers: raise ValueError('\'providers\' argument can\'t be empty!') if not max_workers >= 1: raise ValueError('\'max_workers\' must be at least 1!') if not provider_configs: provider_configs = {} __tree_dict = lambda: defaultdict(__tree_dict) result = __tree_dict() encoding = codecs.lookup(encoding).name age = timedelta(weeks=scan_age) languages = set([Language(l) for l in languages]) plex = None if plex_url and plex_token: plex = PlexServer(plex_url, plex_token) scan_start = datetime.now() videos = [] ignored_videos = [] if not region.is_configured: region.configure('dogpile.cache.dbm', expiration_time=timedelta(days=30), arguments={ 'filename': 'subliminal.dbm', 'lock_factory': MutexLock }) # scan videos scanned_videos = scan_videos(scan_path, age=age) for video in scanned_videos: video.subtitle_languages |= set( search_external_subtitles(video.name).values()) if check_video(video, languages=languages, age=age, undefined=False): refine(video) if languages - video.subtitle_languages: videos.append(video) else: ignored_videos.append(video) else: ignored_videos.append(video) if videos: result['videos']['collected'] = [ os.path.split(v.name)[1] for v in videos ] if ignored_videos: result['videos']['ignored'] = len(ignored_videos) if videos: # download best subtitles downloaded_subtitles = defaultdict(list) with AsyncProviderPool(max_workers=max_workers, providers=providers, provider_configs=provider_configs) as p: for video in videos: scores = get_scores(video) subtitles_to_download = p.list_subtitles( video, languages - video.subtitle_languages) downloaded_subtitles[video] = p.download_best_subtitles( subtitles_to_download, video, languages, min_score=scores['hash'] * min_score / 100) if p.discarded_providers: result['providers']['discarded'] = list( p.discarded_providers) # filter subtitles with TinyDB('subtitle_db.json') as db: table = db.table('downloaded') query = Query() for video, subtitles in downloaded_subtitles.items(): discarded_subtitles = list() discarded_subtitles_info = list() for s in subtitles: subtitle_hash = hashlib.sha256(s.content).hexdigest() subtitle_file = get_subtitle_path( os.path.split(video.name)[1], s.language) dbo = {'hash': subtitle_hash, 'file': subtitle_file} if table.search((query.hash == subtitle_hash) & (query.file == subtitle_file)): discarded_subtitles.append(s) discarded_subtitles_info.append(dbo) else: table.insert(dbo) downloaded_subtitles[video] = [ x for x in subtitles if x not in discarded_subtitles ] if discarded_subtitles_info: result['subtitles'][ 'discarded'] = result['subtitles'].get( 'discarded', []) + discarded_subtitles_info downloaded_subtitles = { k: v for k, v in downloaded_subtitles.items() if v } # save subtitles saved_subtitles = {} for video, subtitles in downloaded_subtitles.items(): saved_subtitles[video] = save_subtitles(video, subtitles, directory=None, encoding=encoding) for key, group in groupby(saved_subtitles[video], lambda x: x.provider_name): subtitle_filenames = [ get_subtitle_path( os.path.split(video.name)[1], s.language) for s in list(group) ] result['subtitles'][key] = result['subtitles'].get( key, []) + subtitle_filenames result['subtitles']['total'] = sum( len(v) for v in saved_subtitles.values()) # refresh plex for video, subtitles in saved_subtitles.items(): if plex and subtitles: item_found = False for section in plex.library.sections(): try: if isinstance(section, MovieSection) and isinstance( video, Movie): results = section.search(title=video.title, year=video.year, libtype='movie', sort='addedAt:desc', maxresults=1) if not results: raise NotFound plex_item = results[0] elif isinstance(section, ShowSection) and isinstance( video, Episode): results = section.search(title=video.series, year=video.year, libtype='show', sort='addedAt:desc', maxresults=1) if not results: raise NotFound plex_item = results[0].episode( season=video.season, episode=video.episode) else: continue except NotFound: continue except BadRequest: continue if plex_item: plex_item.refresh() result['plex']['refreshed'] = result['plex'].get( 'refreshed', []) + [ '%s%s' % (repr(plex_item.section()), repr(video)) ] item_found = True if not item_found: result['plex']['failed'] = result['plex'].get( 'failed', []) + [repr(video)] # convert subtitles for video, subtitles in saved_subtitles.items(): target_format = aeidon.formats.SUBRIP for s in subtitles: subtitle_path = get_subtitle_path(video.name, s.language) source_format = aeidon.util.detect_format( subtitle_path, encoding) source_file = aeidon.files.new( source_format, subtitle_path, aeidon.encodings.detect_bom(subtitle_path) or encoding) if source_format != target_format: format_info = { 'file': get_subtitle_path( os.path.split(video.name)[1], s.language), 'from': source_format.label, 'to': target_format.label } result['subtitles'][ 'converted'] = result['subtitles'].get( 'converted', []) + [format_info] aeidon_subtitles = source_file.read() for f in [ aeidon.formats.SUBRIP, aeidon.formats.MICRODVD, aeidon.formats.MPL2 ]: markup = aeidon.markups.new(f) for s in aeidon_subtitles: s.main_text = markup.decode(s.main_text) markup = aeidon.markups.new(target_format) for s in aeidon_subtitles: s.main_text = markup.encode(s.main_text) target_file = aeidon.files.new(target_format, subtitle_path, encoding) target_file.write(aeidon_subtitles, aeidon.documents.MAIN) scan_end = datetime.now() result['meta']['start'] = scan_start.isoformat() result['meta']['end'] = scan_end.isoformat() result['meta']['duration'] = str(scan_end - scan_start) return result
def __init__(self): GObject.threads_init() Gtk.Window.__init__(self) # Initial configuration self.set_resizable(False) self.set_title("Subliminal Minimal GUI") self.region = region.configure('dogpile.cache.memory') self.config = SafeConfigParser() # Widget creation and initial config notebook = Gtk.Notebook() grid = Gtk.Grid() frame = Gtk.Frame( label="Download a Single Subtitle" ) grid.set_column_spacing(10) grid.set_row_spacing(10) self.add( notebook ) frame.add( grid ) notebook.append_page( frame, Gtk.Label("Single Sub") ) self.movie_entry = Gtk.Entry() open_movie = Gtk.Button( label = "Open Video" ) best_match = Gtk.Button ( label = "Download") language_label = Gtk.Label("Language") self.provider_combo = Gtk.ComboBoxText.new() video_label = Gtk.Label("Video File") provider_label = Gtk.Label("Provider") self.language_combo = Gtk.ComboBoxText.new_with_entry() self.progress_bar = Gtk.ProgressBar() separator = Gtk.Separator() self.status_bar = Gtk.Statusbar() self.context_id = self.status_bar.get_context_id("stat") self.status_bar.push(self.context_id, "Ready.") # Grid placement grid.attach(video_label, 0, 0, 5, 1) grid.attach(self.movie_entry, 0, 1, 2, 1) grid.attach(open_movie, 2, 1, 2, 1) grid.attach(language_label, 0, 2, 1, 1) grid.attach(self.language_combo, 0, 3, 2, 1) grid.attach(provider_label, 2, 2, 2, 1) grid.attach(self.provider_combo, 3, 3, 1, 1) grid.attach(best_match, 0, 6, 5, 1) grid.attach(self.progress_bar, 0, 5, 5, 1) grid.attach(separator, 0, 6, 5, 5) grid.attach(self.status_bar, 0, 7, 4, 4) # Margin config frame.set_margin_left(10) frame.set_margin_right(10) frame.set_margin_top(10) frame.set_margin_bottom(10) self.language_combo.set_margin_left(10) best_match.set_margin_bottom(10) best_match.set_margin_left(10) best_match.set_margin_right(10) self.movie_entry.set_margin_left(10) video_label.set_margin_top(10) self.status_bar.set_margin_top(10) # Connect events open_movie.connect( "clicked", self.open_file ) best_match.connect( "clicked", self.get_best_match ) self.connect("delete-event", Gtk.main_quit) self.parse_default_config()
PROVIDER_POOL_EXPIRATION_TIME = datetime.timedelta(minutes=15).total_seconds() VIDEO_EXPIRATION_TIME = datetime.timedelta(days=1).total_seconds() provider_manager.register('itasa = subliminal.providers.itasa:ItaSAProvider') provider_manager.register( 'napiprojekt = subliminal.providers.napiprojekt:NapiProjektProvider') basename = __name__.split('.')[0] refiner_manager.register( 'release = {basename}.refiners.release:refine'.format(basename=basename)) refiner_manager.register( 'tvepisode = {basename}.refiners.tvepisode:refine'.format( basename=basename)) region.configure('dogpile.cache.memory') video_key = u'{name}:video|{{video_path}}'.format(name=__name__) episode_refiners = ('metadata', 'release', 'tvepisode', 'tvdb', 'omdb') PROVIDER_URLS = { 'addic7ed': 'http://www.addic7ed.com', 'itasa': 'http://www.italiansubs.net', 'legendastv': 'http://www.legendas.tv', 'napiprojekt': 'http://www.napiprojekt.pl', 'opensubtitles': 'http://www.opensubtitles.org', 'podnapisi': 'http://www.podnapisi.net', 'shooter': 'http://www.shooter.cn', 'subscenter': 'http://www.subscenter.org', 'thesubdb': 'http://www.thesubdb.com', 'tvsubtitles': 'http://www.tvsubtitles.net'
class SubtitleFetcher(object): region.configure('dogpile.cache.dbm', arguments={'filename': f'{OUTPUT_PATH}/cachefile.dbm'}) """ Responsible for fetching the subtitle information including metadata from the open subtitles websites or from analyzed local files """ def __init__(self, video_obj, lang=babelfish.Language("eng")): """ Class constructor which receives as input a video object of a movie or TV series episode and the language of the video :param video_obj: video object that contains a movie's or TV series episode's details :param lang: the language of the video as babelfish object :return: None """ self._video_obj = video_obj self._lang = lang def load_video_obj(self): if isinstance(self._video_obj, types.GeneratorType): self._video_obj = next(self._video_obj) def fetch_subtitle(self, path): """ Fetch the subtitle using subliminal or from local file :param path: the file path to save the subtitle or to load the subtitle details from :return: :rtype: dict """ p = path + os.path.sep + self.get_video_string() + ".pkl" if not os.path.isfile(p) or not glob.glob( f"{path}/{self._video_obj.name}*.srt"): self.load_video_obj() logging.debug("Fetching %s's best matched subtitle" % self.get_video_string()) # This download the best subtitle as SRT file to the current directory try: subtitle = download_best_subtitles({self._video_obj}, {self._lang}, hearing_impaired=True) subtitle = subtitle[self._video_obj] except GuessitException: subtitle = [] if not subtitle: raise SubtitleNotFound save_subtitles(self._video_obj, subtitle, encoding='utf-8', directory=path) self._save_subtitle_info_dict(path) logging.debug("Loading %s metadata from %s" % (self.get_video_string(), p)) with open(p, "rb") as f: # os.chdir(owd) return pickle.load(f) # test if the subtitle object is loadable def _get_subtitle_srt_path(self, search_path): """ Trys to find video's subtitle in the search path :param search_path: path for searching the video's subtitle :return: path to the video's subtitles or None :rtype: str """ if self.is_episode: for p in os.listdir(search_path): for e in self.episode_details_strings(): if e.lower() in p.lower() and ".srt" in p.lower(): return search_path + os.path.sep + p elif self.is_movie: movie_name = self._video_obj.name.lower() for p in os.listdir(search_path): if movie_name in p.lower() and ".srt" in p.lower(): return search_path + os.path.sep + p return None def _save_subtitle_info_dict(self, path): """ save subtitle's metadata as a dict object to a file using pickle :param path: the path to save the subtitle's metadata dict using cPcikle """ p = path + os.path.sep + self.get_video_string() + ".pkl" roles_path = path + os.path.sep + self.get_video_string() + "roles.pkl" try: d = { VIDEO_NAME: self._video_obj.name, IMDB_ID: self._video_obj.imdb_id, SUBTITLE_PATH: self._get_subtitle_srt_path(path), ROLES_PATH: roles_path } except AttributeError: d = { VIDEO_NAME: self._video_obj.name, IMDB_ID: self._video_obj.series_imdb_id, SUBTITLE_PATH: self._get_subtitle_srt_path(path), ROLES_PATH: roles_path } logging.debug(f"Saving {self.get_video_string()}'s metadata to {p}") with open(p, "wb") as f: pickle.dump(d, f) def get_video_string(self): """ Return the video's representing name name :return: string with the video's representing name :rtype: str """ if self.is_episode: return f"{self._video_obj.series} {self.episode_details_strings()[1]}" if self.is_movie: return self._video_obj.name raise Exception("Unsupported video type") def episode_details_strings(self): """ In many case the downloaded subtitle file may contain various versions of the episodes season's & episode's names. This function return a list with most common episode's & season's name :return: list of strings with the most common season & episode names :rtype: list of [str] """ episode_name_list = [] if self.is_episode: episode_name_list.append( f"S0{self._video_obj.season}E0{self._video_obj.episode}") episode_name_list.append( f"S{self._video_obj.season}E{self._video_obj.episode}") e = "" if self._video_obj.season < 10: e += f"S0{self._video_obj.season}" else: e += f"S{self._video_obj.season}" if self._video_obj.episode < 10: e += f"E0{self._video_obj.episode}" else: e += f"E{self._video_obj.episode}" episode_name_list.append(e) e = f"S0{self._video_obj.season}" if self._video_obj.episode < 10: e += f"E0{self._video_obj.episode}" else: e += f"E{self._video_obj.episode}" episode_name_list.append(e) return episode_name_list @property def is_episode(self): """ Is video TV series episode? :return: True if the video is TV series episode or False otherwise :rtype: bool """ return type(self._video_obj) is video.Episode @property def is_movie(self): """ Is movie object? :return: True if the video is a movie or false otherwise :rtype: bool """ return type(self._video_obj) is video.Movie @staticmethod def get_episode_obj(video_name, series, season_num, episode_num, episode_name, imdb_id): """ Returns a subliminal TV episode object according to the episode's details :param imdb_id: :param video_name: the episode name, which usually consists of the series name and episode details :param series: the episode's series name :param season_num: the episode's season number :param episode_num: the episode number :param episode_name: the episode title :return: video.Episode object :rtype: video.Episode """ logging.info( "Fetching Subtitle Series:%s | Season: %s | Episode Number: %s | Name: %s" % (series, season_num, episode_num, episode_name)) return video.Episode(video_name, series, season_num, episode_num, title=episode_name, series_imdb_id=imdb_id)
def _prepare_subliminal(self): if not os.path.exists(ExtractSubs.SUBLIMINAL_CACHE_DIR): os.makedirs(ExtractSubs.SUBLIMINAL_CACHE_DIR) cache_file = os.path.join(ExtractSubs.SUBLIMINAL_CACHE_DIR, 'subliminal.cachefile.dbm') # configure the cache region.configure('dogpile.cache.dbm', arguments={'filename': cache_file})
from sickrage.show.Show import Show from . import db, history, processTV from .helpers import isMediaFile, isRarFile, remove_non_release_groups logger = logging.getLogger(__name__) PROVIDER_POOL_EXPIRATION_TIME = datetime.timedelta(minutes=15).total_seconds() VIDEO_EXPIRATION_TIME = datetime.timedelta(days=1).total_seconds() provider_manager.register('itasa = subliminal.providers.itasa:ItaSAProvider') provider_manager.register('napiprojekt = subliminal.providers.napiprojekt:NapiProjektProvider') refiner_manager.register('release = sickbeard.refiners.release:refine') region.configure('dogpile.cache.memory') video_key = u'{name}:video|{{video_path}}'.format(name=__name__) episode_refiners = ('metadata', 'release', 'tvdb', 'omdb') PROVIDER_URLS = { 'addic7ed': 'http://www.addic7ed.com', 'itasa': 'http://www.italiansubs.net', 'legendastv': 'http://www.legendas.tv', 'napiprojekt': 'http://www.napiprojekt.pl', 'opensubtitles': 'http://www.opensubtitles.org', 'podnapisi': 'http://www.podnapisi.net', 'shooter': 'http://www.shooter.cn', 'subscenter': 'http://www.subscenter.org', 'thesubdb': 'http://www.thesubdb.com', 'tvsubtitles': 'http://www.tvsubtitles.net'
from wtforms import StringField, SubmitField, SelectField, FileField from wtforms.validators import Required import time # time-test from werkzeug import secure_filename from babelfish import Language from subliminal import (download_best_subtitles, list_subtitles, compute_score, region, download_subtitles, Video, Movie, Episode, Subtitle) import unittest import coverage # # CONFIGURATION # basedir = os.path.abspath(os.path.dirname(__file__)) MY_REGION = region.configure('dogpile.cache.memory') app = Flask(__name__) app.config['SECRET_KEY'] = 'shshezyyzuz£é123jsh' manager = Manager(app) bootstrap = Bootstrap(app) moment = Moment(app) # # TEST AND TEST COVERAGE # @manager.command def test(): """Runs the unit tests without coverage."""