Рубрики
Без рубрики

Автоматизация смотрит местный сериал в Python

У меня есть несколько серийных локально скачанных (я знаю, пиратство не круто) и единственная причина, по которой я не был … Помечено с Python, учебником, начинающим, производительностью.

У меня есть несколько серийных локально скачанных (я знаю, что пиратство не круто) и единственная причина, по которой я не смог посмотреть их до сих пор, мне слишком скучно наблюдать за ними один за другим и отслеживать Один я в последний раз смотрел.

Итак, я подумал, я могу написать сценарий Python, который сделает все это для меня, и все, что мне придется сделать, это запускать его, и это будет делать остальные. (Да, я знаю Netflix делает это Но тогда эти серии были недоступны на Netflix).

После многих мозгового штурма я пришел со следующим процессом, который я бы реализовал, чтобы сделать вышеуказанное.

Процесс

  1. Если серия еще не кэширована, кэлит это (объяснит это позже)
  2. Получить последний поигранный эпизод
  3. Позвоните внешнему игроку, как MPV.

1. Кэширование

Итак, вот сделка. Серия, которую мы сохраняем локально загруженные, хранятся в следующем формате

├── TAAHM
│   ├── Season 01
│   │   ├── Two And A Half Men Season 01 Episode 01 - Pilot - Most Chicks Wont Eat Veal.avi
│   │   ├── Two And A Half Men Season 01 Episode 02 - Big Flappy Bastards.avi
│   │   ├── Two And A Half Men Season 01 Episode 03 - Go East on Sunset Until You Reach the Gates of Hell.avi
│   │   ├── Two And A Half Men Season 01 Episode 04 - If I Can't Write My Chocolate Song, I'm Going to Take a Nap.avi
│   │   ├── Two And A Half Men Season 01 Episode 05 - The Last Thing You Want to Do Is Wind Up with a Hump.avi
│   │   ├── Two And A Half Men Season 01 Episode 06 - Did You Check with the Captain of the Flying Monkeys.avi
│   │   ├── Two And A Half Men Season 01 Episode 07 - If They Do Go Either Way, They're Usually Fake.avi
│   │   ├── Two And A Half Men Season 01 Episode 08 - Twenty-Five Little Pre-pubers Without a Snoot-ful.avi
│   │   ├── Two And A Half Men Season 01 Episode 09 - Phase One, Complete.avi
│   │   ├── .....
│   ├── Season 02
│   │   ├── ......

Итак, во-первых, во-первых, нам нужно определить функцию, которая может рекурсивно выяснить все сезоны и эпизоды.

Однако есть поймать, мы не можем просто рекурсивно пройти через все файлы, нам также нужно извлечь из них номера сезона и эпизода и придется отсортировать их на основе этого и хранить их соответственно.

Только тогда мы сможем кэшировать их, чтобы в следующий раз мы сможем просто найти кэшированные данные и пропустить эту часть.

Давайте напишем (некоторые) функции (ы) для извлечения данных

def _get_all_match(self, values, keyword):
        """Get all the possible matches of the keyword passed in the list."""
        matched_list = {}

        for value in values:
            # Try to extract the season number, if it's not present
            # skip the dir
            season_name = value.name.lower()
            result = re.search(
                    '{}({})?[\ \.]?[0-9]?[0-9]'.format(keyword[0], keyword[1:]),
                    season_name
                )
            if result is not None:
                result = result.group(0)
            else:
                continue
            season_number = re.sub(
                                    '{}({})?'.format(keyword[0], keyword[1:]),
                                    '',
                                    result
                                ).replace(" ", "")
            matched_list[int(season_number)] = value.as_posix()

        return matched_list

Что эта функция делает, предпринимает некоторые значения и принимает ключевое слово.

Я сделал функцию Generic так, чтобы она могла получить сочетание эпизода, а также в сезон с той же логикой.

Например:

Если мы хотим найти все эпизоды в сезон.

Мы будем соответствовать каждому имени файла с рисунком Regex.

Если мы хотим найти для эпизода, то это может быть либо E01 или Episode01 или E12 или E1 Отказ

Увидеть что-нибудь подобное в вышесказанном?

Хорошо, в каждом из них начало письмо е и эпизод Часть не является обязательной, но опять необходимо, должно быть два числа, следующие за этими буквами, и в числах первая необязательна (В 01, 0 может не присутствовать все время), но требуется второй.

Таким образом, мы придумаем следующее Regex

'e(pisode)?[\ \.]?[0-9]?[0-9]'

Но опять же в случае сезона это будет

's(eason)?[\ \.]?[0-9]?[0-9]'

Мы преобразуем строки ниже, чтобы быть на безопасной стороне.

После того, как наша логика готова, мы можем просто определить две функции, которые соответственно вызывают эту функцию для эпизода и сезонов.

def _process_parent(self):
        """Process the parent directory and extract all the Seasons."""
        season_list = []

        for season in self.parent_dir.iterdir():
            if season.is_dir():
                season_list.append(season)

        return OrderedDict(sorted(
                            self._get_all_match(season_list, "season")
                            .items()
                            ))

Здесь мы используем ЗаказДикт Потому что нам нужны сезоны в правильном порядке возрастающих чисел.

Сериализация данных

У нас есть еще одна проблема. Мы не можем просто хранить такие данные в файле JSON и вызовите его кэшированным.

