Exemple #1
0
 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'))
Exemple #2
0
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]}
Exemple #3
0
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]}
Exemple #4
0
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
                         })
Exemple #6
0
 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
                      })
Exemple #7
0
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)
Exemple #8
0
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)
Exemple #9
0
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)
Exemple #10
0
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})
Exemple #12
0
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
Exemple #14
0
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)
Exemple #15
0
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
Exemple #16
0
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]}
Exemple #17
0
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)
Exemple #18
0
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)
Exemple #19
0
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)
Exemple #20
0
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])
Exemple #22
0
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
Exemple #23
0
    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()
Exemple #24
0
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()
Exemple #28
0
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'
Exemple #29
0
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)
Exemple #30
0
 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})
Exemple #31
0
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'
Exemple #32
0
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."""