Пример #1
0
def get_video(video_path, subtitles_path=None):
    if not subtitles_path:
        subtitles_path = get_subtitles_path(video_path)

    try:
        # Encode paths to UTF-8 to ensure subliminal support.
        video_path = video_path.encode('utf-8')
        subtitles_path = subtitles_path.encode('utf-8')
    except UnicodeEncodeError:
        # Fallback to system encoding. This should never happen.
        video_path = video_path.encode(sickbeard.SYS_ENCODING)
        subtitles_path = subtitles_path.encode(sickbeard.SYS_ENCODING)

    try:
        if not sickbeard.EMBEDDED_SUBTITLES_ALL and video_path.endswith('.mkv'):
            video = subliminal.scan_video(video_path, subtitles=True, embedded_subtitles=True,
                                          subtitles_dir=subtitles_path)
        else:
            video = subliminal.scan_video(video_path, subtitles=True, embedded_subtitles=False,
                                          subtitles_dir=subtitles_path)
    except Exception as error:
        logger.log(u'Exception: {}'.format(error), logger.DEBUG)
        return None

    return video
Пример #2
0
def get_video(video_path, subtitles_path=None):
    if not subtitles_path:
        try:
            subtitles_path = get_subtitles_path(video_path).encode(
                sickbeard.SYS_ENCODING)
        except UnicodeEncodeError as error:
            logger.log(
                u'An error occurred while encoding \'{}\' with your current locale. '
                'Rename the file or try a different locale. Error: {}'.format(
                    video_path, ex(error)), logger.WARNING)
            return None

    try:
        if not sickbeard.EMBEDDED_SUBTITLES_ALL and video_path.endswith(
                '.mkv'):
            video = subliminal.scan_video(video_path,
                                          subtitles=True,
                                          embedded_subtitles=True,
                                          subtitles_dir=subtitles_path)
        else:
            video = subliminal.scan_video(video_path,
                                          subtitles=True,
                                          embedded_subtitles=False,
                                          subtitles_dir=subtitles_path)
    except Exception:
        return None

    return video
Пример #3
0
def get_video(video_path, subtitles_path=None):
    if not subtitles_path:
        subtitles_path = get_subtitles_path(video_path).encode(sickbeard.SYS_ENCODING)

    try:
        if not sickbeard.EMBEDDED_SUBTITLES_ALL and video_path.endswith('.mkv'):
            video = subliminal.scan_video(video_path, subtitles=True, embedded_subtitles=True,
                                          subtitles_dir=subtitles_path)
        else:
            video = subliminal.scan_video(video_path, subtitles=True, embedded_subtitles=False,
                                          subtitles_dir=subtitles_path)
    except Exception:
        return None

    return video
Пример #4
0
def import_subs(filename):
    if not core.GETSUBS:
        return
    try:
        subliminal.region.configure('dogpile.cache.dbm',
                                    arguments={'filename': 'cachefile.dbm'})
    except Exception:
        pass

    languages = set()
    for item in core.SLANGUAGES:
        try:
            languages.add(Language(item))
        except Exception:
            pass
    if not languages:
        return

    logger.info('Attempting to download subtitles for {0}'.format(filename),
                'SUBTITLES')
    try:
        video = subliminal.scan_video(filename)
        subtitles = subliminal.download_best_subtitles({video}, languages)
        subliminal.save_subtitles(video, subtitles[video])

        for subtitle in subtitles[video]:
            subtitle_path = subliminal.subtitle.get_subtitle_path(
                video.name, subtitle.language)
            os.chmod(subtitle_path, 0o644)
    except Exception as e:
        logger.error(
            'Failed to download subtitles for {0} due to: {1}'.format(
                filename, e), 'SUBTITLES')
Пример #5
0
    def on_created(event):
        if event.is_directory:
            return

        path = event.src_path

        if not mimetypes.guess_type(path)[0].startswith('video'):
            return

        try:
            logging.info(f"Pulling subtitles for: {path}")
            video = scan_video(path)
            provider_pool = ProviderPool(
                providers=ENABLED_PROVIDERS,
                provider_configs=PROVIDER_CONFIGURATIONS)
            subtitles = provider_pool.list_subtitles(
                video=video, languages={Language('eng'),
                                        Language('nld')})
            best_subtitles = provider_pool.download_best_subtitles(
                subtitles=subtitles,
                video=video,
                languages={Language('eng'), Language('nld')})
            save_subtitles(video, best_subtitles)
            logging.info(f"Subtitles saved for: {path}")
        except Exception as e:
            logging.error(f"Error: {repr(e)}")
Пример #6
0
def download_subtitles():
    """Download subtitles"""
    if request.json:
        mydata = request.json
        if not 'path' in mydata:  # check if empty
            log(NO_PATH_PROVIDED)
            return error(NO_PATH_PROVIDED, 406)

        # check if languages is empty, if so use english
        if not 'languages' in mydata or not mydata['languages']:
            mydata['languages'] = "eng"

        log(json.dumps(mydata))
        path = mydata['path']
        videos = []
        try:
            videos.append(scan_video(path))
            subtitles = download_best_subtitles(
                videos, parse_languages(mydata['languages']))
            for video in videos:
                save_subtitles(video, subtitles[video])

            return json.dumps(mydata)
        except Exception:
            log(NO_SUBTITLES_FOUND)
            return error(NO_SUBTITLES_FOUND, 404)
    else:
        log(NO_DATA_RECEIVED)
        return error(NO_DATA_RECEIVED, 406)
Пример #7
0
def get_video(video_path, subtitles_path=None, subtitles=True, embedded_subtitles=None):
    if not subtitles_path:
        subtitles_path = get_subtitles_path(video_path)

    try:
        # Encode paths to UTF-8 to ensure subliminal support.
        video_path = video_path.encode('utf-8')
        subtitles_path = subtitles_path.encode('utf-8')
    except UnicodeEncodeError:
        # Fallback to system encoding. This should never happen.
        video_path = video_path.encode(sickbeard.SYS_ENCODING)
        subtitles_path = subtitles_path.encode(sickbeard.SYS_ENCODING)

    try:
        video = subliminal.scan_video(video_path)

        # external subtitles
        if subtitles:
            video.subtitle_languages |= \
                set(subliminal.core.search_external_subtitles(video_path, directory=subtitles_path).values())

        if embedded_subtitles is None:
            embedded_subtitles = bool(not sickbeard.EMBEDDED_SUBTITLES_ALL and video_path.endswith('.mkv'))

        subliminal.refine(video, embedded_subtitles=embedded_subtitles)
    except Exception as error:
        logger.log(u'Exception: {0}'.format(error), logger.DEBUG)
        return None

    return video
Пример #8
0
def subtitlesLanguages(video_path):
    """Return a list detected subtitles for the given video file"""
    resultList = []

    # Serch for embedded subtitles
    embedded_languages = subliminal.scan_video(video_path, subtitles=False, embedded_subtitles=not sickbeard.EMBEDDED_SUBTITLES_ALL)

    # Search subtitles in the absolute path
    if sickbeard.SUBTITLES_DIR and ek(os.path.exists, sickbeard.SUBTITLES_DIR):
        video_path = ek(os.path.join, sickbeard.SUBTITLES_DIR, ek(os.path.basename, video_path))
    # Search subtitles in the relative path
    elif sickbeard.SUBTITLES_DIR:
        video_path = ek(os.path.join, ek(os.path.dirname, video_path), sickbeard.SUBTITLES_DIR, ek(os.path.basename, video_path))

    languages = subliminal.video.scan_subtitle_languages(video_path)

    for language in languages.union(embedded_languages.subtitle_languages):
        if hasattr(language, 'opensubtitles') and language.opensubtitles:
            resultList.append(language.opensubtitles)
        elif hasattr(language, 'alpha3') and language.alpha3:
            resultList.append(language.alpha3)
        elif hasattr(language, 'alpha2') and language.alpha2:
            resultList.append(language.alpha2)

    defaultLang = wantedLanguages()

    if ('pob' in defaultLang or 'pb' in defaultLang) and ('pt' not in defaultLang and 'por' not in defaultLang):
            resultList = [x if not x in ['por', 'pt'] else u'pob' for x in resultList]

    return sorted(resultList)
