Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
1a05d51
Added Language.py
Entree3k Jun 19, 2024
99b073b
Added Languge.py
Entree3k Jun 19, 2024
ed37659
Update Language.py
Entree3k Jun 20, 2024
3a65a5b
Update README.md
Entree3k Jun 20, 2024
beb658f
Update Language.py
Entree3k Jun 20, 2024
9076dd6
Delete Dockerfile
Entree3k Jul 22, 2024
0c29a70
Delete start.sh
Entree3k Jul 22, 2024
2f70487
Delete template directory
Entree3k Jul 22, 2024
0daf80a
Delete edition-manager-for-plex.py
Entree3k Jul 22, 2024
5ab0028
Delete emp-all.bat
Entree3k Jul 22, 2024
af287e5
Delete emp-all.command
Entree3k Jul 22, 2024
11ce251
Delete emp-new.command
Entree3k Jul 22, 2024
074777f
Delete emp-reset.bat
Entree3k Jul 22, 2024
ef1b026
Delete emp-new.bat
Entree3k Jul 22, 2024
e85ab70
Delete emp-reset.command
Entree3k Jul 22, 2024
fae57b8
Delete requirements.txt
Entree3k Jul 22, 2024
15e049d
Delete modules/AudioCodec.py
Entree3k Jul 22, 2024
5d6712a
Delete modules directory
Entree3k Jul 22, 2024
4108f2d
Update config.ini
Entree3k Jul 22, 2024
4046817
Add files via upload
Entree3k Jul 22, 2024
8031fce
Rename edition-manager-for-plex.py to edition-manager.py
Entree3k Jul 22, 2024
79e674f
Create dockerfile
Entree3k Jul 22, 2024
fe0b495
Rename dockerfile to Dockerfile
Entree3k Jul 22, 2024
870526a
Delete compose/edition-manager-for-plex-reset directory
Entree3k Jul 22, 2024
57a3c80
Delete compose/edition-manager-for-plex directory
Entree3k Jul 22, 2024
a1f468d
Create compose.yml
Entree3k Jul 22, 2024
9820efa
Update compose.yml
Entree3k Jul 22, 2024
d30a0fb
Update Dockerfile
Entree3k Jul 22, 2024
1d1cabf
Add files via upload
Entree3k Jul 22, 2024
8367628
Update edition-manager.py
Entree3k Jul 22, 2024
036f948
Update edition-manager.py
Entree3k Jul 22, 2024
ae34bdf
Update config.ini
Entree3k Jul 23, 2024
f0005bb
Update compose.yml
Entree3k Jul 23, 2024
73cd891
Update Dockerfile
Entree3k Jul 23, 2024
fa966e7
Update README.md
Entree3k Jul 23, 2024
a47c5e4
Update README.md
Entree3k Jul 23, 2024
8e8da77
Update README.md
Entree3k Jul 23, 2024
c8cde95
Update README.md
Entree3k Jul 23, 2024
3e9b9e5
Update edition-manager.py
Entree3k Jul 24, 2024
58aa1bd
Added new modules
Entree3k Jul 24, 2024
0449c18
Update README.md
Entree3k Jul 24, 2024
23a7212
Update README.md
Entree3k Jul 24, 2024
9726480
Update README.md
Entree3k Sep 5, 2024
747a823
Add files via upload
Entree3k Sep 5, 2024
41b347e
Update config.ini
Entree3k Mar 13, 2025
57a393c
Update edition-manager-gui.py
Entree3k Mar 13, 2025
36c15d7
Update requirements.txt
Entree3k Mar 13, 2025
439f1c7
Update edition-manager.py
Entree3k Mar 13, 2025
97689da
Update edition-manager.py
Entree3k Mar 13, 2025
9a1f08c
Update Language.py
Entree3k Mar 13, 2025
1727a78
Create Edition Manager Modules.md
Entree3k Mar 13, 2025
9aa5130
Update README.md
Entree3k Mar 13, 2025
1c791c4
Update README.md
Entree3k Mar 18, 2025
c254d09
Add files via upload
Entree3k May 24, 2025
fcc9c67
Update requirements.txt
Entree3k May 24, 2025
59c397a
Removed - cache_ttl
Entree3k May 24, 2025
3a4d7d5
Update edition-manager-gui.py
Entree3k Aug 19, 2025
e482ed9
Create Edition Manager GUI.md
Entree3k Aug 20, 2025
ee02eb5
Update README.md
Entree3k Aug 20, 2025
1448920
Add files via upload
Entree3k Sep 11, 2025
2c4692f
Add files via upload
Entree3k Oct 22, 2025
e027243
Update Edition Manager GUI.md
Entree3k Oct 22, 2025
94f5dc6
Update README.md
Entree3k Oct 23, 2025
6cc159d
Update README.md
Entree3k Oct 23, 2025
e3bfa28
Update README.md
Entree3k Oct 23, 2025
5bd3f98
Delete compose.yml
Entree3k Oct 23, 2025
de914fe
Delete Dockerfile
Entree3k Oct 23, 2025
db95061
Delete edition-manager-gui.bat
Entree3k Oct 23, 2025
de6072b
Add files via upload
Entree3k Oct 23, 2025
c9fb9fd
Update config.ini
Entree3k Oct 23, 2025
f06daa1
Update README.md
Entree3k Oct 23, 2025
1f8a022
Add files via upload
Entree3k Nov 3, 2025
e0d2edc
Add files via upload
Entree3k Nov 3, 2025
162061e
Add files via upload
Entree3k Nov 3, 2025
0185228
Update README.md
Entree3k Nov 5, 2025
e95adf3
Update README.md
Entree3k Nov 5, 2025
8f866d9
Add files via upload
Entree3k Nov 6, 2025
3b9701c
Add files via upload
Entree3k Nov 6, 2025
1853af4
Add files via upload
Entree3k Nov 6, 2025
54f62f8
Update Edition Manager Modules.md
Entree3k Nov 9, 2025
3c6b762
Update Edition Manager GUI.md
Entree3k Nov 9, 2025
c1ca91d
Update README.md
Entree3k Nov 9, 2025
b8eceac
Update README.md
Entree3k Nov 9, 2025
fe352e3
Add files via upload
Entree3k Nov 9, 2025
7778fb0
Delete edition-manager-gui.py
Entree3k Nov 9, 2025
a428856
Delete edition-manager-gui.sh
Entree3k Nov 9, 2025
80159ed
Delete edition-manager-gui.pyw
Entree3k Nov 9, 2025
5bdde21
Delete edition-manager.py
Entree3k Nov 9, 2025
ed8b970
Update config.ini
Entree3k Nov 9, 2025
cbc27e0
Add files via upload
Entree3k Nov 9, 2025
69a00c8
Create file_delete.txt
Entree3k Nov 9, 2025
aa9d0d8
Add files via upload
Entree3k Nov 9, 2025
b36f75b
Delete assets/file_delete.txt
Entree3k Nov 9, 2025
ff715ed
Update messages.txt
Entree3k Nov 10, 2025
c40c316
Add files via upload
Entree3k Nov 10, 2025
8bf5c70
Update messages.txt
Entree3k Nov 11, 2025
ec04e06
Update README.md
Entree3k Nov 11, 2025
c633a72
Add files via upload
Entree3k Nov 13, 2025
19c9275
Add files via upload
Entree3k Nov 13, 2025
d19f630
Update README.md
Entree3k Nov 13, 2025
dfefd57
Update Edition Manager GUI.md
Entree3k Nov 13, 2025
e7f5acb
Fixed issue where it wasn't reading from config
Entree3k Nov 29, 2025
1a1d2f6
Added short code patterns for Cut editions
Entree3k Nov 29, 2025
c6f88bd
Update config.ini
Entree3k Feb 28, 2026
36d7c9b
Add files via upload
Entree3k Feb 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions edition-manager-for-plex.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from modules.Resolution import get_Resolution
from modules.DynamicRange import get_DynamicRange
from modules.ContentRating import get_ContentRating
from modules.Language import get_Language
from pathlib import Path
from flask import Flask, request
from configparser import ConfigParser
Expand All @@ -42,8 +43,8 @@ def initialize_settings():
token = config.get('server', 'token')
skip_libraries = set(re.split(r'[;;]', config.get('server', 'skip_libraries'))) if config.has_option('server', 'skip_libraries') else set()
language = config.get('server', 'language') if config.has_option('server', 'language') else 'en'
module_mapping = {'片源版本': 'Source', '分辨率': 'Resolution', '音频编码': 'AudioCodec', '视频编码': 'VideoCodec', '帧率': 'FrameRate', '比特率': 'Bitrate', '时长': 'Duration', '评分': 'Rating', '剪辑版本': 'Cut', '发行版本': 'Release', '动态范围': 'DynamicRange', '国家': 'Country', '内容分级': 'ContentRating', '大小': 'Size'}
modules = re.split(r'[;;]', config.get('modules', 'order')) if config.has_option('modules', 'order') else ['Source', 'Resolution', 'AudioCodec', 'VideoCodec', 'FrameRate', 'Bitrate', 'Duration', 'Rating', 'Cut', 'Release', 'DynamicRange', 'Country', 'ContentRating', 'Size']
module_mapping = {'语言': 'Language', '片源版本': 'Source', '分辨率': 'Resolution', '音频编码': 'AudioCodec', '视频编码': 'VideoCodec', '帧率': 'FrameRate', '比特率': 'Bitrate', '时长': 'Duration', '评分': 'Rating', '剪辑版本': 'Cut', '发行版本': 'Release', '动态范围': 'DynamicRange', '国家': 'Country', '内容分级': 'ContentRating', '大小': 'Size'}
modules = re.split(r'[;;]', config.get('modules', 'order')) if config.has_option('modules', 'order') else ['Source', 'Resolution', 'AudioCodec', 'VideoCodec', 'FrameRate', 'Bitrate', 'Duration', 'Rating', 'Cut', 'Release', 'DynamicRange', 'Country', 'ContentRating', 'Size', 'Language']
modules = [module_mapping.get(module, module) for module in modules]
try:
headers = {'X-Plex-Token': token, 'Accept': 'application/json'}
Expand Down Expand Up @@ -145,6 +146,10 @@ def process_movies(server, token, skip_libraries, language, modules):
Size = get_Size(server, token, movie['ratingKey'])
if Size:
tags.append(Size)
elif module == 'Language':
Language = get_Language(server, token, movie['ratingKey'])
if Language:
tags.append(Language)
update_movie(server, token, movie, tags, language)

