Durinthal

airing_feed_processor.py

May 4th, 2019
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.13 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. import os
  4. import re
  5. import ssl
  6. import time
  7. import traceback
  8. import urllib.request
  9.  
  10. PLEX_TOKEN = "<insert token here>"
  11.  
  12. BASIC_RE = r"(?:\[(?P<group>.+?)\] ?)?(?P<name>.+?)(?: -)? (?P<number>\d+)(?: ?v\d)?.*?(?: [\[()](?P<quality>(?:\d+p|.+?))[\])])?(?:\s*[\[()](?P<hash>[A-Fa-f0-9]+)[\])])?\s*\.(?P<ext>(?:mkv|ass|srt))"
  13. POKEMON_RE = r"\[(?P<group>.+?)\]_?(?P<name>.+?)(?:_-)?_(?P<number>\d+)(?:_?\[?v\d\]?)?(?:_?[\[()](?P<quality>(?:\d+p|.+?))[\])])?(?:\s*|_[\[()](?P<hash>[A-Fa-f0-9]+)[\])])?\.(?P<ext>(?:mkv|ass|srt))"
  14.  
  15. REGEX_LIST = [BASIC_RE, POKEMON_RE]
  16. FILE_EXTS = [".mkv", ".ass", ".srt"]
  17.  
  18. MONITOR_DIR = "/path/to/downloaded/files/"
  19. MINIMUM_UNMODIFIED_TIME = 120  # seconds
  20.  
  21. DEFAULTS = {
  22.     "season": 1,
  23.     "offset": 0,
  24.     "show_dir": "",
  25.     "base_path": "/parent/path/to/save/to/"
  26. }
  27.  
  28. SEASON_MAP = {
  29.     # Autumn 2018
  30.     "Uchuu Senkan Tiramisu S2": {"show_dir": "Uchuu Senkan Tiramisu", "season": 2},
  31.     "Thunderbolt Fantasy S2": {"show_dir": "Thunderbolt Fantasy", "season": 2},
  32.     "Fairy Tail Final Season": {"show_dir": "Fairy Tail (2018)", "offset": 277},
  33.     "Ace Attorney S2": {"show_dir": "Ace Attorney", "season": 2},
  34.     "Inazuma_Eleven_Orion_no_Kokuin": {"show_dir": "Inazuma Eleven - Orion no Kokuin"},
  35.     "Jojo's_Bizarre_Adventure_Golden_Wind": {"show_dir": "JoJo's Bizarre Adventure - Golden Wind"},
  36.     "SSSS.GRIDMAN": {"show_dir": "SSSS.Gridman"},
  37.     "To Aru Majutsu no Index III": {"show_dir": "Toaru Majutsu no Index III"},
  38.     "Zombie Land Saga": {"show_dir": "Zombieland Saga"},
  39.     "Sword Art Onlineː Alicization": {"show_dir": "Sword Art Online - Alicization"},
  40.     # Winter 2019
  41.     "BanG Dream! S2": {"show_dir": "BanG Dream!", "season": 2},
  42.     "Mob Psycho": {"show_dir": "Mob Psycho 100", "season": 2},
  43.     "Dororo": {"show_dir": "Dororo (2019)"},
  44.     "Kakegurui xx": {"show_dir": "Kakegurui", "season": 2},
  45.     "B-Project S2": {"show_dir": "B-Project", "season": 2},
  46.     "Date A Live S3": {"show_dir": "Date A Live", "season": 3},
  47.     "Fukigen na Mononokean S2": {"show_dir": "Fukigen na Mononokean", "season": 2},
  48.     "Kaguya-sama ~Love is War~": {"show_dir": "Kaguya-sama wa Kokurasetai"},
  49.     "Date A Live III": {"show_dir": "Date A Live", "season": 3},
  50.     "Kemono Friends S2": {"show_dir": "Kemono Friends", "season": 2},
  51.     "Star☆Twinkle Precure": {"show_dir": "Star Twinkle Precure"},
  52.     # Spring 2019
  53.     "One Punch Man S2": {"show_dir": "One Punch Man", "season": 2},
  54.     "Hora, Mimi ga Mieteru yo!": {"show_dir": "Hora, Mimi ga Mieteru yo!", "season": 2},
  55.     "Midara na Ao-chan wa Benkyou ga Dekinai - Ao's Too Horny to Study": {"show_dir": "Midara na Ao-chan wa Benkyou ga Dekinai"},
  56. }
  57.  
  58. BLACKLIST = [
  59.     "One Piece",
  60. ]
  61.  
  62.  
  63. def make_link(source_path):
  64.  
  65.     filename = os.path.basename(source_path)
  66.     dst_file = filename
  67.  
  68.     for regex in REGEX_LIST:
  69.         parse_result = re.match(regex, filename)
  70.         if parse_result:
  71.             break
  72.     else:
  73.         print("\"{}\" does not match expected name format!".format(filename))
  74.         return False
  75.  
  76.     parsed_values = parse_result.groupdict()
  77.     show_name = parsed_values["name"]
  78.  
  79.     settings = DEFAULTS.copy()
  80.     settings["show_dir"] = show_name
  81.     if show_name in SEASON_MAP:
  82.         settings.update(SEASON_MAP[show_name])
  83.  
  84.     if settings["offset"] != 0:
  85.         episode_number = int(parsed_values["number"]) - settings["offset"]
  86.         dst_file = dst_file.replace(" - {} ".format(parsed_values["number"]),
  87.                                     " - S%02dE%02d " % (settings["season"], episode_number))
  88.  
  89.     season_path = os.path.join(settings["base_path"], settings["show_dir"], "Season %02d" % settings["season"])
  90.     if not os.path.exists(season_path):
  91.         os.makedirs(season_path)
  92.         print('Made directory "{}"'.format(season_path))
  93.  
  94.     dst_path = os.path.join(season_path, dst_file)
  95.  
  96.     if not os.path.isfile(dst_path):
  97.         os.link(source_path, dst_path)
  98.         print('Copied "{}" to "{}"'.format(filename, dst_path))
  99.         return True
  100.     return False
  101.  
  102.  
  103. def scan_for_files(dir_path):
  104.  
  105.     any_files_moved = False
  106.     for filename in os.listdir(dir_path):
  107.         file_ext = os.path.splitext(filename)[-1]
  108.         if file_ext not in FILE_EXTS or any([show in filename for show in BLACKLIST]):
  109.             continue
  110.         try:
  111.             file_path = os.path.join(dir_path, filename)
  112.             if time.time() - os.path.getmtime(file_path) < MINIMUM_UNMODIFIED_TIME:
  113.                 continue
  114.             os.chmod(file_path, 0o644)
  115.             file_moved = make_link(file_path)
  116.             if file_moved:
  117.                 any_files_moved = True
  118.         except Exception as e:
  119.             traceback.print_exc()
  120.  
  121.     return any_files_moved
  122.  
  123.  
  124. def update_plex():
  125.     plex_request = urllib.request.Request(
  126.         "https://<url-for-plex-server>/library/sections/<anime-library-number>/refresh",
  127.         headers={"X-Plex-Token": PLEX_TOKEN},
  128.         method="GET")
  129.     urllib.request.urlopen(plex_request)
  130.  
  131. if __name__ == "__main__":
  132.     files_moved = scan_for_files(MONITOR_DIR)
  133.     if files_moved:
  134.         print("Updating Plex...")
  135.         update_plex()
Advertisement
Add Comment
Please, Sign In to add comment