Пример #9
0
def match_episodes(episodes, show_list):
    """Match episodes using subliminal."""
    episode_matching = {'matched': [],
                        'notmatched': []}
    for episode_path in episodes:
        try:
            episode = subliminal.scan_video(episode_path)
        except ValueError:
            tv_data = re_tv.match(os.path.basename(episode_path))
            episode = None
            if tv_data:
                episode = subliminal.video.Episode(episode_path,
                                                   tv_data.group(1).replace(".", " "),
                                                   tv_data.group(2),
                                                   tv_data.group(3))
        if not episode:
            episode_matching['notmatched'].append((episode_path, 'id'))
            continue
        series = None
        for show in show_list:
            if isinstance(episode, subliminal.Movie):
                # It's a show detected as a movie
                episod = EpisodePlaceholder()
                episod.series = episode.title
                episod.season = 1
                episod.name = episode.name
                episode = episod
            if show.lower() == SHOW_CONVERSIONS.get(episode.series, episode.series.lower()):
                series = show
                episode.series = show
        if not series:
            episode_matching['notmatched'].append((episode_path, 'showlist'))
            continue
        episode_matching['matched'].append(episode)
    return episode_matching['matched'], episode_matching['notmatched']
Пример #10
0
def downloadSubtitles(subtitles_info):
    existing_subtitles = subtitles_info[b'subtitles']
    # First of all, check if we need subtitles
    languages = getNeededLanguages(existing_subtitles)
    if not languages:
        sickrage.LOGGER.debug('%s: No missing subtitles for S%02dE%02d' % (
            subtitles_info[b'show.indexerid'], subtitles_info[b'season'], subtitles_info[b'episode']))
        return existing_subtitles, None

    subtitles_path = getSubtitlesPath(subtitles_info[b'location']).encode(sickrage.SYS_ENCODING)
    video_path = subtitles_info[b'location'].encode(sickrage.SYS_ENCODING)
    providers = getEnabledServiceList()

    try:
        video = subliminal.scan_video(video_path, subtitles=False, embedded_subtitles=False)
    except Exception:
        sickrage.LOGGER.debug('%s: Exception caught in subliminal.scan_video for S%02dE%02d' %
                      (subtitles_info[b'show.indexerid'], subtitles_info[b'season'], subtitles_info[b'episode']))
        return existing_subtitles, None

    provider_configs = {'addic7ed': {'username': sickrage.ADDIC7ED_USER, 'password': sickrage.ADDIC7ED_PASS},
                        'legendastv': {'username': sickrage.LEGENDASTV_USER, 'password': sickrage.LEGENDASTV_PASS},
                        'opensubtitles': {'username': sickrage.OPENSUBTITLES_USER,
                                          'password': sickrage.OPENSUBTITLES_PASS}}

    pool = subliminal.api.ProviderPool(providers=providers, provider_configs=provider_configs)

    try:
        subtitles_list = pool.list_subtitles(video, languages)
        if not subtitles_list:
            sickrage.LOGGER.debug('%s: No subtitles found for S%02dE%02d on any provider' % (
                subtitles_info[b'show.indexerid'], subtitles_info[b'season'], subtitles_info[b'episode']))
            return existing_subtitles, None

        found_subtitles = pool.download_best_subtitles(subtitles_list, video, languages=languages,
                                                       hearing_impaired=sickrage.SUBTITLES_HEARING_IMPAIRED,
                                                       only_one=not sickrage.SUBTITLES_MULTI)

        save_subtitles(video, found_subtitles, directory=subtitles_path, single=not sickrage.SUBTITLES_MULTI)

        if not sickrage.EMBEDDED_SUBTITLES_ALL and sickrage.SUBTITLES_EXTRA_SCRIPTS and video_path.endswith(
                ('.mkv', '.mp4')):
            run_subs_extra_scripts(subtitles_info, found_subtitles, video, single=not sickrage.SUBTITLES_MULTI)

        current_subtitles = subtitlesLanguages(video_path)[0]
        new_subtitles = frozenset(current_subtitles).difference(existing_subtitles)

    except Exception:
        sickrage.LOGGER.info("Error occurred when downloading subtitles for: %s" % video_path)
        sickrage.LOGGER.error(traceback.format_exc())
        return existing_subtitles, None

    if sickrage.SUBTITLES_HISTORY:
        for subtitle in found_subtitles:
            sickrage.LOGGER.debug('history.logSubtitle %s, %s' % (subtitle.provider_name, subtitle.language.opensubtitles))
            History.logSubtitle(subtitles_info[b'show.indexerid'], subtitles_info[b'season'],
                                subtitles_info[b'episode'],
                                subtitles_info[b'status'], subtitle)

    return current_subtitles, new_subtitles
Пример #11
0
def get_video(video_path,
              subtitles_path=None,
              subtitles=True,
              embedded_subtitles=None,
              episode=None):
    if not subtitles_path:
        subtitles_path = get_subtitles_path(video_path)

    try:
        video = subliminal.scan_video(video_path)

        # external subtitles
        if subtitles:
            video.subtitle_languages |= \
                set(subliminal.core.search_external_subtitles(video_path, directory=subtitles_path).values())

        if embedded_subtitles is None:
            embedded_subtitles = bool(
                not sickrage.app.config.embedded_subtitles_all
                and video_path.endswith('.mkv'))

        # Let sickrage add more information to video file, based on the metadata.
        if episode:
            refine_video(video, episode)

        subliminal.refine(video, embedded_subtitles=embedded_subtitles)
    except Exception as error:
        sickrage.app.log.debug('Exception: {}'.format(error))
        return None

    # remove format metadata
    video.format = ""

    return video
Пример #12
0
def import_subs(filename):
    if not core.GETSUBS:
        return
    try:
        subliminal.cache_region.configure('dogpile.cache.memory')
    except:
        pass

    languages = set()
    for item in core.SLANGUAGES:
        try:
            languages.add(Language(item))
        except:
            pass
    if not languages:
        return

    logger.debug("Attempting to download subtitles for %s" % (filename),
                 'SUBTITLES')
    try:
        video = subliminal.scan_video(filename,
                                      subtitles=True,
                                      embedded_subtitles=True)
        subtitles = subliminal.download_best_subtitles([video],
                                                       languages,
                                                       hearing_impaired=False)
        subliminal.save_subtitles(subtitles)
    except Exception as e:
        logger.error(
            "Failed to download subtitles for %s due to: %s" % (filename, e),
            'SUBTITLES')
Пример #13
0
def import_subs(filename):
    if not core.GETSUBS:
        return
    try:
        subliminal.cache_region.configure('dogpile.cache.memory')
    except:
        pass   

    languages = set()
    for item in core.SLANGUAGES:
        try:
            languages.add(Language(item))
        except:
            pass
    if not languages:
        return

    logger.debug("Attempting to download subtitles for %s" %(filename), 'SUBTITLES')
    try:
        # subliminal.logger = subliminal.logging.getLogger('subliminal')
        # subliminal.logger.setLevel(subliminal.logging.DEBUG)
        # ch = subliminal.logging.StreamHandler()
        # ch.setLevel(subliminal.logging.DEBUG)
        # formatter = subliminal.logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        # ch.setFormatter(formatter)
        # subliminal.logger.addHandler(ch)

        video = subliminal.scan_video(filename, subtitles=True, embedded_subtitles=True)
        subtitles = subliminal.download_best_subtitles([video], languages, hearing_impaired=False)
        saved_subtitles = subliminal.save_subtitles(video, subtitles[video])
        logger.debug("Saved subtitles:%s" %(saved_subtitles), 'SUBTITLES')
    except Exception as e:
        logger.error("Failed to download subtitles for %s due to: %s" %(filename, e), 'SUBTITLES') 
Пример #14
0
def get_video(video_path,
              subtitles_path=None,
              subtitles=True,
              embedded_subtitles=None):
    if not subtitles_path:
        subtitles_path = get_subtitles_path(video_path)

    try:
        # Encode paths to UTF-8 to ensure subliminal support.
        video_path = video_path.encode('utf-8')
        subtitles_path = subtitles_path.encode('utf-8')
    except UnicodeEncodeError:
        # Fallback to system encoding. This should never happen.
        video_path = video_path.encode(sickbeard.SYS_ENCODING)
        subtitles_path = subtitles_path.encode(sickbeard.SYS_ENCODING)

    try:
        video = subliminal.scan_video(video_path)

        # external subtitles
        if subtitles:
            video.subtitle_languages |= \
                set(subliminal.core.search_external_subtitles(video_path, directory=subtitles_path).values())

        if embedded_subtitles is None:
            embedded_subtitles = bool(not sickbeard.EMBEDDED_SUBTITLES_ALL
                                      and video_path.endswith('.mkv'))

        subliminal.refine(video, embedded_subtitles=embedded_subtitles)
    except Exception as error:
        logger.log(u'Exception: {0}'.format(error), logger.DEBUG)
        return None

    return video
