Skip to content

Commit

Permalink
Merge pull request #42 from 31December99/0.x.x
Browse files Browse the repository at this point in the history
Mediainfo resolution, ftp
  • Loading branch information
31December99 authored Sep 25, 2024
2 parents 98f20ac + 8f3b96e commit f897fb1
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 50 deletions.
10 changes: 5 additions & 5 deletions common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def create_default_env_file(path):
# IGDB
IGDB_CLIENT_ID=
IGDB_ACCESS_TK=
IGDB_ID_SECRET=
"""
with open(path, "w") as f:
f.write(default_content.strip())
Expand Down Expand Up @@ -117,7 +117,7 @@ class Config(BaseSettings):
FTPX_IP: str | None = Field(default=None, env="FTPX_IP")
FTPX_PORT: str | None = Field(default="2121", env="FTPX_PORT")
IGDB_CLIENT_ID: str | None = Field(default=None, env="IGDB_CLIENT_ID")
IGDB_ACCESS_TK: str | None = Field(default=None, env="IGDB_ACCESS_TK")
IGDB_ID_SECRET: str | None = Field(default=None, env="IGDB_ID_SECRET")

# TORRENT CLIENT
QBIT_USER: str | None = Field(default=None, env="QBIT_USER")
Expand Down Expand Up @@ -313,10 +313,10 @@ def validate_igdb_client_id(cls, value):
# custom_console.bot_question_log("[Optional] No IGDB_CLIENT_ID provided\n")
return value

@field_validator("IGDB_ACCESS_TK")
def validate_igdb_access_tk(cls, value):
@field_validator("IGDB_ID_SECRET")
def validate_igdb_id_secret(cls, value):
# if not value:
# custom_console.bot_question_log("[Optional] No IGDB_ACCESS_TK provided\n")
# custom_console.bot_question_log("[Optional] No IGDB_ID_SECRET provided\n")
return value


Expand Down
6 changes: 5 additions & 1 deletion common/external_services/ftpx/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ def select_file(self, one_file_selected: FTPDirectory):
self.ftpx_service.current_path(), one_file_selected.name
)
self.single_file_selected = True
## change the path ( replace '\' to '/' for windows OS) ##
self.remote_path = self.remote_path.replace("\\", "/")

# Create a list of FPTDirectory for a single file
self.current_list_of_files = [one_file_selected]
Expand All @@ -230,7 +232,9 @@ def change_path(self, selected_folder: str):
self.remote_path = os.path.join(
self.ftpx_service.current_path(), selected_folder
)
# change the path

## change the path ( replace '\' to '/' for windows OS) ##
self.remote_path = self.remote_path.replace("\\", "/")
self.ftpx_service.change_dir(new_path=self.remote_path)
# // Build a new Home page for the current folder
home_folder = self.ftpx_service.get_list(remote_path=config.FTPX_ROOT)
Expand Down
6 changes: 3 additions & 3 deletions common/external_services/igdb/core/igdb_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ def cls_login(cls) -> bool:

params = {
"client_id": config.IGDB_CLIENT_ID,
"client_secret": config.IGDB_ACCESS_TK,
"client_secret": config.IGDB_ID_SECRET,
"grant_type": "client_credentials",
}

if not config.IGDB_CLIENT_ID:
custom_console.bot_question_log("No IGDB_CLIENT_ID provided\n")
return False

if not config.IGDB_ACCESS_TK:
custom_console.bot_question_log("No IGDB_ACCESS_TK provided\n")
if not config.IGDB_ID_SECRET:
custom_console.bot_question_log("No IGDB_ID_SECRET provided\n")
return False

response = cls.http_client.get_url(oauth, params=params, get_method=False)
Expand Down
1 change: 0 additions & 1 deletion common/external_services/igdb/core/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@
"FAITH",
"SABER",
"BLITZ",
"PRIME",
"SPECTRUM",
"SHADOWFANG",
"FROST",
Expand Down
14 changes: 11 additions & 3 deletions common/mediainfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,19 @@ def video_width(self):

@property
def video_height(self):
"""Returns the height of the videoo"""
"""Returns the height of the video"""
video = self.video_track
if video:
return video[0].get('height', 'Unknown')
return 'Unknown'
return video[0].get('height', None)
return None

@property
def video_scan_type(self):
"""Returns the scan type"""
video = self.video_track
if video:
return video[0].get('scan_type', None)
return None

@property
def video_aspect_ratio(self):
Expand Down
4 changes: 4 additions & 0 deletions common/trackers/itt.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
"dlmux": 27,
"bdmux": 29
},
"TAGS": {
"SD": 1,
"HD": 0,
},
"RESOLUTION": {
"4320p": 1,
"2160p": 2,
Expand Down
54 changes: 43 additions & 11 deletions unit3dup/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,30 +49,62 @@ def run(self) -> None:
"""
custom_console.panel_message("Analyzing... Please wait")