Если мы сделаем вышеизложенное, нам придется снова найти следующий сезон/эпизод, и повторяя все данные (кэшированные).

Так вот вот что мы можем сделать.

Мы будем ссылаться на каждый сезон, используя номер сезона и каждый эпизод с его номером эпизода.

Мы храним данные в следующем формате

"3": {
    "1": "/home/deepjyoti30/Downloads/TAAHM/Two and a Half Men Season 3 720p MaRS/Two.and.a.Half.Men.S03E01.720p.WEB-DL-MaRS.mkv",
    "2": "/home/deepjyoti30/Downloads/TAAHM/Two and a Half Men Season 3 720p MaRS/Two.and.a.Half.Men.S03E02.720p.WEB-DL-MaRS.mkv",
    "3": "/home/deepjyoti30/Downloads/TAAHM/Two and a Half Men Season 3 720p MaRS/Two.and.a.Half.Men.S03E03.720p.WEB-DL-MaRS.mkv",
    "4": "/home/deepjyoti30/Downloads/TAAHM/Two and a Half Men Season 3 720p MaRS/Two.and.a.Half.Men.S03E04.720p.WEB-DL-MaRS.mkv",
    "5": "/home/deepjyoti30/Downloads/TAAHM/Two and a Half Men Season 3 720p MaRS/Two.and.a.Half.Men.S03E05.720p.WEB-DL-MaRS.mkv",

Мы можем сериализовать данные по следующей функции

def _serialize_data(self, series_data):
        """Serialize the data."""
        serialized_data = {}

        for season_number, season_data in series_data.items():
            for episode_number in range(0, len(season_data)):
                data_value = season_data[str(episode_number + 1)]
                if len(season_number) < 2:
                    season_number = "0" + season_number
                if episode_number < 9:
                    episode_number = "0" + str(episode_number + 1)
                else:
                    episode_number = str(episode_number + 1)
                data_key = "{}{}".format(season_number, episode_number)
                serialized_data[data_key] = data_value

        return serialized_data

Мы также будем хранить текущий воспроизводимый эпизод в другом файле, который мы будем читать в начале сценария каждый раз.

Теперь, когда у нас есть данные, кэшированные последовательно, вот как сценарий выполняется после этой части

  • Он загрузит кэшированные (сериализованные) данные.
  • Он прочитал текущий эпизод
  • Он будет воспроизводить текущий эпизод и подождать, пока внешний проигрыватель не возвращается
  • Прочитайте следующий эпизод в сериализованных данных.

Например:

Если текущий эпизод 0106 Мы будем играть текущую и то, что сделано, мы просто получим следующий номер из файла JSON и снова позвоните в функцию проигрывателя.

2. Получить последний сыгранный

Это простая часть. Мы можем просто прочитать файл, который у нас есть последний игровой эпизод, хранящийся в.

Я храним файлы в ~/.cache каталог.

Кроме того, файл, содержащий текущий эпизод, имеет имя AS .Текущий и тот, который содержащий сериализованные данные, это .ряд

Мы можем прочитать данные, используя следующую функцию

# Read the JSON data
with open(, 'r') as RSTREAM:
     data = json.load(RSTREAM)

# Read the current episode
current_epi = open(, 'r').read().replace("\n", "")

Вот как мы будем играть в файл

def _play(self, episode):
        """Play the passed episode."""
        starting_epi = episode

        for it in self._cached_data:
            try:
                if it < starting_epi:
                    continue
                print("[*] Playing {}".format(it))
                self._save_current(it)
                self._mpv(self._cached_data[it])
            except KeyboardInterrupt:
                print("[*] You watched till {}".format(it))
                exit(0)

Мы обнаруживаем прерывание клавиатуры для выхода из скрипта.

3. Позвоните внешнему игроку

Я использую подпрокат Модуль, чтобы вызвать внешний проигрыватель.

Я использую MPV Поскольку он имеет встроенный вариант для возобновления воспроизведения на последней остановленной позиции.

Вот как мы позвоним игроку

def _mpv(self, path):
        """Call MPV and pass the path to play."""
        call([
                'mpv',
                '--really-quiet',
                '--save-position-on-quit',
                '--resume-playback',
                path
            ])

Мы называем игроком с тремя аргументами, один – сохранить минимальный срок.

Другие два довольно явно объясняют.

Один из них заставит игрока сохранить позицию воспроизведения на выходе, а другой будет возобновить его с последней сохраненной точки.

Вывод

Первое первое, пиратство не круто.

Но затем Netflix просто не дает нам несколько серий, которые мы хотим посмотреть очень плохо, а когда это произойдет, получите серию из где-то а затем используйте этот скрипт, чтобы автоматизировать все.

Просто чтобы сделать все более простые, я также добавил функциональность, что путь к серии передается в качестве аргумента для скрипта.

Просто используйте Sys модуль для этого.

Хотя из-за вышеупомянутых, нам нужно добавить дополнительные проверки, чтобы посмотреть, являются ли пути действительны и прочее.

Весь скрипт можно найти здесь

Спасибо за чтение!

Я также пишу о технических вещах на моей личной странице. Считайте, что проверка постов там.

Оригинал: “https://dev.to/deepjyoti30/automate-watching-a-local-series-in-python-1aai”