├── requirements-dev.txt ├── MANIFEST.in ├── setup.cfg ├── requirements.txt ├── .gitignore ├── .editorconfig ├── PTN ├── __init__.py ├── extras.py ├── post.py ├── patterns.py └── parse.py ├── cli.py ├── .travis.yml ├── LICENSE ├── setup.py ├── tests ├── test_parse.py ├── test_generator.py └── files │ ├── input.json │ └── output_standard.json └── README.md /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | black 2 | feedparser 3 | numpy 4 | pytest 5 | setuptools 6 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include MANIFEST.in 3 | include tests/files/*.json 4 | include README.md 5 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 88 3 | select = C,E,F,W,B,B950 4 | extend-ignore = E203, E501, W605, E402 5 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | regex==2020.6.8 # Newer versions don't work with Python 2.7 (we don't use this package with Python 3) 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.egg-info/ 2 | 3 | build/ 4 | dist/ 5 | env/ 6 | venv*/ 7 | 8 | *.pyc 9 | .idea/ 10 | 11 | tests/files/seen_inputs.json 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | indent_style = space 7 | indent_size = 4 8 | 9 | [{.travis.yml,*.json}] 10 | indent_size = 2 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /PTN/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | 4 | 5 | if sys.version_info.major == 3: 6 | import importlib 7 | 8 | re = importlib.import_module("re") 9 | 10 | elif sys.version_info.major == 2: 11 | import pkgutil 12 | # Regex in python 2 is very slow so we check if the faster 'regex' library is available. 13 | faster_regex = pkgutil.find_loader("regex") 14 | if faster_regex is not None: 15 | re = faster_regex.load_module("regex") 16 | else: 17 | re = pkgutil.find_loader("re").load_module("re") 18 | 19 | from .parse import PTN 20 | 21 | __author__ = "Giorgio Momigliano" 22 | __email__ = "gmomigliano@protonmail.com" 23 | __version__ = "2.8.1" 24 | __license__ = "MIT" 25 | 26 | 27 | def parse(name, standardise=True, coherent_types=False): 28 | return PTN().parse(name, standardise, coherent_types) 29 | -------------------------------------------------------------------------------- /cli.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import json 3 | 4 | import PTN 5 | 6 | parser = argparse.ArgumentParser( 7 | description="Extract media information from torrent-like filename." 8 | ) 9 | parser.add_argument("torrent", type=str, help="a torrent-like filename") 10 | parser.add_argument( 11 | "--raw", 12 | dest="standardise", 13 | action="store_const", 14 | const=False, 15 | default=True, 16 | help="don't standardise the output", 17 | ) 18 | parser.add_argument( 19 | "--coherent-types", 20 | dest="coherent_types", 21 | action="store_const", 22 | const=True, 23 | default=False, 24 | help="make all non-boolean fields (outside of title and episodeName) into lists.", 25 | ) 26 | args = parser.parse_args() 27 | 28 | parsed = PTN.parse( 29 | args.torrent, standardise=args.standardise, coherent_types=args.coherent_types 30 | ) 31 | 32 | print(json.dumps(parsed, indent=2)) 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - '2.7' 4 | - '3.5' 5 | sudo: true 6 | script: python tests/test_parse.py 7 | before_install: 8 | - pip install -U pip 9 | - python setup.py install 10 | - python3 --version 11 | install: 12 | - pip install -r requirements.txt 13 | before_deploy: 14 | - python3 -m venv ~/venv 15 | - source ~/venv/bin/activate 16 | deploy: 17 | provider: pypi 18 | user: __token__ 19 | password: 20 | secure: EOmx2AahE9H/ZXNoAzIyOaxun7+9gJItet6+jkPq00mnqCF5zqTgZJe3/uejEVFFb/ccFcz5sR1/Y65jesW1dW4Xv2QvBXB5uSQaD0H8T8pNC6UGlbz9SKHFadHtvsa/2kgyyJ4kkdFbzGcQ/2qRFDj+l7eLeIo4JHTMaRLJLn+0ZkGSEKnNztWd57VZXxfWw+1msEncKR54ZHbju5naV1rcxZink6X+yt75v/V5U+U0Gy1JnYgiCgB9ykP9pMrXxpO8X6xCOqbWJFOCetCHGy+JaYBEi3Lr0oZDcsIRdyK/nt3Z0PJlSmna5TP4EO6JslGFwV5mO9foIZRaBkxFrygdvCm1uAtMZBeU4nfZAcVEa42c9/a/7zdkN23kZz7Mzy836MP6bMAhpKmqqwDcdUYQ/nWgu8QtJuCB5mbYrb3EPbORRwgF0xodYD+W2tvHem7sNAKpRibY6KZ5nJ1qR29/eMmF6X7zrMp3BBu4OqG4cTtb/MPMG+FqCygmosIqGdUI6gOq1cfvVXAmXgCtZgvSwDmVcS2HiBr3EMRaw0Wp7D+g4TIDrXTHVNgFWifamIep8RBw0wUQGI90b1tb7aCeL0jj52TplRKGw12orfjIIR4D6MMSdhQOUMQnJLqrpMIQMXc5cVcEAIs9x/UaAgiCj2BSP9+LM+jCbhcVBRQ= 21 | distributions: sdist bdist_wheel 22 | skip_existing: true 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2017 Divij Bindlish (divijbindlish.com) 4 | Copyright (c) 2020 Giorgio Momigliano 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | import os 3 | 4 | from setuptools import setup 5 | 6 | readme_path = os.path.join(os.path.dirname(__file__), "README.md") 7 | 8 | with codecs.open(readme_path, mode="r", encoding="utf-8") as f: 9 | description = f.read() 10 | 11 | setup( 12 | name="parse-torrent-title", 13 | version=__import__("PTN").__version__, 14 | author=__import__("PTN").__author__, 15 | author_email=__import__("PTN").__email__, 16 | license=__import__("PTN").__license__, 17 | url="https://github.com/platelminto/parse-torrent-title", 18 | description="Extract media information from torrent-like filename", 19 | long_description=description, 20 | long_description_content_type="text/markdown", 21 | packages=["PTN"], 22 | keywords=( 23 | "parse parser torrent torrents name names proper rename " 24 | "movie movies tv show shows series extract find quality " 25 | "group codec audio resolution title season episode year " 26 | "information filename filenames file files meaningful" 27 | ), 28 | classifiers=[ 29 | "Development Status :: 5 - Production/Stable", 30 | "Intended Audience :: Developers", 31 | "License :: OSI Approved :: MIT License", 32 | "Natural Language :: English", 33 | "Topic :: Text Processing", 34 | ], 35 | ) 36 | -------------------------------------------------------------------------------- /tests/test_parse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import json 4 | import os 5 | import PTN 6 | import pytest 7 | 8 | 9 | def load_json_file(file_name): 10 | with open(file_name) as input_file: 11 | return json.load(input_file) 12 | 13 | 14 | def get_raw_data(): 15 | json_input = os.path.join(os.path.dirname(__file__), "files/input.json") 16 | torrents = load_json_file(json_input) 17 | 18 | json_output = os.path.join(os.path.dirname(__file__), "files/output_raw.json") 19 | expected_results = load_json_file(json_output) 20 | 21 | return zip(torrents, expected_results) 22 | 23 | 24 | def get_standard_data(): 25 | json_input = os.path.join(os.path.dirname(__file__), "files/input.json") 26 | torrents = load_json_file(json_input) 27 | 28 | json_output = os.path.join(os.path.dirname(__file__), "files/output_standard.json") 29 | expected_results = load_json_file(json_output) 30 | 31 | return zip(torrents, expected_results) 32 | 33 | 34 | class TestTorrentParser: 35 | total_excess = 0 36 | 37 | @classmethod 38 | def setup_class(cls): 39 | cls.total_excess = 0 40 | 41 | @classmethod 42 | def teardown_class(cls): 43 | print("\nExcess elements total: {}".format(cls.total_excess)) 44 | 45 | @pytest.mark.parametrize("torrent,expected_result", get_raw_data()) 46 | def test_all_raw(self, torrent, expected_result): 47 | result = PTN.parse(torrent, standardise=False) 48 | if "excess" in result: 49 | if isinstance(result["excess"], list): 50 | TestTorrentParser.total_excess += len(result["excess"]) 51 | else: 52 | TestTorrentParser.total_excess += 1 53 | for key in expected_result: 54 | assert key in result, "'{}' was missing for \n{}".format(key, torrent) 55 | assert result[key] == expected_result[key], "'{}' failed for \n{}".format( 56 | key, torrent 57 | ) 58 | for key in result.keys(): 59 | if key not in ("encoder", "excess", "site"): # Not needed in tests 60 | assert key in expected_result 61 | 62 | @pytest.mark.parametrize("torrent,expected_result", get_standard_data()) 63 | def test_standardised(self, torrent, expected_result): 64 | result = PTN.parse(torrent, standardise=True) 65 | for key in expected_result: 66 | assert key in result, "'{}' was missing for \n{}".format(key, torrent) 67 | assert result[key] == expected_result[key], "'{}' failed for \n{}".format( 68 | key, torrent 69 | ) 70 | -------------------------------------------------------------------------------- /PTN/extras.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Helper functions and constants for patterns.py 4 | 5 | delimiters = "[\.\s\-\+_\/(),]" 6 | 7 | langs = [ 8 | ("rus(?:sian)?", "Russian"), 9 | ("(?:True)?fre?(?:nch)?", "French"), 10 | ("(?:nu)?ita(?:liano?)?", "Italian"), 11 | ("castellano|spa(?:nish)?|esp?", "Spanish"), 12 | ("swedish", "Swedish"), 13 | ("dk|dan(?:ish)?", "Danish"), 14 | ("ger(?:man)?|deu(?:tsch)?", "German"), 15 | ("nordic", "Nordic"), 16 | ("exyu", "ExYu"), 17 | ("chs|chi(?:nese)?", "Chinese"), 18 | ("hin(?:di)?", "Hindi"), 19 | ("polish|poland|pl", "Polish"), 20 | ("mandarin", "Mandarin"), 21 | ("kor(?:ean)?", "Korean"), 22 | ("ben(?:gali)?|bangla", "Bengali"), 23 | ("kan(?:nada)?", "Kannada"), 24 | ("tam(?:il)?", "Tamil"), 25 | ("tel(?:ugu)?", "Telugu"), 26 | ("mar(?:athi)?", "Marathi"), 27 | ("mal(?:ayalam)?", "Malayalam"), 28 | ("japanese|ja?p", "Japanese"), 29 | ("interslavic", "Interslavic"), 30 | ("ara(?:bic)?", "Arabic"), 31 | ("urdu", "Urdu"), 32 | ("punjabi", "Punjabi"), 33 | ("portuguese", "Portuguese"), 34 | ("albanian?", "Albanian"), 35 | ("egypt(?:ian)?", "Egyptian"), 36 | ("en?(?:g(?:lish)?)?", "English"), # Must be at end, matches just an 'e' 37 | ] 38 | 39 | genres = [ 40 | ("Sci-?Fi", "Sci-Fi"), 41 | ("Drama", "Drama"), 42 | ("Comedy", "Comedy"), 43 | ("West(?:\.|ern)?", "Western"), 44 | ("Action", "Action"), 45 | ("Adventure", "Adventure"), 46 | ("Thriller", "Thriller"), 47 | ] 48 | 49 | # Match strings like "complete series" for tv seasons/series, matching within the final title string. 50 | complete_series = [ 51 | r"(?:the\s)?complete\s(?:series|season|collection)$", 52 | r"(?:the)\scomplete\s?(?:series|season|collection)?$", 53 | ] 54 | 55 | # Some titles just can't be parsed without breaking everything else, so here 56 | # are known those known exceptions. They are executed when the parsed_title and 57 | # incorrect_parse match within a .parse() dict, removing the latter, and replacing 58 | # the former with actual_title. 59 | exceptions = [ 60 | { 61 | "parsed_title": "Marvel's Agents of S H I E L D", 62 | "incorrect_parse": ("title", "Marvel's Agents of S H I E L D"), 63 | "actual_title": "Marvel's Agents of S.H.I.E.L.D.", 64 | }, 65 | { 66 | "parsed_title": "Marvels Agents of S H I E L D", 67 | "incorrect_parse": ("title", "Marvels Agents of S H I E L D"), 68 | "actual_title": "Marvel's Agents of S.H.I.E.L.D.", 69 | }, 70 | { 71 | "parsed_title": "Magnum P I", 72 | "incorrect_parse": ("title", "Magnum P I"), 73 | "actual_title": "Magnum P.I.", 74 | }, 75 | ] 76 | 77 | # Patterns that should only try to be matched after the 'title delimiter', either a year 78 | # or a season. So if we have a language in the title it won't cause issues by getting matched. 79 | # Empty list indicates to always do so, as opposed to matching specific regexes. 80 | patterns_ignore_title = { 81 | "language": [], 82 | "audio": ["LiNE"], 83 | "network": ["Hallmark"], 84 | "untouched": [], 85 | "internal": [], 86 | "limited": [], 87 | "proper": [], 88 | "extended": [], 89 | } 90 | 91 | 92 | channels = [(1, 0), (2, 0), (5, 0), (5, 1), (6, 1), (7, 1)] 93 | 94 | 95 | # Return tuple with regexes for audio name with appended channel types, and without any channels 96 | def get_channel_audio_options(patterns_with_names): 97 | options = [] 98 | for (audio_pattern, name) in patterns_with_names: 99 | for (speakers, subwoofers) in channels: 100 | options.append( 101 | ( 102 | "((?:{}){}*{}[. \-]?{}(?:ch)?)".format( 103 | audio_pattern, delimiters, speakers, subwoofers 104 | ), 105 | "{} {}.{}".format(name, speakers, subwoofers), 106 | ) 107 | ) 108 | options.append( 109 | ("({})".format(audio_pattern), name) 110 | ) # After for loop, would match first 111 | 112 | return options 113 | 114 | 115 | def prefix_pattern_with(prefixes, pattern_options, between="", optional=False): 116 | if optional: 117 | optional_char = "?" 118 | else: 119 | optional_char = "" 120 | options = [] 121 | if not isinstance(prefixes, list): 122 | prefixes = [prefixes] 123 | for prefix in prefixes: 124 | if not isinstance(pattern_options, list): 125 | pattern_options = [pattern_options] 126 | for pattern_option in pattern_options: 127 | if isinstance(pattern_option, str): 128 | options.append( 129 | "(?:{}){}(?:{})?({})".format( 130 | prefix, optional_char, between, pattern_option 131 | ) 132 | ) 133 | else: 134 | options.append( 135 | ( 136 | "(?:{}){}(?:{})?({})".format( 137 | prefix, optional_char, between, pattern_option[0] 138 | ), 139 | ) 140 | + pattern_option[1:] 141 | ) 142 | 143 | return options 144 | 145 | 146 | def suffix_pattern_with(suffixes, pattern_options, between="", optional=False): 147 | if optional: 148 | optional_char = "?" 149 | else: 150 | optional_char = "" 151 | options = [] 152 | if not isinstance(suffixes, list): 153 | suffixes = [suffixes] 154 | for suffix in suffixes: 155 | if not isinstance(pattern_options, list): 156 | pattern_options = [pattern_options] 157 | for pattern_option in pattern_options: 158 | if isinstance(pattern_option, tuple): 159 | options.append( 160 | ( 161 | "({})(?:{})?(?:{}){}".format( 162 | pattern_option[0], between, suffix, optional_char 163 | ), 164 | ) 165 | + pattern_option[1:] 166 | ) 167 | else: 168 | options.append( 169 | "({})(?:{})?(?:{}){}".format( 170 | pattern_option, between, suffix, optional_char 171 | ) 172 | ) 173 | 174 | return options 175 | 176 | 177 | # Link a regex-tuple list into a single regex (to be able to use elsewhere while 178 | # maintaining standardisation functionality). 179 | def link_patterns(pattern_options): 180 | if not isinstance(pattern_options, list): 181 | return pattern_options 182 | return ( 183 | "(?:" 184 | + "|".join( 185 | [ 186 | pattern_option[0] 187 | if isinstance(pattern_option, tuple) 188 | else pattern_option 189 | for pattern_option in pattern_options 190 | ] 191 | ) 192 | + ")" 193 | ) 194 | -------------------------------------------------------------------------------- /tests/test_generator.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | import feedparser 4 | import numpy 5 | 6 | INDENT = 2 7 | SPACE = " " 8 | NEWLINE = "\n" 9 | 10 | 11 | def to_json(o, level=0): 12 | ret = "" 13 | if isinstance(o, dict): 14 | ret += "{" + NEWLINE 15 | comma = "" 16 | for k in sorted(o): 17 | v = o[k] 18 | ret += comma 19 | comma = ",\n" 20 | ret += SPACE * INDENT * (level + 1) 21 | ret += '"' + str(k) + '":' + SPACE 22 | ret += to_json(v, level + 1) 23 | 24 | ret += NEWLINE + SPACE * INDENT * level + "}" 25 | elif isinstance(o, str): 26 | ret += '"' + o + '"' 27 | elif isinstance(o, list): 28 | if isinstance(o[0], dict): 29 | ret += ( 30 | "[\n" 31 | + SPACE * INDENT * (level + 1) 32 | + (",\n" + SPACE * INDENT * (level + 1)).join( 33 | [to_json(e, level + 1) for e in o] 34 | ) 35 | + "\n]" 36 | ) 37 | else: 38 | ret += "[" + ",".join([to_json(e, level + 1) for e in o]) + "]" 39 | elif isinstance(o, bool): 40 | ret += "true" if o else "false" 41 | elif isinstance(o, int): 42 | ret += str(o) 43 | elif isinstance(o, float): 44 | ret += "%.7g" % o 45 | elif isinstance(o, numpy.ndarray) and numpy.issubdtype(o.dtype, numpy.integer): 46 | ret += "[" + ",".join(map(str, o.flatten().tolist())) + "]" 47 | elif isinstance(o, numpy.ndarray) and numpy.issubdtype(o.dtype, numpy.inexact): 48 | ret += "[" + ",".join(map(lambda x: "%.7g" % x, o.flatten().tolist())) + "]" 49 | elif o is None: 50 | ret += "null" 51 | else: 52 | raise TypeError("Unknown type '%s' for json serialization" % str(type(o))) 53 | return ret 54 | 55 | 56 | def add_titles(titles): 57 | import PTN 58 | 59 | for title in titles: 60 | with open("files/seen_inputs.json", "a+") as seen_inputs: 61 | if seen_inputs.tell() == 0: 62 | seen_inputs.write("[]") 63 | seen_inputs.seek(0) 64 | seen = json.load(seen_inputs) 65 | if title in seen: 66 | continue 67 | print(title) 68 | raw_parsed = PTN.parse(title, standardise=False) 69 | standard_parsed = PTN.parse(title, standardise=True) 70 | difference_parsed = dict() 71 | standard_filtered = dict() 72 | standard_filtered["title"] = raw_parsed["title"] 73 | 74 | for key, raw_value in raw_parsed.items(): 75 | standard_value = standard_parsed[key] 76 | if standard_value != raw_value: 77 | difference_parsed[key] = [raw_value, standard_value] 78 | standard_filtered[key] = standard_value 79 | else: 80 | difference_parsed[key] = raw_value 81 | 82 | print(to_json(difference_parsed)) 83 | print() 84 | 85 | option = input("(s)ave/(i)gnore/s(k)ip: ") 86 | 87 | if option == "s" or option == "save": 88 | with open("files/input.json", "r") as inputs_file: 89 | inputs = json.load(inputs_file) 90 | if title in inputs: 91 | print("WARNING: Not added, already in inputs") 92 | continue 93 | inputs.append(title) 94 | with open("files/input.json", "w") as inputs_file: 95 | inputs_file.write(json.dumps(inputs, indent=2)) 96 | with open("files/seen_inputs.json", "r") as seen_inputs: 97 | inputs = json.load(seen_inputs) 98 | inputs.append(title) 99 | with open("files/seen_inputs.json", "w") as seen_inputs: 100 | seen_inputs.write(json.dumps(inputs)) 101 | 102 | filtered_parsed = raw_parsed.copy() 103 | # filtered_parsed.pop('group', '') 104 | filtered_parsed.pop("excess", "") 105 | with open("files/output_raw.json", "r") as outputs_file: 106 | outputs = json.load(outputs_file) 107 | outputs.append(filtered_parsed) 108 | with open("files/output_raw.json", "w") as outputs_file: 109 | outputs_file.write(to_json(outputs)) 110 | 111 | with open("files/output_standard.json", "r") as outputs_file: 112 | outputs = json.load(outputs_file) 113 | outputs.append(standard_filtered) 114 | with open("files/output_standard.json", "w") as outputs_file: 115 | outputs_file.write(to_json(outputs)) 116 | 117 | elif option == "i" or option == "ignore": 118 | with open("files/seen_inputs.json", "r") as seen_inputs: 119 | inputs = json.load(seen_inputs) 120 | inputs.append(title) 121 | with open("files/seen_inputs.json", "w") as seen_inputs: 122 | seen_inputs.write(json.dumps(inputs)) 123 | elif option == "k" or option == "skip": 124 | continue 125 | else: 126 | break 127 | 128 | 129 | def add_random_titles(): 130 | RECENT_FEED = ( 131 | "http://localhost:9117/api/v2.0/indexers/torrentgalaxy/results/torznab/api?apikey" 132 | "=rfvvjrk9r22qe7k2cbdjxdazriemhifq&t=search&cat=2000&q=" 133 | ) 134 | RECENT_FEED_2 = "http://localhost:9117/api/v2.0/indexers/1337x/results/torznab/api?apikey=rfvvjrk9r22qe7k2cbdjxdazriemhifq&t=search&cat=&q=" 135 | POPULAR_FEED_TV = "http://localhost:9117/api/v2.0/indexers/rarbg/results/torznab/api?apikey=rfvvjrk9r22qe7k2cbdjxdazriemhifq&t=search&cat=5030,5040,5045&q=" 136 | POPULAR_FEED_MOVIE = "http://localhost:9117/api/v2.0/indexers/rarbg/results/torznab/api?apikey=rfvvjrk9r22qe7k2cbdjxdazriemhifq&t=search&cat=2030,2040,2045,2050,2060&q=" 137 | ANIME_FEED = "http://localhost:9117/api/v2.0/indexers/torrentgalaxyorg/results/torznab/api?apikey=rfvvjrk9r22qe7k2cbdjxdazriemhifq&t=search&cat=5070&q=" 138 | FOREIGN_MOVIE_FEED = "http://localhost:9117/api/v2.0/indexers/torrentgalaxyorg/results/torznab/api?apikey=rfvvjrk9r22qe7k2cbdjxdazriemhifq&t=search&cat=2010&q=" 139 | DOCUMENTARY_FEED = "http://localhost:9117/api/v2.0/indexers/torrentgalaxyorg/results/torznab/api?apikey=rfvvjrk9r22qe7k2cbdjxdazriemhifq&t=search&cat=5080&q=" 140 | 141 | recent_results = feedparser.parse(RECENT_FEED) 142 | recent2_results = feedparser.parse(RECENT_FEED_2) 143 | popular_tv_results = feedparser.parse(POPULAR_FEED_TV) 144 | popular_movie_results = feedparser.parse(POPULAR_FEED_MOVIE) 145 | anime_results = feedparser.parse(ANIME_FEED) 146 | foreign_movies_results = feedparser.parse(FOREIGN_MOVIE_FEED) 147 | documentary_results = feedparser.parse(DOCUMENTARY_FEED) 148 | 149 | # for entry in [j for i in zip(recent_results['entries'],popular_results['entries']) for j in i]: 150 | add_titles(entry["title"] for entry in recent2_results["entries"]) 151 | 152 | 153 | if __name__ == "__main__": 154 | # add_random_titles() 155 | add_titles( 156 | [ 157 | # "Seinfeld.S04E23E24.The.Pilot.FiNAL.MULTi.1080p.NF.WEB-DL.HE-AAC2.0.H264-Ralf.mkv", 158 | ] 159 | ) 160 | -------------------------------------------------------------------------------- /PTN/post.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Post-processing functions that run after the main parsing. 4 | 5 | from . import re 6 | from .extras import link_patterns, complete_series 7 | from .patterns import episode_name_pattern, langs, patterns, pre_website_encoder_pattern 8 | 9 | # Before excess functions (before we split what was unmatched in the title into a list). 10 | # They all take in the parse object and what was unmatched, and must return the latter minus 11 | # what they used. 12 | 13 | 14 | # Try and find the episode name. 15 | def try_episode_name(self, unmatched): 16 | match = re.findall(episode_name_pattern, unmatched) 17 | # First we see if there's a match in unmatched, then we look if it's after an episode, a day, 18 | # or a year, in the full release title. 19 | if match: 20 | match = re.search( 21 | "(?:" 22 | + link_patterns(patterns["episode"]) 23 | + "|" 24 | + patterns["day"] 25 | + "|" 26 | + patterns["year"] 27 | + r")[._\-\s+]*(" 28 | + re.escape(match[0]) 29 | + ")", 30 | self.torrent_name, 31 | re.IGNORECASE, 32 | ) 33 | if match: 34 | match_s, match_e = match.start(len(match.groups())), match.end( 35 | len(match.groups()) 36 | ) 37 | match = match.groups()[-1] 38 | self._part("episodeName", (match_s, match_e), self._clean_string(match)) 39 | unmatched = unmatched.replace(match, "") 40 | return unmatched 41 | 42 | 43 | def try_encoder_before_site(self, unmatched): 44 | match = re.findall(pre_website_encoder_pattern, unmatched.strip()) 45 | 46 | if match: 47 | found_match = None 48 | for m in match: 49 | full_title_match = re.search( 50 | r"[\s\-](" 51 | + re.escape(m) 52 | + ")(?:\." 53 | + link_patterns(patterns["filetype"]) 54 | + ")?$", 55 | self.torrent_name, 56 | re.I, 57 | ) 58 | if full_title_match: 59 | found_match = full_title_match 60 | break 61 | match = found_match 62 | if match: 63 | match_s, match_e = match.start(0), match.end(0) 64 | encoder_and_site = list( 65 | filter(None, re.split(r"[\-\s\)]", match.groups()[0])) 66 | ) 67 | if len(encoder_and_site) == 2: 68 | encoder_raw = encoder_and_site[0] 69 | site_raw = encoder_and_site[1] 70 | self._part( 71 | "encoder", 72 | (match_s, match_e - len(site_raw)), 73 | self._clean_string(encoder_raw), 74 | ) 75 | self._part( 76 | "site", 77 | (match_s + len(encoder_raw), match_e), 78 | self._clean_string(site_raw), 79 | overwrite=True, 80 | ) 81 | unmatched = unmatched.replace(match.group(0), "") 82 | 83 | return unmatched 84 | 85 | 86 | def remove_complete_series_string(self, unmatched): 87 | if "title" in self.parts: 88 | complete_series_regex = link_patterns(complete_series) 89 | complete_match = re.search(complete_series_regex, self.parts["title"], flags=re.I) 90 | if complete_match: 91 | title = self.parts["title"] 92 | title = title[: complete_match.start()] + title[complete_match.end() :] 93 | self._part("title", (complete_match.start(), complete_match.end()), self._clean_string(title), overwrite=True) 94 | 95 | return unmatched 96 | 97 | 98 | post_processing_before_excess = [ 99 | remove_complete_series_string, 100 | try_episode_name, 101 | try_encoder_before_site, 102 | ] 103 | 104 | 105 | # After excess functions take in just the parse object, and shouldn't return anything. 106 | 107 | 108 | # encoder is assumed to be the last element of `excess`, if not already added. 109 | def try_encoder(self): 110 | if "excess" not in self.parts or "encoder" in self.parts: 111 | return 112 | excess = self.parts["excess"] 113 | if not isinstance(excess, list): 114 | excess = [excess] 115 | 116 | if excess: 117 | encoder = excess.pop() 118 | self._part("encoder", None, encoder, overwrite=True) 119 | 120 | if not excess: 121 | self.parts.pop("excess") 122 | else: 123 | self._part("excess", None, excess, overwrite=True) 124 | 125 | 126 | # Split encoder name and site, adding the latter to self.parts 127 | def try_site(self): 128 | if "encoder" not in self.parts or "website" in self.parts: 129 | return 130 | encoder = self.parts["encoder"] 131 | if self.coherent_types: 132 | encoder = encoder[0] 133 | pat = r"(\[(.*)\])" 134 | match = re.findall(pat, encoder, re.IGNORECASE) 135 | if match: 136 | match = match[0] 137 | raw = match[0] 138 | if match: 139 | if not re.match(r"[\[\],.+\-]*\Z", match[1], re.IGNORECASE): 140 | self._part("site", None, match[1]) 141 | self._part("encoder", None, encoder.replace(raw, ""), overwrite=True) 142 | 143 | 144 | # If this match starts like the language one did, the only match for language 145 | # and subtitles is a list of langs directly followed by a subs-string. When this 146 | # is true, they would both match on it, but what it likely means is that all the 147 | # langs are language, and the subs string just indicates the existance of subtitles. 148 | # (e.g. Ita.Eng.MSubs would match Ita and Eng for language and subs - this makes 149 | # subs only become MSubs, and leaves language as Ita and Eng) 150 | def fix_same_subtitles_language_match(self): 151 | if ( 152 | "language" in self.part_slices 153 | and "subtitles" in self.part_slices 154 | and self.part_slices["language"][0] == self.part_slices["subtitles"][0] 155 | ): 156 | subs = self.parts["subtitles"][-1] 157 | if self.standardise: 158 | subs = "Available" 159 | self._part("subtitles", None, subs, overwrite=True) 160 | 161 | 162 | # If there are no languages, but subtitles were matched, we should assume the first lang 163 | # is the actual language, and remove it from the subtitles. 164 | def fix_subtitles_no_language(self): 165 | if ( 166 | "language" not in self.parts 167 | and "subtitles" in self.parts 168 | and isinstance(self.parts["subtitles"], list) 169 | and len(self.parts["subtitles"]) > 1 170 | ): 171 | self._part("language", None, self.parts["subtitles"][0]) 172 | self._part("subtitles", None, self.parts["subtitles"][1:], overwrite=True) 173 | 174 | 175 | # Language matches, to support multi-language releases that have the audio with each 176 | # language, will contain audio info (or simply extra strings like 'dub'). 177 | # We remove non-lang matching items from this list. 178 | def filter_non_languages(self): 179 | if "language" in self.parts and isinstance(self.parts["language"], list): 180 | languages = list(self.parts["language"]) 181 | for lang in self.parts["language"]: 182 | matched = False 183 | for (lang_regex, lang_clean) in langs: 184 | if re.match(lang_regex, lang, re.IGNORECASE): 185 | matched = True 186 | break 187 | if not matched: 188 | languages.remove(lang) 189 | 190 | self._part("language", self.part_slices["language"], languages, overwrite=True) 191 | 192 | 193 | def try_vague_season_episode(self): 194 | title = self.parts["title"] 195 | m = re.search("(\d{1,2})-(\d{1,2})$", title) 196 | if m: 197 | if "season" not in self.parts and "episode" not in self.parts: 198 | new_title = title[: m.start()] 199 | offset = self.part_slices["title"][0] 200 | # Setting the match slices here doesn't actually matter, but good practice. 201 | self._part( 202 | "season", (offset + m.start(1), offset + m.end(1)), int(m.group(1)) 203 | ) 204 | self._part( 205 | "episode", (offset + m.start(2), offset + m.end(2)), int(m.group(2)) 206 | ) 207 | self._part( 208 | "title", 209 | (offset, offset + len(new_title)), 210 | self._clean_string(new_title), 211 | overwrite=True, 212 | ) 213 | 214 | 215 | # Probably for movies like 1917, where the title is just the year (would need the release year to also be absent) 216 | def use_year_as_title_if_absent(self): 217 | if "year" in self.parts and not self.parts.get("title"): 218 | self._part("title", None, str(self.parts["year"]), overwrite=True) 219 | self.parts.pop("year") 220 | 221 | 222 | def remove_empty_parts(self): 223 | non_empty_parts = {} 224 | for part in self.parts: 225 | if self.parts[part] != "": 226 | non_empty_parts[part] = self.parts[part] 227 | 228 | self.parts = non_empty_parts 229 | 230 | 231 | post_processing_after_excess = [ 232 | try_encoder, 233 | try_site, 234 | fix_same_subtitles_language_match, 235 | fix_subtitles_no_language, 236 | filter_non_languages, 237 | try_vague_season_episode, 238 | use_year_as_title_if_absent, 239 | remove_empty_parts, 240 | ] 241 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # parse-torrent-title 2 | 3 | > Extract media information from torrent-like filename 4 | 5 | ![Python versions](https://img.shields.io/badge/Python-2.7%2C%203.5-brightgreen.svg?style=flat-square) 6 | 7 | Originally based off of [this JavaScript 8 | library](https://github.com/jzjzjzj/parse-torrent-name). 9 | 10 | Extract all possible media information from a filename. Multiple regex 11 | rules are applied on the filename, each of which extracts appropriate 12 | information. If a rule matches, the corresponding part 13 | is removed from the filename. Finally, what remains is taken as the 14 | title of the content. 15 | 16 | 17 | ## Install 18 | 19 | PTN can be installed automatically using `pip`. 20 | 21 | ```sh 22 | $ pip install parse-torrent-title 23 | ``` 24 | 25 | ### Requirements 26 | 27 | Requirements are **optional**. That being said, the `regex` library increases performance on Python 2 by more than 10x, so it might be worth installing with: 28 | 29 | ```sh 30 | $ pip install -r requirements.txt 31 | ``` 32 | 33 | With Python 3, the default `re` module is faster than `regex`, so it will always be used regardless of installed requirements. 34 | 35 | ## Why? 36 | 37 | Online APIs by providers like 38 | [TMDb](https://www.themoviedb.org/documentation/api), 39 | [TVDb](http://thetvdb.com/wiki/index.php?title=Programmers_API), and 40 | [OMDb](http://www.omdbapi.com/) don't react well to 41 | queries which include any kind of extra information. To get proper results from 42 | these APIs, only the title of the content should be provided in the search 43 | query. The accuracy of the results can be 44 | improved by passing in the year, which can also be extracted using this library. 45 | 46 | ## Examples 47 | 48 | Movies, series (seasons & episodes), and subtitles can be parsed. All meaningful information is 49 | extracted and returned in a dictionary. Text which couldn't be 50 | parsed is returned in the `excess` field. 51 | 52 | ```py 53 | import PTN 54 | 55 | 56 | PTN.parse('The Walking Dead S05E03 720p HDTV x264-ASAP[ettv]') 57 | # { 58 | # 'encoder': 'ASAP', 59 | # 'title': 'The Walking Dead', 60 | # 'season': 5, 61 | # 'episode': 3, 62 | # 'resolution': '720p', 63 | # 'codec': 'H.264', 64 | # 'quality': 'HDTV', 65 | # 'website': 'ettv' 66 | # } 67 | 68 | PTN.parse('Vacancy (2007) 720p Bluray Dual Audio [Hindi + English] ⭐800 MB⭐ DD - 2.0 MSub x264 - Shadow (BonsaiHD)') 69 | # { 70 | # 'encoder': 'Shadow', 71 | # 'title': 'Vacancy', 72 | # 'resolution': '720p', 73 | # 'codec': 'H.264', 74 | # 'year': 2007, 75 | # 'audio': 'Dolby Digital 2.0', 76 | # 'quality': 'Blu-ray', 77 | # 'language': ['Hindi', 'English'], 78 | # 'subtitles': 'Available', 79 | # 'size': 800MB, 80 | # 'website': BonsaiHD 81 | # 'excess': '⭐⭐' 82 | # } 83 | 84 | PTN.parse('Deadliest.Catch.S00E66.No.Safe.Passage.720p.AMZN.WEB-DL.DDP2.0.H.264-NTb[TGx]') 85 | # { 86 | # 'encoder': 'NTb', 87 | # 'title': 'Deadliest Catch', 88 | # 'resolution': '720p', 89 | # 'codec': 'H.264', 90 | # 'audio' : 'Dolby Digital Plus 2.0', 91 | # 'network': 'Amazon Studios', 92 | # 'season': 0, 93 | # 'episode': 66, 94 | # 'quality': 'WEB-DL', 95 | # 'episodeName': 'No Safe Passage', 96 | # 'website': 'TGx' 97 | # } 98 | 99 | PTN.parse('Insecure.S04.COMPLETE.720p.AMZN.WEBRip.x264-GalaxyTV') 100 | # { 101 | # 'title': 'Insecure' 102 | # 'encoder': 'GalaxyTV', 103 | # 'codec': 'H.264', 104 | # 'season': 4, 105 | # 'resolution': '720p', 106 | # 'network': 'Amazon Studios', 107 | # 'quality': 'WEBRip', 108 | # } 109 | ``` 110 | 111 | More examples (inputs and outputs) can be found looking through `tests/files`. 112 | 113 | ## CLI 114 | 115 | You can use PTN from your command line, where the output will be printed as JSON: 116 | 117 | ```sh 118 | $ python cli.py 'Insecure.S04.COMPLETE.720p.AMZN.WEBRip.x264-GalaxyTV' 119 | 120 | { 121 | 'title': 'Insecure' 122 | 'encoder': 'GalaxyTV', 123 | 'codec': 'H.264', 124 | 'season': 4, 125 | 'resolution': '720p', 126 | 'network': 'Amazon Studios', 127 | 'quality': 'WEBRip', 128 | } 129 | ``` 130 | 131 | For help, use the `-h` or `--help` flag: 132 | 133 | ```sh 134 | $ python cli.py --help 135 | ``` 136 | 137 | This will provide a brief overview of the available options and their usage. 138 | 139 | ### Raw info 140 | 141 | The matches in the torrent name are standardised into specific strings, according to scene rules where possible - `'WEBDL'`, `'WEB DL'`, and `'HDRip'` are all converted to `'WEB-DL'`, for example. `'DDP51'` becomes `'Dolby Digital Plus 5.1'`. `['ita', 'eng']` becomes `['Italian', 'English']`.To disable this, and return just what was matched in the torrent, run: 142 | 143 | ```py 144 | PTN.parse('A freakishly cool movie or TV episode', standardise=False) 145 | ``` 146 | 147 | In the CLI, you can use the `--raw` flag: 148 | 149 | ```sh 150 | $ python cli.py --raw 'A freakishly cool movie or TV episode' 151 | ``` 152 | 153 | ### Types of parts 154 | 155 | The types of parts can be strings, integers, booleans, or lists of the first 2. To simplify this, you can enable the `coherent_types` flag. This will override the types described below according to these rules: 156 | - `title` and `episodeName` will always be strings. 157 | - All other non-boolean fields will become lists of the type they currently are. For example, `language` will always be a list of strings, and `episode` a list of episodes. This can be weird for some fields, but it avoids a lot of `isinstance` calls - just always use `x in y` and you should be fine. 158 | - Boolean types will remain as booleans. 159 | 160 | To enable this flag: 161 | ```py 162 | PTN.parse('An even cooler movie or TV episode', coherent_types=True) 163 | ``` 164 | 165 | In the CLI, you can use the `--coherent-types` flag: 166 | 167 | ```sh 168 | $ python cli.py --coherent-types 'A freakishly cool movie or TV episode' 169 | ``` 170 | 171 | ### Parts extracted 172 | 173 | * **audio** *(string)* 174 | * **bitDepth** *(integer)* 175 | * **codec** *(string)* 176 | * **day** *(integer)* 177 | * **directorsCut** *(boolean)* 178 | * **documentary** *(boolean)* 179 | * **encoder** *(string)* 180 | * **episode** *(integer, integer list)* 181 | * **episodeName** *(string)* 182 | * **excess** *(string, string list)* 183 | * **extended** *(boolean)* 184 | * **filetype** *(string)* 185 | * **fps** *(integer)* 186 | * **genre** *(string, string list)* 187 | * **hardcoded** *(boolean)* 188 | * **hdr** *(boolean)* 189 | * **internal** *(boolean)* 190 | * **internationalCut** *(boolean)* 191 | * **language** *(string, string list)* 192 | * **limited** *(boolean)* 193 | * **month** *(integer)* 194 | * **network** *(string)* 195 | * **proper** *(boolean)* 196 | * **quality** *(string)* 197 | * **readnfo** *(boolean)* 198 | * **region** *(string)* 199 | * **remastered** *(boolean)* 200 | * **remux** *(boolean)* 201 | * **repack** *(boolean)* 202 | * **resolution** *(string)* 203 | * **sbs** *(string)* 204 | * **season** *(integer, integer list)* 205 | * **site** *(string)* 206 | * **size** *(string)* 207 | * **subtitles** *(string, string list)* 208 | * **title** *(string)* 209 | * **unrated** *(boolean)* 210 | * **untouched** *(boolean)* 211 | * **upscaled** *(boolean)* 212 | * **widescreen** *(boolean)* 213 | * **year** *(integer)* 214 | * **3d** *(boolean)* 215 | 216 | ## Contributing 217 | 218 | Submit a PR on the `dev` branch, including tests for what gets newly matched (if applicable), having run the `pre-commit` hooks. Add the titles you want to add to the tests in `tests/test_generator`'s main method (in `add_titles()`), it will automatically add what's needed to `files/input.json`, `files/output_raw.json`, and `files/output_standard.json`. The fields `encoder`, `excess`, `site`, and `episodeName` don't always have to be correct - if they're giving you issues, or seem wrong, feel free to remove them from the output test files. 219 | 220 | (What it does: `add_titles()` adds input torrent names to `tests/files/input.json` and full output json objects (with `standardise=False`) to `tests/files/output_raw.json`. It also adds the standardised output to `tests/files/output_standard.json`, only including fields that are changed, along with `title`.) 221 | 222 | ## Additions to parse-torrent-name 223 | 224 | Below are the additions that have been made to [/u/divijbindlish's original repo](https://github.com/divijbindlish/parse-torrent-name), including other contributors' work. parse-torrent-title was initially forked from [here](https://github.com/roidayan/parse-torrent-name/tree/updates), but a lot of extra work has been done since, and given that the original repo is inactive, it was unforked. 225 | 226 | ### Updates on top of [/u/roidayan's work](https://github.com/roidayan/parse-torrent-name/tree/updates) 227 | 228 | - Added standardisation of output strings. 229 | - Added multi-language support. 230 | - Added multi-episode support. 231 | - Added a basic CLI. 232 | - Added thread safety. 233 | - Improved support for anime tv releases. 234 | - Improved support for Indian releases. 235 | - Added various fields (see field list above). 236 | - Added proper subtitle support. 237 | - Added proper support for matching episode names. 238 | - Added support for full `YYYY-MM-DD`-type dates, usually useful for daily shows that otherwise have no episode name. 239 | - Added support for 2020s release years. 240 | - Added exceptions list for media with known, non-fixable issues. 241 | - Expanded and improved matching for various fields. 242 | - Fixed incorrect parsing of titles containing years. 243 | - Fixed groups/encoders/websites mixups: a group/encoder is now just called an encoder, and a public tracker site goes under website. 244 | - Added more tests and cleaned up previous ones. 245 | 246 | 247 | ### [/u/roidayan's work](https://github.com/roidayan/parse-torrent-name/tree/updates) on top of [the original](https://github.com/divijbindlish/parse-torrent-name) 248 | 249 | - Added support for complete season parsing (either just a full season, or a range), not just single episodes. 250 | - Added to various fields' patterns. 251 | - Improved season & episode matching. 252 | - Fixed group names from having the container & bt site name. 253 | - Added more tests. 254 | 255 | ## License 256 | 257 | MIT © 2015-2017 [Divij Bindlish](http://divijbindlish.in) 258 | 259 | MIT © 2020 [Giorgio Momigliano](https://github.com/platelminto) 260 | -------------------------------------------------------------------------------- /PTN/patterns.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Patterns are either just a regex, or a tuple (or list of tuples) that contain the regex 4 | # to match, (optional) what it should be replaced with (None if to not replace), and 5 | # (optional) a string function's name to transform the value after everything (None if 6 | # to do nothing). The transform can also be a tuple (or list of tuples) with function names 7 | # and list of arguments. 8 | # The list of regexes all get matched, but only the first gets added to the returning info, 9 | # the rest are just matched to be removed from `excess`. 10 | 11 | from .extras import ( 12 | delimiters, 13 | genres, 14 | get_channel_audio_options, 15 | langs, 16 | link_patterns, 17 | suffix_pattern_with, 18 | ) 19 | 20 | season_range_pattern = ( 21 | "(?:Complete" 22 | + delimiters 23 | + "*)?" 24 | + delimiters 25 | + "*(?:s(?:easons?)?)" 26 | + delimiters 27 | + "*(?:s?[0-9]{1,2}[\s]*(?:(?:\-|(?:\s*to\s*))[\s]*s?[0-9]{1,2}))(?:" 28 | + delimiters 29 | + "*Complete)?" 30 | ) 31 | 32 | year_pattern = "(?:19[0-9]|20[0-2])[0-9]" 33 | month_pattern = "0[1-9]|1[0-2]" 34 | day_pattern = "[0-2][0-9]|3[01]" 35 | 36 | episode_name_pattern = ( 37 | "((?:[Pp](?:ar)?t" 38 | + delimiters 39 | + "*[0-9]|(?:[A-Za-z]|[0-9])[a-z]*(?:" 40 | + delimiters 41 | + "|$))+)" 42 | ) 43 | pre_website_encoder_pattern = r"[^\s\.\[\]\-\(\)]+\)\s*\[[^\s\-]+\]|[^\s\.\[\]\-\(\)]+\s*(?:-\s)?[^\s\.\[\]\-]+$" 44 | 45 | # Forces an order to go by the regexes, as we want this to be deterministic (different 46 | # orders can generate different matchings). e.g. "doctor_who_2005..." in input.json 47 | patterns_ordered = [ 48 | "resolution", 49 | "quality", 50 | "season", 51 | "episode", 52 | "year", 53 | "month", 54 | "day", 55 | "codec", 56 | "audio", 57 | "region", 58 | "extended", 59 | "hardcoded", 60 | "proper", 61 | "repack", 62 | "filetype", 63 | "widescreen", 64 | "sbs", 65 | "site", 66 | "documentary", 67 | "language", 68 | "subtitles", 69 | "unrated", 70 | "size", 71 | "bitDepth", 72 | "3d", 73 | "internal", 74 | "readnfo", 75 | "network", 76 | "fps", 77 | "hdr", 78 | "limited", 79 | "remastered", 80 | "directorsCut", 81 | "upscaled", 82 | "untouched", 83 | "remux", 84 | "internationalCut", 85 | "genre", 86 | ] 87 | 88 | 89 | # Some patterns overlap with others. Season & episode do this a lot. Without something like this, we'd get issues like 90 | # the Avatar test: ... Complete Series 1080p ... 'Series 10' would be matched as a season, but the 10 is 91 | # from 1080p, which also gets matched. 92 | patterns_allow_overlap = [ 93 | "season", 94 | "episode", 95 | "language", 96 | "subtitles", 97 | "sbs" 98 | ] 99 | 100 | patterns = {} 101 | patterns["episode"] = [ 102 | r"(? 1: 220 | # for season we might have it in index 1 or index 2 221 | # e.g. "5x09" TODO is this weirdness necessary 222 | for i in range(1, len(match)): 223 | if match[i]: 224 | index["clean"] = i 225 | break 226 | 227 | return index 228 | 229 | @staticmethod 230 | def get_season_episode(match): 231 | clean = None 232 | m = re.findall(r"[0-9]+", match[0]) 233 | if m and len(m) > 1: 234 | clean = list(range(int(m[0]), int(m[-1]) + 1)) 235 | # This elif exists entirely for the Seasons 1, 2, 3, 4, etc. case. No other regex gives a number in match[1]. 236 | elif len(match) > 1 and match[1] and m: 237 | clean = list(range(int(m[0]), int(match[1]) + 1)) 238 | elif m: 239 | clean = int(m[0]) 240 | 241 | return clean 242 | 243 | @staticmethod 244 | def split_multi(match): 245 | m = re.split(r"{}+".format(delimiters), match[0]) 246 | clean = list(filter(None, m)) 247 | 248 | return clean 249 | 250 | @staticmethod 251 | def get_subtitles(match): 252 | # handle multi subtitles 253 | m = re.split(r"{}+".format(delimiters), match[0]) 254 | m = list(filter(None, m)) 255 | clean = [] 256 | # If it's only 1 result, it's fine if it's just 'subs'. 257 | if len(m) == 1: 258 | clean = m 259 | else: 260 | for x in m: 261 | if not re.match("subs?|soft", x, re.I): 262 | clean.append(x) 263 | 264 | return clean 265 | 266 | def standardise_clean(self, clean, key, replace, transforms): 267 | if replace: 268 | clean = replace 269 | if transforms: 270 | for transform in filter(lambda t: t[0], transforms): 271 | # For python2 compatibility, we're not able to simply pass functions as str.upper 272 | # means different things in 2.7 and 3.5. 273 | clean = getattr(clean, transform[0])(*transform[1]) 274 | if key == "language" or key == "subtitles": 275 | clean = self.standardise_languages(clean) 276 | if not clean: 277 | clean = "Available" 278 | if key == "genre": 279 | clean = self.standardise_genres(clean) 280 | return clean 281 | 282 | @staticmethod 283 | def standardise_languages(clean): 284 | cleaned_langs = [] 285 | for lang in clean: 286 | for (lang_regex, lang_clean) in langs: 287 | if re.match( 288 | lang_regex, 289 | re.sub( 290 | link_patterns(patterns["subtitles"][-2:]), "", lang, flags=re.I 291 | ), 292 | re.IGNORECASE, 293 | ): 294 | cleaned_langs.append(lang_clean) 295 | break 296 | clean = cleaned_langs 297 | return clean 298 | 299 | @staticmethod 300 | def standardise_genres(clean): 301 | standard_genres = [] 302 | for genre in clean: 303 | for (regex, clean) in genres: 304 | if re.match(regex, genre, re.IGNORECASE): 305 | standard_genres.append(clean) 306 | break 307 | return standard_genres 308 | 309 | # Merge all the match slices (such as when they overlap), then remove 310 | # them from excess. 311 | def merge_match_slices(self): 312 | matches = sorted(self.match_slices, key=lambda match: match[0]) 313 | 314 | i = 0 315 | slices = [] 316 | while i < len(matches): 317 | start, end = matches[i] 318 | i += 1 319 | for (next_start, next_end) in matches[i:]: 320 | if next_start <= end: 321 | end = max(end, next_end) 322 | i += 1 323 | else: 324 | break 325 | slices.append((start, end)) 326 | 327 | self.match_slices = slices 328 | 329 | def process_title(self): 330 | unmatched = self.unmatched_list(keep_punctuation=False) 331 | 332 | # Use the first one as the title 333 | if unmatched: 334 | title_start, title_end = unmatched[0][0], unmatched[0][1] 335 | 336 | # If our unmatched is after the first 3 matches, we assume the title is missing 337 | # (or more likely got parsed as something else), as no torrents have it that 338 | # far away from the beginning of the release title. 339 | if ( 340 | len(self.part_slices) > 3 341 | and title_start 342 | > sorted(self.part_slices.values(), key=lambda s: s[0])[3][0] 343 | ): 344 | self._part("title", None, "") 345 | 346 | raw = self.torrent_name[title_start:title_end] 347 | # Something in square brackets with 3 chars or fewer is too weird to be right. 348 | # If this seems too arbitrary, make it any square bracket, and Mother test 349 | # case will lose its translated title (which is mostly fine I think). 350 | m = re.search(r"\(|(?:\[(?:.{,3}\]|[^\]]*\d[^\]]*\]?))", raw, flags=re.I) 351 | if m: 352 | relative_title_end = m.start() 353 | raw = raw[:relative_title_end] 354 | title_end = relative_title_end + title_start 355 | # Similar logic as above, but looking at beginning of string unmatched brackets. 356 | m = re.search(r"^(?:\)|\[.*\])", raw) 357 | if m: 358 | relative_title_start = m.end() 359 | raw = raw[relative_title_start:] 360 | title_start = relative_title_start + title_start 361 | clean = self._clean_string(raw) 362 | # Re-add title_start to unrelative the index from raw to self.torrent_name 363 | self._part("title", (title_start, title_end), clean) 364 | else: 365 | self._part("title", None, "") 366 | 367 | def unmatched_list(self, keep_punctuation=True): 368 | self.merge_match_slices() 369 | unmatched = [] 370 | prev_start = 0 371 | # A default so the last append won't crash if nothing has matched 372 | end = len(self.torrent_name) 373 | # Find all unmatched strings that aren't just punctuation 374 | for (start, end) in self.match_slices: 375 | if keep_punctuation or not re.match( 376 | delimiters + r"*\Z", self.torrent_name[prev_start:start] 377 | ): 378 | unmatched.append((prev_start, start)) 379 | prev_start = end 380 | 381 | # Add the last unmatched slice 382 | if keep_punctuation or not re.match( 383 | delimiters + r"*\Z", self.torrent_name[end:] 384 | ): 385 | unmatched.append((end, len(self.torrent_name))) 386 | 387 | # If nothing matched, assume the whole thing is the title 388 | if not self.match_slices: 389 | unmatched.append((0, len(self.torrent_name))) 390 | 391 | return unmatched 392 | 393 | def fix_known_exceptions(self): 394 | # Considerations for results that are known to cause issues, such 395 | # as media with years in them but without a release year. 396 | for exception in exceptions: 397 | incorrect_key, incorrect_value = exception["incorrect_parse"] 398 | if ( 399 | self.parts["title"] == exception["parsed_title"] 400 | and incorrect_key in self.parts 401 | ): 402 | if self.parts[incorrect_key] == incorrect_value or ( 403 | self.coherent_types and incorrect_value in self.parts[incorrect_key] 404 | ): 405 | self.parts.pop(incorrect_key) 406 | self._part("title", None, exception["actual_title"], overwrite=True) 407 | 408 | def get_unmatched(self): 409 | unmatched = "" 410 | for (start, end) in self.unmatched_list(): 411 | unmatched += self.torrent_name[start:end] 412 | 413 | return unmatched 414 | 415 | def clean_unmatched(self): 416 | unmatched = [] 417 | for (start, end) in self.unmatched_list(): 418 | unmatched.append(self.torrent_name[start:end]) 419 | 420 | unmatched_clean = [] 421 | for raw in unmatched: 422 | clean = re.sub(r"(^[-_.\s(),]+)|([-.\s,]+$)", "", raw) 423 | clean = re.sub(r"[()/]", " ", clean) 424 | unmatched_clean += re.split(r"\.\.+|\s+", clean) 425 | 426 | filtered = [] 427 | for extra in unmatched_clean: 428 | # re.fullmatch() is not available in python 2.7, so we manually do it with \Z. 429 | if not re.match( 430 | r"(?:Complete|Season|Full)?[\]\[,.+\- ]*(?:Complete|Season|Full)?\Z", 431 | extra, 432 | re.IGNORECASE, 433 | ): 434 | filtered.append(extra) 435 | return filtered 436 | -------------------------------------------------------------------------------- /tests/files/input.json: -------------------------------------------------------------------------------- 1 | [ 2 | "The Walking Dead S05E03 720p HDTV x264-ASAP[ettv]", 3 | "Hercules (2014) 1080p BrRip H264 - YIFY", 4 | "Dawn.of.the.Planet.of.the.Apes.2014.HDRip.XViD-EVO", 5 | "The Big Bang Theory S08E06 HDTV XviD-LOL [eztv]", 6 | "22 Jump Street (2014) 720p BrRip x264 - YIFY", 7 | "Hercules.2014.EXTENDED.1080p.WEB-DL.DD5.1.H264-RARBG", 8 | "Hercules.2014.Extended.Cut.HDRip.XViD-juggs[ETRG]", 9 | "Hercules (2014) WEBDL DVDRip XviD-MAX", 10 | "WWE Hell in a Cell 2014 PPV WEB-DL x264-WD -={SPARROW}=-", 11 | "UFC.179.PPV.HDTV.x264-Ebi[rartv]", 12 | "Marvels Agents of S H I E L D S02E05 HDTV x264-KILLERS [eztv]", 13 | "X-Men.Days.of.Future.Past.2014.1080p.WEB-DL.DD5.1.H264-RARBG", 14 | "Guardians Of The Galaxy 2014 R6 720p HDCAM x264-JYK", 15 | "Marvel's.Agents.of.S.H.I.E.L.D.S02E01.Shadows.1080p.WEB-DL.DD5.1", 16 | "Marvels Agents of S.H.I.E.L.D. S02E06 HDTV x264-KILLERS[ettv]", 17 | "Guardians of the Galaxy (CamRip / 2014)", 18 | "The.Walking.Dead.S05E03.1080p.WEB-DL.DD5.1.H.264-Cyphanix[rartv]", 19 | "Brave.2012.R5.DVDRip.XViD.LiNE-UNiQUE", 20 | "Lets.Be.Cops.2014.BRRip.XViD-juggs[ETRG]", 21 | "These.Final.Hours.2013.WBBRip XViD", 22 | "Downton Abbey 5x06 HDTV x264-FoV [eztv]", 23 | "Annabelle.2014.HC.HDRip.XViD.AC3-juggs[ETRG]", 24 | "Lucy.2014.HC.HDRip.XViD-juggs[ETRG]", 25 | "The Flash 2014 S01E04 HDTV x264-FUM[ettv]", 26 | "South Park S18E05 HDTV x264-KILLERS [eztv]", 27 | "The Flash 2014 S01E03 HDTV x264-LOL[ettv]", 28 | "The Flash 2014 S01E01 HDTV x264-LOL[ettv]", 29 | "Lucy 2014 Dual-Audio WEBRip 1400Mb", 30 | "Teenage Mutant Ninja Turtles (HdRip / 2014)", 31 | "Teenage Mutant Ninja Turtles (unknown_release_type / 2014)", 32 | "The Simpsons S26E05 HDTV x264 PROPER-LOL [eztv]", 33 | "2047 - Sights of Death (2014) 720p BrRip x264 - YIFY", 34 | "Two and a Half Men S12E01 HDTV x264 REPACK-LOL [eztv]", 35 | "Dinosaur 13 2014 WEBrip XviD AC3 MiLLENiUM", 36 | "Teenage.Mutant.Ninja.Turtles.2014.HDRip.XviD.MP3-RARBG", 37 | "Dawn.Of.The.Planet.of.The.Apes.2014.1080p.WEB-DL.DD51.H264-RARBG", 38 | "Teenage.Mutant.Ninja.Turtles.2014.720p.HDRip.x264.AC3.5.1-RARBG", 39 | "Gotham.S01E05.Viper.WEB-DL.x264.AAC", 40 | "Into.The.Storm.2014.1080p.WEB-DL.AAC2.0.H264-RARBG", 41 | "Lucy 2014 Dual-Audio 720p WEBRip", 42 | "Into The Storm 2014 1080p BRRip x264 DTS-JYK", 43 | "Sin.City.A.Dame.to.Kill.For.2014.1080p.BluRay.x264-SPARKS", 44 | "WWE Monday Night Raw 3rd Nov 2014 HDTV x264-Sir Paul", 45 | "Jack.And.The.Cuckoo-Clock.Heart.2013.BRRip XViD", 46 | "WWE Hell in a Cell 2014 HDTV x264 SNHD", 47 | "Dracula.Untold.2014.TS.XViD.AC3.MrSeeN-SiMPLE", 48 | "The Missing 1x01 Pilot HDTV x264-FoV [eztv]", 49 | "Doctor.Who.2005.8x11.Dark.Water.720p.HDTV.x264-FoV[rartv]", 50 | "Gotham.S01E07.Penguins.Umbrella.WEB-DL.x264.AAC", 51 | "One Shot [2014] DVDRip XViD-ViCKY", 52 | "The Shaukeens 2014 Hindi (1CD) DvDScr x264 AAC...Hon3y", 53 | "The Shaukeens (2014) 1CD DvDScr Rip x264 [DDR]", 54 | "Annabelle.2014.1080p.PROPER.HC.WEBRip.x264.AAC.2.0-RARBG", 55 | "Interstellar (2014) CAM ENG x264 AAC-CPG", 56 | "Guardians of the Galaxy (2014) Dual Audio DVDRip AVI", 57 | "Eliza Graves (2014) Dual Audio WEB-DL 720p MKV x264", 58 | "WWE Monday Night Raw 2014 11 10 WS PDTV x264-RKOFAN1990 -={SPARR", 59 | "Sons.of.Anarchy.S01E03", 60 | "doctor_who_2005.8x12.death_in_heaven.720p_hdtv_x264-fov", 61 | "breaking.bad.s01e01.720p.bluray.x264-reward", 62 | "Game of Thrones - 4x03 - Breaker of Chains", 63 | "[720pMkv.Com]_sons.of.anarchy.s05e10.480p.BluRay.x264-GAnGSteR", 64 | "[ www.Speed.cd ] -Sons.of.Anarchy.S07E07.720p.HDTV.X264-DIMENSION", 65 | "Community.s02e20.rus.eng.720p.Kybik.v.Kybe", 66 | "The.Jungle.Book.2016.3D.1080p.BRRip.SBS.x264.AAC-ETRG", 67 | "Ant-Man.2015.3D.1080p.BRRip.Half-SBS.x264.AAC-m2g", 68 | "Ice.Age.Collision.Course.2016.READNFO.720p.HDRIP.X264.AC3.TiTAN", 69 | "Red.Sonja.Queen.Of.Plagues.2016.BDRip.x264-W4F[PRiME]", 70 | "The Purge: Election Year (2016) HC - 720p HDRiP - 900MB - ShAaNi", 71 | "War Dogs (2016) HDTS 600MB - NBY", 72 | "The Hateful Eight (2015) 720p BluRay - x265 HEVC - 999MB - ShAaN", 73 | "The.Boss.2016.UNRATED.720p.BRRip.x264.AAC-ETRG", 74 | "Return.To.Snowy.River.1988.iNTERNAL.DVDRip.x264-W4F[PRiME]", 75 | "Akira (2016) - UpScaled - 720p - DesiSCR-Rip - Hindi - x264 - AC3 - 5.1 - Mafiaking - M2Tv", 76 | "Ben Hur 2016 TELESYNC x264 AC3 MAXPRO", 77 | "The.Secret.Life.of.Pets.2016.HDRiP.AAC-LC.x264-LEGi0N", 78 | "The.X-Files.S01.Retail.DKsubs.720p.BluRay.x264-RAPiDCOWS", 79 | "The.X-Files.S01-S03.DKsubs.1080p.BluRay.HEVC.x265", 80 | "The.X-Files.Complete.S01-S09.1080p.BluRay.x264-GECKOS", 81 | "The.Flash.2014.S03.720p.HDTV.x264-Scene", 82 | "Boku.Unmei.no.Hito.desu.Ep07.Chi_Jap.HDTVrip.1280X720-ZhuixinFan.mp4", 83 | "Blind.2017.NORDiC.720p.BluRay.x264.DTS5.1-TWA", 84 | "Family.Guy.S17.Complete.Season.17.x264.720p", 85 | "South Park Season 23 Complete 720p AMZN WEB-DL x264 [i_c]", 86 | "Borgen-Season 1-[2010].x264.DVDrip", 87 | "Bumbibjornarna.COMPLETE.S02.SWEDiSH.DVDRip.XviD-Rezar1337", 88 | "The Martian 2015 540p HDRip KORSUB x264 AAC2 0-FGT", 89 | "Borgen S1E9 - Divide and Rule ('Del og hersk').mp4", 90 | "The.Legend.of.1900.1998.1080p.BluRay.H264.AAC-RARBG", 91 | "2001.A.Space.Odyssey.1968.iNTERNAL.1080p.BluRay.x264-MANNEKEPiS", 92 | "Impractical.Jokers.The.Movie.2020.1080p.WEBRip.x264.AAC5.1", 93 | "1983 - Season 1 - Polish - 1080p AAC5.1 - NF WEB-DL - X264-Rapta", 94 | "The Bridge (Bron Broen) S01 Season 1 BRRip x264 AAC E-Subs [GWC]", 95 | "The.Meg.2018.1080p.HDRip.x264.[ExYu-Subs]", 96 | "Dragon Ball Super: Broly (2018) CAM-Rip English Subs x264 - KatmovieHD.Pw", 97 | "Joker(2019) English HC 720p HDRip x264 [ Hindi - Eng Multi Subs] Shadow (HDWebmovies)", 98 | "IP Man And Four Kings 2019 HDRip 1080p x264 AAC Mandarin HC CHS-ENG SUBS Mp4Ba", 99 | "American Dad! S01 - S13 Complete", 100 | "The Simpsons - Season 1 Complete [DVDrip ITA ENG] TNT Village", 101 | "The Simpsons - Complete Seasons S01 to S28 (1080p, 720p, DVDRip)", 102 | "Stephen.Colbert.2020.04.02.Alicia.Keys.HDTV.x264-SORNY[TGx]", 103 | "Jimmy.Not.Funny.2017.08.01.Jerry.Benner.720p.HDTV.x264-SORNY[eztv].mkv", 104 | " Tom.Clancys.Jack.Ryan.S02.COMPLETE.720p.AMZN.WEBRip.x264-GalaxyTV[TGx] ", 105 | "Sacred Games 2018 S01 Complete Season 1 Hindi 720p NetFlix x264 DDP 5.1 ESub - xRG", 106 | "Homeland.Season.1-4.Complete.720p.HDTV.X264-MRSK", 107 | "Home Before Dark (2020) S01 (1080p ATVP Webrip x265 10bit EAC3 5.1 - ArcX)[TAoE]", 108 | "Our.Girl.S05E03.HDTV.x264-RiVER[TGx]", 109 | "Roswell.New.Mexico.S02E04.480p.x264-ZMNT", 110 | "Coyote.Peterson-Brave.the.Wild.S01E00.Coyotes.Journal.Coyote.And.His.Faithful.Crew.iNTERNAL.WEB.x264-ROBOTS[TGx]", 111 | "The.Blacklist.S07e05-06.ITA.ENG.1080p.AMZN.WEB-DLMux.DD5.1.H264-MeM", 112 | "Are You Being Served (1972) Season 1-10 S01-S10 + Extras (576p AMZN WEB-DL x265 HEVC 10bit EAC3 2.0 MONOLITH) [QxR]", 113 | "Empire.2015.S06E16.WEB.H264-iNSiDiOUS[TGx]", 114 | "Mixed-ish.S01E20.XviD-AFG[TGx]", 115 | "Marvels Iron Fist S02 Complete 720p WEB-DL x264 [4.3GB] [MP4] [Season 2]", 116 | "Dag.Vreemde.Man.2016.1080p.BluRay.x264-BARGAiN[EtHD]", 117 | "Boi.2016.1080p.BluRay.x264-BARGAiN[EtHD]", 118 | "Label.Me.2019.720p.AMZN.WEBRip.800MB.x264-GalaxyRG", 119 | "A.Touch.Of.Cloth.S03E01-E02.720p.WEB.h264-FaiLED[TGx]", 120 | "The Hand Bag (2020) HDRip x264 - SHADOW[TGx]", 121 | "Z Nation (2014)S01-01-13 (2014) Full Season.XviD - Italian English.Ac3.Sub.ita.eng.MIRCrew", 122 | "1917 (2019) [BluRay Rip 1080p ITA-ENG AC3 SUBS] [[email protected]]", 123 | "Johnny.English.2003.1080p.BluRay.x264-[YTS.AG]", 124 | "Johnny.English.Reborn.2011.1080p.BRRip.x264 [MovieOW]", 125 | "Johnny.English.Strikes.Again.2018.1080p.BluRay.x264-[YTS.AM]", 126 | "The French Connection (1971) Remastered 1080p BluRay x265 HEVC EAC3-SARTRE", 127 | "The Thin Blue Line 1995 S01-S02 Complete DVDRip H264 BONE", 128 | "Heavy.Rescue.401.S02E10.480p.x264-mSD[TGx]", 129 | "Coronation Street 2020 1080p (Deep61)[TGx]", 130 | "Deadliest.Catch.S00E66.No.Safe.Passage.720p.AMZN.WEB-DL.DDP2.0.H.264-NTb[TGx]", 131 | "New.Girl.S07.Season.7.Complete.1080p.NF.WEB.x264-maximersk [mrsktv]", 132 | "Accused.Guilty.or.Innocent.S01E07.Murdered.His.Mother.or.Falsely.Accused.Pt2.HDTV.x264-CRiMSON[TGx]", 133 | "The Peacemaker (1997)Mp-4-X264-Dvd-Rip-480p-AAC-DSD", 134 | "The Big Bus - Il fantabus (1976).720p.H264.ita.eng.Ac3.sub.ita.eng-MIRCrew", 135 | "The Hunt (2020) BluRay 1080p.H264 Ita Eng AC3 5.1 Sub Ita Eng MIRCrew", 136 | "Near.Death.2004.1080p.BluRay.H264.AAC-RARBG", 137 | "The.Red.Pony.1949.1080p.BluRay.H264.AAC-RARBG", 138 | "We Were Soldiers 2002 720p BluRay HEVC H265 BONE", 139 | "Diabolique (1996).720p.H264.ita.eng.Ac3-5.1.sub.ita.eng-MIRCrew", 140 | "Road.House.2.Last.Call.2006.Unrated.1080p.HDTV.H264.AC3.DD2.0.Will1869", 141 | "We.Summon.The.Darkness.2020.1080p.Bluray.Atmos.TrueHD.7.1.x264-EVO[TGx]", 142 | "37\u00b02 le matin - Betty Blue (1986) Director's Cut.720p.H264.ita.fre.sub.Eng-MIRCrew", 143 | "Non-Fiction.2018.1080p.BluRay.x264-USURY", 144 | "Spring.Night.Summer.Night.1967.BDRip.x264-GHOULS[TGx]", 145 | "Insecure.S04.COMPLETE.720p.AMZN.WEBRip.x264-GalaxyTV", 146 | "Let.It.Fall.Los.Angeles.1982-1992.2017.DOCU.iNTERNAL.HDTV.x264-W4F[rartv]", 147 | "Dr.Phil.2019.04.19.720p.HDTV.x264-W4F[rartv]", 148 | "Starhunter.ReduX.S02.1080p.AMZN.WEBRip.DDP5.1.x264-GLUE[rartv]", 149 | "Jimmy.Fallon.2020.06.16.Gwyneth.Paltrow.720p.WEB.h264-TRUMP[TGx]", 150 | "Kami no Tou - S01E12-Judas[TGx]", 151 | "EastEnders.2020.06.16.WEB.h264-WEBTUBE[TGx]", 152 | "Lost.Gold.of.World.War.II.S02E07.WEB.h264-TRUMP[TGx]", 153 | "Plunderer - 23 (360p)-HorribleSubs[TGx]", 154 | "[Golumpa] Blood Blockade Battlefront & Beyond - 08 (Kekkai Sensen & Beyond) [FuniDub 1080p x264 AAC] [78481C9C].mkv (1.4 GB)", 155 | "Tower of God - 12 (480p)-HorribleSubs[TGx]", 156 | "Kami no Tou - 12 (720p)(Multiple Subtitle)-Erai-raws[TGx]", 157 | "Plunderer - 23 (1080p)(HEVC x265 10bit)(Eng-Subs)-Judas[TGx]", 158 | "Tamayomi - 12 (360p)-HorribleSubs[TGx]", 159 | "Ahiru no Sora - 36 (480p)-HorribleSubs[TGx]", 160 | "Shadowverse - 11 (720p)(Multiple Subtitle)-Erai-raws[TGx]", 161 | "A3! Season Spring & Summer - 11 (360p)-HorribleSubs[TGx]", 162 | "Kitsutsuki Tanteidokoro - 10 (720p)(Multiple Subtitle)-Erai-raws[TGx]", 163 | "Princess Connect! Re-Dive - 11 (720p)(Multiple Subtitle)-Erai-raws[TGx]", 164 | "Fruits Basket S2 (2019) - 11 (720p)-HorribleSubs[TGx]", 165 | "Kadakh (2020) Hindi 720p SonyLiv WEB-DL \u2b501.1 GB\u2b50 AAC DD- 2.0 ESub x264 - Shadow (BonsaiHD)", 166 | "Satyagraha (2013) (1080p BluRay x265 10bit HEVC AAC 5.1 RONIN)", 167 | "Shuddh Desi Romance 2013 Hindi 720p BluRay x264 AAC 5.1 MSubs - LOKiHD - Telly", 168 | "Face 2 Face (2019) Kannada HDRip - 720p - x264 - DD5.1 - 1.1GB - ESub - TamilMV", 169 | "Chaman Bahar (2020) Hindi 720p NF WEBRip \u2b50800 MB\u2b50 DD- 5.1 ESub x264 - Shadow (BonsaiHD)", 170 | "Piprabidya (2013) Bengali 720p Hoichoi WEB-DL \u2b50650 MB\u2b50 AAC DD- 2.0 ESub x264 - Shadow (BonsaiHD)", 171 | "Penguin (2020) Tamil 720p AMZN WEBRip \u2b501.1 GB\u2b50 AAC DD- 5.1 ESub x264 - Shadow (BonsaiHD)", 172 | "Kadakh 2020 Hindi 1080p WEBRip x264 AC3 ESubs - LOKiHD - Telly", 173 | "Satyagraha (2013) (1080p BluRay x265 10bit HEVC AAC 5.1 RONIN)", 174 | "Kavacham (2018) Proper HDRip - x264 - [Tamil + Telugu + Hindi] - 750MB - ESub - TamilMV", 175 | "M.S. Dhoni: The Untold Story (2016) BR-Rip - x264 - [Telugu + Tamil] - 450MB - ESub - TamilMV", 176 | "M.S. Dhoni: The Untold Story (2016) BluRay - 720p - (DD5.1) [Telugu + Tamil + Hindi] - 1.6GB - ESub - TamilMV", 177 | "Detective Byomkesh Bakshy 2015 Hindi 720p BluRay x264 DTS 5.1 MSubs - LOKiHD - Telly", 178 | "Kasganj 2019 WebRip 720p Hindi x264 AAC ESub - mkvCinemas [Telly].mkv", 179 | "Kasganj 2019 Hindi 1080p Zee5 WebDL AVC AAC 2.0 ESub - Telly.mkv", 180 | "Penguin (2020) [Tam+Tel+Mal - 720p - WEB HDRip - x264 - DD 5.1 - MSub - 2GB] - MAZE", 181 | "Kakushigoto - 12 END (720p)-Erai-raws[TGx]", 182 | "Shaman King (Season 1) (1080p)(HEVC x265 10bit)(Eng-Subs)-Judas[TGx]", 183 | "A.Whisker.Away.2020.JAPANESE.1080p.NF.WEBRip.DDP5.1.x264-NTG[TGx]", 184 | "liz.and.the.blue.bird.2018.japanese.1080p.bluray.dd5.1.hevc.x265.rmteam.mkv", 185 | "The.Flash.2014.S06E13.Il.mio.amico.Grodd.Repack.ITA.ENG.1080p.AMZN.WEB-DLMux.H.264-MeM.mkv", 186 | "Harley.Quinn.S02E12.Lovers.Quarrel.1080p.DCU.WEB-DL.DDP5.1.H264-NTb[TGx]", 187 | "The.Killer.Truth.S01E05.Homicide.at.Home.HDTV.x264-CRiMSON[TGx]", 188 | "The Flintstones (1960) S06 (1080p HMAX Webrip x265 10bit AC3 2.0 - Goki)[TAoE]", 189 | "Jamies.Super.Food.S02E04.WEB.H264-DENTiST[TGx]", 190 | "Blindspot.S05E06.Fire.and.Brimstone.1080p.AMZN.WEB-DL.DDP5.1.H.264-NTb[TGx]", 191 | "In.the.Dark.2019.S02E10.The.Last.Dance.720p.AMZN.WEB-DL.DDP5.1.H.264-NTb[TGx]", 192 | "Babies.S02.COMPLETE.720p.NF.WEBRip.x264-GalaxyTV", 193 | "WWE.Monday.Night.RAW.2020-06-16.German.720p.HDTV.x264-SPORTY[TGx]", 194 | "The.Rachel.Maddow.Show.2020.06.18.540p.WEBDL-Anon", 195 | "The.Last.Word.with.Lawrence.O'Donnell.2020.06.18.540p.WEBDL-Anon", 196 | "Design.at.Your.Door.S01E03.Major.Bonus.Room.WEB.h264-ROBOTS[TGx]", 197 | "The.Rachel.Maddow.Show.2020.06.18.720p.MNBC.WEB-DL.AAC2.0.H.264-BTW[TGx]", 198 | "Lalbazaar S01 E01-10 WebRip 720p Hindi x264 AAC - mkvCinemas [Telly]", 199 | "Scandalous.The.Untold.Story.of.the.National.Enquirer.2020.720p.HMAX.WEBRip.800MB.x264-GalaxyRG", 200 | "Turtle Odyssey (2019) 1080p 5.1 - 2.0 x264 Phun Psyz", 201 | "Still A Mystery S01 WEBRip x264-CAFFEiNE", 202 | "When Bjork Met Attenborough (2013) (1080p BluRay x265 HEVC 10bit AC3 2.0 Silence) [QxR]", 203 | "And.We.Go.Green.2019.720p.HULU.WEBRip.800MB.x264-GalaxyRG", 204 | "Ella Fitzgerald - Just One of Those Things MP4 + subs BigJ0554", 205 | "Inventing.Tomorrow.2018.DOCU.HDTV.x264-W4F[TGx]", 206 | "Eating.Up.Easter.2018.DOCU.HDTV.x264-W4F[TGx]", 207 | "Trackers.S01E03.PROPER.720p.WEB.H264-GHOSTS[TGx]", 208 | "BBC.When.Pop.Went.Epic.1080p.HDTV.x265.AAC.MVGroup.org.mkv", 209 | "Big.Brother.AU.S12E06.720p.WEBRip.x264-Nemo", 210 | "Frontline.S38E20.Opioids.Inc.WEB.h264-LiGATE[TGx]", 211 | "Marvels.Agents.of.S.H.I.E.L.D.S07E03.Comunisti.alieni.dal.futuro.ITA.ENG.1080p.AMZN.WEB-DLMux.DD5.1.H.264-MeM.mkv", 212 | "Your Honor 2020 S01 Hindi 720p WEBRip x264 AAC ESubs - LOKiHD - Telly", 213 | "The Beat with Ari Melber 2020 06 19 720p WEBRip x264-PC.mp4", 214 | "Thirteen S01 MultiSub 720p x264-StB", 215 | "Paan Singh Tomar 2012 Hindi 720p NF WEBRip x264 AAC 5.1 ESubs - LOKiHD - Telly", 216 | "MASH.S01E20.The.Army-Navy.Game.1080p.HULU.WEB-DL.AAC2.0.H.264-AJP69[eztv]", 217 | "Trishas.Southern.Kitchen.S16E12.Family.Favorites.with.Allie.iNTERNAL.WEB.h264-ROBOTS[eztv]", 218 | "Split.Image.1982.Xvid.Eng.ETRG", 219 | "Kaguya-sama wa Kokurasetai S2 - 11 (720p)-HorribleSubs[TGx]", 220 | "Five.1951.DVDRip.XViD.B&W.Eng.1Ch.Audio.ETRG", 221 | "NOS4A2.S02E01.720p.WEB.H264-OATH[TGx]", 222 | "Diners.Drive-Ins.and.Dives.S31E12.Sicilian.and.Seafood.WEBRip.x264-LiGATE[TGx]", 223 | "[Erai-raws] Arte - 12 END [720p].mkv", 224 | "Kaguya-sama wa Kokurasetai! Tensai-tachi no Renai Zunousen 2 - 11 (720p)-Erai-raws[TGx]", 225 | "Prawaas 2020.1080p.AMZN.WEB-DL.DD+5.1.H264.Dus.IcTv", 226 | "[Erai-raws] Yesterday o Utatte - 12 END [720p][Multiple Subtitle].mkv", 227 | "[Erai-raws] Honzuki no Gekokujou - Shisho ni Naru Tame ni wa Shudan wo Erandeiraremasen 2nd Season - 12 END [1080p][Multiple Subtitle].mkv", 228 | "Babyteeth (2019) [1080p] [WebRip] [YTS]", 229 | "Weekend at Bernie's II (1993) [1080p] [BluRay] [YTS]", 230 | "Naked.and.Afraid.XL.S06E00.Clothed.and.Opinionated.Part.2.720p.WEB.h264-ROBOTS[eztv]", 231 | "The Fresh Prince of Bel-Air (1990) S01 REPACK (1080p NF Webrip x265 10bit AC3 2.0 - DNU) [TAoE]", 232 | "Tsugumomo S2 - 12 (720p)-HorribleSubs[TGx]", 233 | "Black Hollywood: 'They've Gotta Have Us' S01 complete (BBC, 2018) (1280x720p HD, 50fps, soft Eng subs)", 234 | "Police.Ten.7.S27E13.HDTV.x264-FiHTV[TGx]", 235 | "2nd.Chance.Charlie.S01E02.HDTV.x264-FiHTV[TGx]", 236 | "BBC.Billy.and.Us.1080p.HDTV.x265.AAC.MVGroup.org.mkv", 237 | "Mystery Diners S08 Season 8 Complete x265 720P", 238 | "Amar (2017) HDRip 720p Hindi + Spanish 800MB[MB].", 239 | "Oolu (2019)[Malayalam 720p HDTV UNTOUCHED - x264 1.4GB[MB]", 240 | "Vacancy (2007) 720p Bluray Dual Audio [Hindi + English] \u2b50800 MB\u2b50 DD - 2.0 MSub x264 - Shadow (BonsaiHD)", 241 | "Darkness Falls (2020) HDRip 720p [Hindi-Dub] Dual-Audio x264 - 1XCinema", 242 | "Wasp Network (2020) ITA-ENG Ac3 5.1 WEBRip 1080p H264 [ArMor]", 243 | "Darlin (2019) ITA-ENG Bluray 1080p - L@Z59 - iDN CreW.mkv", 244 | "Wild Target (2010)Mp-4-X264-Dvd-Rip-480p-AAC-DSD", 245 | "Infection-What We Become (2015) ITA-DAN Ac3 5.1 BDRip 1080p H264 [ArMor]", 246 | "Perversion (2020) full HIndi 720p Flizmovies WEB-DL x264", 247 | "Casino (1995) (1080p BluRay x265 HEVC 10bit HDR AAC 7.1 afm72) [QxR]", 248 | "[zooqle.com] Parks and Recreation S02 Season 2 720p 5.1Ch Web-DL ReEnc-DeeJayAhmed", 249 | "The Amazing Spider-Man 2 2014 720p BluRay Hindi English x264 AAC 5.1 MSubs - LOKiHD - Telly", 250 | "Jay And Silent Bob Strike Back (2001) (1080p BDRip x265 10bit EAC3 5.1 - xtrem3x)[TAoE].mkv", 251 | "Mother [Madre] (2016) BluRay - 720p - [Tamil + Hindi + Spanish] - 950MB - ESub - TamilMV", 252 | "Ridoy Jure 2020 Bangla Movie HDRip 800MB ORG", 253 | "The Deep Blue Sea - Drama 2011 Eng Rus Multi-Subs 720p [H264-mp4]", 254 | "Clerks II (2006) (1080p BDRip x265 10bit TrueHD 5.1 - xtrem3x)[TAoE].mkv", 255 | "Rustlers on Horseback (Western 1950) Allan Lane", 256 | "Athlete.A.2020.1080p.WEB.H264-HUZZAH[TGx]", 257 | "SHAHENSHA 2020 BANGLA MOVIE SHAKIB KHAN HDRIP", 258 | "Rasbhari (2020) Hindi AMZN WEB-DL DD2.0 x264 AAC Esub - CineVood", 259 | "A Walk in the Woods (2015)Mp-4-X264-Dvd-Rip-480p-AAC-DSD", 260 | "Treasure Planet 2002 1080p FLAC MKV (oan)", 261 | "L.A. Story (1991) [4K AI upscale H265 AAC 5.1 stereo EN JP] - CalicoSkies", 262 | "Monk.S08E14.1080p.HEVC.x265-MeGusta[eztv]", 263 | "24.Hours.In.A.And.E.S21E02.1080p.HEVC.x265-MeGusta[eztv]", 264 | "Stephen.Colbert.2020.06.23.John.Bolton.720p.HDTV.x264-SORNY[eztv]", 265 | "American.Masters.S33E15.Toni.Morrison.The.Pieces.I.Am.720p.WEB.h264-LiGATE[eztv]", 266 | "The 11th Hour with Brian Williams 2020 06 23 1080p WEBRip x265 HEVC-LM", 267 | "Black Lagoon (Seasons 1-2 + OVAs) (BD 1080p)(HEVC x265 10bit)(Dual-Audio)(Eng-Subs)-Judas[TGx]", 268 | "One Piece - 927 (1080p)(HEVC x265 10bit)(Multi-Subs)-Judas[TGx]", 269 | "Shokugeki No Soma - S05E01-Judas[TGx]", 270 | "Dil Chahta Hai 2001 Hindi 1080p BluRay x264 DTS-HDMA 5.1 - Hon3yHD", 271 | "NOS4A2 (2019) Multi Audio [Hindi - Tamil - Bengali] 720p Untouched AMZN WEB-DL x264 AAC Esub - CineVood", 272 | "Haikyuu!! (Season 4 Part 1) (1080p)(HEVC x265 10bit)(Multi-Subs)-Judas[TGx]", 273 | "Moothon: The Elder One (2019) Malayalam UNTOUCHED 720p WEB-DL - 2.5 GB - (DD- 2.0) ESub x264 - Shadow (BonsaiHD)", 274 | "Doppia Pelle - Le Daim (2019) BluRay 1080p.H264 Ita Fre AC3 5.1 Sub Ita Eng MIRCrew", 275 | "The Twilight Saga: Breaking Down - Parte 2 (2012) - 720p H264 Ita Eng DTS HD Masters 5.1 Sub Ita Eng by SnakeSPL MIRCrew", 276 | "The Painted Bird (2019) Interslavic 720p Bluray \u2b501.3 GB\u2b50 DD- 2.0 ESub x264 - Shadow (BonsaiHD)", 277 | "Proximity.2020.1080p.Bluray.DTS-HD.MA.5.1.X264-EVO[TGx]", 278 | "Soviet Cinema - Provintsialki 1990 SATRip XviD x263-NOGROUP", 279 | "Just Mercy - Il diritto di opporsi (2019) AC3 5.1 ITA.ENG 1080p H265 sub NUita.eng Sp33dy94 MIRCrew", 280 | "Mae.West.Dirty.Blonde.2019.DOCU.720p.HDTV.800MB.x264-GalaxyRG", 281 | "[06] Documentry -BBC - The Ottomans: Europe's Muslim Emperors (2013) eng.ara sub [Etcohod]", 282 | "War.2019.LIMITED.720p.BluRay.x264-Chakra[TGx]", 283 | "X-Men.2000.REMASTERED.BRRip.XviD.B4ND1T69", 284 | "X2.X-Men.United.2003.REMASTERED.BRRip.XviD.B4ND1T69", 285 | "#Yaaram (2019) Hindi 720p DC WEBRip \u2b501.5 GB\u2b50 (DD- 2.0) HC ESub x264 - Shadow (BonsaiHD)", 286 | "Nessuno sa chi io sono qui-Nadie sabe que estoy aqui (2020) ITA-SPA Ac3 5.1 WEBRip 1080p H264 [ArMor]", 287 | "L.ultima corve (1973) ITA-ENG Ac3 2.0 BDRip 1080p H264 [ArMor]", 288 | "La signora di Shanghai-The lady from Shanghai (1947) ITA-ENG Ac3 2.0 BDRip 1080p H264 [ArMor]", 289 | "The Four (2012) BluRay - 720p - [Telugu + Tamil + Hindi + Chi] - 1.1GB - ESub - TamilMV", 290 | "Samrat & Co. (2014) Hindi 720p AMZN WEBRip \u2b501.2 GB\u2b50 2CH ESub x264 - Shadow (BonsaiHD)", 291 | "Tulips in Spring 2016 Hallmark 720p HDRip X264 Solar", 292 | "Adu (2020) 720p NF WEB-DL Dual Audio [English + spanish] \u2b50950 MB\u2b50 DD- 5.1 x265 - Shadow (BonsaiHD)", 293 | "When Sparks Fly 2014 Hallmark 720P HDTV X264 Solar", 294 | "The Fxxk-It List (2020) [English+Hindi - 720p - WEB HDRip - x264 - DD 5.1 - MSub - 2GB] - MAZE", 295 | "The Twilight Saga Breaking Dawn - Part 2 (2012) (1080p BDRip x265 10bit DTS-HD MA 7.1 - r0b0t) [TAoE].mkv", 296 | "Scooby-Doo Goes Hollywood (1980) (1080p Dvdrip AI upscale x265 10bit AAC 1.0 - Frys) [TAoE].mkv", 297 | "Sarkar 3 2017 Hindi 1080p WEBRip x264 AC3 ESubs - LOKiHD - Telly", 298 | "Jagga Jagravan Joga 2020.1080p.AMZN.WEB.DL.DD.2.0.AVC.Dus.IcTv", 299 | "Sea.Monsters..Series.2.Part.11.Oceans.Most.Powerful.1080p.HDTV.x264.AAC.MVGroup.org.mp4", 300 | "Dukhtar 2014 Urdu 1080p BluRay x264 DD 5.1 ESubs - LOKiHD - Telly", 301 | "Main Teri Tu Mera 2016 Punjabi 720p WEBRip ESubs - LMH123", 302 | "RangiTaranga (2015) 720p Kannada movie HDRip", 303 | "McFarland.USA.2015.1080p.BluRay.x265-RARBG", 304 | "Jasper.Mall.2020.1080p.BluRay.REMUX.AVC.DTS-HD.MA.5.1-FGT", 305 | "Lupin.III.The.First.2019.JAPANESE.1080p.BluRay.x265-VXT", 306 | "The.Rule.for.a.Vagabond.1965.JAPANESE.ENSUBBED.1080p.WEBRip.x265-VXT", 307 | "Cousins.2019.PORTUGUESE.1080p.BluRay.H264.AAC-VXT", 308 | "Easy Rider (Drama 1969) Peter Fonda 720p BrRip", 309 | "PENALTY (2019) Hindi HDRip - 720p - x264 - DD+5.1 - 1.3GB - ESub - TamilMV", 310 | "Wasp Network (2019) HDRip 720p [Hindi-Dub] Dual-Audio x264", 311 | "The.Gentlemen.2019.576p.DQLDR.BRRIP", 312 | "Nicos.Menu.Mission.S01E01.WEB.h264-WEBTUBE[TGx]", 313 | "If.Loving.You.Is.Wrong.S05E11.I.Need.A.Hero.480p.x264-mSD[eztv]", 314 | "Digimon Adventure (2020) - S01E05-Judas[TGx]", 315 | "Kavali (2020) 720p Hindi Dubbed WEBHD 450MB - MovCr", 316 | "Gangs.Of.London.S01E01.Episodio.01.ITA.ENG.1080p.AHDTVMux.x264-Morpheus.mkv", 317 | "Fear.the.Walking.Dead.S05E09.Canale.4.ITA.ENG.1080p.Bluray.x264-MeM.mkv", 318 | "2nd.Chance.Charlie.S01E05.720p.HDTV.x264-FiHTV[eztv]", 319 | "Police.Ten.7.S27E15.HDTV.x264-FiHTV[eztv]", 320 | "Nude - International Cut (2018) 720p WEB Rip Dual Audios [ HIN, MARATHI ]", 321 | "X-men The Last Stand (2006) (1080p BluRay x265 HEVC 10bit AAC 6.1 Vyndros)", 322 | "The Kissing Bandit (Comedy West. 1948) Frank Sinatra 720p HD", 323 | "The King of Comedy 1982 DVD9 PAL-iCMAL", 324 | "The Mouse on the Moon [1963 - UK] comedy", 325 | "Romantic.Comedy.2019.1080p.AMZN.WEBRip.DDP2.0.x264-TEPES[TGx]", 326 | "Sugarfoot (Action Western 1951) Randolph Scott", 327 | "Valeries.Home.Cooking.S11E10.Lights.Camera.Eat.iNTERNAL.720p.WEB.h264-ROBOTS[eztv]", 328 | "American.Monster.S05E06.My.Body.720p.ID.WEB-DL.AAC2.0.x264-BOOP[eztv]", 329 | "Professor Marston and the Wonder Women (2017) - H264 Ita Eng Deu Esp Ac3 5.1 Multisub - DVDRip - by SnakeSPL MIRCrew", 330 | "Extraterrestrial.2011.BluRay.1080i.DTS-HD.MA.5.1.AVC.REMUX-FraMeSToR.mkv", 331 | "Magnum.P.I.2018.S03E04.720p.HDTV.x264-SYNCOPY", 332 | "Friends.S09E23E24.720p.BluRay.DD5.1.x264-NTb.mkv", 333 | "Shrek.2.2004.1080p.BluRay.x264.YIFY.srt", 334 | "Accepted.2006.720p.HDDVD.DD5.1.x264-EbP", 335 | "Its.Always.Sunny.In.Philadelphia.S12.1080p.Amazon.WEB-DL.DD+2.0.H.264-CtrlHD", 336 | "Animals.S01.1080p.HBO.WEBRip.DD5.1.H.264-monkee", 337 | "SpongeBob.SquarePants.S02.iT.WEB-DL.AAC2.0.H.264-NOGRP", 338 | "The.Shivering.Truth.S01.1080p.AS.WEB-DL.AAC2.0.H.264-BTN", 339 | "Letterkenny.S05.720p.CRAV.WEB-DL.AAC2.0.H.264-BTW", 340 | "Workaholics.S07.1080p.CC.WEBRip.AAC2.0.x264-BTW", 341 | "HarmonQuest.S01.1080p.SESO.WEBRip.AAC2.0.x264-BTW", 342 | "Bee.and.Puppycat.S01.1080p.VRV.WEB-DL.x264-Bernd_Lauert", 343 | "A.P.Bio.S03.1080p.PCOK.WEB-DL.DDP5.0.x264-NTb", 344 | "Star.Trek.Discovery.S01E01.The.Vulcan.Hello.540p.CBS.WEB-DL.AAC2.0.x264-AJP69.mkv", 345 | "IMAX.Blue.Planet.1990.1080p.BluRay.REMUX.VC-1.TrueHD.5.1-EPSiLON.mkv", 346 | "John.Wick.Chapter.2.2017.720p.BluRay.DD-EX.x264-TayTO", 347 | "Archer.S02.1080p.BluRay.DTSMA.AVC.Remux", 348 | "Peaky.Blinders.S01.720p.BluRay.FLAC2.0.x264-DON", 349 | "Ghost.Stories.S01.DVDRip.OGG.x264-Exiled-Destiny", 350 | "Rick.Steins.Road.To.Mexico.S01E01.720p.iP.WEB-DL.AAC2.0.H.264-RTN.mkv", 351 | "Road.to.the.NHL.Winter.Classic.S07E01.Rangers.vs.Sabres.Part1.1080p.REPACK.NBC.WEB-DL.AAC2.0.H.264-BTW.mkv", 352 | "Robert.Kirkmans.Secret.History.of.Comics.S01E01.The.Mighty.Misfits.Who.Made.Marvel.1080p.AMC.WEB-DL.AAC2.0.H.264-BOOP.mkv", 353 | "Ready.Jet.Go.S01E12.Chore.Day.720p.PBS.WEBRip.AAC2.0.x264-SynHD.mkv", 354 | "Philip.K.Dicks.Electric.Dreams.S01E01.The.Hood.Maker.STAN.WEB-DL.AAC2.0.H.264-BTW.mkv", 355 | "Octonauts.S04E15.The.Great.Swamp.Search.720p.DSNY.WEBRip.AAC2.0.x264-RTN.mkv", 356 | "Nowhere.Fast.S01E01.RTE.WEB-DL.AAC2.0.H.264-RTN.mkv", 357 | "New.Game.S02.CR.WEB-DL.AAC2.0.x264-HorribleSubs", 358 | "Mystery.of.the.Lost.Islands.S01E01.Shark.Island.1080p.ANPL.WEB-DL.AAC2.0.x264-BOOP.mkv", 359 | "Mr.Mercedes.S01E01.Pilot.DTV.WEB-DL.DD2.0.x264-BTW.mkv", 360 | "Most.Expensivest.S01E01.Treat.Yo.Self.1080p.VICE.WEB-DL.AAC2.0.x264-BOOP.mkv", 361 | "[Anonymous] Non Non Biyori [BD 1080p 10bit H.264 FLAC]", 362 | "[Arjix] Darling in the Franxx [BD-Remux]", 363 | "[BDremux] One Piece Movies Collection", 364 | "[JySzE] Naruto [v2] [R2J] [VFR] [Dual Audio] [Complete] [Extras] [x264]", 365 | "Attack.on.Titan.S01.S02.S03.1080p.Blu-Ray.Remux.Dual-Audio.TrueHD", 366 | "Black Clover S01 USBD REMUX", 367 | "Hero Mask S1 + S2 + Extras [npz][US BD REMUX, 1080p]", 368 | "[CBT] Nisekoi S1+S2 [BDrip 1920x1080 x264 FLAC]", 369 | "[YURI] Kimi no Suizou o Tabetai [BD1080p HEVC FLAC][Dual Audio] v4", 370 | "[FFF-Remux][Batch] Accel World 1-24 Dual-Audio 1080p FLAC", 371 | "The Djinn 2021 1080p BRRip DD5 1 X 264-EVO", 372 | "Hive [2021 - Albania] drama", 373 | "Souad [2021 - Egypt] drama", 374 | "Swinki [2009 - Poland] drama", 375 | "Dead Heat on a Merry Go Round [1966 - USA] thriller", 376 | "Justified - Season 1 to 6 - Mp4 x264 AC3 1080p", 377 | "Movie 43 (2013) 720p BluRay x264 -[MoviesFD]", 378 | "Mommy (2014) French 720p BluRay x264 -[MoviesFD]", 379 | "Rendez Vous.2015.DUBBED.1080p.WEBRip.x265-R4RBG[TGx]", 380 | "The Best Offer.mkv", 381 | "What.If...2010.1080p.WEB-DL.DDP2.0.H264.mkv", 382 | "Eu.gosto.do.Homem-Aranha.....y.dai.1080p.AAC2.0.H264.mkv", 383 | "tick.tick...BOOM.mp4", 384 | "Sons of Anarchy Season 3 Complete 1280 x 720 x264 Phun Psyz", 385 | "Lollapalooza.2022.Cat.Dealers.1080p.WEB-DL.AAC2.0.x264.mkv", 386 | "Crazy4TV.com - Dark Matter Season 1 S01 720p BluRay x265 HEVC Crazy4ad", 387 | "www.Torrenting.com - Presque.2021.FRENCH.1080p.WEB.H264-SEiGHT", 388 | "www.1TamilBlasters.sbs - Lucky Man (2023) [Tamil - 720p HQ HDRip - HEVC - x265 - [DDP5.1 (192Kbps) + AAC] - 900MB - ESub].mkv", 389 | "www.1TamilBlasters.art - Sultan of Delhi (2023) S01EP(01-09) [HQ HDRip - x264 - [Tam + Mal + Tel + Kan] - AAC - 1.2GB - ESub]", 390 | "Mission.Impossible.1996.Custom.Audio.1080p.PL-Spedboy.mkv", 391 | "Black.Rain.1989.MULTi.1080p.BluRay.REMUX.MPEG-2.DTS-ES.6.1-LTS.mkv", 392 | "Bolt.2008.MULTI.BluRay.3D.1080p.AVC.DTS-HD.MA.DD.EX.5.1-SnOoP-UPR.iso", 393 | "Casino.1995.MULTi.REMUX.2160p.UHD.Blu-ray.HDR.HEVC.DTS-X7.1-DENDA.mkv", 394 | "Seinfeld.S04E23E24.The.Pilot.FiNAL.MULTi.1080p.NF.WEB-DL.HE-AAC2.0.H264-Ralf.mkv", 395 | "Escape.Room.Tournament.of.Champions.2021.PL.EXTENDED.1080p.BRRip.HE-AACv2.AV1.mkv", 396 | "Steven Universe", 397 | "The Amazing World of Gumball", 398 | "Avatar The Last Airbender - The Complete Series 1080p [HEVC AAC] - SEPH1", 399 | "The Inbetweeners Complete Collection", 400 | "The Sopranos - The Complete Series (Season 1, 2, 3, 4, 5 & 6) + Extras", 401 | "The.Walking.Dead.S06E07.SUBFRENCH.HDTV.x264-AMB3R.mkv", 402 | "The Good German (2006).VOSTFR.720p.WEBDL.h264.aac.mkv", 403 | "www.Torrenting.com - Anatomy Of A Fall (2023)", 404 | "Eu.gosto.do.Homem-Aranha.e.dai.1080p.AAC2.0.H264.mkv", 405 | "www.1TamilBlasters.lat - Thuritham (2023) [Tamil - 2K QHD AVC UNTOUCHED - x264 - AAC - 3.4GB - ESub].mkv" 406 | ] 407 | -------------------------------------------------------------------------------- /tests/files/output_standard.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "codec": "H.264", 4 | "quality": "HDTV", 5 | "title": "The Walking Dead" 6 | }, 7 | { 8 | "codec": "H.264", 9 | "quality": "BRRip", 10 | "title": "Hercules" 11 | }, 12 | { 13 | "codec": "Xvid", 14 | "quality": "WEB-DL", 15 | "title": "Dawn of the Planet of the Apes" 16 | }, 17 | { 18 | "codec": "Xvid", 19 | "quality": "HDTV", 20 | "title": "The Big Bang Theory" 21 | }, 22 | { 23 | "codec": "H.264", 24 | "quality": "BRRip", 25 | "title": "22 Jump Street" 26 | }, 27 | { 28 | "audio": "Dolby Digital 5.1", 29 | "codec": "H.264", 30 | "quality": "WEB-DL", 31 | "title": "Hercules" 32 | }, 33 | { 34 | "codec": "Xvid", 35 | "quality": "WEB-DL", 36 | "title": "Hercules" 37 | }, 38 | { 39 | "codec": "Xvid", 40 | "quality": "WEB-DL", 41 | "title": "Hercules" 42 | }, 43 | { 44 | "codec": "H.264", 45 | "quality": "WEB-DL", 46 | "title": "WWE Hell in a Cell" 47 | }, 48 | { 49 | "codec": "H.264", 50 | "quality": "HDTV", 51 | "title": "UFC 179" 52 | }, 53 | { 54 | "codec": "H.264", 55 | "quality": "HDTV", 56 | "title": "Marvel's Agents of S.H.I.E.L.D." 57 | }, 58 | { 59 | "audio": "Dolby Digital 5.1", 60 | "codec": "H.264", 61 | "quality": "WEB-DL", 62 | "title": "X-Men Days of Future Past" 63 | }, 64 | { 65 | "codec": "H.264", 66 | "quality": "Cam", 67 | "title": "Guardians Of The Galaxy" 68 | }, 69 | { 70 | "audio": "Dolby Digital 5.1", 71 | "quality": "WEB-DL", 72 | "title": "Marvel's Agents of S.H.I.E.L.D." 73 | }, 74 | { 75 | "codec": "H.264", 76 | "quality": "HDTV", 77 | "title": "Marvels Agents of S.H.I.E.L.D." 78 | }, 79 | { 80 | "quality": "Cam", 81 | "title": "Guardians of the Galaxy" 82 | }, 83 | { 84 | "audio": "Dolby Digital 5.1", 85 | "codec": "H.264", 86 | "quality": "WEB-DL", 87 | "title": "The Walking Dead" 88 | }, 89 | { 90 | "audio": "LiNE", 91 | "codec": "Xvid", 92 | "quality": "DVD-Rip", 93 | "title": "Brave" 94 | }, 95 | { 96 | "codec": "Xvid", 97 | "quality": "BRRip", 98 | "title": "Lets Be Cops" 99 | }, 100 | { 101 | "codec": "Xvid", 102 | "quality": "WEBRip", 103 | "title": "These Final Hours" 104 | }, 105 | { 106 | "codec": "H.264", 107 | "quality": "HDTV", 108 | "title": "Downton Abbey" 109 | }, 110 | { 111 | "audio": "Dolby Digital", 112 | "codec": "Xvid", 113 | "quality": "WEB-DL", 114 | "title": "Annabelle" 115 | }, 116 | { 117 | "codec": "Xvid", 118 | "quality": "WEB-DL", 119 | "title": "Lucy" 120 | }, 121 | { 122 | "codec": "H.264", 123 | "quality": "HDTV", 124 | "title": "The Flash" 125 | }, 126 | { 127 | "codec": "H.264", 128 | "quality": "HDTV", 129 | "title": "South Park" 130 | }, 131 | { 132 | "codec": "H.264", 133 | "quality": "HDTV", 134 | "title": "The Flash" 135 | }, 136 | { 137 | "codec": "H.264", 138 | "quality": "HDTV", 139 | "title": "The Flash" 140 | }, 141 | { 142 | "audio": "Dual", 143 | "quality": "WEBRip", 144 | "size": "1400MB", 145 | "title": "Lucy" 146 | }, 147 | { 148 | "quality": "WEB-DL", 149 | "title": "Teenage Mutant Ninja Turtles" 150 | }, 151 | { 152 | "title": "Teenage Mutant Ninja Turtles" 153 | }, 154 | { 155 | "codec": "H.264", 156 | "quality": "HDTV", 157 | "title": "The Simpsons" 158 | }, 159 | { 160 | "codec": "H.264", 161 | "quality": "BRRip", 162 | "title": "2047 - Sights of Death" 163 | }, 164 | { 165 | "codec": "H.264", 166 | "quality": "HDTV", 167 | "title": "Two and a Half Men" 168 | }, 169 | { 170 | "audio": "Dolby Digital", 171 | "codec": "Xvid", 172 | "quality": "WEBRip", 173 | "title": "Dinosaur 13" 174 | }, 175 | { 176 | "audio": "MP3", 177 | "codec": "Xvid", 178 | "quality": "WEB-DL", 179 | "title": "Teenage Mutant Ninja Turtles" 180 | }, 181 | { 182 | "audio": "Dolby Digital 5.1", 183 | "codec": "H.264", 184 | "quality": "WEB-DL", 185 | "title": "Dawn Of The Planet of The Apes" 186 | }, 187 | { 188 | "audio": "Dolby Digital 5.1", 189 | "codec": "H.264", 190 | "quality": "WEB-DL", 191 | "title": "Teenage Mutant Ninja Turtles" 192 | }, 193 | { 194 | "audio": "AAC", 195 | "codec": "H.264", 196 | "quality": "WEB-DL", 197 | "title": "Gotham" 198 | }, 199 | { 200 | "audio": "AAC 2.0", 201 | "codec": "H.264", 202 | "quality": "WEB-DL", 203 | "title": "Into The Storm" 204 | }, 205 | { 206 | "audio": "Dual", 207 | "quality": "WEBRip", 208 | "title": "Lucy" 209 | }, 210 | { 211 | "audio": "DTS", 212 | "codec": "H.264", 213 | "quality": "BRRip", 214 | "title": "Into The Storm" 215 | }, 216 | { 217 | "codec": "H.264", 218 | "quality": "Blu-ray", 219 | "title": "Sin City A Dame to Kill For" 220 | }, 221 | { 222 | "codec": "H.264", 223 | "quality": "HDTV", 224 | "title": "WWE Monday Night Raw 3rd Nov" 225 | }, 226 | { 227 | "codec": "Xvid", 228 | "quality": "BRRip", 229 | "title": "Jack And The Cuckoo-Clock Heart" 230 | }, 231 | { 232 | "codec": "H.264", 233 | "quality": "HDTV", 234 | "title": "WWE Hell in a Cell" 235 | }, 236 | { 237 | "audio": "Dolby Digital", 238 | "codec": "Xvid", 239 | "quality": "Telesync", 240 | "title": "Dracula Untold" 241 | }, 242 | { 243 | "codec": "H.264", 244 | "quality": "HDTV", 245 | "title": "The Missing" 246 | }, 247 | { 248 | "codec": "H.264", 249 | "quality": "HDTV", 250 | "title": "Doctor Who" 251 | }, 252 | { 253 | "audio": "AAC", 254 | "codec": "H.264", 255 | "quality": "WEB-DL", 256 | "title": "Gotham" 257 | }, 258 | { 259 | "codec": "Xvid", 260 | "quality": "DVD-Rip", 261 | "title": "One Shot" 262 | }, 263 | { 264 | "audio": "AAC", 265 | "codec": "H.264", 266 | "language": "Hindi", 267 | "quality": "Screener", 268 | "title": "The Shaukeens" 269 | }, 270 | { 271 | "codec": "H.264", 272 | "quality": "Screener", 273 | "title": "The Shaukeens" 274 | }, 275 | { 276 | "audio": "AAC 2.0", 277 | "codec": "H.264", 278 | "quality": "WEBRip", 279 | "title": "Annabelle" 280 | }, 281 | { 282 | "audio": "AAC", 283 | "codec": "H.264", 284 | "language": "English", 285 | "quality": "Cam", 286 | "title": "Interstellar" 287 | }, 288 | { 289 | "audio": "Dual", 290 | "filetype": "AVI", 291 | "quality": "DVD-Rip", 292 | "title": "Guardians of the Galaxy" 293 | }, 294 | { 295 | "audio": "Dual", 296 | "codec": "H.264", 297 | "filetype": "MKV", 298 | "quality": "WEB-DL", 299 | "title": "Eliza Graves" 300 | }, 301 | { 302 | "codec": "H.264", 303 | "quality": "PDTV", 304 | "title": "WWE Monday Night Raw" 305 | }, 306 | { 307 | "title": "Sons of Anarchy" 308 | }, 309 | { 310 | "codec": "H.264", 311 | "quality": "HDTV", 312 | "title": "doctor who" 313 | }, 314 | { 315 | "codec": "H.264", 316 | "quality": "Blu-ray", 317 | "title": "breaking bad" 318 | }, 319 | { 320 | "title": "Game of Thrones" 321 | }, 322 | { 323 | "codec": "H.264", 324 | "quality": "Blu-ray", 325 | "title": "sons of anarchy" 326 | }, 327 | { 328 | "codec": "H.264", 329 | "quality": "HDTV", 330 | "title": "Sons of Anarchy" 331 | }, 332 | { 333 | "language": ["Russian","English"], 334 | "title": "Community" 335 | }, 336 | { 337 | "audio": "AAC", 338 | "codec": "H.264", 339 | "quality": "BRRip", 340 | "sbs": "SBS", 341 | "title": "The Jungle Book" 342 | }, 343 | { 344 | "audio": "AAC", 345 | "codec": "H.264", 346 | "quality": "BRRip", 347 | "sbs": "Half SBS", 348 | "title": "Ant-Man" 349 | }, 350 | { 351 | "audio": "Dolby Digital", 352 | "codec": "H.264", 353 | "quality": "WEB-DL", 354 | "title": "Ice Age Collision Course" 355 | }, 356 | { 357 | "codec": "H.264", 358 | "quality": "BDRip", 359 | "title": "Red Sonja Queen Of Plagues" 360 | }, 361 | { 362 | "quality": "WEB-DL", 363 | "size": "900MB", 364 | "title": "The Purge: Election Year" 365 | }, 366 | { 367 | "quality": "Telesync", 368 | "size": "600MB", 369 | "title": "War Dogs" 370 | }, 371 | { 372 | "codec": "H.265", 373 | "quality": "Blu-ray", 374 | "size": "999MB", 375 | "title": "The Hateful Eight" 376 | }, 377 | { 378 | "audio": "AAC", 379 | "codec": "H.264", 380 | "quality": "BRRip", 381 | "title": "The Boss" 382 | }, 383 | { 384 | "codec": "H.264", 385 | "quality": "DVD-Rip", 386 | "title": "Return To Snowy River" 387 | }, 388 | { 389 | "audio": "Dolby Digital 5.1", 390 | "codec": "H.264", 391 | "language": "Hindi", 392 | "title": "Akira" 393 | }, 394 | { 395 | "audio": "Dolby Digital", 396 | "codec": "H.264", 397 | "quality": "Telesync", 398 | "title": "Ben Hur" 399 | }, 400 | { 401 | "audio": "AAC-LC", 402 | "codec": "H.264", 403 | "quality": "WEB-DL", 404 | "title": "The Secret Life of Pets" 405 | }, 406 | { 407 | "codec": "H.264", 408 | "quality": "Blu-ray", 409 | "subtitles": "Danish", 410 | "title": "The X-Files" 411 | }, 412 | { 413 | "codec": "H.265", 414 | "quality": "Blu-ray", 415 | "subtitles": "Danish", 416 | "title": "The X-Files" 417 | }, 418 | { 419 | "codec": "H.264", 420 | "quality": "Blu-ray", 421 | "title": "The X-Files" 422 | }, 423 | { 424 | "codec": "H.264", 425 | "quality": "HDTV", 426 | "title": "The Flash" 427 | }, 428 | { 429 | "filetype": "MP4", 430 | "language": ["Chinese","Japanese"], 431 | "quality": "HDTV", 432 | "resolution": "720p", 433 | "title": "Boku Unmei no Hito desu" 434 | }, 435 | { 436 | "audio": "DTS 5.1", 437 | "codec": "H.264", 438 | "language": "Nordic", 439 | "quality": "Blu-ray", 440 | "title": "Blind" 441 | }, 442 | { 443 | "codec": "H.264", 444 | "title": "Family Guy" 445 | }, 446 | { 447 | "codec": "H.264", 448 | "network": "Amazon Studios", 449 | "quality": "WEB-DL", 450 | "title": "South Park" 451 | }, 452 | { 453 | "codec": "H.264", 454 | "quality": "DVD-Rip", 455 | "title": "Borgen" 456 | }, 457 | { 458 | "codec": "Xvid", 459 | "language": "Swedish", 460 | "quality": "DVD-Rip", 461 | "title": "Bumbibjornarna" 462 | }, 463 | { 464 | "audio": "AAC 2.0", 465 | "codec": "H.264", 466 | "quality": "WEB-DL", 467 | "subtitles": "Korean", 468 | "title": "The Martian" 469 | }, 470 | { 471 | "filetype": "MP4", 472 | "title": "Borgen" 473 | }, 474 | { 475 | "audio": "AAC", 476 | "codec": "H.264", 477 | "quality": "Blu-ray", 478 | "title": "The Legend of 1900" 479 | }, 480 | { 481 | "codec": "H.264", 482 | "quality": "Blu-ray", 483 | "title": "2001 A Space Odyssey" 484 | }, 485 | { 486 | "audio": "AAC 5.1", 487 | "codec": "H.264", 488 | "quality": "WEBRip", 489 | "title": "Impractical Jokers The Movie" 490 | }, 491 | { 492 | "audio": "AAC 5.1", 493 | "codec": "H.264", 494 | "language": "Polish", 495 | "network": "Netflix", 496 | "quality": "WEB-DL", 497 | "title": "1983" 498 | }, 499 | { 500 | "audio": "AAC", 501 | "codec": "H.264", 502 | "quality": "BRRip", 503 | "subtitles": "English", 504 | "title": "The Bridge" 505 | }, 506 | { 507 | "codec": "H.264", 508 | "quality": "WEB-DL", 509 | "subtitles": "ExYu", 510 | "title": "The Meg" 511 | }, 512 | { 513 | "codec": "H.264", 514 | "quality": "Cam", 515 | "subtitles": "English", 516 | "title": "Dragon Ball Super: Broly" 517 | }, 518 | { 519 | "codec": "H.264", 520 | "language": "English", 521 | "quality": "WEB-DL", 522 | "subtitles": ["Hindi","English"], 523 | "title": "Joker" 524 | }, 525 | { 526 | "audio": "AAC", 527 | "codec": "H.264", 528 | "language": "Mandarin", 529 | "quality": "WEB-DL", 530 | "subtitles": ["Chinese","English"], 531 | "title": "IP Man And Four Kings" 532 | }, 533 | { 534 | "title": "American Dad!" 535 | }, 536 | { 537 | "language": ["Italian","English"], 538 | "quality": "DVD-Rip", 539 | "title": "The Simpsons" 540 | }, 541 | { 542 | "quality": "DVD-Rip", 543 | "title": "The Simpsons" 544 | }, 545 | { 546 | "codec": "H.264", 547 | "quality": "HDTV", 548 | "title": "Stephen Colbert" 549 | }, 550 | { 551 | "codec": "H.264", 552 | "filetype": "MKV", 553 | "quality": "HDTV", 554 | "title": "Jimmy Not Funny" 555 | }, 556 | { 557 | "codec": "H.264", 558 | "network": "Amazon Studios", 559 | "quality": "WEBRip", 560 | "title": "Tom Clancys Jack Ryan" 561 | }, 562 | { 563 | "audio": "Dolby Digital Plus 5.1", 564 | "codec": "H.264", 565 | "language": "Hindi", 566 | "subtitles": "English", 567 | "title": "Sacred Games" 568 | }, 569 | { 570 | "codec": "H.264", 571 | "quality": "HDTV", 572 | "title": "Homeland" 573 | }, 574 | { 575 | "audio": "Dolby Digital Plus 5.1", 576 | "bitDepth": 10, 577 | "codec": "H.265", 578 | "network": "Apple TV+", 579 | "quality": "WEBRip", 580 | "title": "Home Before Dark" 581 | }, 582 | { 583 | "codec": "H.264", 584 | "quality": "HDTV", 585 | "title": "Our Girl" 586 | }, 587 | { 588 | "codec": "H.264", 589 | "title": "Roswell New Mexico" 590 | }, 591 | { 592 | "codec": "H.264", 593 | "quality": "WEBRip", 594 | "title": "Coyote Peterson-Brave the Wild" 595 | }, 596 | { 597 | "audio": "Dolby Digital 5.1", 598 | "codec": "H.264", 599 | "language": ["Italian","English"], 600 | "network": "Amazon Studios", 601 | "quality": "WEB-DL", 602 | "title": "The Blacklist" 603 | }, 604 | { 605 | "audio": "Dolby Digital Plus 2.0", 606 | "bitDepth": 10, 607 | "codec": "H.265", 608 | "network": "Amazon Studios", 609 | "quality": "WEB-DL", 610 | "title": "Are You Being Served" 611 | }, 612 | { 613 | "codec": "H.264", 614 | "quality": "WEBRip", 615 | "title": "Empire" 616 | }, 617 | { 618 | "codec": "Xvid", 619 | "title": "Mixed-ish" 620 | }, 621 | { 622 | "codec": "H.264", 623 | "filetype": "MP4", 624 | "quality": "WEB-DL", 625 | "size": "4.3GB", 626 | "title": "Marvels Iron Fist" 627 | }, 628 | { 629 | "codec": "H.264", 630 | "quality": "Blu-ray", 631 | "title": "Dag Vreemde Man" 632 | }, 633 | { 634 | "codec": "H.264", 635 | "quality": "Blu-ray", 636 | "title": "Boi" 637 | }, 638 | { 639 | "codec": "H.264", 640 | "network": "Amazon Studios", 641 | "quality": "WEBRip", 642 | "size": "800MB", 643 | "title": "Label Me" 644 | }, 645 | { 646 | "codec": "H.264", 647 | "quality": "WEBRip", 648 | "title": "A Touch Of Cloth" 649 | }, 650 | { 651 | "codec": "H.264", 652 | "quality": "WEB-DL", 653 | "title": "The Hand Bag" 654 | }, 655 | { 656 | "audio": "Dolby Digital", 657 | "codec": "Xvid", 658 | "language": ["Italian","English"], 659 | "subtitles": ["Italian","English"], 660 | "title": "Z Nation" 661 | }, 662 | { 663 | "audio": "Dolby Digital", 664 | "language": ["Italian","English"], 665 | "quality": "BDRip", 666 | "subtitles": "Available", 667 | "title": "1917" 668 | }, 669 | { 670 | "codec": "H.264", 671 | "quality": "Blu-ray", 672 | "title": "Johnny English" 673 | }, 674 | { 675 | "codec": "H.264", 676 | "quality": "BRRip", 677 | "title": "Johnny English Reborn" 678 | }, 679 | { 680 | "codec": "H.264", 681 | "quality": "Blu-ray", 682 | "title": "Johnny English Strikes Again" 683 | }, 684 | { 685 | "audio": "Dolby Digital Plus", 686 | "codec": "H.265", 687 | "quality": "Blu-ray", 688 | "title": "The French Connection" 689 | }, 690 | { 691 | "codec": "H.264", 692 | "quality": "DVD-Rip", 693 | "title": "The Thin Blue Line" 694 | }, 695 | { 696 | "codec": "H.264", 697 | "title": "Heavy Rescue 401" 698 | }, 699 | { 700 | "title": "Coronation Street" 701 | }, 702 | { 703 | "audio": "Dolby Digital Plus 2.0", 704 | "codec": "H.264", 705 | "network": "Amazon Studios", 706 | "quality": "WEB-DL", 707 | "title": "Deadliest Catch" 708 | }, 709 | { 710 | "codec": "H.264", 711 | "network": "Netflix", 712 | "quality": "WEBRip", 713 | "title": "New Girl" 714 | }, 715 | { 716 | "codec": "H.264", 717 | "quality": "HDTV", 718 | "title": "Accused Guilty or Innocent" 719 | }, 720 | { 721 | "audio": "AAC", 722 | "codec": "H.264", 723 | "filetype": "MP4", 724 | "quality": "DVD-Rip", 725 | "title": "The Peacemaker" 726 | }, 727 | { 728 | "audio": "Dolby Digital", 729 | "codec": "H.264", 730 | "language": ["Italian","English"], 731 | "subtitles": ["Italian","English"], 732 | "title": "The Big Bus - Il fantabus" 733 | }, 734 | { 735 | "audio": "Dolby Digital 5.1", 736 | "codec": "H.264", 737 | "language": ["Italian","English"], 738 | "quality": "Blu-ray", 739 | "subtitles": ["Italian","English"], 740 | "title": "The Hunt" 741 | }, 742 | { 743 | "codec": "H.264", 744 | "quality": "Blu-ray", 745 | "title": "Near Death" 746 | }, 747 | { 748 | "codec": "H.264", 749 | "quality": "Blu-ray", 750 | "title": "The Red Pony" 751 | }, 752 | { 753 | "codec": "H.265", 754 | "quality": "Blu-ray", 755 | "title": "We Were Soldiers" 756 | }, 757 | { 758 | "audio": "Dolby Digital 5.1", 759 | "codec": "H.264", 760 | "language": ["Italian","English"], 761 | "subtitles": ["Italian","English"], 762 | "title": "Diabolique" 763 | }, 764 | { 765 | "audio": "Dolby Digital 2.0", 766 | "codec": "H.264", 767 | "title": "Road House 2 Last Call" 768 | }, 769 | { 770 | "audio": "Dolby TrueHD 7.1", 771 | "codec": "H.264", 772 | "quality": "Blu-ray", 773 | "title": "We Summon The Darkness" 774 | }, 775 | { 776 | "codec": "H.264", 777 | "language": ["Italian","French"], 778 | "subtitles": "English", 779 | "title": "37°2 le matin - Betty Blue" 780 | }, 781 | { 782 | "codec": "H.264", 783 | "quality": "Blu-ray", 784 | "title": "Non-Fiction" 785 | }, 786 | { 787 | "codec": "H.264", 788 | "title": "Spring Night Summer Night" 789 | }, 790 | { 791 | "codec": "H.264", 792 | "network": "Amazon Studios", 793 | "title": "Insecure" 794 | }, 795 | { 796 | "codec": "H.264", 797 | "title": "Let It Fall Los Angeles 1982-1992" 798 | }, 799 | { 800 | "codec": "H.264", 801 | "title": "Dr Phil" 802 | }, 803 | { 804 | "audio": "Dolby Digital Plus 5.1", 805 | "codec": "H.264", 806 | "network": "Amazon Studios", 807 | "title": "Starhunter ReduX" 808 | }, 809 | { 810 | "codec": "H.264", 811 | "quality": "WEBRip", 812 | "title": "Jimmy Fallon" 813 | }, 814 | { 815 | "title": "Kami no Tou" 816 | }, 817 | { 818 | "codec": "H.264", 819 | "quality": "WEBRip", 820 | "title": "EastEnders" 821 | }, 822 | { 823 | "codec": "H.264", 824 | "quality": "WEBRip", 825 | "title": "Lost Gold of World War II" 826 | }, 827 | { 828 | "title": "Plunderer" 829 | }, 830 | { 831 | "codec": "H.264", 832 | "filetype": "MKV", 833 | "size": "1.4GB", 834 | "title": "Blood Blockade Battlefront & Beyond" 835 | }, 836 | { 837 | "title": "Tower of God" 838 | }, 839 | { 840 | "episode": 12, 841 | "subtitles": "Available", 842 | "title": "Kami no Tou" 843 | }, 844 | { 845 | "codec": "H.265", 846 | "subtitles": "English", 847 | "title": "Plunderer" 848 | }, 849 | { 850 | "title": "Tamayomi" 851 | }, 852 | { 853 | "title": "Ahiru no Sora" 854 | }, 855 | { 856 | "subtitles": "Available", 857 | "title": "Shadowverse" 858 | }, 859 | { 860 | "title": "A3! Season Spring & Summer" 861 | }, 862 | { 863 | "subtitles": "Available", 864 | "title": "Kitsutsuki Tanteidokoro" 865 | }, 866 | { 867 | "subtitles": "Available", 868 | "title": "Princess Connect! Re-Dive" 869 | }, 870 | { 871 | "title": "Fruits Basket" 872 | }, 873 | { 874 | "audio": "Dolby Digital 2.0", 875 | "codec": "H.264", 876 | "network": "SONY LIV", 877 | "size": "1.1GB", 878 | "subtitles": "English", 879 | "title": "Kadakh" 880 | }, 881 | { 882 | "codec": "H.265", 883 | "quality": "Blu-ray", 884 | "title": "Satyagraha" 885 | }, 886 | { 887 | "codec": "H.264", 888 | "quality": "Blu-ray", 889 | "subtitles": "Available", 890 | "title": "Shuddh Desi Romance" 891 | }, 892 | { 893 | "audio": "Dolby Digital 5.1", 894 | "codec": "H.264", 895 | "quality": "WEB-DL", 896 | "subtitles": "English", 897 | "title": "Face 2 Face" 898 | }, 899 | { 900 | "audio": "Dolby Digital 5.1", 901 | "codec": "H.264", 902 | "network": "Netflix", 903 | "size": "800MB", 904 | "subtitles": "English", 905 | "title": "Chaman Bahar" 906 | }, 907 | { 908 | "audio": "Dolby Digital 2.0", 909 | "codec": "H.264", 910 | "size": "650MB", 911 | "subtitles": "English", 912 | "title": "Piprabidya" 913 | }, 914 | { 915 | "audio": "Dolby Digital 5.1", 916 | "codec": "H.264", 917 | "network": "Amazon Studios", 918 | "size": "1.1GB", 919 | "subtitles": "English", 920 | "title": "Penguin" 921 | }, 922 | { 923 | "audio": "Dolby Digital", 924 | "codec": "H.264", 925 | "subtitles": "English", 926 | "title": "Kadakh" 927 | }, 928 | { 929 | "codec": "H.265", 930 | "quality": "Blu-ray", 931 | "title": "Satyagraha" 932 | }, 933 | { 934 | "codec": "H.264", 935 | "quality": "WEB-DL", 936 | "subtitles": "English", 937 | "title": "Kavacham" 938 | }, 939 | { 940 | "codec": "H.264", 941 | "quality": "BRRip", 942 | "subtitles": "English", 943 | "title": "M.S. Dhoni: The Untold Story" 944 | }, 945 | { 946 | "audio": "Dolby Digital 5.1", 947 | "quality": "Blu-ray", 948 | "subtitles": "English", 949 | "title": "M.S. Dhoni: The Untold Story" 950 | }, 951 | { 952 | "codec": "H.264", 953 | "quality": "Blu-ray", 954 | "subtitles": "Available", 955 | "title": "Detective Byomkesh Bakshy" 956 | }, 957 | { 958 | "codec": "H.264", 959 | "filetype": "MKV", 960 | "quality": "WEBRip", 961 | "subtitles": "English", 962 | "title": "Kasganj" 963 | }, 964 | { 965 | "codec": "H.264", 966 | "filetype": "MKV", 967 | "network": "ZEE5", 968 | "quality": "WEB-DL", 969 | "subtitles": "English", 970 | "title": "Kasganj" 971 | }, 972 | { 973 | "audio": "Dolby Digital 5.1", 974 | "codec": "H.264", 975 | "language": ["Tamil","Telugu","Malayalam"], 976 | "quality": "WEB-DL", 977 | "subtitles": "Available", 978 | "title": "Penguin" 979 | }, 980 | { 981 | "title": "Kakushigoto" 982 | }, 983 | { 984 | "codec": "H.265", 985 | "subtitles": "English", 986 | "title": "Shaman King" 987 | }, 988 | { 989 | "audio": "Dolby Digital Plus 5.1", 990 | "codec": "H.264", 991 | "language": "Japanese", 992 | "network": "Netflix", 993 | "title": "A Whisker Away" 994 | }, 995 | { 996 | "audio": "Dolby Digital 5.1", 997 | "codec": "H.265", 998 | "filetype": "MKV", 999 | "language": "Japanese", 1000 | "quality": "Blu-ray", 1001 | "title": "liz and the blue bird" 1002 | }, 1003 | { 1004 | "filetype": "MKV", 1005 | "language": ["Italian","English"], 1006 | "network": "Amazon Studios", 1007 | "quality": "WEB-DL", 1008 | "title": "The Flash" 1009 | }, 1010 | { 1011 | "audio": "Dolby Digital Plus 5.1", 1012 | "codec": "H.264", 1013 | "network": "DC Universe", 1014 | "title": "Harley Quinn" 1015 | }, 1016 | { 1017 | "codec": "H.264", 1018 | "title": "The Killer Truth" 1019 | }, 1020 | { 1021 | "audio": "Dolby Digital 2.0", 1022 | "codec": "H.265", 1023 | "network": "HBO Max", 1024 | "quality": "WEBRip", 1025 | "title": "The Flintstones" 1026 | }, 1027 | { 1028 | "codec": "H.264", 1029 | "quality": "WEBRip", 1030 | "title": "Jamies Super Food" 1031 | }, 1032 | { 1033 | "audio": "Dolby Digital Plus 5.1", 1034 | "network": "Amazon Studios", 1035 | "title": "Blindspot" 1036 | }, 1037 | { 1038 | "audio": "Dolby Digital Plus 5.1", 1039 | "network": "Amazon Studios", 1040 | "title": "In the Dark" 1041 | }, 1042 | { 1043 | "codec": "H.264", 1044 | "network": "Netflix", 1045 | "title": "Babies" 1046 | }, 1047 | { 1048 | "codec": "H.264", 1049 | "title": "WWE Monday Night RAW" 1050 | }, 1051 | { 1052 | "quality": "WEB-DL", 1053 | "title": "The Rachel Maddow Show" 1054 | }, 1055 | { 1056 | "quality": "WEB-DL", 1057 | "title": "The Last Word with Lawrence O'Donnell" 1058 | }, 1059 | { 1060 | "codec": "H.264", 1061 | "quality": "WEBRip", 1062 | "title": "Design at Your Door" 1063 | }, 1064 | { 1065 | "audio": "AAC 2.0", 1066 | "network": "MSNBC", 1067 | "title": "The Rachel Maddow Show" 1068 | }, 1069 | { 1070 | "codec": "H.264", 1071 | "quality": "WEBRip", 1072 | "title": "Lalbazaar" 1073 | }, 1074 | { 1075 | "codec": "H.264", 1076 | "network": "HBO Max", 1077 | "title": "Scandalous The Untold Story of the National Enquirer" 1078 | }, 1079 | { 1080 | "codec": "H.264", 1081 | "title": "Turtle Odyssey" 1082 | }, 1083 | { 1084 | "codec": "H.264", 1085 | "title": "Still A Mystery" 1086 | }, 1087 | { 1088 | "audio": "Dolby Digital 2.0", 1089 | "codec": "H.265", 1090 | "quality": "Blu-ray", 1091 | "title": "When Bjork Met Attenborough" 1092 | }, 1093 | { 1094 | "codec": "H.264", 1095 | "network": "Hulu Networks", 1096 | "title": "And We Go Green" 1097 | }, 1098 | { 1099 | "subtitles": "Available", 1100 | "title": "Ella Fitzgerald - Just One of Those Things" 1101 | }, 1102 | { 1103 | "codec": "H.264", 1104 | "title": "Inventing Tomorrow" 1105 | }, 1106 | { 1107 | "codec": "H.264", 1108 | "title": "Eating Up Easter" 1109 | }, 1110 | { 1111 | "codec": "H.264", 1112 | "quality": "WEBRip", 1113 | "title": "Trackers" 1114 | }, 1115 | { 1116 | "codec": "H.265", 1117 | "filetype": "MKV", 1118 | "title": "When Pop Went Epic" 1119 | }, 1120 | { 1121 | "codec": "H.264", 1122 | "title": "Big Brother AU" 1123 | }, 1124 | { 1125 | "codec": "H.264", 1126 | "quality": "WEBRip", 1127 | "title": "Frontline" 1128 | }, 1129 | { 1130 | "audio": "Dolby Digital 5.1", 1131 | "filetype": "MKV", 1132 | "language": ["Italian","English"], 1133 | "network": "Amazon Studios", 1134 | "quality": "WEB-DL", 1135 | "title": "Marvel's Agents of S.H.I.E.L.D." 1136 | }, 1137 | { 1138 | "codec": "H.264", 1139 | "subtitles": "English", 1140 | "title": "Your Honor" 1141 | }, 1142 | { 1143 | "codec": "H.264", 1144 | "filetype": "MP4", 1145 | "title": "The Beat with Ari Melber" 1146 | }, 1147 | { 1148 | "codec": "H.264", 1149 | "subtitles": "Available", 1150 | "title": "Thirteen" 1151 | }, 1152 | { 1153 | "codec": "H.264", 1154 | "network": "Netflix", 1155 | "subtitles": "English", 1156 | "title": "Paan Singh Tomar" 1157 | }, 1158 | { 1159 | "audio": "AAC 2.0", 1160 | "network": "Hulu Networks", 1161 | "title": "MASH" 1162 | }, 1163 | { 1164 | "codec": "H.264", 1165 | "quality": "WEBRip", 1166 | "title": "Trishas Southern Kitchen" 1167 | }, 1168 | { 1169 | "language": "English", 1170 | "title": "Split Image" 1171 | }, 1172 | { 1173 | "title": "Kaguya-sama wa Kokurasetai" 1174 | }, 1175 | { 1176 | "audio": "Mono", 1177 | "codec": "Xvid", 1178 | "language": "English", 1179 | "quality": "DVD-Rip", 1180 | "title": "Five" 1181 | }, 1182 | { 1183 | "codec": "H.264", 1184 | "quality": "WEBRip", 1185 | "title": "NOS4A2" 1186 | }, 1187 | { 1188 | "codec": "H.264", 1189 | "title": "Diners Drive-Ins and Dives" 1190 | }, 1191 | { 1192 | "filetype": "MKV", 1193 | "title": "Arte" 1194 | }, 1195 | { 1196 | "title": "Kaguya-sama wa Kokurasetai! Tensai-tachi no Renai Zunousen" 1197 | }, 1198 | { 1199 | "audio": "Dolby Digital 5.1", 1200 | "codec": "H.264", 1201 | "network": "Amazon Studios", 1202 | "title": "Prawaas" 1203 | }, 1204 | { 1205 | "filetype": "MKV", 1206 | "subtitles": "Available", 1207 | "title": "Yesterday o Utatte" 1208 | }, 1209 | { 1210 | "filetype": "MKV", 1211 | "subtitles": "Available", 1212 | "title": "Honzuki no Gekokujou - Shisho ni Naru Tame ni wa Shudan wo Erandeiraremasen" 1213 | }, 1214 | { 1215 | "quality": "WEBRip", 1216 | "title": "Babyteeth" 1217 | }, 1218 | { 1219 | "quality": "Blu-ray", 1220 | "title": "Weekend at Bernie's II" 1221 | }, 1222 | { 1223 | "codec": "H.264", 1224 | "quality": "WEBRip", 1225 | "title": "Naked and Afraid XL" 1226 | }, 1227 | { 1228 | "audio": "Dolby Digital 2.0", 1229 | "codec": "H.265", 1230 | "network": "Netflix", 1231 | "quality": "WEBRip", 1232 | "title": "The Fresh Prince of Bel-Air" 1233 | }, 1234 | { 1235 | "title": "Tsugumomo" 1236 | }, 1237 | { 1238 | "resolution": "720p", 1239 | "subtitles": "English", 1240 | "title": "Black Hollywood: 'They've Gotta Have Us'" 1241 | }, 1242 | { 1243 | "codec": "H.264", 1244 | "title": "Police Ten 7" 1245 | }, 1246 | { 1247 | "codec": "H.264", 1248 | "title": "2nd Chance Charlie" 1249 | }, 1250 | { 1251 | "codec": "H.265", 1252 | "filetype": "MKV", 1253 | "title": "Billy and Us" 1254 | }, 1255 | { 1256 | "codec": "H.265", 1257 | "resolution": "720p", 1258 | "title": "Mystery Diners" 1259 | }, 1260 | { 1261 | "quality": "WEB-DL", 1262 | "title": "Amar" 1263 | }, 1264 | { 1265 | "codec": "H.264", 1266 | "title": "Oolu" 1267 | }, 1268 | { 1269 | "audio": "Dolby Digital 2.0", 1270 | "codec": "H.264", 1271 | "quality": "Blu-ray", 1272 | "size": "800MB", 1273 | "subtitles": "Available", 1274 | "title": "Vacancy" 1275 | }, 1276 | { 1277 | "audio": "Dual", 1278 | "codec": "H.264", 1279 | "quality": "WEB-DL", 1280 | "title": "Darkness Falls" 1281 | }, 1282 | { 1283 | "audio": "Dolby Digital 5.1", 1284 | "codec": "H.264", 1285 | "language": ["Italian","English"], 1286 | "title": "Wasp Network" 1287 | }, 1288 | { 1289 | "filetype": "MKV", 1290 | "language": ["Italian","English"], 1291 | "quality": "Blu-ray", 1292 | "title": "Darlin" 1293 | }, 1294 | { 1295 | "codec": "H.264", 1296 | "filetype": "MP4", 1297 | "quality": "DVD-Rip", 1298 | "title": "Wild Target" 1299 | }, 1300 | { 1301 | "audio": "Dolby Digital 5.1", 1302 | "codec": "H.264", 1303 | "language": ["Italian","Danish"], 1304 | "title": "Infection-What We Become" 1305 | }, 1306 | { 1307 | "codec": "H.264", 1308 | "language": "Hindi", 1309 | "title": "Perversion" 1310 | }, 1311 | { 1312 | "codec": "H.265", 1313 | "quality": "Blu-ray", 1314 | "title": "Casino" 1315 | }, 1316 | { 1317 | "audio": "5.1", 1318 | "quality": "WEB-DL", 1319 | "title": "Parks and Recreation" 1320 | }, 1321 | { 1322 | "codec": "H.264", 1323 | "quality": "Blu-ray", 1324 | "subtitles": "Available", 1325 | "title": "The Amazing Spider-Man 2" 1326 | }, 1327 | { 1328 | "audio": "Dolby Digital Plus 5.1", 1329 | "codec": "H.265", 1330 | "filetype": "MKV", 1331 | "title": "Jay And Silent Bob Strike Back" 1332 | }, 1333 | { 1334 | "quality": "Blu-ray", 1335 | "subtitles": "English", 1336 | "title": "Mother [Madre]" 1337 | }, 1338 | { 1339 | "language": "Bengali", 1340 | "quality": "WEB-DL", 1341 | "title": "Ridoy Jure" 1342 | }, 1343 | { 1344 | "codec": "H.264", 1345 | "filetype": "MP4", 1346 | "language": ["English","Russian"], 1347 | "subtitles": "Available", 1348 | "title": "The Deep Blue Sea" 1349 | }, 1350 | { 1351 | "audio": "Dolby TrueHD 5.1", 1352 | "codec": "H.265", 1353 | "filetype": "MKV", 1354 | "title": "Clerks II" 1355 | }, 1356 | { 1357 | "title": "Rustlers on Horseback" 1358 | }, 1359 | { 1360 | "codec": "H.264", 1361 | "quality": "WEBRip", 1362 | "title": "Athlete A" 1363 | }, 1364 | { 1365 | "language": "Bengali", 1366 | "quality": "WEB-DL", 1367 | "title": "SHAHENSHA" 1368 | }, 1369 | { 1370 | "audio": "Dolby Digital 2.0", 1371 | "codec": "H.264", 1372 | "network": "Amazon Studios", 1373 | "subtitles": "English", 1374 | "title": "Rasbhari" 1375 | }, 1376 | { 1377 | "codec": "H.264", 1378 | "filetype": "MP4", 1379 | "quality": "DVD-Rip", 1380 | "title": "A Walk in the Woods" 1381 | }, 1382 | { 1383 | "title": "Treasure Planet" 1384 | }, 1385 | { 1386 | "codec": "H.265", 1387 | "language": ["English","Japanese"], 1388 | "title": "L.A. Story" 1389 | }, 1390 | { 1391 | "codec": "H.265", 1392 | "title": "Monk" 1393 | }, 1394 | { 1395 | "codec": "H.265", 1396 | "title": "24 Hours In A And E" 1397 | }, 1398 | { 1399 | "codec": "H.264", 1400 | "title": "Stephen Colbert" 1401 | }, 1402 | { 1403 | "codec": "H.264", 1404 | "quality": "WEBRip", 1405 | "title": "American Masters" 1406 | }, 1407 | { 1408 | "codec": "H.265", 1409 | "title": "The 11th Hour with Brian Williams" 1410 | }, 1411 | { 1412 | "audio": "Dual", 1413 | "codec": "H.265", 1414 | "quality": "Blu-ray", 1415 | "subtitles": "English", 1416 | "title": "Black Lagoon" 1417 | }, 1418 | { 1419 | "codec": "H.265", 1420 | "subtitles": "Available", 1421 | "title": "One Piece" 1422 | }, 1423 | { 1424 | "title": "Shokugeki No Soma" 1425 | }, 1426 | { 1427 | "audio": "DTS-HD MA 5.1", 1428 | "codec": "H.264", 1429 | "quality": "Blu-ray", 1430 | "title": "Dil Chahta Hai" 1431 | }, 1432 | { 1433 | "codec": "H.264", 1434 | "network": "Amazon Studios", 1435 | "subtitles": "English", 1436 | "title": "NOS4A2" 1437 | }, 1438 | { 1439 | "codec": "H.265", 1440 | "subtitles": "Available", 1441 | "title": "Haikyuu!!" 1442 | }, 1443 | { 1444 | "audio": "Dolby Digital 2.0", 1445 | "codec": "H.264", 1446 | "size": "2.5GB", 1447 | "subtitles": "English", 1448 | "title": "Moothon: The Elder One" 1449 | }, 1450 | { 1451 | "audio": "Dolby Digital 5.1", 1452 | "codec": "H.264", 1453 | "language": ["Italian","French"], 1454 | "quality": "Blu-ray", 1455 | "subtitles": ["Italian","English"], 1456 | "title": "Doppia Pelle - Le Daim" 1457 | }, 1458 | { 1459 | "audio": "DTS-HD MA 5.1", 1460 | "codec": "H.264", 1461 | "language": ["Italian","English"], 1462 | "subtitles": ["Italian","English"], 1463 | "title": "The Twilight Saga: Breaking Down - Parte 2" 1464 | }, 1465 | { 1466 | "audio": "Dolby Digital 2.0", 1467 | "codec": "H.264", 1468 | "quality": "Blu-ray", 1469 | "size": "1.3GB", 1470 | "subtitles": "English", 1471 | "title": "The Painted Bird" 1472 | }, 1473 | { 1474 | "audio": "DTS-HD MA 5.1", 1475 | "codec": "H.264", 1476 | "quality": "Blu-ray", 1477 | "title": "Proximity" 1478 | }, 1479 | { 1480 | "codec": "Xvid", 1481 | "quality": "DSRip", 1482 | "title": "Soviet Cinema - Provintsialki" 1483 | }, 1484 | { 1485 | "audio": "Dolby Digital 5.1", 1486 | "codec": "H.265", 1487 | "language": ["Italian","English"], 1488 | "subtitles": ["Italian","English"], 1489 | "title": "Just Mercy - Il diritto di opporsi" 1490 | }, 1491 | { 1492 | "codec": "H.264", 1493 | "title": "Mae West Dirty Blonde" 1494 | }, 1495 | { 1496 | "language": "English", 1497 | "subtitles": "Arabic", 1498 | "title": "The Ottomans: Europe's Muslim Emperors" 1499 | }, 1500 | { 1501 | "codec": "H.264", 1502 | "quality": "Blu-ray", 1503 | "title": "War" 1504 | }, 1505 | { 1506 | "codec": "Xvid", 1507 | "title": "X-Men" 1508 | }, 1509 | { 1510 | "codec": "Xvid", 1511 | "title": "X2 X-Men United" 1512 | }, 1513 | { 1514 | "audio": "Dolby Digital 2.0", 1515 | "codec": "H.264", 1516 | "size": "1.5GB", 1517 | "subtitles": "English", 1518 | "title": "#Yaaram" 1519 | }, 1520 | { 1521 | "audio": "Dolby Digital 5.1", 1522 | "codec": "H.264", 1523 | "language": ["Italian","Spanish"], 1524 | "title": "Nessuno sa chi io sono qui-Nadie sabe que estoy aqui" 1525 | }, 1526 | { 1527 | "audio": "Dolby Digital 2.0", 1528 | "codec": "H.264", 1529 | "language": ["Italian","English"], 1530 | "title": "L.ultima corve" 1531 | }, 1532 | { 1533 | "audio": "Dolby Digital 2.0", 1534 | "codec": "H.264", 1535 | "language": ["Italian","English"], 1536 | "title": "La signora di Shanghai-The lady from Shanghai" 1537 | }, 1538 | { 1539 | "language": ["Telugu","Tamil","Hindi","Chinese"], 1540 | "quality": "Blu-ray", 1541 | "subtitles": "English", 1542 | "title": "The Four" 1543 | }, 1544 | { 1545 | "audio": "Dual", 1546 | "codec": "H.264", 1547 | "network": "Amazon Studios", 1548 | "size": "1.2GB", 1549 | "subtitles": "English", 1550 | "title": "Samrat & Co." 1551 | }, 1552 | { 1553 | "codec": "H.264", 1554 | "quality": "WEB-DL", 1555 | "title": "Tulips in Spring" 1556 | }, 1557 | { 1558 | "audio": "Dolby Digital 5.1", 1559 | "codec": "H.265", 1560 | "language": ["English","Spanish"], 1561 | "network": "Netflix", 1562 | "size": "950MB", 1563 | "title": "Adu" 1564 | }, 1565 | { 1566 | "codec": "H.264", 1567 | "resolution": "720p", 1568 | "title": "When Sparks Fly" 1569 | }, 1570 | { 1571 | "audio": "Dolby Digital 5.1", 1572 | "codec": "H.264", 1573 | "quality": "WEB-DL", 1574 | "subtitles": "Available", 1575 | "title": "The Fxxk-It List" 1576 | }, 1577 | { 1578 | "codec": "H.265", 1579 | "filetype": "MKV", 1580 | "title": "The Twilight Saga Breaking Dawn - Part 2" 1581 | }, 1582 | { 1583 | "codec": "H.265", 1584 | "filetype": "MKV", 1585 | "quality": "DVD-Rip", 1586 | "title": "Scooby-Doo Goes Hollywood" 1587 | }, 1588 | { 1589 | "audio": "Dolby Digital", 1590 | "codec": "H.264", 1591 | "subtitles": "English", 1592 | "title": "Sarkar 3" 1593 | }, 1594 | { 1595 | "audio": "Dolby Digital 2.0", 1596 | "codec": "H.264", 1597 | "network": "Amazon Studios", 1598 | "quality": "WEB-DL", 1599 | "title": "Jagga Jagravan Joga" 1600 | }, 1601 | { 1602 | "codec": "H.264", 1603 | "filetype": "MP4", 1604 | "title": "Sea Monsters" 1605 | }, 1606 | { 1607 | "audio": "Dolby Digital 5.1", 1608 | "codec": "H.264", 1609 | "quality": "Blu-ray", 1610 | "subtitles": "English", 1611 | "title": "Dukhtar" 1612 | }, 1613 | { 1614 | "subtitles": "English", 1615 | "title": "Main Teri Tu Mera" 1616 | }, 1617 | { 1618 | "quality": "WEB-DL", 1619 | "title": "RangiTaranga" 1620 | }, 1621 | { 1622 | "codec": "H.265", 1623 | "quality": "Blu-ray", 1624 | "title": "McFarland USA" 1625 | }, 1626 | { 1627 | "audio": "DTS-HD MA 5.1", 1628 | "codec": "H.264", 1629 | "quality": "Blu-ray", 1630 | "title": "Jasper Mall" 1631 | }, 1632 | { 1633 | "codec": "H.265", 1634 | "language": "Japanese", 1635 | "quality": "Blu-ray", 1636 | "title": "Lupin III The First" 1637 | }, 1638 | { 1639 | "codec": "H.265", 1640 | "language": "Japanese", 1641 | "subtitles": "English", 1642 | "title": "The Rule for a Vagabond" 1643 | }, 1644 | { 1645 | "codec": "H.264", 1646 | "language": "Portuguese", 1647 | "quality": "Blu-ray", 1648 | "title": "Cousins" 1649 | }, 1650 | { 1651 | "quality": "BRRip", 1652 | "title": "Easy Rider" 1653 | }, 1654 | { 1655 | "audio": "Dolby Digital 5.1", 1656 | "codec": "H.264", 1657 | "quality": "WEB-DL", 1658 | "subtitles": "English", 1659 | "title": "PENALTY" 1660 | }, 1661 | { 1662 | "audio": "Dual", 1663 | "codec": "H.264", 1664 | "quality": "WEB-DL", 1665 | "title": "Wasp Network" 1666 | }, 1667 | { 1668 | "quality": "BRRip", 1669 | "title": "The Gentlemen" 1670 | }, 1671 | { 1672 | "codec": "H.264", 1673 | "quality": "WEBRip", 1674 | "title": "Nicos Menu Mission" 1675 | }, 1676 | { 1677 | "codec": "H.264", 1678 | "title": "If Loving You Is Wrong" 1679 | }, 1680 | { 1681 | "title": "Digimon Adventure" 1682 | }, 1683 | { 1684 | "title": "Kavali" 1685 | }, 1686 | { 1687 | "codec": "H.264", 1688 | "filetype": "MKV", 1689 | "language": ["Italian","English"], 1690 | "quality": "AHDTV", 1691 | "title": "Gangs Of London" 1692 | }, 1693 | { 1694 | "codec": "H.264", 1695 | "filetype": "MKV", 1696 | "language": ["Italian","English"], 1697 | "quality": "Blu-ray", 1698 | "title": "Fear the Walking Dead" 1699 | }, 1700 | { 1701 | "codec": "H.264", 1702 | "title": "2nd Chance Charlie" 1703 | }, 1704 | { 1705 | "codec": "H.264", 1706 | "title": "Police Ten 7" 1707 | }, 1708 | { 1709 | "audio": "Dual", 1710 | "language": ["Hindi","Marathi"], 1711 | "quality": "WEBRip", 1712 | "title": "Nude" 1713 | }, 1714 | { 1715 | "codec": "H.265", 1716 | "quality": "Blu-ray", 1717 | "title": "X-men The Last Stand" 1718 | }, 1719 | { 1720 | "genre": ["Comedy","Western"], 1721 | "title": "The Kissing Bandit" 1722 | }, 1723 | { 1724 | "title": "The King of Comedy" 1725 | }, 1726 | { 1727 | "genre": "Comedy", 1728 | "title": "The Mouse on the Moon" 1729 | }, 1730 | { 1731 | "audio": "Dolby Digital Plus 2.0", 1732 | "codec": "H.264", 1733 | "network": "Amazon Studios", 1734 | "title": "Romantic Comedy" 1735 | }, 1736 | { 1737 | "title": "Sugarfoot" 1738 | }, 1739 | { 1740 | "codec": "H.264", 1741 | "quality": "WEBRip", 1742 | "title": "Valeries Home Cooking" 1743 | }, 1744 | { 1745 | "audio": "AAC 2.0", 1746 | "codec": "H.264", 1747 | "network": "Investigation Discovery", 1748 | "title": "American Monster" 1749 | }, 1750 | { 1751 | "audio": "Dolby Digital 5.1", 1752 | "codec": "H.264", 1753 | "language": ["Italian","English","German","Spanish"], 1754 | "quality": "DVD-Rip", 1755 | "subtitles": "Available", 1756 | "title": "Professor Marston and the Wonder Women" 1757 | }, 1758 | { 1759 | "audio": "DTS-HD MA 5.1", 1760 | "codec": "H.264", 1761 | "filetype": "MKV", 1762 | "quality": "Blu-ray", 1763 | "title": "Extraterrestrial" 1764 | }, 1765 | { 1766 | "codec": "H.264", 1767 | "title": "Magnum P.I." 1768 | }, 1769 | { 1770 | "audio": "Dolby Digital 5.1", 1771 | "codec": "H.264", 1772 | "filetype": "MKV", 1773 | "quality": "Blu-ray", 1774 | "title": "Friends" 1775 | }, 1776 | { 1777 | "codec": "H.264", 1778 | "filetype": "SRT", 1779 | "quality": "Blu-ray", 1780 | "title": "Shrek 2" 1781 | }, 1782 | { 1783 | "audio": "Dolby Digital 5.1", 1784 | "codec": "H.264", 1785 | "quality": "HD DVD", 1786 | "title": "Accepted" 1787 | }, 1788 | { 1789 | "audio": "Dolby Digital 2.0", 1790 | "network": "Amazon Studios", 1791 | "title": "Its Always Sunny In Philadelphia" 1792 | }, 1793 | { 1794 | "audio": "Dolby Digital 5.1", 1795 | "title": "Animals" 1796 | }, 1797 | { 1798 | "audio": "AAC 2.0", 1799 | "network": "iTunes", 1800 | "title": "SpongeBob SquarePants" 1801 | }, 1802 | { 1803 | "audio": "AAC 2.0", 1804 | "network": "Adult Swim", 1805 | "title": "The Shivering Truth" 1806 | }, 1807 | { 1808 | "audio": "AAC 2.0", 1809 | "network": "Crave", 1810 | "title": "Letterkenny" 1811 | }, 1812 | { 1813 | "audio": "AAC 2.0", 1814 | "codec": "H.264", 1815 | "network": "Comedy Central", 1816 | "title": "Workaholics" 1817 | }, 1818 | { 1819 | "audio": "AAC 2.0", 1820 | "codec": "H.264", 1821 | "network": "Seeso", 1822 | "title": "HarmonQuest" 1823 | }, 1824 | { 1825 | "codec": "H.264", 1826 | "title": "Bee and Puppycat" 1827 | }, 1828 | { 1829 | "audio": "Dolby Digital Plus 5.0", 1830 | "codec": "H.264", 1831 | "network": "Peacock", 1832 | "title": "A P Bio" 1833 | }, 1834 | { 1835 | "audio": "AAC 2.0", 1836 | "codec": "H.264", 1837 | "filetype": "MKV", 1838 | "title": "Star Trek Discovery" 1839 | }, 1840 | { 1841 | "audio": "Dolby TrueHD 5.1", 1842 | "filetype": "MKV", 1843 | "quality": "Blu-ray", 1844 | "title": "IMAX Blue Planet" 1845 | }, 1846 | { 1847 | "audio": "Dolby Digital EX", 1848 | "codec": "H.264", 1849 | "quality": "Blu-ray", 1850 | "title": "John Wick Chapter 2" 1851 | }, 1852 | { 1853 | "audio": "DTS-HD MA", 1854 | "codec": "H.264", 1855 | "quality": "Blu-ray", 1856 | "title": "Archer" 1857 | }, 1858 | { 1859 | "audio": "FLAC 2.0", 1860 | "codec": "H.264", 1861 | "quality": "Blu-ray", 1862 | "title": "Peaky Blinders" 1863 | }, 1864 | { 1865 | "codec": "H.264", 1866 | "quality": "DVD-Rip", 1867 | "title": "Ghost Stories" 1868 | }, 1869 | { 1870 | "audio": "AAC 2.0", 1871 | "filetype": "MKV", 1872 | "network": "BBC iPlayer", 1873 | "title": "Rick Steins Road To Mexico" 1874 | }, 1875 | { 1876 | "audio": "AAC 2.0", 1877 | "filetype": "MKV", 1878 | "title": "Road to the NHL Winter Classic" 1879 | }, 1880 | { 1881 | "audio": "AAC 2.0", 1882 | "filetype": "MKV", 1883 | "title": "Robert Kirkmans Secret History of Comics" 1884 | }, 1885 | { 1886 | "audio": "AAC 2.0", 1887 | "codec": "H.264", 1888 | "filetype": "MKV", 1889 | "title": "Ready Jet Go" 1890 | }, 1891 | { 1892 | "audio": "AAC 2.0", 1893 | "filetype": "MKV", 1894 | "network": "Stan.", 1895 | "title": "Philip K Dicks Electric Dreams" 1896 | }, 1897 | { 1898 | "audio": "AAC 2.0", 1899 | "codec": "H.264", 1900 | "filetype": "MKV", 1901 | "network": "DisneyNOW", 1902 | "title": "Octonauts" 1903 | }, 1904 | { 1905 | "audio": "AAC 2.0", 1906 | "filetype": "MKV", 1907 | "network": "RTE Player", 1908 | "title": "Nowhere Fast" 1909 | }, 1910 | { 1911 | "audio": "AAC 2.0", 1912 | "codec": "H.264", 1913 | "network": "Crunchyroll", 1914 | "title": "New Game" 1915 | }, 1916 | { 1917 | "audio": "AAC 2.0", 1918 | "codec": "H.264", 1919 | "filetype": "MKV", 1920 | "network": "Animal Planet Live", 1921 | "title": "Mystery of the Lost Islands" 1922 | }, 1923 | { 1924 | "audio": "Dolby Digital 2.0", 1925 | "codec": "H.264", 1926 | "filetype": "MKV", 1927 | "network": "DirecTV Stream", 1928 | "title": "Mr Mercedes" 1929 | }, 1930 | { 1931 | "audio": "AAC 2.0", 1932 | "codec": "H.264", 1933 | "filetype": "MKV", 1934 | "title": "Most Expensivest" 1935 | }, 1936 | { 1937 | "quality": "Blu-ray", 1938 | "title": "Non Non Biyori" 1939 | }, 1940 | { 1941 | "quality": "Blu-ray", 1942 | "title": "Darling in the Franxx" 1943 | }, 1944 | { 1945 | "quality": "Blu-ray", 1946 | "title": "One Piece Movies Collection" 1947 | }, 1948 | { 1949 | "audio": "Dual", 1950 | "codec": "H.264", 1951 | "title": "Naruto" 1952 | }, 1953 | { 1954 | "audio": "Dolby TrueHD", 1955 | "quality": "Blu-ray", 1956 | "title": "Attack on Titan" 1957 | }, 1958 | { 1959 | "quality": "Blu-ray", 1960 | "title": "Black Clover" 1961 | }, 1962 | { 1963 | "quality": "Blu-ray", 1964 | "title": "Hero Mask" 1965 | }, 1966 | { 1967 | "codec": "H.264", 1968 | "quality": "BDRip", 1969 | "resolution": "1080p", 1970 | "title": "Nisekoi" 1971 | }, 1972 | { 1973 | "audio": "Dual", 1974 | "codec": "H.265", 1975 | "title": "Kimi no Suizou o Tabetai" 1976 | }, 1977 | { 1978 | "audio": "Dual", 1979 | "title": "Accel World" 1980 | }, 1981 | { 1982 | "audio": "Dolby Digital 5.1", 1983 | "codec": "H.264", 1984 | "title": "The Djinn" 1985 | }, 1986 | { 1987 | "genre": "Drama", 1988 | "language": "Albanian", 1989 | "title": "Hive" 1990 | }, 1991 | { 1992 | "genre": "Drama", 1993 | "language": "Egyptian", 1994 | "title": "Souad" 1995 | }, 1996 | { 1997 | "genre": "Drama", 1998 | "language": "Polish", 1999 | "title": "Swinki" 2000 | }, 2001 | { 2002 | "genre": "Thriller", 2003 | "title": "Dead Heat on a Merry Go Round" 2004 | }, 2005 | { 2006 | "audio": "Dolby Digital", 2007 | "codec": "H.264", 2008 | "filetype": "MP4", 2009 | "title": "Justified" 2010 | }, 2011 | { 2012 | "codec": "H.264", 2013 | "quality": "Blu-ray", 2014 | "title": "Movie 43" 2015 | }, 2016 | { 2017 | "codec": "H.264", 2018 | "quality": "Blu-ray", 2019 | "title": "Mommy" 2020 | }, 2021 | { 2022 | "codec": "H.265", 2023 | "title": "Rendez Vous." 2024 | }, 2025 | { 2026 | "filetype": "MKV", 2027 | "title": "The Best Offer" 2028 | }, 2029 | { 2030 | "audio": "Dolby Digital Plus 2.0", 2031 | "codec": "H.264", 2032 | "filetype": "MKV", 2033 | "title": "What If..." 2034 | }, 2035 | { 2036 | "audio": "AAC 2.0", 2037 | "codec": "H.264", 2038 | "filetype": "MKV", 2039 | "title": "Eu gosto do Homem-Aranha... y dai" 2040 | }, 2041 | { 2042 | "filetype": "MP4", 2043 | "title": "tick tick...BOOM" 2044 | }, 2045 | { 2046 | "codec": "H.264", 2047 | "resolution": "720p", 2048 | "title": "Sons of Anarchy" 2049 | }, 2050 | { 2051 | "audio": "AAC 2.0", 2052 | "codec": "H.264", 2053 | "filetype": "MKV", 2054 | "title": "Lollapalooza" 2055 | }, 2056 | { 2057 | "codec": "H.265", 2058 | "quality": "Blu-ray", 2059 | "title": "Dark Matter" 2060 | }, 2061 | { 2062 | "codec": "H.264", 2063 | "language": "French", 2064 | "quality": "WEBRip", 2065 | "title": "Presque" 2066 | }, 2067 | { 2068 | "audio": "Dolby Digital Plus 5.1", 2069 | "codec": "H.265", 2070 | "filetype": "MKV", 2071 | "quality": "WEB-DL", 2072 | "sbs": "SBS", 2073 | "subtitles": "English", 2074 | "title": "Lucky Man" 2075 | }, 2076 | { 2077 | "codec": "H.264", 2078 | "language": ["Tamil","Malayalam","Telugu","Kannada"], 2079 | "quality": "WEB-DL", 2080 | "subtitles": "English", 2081 | "title": "Sultan of Delhi" 2082 | }, 2083 | { 2084 | "audio": "Custom", 2085 | "filetype": "MKV", 2086 | "language": "Polish", 2087 | "title": "Mission Impossible" 2088 | }, 2089 | { 2090 | "audio": "DTS-ES 6.1", 2091 | "filetype": "MKV", 2092 | "quality": "Blu-ray", 2093 | "title": "Black Rain" 2094 | }, 2095 | { 2096 | "audio": "Dolby Digital EX 5.1", 2097 | "codec": "H.264", 2098 | "filetype": "ISO", 2099 | "quality": "Blu-ray", 2100 | "title": "Bolt" 2101 | }, 2102 | { 2103 | "audio": "DTS:X 7.1", 2104 | "codec": "H.265", 2105 | "filetype": "MKV", 2106 | "quality": "Blu-ray", 2107 | "title": "Casino" 2108 | }, 2109 | { 2110 | "audio": "HE-AAC 2.0", 2111 | "codec": "H.264", 2112 | "filetype": "MKV", 2113 | "network": "Netflix", 2114 | "title": "Seinfeld" 2115 | }, 2116 | { 2117 | "audio": "HE-AAC v2", 2118 | "filetype": "MKV", 2119 | "language": "Polish", 2120 | "title": "Escape Room Tournament of Champions" 2121 | }, 2122 | { 2123 | "title": "Steven Universe" 2124 | }, 2125 | { 2126 | "title": "The Amazing World of Gumball" 2127 | }, 2128 | { 2129 | "codec": "H.265", 2130 | "title": "Avatar The Last Airbender" 2131 | }, 2132 | { 2133 | "title": "The Inbetweeners" 2134 | }, 2135 | { 2136 | "title": "The Sopranos" 2137 | }, 2138 | { 2139 | "codec": "H.264", 2140 | "filetype": "MKV", 2141 | "subtitles": "French", 2142 | "title": "The Walking Dead" 2143 | }, 2144 | { 2145 | "audio": "AAC", 2146 | "codec": "H.264", 2147 | "filetype": "MKV", 2148 | "quality": "WEB-DL", 2149 | "subtitles": "French", 2150 | "title": "The Good German" 2151 | }, 2152 | { 2153 | "title": "Anatomy Of A Fall" 2154 | }, 2155 | { 2156 | "audio": "AAC 2.0", 2157 | "codec": "H.264", 2158 | "filetype": "MKV", 2159 | "title": "Eu gosto do Homem-Aranha e dai" 2160 | }, 2161 | { 2162 | "codec": "H.264", 2163 | "filetype": "MKV", 2164 | "resolution": "1440p", 2165 | "subtitles": "English", 2166 | "title": "Thuritham" 2167 | } 2168 | ] 2169 | --------------------------------------------------------------------------------