def run(self): subdl = periscope.Periscope() print "prefered languages: %s" % subdl.preferedLanguages for filename in self.filenames: subtitle = subdl.downloadSubtitle(filename, subdl.preferedLanguages) if subtitle: self.found.append(subtitle) else: self.notfound.append({"filename": filename}) self.callback(self.found, self.notfound)
def on_task_output(self, task, config): """ Configuration:: periscope: languages: List of languages in order of preference (at least one is required). alternatives: List of second-choice languages; subs will be downloaded but entries rejected. overwrite: If yes it will try to download even for videos that are already subbed. Default: no. subexts: List of subtitles file extensions to check (only useful with overwrite=no). Default: srt, stp, sub, stl, ssa. """ if not task.accepted: log.debug('nothing accepted, aborting') return import periscope psc = periscope.Periscope(tempfile.gettempdir()) logging.getLogger('periscope').setLevel( logging.CRITICAL) # LOT of messages otherwise langs = [s.encode('utf8') for s in config['languages']] # avoid unicode warnings alts = [s.encode('utf8') for s in config.get('alternatives', [])] if not config['overwrite']: self.exts = ['.' + s for s in config['subexts']] for entry in task.accepted: if 'location' not in entry: log.warning( 'Cannot act on entries that do not represent a local file.' ) elif not os.path.exists(entry['location']): entry.fail('file not found: %s' % entry['location']) elif '$RECYCLE.BIN' in entry['location']: continue # ignore deleted files in Windows shares elif not config['overwrite'] and self.subbed(entry['location']): log.warning('cannot overwrite existing subs for %s' % entry['location']) else: try: if psc.downloadSubtitle(entry['location'].encode("utf8"), langs): log.info('Subtitles found for %s' % entry['location']) elif alts and psc.downloadSubtitle( entry['location'].encode('utf8'), alts): entry.fail( 'subtitles found for a second-choice language.') else: entry.fail('cannot find any subtitles for now.') except Exception as err: # don't want to abort the entire task for errors in a # single video file or for occasional network timeouts entry.fail(err.message)
def run(self): subdl = periscope.Periscope(self.cache_folder) print "prefered languages: %s" % subdl.preferedLanguages for filename in self.filenames: subtitle = subdl.downloadSubtitle(filename, subdl.preferedLanguages) if subtitle: del subtitle[ "plugin"] # multiprocessing Queue won't be able to pickle this and will bark self.found.append(subtitle) else: self.notfound.append({"filename": filename}) self.queue.put([self.found, self.notfound]) self.queue.close( ) # we won't have anything more to transmit to the parent process
def runTests(self, tests): total = {} correct = {} for subdata in tests: video = datafile(subdata['video']) lang = subdata['language'] subfile = subdata['result'] plugins = subdata['plugins'] for plugin in plugins: total[plugin] = total.get(plugin, 0) + 1 log.debug('Searching for sub for: ' + video + ' with plugin ' + plugin) subdl = periscope.Periscope() subdl.pluginNames = [plugin] subs = subdl.listSubtitles(video, [lang]) if not subs: log.warning('Could not find any sub for: ' + video + ' with plugin ' + plugin) continue for sub in subs: log.debug( "Found a sub from %s in language %s, downloadable from %s" % (sub['plugin'], sub['lang'], sub['link'])) sub = subdl.attemptDownloadSubtitleText(subs, [lang]) if sub: result = sub["subtitletext"] else: log.warning('Could not complete download for sub for: ' + video + ' with plugin ' + plugin) continue #self.assert_(self.subtitlesEqual(result, open(datafile(subfile)).read())) if self.subtitlesEqual(result, open(datafile(subfile)).read()): correct[plugin] = correct.get(plugin, 0) + 1 print '---- Summary ----' for plugin, ntests in total.items(): print 'Plugin %s found %d subs out of %d' % ( plugin, correct.get(plugin, 0), ntests)
def __init__(self, options, log=None): """Constructor for Perisope daemon """ self.config = ConfigParser.SafeConfigParser() self.supported_formats = 'video/x-msvideo', 'video/quicktime', 'video/x-matroska', 'video/mp4' self.options = options self.init_logger() self.log = self.getLogger(log) self.check_config( ) # Will raise an exception if cannot reach the configs file self.config.read(self.config_file()) self.log.debug("Cache folder : '%s'" % (self.get_cache_folder())) self.p = periscope.Periscope(self.get_cache_folder()) self.read_config() self.db = self.init_db() mimetypes.add_type("video/x-matroska", ".mkv")
def main(): '''Download subtitles''' # parse command line options parser = OptionParser("usage: %prog [options] file1 file2", version=periscope.VERSION) parser.add_option( "-l", "--language", action="append", dest="langs", help= "wanted language (ISO 639-1 two chars) for the subtitles (fr, en, ja, ...). If none is specified will download a subtitle in any language. This option can be used multiple times like %prog -l fr -l en file1 will try to download in french and then in english if no french subtitles are found." ) parser.add_option( "-f", "--force", action="store_true", dest="force_download", help="force download of a subtitle even there is already one present") parser.add_option("-q", "--query", action="append", dest="queries", help="query to send to the subtitles website") parser.add_option( "--cache-folder", action="store", type="string", dest="cache_folder", help= "location of the periscope cache/config folder (default is ~/.config/periscope)" ) parser.add_option("--list-plugins", action="store_true", dest="show_plugins", help="list all plugins supported by periscope") parser.add_option( "--list-active-plugins", action="store_true", dest="show_active_plugins", help= "list all plugins used to search subtitles (a subset of all the supported plugins)" ) parser.add_option( "--quiet", action="store_true", dest="quiet", help="run in quiet mode (only show warn and error messages)") parser.add_option("--debug", action="store_true", dest="debug", help="set the logging level to debug") (options, args) = parser.parse_args() if not args: print parser.print_help() exit() # process args if options.debug: logging.basicConfig(level=logging.DEBUG) elif options.quiet: logging.basicConfig(level=logging.WARN) else: logging.basicConfig(level=logging.INFO) if not options.cache_folder: try: import xdg.BaseDirectory as bd options.cache_folder = os.path.join(bd.xdg_config_home, "periscope") except: home = os.path.expanduser("~") if home == "~": log.error( "Could not generate a cache folder at the home location using XDG (freedesktop). You must specify a --cache-config folder where the cache and config will be located (always use the same folder)." ) exit() options.cache_folder = os.path.join(home, ".config", "periscope") periscope_client = periscope.Periscope(options.cache_folder) if options.show_active_plugins: print "Active plugins: " plugins = periscope_client.listActivePlugins() for plugin in plugins: print "%s" % (plugin) exit() if options.show_plugins: print "All plugins: " plugins = periscope_client.listExistingPlugins() for plugin in plugins: print "%s" % (plugin) exit() if options.queries: args += options.queries videos = [] for arg in args: videos += recursive_search(arg, options) subs = [] for arg in videos: if not options.langs: #Look into the config log.info("No lang given, looking into config file") langs = periscope_client.preferedLanguages else: langs = options.langs sub = periscope_client.downloadSubtitle(arg, langs) if sub: subs.append(sub) log.info("*" * 50) log.info("Downloaded %s subtitles" % len(subs)) for s in subs: log.info(s['lang'] + " - " + s['subtitlepath']) log.info("*" * 50) if len(subs) == 0: exit(1)