Пример #15
0
def get_video(video_path, subtitles_path=None, subtitles=True, embedded_subtitles=None, episode=None):
    if not subtitles_path:
        subtitles_path = get_subtitles_path(video_path)

    try:
        # Encode paths to UTF-8 to ensure subliminal support.
        video_path = video_path.encode('utf-8')
        subtitles_path = subtitles_path.encode('utf-8')
    except UnicodeEncodeError:
        # Fallback to system encoding. This should never happen.
        video_path = video_path.encode(sickrage.srCore.SYS_ENCODING)
        subtitles_path = subtitles_path.encode(sickrage.srCore.SYS_ENCODING)

    try:
        video = subliminal.scan_video(video_path)

        # external subtitles
        if subtitles:
            video.subtitle_languages |= \
                set(subliminal.core.search_external_subtitles(video_path, directory=subtitles_path).values())

        if embedded_subtitles is None:
            embedded_subtitles = bool(
                not sickrage.srCore.srConfig.EMBEDDED_SUBTITLES_ALL and video_path.endswith('.mkv'))

        # Let sickrage add more information to video file, based on the metadata.
        if episode:
            refine_video(video, episode)

        subliminal.refine(video, embedded_subtitles=embedded_subtitles)
    except Exception as error:
        sickrage.srCore.srLogger.debug('Exception: {}'.format(error))
        return None

    return video
Пример #16
0
def _scan_wanted_item_for_video(wanted_item, is_manual=False):
    video_path = wanted_item.videopath
    log.info('Scanning video')

    try:
        # Scan the video
        video = subliminal.scan_video(video_path)

        # Use our manual refiner only for manual search if enabled
        # Always keep this first because you may completely override the video with this!
        if is_manual and autosubliminal.MANUALREFINEVIDEO:
            refiners = ('manual',)  # don't remove the , -> needs to be a tuple
            subliminal.refine(video, episode_refiners=refiners, movie_refiners=refiners, wanted_item=wanted_item)

        # Use build-in refiners
        if autosubliminal.REFINEVIDEO:
            subliminal.refine(video)

        # Use our namemapping refiner (always enabled to enable our name mappings)
        # This should always be at the end since we want to enrich the result after the build-in refiners
        refiners = ('namemapping',)  # don't remove the , -> needs to be a tuple
        subliminal.refine(video, episode_refiners=refiners, movie_refiners=refiners)
    except Exception:
        log.exception('Error while scanning video, skipping %s', video_path)
        return

    # Add video to wanted item
    wanted_item.video = video

    return video
Пример #17
0
 def download(self, model):
     """Download subtitles using subliminal"""
     video = subliminal.scan_video(model.series_path)
     subtitles = subliminal.download_best_subtitles(
         {video}, {Language('eng')},
     )
     save_subtitles(subtitles, True, config.download_path)
Пример #18
0
 def test_scan_video_subtitles_languages(self):
     video = EPISODES[0]
     open(os.path.join(TEST_DIR, os.path.splitext(os.path.split(video.name)[1])[0]) + '.en.srt', 'w').close()
     open(os.path.join(TEST_DIR, os.path.splitext(os.path.split(video.name)[1])[0]) + '.fr.srt', 'w').close()
     open(os.path.join(TEST_DIR, os.path.splitext(os.path.split(video.name)[1])[0]) + '.srt', 'w').close()
     scanned_video = scan_video(os.path.join(TEST_DIR, os.path.split(video.name)[1]))
     self.assertEqual(scanned_video.subtitle_languages, {Language('eng'), Language('fra'), Language('und')})
Пример #19
0
    def get_subtitles(self, entry):
        if (
            entry.get('subtitles', eval_lazy=False)
            or not ('location' in entry)
            or ('$RECYCLE.BIN' in entry['location'])
            or not os.path.exists(entry['location'])
        ):
            return
        from subliminal import scan_video
        from subliminal.core import search_external_subtitles, refine

        try:
            video = scan_video(entry['location'])
            # grab external and internal subtitles
            subtitles = video.subtitle_languages
            refiner = ('metadata',)
            refine(video, episode_refiners=refiner, movie_refiners=refiner)
            subtitles |= set(search_external_subtitles(entry['location']).values())
            if subtitles:
                # convert to human-readable strings
                subtitles = [str(l) for l in subtitles]
                entry['subtitles'] = subtitles
                log.debug('Found subtitles %s for %s', '/'.join(subtitles), entry['title'])
        except Exception as e:
            log.error('Error checking local subtitles for %s: %s', entry['title'], e)
Пример #20
0
 def getSubtitle(self):
     if not "sub" in self.config or not os.path.isfile(self.config['sub']):
         self.config['sub'] = {}
         name = os.path.splitext(self.config['file']['name'])[0]
         file = os.path.join(self.config['file']['path'], name + ".srt")
         if os.path.isfile(file):
             print "found file. copying to temp"
             shutil.copy(file, self.config['temp']['path'])
             self.config['sub']['file'] = os.path.join(self.config['temp']['path'], name + ".srt")
             self.config['sub']['lang'] = self.config['language']['subtitle'][0]
         else:
             print "trying to download subtitle"
             file = self.config['file']['name']
             lang = self.config['language']['subtitle']
             languages = set();
             for l in lang:
                 languages.add(Language(l))
             print languages
             videoPath = os.path.join(self.config['temp']['path'], file)
             video = set([subliminal.scan_video(videoPath)])
             print video
             cache = self.config['temp']['path'] if "temp" in self.config else self.config['file']['path']
             sub = subliminal.download_best_subtitles(video, languages)
             print sub.items()
             if not sub.items():
                 self.config['sub'] = False
             for item in sub.items():
                 subLang = item[1][0].language.alpha3
                 self.config['sub'][subLang] = {}
                 self.config['sub'][subLang]['lang'] = subLang
                 self.config['sub'][subLang]['file'] = subliminal.subtitle.get_subtitle_path(videoPath, Language(subLang))
             
             print self.config['sub']
     return self.config['sub']
Пример #21
0
def get_video(video_path,
              subtitles_path=None,
              subtitles=True,
              embedded_subtitles=None,
              episode=None):
    if not subtitles_path:
        subtitles_path = get_subtitles_path(video_path)

    try:
        video = subliminal.scan_video(video_path)

        # external subtitles
        if subtitles:
            video.subtitle_languages |= set(
                subliminal.core.search_external_subtitles(
                    video_path, directory=subtitles_path).values())

        if embedded_subtitles is None:
            embedded_subtitles = bool(not settings.EMBEDDED_SUBTITLES_ALL
                                      and video_path.endswith(".mkv"))

        # Let sickchill add more information to video file, based on the metadata.
        if episode:
            refine_video(video, episode)

        subliminal.refine(video, embedded_subtitles=embedded_subtitles)
    except Exception as error:
        logger.info(traceback.format_exc())
        logger.debug("Exception: {0}".format(error))
        return None

    return video
Пример #22
0
    def get_subtitles(self, entry):
        if (entry.get('subtitles', eval_lazy=False)
                or not ('location' in entry)
                or ('$RECYCLE.BIN' in entry['location'])
                or not os.path.exists(entry['location'])):
            return
        from subliminal import scan_video
        from subliminal.core import search_external_subtitles, refine

        try:
            video = scan_video(entry['location'])
            # grab external and internal subtitles
            subtitles = video.subtitle_languages
            refiner = ('metadata', )
            refine(video, episode_refiners=refiner, movie_refiners=refiner)
            subtitles |= set(
                search_external_subtitles(entry['location']).values())
            if subtitles:
                # convert to human-readable strings
                subtitles = [str(l) for l in subtitles]
                entry['subtitles'] = subtitles
                log.debug('Found subtitles %s for %s', '/'.join(subtitles),
                          entry['title'])
        except Exception as e:
            log.error('Error checking local subtitles for %s: %s',
                      entry['title'], e)