# Get user contents
# Get Files list with basic attributes
# from the upload() or scan command()
# and create an object Media
# torrent_path
# media_type
# crew
# game_tags
# game_title
self.content_manager = ContentManager(
path=self.path, tracker_name=self.tracker_name, mode=self.mode
)
file_media_list = self.content_manager.get_files()

# Get the contents (Media)
files = self.content_manager.get_files()
# Search for rar files and decompress them
if not files:
if not file_media_list:
custom_console.bot_error_log("There are no files to process")
return
extractor = Extractor(media=files)
result = extractor.unrar()
if result is False:
exit(1)

# Create the file objects
# Decompress the rar files( only for ftp)
if self.cli.ftp:
extractor = Extractor(media=file_media_list)
result = extractor.unrar()
if result is False:
exit(1)

# Create an object Files for each file from the files_list
# We need to prepare each file (Files class) to create a content object (Contents):

# file without folder
# file with folder
# folder with files
# tv show title string
# movie title string
# display_name for the tracker website string
# media_info json
# game by crew
# game title for query igdb
# game tags (platform) for query igdb
# document
# doc description
# torrent package
# torrent name
# torrent file name
# torrent meta_file
# torrent size (field)
# audio languages

# Media > Files > Content
contents = [
content
for item in files
if (content := self.content_manager.get_media(item))
for media in file_media_list
if (content := self.content_manager.get_media(media))
]

# Print the list of selected files being processed
# the contents objects
custom_console.bot_process_table_log(contents)

# Process them
Expand Down
66 changes: 56 additions & 10 deletions unit3dup/contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@
suffixes,
platform_patterns,
)

from common.custom_console import custom_console
from common.trackers.trackers import ITTData
from dataclasses import dataclass, field
from common.mediainfo import MediaFile
from common.utility import title

# Get the name of the crew only if it's the last substring in the title by \b$
crew_pattern = r"\b(" + "|".join(pattern.replace(" ", "_") for pattern in crew_patterns) + r")\b$"
crew_pattern = (
r"\b(" + "|".join(pattern.replace(" ", "_") for pattern in crew_patterns) + r")\b$"
)

# Get the platform substr
tag_pattern = r"\b(" + "|".join(platform_patterns) + r")\b"
Expand Down Expand Up @@ -43,23 +47,63 @@ class Contents:
game_tags: list

def __post_init__(self):
###
# Search for the episode title
####
guess_filename = title.Guessit(self.file_name)
self.episode_title = guess_filename.guessit_episode_title
if self.episode_title:
self.display_name = " ".join(
self.display_name.replace(self.episode_title, "").split()
)

# Search for resolution based on mediainfo string
tracker_data = ITTData.load_from_module()
file_path = os.path.join(self.folder, self.file_name)
media_file = MediaFile(file_path)
video_height = f"{media_file.video_height}p"
if video_height not in tracker_data.resolution:
self.resolution = tracker_data.resolution["altro"]
else:
self.resolution = tracker_data.resolution[video_height]
if not self.game_crew:
# Load the tracker data from the dictionary
tracker_data = ITTData.load_from_module()
# Read from the current video file the height field
file_path = os.path.join(self.folder, self.file_name)
media_file = MediaFile(file_path)

# Get the resolution sub from the dictionary
resolutions = tracker_data.resolution
# Remove duplicate because the 'i' and 'p' and return a set
resolution_values = {
key[:-1] for key in resolutions.keys() if key[:-1].isdigit()
}

# The resolution from the mediainfo not always mach those in tracker data
# so we apply the difference between 'x' (tracker resolution in set) and the video_height
# do it for each value in resolution_values and return the min among all values
# example: height = 1000...
# For 720: abs(720 - 1000) = 280
# For 1080: abs(1080 - 1000) = 80
# -> get 1080

if media_file.video_height:
closest_resolution = min(
resolution_values,
key=lambda x: abs(int(x) - int(media_file.video_height)),
)

# Get scan type: progressive or interlaced
scan_type = media_file.video_scan_type

if scan_type:
if scan_type.lower() == "progressive":
closest_resolution = f"{closest_resolution}p"
else:
closest_resolution = f"{closest_resolution}i"
else:
closest_resolution = tracker_data.resolution["altro"]

if closest_resolution not in tracker_data.resolution:
self.resolution = tracker_data.resolution["altro"]
else:
self.resolution = tracker_data.resolution[closest_resolution]
else:
custom_console.bot_error_log(f"Video Height resolution not found in {self.file_name}")
custom_console.bot_error_log(f"Set to default value {tracker_data.category['altro']}")
self.resolution = tracker_data.resolution["altro"]


@dataclass
Expand Down Expand Up @@ -106,9 +150,11 @@ def audio_codec(self):
def subtitle(self):
return self.guess_filename.subtitle

"""
@property
def resolution(self):
return self.guess_filename.screen_size
"""

@property
def torrent_path(self) -> str:
Expand Down
Loading

0 comments on commit f897fb1

Please sign in to comment.