Compare commits
2 Commits
4365e083dc
...
9dc08d48e9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9dc08d48e9 | ||
|
|
20bdfc0dd7 |
@@ -60,7 +60,7 @@
|
|||||||
- optional crop detection and crop application,
|
- optional crop detection and crop application,
|
||||||
- optional deinterlacing and denoising,
|
- optional deinterlacing and denoising,
|
||||||
- optional subtitle import from external files,
|
- optional subtitle import from external files,
|
||||||
- rename-only copy mode.
|
- rename-only move mode.
|
||||||
- The system shall support optional TMDB lookups to resolve show names, years, and episode titles when a show ID, season, and episode are available.
|
- The system shall support optional TMDB lookups to resolve show names, years, and episode titles when a show ID, season, and episode are available.
|
||||||
- The system shall generate output filenames from show metadata, season and episode indices, and episode names using the configured filename template.
|
- The system shall generate output filenames from show metadata, season and episode indices, and episode names using the configured filename template.
|
||||||
- The system shall allow CLI overrides for stream languages, stream titles, default and forced tracks, stream order, TMDB show and episode data, output directory, label prefix, and processing resource limits.
|
- The system shall allow CLI overrides for stream languages, stream titles, default and forced tracks, stream order, TMDB show and episode data, output directory, label prefix, and processing resource limits.
|
||||||
|
|||||||
@@ -764,7 +764,7 @@ def checkUniqueDispositions(context, mediaDescriptor: MediaDescriptor):
|
|||||||
help=CPU_OPTION_HELP,
|
help=CPU_OPTION_HELP,
|
||||||
)
|
)
|
||||||
|
|
||||||
@click.option('--rename-only', is_flag=True, default=False, help='Only renaming, no recoding')
|
@click.option('--rename-only', is_flag=True, default=False, help='Only renaming and moving, no recoding')
|
||||||
|
|
||||||
def convert(ctx,
|
def convert(ctx,
|
||||||
paths,
|
paths,
|
||||||
@@ -1247,7 +1247,7 @@ def convert(ctx,
|
|||||||
|
|
||||||
|
|
||||||
if rename_only:
|
if rename_only:
|
||||||
shutil.copyfile(sourcePath, targetPath)
|
shutil.move(sourcePath, targetPath)
|
||||||
else:
|
else:
|
||||||
fc.runJob(sourcePath,
|
fc.runJob(sourcePath,
|
||||||
targetPath,
|
targetPath,
|
||||||
|
|||||||
@@ -1,68 +1,155 @@
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
import difflib
|
import difflib
|
||||||
|
|
||||||
|
|
||||||
class IsoLanguage(Enum):
|
class IsoLanguage(Enum):
|
||||||
|
|
||||||
|
ABKHAZIAN = {"name": "Abkhazian", "iso639_1": "ab", "iso639_2": ["abk"]}
|
||||||
|
AFAR = {"name": "Afar", "iso639_1": "aa", "iso639_2": ["aar"]}
|
||||||
AFRIKAANS = {"name": "Afrikaans", "iso639_1": "af", "iso639_2": ["afr"]}
|
AFRIKAANS = {"name": "Afrikaans", "iso639_1": "af", "iso639_2": ["afr"]}
|
||||||
ALBANIAN = {"name": "Albanian", "iso639_1": "sq", "iso639_2": ["alb"]}
|
AKAN = {"name": "Akan", "iso639_1": "ak", "iso639_2": ["aka"]}
|
||||||
|
ALBANIAN = {"name": "Albanian", "iso639_1": "sq", "iso639_2": ["sqi", "alb"]}
|
||||||
|
AMHARIC = {"name": "Amharic", "iso639_1": "am", "iso639_2": ["amh"]}
|
||||||
ARABIC = {"name": "Arabic", "iso639_1": "ar", "iso639_2": ["ara"]}
|
ARABIC = {"name": "Arabic", "iso639_1": "ar", "iso639_2": ["ara"]}
|
||||||
ARMENIAN = {"name": "Armenian", "iso639_1": "hy", "iso639_2": ["arm"]}
|
ARAGONESE = {"name": "Aragonese", "iso639_1": "an", "iso639_2": ["arg"]}
|
||||||
|
ARMENIAN = {"name": "Armenian", "iso639_1": "hy", "iso639_2": ["hye", "arm"]}
|
||||||
|
ASSAMESE = {"name": "Assamese", "iso639_1": "as", "iso639_2": ["asm"]}
|
||||||
|
AVARIC = {"name": "Avaric", "iso639_1": "av", "iso639_2": ["ava"]}
|
||||||
|
AVESTAN = {"name": "Avestan", "iso639_1": "ae", "iso639_2": ["ave"]}
|
||||||
|
AYMARA = {"name": "Aymara", "iso639_1": "ay", "iso639_2": ["aym"]}
|
||||||
AZERBAIJANI = {"name": "Azerbaijani", "iso639_1": "az", "iso639_2": ["aze"]}
|
AZERBAIJANI = {"name": "Azerbaijani", "iso639_1": "az", "iso639_2": ["aze"]}
|
||||||
BASQUE = {"name": "Basque", "iso639_1": "eu", "iso639_2": ["baq"]}
|
BAMBARA = {"name": "Bambara", "iso639_1": "bm", "iso639_2": ["bam"]}
|
||||||
|
BASHKIR = {"name": "Bashkir", "iso639_1": "ba", "iso639_2": ["bak"]}
|
||||||
|
BASQUE = {"name": "Basque", "iso639_1": "eu", "iso639_2": ["eus", "baq"]}
|
||||||
BELARUSIAN = {"name": "Belarusian", "iso639_1": "be", "iso639_2": ["bel"]}
|
BELARUSIAN = {"name": "Belarusian", "iso639_1": "be", "iso639_2": ["bel"]}
|
||||||
BOKMAL = {"name": "Bokmål", "iso639_1": "nb", "iso639_2": ["nob"]} # Norwegian Bokmål
|
BENGALI = {"name": "Bengali", "iso639_1": "bn", "iso639_2": ["ben"]}
|
||||||
|
BISLAMA = {"name": "Bislama", "iso639_1": "bi", "iso639_2": ["bis"]}
|
||||||
|
BOKMAL = {"name": "Bokmål", "iso639_1": "nb", "iso639_2": ["nob"]}
|
||||||
|
BOSNIAN = {"name": "Bosnian", "iso639_1": "bs", "iso639_2": ["bos"]}
|
||||||
|
BRETON = {"name": "Breton", "iso639_1": "br", "iso639_2": ["bre"]}
|
||||||
BULGARIAN = {"name": "Bulgarian", "iso639_1": "bg", "iso639_2": ["bul"]}
|
BULGARIAN = {"name": "Bulgarian", "iso639_1": "bg", "iso639_2": ["bul"]}
|
||||||
|
BURMESE = {"name": "Burmese", "iso639_1": "my", "iso639_2": ["mya", "bur"]}
|
||||||
CATALAN = {"name": "Catalan", "iso639_1": "ca", "iso639_2": ["cat"]}
|
CATALAN = {"name": "Catalan", "iso639_1": "ca", "iso639_2": ["cat"]}
|
||||||
|
CHAMORRO = {"name": "Chamorro", "iso639_1": "ch", "iso639_2": ["cha"]}
|
||||||
|
CHECHEN = {"name": "Chechen", "iso639_1": "ce", "iso639_2": ["che"]}
|
||||||
|
CHICHEWA = {"name": "Chichewa", "iso639_1": "ny", "iso639_2": ["nya"]}
|
||||||
CHINESE = {"name": "Chinese", "iso639_1": "zh", "iso639_2": ["zho", "chi"]}
|
CHINESE = {"name": "Chinese", "iso639_1": "zh", "iso639_2": ["zho", "chi"]}
|
||||||
|
CHURCH_SLAVIC = {"name": "Church Slavic", "iso639_1": "cu", "iso639_2": ["chu"]}
|
||||||
|
CHUVASH = {"name": "Chuvash", "iso639_1": "cv", "iso639_2": ["chv"]}
|
||||||
|
CORNISH = {"name": "Cornish", "iso639_1": "kw", "iso639_2": ["cor"]}
|
||||||
|
CORSICAN = {"name": "Corsican", "iso639_1": "co", "iso639_2": ["cos"]}
|
||||||
|
CREE = {"name": "Cree", "iso639_1": "cr", "iso639_2": ["cre"]}
|
||||||
CROATIAN = {"name": "Croatian", "iso639_1": "hr", "iso639_2": ["hrv"]}
|
CROATIAN = {"name": "Croatian", "iso639_1": "hr", "iso639_2": ["hrv"]}
|
||||||
CZECH = {"name": "Czech", "iso639_1": "cs", "iso639_2": ["cze"]}
|
CZECH = {"name": "Czech", "iso639_1": "cs", "iso639_2": ["ces", "cze"]}
|
||||||
DANISH = {"name": "Danish", "iso639_1": "da", "iso639_2": ["dan"]}
|
DANISH = {"name": "Danish", "iso639_1": "da", "iso639_2": ["dan"]}
|
||||||
|
DIVEHI = {"name": "Divehi", "iso639_1": "dv", "iso639_2": ["div"]}
|
||||||
DUTCH = {"name": "Dutch", "iso639_1": "nl", "iso639_2": ["nld", "dut"]}
|
DUTCH = {"name": "Dutch", "iso639_1": "nl", "iso639_2": ["nld", "dut"]}
|
||||||
|
DZONGKHA = {"name": "Dzongkha", "iso639_1": "dz", "iso639_2": ["dzo"]}
|
||||||
ENGLISH = {"name": "English", "iso639_1": "en", "iso639_2": ["eng"]}
|
ENGLISH = {"name": "English", "iso639_1": "en", "iso639_2": ["eng"]}
|
||||||
|
ESPERANTO = {"name": "Esperanto", "iso639_1": "eo", "iso639_2": ["epo"]}
|
||||||
ESTONIAN = {"name": "Estonian", "iso639_1": "et", "iso639_2": ["est"]}
|
ESTONIAN = {"name": "Estonian", "iso639_1": "et", "iso639_2": ["est"]}
|
||||||
FILIPINO = {"name": "Filipino", "iso639_1": "tl", "iso639_2": ["fil"]} # Tagalog
|
EWE = {"name": "Ewe", "iso639_1": "ee", "iso639_2": ["ewe"]}
|
||||||
|
FAROESE = {"name": "Faroese", "iso639_1": "fo", "iso639_2": ["fao"]}
|
||||||
|
FIJIAN = {"name": "Fijian", "iso639_1": "fj", "iso639_2": ["fij"]}
|
||||||
FINNISH = {"name": "Finnish", "iso639_1": "fi", "iso639_2": ["fin"]}
|
FINNISH = {"name": "Finnish", "iso639_1": "fi", "iso639_2": ["fin"]}
|
||||||
FRENCH = {"name": "French", "iso639_1": "fr", "iso639_2": ["fra", "fre"]}
|
FRENCH = {"name": "French", "iso639_1": "fr", "iso639_2": ["fra", "fre"]}
|
||||||
|
FULAH = {"name": "Fulah", "iso639_1": "ff", "iso639_2": ["ful"]}
|
||||||
GALICIAN = {"name": "Galician", "iso639_1": "gl", "iso639_2": ["glg"]}
|
GALICIAN = {"name": "Galician", "iso639_1": "gl", "iso639_2": ["glg"]}
|
||||||
GEORGIAN = {"name": "Georgian", "iso639_1": "ka", "iso639_2": ["geo"]}
|
GANDA = {"name": "Ganda", "iso639_1": "lg", "iso639_2": ["lug"]}
|
||||||
|
GEORGIAN = {"name": "Georgian", "iso639_1": "ka", "iso639_2": ["kat", "geo"]}
|
||||||
GERMAN = {"name": "German", "iso639_1": "de", "iso639_2": ["deu", "ger"]}
|
GERMAN = {"name": "German", "iso639_1": "de", "iso639_2": ["deu", "ger"]}
|
||||||
GREEK = {"name": "Greek", "iso639_1": "el", "iso639_2": ["gre"]}
|
GREEK = {"name": "Greek", "iso639_1": "el", "iso639_2": ["ell", "gre"]}
|
||||||
|
GUARANI = {"name": "Guarani", "iso639_1": "gn", "iso639_2": ["grn"]}
|
||||||
|
GUJARATI = {"name": "Gujarati", "iso639_1": "gu", "iso639_2": ["guj"]}
|
||||||
|
HAITIAN = {"name": "Haitian", "iso639_1": "ht", "iso639_2": ["hat"]}
|
||||||
|
HAUSA = {"name": "Hausa", "iso639_1": "ha", "iso639_2": ["hau"]}
|
||||||
HEBREW = {"name": "Hebrew", "iso639_1": "he", "iso639_2": ["heb"]}
|
HEBREW = {"name": "Hebrew", "iso639_1": "he", "iso639_2": ["heb"]}
|
||||||
|
HERERO = {"name": "Herero", "iso639_1": "hz", "iso639_2": ["her"]}
|
||||||
HINDI = {"name": "Hindi", "iso639_1": "hi", "iso639_2": ["hin"]}
|
HINDI = {"name": "Hindi", "iso639_1": "hi", "iso639_2": ["hin"]}
|
||||||
|
HIRI_MOTU = {"name": "Hiri Motu", "iso639_1": "ho", "iso639_2": ["hmo"]}
|
||||||
HUNGARIAN = {"name": "Hungarian", "iso639_1": "hu", "iso639_2": ["hun"]}
|
HUNGARIAN = {"name": "Hungarian", "iso639_1": "hu", "iso639_2": ["hun"]}
|
||||||
ICELANDIC = {"name": "Icelandic", "iso639_1": "is", "iso639_2": ["ice"]}
|
ICELANDIC = {"name": "Icelandic", "iso639_1": "is", "iso639_2": ["isl", "ice"]}
|
||||||
|
IDO = {"name": "Ido", "iso639_1": "io", "iso639_2": ["ido"]}
|
||||||
|
IGBO = {"name": "Igbo", "iso639_1": "ig", "iso639_2": ["ibo"]}
|
||||||
INDONESIAN = {"name": "Indonesian", "iso639_1": "id", "iso639_2": ["ind"]}
|
INDONESIAN = {"name": "Indonesian", "iso639_1": "id", "iso639_2": ["ind"]}
|
||||||
|
INTERLINGUA = {"name": "Interlingua", "iso639_1": "ia", "iso639_2": ["ina"]}
|
||||||
|
INTERLINGUE = {"name": "Interlingue", "iso639_1": "ie", "iso639_2": ["ile"]}
|
||||||
|
INUKTITUT = {"name": "Inuktitut", "iso639_1": "iu", "iso639_2": ["iku"]}
|
||||||
|
INUPIAQ = {"name": "Inupiaq", "iso639_1": "ik", "iso639_2": ["ipk"]}
|
||||||
IRISH = {"name": "Irish", "iso639_1": "ga", "iso639_2": ["gle"]}
|
IRISH = {"name": "Irish", "iso639_1": "ga", "iso639_2": ["gle"]}
|
||||||
ITALIAN = {"name": "Italian", "iso639_1": "it", "iso639_2": ["ita"]}
|
ITALIAN = {"name": "Italian", "iso639_1": "it", "iso639_2": ["ita"]}
|
||||||
JAPANESE = {"name": "Japanese", "iso639_1": "ja", "iso639_2": ["jpn"]}
|
JAPANESE = {"name": "Japanese", "iso639_1": "ja", "iso639_2": ["jpn"]}
|
||||||
|
JAVANESE = {"name": "Javanese", "iso639_1": "jv", "iso639_2": ["jav"]}
|
||||||
|
KALAALLISUT = {"name": "Kalaallisut", "iso639_1": "kl", "iso639_2": ["kal"]}
|
||||||
KANNADA = {"name": "Kannada", "iso639_1": "kn", "iso639_2": ["kan"]}
|
KANNADA = {"name": "Kannada", "iso639_1": "kn", "iso639_2": ["kan"]}
|
||||||
|
KANURI = {"name": "Kanuri", "iso639_1": "kr", "iso639_2": ["kau"]}
|
||||||
|
KASHMIRI = {"name": "Kashmiri", "iso639_1": "ks", "iso639_2": ["kas"]}
|
||||||
KAZAKH = {"name": "Kazakh", "iso639_1": "kk", "iso639_2": ["kaz"]}
|
KAZAKH = {"name": "Kazakh", "iso639_1": "kk", "iso639_2": ["kaz"]}
|
||||||
|
KHMER = {"name": "Khmer", "iso639_1": "km", "iso639_2": ["khm"]}
|
||||||
|
KIKUYU = {"name": "Kikuyu", "iso639_1": "ki", "iso639_2": ["kik"]}
|
||||||
|
KINYARWANDA = {"name": "Kinyarwanda", "iso639_1": "rw", "iso639_2": ["kin"]}
|
||||||
|
KIRGHIZ = {"name": "Kirghiz", "iso639_1": "ky", "iso639_2": ["kir"]}
|
||||||
|
KOMI = {"name": "Komi", "iso639_1": "kv", "iso639_2": ["kom"]}
|
||||||
|
KONGO = {"name": "Kongo", "iso639_1": "kg", "iso639_2": ["kon"]}
|
||||||
KOREAN = {"name": "Korean", "iso639_1": "ko", "iso639_2": ["kor"]}
|
KOREAN = {"name": "Korean", "iso639_1": "ko", "iso639_2": ["kor"]}
|
||||||
|
KUANYAMA = {"name": "Kuanyama", "iso639_1": "kj", "iso639_2": ["kua"]}
|
||||||
|
KURDISH = {"name": "Kurdish", "iso639_1": "ku", "iso639_2": ["kur"]}
|
||||||
|
LAO = {"name": "Lao", "iso639_1": "lo", "iso639_2": ["lao"]}
|
||||||
LATIN = {"name": "Latin", "iso639_1": "la", "iso639_2": ["lat"]}
|
LATIN = {"name": "Latin", "iso639_1": "la", "iso639_2": ["lat"]}
|
||||||
LATVIAN = {"name": "Latvian", "iso639_1": "lv", "iso639_2": ["lav"]}
|
LATVIAN = {"name": "Latvian", "iso639_1": "lv", "iso639_2": ["lav"]}
|
||||||
|
LIMBURGAN = {"name": "Limburgan", "iso639_1": "li", "iso639_2": ["lim"]}
|
||||||
|
LINGALA = {"name": "Lingala", "iso639_1": "ln", "iso639_2": ["lin"]}
|
||||||
LITHUANIAN = {"name": "Lithuanian", "iso639_1": "lt", "iso639_2": ["lit"]}
|
LITHUANIAN = {"name": "Lithuanian", "iso639_1": "lt", "iso639_2": ["lit"]}
|
||||||
MACEDONIAN = {"name": "Macedonian", "iso639_1": "mk", "iso639_2": ["mac"]}
|
LUBA_KATANGA = {"name": "Luba-Katanga", "iso639_1": "lu", "iso639_2": ["lub"]}
|
||||||
MALAY = {"name": "Malay", "iso639_1": "ms", "iso639_2": ["may"]}
|
LUXEMBOURGISH = {"name": "Luxembourgish", "iso639_1": "lb", "iso639_2": ["ltz"]}
|
||||||
|
MACEDONIAN = {"name": "Macedonian", "iso639_1": "mk", "iso639_2": ["mkd", "mac"]}
|
||||||
|
MALAGASY = {"name": "Malagasy", "iso639_1": "mg", "iso639_2": ["mlg"]}
|
||||||
|
MALAY = {"name": "Malay", "iso639_1": "ms", "iso639_2": ["msa", "may"]}
|
||||||
MALAYALAM = {"name": "Malayalam", "iso639_1": "ml", "iso639_2": ["mal"]}
|
MALAYALAM = {"name": "Malayalam", "iso639_1": "ml", "iso639_2": ["mal"]}
|
||||||
MALTESE = {"name": "Maltese", "iso639_1": "mt", "iso639_2": ["mlt"]}
|
MALTESE = {"name": "Maltese", "iso639_1": "mt", "iso639_2": ["mlt"]}
|
||||||
|
MANX = {"name": "Manx", "iso639_1": "gv", "iso639_2": ["glv"]}
|
||||||
|
MAORI = {"name": "Maori", "iso639_1": "mi", "iso639_2": ["mri", "mao"]}
|
||||||
|
MARATHI = {"name": "Marathi", "iso639_1": "mr", "iso639_2": ["mar"]}
|
||||||
|
MARSHALLESE = {"name": "Marshallese", "iso639_1": "mh", "iso639_2": ["mah"]}
|
||||||
|
MONGOLIAN = {"name": "Mongolian", "iso639_1": "mn", "iso639_2": ["mon"]}
|
||||||
|
NAURU = {"name": "Nauru", "iso639_1": "na", "iso639_2": ["nau"]}
|
||||||
|
NAVAJO = {"name": "Navajo", "iso639_1": "nv", "iso639_2": ["nav"]}
|
||||||
|
NDONGA = {"name": "Ndonga", "iso639_1": "ng", "iso639_2": ["ndo"]}
|
||||||
|
NEPALI = {"name": "Nepali", "iso639_1": "ne", "iso639_2": ["nep"]}
|
||||||
|
NORTH_NDEBELE = {"name": "North Ndebele", "iso639_1": "nd", "iso639_2": ["nde"]}
|
||||||
|
NORTHERN_SAMI = {"name": "Northern Sami", "iso639_1": "se", "iso639_2": ["sme"]}
|
||||||
NORWEGIAN = {"name": "Norwegian", "iso639_1": "no", "iso639_2": ["nor"]}
|
NORWEGIAN = {"name": "Norwegian", "iso639_1": "no", "iso639_2": ["nor"]}
|
||||||
PERSIAN = {"name": "Persian", "iso639_1": "fa", "iso639_2": ["per"]}
|
NORWEGIAN_NYNORSK = {"name": "Nynorsk", "iso639_1": "nn", "iso639_2": ["nno"]}
|
||||||
|
OCCITAN = {"name": "Occitan", "iso639_1": "oc", "iso639_2": ["oci"]}
|
||||||
|
OJIBWA = {"name": "Ojibwa", "iso639_1": "oj", "iso639_2": ["oji"]}
|
||||||
|
ORIYA = {"name": "Oriya", "iso639_1": "or", "iso639_2": ["ori"]}
|
||||||
|
OROMO = {"name": "Oromo", "iso639_1": "om", "iso639_2": ["orm"]}
|
||||||
|
OSSETIAN = {"name": "Ossetian", "iso639_1": "os", "iso639_2": ["oss"]}
|
||||||
|
PALI = {"name": "Pali", "iso639_1": "pi", "iso639_2": ["pli"]}
|
||||||
|
PANJABI = {"name": "Panjabi", "iso639_1": "pa", "iso639_2": ["pan"]}
|
||||||
|
PERSIAN = {"name": "Persian", "iso639_1": "fa", "iso639_2": ["fas", "per"]}
|
||||||
POLISH = {"name": "Polish", "iso639_1": "pl", "iso639_2": ["pol"]}
|
POLISH = {"name": "Polish", "iso639_1": "pl", "iso639_2": ["pol"]}
|
||||||
PORTUGUESE = {"name": "Portuguese", "iso639_1": "pt", "iso639_2": ["por"]}
|
PORTUGUESE = {"name": "Portuguese", "iso639_1": "pt", "iso639_2": ["por"]}
|
||||||
ROMANIAN = {"name": "Romanian", "iso639_1": "ro", "iso639_2": ["rum"]}
|
PUSHTO = {"name": "Pushto", "iso639_1": "ps", "iso639_2": ["pus"]}
|
||||||
|
QUECHUA = {"name": "Quechua", "iso639_1": "qu", "iso639_2": ["que"]}
|
||||||
|
ROMANIAN = {"name": "Romanian", "iso639_1": "ro", "iso639_2": ["ron", "rum"]}
|
||||||
|
ROMANSH = {"name": "Romansh", "iso639_1": "rm", "iso639_2": ["roh"]}
|
||||||
|
RUNDI = {"name": "Rundi", "iso639_1": "rn", "iso639_2": ["run"]}
|
||||||
RUSSIAN = {"name": "Russian", "iso639_1": "ru", "iso639_2": ["rus"]}
|
RUSSIAN = {"name": "Russian", "iso639_1": "ru", "iso639_2": ["rus"]}
|
||||||
NORTHERN_SAMI = {"name": "Northern Sami", "iso639_1": "se", "iso639_2": ["sme"]}
|
|
||||||
SAMOAN = {"name": "Samoan", "iso639_1": "sm", "iso639_2": ["smo"]}
|
SAMOAN = {"name": "Samoan", "iso639_1": "sm", "iso639_2": ["smo"]}
|
||||||
SANGO = {"name": "Sango", "iso639_1": "sg", "iso639_2": ["sag"]}
|
SANGO = {"name": "Sango", "iso639_1": "sg", "iso639_2": ["sag"]}
|
||||||
SANSKRIT = {"name": "Sanskrit", "iso639_1": "sa", "iso639_2": ["san"]}
|
SANSKRIT = {"name": "Sanskrit", "iso639_1": "sa", "iso639_2": ["san"]}
|
||||||
SARDINIAN = {"name": "Sardinian", "iso639_1": "sc", "iso639_2": ["srd"]}
|
SARDINIAN = {"name": "Sardinian", "iso639_1": "sc", "iso639_2": ["srd"]}
|
||||||
|
SCOTTISH_GAELIC = {"name": "Scottish Gaelic", "iso639_1": "gd", "iso639_2": ["gla"]}
|
||||||
SERBIAN = {"name": "Serbian", "iso639_1": "sr", "iso639_2": ["srp"]}
|
SERBIAN = {"name": "Serbian", "iso639_1": "sr", "iso639_2": ["srp"]}
|
||||||
SHONA = {"name": "Shona", "iso639_1": "sn", "iso639_2": ["sna"]}
|
SHONA = {"name": "Shona", "iso639_1": "sn", "iso639_2": ["sna"]}
|
||||||
|
SICHUAN_YI = {"name": "Sichuan Yi", "iso639_1": "ii", "iso639_2": ["iii"]}
|
||||||
SINDHI = {"name": "Sindhi", "iso639_1": "sd", "iso639_2": ["snd"]}
|
SINDHI = {"name": "Sindhi", "iso639_1": "sd", "iso639_2": ["snd"]}
|
||||||
SINHALA = {"name": "Sinhala", "iso639_1": "si", "iso639_2": ["sin"]}
|
SINHALA = {"name": "Sinhala", "iso639_1": "si", "iso639_2": ["sin"]}
|
||||||
SLOVAK = {"name": "Slovak", "iso639_1": "sk", "iso639_2": ["slk"]}
|
SLOVAK = {"name": "Slovak", "iso639_1": "sk", "iso639_2": ["slk", "slo"]}
|
||||||
SLOVENIAN = {"name": "Slovenian", "iso639_1": "sl", "iso639_2": ["slv"]}
|
SLOVENIAN = {"name": "Slovenian", "iso639_1": "sl", "iso639_2": ["slv"]}
|
||||||
SOMALI = {"name": "Somali", "iso639_1": "so", "iso639_2": ["som"]}
|
SOMALI = {"name": "Somali", "iso639_1": "so", "iso639_2": ["som"]}
|
||||||
|
SOUTH_NDEBELE = {"name": "South Ndebele", "iso639_1": "nr", "iso639_2": ["nbl"]}
|
||||||
SOUTHERN_SOTHO = {"name": "Southern Sotho", "iso639_1": "st", "iso639_2": ["sot"]}
|
SOUTHERN_SOTHO = {"name": "Southern Sotho", "iso639_1": "st", "iso639_2": ["sot"]}
|
||||||
SPANISH = {"name": "Spanish", "iso639_1": "es", "iso639_2": ["spa"]}
|
SPANISH = {"name": "Spanish", "iso639_1": "es", "iso639_2": ["spa"]}
|
||||||
SUNDANESE = {"name": "Sundanese", "iso639_1": "su", "iso639_2": ["sun"]}
|
SUNDANESE = {"name": "Sundanese", "iso639_1": "su", "iso639_2": ["sun"]}
|
||||||
@@ -70,14 +157,38 @@ class IsoLanguage(Enum):
|
|||||||
SWATI = {"name": "Swati", "iso639_1": "ss", "iso639_2": ["ssw"]}
|
SWATI = {"name": "Swati", "iso639_1": "ss", "iso639_2": ["ssw"]}
|
||||||
SWEDISH = {"name": "Swedish", "iso639_1": "sv", "iso639_2": ["swe"]}
|
SWEDISH = {"name": "Swedish", "iso639_1": "sv", "iso639_2": ["swe"]}
|
||||||
TAGALOG = {"name": "Tagalog", "iso639_1": "tl", "iso639_2": ["tgl"]}
|
TAGALOG = {"name": "Tagalog", "iso639_1": "tl", "iso639_2": ["tgl"]}
|
||||||
|
TAHITIAN = {"name": "Tahitian", "iso639_1": "ty", "iso639_2": ["tah"]}
|
||||||
|
TAJIK = {"name": "Tajik", "iso639_1": "tg", "iso639_2": ["tgk"]}
|
||||||
TAMIL = {"name": "Tamil", "iso639_1": "ta", "iso639_2": ["tam"]}
|
TAMIL = {"name": "Tamil", "iso639_1": "ta", "iso639_2": ["tam"]}
|
||||||
|
TATAR = {"name": "Tatar", "iso639_1": "tt", "iso639_2": ["tat"]}
|
||||||
TELUGU = {"name": "Telugu", "iso639_1": "te", "iso639_2": ["tel"]}
|
TELUGU = {"name": "Telugu", "iso639_1": "te", "iso639_2": ["tel"]}
|
||||||
THAI = {"name": "Thai", "iso639_1": "th", "iso639_2": ["tha"]}
|
THAI = {"name": "Thai", "iso639_1": "th", "iso639_2": ["tha"]}
|
||||||
|
TIBETAN = {"name": "Tibetan", "iso639_1": "bo", "iso639_2": ["bod", "tib"]}
|
||||||
|
TIGRINYA = {"name": "Tigrinya", "iso639_1": "ti", "iso639_2": ["tir"]}
|
||||||
|
TONGA = {"name": "Tonga", "iso639_1": "to", "iso639_2": ["ton"]}
|
||||||
|
TSONGA = {"name": "Tsonga", "iso639_1": "ts", "iso639_2": ["tso"]}
|
||||||
|
TSWANA = {"name": "Tswana", "iso639_1": "tn", "iso639_2": ["tsn"]}
|
||||||
TURKISH = {"name": "Turkish", "iso639_1": "tr", "iso639_2": ["tur"]}
|
TURKISH = {"name": "Turkish", "iso639_1": "tr", "iso639_2": ["tur"]}
|
||||||
|
TURKMEN = {"name": "Turkmen", "iso639_1": "tk", "iso639_2": ["tuk"]}
|
||||||
|
TWI = {"name": "Twi", "iso639_1": "tw", "iso639_2": ["twi"]}
|
||||||
|
UIGHUR = {"name": "Uighur", "iso639_1": "ug", "iso639_2": ["uig"]}
|
||||||
UKRAINIAN = {"name": "Ukrainian", "iso639_1": "uk", "iso639_2": ["ukr"]}
|
UKRAINIAN = {"name": "Ukrainian", "iso639_1": "uk", "iso639_2": ["ukr"]}
|
||||||
URDU = {"name": "Urdu", "iso639_1": "ur", "iso639_2": ["urd"]}
|
URDU = {"name": "Urdu", "iso639_1": "ur", "iso639_2": ["urd"]}
|
||||||
VIETNAMESE = {"name": "Vietnamese", "iso639_1": "vi", "iso639_2":[ "vie"]}
|
UZBEK = {"name": "Uzbek", "iso639_1": "uz", "iso639_2": ["uzb"]}
|
||||||
WELSH = {"name": "Welsh", "iso639_1": "cy", "iso639_2": ["wel"]}
|
VENDA = {"name": "Venda", "iso639_1": "ve", "iso639_2": ["ven"]}
|
||||||
|
VIETNAMESE = {"name": "Vietnamese", "iso639_1": "vi", "iso639_2": ["vie"]}
|
||||||
|
VOLAPUK = {"name": "Volapük", "iso639_1": "vo", "iso639_2": ["vol"]}
|
||||||
|
WALLOON = {"name": "Walloon", "iso639_1": "wa", "iso639_2": ["wln"]}
|
||||||
|
WELSH = {"name": "Welsh", "iso639_1": "cy", "iso639_2": ["cym", "wel"]}
|
||||||
|
WESTERN_FRISIAN = {"name": "Western Frisian", "iso639_1": "fy", "iso639_2": ["fry"]}
|
||||||
|
WOLOF = {"name": "Wolof", "iso639_1": "wo", "iso639_2": ["wol"]}
|
||||||
|
XHOSA = {"name": "Xhosa", "iso639_1": "xh", "iso639_2": ["xho"]}
|
||||||
|
YIDDISH = {"name": "Yiddish", "iso639_1": "yi", "iso639_2": ["yid"]}
|
||||||
|
YORUBA = {"name": "Yoruba", "iso639_1": "yo", "iso639_2": ["yor"]}
|
||||||
|
ZHUANG = {"name": "Zhuang", "iso639_1": "za", "iso639_2": ["zha"]}
|
||||||
|
ZULU = {"name": "Zulu", "iso639_1": "zu", "iso639_2": ["zul"]}
|
||||||
|
|
||||||
|
FILIPINO = {"name": "Filipino", "iso639_1": "tl", "iso639_2": ["fil"]}
|
||||||
|
|
||||||
UNDEFINED = {"name": "undefined", "iso639_1": "xx", "iso639_2": ["und"]}
|
UNDEFINED = {"name": "undefined", "iso639_1": "xx", "iso639_2": ["und"]}
|
||||||
|
|
||||||
@@ -88,24 +199,22 @@ class IsoLanguage(Enum):
|
|||||||
closestMatches = difflib.get_close_matches(label, [l.value["name"] for l in IsoLanguage], n=1)
|
closestMatches = difflib.get_close_matches(label, [l.value["name"] for l in IsoLanguage], n=1)
|
||||||
|
|
||||||
if closestMatches:
|
if closestMatches:
|
||||||
foundLangs = [l for l in IsoLanguage if l.value['name'] == closestMatches[0]]
|
foundLangs = [l for l in IsoLanguage if l.value["name"] == closestMatches[0]]
|
||||||
return foundLangs[0] if foundLangs else IsoLanguage.UNDEFINED
|
return foundLangs[0] if foundLangs else IsoLanguage.UNDEFINED
|
||||||
else:
|
else:
|
||||||
return IsoLanguage.UNDEFINED
|
return IsoLanguage.UNDEFINED
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def findThreeLetter(theeLetter : str):
|
def findThreeLetter(theeLetter : str):
|
||||||
foundLangs = [l for l in IsoLanguage if str(theeLetter) in l.value['iso639_2']]
|
foundLangs = [l for l in IsoLanguage if str(theeLetter) in l.value["iso639_2"]]
|
||||||
return foundLangs[0] if foundLangs else IsoLanguage.UNDEFINED
|
return foundLangs[0] if foundLangs else IsoLanguage.UNDEFINED
|
||||||
|
|
||||||
|
|
||||||
def label(self):
|
def label(self):
|
||||||
return str(self.value['name'])
|
return str(self.value["name"])
|
||||||
|
|
||||||
def twoLetter(self):
|
def twoLetter(self):
|
||||||
return str(self.value['iso639_1'])
|
return str(self.value["iso639_1"])
|
||||||
|
|
||||||
def threeLetter(self):
|
def threeLetter(self):
|
||||||
return str(self.value['iso639_2'][0])
|
return str(self.value["iso639_2"][0])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import click
|
import click
|
||||||
|
|
||||||
|
from ffx.iso_language import IsoLanguage
|
||||||
from ffx.media_descriptor import MediaDescriptor
|
from ffx.media_descriptor import MediaDescriptor
|
||||||
from ffx.track_descriptor import TrackDescriptor
|
from ffx.track_descriptor import TrackDescriptor
|
||||||
|
|
||||||
@@ -117,7 +118,11 @@ class MediaDescriptorChangeSet():
|
|||||||
sourceTrackDescriptor: TrackDescriptor = None):
|
sourceTrackDescriptor: TrackDescriptor = None):
|
||||||
|
|
||||||
sourceTrackTags = sourceTrackDescriptor.getTags() if sourceTrackDescriptor is not None else {}
|
sourceTrackTags = sourceTrackDescriptor.getTags() if sourceTrackDescriptor is not None else {}
|
||||||
targetTrackTags = targetTrackDescriptor.getTags() if targetTrackDescriptor is not None else {}
|
targetTrackTags = (
|
||||||
|
self.normalizeTrackTags(targetTrackDescriptor.getTags())
|
||||||
|
if targetTrackDescriptor is not None
|
||||||
|
else {}
|
||||||
|
)
|
||||||
|
|
||||||
trackCompareResult = {}
|
trackCompareResult = {}
|
||||||
|
|
||||||
@@ -142,6 +147,25 @@ class MediaDescriptorChangeSet():
|
|||||||
|
|
||||||
return trackCompareResult
|
return trackCompareResult
|
||||||
|
|
||||||
|
def normalizeTrackTagValue(self, tagKey, tagValue):
|
||||||
|
if tagKey != "language":
|
||||||
|
return tagValue
|
||||||
|
|
||||||
|
if isinstance(tagValue, IsoLanguage):
|
||||||
|
return tagValue.threeLetter()
|
||||||
|
|
||||||
|
trackLanguage = IsoLanguage.findThreeLetter(str(tagValue))
|
||||||
|
if trackLanguage != IsoLanguage.UNDEFINED:
|
||||||
|
return trackLanguage.threeLetter()
|
||||||
|
|
||||||
|
return tagValue
|
||||||
|
|
||||||
|
def normalizeTrackTags(self, trackTags: dict):
|
||||||
|
return {
|
||||||
|
tagKey: self.normalizeTrackTagValue(tagKey, tagValue)
|
||||||
|
for tagKey, tagValue in trackTags.items()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def generateDispositionTokens(self):
|
def generateDispositionTokens(self):
|
||||||
"""
|
"""
|
||||||
@@ -243,7 +267,7 @@ class MediaDescriptorChangeSet():
|
|||||||
addedTracks: dict = self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_ADDED_KEY]
|
addedTracks: dict = self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_ADDED_KEY]
|
||||||
trackDescriptor: TrackDescriptor
|
trackDescriptor: TrackDescriptor
|
||||||
for trackDescriptor in addedTracks.values():
|
for trackDescriptor in addedTracks.values():
|
||||||
for tagKey, tagValue in trackDescriptor.getTags().items():
|
for tagKey, tagValue in self.normalizeTrackTags(trackDescriptor.getTags()).items():
|
||||||
if not tagKey in self.__removeTrackKeys:
|
if not tagKey in self.__removeTrackKeys:
|
||||||
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
|
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
|
||||||
+ f":{trackDescriptor.getSubIndex()}",
|
+ f":{trackDescriptor.getSubIndex()}",
|
||||||
@@ -267,7 +291,7 @@ class MediaDescriptorChangeSet():
|
|||||||
|
|
||||||
trackDescriptor = self.__targetTrackDescriptorsByIndex[trackIndex]
|
trackDescriptor = self.__targetTrackDescriptorsByIndex[trackIndex]
|
||||||
|
|
||||||
for tagKey, tagValue in outputTrackTags.items():
|
for tagKey, tagValue in self.normalizeTrackTags(outputTrackTags).items():
|
||||||
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
|
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
|
||||||
+ f":{trackDescriptor.getSubIndex()}",
|
+ f":{trackDescriptor.getSubIndex()}",
|
||||||
f"{tagKey}={tagValue}"]
|
f"{tagKey}={tagValue}"]
|
||||||
@@ -285,7 +309,7 @@ class MediaDescriptorChangeSet():
|
|||||||
}
|
}
|
||||||
| unchangedTrackTags
|
| unchangedTrackTags
|
||||||
)
|
)
|
||||||
for tagKey, tagValue in preservedTrackTags.items():
|
for tagKey, tagValue in self.normalizeTrackTags(preservedTrackTags).items():
|
||||||
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
|
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
|
||||||
+ f":{trackDescriptor.getSubIndex()}",
|
+ f":{trackDescriptor.getSubIndex()}",
|
||||||
f"{tagKey}={tagValue}"]
|
f"{tagKey}={tagValue}"]
|
||||||
|
|||||||
125
tests/unit/test_cli_rename_only.py
Normal file
125
tests/unit/test_cli_rename_only.py
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import unittest
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from click.testing import CliRunner
|
||||||
|
|
||||||
|
|
||||||
|
SRC_ROOT = Path(__file__).resolve().parents[2] / "src"
|
||||||
|
|
||||||
|
if str(SRC_ROOT) not in sys.path:
|
||||||
|
sys.path.insert(0, str(SRC_ROOT))
|
||||||
|
|
||||||
|
|
||||||
|
from ffx import cli # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
|
class _FakeMediaDescriptor:
|
||||||
|
def getVideoTracks(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
def getAudioTracks(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
def getSubtitleTracks(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
def getAttachmentTracks(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
class _FakeFileProperties:
|
||||||
|
def __init__(self, context, source_path):
|
||||||
|
self.source_path = source_path
|
||||||
|
|
||||||
|
def getShowId(self):
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def getSeason(self):
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def getEpisode(self):
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def getMediaDescriptor(self):
|
||||||
|
return _FakeMediaDescriptor()
|
||||||
|
|
||||||
|
def getPattern(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class _FakeShiftedSeasonController:
|
||||||
|
def __init__(self, context):
|
||||||
|
self.context = context
|
||||||
|
|
||||||
|
def shiftSeason(self, show_id, season, episode):
|
||||||
|
return season, episode
|
||||||
|
|
||||||
|
|
||||||
|
class _FakeFfxController:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def runJob(self, *args, **kwargs):
|
||||||
|
raise AssertionError("runJob should not be called for --rename-only")
|
||||||
|
|
||||||
|
|
||||||
|
class RenameOnlyCliTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.tempdir = tempfile.TemporaryDirectory()
|
||||||
|
self.home_dir = Path(self.tempdir.name) / "home"
|
||||||
|
self.home_dir.mkdir()
|
||||||
|
self.database_path = Path(self.tempdir.name) / "test.db"
|
||||||
|
self.source_dir = Path(self.tempdir.name) / "source"
|
||||||
|
self.source_dir.mkdir()
|
||||||
|
self.output_dir = Path(self.tempdir.name) / "output"
|
||||||
|
self.output_dir.mkdir()
|
||||||
|
self.source_path = self.source_dir / "episode.mkv"
|
||||||
|
self.source_bytes = b"rename-only-source"
|
||||||
|
self.source_path.write_bytes(self.source_bytes)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.tempdir.cleanup()
|
||||||
|
|
||||||
|
def test_rename_only_moves_source_file_into_output_directory(self):
|
||||||
|
runner = CliRunner()
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch("ffx.file_properties.FileProperties", _FakeFileProperties),
|
||||||
|
patch("ffx.ffx_controller.FfxController", _FakeFfxController),
|
||||||
|
patch(
|
||||||
|
"ffx.shifted_season_controller.ShiftedSeasonController",
|
||||||
|
_FakeShiftedSeasonController,
|
||||||
|
),
|
||||||
|
):
|
||||||
|
result = runner.invoke(
|
||||||
|
cli.ffx,
|
||||||
|
[
|
||||||
|
"--database-file",
|
||||||
|
str(self.database_path),
|
||||||
|
"convert",
|
||||||
|
"--no-tmdb",
|
||||||
|
"--no-pattern",
|
||||||
|
"--rename-only",
|
||||||
|
"--output-directory",
|
||||||
|
str(self.output_dir),
|
||||||
|
str(self.source_path),
|
||||||
|
],
|
||||||
|
env={**os.environ, "HOME": str(self.home_dir)},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(0, result.exit_code, result.output)
|
||||||
|
|
||||||
|
target_path = self.output_dir / "out_episode.mkv"
|
||||||
|
self.assertFalse(self.source_path.exists())
|
||||||
|
self.assertTrue(target_path.exists())
|
||||||
|
self.assertEqual(self.source_bytes, target_path.read_bytes())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
41
tests/unit/test_iso_language.py
Normal file
41
tests/unit/test_iso_language.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
SRC_ROOT = Path(__file__).resolve().parents[2] / "src"
|
||||||
|
|
||||||
|
if str(SRC_ROOT) not in sys.path:
|
||||||
|
sys.path.insert(0, str(SRC_ROOT))
|
||||||
|
|
||||||
|
|
||||||
|
from ffx.iso_language import IsoLanguage # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
|
class IsoLanguageTests(unittest.TestCase):
|
||||||
|
def test_language_constant_set_covers_iso_639_1_plus_filipino_alias(self):
|
||||||
|
languages = [language for language in IsoLanguage if language is not IsoLanguage.UNDEFINED]
|
||||||
|
|
||||||
|
self.assertEqual(184, len(languages))
|
||||||
|
self.assertEqual(183, len({language.twoLetter() for language in languages}))
|
||||||
|
|
||||||
|
def test_primary_three_letter_code_is_returned_first(self):
|
||||||
|
self.assertEqual("sqi", IsoLanguage.ALBANIAN.threeLetter())
|
||||||
|
self.assertEqual("deu", IsoLanguage.GERMAN.threeLetter())
|
||||||
|
self.assertEqual("cym", IsoLanguage.WELSH.threeLetter())
|
||||||
|
|
||||||
|
def test_secondary_three_letter_codes_still_resolve_to_the_same_language(self):
|
||||||
|
self.assertIs(IsoLanguage.ALBANIAN, IsoLanguage.findThreeLetter("alb"))
|
||||||
|
self.assertIs(IsoLanguage.GERMAN, IsoLanguage.findThreeLetter("ger"))
|
||||||
|
self.assertIs(IsoLanguage.WELSH, IsoLanguage.findThreeLetter("wel"))
|
||||||
|
|
||||||
|
def test_newly_added_languages_and_media_aliases_resolve(self):
|
||||||
|
self.assertIs(IsoLanguage.ASSAMESE, IsoLanguage.find("Assamese"))
|
||||||
|
self.assertIs(IsoLanguage.YORUBA, IsoLanguage.findThreeLetter("yor"))
|
||||||
|
self.assertIs(IsoLanguage.FILIPINO, IsoLanguage.findThreeLetter("fil"))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
@@ -27,6 +27,64 @@ class StaticConfig:
|
|||||||
|
|
||||||
|
|
||||||
class MediaDescriptorChangeSetTests(unittest.TestCase):
|
class MediaDescriptorChangeSetTests(unittest.TestCase):
|
||||||
|
def test_non_primary_source_language_code_is_normalized_in_changed_track_metadata(self):
|
||||||
|
context = {
|
||||||
|
"logger": get_ffx_logger(),
|
||||||
|
"config": StaticConfig({}),
|
||||||
|
}
|
||||||
|
|
||||||
|
source_track = TrackDescriptor(
|
||||||
|
index=0,
|
||||||
|
source_index=0,
|
||||||
|
sub_index=0,
|
||||||
|
track_type=TrackType.AUDIO,
|
||||||
|
tags={"language": "ger", "title": "German Main"},
|
||||||
|
)
|
||||||
|
target_track = TrackDescriptor(
|
||||||
|
index=0,
|
||||||
|
source_index=0,
|
||||||
|
sub_index=0,
|
||||||
|
track_type=TrackType.AUDIO,
|
||||||
|
tags={"language": "ger", "title": "German Main"},
|
||||||
|
)
|
||||||
|
|
||||||
|
change_set = MediaDescriptorChangeSet(
|
||||||
|
context,
|
||||||
|
MediaDescriptor(track_descriptors=[target_track]),
|
||||||
|
MediaDescriptor(track_descriptors=[source_track]),
|
||||||
|
)
|
||||||
|
|
||||||
|
metadata_tokens = change_set.generateMetadataTokens()
|
||||||
|
|
||||||
|
self.assertIn("-metadata:s:a:0", metadata_tokens)
|
||||||
|
self.assertIn("language=deu", metadata_tokens)
|
||||||
|
self.assertNotIn("language=ger", metadata_tokens)
|
||||||
|
|
||||||
|
def test_target_only_track_language_metadata_uses_primary_code(self):
|
||||||
|
context = {
|
||||||
|
"logger": get_ffx_logger(),
|
||||||
|
"config": StaticConfig({}),
|
||||||
|
}
|
||||||
|
|
||||||
|
target_track = TrackDescriptor(
|
||||||
|
index=0,
|
||||||
|
source_index=0,
|
||||||
|
sub_index=0,
|
||||||
|
track_type=TrackType.AUDIO,
|
||||||
|
tags={"language": "ger", "title": "German Main"},
|
||||||
|
)
|
||||||
|
|
||||||
|
change_set = MediaDescriptorChangeSet(
|
||||||
|
context,
|
||||||
|
MediaDescriptor(track_descriptors=[target_track]),
|
||||||
|
)
|
||||||
|
|
||||||
|
metadata_tokens = change_set.generateMetadataTokens()
|
||||||
|
|
||||||
|
self.assertIn("-metadata:s:a:0", metadata_tokens)
|
||||||
|
self.assertIn("language=deu", metadata_tokens)
|
||||||
|
self.assertNotIn("language=ger", metadata_tokens)
|
||||||
|
|
||||||
def test_external_subtitle_preserves_source_only_tags_except_removed_keys(self):
|
def test_external_subtitle_preserves_source_only_tags_except_removed_keys(self):
|
||||||
context = {
|
context = {
|
||||||
"logger": get_ffx_logger(),
|
"logger": get_ffx_logger(),
|
||||||
@@ -79,6 +137,40 @@ class MediaDescriptorChangeSetTests(unittest.TestCase):
|
|||||||
self.assertNotIn("BPS=remove-me", metadata_tokens)
|
self.assertNotIn("BPS=remove-me", metadata_tokens)
|
||||||
self.assertIn("BPS=", metadata_tokens)
|
self.assertIn("BPS=", metadata_tokens)
|
||||||
|
|
||||||
|
def test_external_subtitle_normalizes_preserved_source_language_metadata(self):
|
||||||
|
context = {
|
||||||
|
"logger": get_ffx_logger(),
|
||||||
|
"config": StaticConfig({}),
|
||||||
|
}
|
||||||
|
|
||||||
|
source_track = TrackDescriptor(
|
||||||
|
index=0,
|
||||||
|
source_index=0,
|
||||||
|
sub_index=0,
|
||||||
|
track_type=TrackType.SUBTITLE,
|
||||||
|
tags={"language": "ger", "title": "German Subtitle"},
|
||||||
|
)
|
||||||
|
target_track = TrackDescriptor(
|
||||||
|
index=0,
|
||||||
|
source_index=0,
|
||||||
|
sub_index=0,
|
||||||
|
track_type=TrackType.SUBTITLE,
|
||||||
|
tags={},
|
||||||
|
external_source_file="/tmp/external-subtitle.vtt",
|
||||||
|
)
|
||||||
|
|
||||||
|
change_set = MediaDescriptorChangeSet(
|
||||||
|
context,
|
||||||
|
MediaDescriptor(track_descriptors=[target_track]),
|
||||||
|
MediaDescriptor(track_descriptors=[source_track]),
|
||||||
|
)
|
||||||
|
|
||||||
|
metadata_tokens = change_set.generateMetadataTokens()
|
||||||
|
|
||||||
|
self.assertIn("-metadata:s:s:0", metadata_tokens)
|
||||||
|
self.assertIn("language=deu", metadata_tokens)
|
||||||
|
self.assertNotIn("language=ger", metadata_tokens)
|
||||||
|
|
||||||
def test_target_only_tracks_still_emit_remove_tokens_for_configured_stream_keys(self):
|
def test_target_only_tracks_still_emit_remove_tokens_for_configured_stream_keys(self):
|
||||||
context = {
|
context = {
|
||||||
"logger": get_ffx_logger(),
|
"logger": get_ffx_logger(),
|
||||||
|
|||||||
Reference in New Issue
Block a user