Пример #23
0
    def get_video(self, video_path, subtitles_path=None, subtitles=True, embedded_subtitles=None, episode_object=None):
        if not subtitles_path:
            subtitles_path = self.get_subtitles_path(video_path)

        try:
            video = subliminal.scan_video(video_path)
        except Exception as error:
            sickrage.app.log.debug('Exception: {}'.format(error))
        else:
            if video.size > 10485760:
                video.hashes['itasa'] = hash_itasa(video_path)

            # external subtitles
            if subtitles:
                video.subtitle_languages |= set(subliminal.core.search_external_subtitles(video_path, directory=subtitles_path).values())

            if embedded_subtitles is None:
                embedded_subtitles = bool(
                    not sickrage.app.config.embedded_subtitles_all and video_path.endswith('.mkv'))

            subliminal.refine(video, episode_refiners=self.episode_refiners, embedded_subtitles=embedded_subtitles, release_name=episode_object.name,
                              tv_episode=episode_object)

            from sickrage.core.scene_exceptions import get_scene_exceptions
            video.alternative_series = list(get_scene_exceptions(episode_object.show.indexer_id))

            # remove format metadata
            video.format = ""

            return video
Пример #24
0
def get_video(video_path, subtitles_path=None, subtitles=True, embedded_subtitles=None, episode=None):
    if not subtitles_path:
        subtitles_path = get_subtitles_path(video_path)

    try:
        video = subliminal.scan_video(video_path)
    except Exception as error:
        sickrage.app.log.debug('Exception: {}'.format(error))
    else:
        if video.size > 10485760:
            video.hashes['itasa'] = hash_itasa(video_path)

        # external subtitles
        if subtitles:
            video.subtitle_languages |= \
                set(subliminal.core.search_external_subtitles(video_path, directory=subtitles_path).values())

        if embedded_subtitles is None:
            embedded_subtitles = bool(
                not sickrage.app.config.embedded_subtitles_all and video_path.endswith('.mkv'))

        subliminal.refine(video, episode_refiners=episode_refiners, embedded_subtitles=embedded_subtitles,
                          release_name=episode.name, tv_episode=episode)

        video.alternative_series = list(get_scene_exceptions(episode.show.indexerid))

        # remove format metadata
        video.format = ""

        return video
Пример #25
0
def getsrt(source, srcPath=watchPath):
    try:
        video = scan_video(source)
        videos = [video]
        logging.debug(prelog + 'getting subtitles')
        subtitles = download_best_subtitles(
            videos, {Language('eng'), Language('fra')},
            providers=None,
            provider_configs={
                'addic7ed': {
                    'username': '******',
                    'password': '******'
                },
                'opensubtitles': {
                    'username': '******',
                    'password': '******'
                }
            })
        sourceDir = os.path.dirname(source)
        savePath = sourceDir.replace(srcPath, srtPath)
        if not os.path.isdir(savePath):
            logging.debug(prelog + 'creating srt directory ' + savePath)
            os.makedirs(savePath)
        save_subtitles(video, subtitles[video], directory=savePath)
    except:
        logging.exception(prelog)
        pass
Пример #26
0
 def on_task_output(self, task, config):
     """
     Configuration::
         subliminal:
             languages: List of languages (3-letter ISO-639-3 code) in order of preference. At least one is required.
             alternatives: List of second-choice languages; subs will be downloaded but entries rejected.
             exact_match: Use file hash only to search for subs, otherwise Subliminal will try to guess by filename.
     """
     if not task.accepted:
         log.debug('nothing accepted, aborting')
         return
     from babelfish import Language
     from dogpile.cache.exception import RegionAlreadyConfigured
     import subliminal
     try:
         subliminal.cache_region.configure('dogpile.cache.dbm',
                                           arguments={
                                               'filename':
                                               os.path.join(
                                                   tempfile.gettempdir(),
                                                   'cachefile.dbm'),
                                               'lock_factory':
                                               subliminal.MutexLock
                                           })
     except RegionAlreadyConfigured:
         pass
     logging.getLogger("subliminal").setLevel(logging.CRITICAL)
     logging.getLogger("enzyme").setLevel(logging.WARNING)
     langs = set([Language(s) for s in config['languages']])
     alts = set([Language(s) for s in config.get('alternatives', [])])
     for entry in task.accepted:
         if not 'location' 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 not '$RECYCLE.BIN' in entry[
                 'location']:  # ignore deleted files in Windows shares
             try:
                 video = subliminal.scan_video(entry['location'])
                 msc = video.scores['hash'] if config['exact_match'] else 0
                 if langs & video.subtitle_languages:
                     continue  # subs for preferred lang(s) already exists
                 elif subliminal.download_best_subtitles([video],
                                                         langs,
                                                         min_score=msc):
                     log.info('Subtitles found for %s' % entry['location'])
                 elif alts and (alts - video.subtitle_languages) and \
                     subliminal.download_best_subtitles([video], alts, min_score=msc):
                     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
                 log.debug(err.message)
                 entry.fail(err.message)
    def choose_callback(self, menuitem, files):
        # scan the video
        video = scan_video(files[0].get_location().get_path())
        refine(video,
               episode_refiners=self.config.refiners,
               movie_refiners=self.config.refiners,
               embedded_subtitles=False)

        # load the interface
        builder = Gtk.Builder()
        builder.set_translation_domain('subliminal')
        builder.add_from_file(
            os.path.join(os.path.dirname(__file__), 'subliminal', 'ui',
                         'choose.glade'))

        # set the video filename
        video_filename = builder.get_object('video_filename_label')
        video_filename.set_text(files[0].get_name())

        # start the spinner
        spinner = builder.get_object('spinner')
        spinner.start()

        def _list_subtitles():
            # list subtitles
            with AsyncProviderPool(
                    providers=self.config.providers,
                    provider_configs=self.config.provider_configs) as pool:
                subtitles = pool.list_subtitles(video, self.config.languages)

            # fill the subtitle liststore
            subtitle_liststore = builder.get_object('subtitle_liststore')
            for s in subtitles:
                scaled_score = compute_score(s, video)
                scores = get_scores(video)
                if s.hearing_impaired == self.config.hearing_impaired:
                    scaled_score -= scores['hearing_impaired']
                scaled_score *= 100 / scores['hash']
                subtitle_liststore.append([
                    s.id,
                    nice_language(s.language), scaled_score,
                    s.provider_name.capitalize(), s.hearing_impaired,
                    s.page_link, False
                ])
            subtitle_liststore.set_sort_column_id(2, Gtk.SortType.DESCENDING)

            # stop the spinner
            spinner.stop()

            # connect signals
            builder.connect_signals(
                ChooseHandler(self.config, video, subtitles, spinner))

        threading.Thread(target=_list_subtitles).start()

        # display window
        window = builder.get_object('subtitle_window')
        window.show_all()
        Gtk.main()
Пример #28
0
def downloadSubtitles(subtitles_info):
    existing_subtitles = subtitles_info['subtitles']
    # First of all, check if we need subtitles
    languages = getNeededLanguages(existing_subtitles)
    if not languages:
        logger.log(u'%s: No missing subtitles for S%02dE%02d' % (subtitles_info['show.indexerid'], subtitles_info['season'], subtitles_info['episode']), logger.DEBUG)
        return (existing_subtitles, None)

    subtitles_path = getSubtitlesPath(subtitles_info['location']).encode(sickbeard.SYS_ENCODING)
    video_path = subtitles_info['location'].encode(sickbeard.SYS_ENCODING)
    providers = getEnabledServiceList()

    try:
        video = subliminal.scan_video(video_path, subtitles=False, embedded_subtitles=False)
    except Exception:
        logger.log(u'%s: Exception caught in subliminal.scan_video for S%02dE%02d' %
        (subtitles_info['show.indexerid'], subtitles_info['season'], subtitles_info['episode']), logger.DEBUG)
        return (existing_subtitles, None)

    try:
        # TODO: Add gui option for hearing_impaired parameter ?
        found_subtitles = subliminal.download_best_subtitles([video], languages=languages, hearing_impaired=False, only_one=not sickbeard.SUBTITLES_MULTI, providers=providers)
        if not found_subtitles:
            logger.log(u'%s: No subtitles found for S%02dE%02d on any provider' % (subtitles_info['show.indexerid'], subtitles_info['season'], subtitles_info['episode']), logger.DEBUG)
            return (existing_subtitles, None)

        for index, subtitle in enumerate(found_subtitles[video]):
            encoding = subliminal.subtitle.Subtitle.guess_encoding(subtitle)
            found_subtitles[video][index].encoding = encoding

        subliminal.save_subtitles(video, found_subtitles[video], directory=subtitles_path, single=not sickbeard.SUBTITLES_MULTI)

        for video, subtitles in found_subtitles.iteritems():
            for subtitle in subtitles:
                new_video_path = subtitles_path + "/" + video.name.rsplit("/", 1)[-1]
                new_subtitles_path = subliminal.subtitle.get_subtitle_path(new_video_path, subtitle.language if sickbeard.SUBTITLES_MULTI else None)
                sickbeard.helpers.chmodAsParent(new_subtitles_path)
                sickbeard.helpers.fixSetGroupID(new_subtitles_path)

        if not sickbeard.EMBEDDED_SUBTITLES_ALL and sickbeard.SUBTITLES_EXTRA_SCRIPTS and video_path.endswith(('.mkv','.mp4')):
            run_subs_extra_scripts(subtitles_info, found_subtitles)

        current_subtitles = subtitlesLanguages(video_path)[0]
        new_subtitles = frozenset(current_subtitles).difference(existing_subtitles)

    except Exception as e:
                logger.log("Error occurred when downloading subtitles for: %s" % video_path)
                logger.log(traceback.format_exc(), logger.ERROR)
                return (existing_subtitles, None)

    if sickbeard.SUBTITLES_HISTORY:
        for video, subtitles in found_subtitles.iteritems():
            for subtitle in subtitles:
                logger.log(u'history.logSubtitle %s, %s' % (subtitle.provider_name, subtitle.language.opensubtitles), logger.DEBUG)
                history.logSubtitle(subtitles_info['show.indexerid'], subtitles_info['season'], subtitles_info['episode'], subtitles_info['status'], subtitle)

    return (current_subtitles, new_subtitles)