# 更新版本信息
Expand Down Expand Up @@ -238,6 +243,10 @@ def process_new_movie(server, token, metadata, language, modules):
Size = get_Size(server, token, metadata['ratingKey'])
if Size:
tags.append(Size)
elif module == 'Language':
Language = get_Language(server, token, metadata['ratingKey'])
if Language:
tags.append(Language)
update_movie(server, token, metadata, tags, language)

# 重置电影的版本信息
Expand Down
139 changes: 139 additions & 0 deletions modules/Language.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import requests

def get_Language(server, token, movie_id):
headers = {'X-Plex-Token': token, 'Accept': 'application/json'}
response = requests.get(f'{server}/library/metadata/{movie_id}', headers=headers)
data = response.json()

media = data['MediaContainer']['Metadata'][0]['Media'][0]['Part'][0]
if 'Stream' in media:
audio_streams = [stream for stream in media['Stream'] if stream['streamType'] == 2]

# Skip processing if there are multiple audio tracks
if len(audio_streams) > 1:
return None

# Mapping of common language codes to full names in alphabetical order
language_mapping = {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to extend this to also support language tags?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like mi, en, da, etc? or what tag format?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also referred to as locales. Here's another reference.

Personally example much of my library includes Arabic that's either dubbed into both classical/modern standard arabic (ar) or egyptian arabic (ar-eg).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing that will need to be updated along with this is the main README

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also referred to as locales. Here's another reference.

Personally example much of my library includes Arabic that's either dubbed into both classical/modern standard arabic (ar) or egyptian arabic (ar-eg).

image
My languages are based on language codes you would find in mkvtoolnix to define audio tracks

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. So would I be using this designation going forward for any ar-eg files?

'af': 'Afrikaans',
'am': 'Amharic',
'ar': 'Arabic',
'as': 'Assamese',
'ay': 'Aymara',
'az': 'Azerbaijani',
'bh': 'Bihari',
'bi': 'Bislama',
'bn': 'Bengali',
'bo': 'Tibetan',
'bs': 'Bosnian',
'bg': 'Bulgarian',
'ca': 'Catalan',
'cs': 'Czech',
'cy': 'Welsh',
'da': 'Danish',
'de': 'German',
'dz': 'Dzongkha',
'el': 'Greek',
'en': 'English',
'es': 'Spanish',
'et': 'Estonian',
'eu': 'Basque',
'fa': 'Persian',
'fi': 'Finnish',
'fj': 'Fijian',
'fr': 'French',
'ga': 'Irish',
'gu': 'Gujarati',
'he': 'Hebrew',
'hi': 'Hindi',
'hr': 'Croatian',
'hu': 'Hungarian',
'hy': 'Armenian',
'id': 'Indonesian',
'ig': 'Igbo',
'is': 'Icelandic',
'it': 'Italian',
'iu': 'Inuktitut',
'ja': 'Japanese',
'jv': 'Javanese',
'ka': 'Georgian',
'kk': 'Kazakh',
'km': 'Khmer',
'kn': 'Kannada',
'ko': 'Korean',
'ks': 'Kashmiri',
'ky': 'Kyrgyz',
'lo': 'Lao',
'lt': 'Lithuanian',
'lv': 'Latvian',
'mg': 'Malagasy',
'mi': 'Maori',
'mk': 'Macedonian',
'ml': 'Malayalam',
'mn': 'Mongolian',
'mr': 'Marathi',
'ms': 'Malay',
'mt': 'Maltese',
'my': 'Burmese',
'ne': 'Nepali',
'nl': 'Dutch',
'no': 'Norwegian',
'ny': 'Chichewa',
'oj': 'Ojibwe',
'om': 'Oromo',
'or': 'Odia',
'pa': 'Punjabi',
'pl': 'Polish',
'pt': 'Portuguese',
'qu': 'Quechua',
'ro': 'Romanian',
'ru': 'Russian',
'rw': 'Kinyarwanda',
'si': 'Sinhala',
'sk': 'Slovak',
'sl': 'Slovenian',
'sm': 'Samoan',
'so': 'Somali',
'sq': 'Albanian',
'sr': 'Serbian',
'ss': 'Swati',
'st': 'Sotho',
'su': 'Sundanese',
'sv': 'Swedish',
'sw': 'Swahili',
'ta': 'Tamil',
'te': 'Telugu',
'th': 'Thai',
'ti': 'Tigrinya',
'tl': 'Tagalog',
'tn': 'Tswana',
'to': 'Tonga',
'tr': 'Turkish',
'ts': 'Tsonga',
'tt': 'Tatar',
'uk': 'Ukrainian',
'ur': 'Urdu',
'uz': 'Uzbek',
've': 'Venda',
'vi': 'Vietnamese',
'xh': 'Xhosa',
'yo': 'Yoruba',
'zh': 'Chinese',
'zu': 'Zulu',
'nv': 'Navajo',
'cr': 'Cree',
'mh': 'Marshallese',
'ho': 'Hiri Motu',
'hz': 'Herero',
'ty': 'Tahitian',
'to': 'Tonga',
}

# Proceed only if there is a single audio track
if len(audio_streams) == 1:
language_code = audio_streams[0].get('language')
if language_code:
language = language_mapping.get(language_code, language_code)
return language

return None