def scan_video(path, dont_use_actual_file=False, hints=None): """Scan a video from a `path`. patch: - allow passing of hints/options to guessit - allow dry-run with dont_use_actual_file - add crap removal (obfuscated/scrambled) - trust plex's movie name :param str path: existing path to the video. :return: the scanned video. :rtype: :class:`~subliminal.video.Video` """ hints = hints or {} video_type = hints.get("type") # check for non-existing path if not dont_use_actual_file and not os.path.exists(path): raise ValueError('Path does not exist') # check video extension if not path.lower().endswith(VIDEO_EXTENSIONS): raise ValueError('%r is not a valid video extension' % os.path.splitext(path)[1]) dirpath, filename = os.path.split(path) logger.info('Scanning video %r in %r', filename, dirpath) # hint guessit the filename itself and its 2 parent directories if we're an episode (most likely # Series name/Season/filename), else only one guess_from = os.path.join(*os.path.normpath(path).split(os.path.sep)[-3 if video_type == "episode" else -2:]) guess_from = REMOVE_CRAP_FROM_FILENAME.sub(r"\2", guess_from) # guess hints["single_value"] = True guessed_result = guessit(guess_from, options=hints) logger.debug('GuessIt found: %s', json.dumps(guessed_result, cls=GuessitEncoder, indent=4, ensure_ascii=False)) video = Video.fromguess(path, guessed_result) # trust plex's movie name if video_type == "movie" and hints.get("expected_title"): video.title = hints.get("expected_title")[0] if dont_use_actual_file: return video # size and hashes video.size = os.path.getsize(path) if video.size > 10485760: logger.debug('Size is %d', video.size) video.hashes['opensubtitles'] = hash_opensubtitles(path) video.hashes['shooter'] = hash_shooter(path) video.hashes['thesubdb'] = hash_thesubdb(path) video.hashes['napiprojekt'] = hash_napiprojekt(path) logger.debug('Computed hashes %r', video.hashes) else: logger.warning('Size is lower than 10MB: hashes not computed') return video
def scan_video(path, dont_use_actual_file=False, hints=None, providers=None, skip_hashing=False, hash_from=None): """Scan a video from a `path`. patch: - allow passing of hints/options to guessit - allow dry-run with dont_use_actual_file - add crap removal (obfuscated/scrambled) - trust plex's movie name :param str path: existing path to the video. :return: the scanned video. :rtype: :class:`~subliminal.video.Video` """ hints = hints or {} video_type = hints.get("type") # check for non-existing path if not dont_use_actual_file and not os.path.exists(path): raise ValueError('Path does not exist') # check video extension if not path.lower().endswith(VIDEO_EXTENSIONS): raise ValueError('%r is not a valid video extension' % os.path.splitext(path)[1]) dirpath, filename = os.path.split(path) logger.info('Determining basic video properties for %r in %r', filename, dirpath) # hint guessit the filename itself and its 2 parent directories if we're an episode (most likely # Series name/Season/filename), else only one split_path = os.path.normpath(path).split( os.path.sep)[-3 if video_type == "episode" else -2:] # remove crap from folder names if video_type == "episode": if len(split_path) > 2: split_path[-3] = remove_crap_from_fn(split_path[-3]) else: if len(split_path) > 1: split_path[-2] = remove_crap_from_fn(split_path[-2]) guess_from = os.path.join(*split_path) # remove crap from file name guess_from = remove_crap_from_fn(guess_from) # guess hints["single_value"] = True if "title" in hints: hints["expected_title"] = [hints["title"]] guessed_result = guessit(guess_from, options=hints) logger.debug( 'GuessIt found: %s', json.dumps(guessed_result, cls=GuessitEncoder, indent=4, ensure_ascii=False)) video = Video.fromguess(path, guessed_result) video.hints = hints # get possibly alternative title from the filename itself alt_guess = guessit(filename, options=hints) if "title" in alt_guess and alt_guess["title"] != guessed_result["title"]: if video_type == "episode": video.alternative_series.append(alt_guess["title"]) else: video.alternative_titles.append(alt_guess["title"]) logger.debug("Adding alternative title: %s", alt_guess["title"]) if dont_use_actual_file and not hash_from: return video # if all providers are throttled, skip hashing if not providers: skip_hashing = True # size and hashes if not skip_hashing: hash_path = hash_from or path video.size = os.path.getsize(hash_path) if video.size > 10485760: logger.debug('Size is %d', video.size) osub_hash = None if "bsplayer" in providers: video.hashes['bsplayer'] = osub_hash = hash_opensubtitles( hash_path) if "opensubtitles" in providers: video.hashes[ 'opensubtitles'] = osub_hash = osub_hash or hash_opensubtitles( hash_path) if "opensubtitlescom" in providers: video.hashes[ 'opensubtitlescom'] = osub_hash = osub_hash or hash_opensubtitles( hash_path) if "shooter" in providers: video.hashes['shooter'] = hash_shooter(hash_path) if "thesubdb" in providers: video.hashes['thesubdb'] = hash_thesubdb(hash_path) if "napiprojekt" in providers: try: video.hashes['napiprojekt'] = hash_napiprojekt(hash_path) except MemoryError: logger.warning(u"Couldn't compute napiprojekt hash for %s", hash_path) if "napisy24" in providers: # Napisy24 uses the same hash as opensubtitles video.hashes['napisy24'] = osub_hash or hash_opensubtitles( hash_path) logger.debug('Computed hashes %r', video.hashes) else: logger.warning('Size is lower than 10MB: hashes not computed') return video
def test_hash_opensubtitles(mkv): assert hash_opensubtitles(mkv['test1']) == '40b44a7096b71ec3'
def test_hash_opensubtitles_too_small(tmpdir): path = tmpdir.ensure('test_too_small.mkv') assert hash_opensubtitles(str(path)) is None
def scan_video(path, dont_use_actual_file=False, hints=None, providers=None, skip_hashing=False): """Scan a video from a `path`. patch: - allow passing of hints/options to guessit - allow dry-run with dont_use_actual_file - add crap removal (obfuscated/scrambled) - trust plex's movie name :param str path: existing path to the video. :return: the scanned video. :rtype: :class:`~subliminal.video.Video` """ hints = hints or {} video_type = hints.get("type") # check for non-existing path if not dont_use_actual_file and not os.path.exists(path): raise ValueError('Path does not exist') # check video extension if not path.lower().endswith(VIDEO_EXTENSIONS): raise ValueError('%r is not a valid video extension' % os.path.splitext(path)[1]) dirpath, filename = os.path.split(path) logger.info('Determining basic video properties for %r in %r', filename, dirpath) # hint guessit the filename itself and its 2 parent directories if we're an episode (most likely # Series name/Season/filename), else only one split_path = os.path.normpath(path).split(os.path.sep)[-3 if video_type == "episode" else -2:] # remove crap from folder names if video_type == "episode": if len(split_path) > 2: split_path[-3] = remove_crap_from_fn(split_path[-3]) else: if len(split_path) > 1: split_path[-2] = remove_crap_from_fn(split_path[-2]) guess_from = os.path.join(*split_path) # remove crap from file name guess_from = remove_crap_from_fn(guess_from) # guess hints["single_value"] = True if "title" in hints: hints["expected_title"] = [hints["title"]] guessed_result = guessit(guess_from, options=hints) logger.debug('GuessIt found: %s', json.dumps(guessed_result, cls=GuessitEncoder, indent=4, ensure_ascii=False)) video = Video.fromguess(path, guessed_result) video.hints = hints # get possibly alternative title from the filename itself alt_guess = guessit(filename, options=hints) if "title" in alt_guess and alt_guess["title"] != guessed_result["title"]: if video_type == "episode": video.alternative_series.append(alt_guess["title"]) else: video.alternative_titles.append(alt_guess["title"]) logger.debug("Adding alternative title: %s", alt_guess["title"]) if dont_use_actual_file: return video # size and hashes if not skip_hashing: video.size = os.path.getsize(path) if video.size > 10485760: logger.debug('Size is %d', video.size) if "opensubtitles" in providers: video.hashes['opensubtitles'] = hash_opensubtitles(path) if "shooter" in providers: video.hashes['shooter'] = hash_shooter(path) if "thesubdb" in providers: video.hashes['thesubdb'] = hash_thesubdb(path) if "napiprojekt" in providers: try: video.hashes['napiprojekt'] = hash_napiprojekt(path) except MemoryError: logger.warning(u"Couldn't compute napiprojekt hash for %s", path) logger.debug('Computed hashes %r', video.hashes) else: logger.warning('Size is lower than 10MB: hashes not computed') return video