Пример #29
0
def _get_video(filename):
  '''Return the subliminal.Video object from the given filename'''

  if os.path.exists(filename):
    logger.info('File `%s\' exists, parsing file contents', filename)
    return subliminal.scan_video(filename)
  else:
    logger.info('File `%s\' does not exist, parsing filename only', filename)
    return subliminal.Video.fromname(filename)
Пример #30
0
    def download_callback(self, menuitem, files):
        # scan videos
        videos = []
        for f in files:
            # ignore non-writable locations
            if not f.can_write():
                continue

            # directories
            if f.is_directory():
                try:
                    scanned_videos = scan_videos(
                        f.get_location().get_path(),
                        subtitles=True,
                        embedded_subtitles=self.config.embedded_subtitles)
                except:
                    continue
                for video in scanned_videos:
                    if check_video(video,
                                   languages=self.config.languages,
                                   age=self.config.age,
                                   undefined=self.config.single):
                        videos.append(video)
                continue

            # other inputs
            try:
                video = scan_video(
                    f.get_location().get_path(),
                    subtitles=True,
                    embedded_subtitles=self.config.embedded_subtitles)
            except:
                continue
            if check_video(video,
                           languages=self.config.languages,
                           undefined=self.config.single):
                videos.append(video)

        # download best subtitles
        downloaded_subtitles = defaultdict(list)
        with ProviderPool(
                providers=self.config.providers,
                provider_configs=self.config.provider_configs) as pool:
            for v in videos:
                subtitles = pool.download_best_subtitles(
                    pool.list_subtitles(
                        v, self.config.languages - v.subtitle_languages),
                    v,
                    self.config.languages,
                    min_score=v.scores['hash'] * self.config.min_score / 100,
                    hearing_impaired=self.config.hearing_impaired,
                    only_one=self.config.single)
                downloaded_subtitles[v] = subtitles

        # save subtitles
        for v, subtitles in downloaded_subtitles.items():
            save_subtitles(v, subtitles, single=self.config.single)
Пример #31
0
 def download_sub(self, language):
     l = Language(language)
     v = scan_video(self.path)
     sub_path = get_subtitle_path(v.name, l)
     if not os.path.isfile(sub_path):
         sub = download_best_subtitles((v,), {l})
         # TODO Save in tmp folder if regular is not available
         save_subtitles(sub)
     return sub_path
Пример #32
0
def get_video(tv_episode, video_path, subtitles_dir=None, subtitles=True, embedded_subtitles=None, release_name=None):
    """Return the subliminal video for the given path.

    The video_path is used as a key to cache the video to avoid
    scanning and parsing the video metadata all the time

    :param tv_episode:
    :type tv_episode: medusa.tv.Episode
    :param video_path: the video path
    :type video_path: str
    :param subtitles_dir: the subtitles directory
    :type subtitles_dir: str or None
    :param subtitles: True if existing external subtitles should be taken into account
    :type subtitles: bool or None
    :param embedded_subtitles: True if embedded subtitles should be taken into account
    :type embedded_subtitles: bool or None
    :param release_name: the release name
    :type release_name: str or None
    :return: video
    :rtype: subliminal.video.Video
    """
    key = video_key.format(video_path=video_path)
    payload = {'subtitles_dir': subtitles_dir, 'subtitles': subtitles, 'embedded_subtitles': embedded_subtitles,
               'release_name': release_name}
    cached_payload = memory_cache.get(key, expiration_time=VIDEO_EXPIRATION_TIME)
    if cached_payload != NO_VALUE and {k: v for k, v in iteritems(cached_payload) if k != 'video'} == payload:
        logger.debug(u'Found cached video information under key %s', key)
        return cached_payload['video']

    video_is_mkv = video_path.endswith('.mkv')
    subtitles_dir = subtitles_dir or get_subtitles_dir(video_path)

    logger.debug(u'Scanning video %s...', video_path)

    try:
        video = scan_video(video_path)
    except ValueError as error:
        logger.warning(u'Unable to scan video: %s. Error: %r', video_path, error)
    else:

        if subtitles:
            video.subtitle_languages |= set(search_external_subtitles(video_path, directory=subtitles_dir).values())

        if embedded_subtitles is None:
            embedded_subtitles = bool(not app.IGNORE_EMBEDDED_SUBS and video_is_mkv)

        refine(video, episode_refiners=episode_refiners, embedded_subtitles=embedded_subtitles,
               release_name=release_name, tv_episode=tv_episode)

        video.alternative_series = [alias.title for alias in tv_episode.series.aliases]

        payload['video'] = video
        memory_cache.set(key, payload)
        logger.debug(u'Video information cached under key %s', key)

        return video
Пример #33
0
 def test_scan_video_subtitles_language_eng(self):
     video = EPISODES[0]
     open(
         os.path.join(TEST_DIR,
                      os.path.splitext(os.path.split(video.name)[1])[0]) +
         '.en.srt', 'w').close()
     scanned_video = scan_video(
         os.path.join(TEST_DIR,
                      os.path.split(video.name)[1]))
     self.assertEqual(scanned_video.subtitle_languages, {Language('eng')})
Пример #34
0
def moveVideosAndSubtitles(sourceDirPath_, destDirPath_) :
	"""Move videos and subtitles (if exist)

	:param String sourceDirPath_
	:param String destDirPath_
	"""

	LOGGER.info('*** START MOVING VIDEOS AND SUBTITLES ***')
	
	if (os.path.isdir(sourceDirPath_)) :
		for dir, dirs, files in os.walk(sourceDirPath_) :
			localDir = dir[len(sourceDirPath_):]
			for fileName in files :
				fileExtension = os.path.splitext(fileName)[1]
				filePath = os.path.join(dir, fileName)

				if (fileExtension in VIDEO_EXTENSIONS) :
					# Scan video
					LOGGER.debug('Scanning video \'%s\'', filePath)
					video = subliminal.scan_video(filePath, False, True)
						
					# TEMP: if no embedded subtitles have been found, try to find associated sub files
					# This should be done in 'subliminal.scan_video', but... NO.
					# TODO: fork subliminal to fix the method 'scan_subtitle_languages'
					subFileLanguages = subtitles.scanSubtitleLanguages(filePath, SUB_EXTENSIONS)
					
					# If subs found, then move video
					hasSubFiles = babelfish.Language('eng') in subFileLanguages
					hasEmbeddedSub = babelfish.Language('eng') in video.subtitle_languages or babelfish.Language('und') in video.subtitle_languages
					if (hasEmbeddedSub or hasSubFiles) :
						fileTools.transferFile(filePath, sourceDirPath_, destDirPath_)
						
						# Embedded subtitles?
						if (hasEmbeddedSub) :
							LOGGER.debug('Embedded subtitles found for %s', video.name)
					
						# If subtitles files have been found, then move
						if (hasSubFiles) :
							LOGGER.debug('Subtitles files found for %s', video.name)
							# Move subtitles
							for otherFileName in files :
								otherFileExtension = os.path.splitext(otherFileName)[1]
								if (not otherFileName == fileName and otherFileExtension in SUB_EXTENSIONS) :
									# Test if the subtitles have the same name as the movie
									otherFileRoot = os.path.splitext(otherFileName)[0]
									fileRoot = os.path.splitext(fileName)[0]
									if (otherFileRoot[:len(fileRoot)] == fileRoot) :
										# Move subtitles
										otherFilePath = os.path.join(dir, otherFileName)
										fileTools.transferFile(otherFilePath, sourceDirPath_, destDirPath_)
					else :
						LOGGER.warning('No subtitles found, skipping video. (%s)', video.name)
				
	else :
		LOGGER.warning('\'%s\' does not refer to an existing path.', sourceDirPath_)
	def get_best_match(self, widget):
		# Open a thread to find a subtitle through get_best_subtitle
		try:
			self.video = scan_video( self.movie_entry.get_text() )
		except ValueError:
			self.status_bar.pop(self.context_id)
			self.status_bar.push(self.context_id, "Error. Did you choose a video file?")
			self.progress_bar.set_fraction(0)
			return False	
		x = Thread(target=self.get_best_subtitle)
		x.start()
