Conversation
|
Thanks for taking the time to contribute to this project. Upload Assistant is currently in a complete rewrite, and no new development is being conducted on this python source at this time. If you have come this far, please feel free to leave open, any pull requests regarding new sites being added to the source, as these can serve as the baseline for later conversion. If your pull request relates to a critical bug, this will be addressed in this code base, and a new release published as needed. If your pull request only addresses a quite minor bug, it is not likely to be addressed in this code base. Details for the new code base will follow at a later date. |
📝 WalkthroughWalkthroughAdded Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant HUNO_Tracker as "HUNO Tracker"
participant FileSystem as "Temp Filesystem"
participant HUNO_API as "HUNO API"
Client->>HUNO_Tracker: upload(meta)
HUNO_Tracker->>HUNO_Tracker: validate api_token & announce_url
alt missing api_token or announce_url
HUNO_Tracker->>Client: set meta["skipping"]=tracker, return False
else
HUNO_Tracker->>HUNO_Tracker: build payload (get_data)
HUNO_Tracker->>FileSystem: create/read torrent, description, mediainfo/bdinfo
alt debug mode
HUNO_Tracker->>HUNO_Tracker: construct fake response
HUNO_Tracker->>Client: return True
else
HUNO_Tracker->>HUNO_API: POST multipart via httpx (files + api_token)
HUNO_API->>HUNO_Tracker: JSON response (success/failure)
HUNO_Tracker->>HUNO_Tracker: update meta["tracker_status"][tracker]["status_message"]
HUNO_Tracker->>Client: return True/False
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/trackers/HUNO.py`:
- Around line 205-224: The file reads for building the files dict (calls around
self.common.create_torrent_for_upload and variables torrent_path, desc_path,
mediainfo_path, bdinfo_path that populate files["torrent"],
files["description"], files["mediainfo"/"bdinfo"]) occur before the try that
reports tracker status, so missing/corrupt files raise unhandled exceptions;
move the entire file-gathering block (creation of files dict and all
aiofiles.open reads) inside the existing try that begins later (the block that
handles tracker upload/response) so any read errors are caught and the tracker
status/reporting path executes, and ensure files remains a dict scoped to that
try and is cleaned up or logged on exception.
- Line 29: The code directly indexes
self.config["TRACKERS"][self.tracker]["announce_url"] which raises KeyError for
older configs; change the assignment in HUNO.__init__ (or where
self.announce_url is set) to safely fetch the value (e.g., use .get on the
TRACKERS dict or try/except) and default to None or an empty string when
missing, and ensure any later use of self.announce_url handles the None/empty
case so uploads don’t crash.
In `@src/trackersetup.py`:
- Line 589: The plain console.print(data) call is printing the full API response
every run; wrap it behind a debug/verbose check so full payloads are only shown
when debugging. Replace the direct console.print(data) in trackersetup.py with a
conditional that checks an existing debug flag or config (e.g., if debug or if
settings.DEBUG) or fall back to an environment-controlled boolean (e.g., if
os.getenv("DEBUG") == "1"), and only then call console.print(data); otherwise
remove or replace with a minimal log (e.g., logger.debug/console.log summary) to
avoid exposing full responses.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 401f432c-76a9-4862-ba59-ef51a5389ecd
📒 Files selected for processing (3)
data/example-config.pysrc/trackers/HUNO.pysrc/trackersetup.py
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/trackers/HUNO.py (1)
194-196:⚠️ Potential issue | 🟠 MajorMove
get_data()into guarded error flow to prevent unhandled upload crashes.Line 195 executes
await self.get_data(meta)before thetry; sinceget_data()now does file I/O viaget_description(), failures there bypass tracker-status error handling.Proposed fix
async def upload(self, meta: dict[str, Any], _: str = "") -> bool: - data = await self.get_data(meta) - # Initialize tracker status meta.setdefault("tracker_status", {}) meta["tracker_status"].setdefault(self.tracker, {}) api_token = str(self.config["TRACKERS"][self.tracker].get("api_key", "")) if not api_token: console.print(f"[bold red]{self.tracker}: Missing API key in config.[/bold red]") meta["skipping"] = self.tracker return False url = f"{self.upload_url}?api_token={api_token}" - if meta.get("debug", False): - console.print(f"[cyan]{self.tracker} Request Data:") - console.print(data) - meta["tracker_status"][self.tracker]["status_message"] = "Debug mode enabled, not uploading." - await self.common.create_torrent_for_upload(meta, f"{self.tracker}_DEBUG", f"{self.tracker}_DEBUG", announce_url="https://fake.tracker") - return True - try: + data = await self.get_data(meta) + if meta.get("debug", False): + console.print(f"[cyan]{self.tracker} Request Data:") + console.print(data) + meta["tracker_status"][self.tracker]["status_message"] = "Debug mode enabled, not uploading." + await self.common.create_torrent_for_upload(meta, f"{self.tracker}_DEBUG", f"{self.tracker}_DEBUG", announce_url="https://fake.tracker") + return True + files: dict[str, tuple[str, bytes, str]] = {} await self.common.create_torrent_for_upload(meta, self.tracker, self.source_flag, announce_url=self.announce_url) torrent_path = f"{meta['base_dir']}/tmp/{meta['uuid']}/[{self.tracker}].torrent" async with aiofiles.open(torrent_path, "rb") as f: files["torrent"] = (f"{meta['clean_name']}.torrent", await f.read(), "application/x-bittorrent")Also applies to: 216-263
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/trackers/HUNO.py` around lines 194 - 196, The call to await self.get_data(meta) happens before the try/except, so any I/O errors from get_description()/get_data() escape the tracker's status handling; move the get_data call inside the existing try block (and wrap it with the same exception handling used for tracker status updates) so that failures are caught and processed by the tracker error flow—apply the same change to the other upload-related calls in the same file referenced around the 216-263 region (any other await self.get_data(...) or calls that trigger get_description()) so they are executed inside try blocks that update tracker status/error handling (refer to the upload method and the other upload-related functions in HUNO.py).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/trackers/HUNO.py`:
- Around line 194-196: The call to await self.get_data(meta) happens before the
try/except, so any I/O errors from get_description()/get_data() escape the
tracker's status handling; move the get_data call inside the existing try block
(and wrap it with the same exception handling used for tracker status updates)
so that failures are caught and processed by the tracker error flow—apply the
same change to the other upload-related calls in the same file referenced around
the 216-263 region (any other await self.get_data(...) or calls that trigger
get_description()) so they are executed inside try blocks that update tracker
status/error handling (refer to the upload method and the other upload-related
functions in HUNO.py).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: fb47b827-edb2-4ca9-954c-a037056882f8
📒 Files selected for processing (2)
src/trackers/HUNO.pysrc/trackersetup.py
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/trackers/HUNO.py (1)
67-70: Consider using.get()forvalid_mi_settingsaccess.Based on the context from
src/prep.py,meta['valid_mi_settings']is set unconditionally toTruebefore the ENCODE validation, but if that code path isn't reached (e.g., different prep flow), direct dictionary access could raiseKeyError.Proposed defensive fix
- if not meta["valid_mi_settings"]: + if not meta.get("valid_mi_settings", True): console.print(f"{self.tracker}: [bold red]No encoding settings in mediainfo, skipping upload.[/bold red]") return False🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/trackers/HUNO.py` around lines 67 - 70, The access to meta["valid_mi_settings"] can raise KeyError if that key isn’t set; change the check in the HUNO tracker (the block that prints "{self.tracker}: No encoding settings..." and returns False) to use meta.get("valid_mi_settings", False) so missing keys are treated as invalid and the same console.print + return False path is executed; update any other direct meta["valid_mi_settings"] usages in the same function to use .get(...) for consistency.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/trackers/HUNO.py`:
- Around line 78-110: The encoding_settings variable is used outside the
Video-track branch causing a possible NameError and the CRF/bitrate checks run
for non-video tracks; fix by moving the entire CRF/bitrate validation logic
inside the if track.get("@type") == "Video": block (so encoding_settings is
assigned and used in the same scope), and after handling a Video track
(processing crf_match or bitrate) break out of the for tracks loop or return
immediately so you don't re-run validation for subsequent non-video tracks;
reference the variables/functions: tracks, track, encoding_settings, crf_match,
bit_rate, and meta to locate and scope the changes.
---
Nitpick comments:
In `@src/trackers/HUNO.py`:
- Around line 67-70: The access to meta["valid_mi_settings"] can raise KeyError
if that key isn’t set; change the check in the HUNO tracker (the block that
prints "{self.tracker}: No encoding settings..." and returns False) to use
meta.get("valid_mi_settings", False) so missing keys are treated as invalid and
the same console.print + return False path is executed; update any other direct
meta["valid_mi_settings"] usages in the same function to use .get(...) for
consistency.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| if not meta["is_disc"] and meta["type"] in ["ENCODE", "DVDRIP", "HDTV"] and ("x265" in meta.get("video_encode", "") or "HEVC" in meta.get("video_codec", "")): | ||
| tracks = meta.get("mediainfo", {}).get("media", {}).get("track", []) | ||
| for track in tracks: | ||
| if track.get('@type') == "Video": | ||
| encoding_settings = track.get('Encoded_Library_Settings', {}) | ||
|
|
||
| if encoding_settings: | ||
| crf_match = re.search(r'crf[ =:]+([\d.]+)', encoding_settings, re.IGNORECASE) | ||
| if crf_match: | ||
| if meta.get('debug', False): | ||
| console.print(f"Found CRF value: {crf_match.group(1)}") | ||
| crf_value = float(crf_match.group(1)) | ||
| if crf_value > 22: | ||
| if not meta['unattended']: | ||
| console.print(f"CRF value too high: {crf_value} for HUNO") | ||
| return False | ||
| else: | ||
| if meta.get('debug', False): | ||
| console.print("No CRF value found in encoding settings.") | ||
| bit_rate = track.get('BitRate') | ||
| if bit_rate and "Animation" not in meta.get('genre', ""): | ||
| try: | ||
| bit_rate_num = int(bit_rate) | ||
| except (ValueError, TypeError): | ||
| bit_rate_num = None | ||
|
|
||
| if bit_rate_num is not None: | ||
| bit_rate_kbps = bit_rate_num / 1000 | ||
|
|
||
| if bit_rate_kbps < 3000: | ||
| if not meta.get('unattended', False): | ||
| console.print(f"Video bitrate too low: {bit_rate_kbps:.0f} kbps for HUNO") | ||
| return False | ||
| if track.get("@type") == "Video": | ||
| encoding_settings = track.get("Encoded_Library_Settings", {}) | ||
|
|
||
| if encoding_settings: | ||
| crf_match = re.search(r"crf[ =:]+([\d.]+)", encoding_settings, re.IGNORECASE) | ||
| if crf_match: | ||
| if meta.get("debug", False): | ||
| console.print(f"Found CRF value: {crf_match.group(1)}") | ||
| crf_value = float(crf_match.group(1)) | ||
| if crf_value > 22: | ||
| if not meta["unattended"]: | ||
| console.print(f"CRF value too high: {crf_value} for HUNO") | ||
| return False | ||
| else: | ||
| if meta.get("debug", False): | ||
| console.print("No CRF value found in encoding settings.") | ||
| bit_rate = track.get("BitRate") | ||
| if bit_rate and "Animation" not in meta.get("genre", ""): | ||
| try: | ||
| bit_rate_num = int(bit_rate) | ||
| except (ValueError, TypeError): | ||
| bit_rate_num = None | ||
|
|
||
| if bit_rate_num is not None: | ||
| bit_rate_kbps = bit_rate_num / 1000 | ||
|
|
||
| if bit_rate_kbps < 3000: | ||
| if not meta.get("unattended", False): | ||
| console.print(f"Video bitrate too low: {bit_rate_kbps:.0f} kbps for HUNO") | ||
| return False |
There was a problem hiding this comment.
Variable encoding_settings may be referenced before assignment.
The if encoding_settings: block at line 84 is outside the if track.get("@type") == "Video": block, but encoding_settings is only assigned inside that condition. If the first track in tracks is not a Video track, this raises NameError. Additionally, the CRF/bitrate validation runs for every track iteration after finding a Video track, which is likely unintended.
Proposed fix to scope encoding_settings check correctly
if not meta["is_disc"] and meta["type"] in ["ENCODE", "DVDRIP", "HDTV"] and ("x265" in meta.get("video_encode", "") or "HEVC" in meta.get("video_codec", "")):
tracks = meta.get("mediainfo", {}).get("media", {}).get("track", [])
for track in tracks:
if track.get("@type") == "Video":
encoding_settings = track.get("Encoded_Library_Settings", {})
-
- if encoding_settings:
- crf_match = re.search(r"crf[ =:]+([\d.]+)", encoding_settings, re.IGNORECASE)
- if crf_match:
- if meta.get("debug", False):
- console.print(f"Found CRF value: {crf_match.group(1)}")
- crf_value = float(crf_match.group(1))
- if crf_value > 22:
- if not meta["unattended"]:
- console.print(f"CRF value too high: {crf_value} for HUNO")
- return False
- else:
- if meta.get("debug", False):
- console.print("No CRF value found in encoding settings.")
- bit_rate = track.get("BitRate")
- if bit_rate and "Animation" not in meta.get("genre", ""):
- try:
- bit_rate_num = int(bit_rate)
- except (ValueError, TypeError):
- bit_rate_num = None
-
- if bit_rate_num is not None:
- bit_rate_kbps = bit_rate_num / 1000
-
- if bit_rate_kbps < 3000:
- if not meta.get("unattended", False):
- console.print(f"Video bitrate too low: {bit_rate_kbps:.0f} kbps for HUNO")
- return False
+ if encoding_settings:
+ crf_match = re.search(r"crf[ =:]+([\d.]+)", encoding_settings, re.IGNORECASE)
+ if crf_match:
+ if meta.get("debug", False):
+ console.print(f"Found CRF value: {crf_match.group(1)}")
+ crf_value = float(crf_match.group(1))
+ if crf_value > 22:
+ if not meta["unattended"]:
+ console.print(f"CRF value too high: {crf_value} for HUNO")
+ return False
+ else:
+ if meta.get("debug", False):
+ console.print("No CRF value found in encoding settings.")
+ bit_rate = track.get("BitRate")
+ if bit_rate and "Animation" not in meta.get("genre", ""):
+ try:
+ bit_rate_num = int(bit_rate)
+ except (ValueError, TypeError):
+ bit_rate_num = None
+
+ if bit_rate_num is not None:
+ bit_rate_kbps = bit_rate_num / 1000
+
+ if bit_rate_kbps < 3000:
+ if not meta.get("unattended", False):
+ console.print(f"Video bitrate too low: {bit_rate_kbps:.0f} kbps for HUNO")
+ return False
+ break # Found Video track, no need to continue🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/trackers/HUNO.py` around lines 78 - 110, The encoding_settings variable
is used outside the Video-track branch causing a possible NameError and the
CRF/bitrate checks run for non-video tracks; fix by moving the entire
CRF/bitrate validation logic inside the if track.get("@type") == "Video": block
(so encoding_settings is assigned and used in the same scope), and after
handling a Video track (processing crf_match or bitrate) break out of the for
tracks loop or return immediately so you don't re-run validation for subsequent
non-video tracks; reference the variables/functions: tracks, track,
encoding_settings, crf_match, bit_rate, and meta to locate and scope the
changes.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/trackers/HUNO.py (1)
182-182: Parametertypeshadows Python builtin.Ruff flags this (A002). Consider renaming to
type_strorsource_typefor clarity.Suggested fix
- async def get_type_id(self, meta: dict[str, Any], type: str = "", reverse: bool = False, mapping_only: bool = False) -> dict[str, str]: + async def get_type_id(self, meta: dict[str, Any], type_str: str = "", reverse: bool = False, mapping_only: bool = False) -> dict[str, str]: type_id = { ... } ... - elif type: - return {"type_id": type_id.get(type, "0")} + elif type_str: + return {"type_id": type_id.get(type_str, "0")}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/trackers/HUNO.py` at line 182, The parameter name "type" in the async function get_type_id(...) shadows the Python builtin and triggers lint A002; rename that parameter (e.g., to type_str or source_type) across the function signature and all its internal uses in get_type_id (and update any external callers in this diff) to preserve behavior and avoid the shadowing warning.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/trackers/HUNO.py`:
- Line 182: The parameter name "type" in the async function get_type_id(...)
shadows the Python builtin and triggers lint A002; rename that parameter (e.g.,
to type_str or source_type) across the function signature and all its internal
uses in get_type_id (and update any external callers in this diff) to preserve
behavior and avoid the shadowing warning.
|
I tested this, and while it works, it returns a display error and puts the upload in the modq this PR may address that #1322 This has been working without error/issue for the last day and a half. not sure if they changed something on their end. And it's back to not working again. They must've changed something again. |
Summary by CodeRabbit
New Features
Bug Fixes
Chores