Skip to content

Commit

Permalink
Code cleanup (#219)
Browse files Browse the repository at this point in the history
* code cleanup

* more cleanup

* queue.py should have been recycled

* and exportmi.py

* and more cleanup

* update image task functions

* dvd screenshots

* common screens

* multiscreens hack

should be fine since retake should capture black images

* tracker site search

* BHD screens

* image upload tasks

* fix screens uploading

* common awaits

* move tracker status to new file

* Fix tvmaze quick search

* move torrent creation

* async dupe checking

Rest of site files still to be done

* BHD post not get

Other minor tweaks

* correct torrent library

* more await

* easy unit3d copy/paste

* ptp skip image host

* site search httpx

* Direct inject torrent link into torrent comment

Tested with Aither, other sites to be updated

* Inject torrent link into comment

* fix common description

* Minor fixes

* Proper ptp groupid save

* MTV skip image upload

* fix -mps arg

feels ugly, but it works
  • Loading branch information
Audionut authored Dec 27, 2024
1 parent ca370dd commit 9ada2c6
Show file tree
Hide file tree
Showing 64 changed files with 5,280 additions and 5,789 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ A simple tool to take the work out of uploading.
- Can re-use existing torrents instead of hashing new
- Generates proper name for your upload using Mediainfo/BDInfo and TMDb/IMDb conforming to site rules
- Checks for existing releases already on site
- Uploads to ACM/Aither/AL/ANT/BHD/BHDTV/BLU/CBR/FNP/FL/HDB/HDT/HP/HUNO/JPTV/LCD/LST/LT/MTV/NBL/OE/OTW/PSS/PTP/PTER/PTT/RF/R4E(limited)/RTF/SHRI/SN/SPD/STC/STT/TLC/THR/TL/TVC/TTG/ULCX/UTP/YOINK
- Uploads to ACM/Aither/AL/ANT/BHD/BHDTV/BLU/CBR/FNP/FL/HDB/HDT/HHD/HP/HUNO/JPTV/LCD/LST/LT/MTV/NBL/OE/OTW/PSS/PTP/PTER/PTT/RF/R4E(limited)/RTF/SHRI/SN/SPD/STC/STT/TLC/THR/TL/TVC/TTG/ULCX/UTP/YOINK
- Adds to your client with fast resume, seeding instantly (rtorrent/qbittorrent/deluge/watch folder)
- ALL WITH MINIMAL INPUT!
- Currently works with .mkv/.mp4/Blu-ray/DVD/HD-DVDs
Expand Down
15 changes: 4 additions & 11 deletions data/example-config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,18 @@
# Number of screenshots to capture
"screens": "6",

# Tonemap HDR screenshots and set task limit when tonemapping
# When tonemapping, out of memory errors are more likely to occur with higher task limits
# Tonemap HDR screenshots
"tone_map": False,
"tone_task_limit": "1",

# Number of cutoff screenshots
# If there are at least this many screenshots already, perhaps pulled from existing
# description, skip creating and uploading any further screenshots.
"cutoff_screens": "3",

# multi processing task limit
# When capturing/optimizing images, limit to this many concurrent tasks
# Causes issues on UNIX based OS when task_limit > 1
# defaults to os.cpu_count() if thiss value not set
"task_limit": "1",
# When capturing/optimizing/uploading images, limit to this many concurrent tasks
# defaults to os.cpu_count() if this value not set
# "task_limit": "1",

# Providing the option to change the size of the screenshot thumbnails where supported.
# Default is 350, ie [img=350]
Expand Down Expand Up @@ -88,10 +85,6 @@
# Play the bell sound effect when asking for confirmation
"sfx_on_prompt": True,

# Run an API search after upload to find the permalink and insert as comment in torrent
# Needs a 5 second wait to ensure the API is updated
"get_permalink": False,

# How many trackers need to pass successfull checking to continue with the upload process
# Default = 1. If 1 (or more) tracker/s pass banned_group and dupe checking, uploading will continue
# If less than the number of trackers pass the checking, exit immediately.
Expand Down
6 changes: 4 additions & 2 deletions src/bbcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def clean_ptp_description(self, desc, is_disc):
desc = desc.replace(comp, f"COMPARISON_PLACEHOLDER-{i} ")
comp_placeholders.append(comp)

# Remove Images in IMG tags:
# Remove Images in IMG tags
desc = re.sub(r"\[img\][\s\S]*?\[\/img\]", "", desc, flags=re.IGNORECASE)
desc = re.sub(r"\[img=[\s\S]*?\]", "", desc, flags=re.IGNORECASE)

Expand Down Expand Up @@ -309,7 +309,9 @@ def clean_unit3d_description(self, desc, site):
Auto\sUploader\[\/b\]\s*\[img=\d+\]https:\/\/blutopia\.xyz\/favicon\.ico\[\/img\]\s*\[\/center\]|
\[center\]\s*\[b\]Uploaded\sUsing\s\[url=https:\/\/github\.com\/HDInnovations\/UNIT3D\]UNIT3D\[\/url\]
\sAuto\sUploader\[\/b\]\s*\[\/center\]|
\[center\]\[url=https:\/\/github\.com\/z-ink\/uploadrr\]\[img=\d+\]https:\/\/i\.ibb\.co\/2NVWb0c\/uploadrr\.webp\[\/img\]\[\/url\]\[\/center\]
\[center\]\[url=https:\/\/github\.com\/z-ink\/uploadrr\]\[img=\d+\]https:\/\/i\.ibb\.co\/2NVWb0c\/uploadrr\.webp\[\/img\]\[\/url\]\[\/center\]|
\n\[center\]\[url=https:\/\/github\.com\/edge20200\/Only-Uploader\]Powered\sby\s
Only-Uploader\[\/url\]\[\/center\]
"""
desc = re.sub(bot_signature_regex, "", desc, flags=re.IGNORECASE | re.VERBOSE)
desc = re.sub(r"\[center\].*Created by L4G's Upload Assistant.*\[\/center\]", "", desc, flags=re.IGNORECASE)
Expand Down
246 changes: 246 additions & 0 deletions src/exportmi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
from src.console import console
from pymediainfo import MediaInfo
import json
import os


async def mi_resolution(res, guess, width, scan, height, actual_height):
res_map = {
"3840x2160p": "2160p", "2160p": "2160p",
"2560x1440p": "1440p", "1440p": "1440p",
"1920x1080p": "1080p", "1080p": "1080p",
"1920x1080i": "1080i", "1080i": "1080i",
"1280x720p": "720p", "720p": "720p",
"1280x540p": "720p", "1280x576p": "720p",
"1024x576p": "576p", "576p": "576p",
"1024x576i": "576i", "576i": "576i",
"854x480p": "480p", "480p": "480p",
"854x480i": "480i", "480i": "480i",
"720x576p": "576p", "576p": "576p",
"720x576i": "576i", "576i": "576i",
"720x480p": "480p", "480p": "480p",
"720x480i": "480i", "480i": "480i",
"15360x8640p": "8640p", "8640p": "8640p",
"7680x4320p": "4320p", "4320p": "4320p",
"OTHER": "OTHER"}
resolution = res_map.get(res, None)
if actual_height == 540:
resolution = "OTHER"
if resolution is None:
try:
resolution = guess['screen_size']
except Exception:
width_map = {
'3840p': '2160p',
'2560p': '1550p',
'1920p': '1080p',
'1920i': '1080i',
'1280p': '720p',
'1024p': '576p',
'1024i': '576i',
'854p': '480p',
'854i': '480i',
'720p': '576p',
'720i': '576i',
'15360p': '4320p',
'OTHERp': 'OTHER'
}
resolution = width_map.get(f"{width}{scan}", "OTHER")
resolution = await mi_resolution(resolution, guess, width, scan, height, actual_height)

return resolution


async def exportInfo(video, isdir, folder_id, base_dir, export_text):
def filter_mediainfo(data):
filtered = {
"creatingLibrary": data.get("creatingLibrary"),
"media": {
"@ref": data["media"]["@ref"],
"track": []
}
}

for track in data["media"]["track"]:
if track["@type"] == "General":
filtered["media"]["track"].append({
"@type": track["@type"],
"UniqueID": track.get("UniqueID", {}),
"VideoCount": track.get("VideoCount", {}),
"AudioCount": track.get("AudioCount", {}),
"TextCount": track.get("TextCount", {}),
"MenuCount": track.get("MenuCount", {}),
"FileExtension": track.get("FileExtension", {}),
"Format": track.get("Format", {}),
"Format_Version": track.get("Format_Version", {}),
"FileSize": track.get("FileSize", {}),
"Duration": track.get("Duration", {}),
"OverallBitRate": track.get("OverallBitRate", {}),
"FrameRate": track.get("FrameRate", {}),
"FrameCount": track.get("FrameCount", {}),
"StreamSize": track.get("StreamSize", {}),
"IsStreamable": track.get("IsStreamable", {}),
"File_Created_Date": track.get("File_Created_Date", {}),
"File_Created_Date_Local": track.get("File_Created_Date_Local", {}),
"File_Modified_Date": track.get("File_Modified_Date", {}),
"File_Modified_Date_Local": track.get("File_Modified_Date_Local", {}),
"Encoded_Application": track.get("Encoded_Application", {}),
"Encoded_Library": track.get("Encoded_Library", {}),
})
elif track["@type"] == "Video":
filtered["media"]["track"].append({
"@type": track["@type"],
"StreamOrder": track.get("StreamOrder", {}),
"ID": track.get("ID", {}),
"UniqueID": track.get("UniqueID", {}),
"Format": track.get("Format", {}),
"Format_Profile": track.get("Format_Profile", {}),
"Format_Version": track.get("Format_Version", {}),
"Format_Level": track.get("Format_Level", {}),
"Format_Tier": track.get("Format_Tier", {}),
"HDR_Format": track.get("HDR_Format", {}),
"HDR_Format_Version": track.get("HDR_Format_Version", {}),
"HDR_Format_String": track.get("HDR_Format_String", {}),
"HDR_Format_Profile": track.get("HDR_Format_Profile", {}),
"HDR_Format_Level": track.get("HDR_Format_Level", {}),
"HDR_Format_Settings": track.get("HDR_Format_Settings", {}),
"HDR_Format_Compression": track.get("HDR_Format_Compression", {}),
"HDR_Format_Compatibility": track.get("HDR_Format_Compatibility", {}),
"CodecID": track.get("CodecID", {}),
"CodecID_Hint": track.get("CodecID_Hint", {}),
"Duration": track.get("Duration", {}),
"BitRate": track.get("BitRate", {}),
"Width": track.get("Width", {}),
"Height": track.get("Height", {}),
"Stored_Height": track.get("Stored_Height", {}),
"Sampled_Width": track.get("Sampled_Width", {}),
"Sampled_Height": track.get("Sampled_Height", {}),
"PixelAspectRatio": track.get("PixelAspectRatio", {}),
"DisplayAspectRatio": track.get("DisplayAspectRatio", {}),
"FrameRate_Mode": track.get("FrameRate_Mode", {}),
"FrameRate": track.get("FrameRate", {}),
"FrameRate_Num": track.get("FrameRate_Num", {}),
"FrameRate_Den": track.get("FrameRate_Den", {}),
"FrameCount": track.get("FrameCount", {}),
"Standard": track.get("Standard", {}),
"ColorSpace": track.get("ColorSpace", {}),
"ChromaSubsampling": track.get("ChromaSubsampling", {}),
"ChromaSubsampling_Position": track.get("ChromaSubsampling_Position", {}),
"BitDepth": track.get("BitDepth", {}),
"ScanType": track.get("ScanType", {}),
"ScanOrder": track.get("ScanOrder", {}),
"Delay": track.get("Delay", {}),
"Delay_Source": track.get("Delay_Source", {}),
"StreamSize": track.get("StreamSize", {}),
"Language": track.get("Language", {}),
"Default": track.get("Default", {}),
"Forced": track.get("Forced", {}),
"colour_description_present": track.get("colour_description_present", {}),
"colour_description_present_Source": track.get("colour_description_present_Source", {}),
"colour_range": track.get("colour_range", {}),
"colour_range_Source": track.get("colour_range_Source", {}),
"colour_primaries": track.get("colour_primaries", {}),
"colour_primaries_Source": track.get("colour_primaries_Source", {}),
"transfer_characteristics": track.get("transfer_characteristics", {}),
"transfer_characteristics_Source": track.get("transfer_characteristics_Source", {}),
"transfer_characteristics_Original": track.get("transfer_characteristics_Original", {}),
"matrix_coefficients": track.get("matrix_coefficients", {}),
"matrix_coefficients_Source": track.get("matrix_coefficients_Source", {}),
"MasteringDisplay_ColorPrimaries": track.get("MasteringDisplay_ColorPrimaries", {}),
"MasteringDisplay_ColorPrimaries_Source": track.get("MasteringDisplay_ColorPrimaries_Source", {}),
"MasteringDisplay_Luminance": track.get("MasteringDisplay_Luminance", {}),
"MasteringDisplay_Luminance_Source": track.get("MasteringDisplay_Luminance_Source", {}),
"MaxCLL": track.get("MaxCLL", {}),
"MaxCLL_Source": track.get("MaxCLL_Source", {}),
"MaxFALL": track.get("MaxFALL", {}),
"MaxFALL_Source": track.get("MaxFALL_Source", {}),
"Encoded_Library_Settings": track.get("Encoded_Library_Settings", {}),
})
elif track["@type"] == "Audio":
filtered["media"]["track"].append({
"@type": track["@type"],
"StreamOrder": track.get("StreamOrder", {}),
"ID": track.get("ID", {}),
"UniqueID": track.get("UniqueID", {}),
"Format": track.get("Format", {}),
"Format_Version": track.get("Format_Version", {}),
"Format_Profile": track.get("Format_Profile", {}),
"Format_Settings": track.get("Format_Settings", {}),
"Format_Commercial_IfAny": track.get("Format_Commercial_IfAny", {}),
"Format_Settings_Endianness": track.get("Format_Settings_Endianness", {}),
"Format_AdditionalFeatures": track.get("Format_AdditionalFeatures", {}),
"CodecID": track.get("CodecID", {}),
"Duration": track.get("Duration", {}),
"BitRate_Mode": track.get("BitRate_Mode", {}),
"BitRate": track.get("BitRate", {}),
"Channels": track.get("Channels", {}),
"ChannelPositions": track.get("ChannelPositions", {}),
"ChannelLayout": track.get("ChannelLayout", {}),
"Channels_Original": track.get("Channels_Original", {}),
"ChannelLayout_Original": track.get("ChannelLayout_Original", {}),
"SamplesPerFrame": track.get("SamplesPerFrame", {}),
"SamplingRate": track.get("SamplingRate", {}),
"SamplingCount": track.get("SamplingCount", {}),
"FrameRate": track.get("FrameRate", {}),
"FrameCount": track.get("FrameCount", {}),
"Compression_Mode": track.get("Compression_Mode", {}),
"Delay": track.get("Delay", {}),
"Delay_Source": track.get("Delay_Source", {}),
"Video_Delay": track.get("Video_Delay", {}),
"StreamSize": track.get("StreamSize", {}),
"Title": track.get("Title", {}),
"Language": track.get("Language", {}),
"ServiceKind": track.get("ServiceKind", {}),
"Default": track.get("Default", {}),
"Forced": track.get("Forced", {}),
"extra": track.get("extra", {}),
})
elif track["@type"] == "Text":
filtered["media"]["track"].append({
"@type": track["@type"],
"@typeorder": track.get("@typeorder", {}),
"StreamOrder": track.get("StreamOrder", {}),
"ID": track.get("ID", {}),
"UniqueID": track.get("UniqueID", {}),
"Format": track.get("Format", {}),
"CodecID": track.get("CodecID", {}),
"Duration": track.get("Duration", {}),
"BitRate": track.get("BitRate", {}),
"FrameRate": track.get("FrameRate", {}),
"FrameCount": track.get("FrameCount", {}),
"ElementCount": track.get("ElementCount", {}),
"StreamSize": track.get("StreamSize", {}),
"Title": track.get("Title", {}),
"Language": track.get("Language", {}),
"Default": track.get("Default", {}),
"Forced": track.get("Forced", {}),
})
elif track["@type"] == "Menu":
filtered["media"]["track"].append({
"@type": track["@type"],
"extra": track.get("extra", {}),
})
return filtered

if not os.path.exists(f"{base_dir}/tmp/{folder_id}/MEDIAINFO.txt") and export_text:
console.print("[bold yellow]Exporting MediaInfo...")
if not isdir:
os.chdir(os.path.dirname(video))
media_info = MediaInfo.parse(video, output="STRING", full=False, mediainfo_options={'inform_version': '1'})
with open(f"{base_dir}/tmp/{folder_id}/MEDIAINFO.txt", 'w', newline="", encoding='utf-8') as export:
export.write(media_info)
with open(f"{base_dir}/tmp/{folder_id}/MEDIAINFO_CLEANPATH.txt", 'w', newline="", encoding='utf-8') as export_cleanpath:
export_cleanpath.write(media_info.replace(video, os.path.basename(video)))
console.print("[bold green]MediaInfo Exported.")

if not os.path.exists(f"{base_dir}/tmp/{folder_id}/MediaInfo.json.txt"):
media_info_json = MediaInfo.parse(video, output="JSON", mediainfo_options={'inform_version': '1'})
media_info_dict = json.loads(media_info_json)
filtered_info = filter_mediainfo(media_info_dict)
with open(f"{base_dir}/tmp/{folder_id}/MediaInfo.json", 'w', encoding='utf-8') as export:
json.dump(filtered_info, export, indent=4)

with open(f"{base_dir}/tmp/{folder_id}/MediaInfo.json", 'r', encoding='utf-8') as f:
mi = json.load(f)

return mi
Loading

0 comments on commit 9ada2c6

Please sign in to comment.