Пример #36
0
def get_embedded_subtitles(video_path):
    """Return all embedded subtitles for the given video path.

    :param video_path: video filename to be checked
    :type video_path: str
    :return:
    :rtype: set of Language
    """
    subliminal_video = scan_video(video_path)
    refine(subliminal_video, episode_refiners=('metadata', ))
    return subliminal_video.subtitle_languages
Пример #37
0
def get_embedded_subtitles(video_path):
    """Return all embedded subtitles for the given video path.

    :param video_path: video filename to be checked
    :type video_path: str
    :return:
    :rtype: set of Language
    """
    subliminal_video = scan_video(video_path)
    refine(subliminal_video, episode_refiners=('metadata',))
    return subliminal_video.subtitle_languages
Пример #38
0
 def download_sub(self, lang='eng'):
     prov_conf = {'opensubtitles': {'username': '******', 'password': '******'}}
     logging.info("{}: Downloading subtitles...".format(self.filename))
     vid = scan_video(self.path)
     best_subs = download_best_subtitles({vid}, {babelfish.Language(lang)}, only_one=True, provider_configs=prov_conf)
     if best_subs[vid]:
         sub = best_subs[vid][0]
         save_subtitles(vid, [sub], single=True)
         logging.info("{}: Subtitles successfully downloaded.".format(self.filename))
     else:
         logging.error("{}: No subtitles found online.".format(self.filename))
Пример #39
0
def get_video(tv_episode, video_path, subtitles_dir=None, subtitles=True, embedded_subtitles=None, release_name=None):
    """Return the subliminal video for the given path.

    The video_path is used as a key to cache the video to avoid
    scanning and parsing the video metadata all the time

    :param tv_episode:
    :type tv_episode: sickbeard.tv.TVEpisode
    :param video_path: the video path
    :type video_path: str
    :param subtitles_dir: the subtitles directory
    :type subtitles_dir: str or None
    :param subtitles: True if existing external subtitles should be taken into account
    :type subtitles: bool or None
    :param embedded_subtitles: True if embedded subtitles should be taken into account
    :type embedded_subtitles: bool or None
    :param release_name: the release name
    :type release_name: str or None
    :return: video
    :rtype: subliminal.video.Video
    """
    key = video_key.format(video_path=video_path)
    payload = {'subtitles_dir': subtitles_dir, 'subtitles': subtitles, 'embedded_subtitles': embedded_subtitles,
               'release_name': release_name}
    cached_payload = region.get(key, expiration_time=VIDEO_EXPIRATION_TIME)
    if cached_payload != NO_VALUE and {k: v for k, v in iteritems(cached_payload) if k != 'video'} == payload:
        logger.debug(u'Found cached video information under key %s', key)
        return cached_payload['video']

    try:
        video_path = _encode(video_path)
        subtitles_dir = _encode(subtitles_dir or get_subtitles_dir(video_path))

        logger.debug(u'Scanning video %s...', video_path)
        video = scan_video(video_path)

        # external subtitles
        if subtitles:
            video.subtitle_languages |= set(search_external_subtitles(video_path, directory=subtitles_dir).values())

        if embedded_subtitles is None:
            embedded_subtitles = bool(not sickbeard.EMBEDDED_SUBTITLES_ALL and video_path.endswith('.mkv'))

        refine(video, episode_refiners=episode_refiners, embedded_subtitles=embedded_subtitles,
               release_name=release_name, tv_episode=tv_episode)

        payload['video'] = video
        region.set(key, payload)
        logger.debug(u'Video information cached under key %s', key)

        return video
    except Exception as error:
        logger.info(u'Exception: %s', error)
Пример #40
0
 def get_best_match(self, widget):
     # Open a thread to find a subtitle through get_best_subtitle
     try:
         self.video = scan_video(self.movie_entry.get_text())
     except ValueError:
         self.status_bar.pop(self.context_id)
         self.status_bar.push(self.context_id,
                              "Error. Did you choose a video file?")
         self.progress_bar.set_fraction(0)
         return False
     x = Thread(target=self.get_best_subtitle)
     x.start()
Пример #41
0
def get_video(video_path, subtitles_path=None):
    if not subtitles_path:
        try:
            subtitles_path = get_subtitles_path(video_path).encode(sickbeard.SYS_ENCODING)
        except UnicodeEncodeError as error:
            logger.log(u'An error occurred while encoding \'{}\' with your current locale. '
                       'Rename the file or try a different locale. Error: {}'.format
                       (video_path, ex(error)), logger.WARNING)
            return None

    try:
        if not sickbeard.EMBEDDED_SUBTITLES_ALL and video_path.endswith('.mkv'):
            video = subliminal.scan_video(video_path, subtitles=True, embedded_subtitles=True,
                                          subtitles_dir=subtitles_path)
        else:
            video = subliminal.scan_video(video_path, subtitles=True, embedded_subtitles=False,
                                          subtitles_dir=subtitles_path)
    except Exception:
        return None

    return video
Пример #42
0
def find_file_subtitles(path):
    """
    Finds subtitles for the given video file path.

    :param path: The path of the video file to find subtitles to.
    :return: The list of subtitles file paths, or None if a problem occurred.
    """
    logger.info('Searching subtitles for file: {}'.format(path))
    try:
        # Get required video information.
        video = subliminal.scan_video(path)
        other_languages = []
        subtitle_results = []
        for language, providers in LANGUAGES_MAP.items():
            # Filter providers the user didn't ask for.
            if not providers:
                other_languages.append(language)
            else:
                current_result = subliminal.download_best_subtitles(
                    {video}, languages={language},
                    providers=providers).values()
                if len(current_result) > 0:
                    subtitle_results.extend(list(current_result)[0])
        # Download all other languages.
        for language in other_languages:
            current_result = subliminal.download_best_subtitles(
                {video}, languages={language}).values()
            if len(current_result) > 0:
                subtitle_results.extend(list(current_result)[0])
        # Handle results.
        if len(subtitle_results) == 0:
            logger.info('No subtitles were found. Moving on...')
        else:
            logger.info('Found {} subtitles. Saving files...'.format(
                len(subtitle_results)))
            # Save subtitles alongside the video file.
            results_list = list()
            for subtitles in subtitle_results:
                # Filter empty subtitles files.
                if subtitles.content is None:
                    logger.debug(
                        'Skipping subtitle {}: no content'.format(subtitles))
                    continue
                subtitles_path = get_subtitle_path(video.name,
                                                   subtitles.language)
                logger.info('Saving {} to: {}'.format(subtitles,
                                                      subtitles_path))
                open(subtitles_path, 'wb').write(subtitles.content)
                results_list.append(subtitles_path)
            return results_list
    except ValueError:
        # Subliminal raises a ValueError if the given file is not a video file.
        logger.info('Not a video file. Moving on...')
Пример #43
0
 def on_task_output(self, task, config):
     """
     Configuration::
         subliminal:
             languages: List of languages (3-letter ISO-639-3 code) in order of preference. At least one is required.
             alternatives: List of second-choice languages; subs will be downloaded but entries rejected.
             exact_match: Use file hash only to search for subs, otherwise Subliminal will try to guess by filename.
     """
     if not task.accepted:
         log.debug('nothing accepted, aborting')
         return
     from babelfish import Language
     from dogpile.cache.exception import RegionAlreadyConfigured
     import subliminal
     try:
         subliminal.cache_region.configure('dogpile.cache.dbm', 
             arguments={'filename': os.path.join(tempfile.gettempdir(), 'cachefile.dbm'), 
                        'lock_factory': subliminal.MutexLock})
     except RegionAlreadyConfigured:
         pass
     logging.getLogger("subliminal").setLevel(logging.CRITICAL)
     logging.getLogger("enzyme").setLevel(logging.WARNING)
     langs = set([Language(s) for s in config['languages']])
     alts = set([Language(s) for s in config.get('alternatives', [])])
     for entry in task.accepted:
         if not 'location' 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 not '$RECYCLE.BIN' in entry['location']:  # ignore deleted files in Windows shares
             try:
                 video = subliminal.scan_video(entry['location'])
                 msc = video.scores['hash'] if config['exact_match'] else 0
                 if langs & video.subtitle_languages:
                     continue  # subs for preferred lang(s) already exists
                 elif subliminal.download_best_subtitles([video], langs, min_score=msc):
                     log.info('Subtitles found for %s' % entry['location'])
                 elif alts and (alts - video.subtitle_languages) and \
                     subliminal.download_best_subtitles([video], alts, min_score=msc):
                     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
                 if err.args:
                     msg = err.args[0]
                 else:
                     # Subliminal errors don't always have a message, just use the name
                     msg = 'subliminal error: %s' % err.__class__.__name__
                 log.debug(msg)
                 entry.fail(msg)
Пример #44
0
 def get_subtitles(self, entry):
     if entry.get('subtitles', eval_lazy=False) or not ('location' in entry) or \
             ('$RECYCLE.BIN' in entry['location']) or not os.path.exists(entry['location']):
         return
     import subliminal
     try:
         video = subliminal.scan_video(entry['location'])
         lst = [l.alpha3 for l in video.subtitle_languages]
         if lst:
             entry['subtitles'] = lst
             log.trace('Found subtitles %s for %s' % ('/'.join(lst), entry['title']))
     except Exception as e:
         log.debug('Error checking local subtitles for %s: %s' % (entry['title'], e))
Пример #45
0
 def get_subtitles(self, entry):
     if entry.get('subtitles', eval_lazy=False) or not ('location' in entry) or \
             ('$RECYCLE.BIN' in entry['location']) or not os.path.exists(entry['location']):
         return
     import subliminal
     try:
         video = subliminal.scan_video(entry['location'])
         lst = [l.alpha3 for l in video.subtitle_languages]
         if lst:
             entry['subtitles'] = lst
             log.trace('Found subtitles %s for %s' % ('/'.join(lst), entry['title']))
     except Exception as e:
         log.debug('Error checking local subtitles for %s: %s' % (entry['title'], e))
Пример #46
0
    def choose_callback(self, menuitem, files):
        # scan and check the video
        video = scan_video(files[0].get_location().get_path(),
                           subtitles=True,
                           embedded_subtitles=self.config.embedded_subtitles)
        if not check_video(video,
                           languages=self.config.languages,
                           undefined=self.config.single):
            return

        # list subtitles
        with ProviderPool(
                providers=self.config.providers,
                provider_configs=self.config.provider_configs) as pool:
            subtitles = pool.list_subtitles(video, self.config.languages)

        # load the interface
        builder = Gtk.Builder()
        builder.set_translation_domain('subliminal')
        builder.add_from_file(
            os.path.join(os.path.dirname(__file__), 'subliminal', 'ui',
                         'choose.glade'))

        # set the video filename
        video_filename = builder.get_object('video_filename_label')
        video_filename.set_text(files[0].get_name())

        # fill the subtitle liststore
        subtitle_liststore = builder.get_object('subtitle_liststore')
        for s in subtitles:
            matches = s.get_matches(
                video, hearing_impaired=self.config.hearing_impaired)
            scaled_score = compute_score(matches, video)
            if s.hearing_impaired == self.config.hearing_impaired:
                scaled_score -= video.scores['hearing_impaired']
            scaled_score *= 100 / video.scores['hash']
            subtitle_liststore.append([
                s.id,
                nice_language(s.language), scaled_score,
                s.provider_name.capitalize(), s.hearing_impaired, s.page_link,
                False
            ])
        subtitle_liststore.set_sort_column_id(2, Gtk.SortType.DESCENDING)

        # connect signals
        builder.connect_signals(ChooseHandler(self.config, video, subtitles))

        # display window
        window = builder.get_object('subtitle_window')
        window.show_all()
        Gtk.main()
 def test_scan_video_movie(self):
     video = MOVIES[0]
     scanned_video = scan_video(os.path.join(TEST_DIR, os.path.split(video.name)[1]))
     self.assertEqual(scanned_video.name, os.path.join(TEST_DIR, os.path.split(video.name)[1]))
     self.assertEqual(scanned_video.title.lower(), video.title.lower())
     self.assertEqual(scanned_video.year, video.year)
     self.assertEqual(scanned_video.video_codec, video.video_codec)
     self.assertEqual(scanned_video.resolution, video.resolution)
     self.assertEqual(scanned_video.release_group, video.release_group)
     self.assertEqual(scanned_video.subtitle_languages, set())
     self.assertEqual(scanned_video.hashes, {})
     self.assertIsNone(scanned_video.audio_codec)
     self.assertIsNone(scanned_video.imdb_id)
     self.assertEqual(scanned_video.size, 0)
Пример #48
0
	def mixAndMove(_cls, sourceDirPath_, destDirPath_) :
		LOGGER.info('*** START MIXING VIDEOS ***')
		if (os.path.isdir(sourceDirPath_)) :
			for dir, dirs, files in os.walk(sourceDirPath_) :
				localDir = dir[len(sourceDirPath_):]
				for fileName in files :
					fileExtension = os.path.splitext(fileName)[1]
					filePath = os.path.join(dir, fileName)

					if (fileExtension in VIDEO_EXTENSIONS) :
						# Scan video
						LOGGER.debug('Scanning video \'%s\'', filePath)
						video = subliminal.scan_video(filePath, False, True)
							
						# TEMP: if no embedded subtitles have been found, try to find associated sub files
						# This should be done in 'subliminal.scan_video', but... NO.
						# TODO: fork subliminal to fix the method 'scan_subtitle_languages'
						subFileLanguages = subtitles.scanSubtitleLanguages(filePath, SUB_EXTENSIONS)
						
						# If subs found, then move video
						hasSubFiles = babelfish.Language('eng') in subFileLanguages
						hasEmbeddedSub = babelfish.Language('eng') in video.subtitle_languages
						if hasEmbeddedSub :
							LOGGER.debug('%s has already embedded subtitles, skip mixing' % fileName)
							fileTools.transferFile(filePath, sourceDirPath_, destDirPath_)
						elif hasSubFiles :
							LOGGER.debug('Subtitles files found for %s', video.name)
							
							# Find all subtitles files
							subFiles = []
							for otherFileName in files :
								otherFileExtension = os.path.splitext(otherFileName)[1]
								if (not otherFileName == fileName and otherFileExtension in SUB_EXTENSIONS) :
									# Test if the subtitles have the same name as the movie
									otherFileRoot = os.path.splitext(otherFileName)[0]
									fileRoot = os.path.splitext(fileName)[0]
									if (otherFileRoot[:len(fileRoot)] == fileRoot) :
										# Move subtitles
										otherFilePath = os.path.join(dir, otherFileName)
										subFiles.append(otherFilePath)
							assert len(subFiles) > 0
							MkvMixer.mixVideo(filePath, subFiles)
							fileTools.transferFile(filePath, sourceDirPath_, destDirPath_)
							# TODO: remove this when mixing is done
							for subFilePath in subFiles :
								fileTools.transferFile(subFilePath, sourceDirPath_, destDirPath_)
						else :
							LOGGER.debug('%s has already embedded subtitles, skip mixing' % fileName)
		else :
			LOGGER.warning('\'%s\' does not refer to an existing path.', sourceDirPath_)
Пример #49
0
def _scan_wanted_item_for_video(wanted_item):
    originalfile = wanted_item['originalFileLocationOnDisk']
    log.debug("Scanning the wanted item for a video: %s" % originalfile)

    # Scan the video (disable scan for subtitles)
    # With subtitle scan enabled, enzyme looks inside for embedded subtitles
    # When an 'UND' subtitle language is found (f.e. Grimm.S03E04.720p.WEB-DL.DD5.1.H.264-ECI),
    # no other subtitles will be downloaded when using subliminal.download_best_subtitles(..., single=True)
    try:
        video = subliminal.scan_video(originalfile, subtitles=False, embedded_subtitles=False)
    except Exception, e:
        log.error("Error while scanning video, skipping %s" % originalfile)
        log.error("Exception: %s" % e)
        return
    def choose_callback(self, menuitem, files):
        # scan the video
        video = scan_video(files[0].get_location().get_path())
        refine(video, episode_refiners=self.config.refiners, movie_refiners=self.config.refiners,
               embedded_subtitles=False)

        # load the interface
        builder = Gtk.Builder()
        builder.set_translation_domain('subliminal')
        builder.add_from_file(os.path.join(os.path.dirname(__file__), 'subliminal', 'ui', 'choose.glade'))

        # set the video filename
        video_filename = builder.get_object('video_filename_label')
        video_filename.set_text(files[0].get_name())

        # start the spinner
        spinner = builder.get_object('spinner')
        spinner.start()

        def _list_subtitles():
            # list subtitles
            with AsyncProviderPool(providers=self.config.providers,
                                   provider_configs=self.config.provider_configs) as pool:
                subtitles = pool.list_subtitles(video, self.config.languages)

            # fill the subtitle liststore
            subtitle_liststore = builder.get_object('subtitle_liststore')
            for s in subtitles:
                scaled_score = compute_score(s, video)
                scores = get_scores(video)
                if s.hearing_impaired == self.config.hearing_impaired:
                    scaled_score -= scores['hearing_impaired']
                scaled_score *= 100 / scores['hash']
                subtitle_liststore.append([s.id, nice_language(s.language), scaled_score, s.provider_name.capitalize(),
                                           s.hearing_impaired, s.page_link, False])
            subtitle_liststore.set_sort_column_id(2, Gtk.SortType.DESCENDING)

            # stop the spinner
            spinner.stop()

            # connect signals
            builder.connect_signals(ChooseHandler(self.config, video, subtitles, spinner))

        threading.Thread(target=_list_subtitles).start()

        # display window
        window = builder.get_object('subtitle_window')
        window.show_all()
        Gtk.main()
    def download_callback(self, menuitem, files):
        # scan videos
        videos = []
        for f in files:
            # ignore non-writable locations
            if not f.can_write():
                continue

            # directories
            if f.is_directory():
                try:
                    scanned_videos = scan_videos(f.get_location().get_path())
                except:
                    continue
                for video in scanned_videos:
                    if check_video(video, languages=self.config.languages, age=self.config.age,
                                   undefined=self.config.single):
                        video.subtitle_languages |= set(search_external_subtitles(video.name).values())
                        refine(video, episode_refiners=self.config.refiners, movie_refiners=self.config.refiners,
                               embedded_subtitles=self.config.embedded_subtitles)
                        videos.append(video)
                continue

            # other inputs
            try:
                video = scan_video(f.get_location().get_path())
            except:
                continue
            if check_video(video, languages=self.config.languages, undefined=self.config.single):
                video.subtitle_languages |= set(search_external_subtitles(video.name).values())
                refine(video, episode_refiners=self.config.refiners, movie_refiners=self.config.refiners,
                       embedded_subtitles=self.config.embedded_subtitles)
                videos.append(video)

        # download best subtitles
        downloaded_subtitles = defaultdict(list)
        with AsyncProviderPool(providers=self.config.providers, provider_configs=self.config.provider_configs) as pool:
            for v in videos:
                scores = get_scores(v)
                subtitles = pool.download_best_subtitles(
                    pool.list_subtitles(v, self.config.languages - v.subtitle_languages),
                    v, self.config.languages, min_score=scores['hash'] * self.config.min_score / 100,
                    hearing_impaired=self.config.hearing_impaired, only_one=self.config.single
                )
                downloaded_subtitles[v] = subtitles

        # save subtitles
        for v, subtitles in downloaded_subtitles.items():
            save_subtitles(v, subtitles, single=self.config.single)
Пример #52
0
def download_subs(file):
    print("    Analyzing video file...")
    try:
        video = scan_video(file['full_path'])
    except ValueError as ex:
        print("    Failed to analyze video. ", ex)
        return None
    print("    Choosing subtitle from online providers...")
    best_subtitles = download_best_subtitles({video}, {Language('eng')}, only_one=True)
    if best_subtitles[video]:
        sub = best_subtitles[video][0]
        print("    Choosen subtitle: {f}".format(f=sub))
        print("    Downloading...")
        save_subtitles(video, [sub], single=True)
    else:
        print("    ERROR: No subtitles found online.")
Пример #53
0
def _scan_wanted_item_for_video(wanted_item):
    originalfile = wanted_item['originalFileLocationOnDisk']
    log.debug("Scanning the wanted item for a video: %s" % originalfile)

    # Scan the video (disable scan for subtitles)
    # With subtitle scan enabled, enzyme looks inside for embedded subtitles
    # When an 'UND' subtitle language is found (f.e. Grimm.S03E04.720p.WEB-DL.DD5.1.H.264-ECI),
    # no other subtitles will be downloaded when using subliminal.download_best_subtitles(..., single=True)
    try:
        video = subliminal.scan_video(originalfile,
                                      subtitles=False,
                                      embedded_subtitles=False)
    except Exception, e:
        log.error("Error while scanning video, skipping %s" % originalfile)
        log.error("Exception: %s" % e)
        return
Пример #54
0
def download_subs(file):
    print("    Analyzing video file...")
    try:
        video = scan_video(file['full_path'])
    except ValueError as ex:
        print("    Failed to analyze video. ", ex)
        return None
    print("    Choosing subtitle from online providers...")
    best_subtitles = download_best_subtitles({video}, {Language('eng')},
                                             only_one=True)
    if best_subtitles[video]:
        sub = best_subtitles[video][0]
        print("    Choosen subtitle: {f}".format(f=sub))
        print("    Downloading...")
        save_subtitles(video, [sub], single=True)
    else:
        print("    ERROR: No subtitles found online.")
 def test_scan_video_episode(self):
     video = EPISODES[0]
     scanned_video = scan_video(os.path.join(TEST_DIR, os.path.split(video.name)[1]))
     self.assertEqual(scanned_video.name, os.path.join(TEST_DIR, os.path.split(video.name)[1]))
     self.assertEqual(scanned_video.series, video.series)
     self.assertEqual(scanned_video.season, video.season)
     self.assertEqual(scanned_video.episode, video.episode)
     self.assertEqual(scanned_video.video_codec, video.video_codec)
     self.assertEqual(scanned_video.resolution, video.resolution)
     self.assertEqual(scanned_video.release_group, video.release_group)
     self.assertEqual(scanned_video.subtitle_languages, set())
     self.assertEqual(scanned_video.hashes, {})
     self.assertIsNone(scanned_video.title)
     self.assertIsNone(scanned_video.tvdb_id)
     self.assertIsNone(scanned_video.imdb_id)
     self.assertIsNone(scanned_video.audio_codec)
     self.assertEqual(scanned_video.size, 0)
Пример #56
0
def moveAndRenameDownloadedVideos(sourceDirPath_, destDirPath_) :
	"""Move all videos (movies and episodes) from the source path to the destination
	path, and rename them.

	:param String sourceDirPath_
	:param String destDirPath_
	"""

	LOGGER.info('*** START MOVING AND RENAMING DOWNLOADED VIDEOS ***')
	
	if (os.path.isdir(sourceDirPath_)) :
		# Parse all files
		for dir, dirs, files in os.walk(sourceDirPath_) :
			for fileName in files :
				# Retrieve paths
				fileExtension = os.path.splitext(fileName)[1]
				filePath = os.path.join(dir, fileName)
				
				if (fileExtension in VIDEO_EXTENSIONS) :
					# Create video instance
					LOGGER.debug('Scanning video file \'%s\'', filePath)
					
					video = subliminal.scan_video(filePath, True, True)
					print video
					# Specific action according to the type of video
					if (not video is None) :
						if (isinstance(video, subliminal.video.Episode)) :
							if (video.title is None) :
								db = api.TVDB("B43FF87DE395DF56")
								result = db.search(video.series, "en")
								
								for s in range(1, len(result[0])) :
									for e in range(1, len(result[0][s])+1) :
										print 'season ' + str(s) + 'episode ' + str(e) + ' ' + result[0][s][e].EpisodeName
								
								video.title  = unicode(result[0][video.season][video.episode].EpisodeName)
							moveAndRenameEpisode(video, destDirPath_);
						elif (isinstance(video, subliminal.video.Movie)) :
							moveAndRenameMovie(video, destDirPath_);
						else :
							LOGGER.info('Bad video type, skipping file. (%s)', filePath)
				else :
					LOGGER.info('Bad extension, skipping file. (%s)', filePath)
	else :
		LOGGER.warning('\'%s\' does not refer to an existing path.', sourceDirPath_)