Skip to content

Update xham.py#70

Open
PandazNetwork wants to merge 1 commit into
5hojib:mainfrom
PandazNetwork:patch-2
Open

Update xham.py#70
PandazNetwork wants to merge 1 commit into
5hojib:mainfrom
PandazNetwork:patch-2

Conversation

@PandazNetwork
Copy link
Copy Markdown
Contributor

@PandazNetwork PandazNetwork commented Feb 18, 2026

API UPDATED !!

Summary by Sourcery

Switch XhamResolver to use the vidquickly API with xhamster1.desi as the canonical host and update link selection and error handling accordingly.

Enhancements:

  • Update XhamResolver to call the vidquickly API via GET instead of the EasyDownloader API and remove the API key dependency.
  • Change canonical domain normalization to xhamster1.desi and simplify URL handling.
  • Improve link selection by choosing the highest available quality based on numeric resolution parsed from link titles and always returning MP4 metadata.
  • Streamline error handling and JSON parsing failures into consistent ExtractionFailedException messages.

API UPDATED !!
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Feb 18, 2026

Reviewer's Guide

Switches the XhamResolver from the EasyDownloader POST API to the vidquickly GET API, simplifies canonical URL handling, and reworks link selection to choose the highest‑quality MP4 stream with a generated filename based on video metadata.

Sequence diagram for XhamResolver resolve flow using vidquickly GET API

sequenceDiagram
    actor Client
    participant XhamResolver
    participant vidquicklyAPI

    Client->>XhamResolver: resolve(url)
    XhamResolver->>XhamResolver: _normalize_to_canonical(url)
    XhamResolver->>vidquicklyAPI: GET API_URL + canonical_url

    alt HTTP status 200
        vidquicklyAPI-->>XhamResolver: JSON links[], videoDetails
        XhamResolver->>XhamResolver: _extract_quality(link.title) for each link
        XhamResolver->>XhamResolver: select best quality link
        XhamResolver->>XhamResolver: build filename from videoDetails.title or link_url
        XhamResolver-->>Client: LinkResult
    else Non 200 or parse error or no links
        vidquicklyAPI-->>XhamResolver: error or invalid JSON
        XhamResolver->>Client: raise ExtractionFailedException
    end
Loading

Updated class diagram for XhamResolver vidquickly migration

classDiagram
    class BaseResolver

    class ExtractionFailedException

    class LinkResult {
        +str url
        +str filename
        +str mime_type
        +int? size
    }

    class FolderResult

    class XhamResolver {
        +list~str~ DOMAINS
        +str API_URL
        +str CANONICAL_HOST
        +str _normalize_to_canonical(original_url)
        +int _extract_quality(title)
        +LinkResult|FolderResult resolve(url)
    }

    XhamResolver --|> BaseResolver
    XhamResolver ..> ExtractionFailedException
    XhamResolver ..> LinkResult
    XhamResolver ..> FolderResult
Loading

File-Level Changes

Change Details Files
Replace EasyDownloader POST-based integration with vidquickly GET-based integration and adjust error handling.
  • Change API_URL to vidquickly xhamster-get-link endpoint and remove API_KEY constant and payload construction.
  • Use _get with a fully composed query URL instead of _post with JSON body.
  • Update error messages to reference the vidquickly API and raise ExtractionFailedException directly instead of via helper method.
  • Simplify the top-level exception handler to wrap any error with a consistent ExtractionFailedException message and remove the _raise_extraction_failed helper.
src/truelink/resolvers/xham.py
Normalize xhamster URLs to the new canonical host and add quality extraction helper.
  • Update resolver docstring and CANONICAL_HOST to use xhamster1.desi instead of xhamster.desi.
  • Simplify _normalize_to_canonical to just replace the netloc with the canonical host when in the supported domain set.
  • Introduce _extract_quality helper that parses numeric quality (e.g., 720) from a link title string for ranking.
src/truelink/resolvers/xham.py
Adjust response parsing and stream selection to match vidquickly’s response shape and choose the best available MP4 link.
  • Parse links directly from data['links'] instead of from a nested final_urls structure, failing fast when links is empty or invalid.
  • Select the best link by taking the one with the highest numeric quality derived from its title, and ensure the chosen link has a URL.
  • Build a filename from videoDetails.title when present (sanitized and suffixed with .mp4), otherwise fall back to the basename of the link URL path.
  • Hardcode MIME type to video/mp4 and set size to None since the new API does not provide file size information.
src/truelink/resolvers/xham.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @PandazNetwork, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request updates the Xhamster resolver to adapt to a new API, ensuring continued functionality for extracting video links. The changes involve switching to a different API endpoint, refining the link selection process to prioritize higher quality, and improving how filenames are generated from the extracted content. This update is crucial for maintaining the resolver's ability to process xhamster variant URLs effectively.

Highlights

  • API Endpoint Update: The resolver has been updated to use a new API endpoint from vidquickly.com instead of api.easydownloader.app for extracting links from xhamster variants.
  • Link Extraction Logic Refinement: The logic for selecting the best quality link has been improved, now using a dedicated _extract_quality helper to parse resolution from titles and selecting the highest available quality.
  • Filename Generation Enhancement: Filename generation has been revised to prioritize the video title from the API response, sanitizing it for safe use, and falling back to the URL's basename if no title is available.
  • Code Simplification: The API_KEY constant and the _raise_extraction_failed helper method have been removed, simplifying the codebase.
Changelog
  • src/truelink/resolvers/xham.py
    • Updated the API endpoint from api.easydownloader.app to vidquickly.com.
    • Removed the API_KEY constant as it is no longer required by the new API.
    • Modified the CANONICAL_HOST to xhamster1.desi in the resolver's docstring and normalization logic.
    • Introduced a new private method _extract_quality to parse numeric quality from video titles.
    • Refactored the resolve method to use the new API's response structure, selecting the best quality link based on the _extract_quality method.
    • Adjusted filename generation to use the video title from the API response, sanitizing it, or falling back to the URL's basename.
    • Removed the _raise_extraction_failed helper method, inlining the exception raising.
Activity
  • No activity has occurred on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 4 issues, and left some high level feedback:

  • When building api_url by simple string concatenation (self.API_URL + canonical_url), the original URL is not URL-encoded, which can lead to malformed requests if it contains ?, &, or other reserved characters; consider using urllib.parse.quote or urlencode to safely embed the URL in the query string.
  • The _extract_quality helper currently grabs the first number in the title regardless of context, which may mis-rank links if the title contains other numbers (e.g., years or durations); consider tightening the pattern to something like r'(\d{3,4})p\b' or verifying the number is actually a resolution.
  • The broad except Exception as e at the end of resolve will catch and wrap existing ExtractionFailedExceptions, duplicating messages and obscuring their original meaning; consider either not catching ExtractionFailedException or re-raising it unchanged and only wrapping unexpected exception types.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- When building `api_url` by simple string concatenation (`self.API_URL + canonical_url`), the original URL is not URL-encoded, which can lead to malformed requests if it contains `?`, `&`, or other reserved characters; consider using `urllib.parse.quote` or `urlencode` to safely embed the URL in the query string.
- The `_extract_quality` helper currently grabs the first number in the title regardless of context, which may mis-rank links if the title contains other numbers (e.g., years or durations); consider tightening the pattern to something like `r'(\d{3,4})p\b'` or verifying the number is actually a resolution.
- The broad `except Exception as e` at the end of `resolve` will catch and wrap existing `ExtractionFailedException`s, duplicating messages and obscuring their original meaning; consider either not catching `ExtractionFailedException` or re-raising it unchanged and only wrapping unexpected exception types.

## Individual Comments

### Comment 1
<location> `src/truelink/resolvers/xham.py:61` </location>
<code_context>
-        }
+        canonical_url = self._normalize_to_canonical(url)
+
+        api_url = self.API_URL + canonical_url

         try:
</code_context>

<issue_to_address>
**issue (bug_risk):** Canonical URL should be URL-encoded before being appended to the API endpoint.

If `canonical_url` contains `&`, `?`, or other reserved characters, the API call will be malformed and parts of the URL may be treated as extra query parameters. Build the URL with proper encoding instead (e.g., `params={'url': canonical_url}` with `urlencode` / `requests`, or `urllib.parse.quote`), rather than concatenating the string directly.
</issue_to_address>

### Comment 2
<location> `src/truelink/resolvers/xham.py:79-82` </location>
<code_context>
+            links = data.get("links", [])
</code_context>

<issue_to_address>
**suggestion:** Error message claims no MP4 links, but the code never filters by MIME/extension.

The exception message asserts MP4 links specifically, but the code only checks whether `links` is non-empty, without validating that they are MP4s. This can mislead debugging when non-MP4 formats are returned. Either enforce MP4 selection (e.g., via URL or a `type` field) or change the message to reflect the actual check (e.g., “No links found”).
</issue_to_address>

### Comment 3
<location> `src/truelink/resolvers/xham.py:53-56` </location>
<code_context>
+
+        return original_url
+
+    def _extract_quality(self, title: str) -> int:
+        """Extract numeric quality from title like 'Video 720p'."""
+        match = re.search(r"(\d+)", title or "")
+        return int(match.group(1)) if match else 0

</code_context>

<issue_to_address>
**suggestion (bug_risk):** Quality extraction may pick unintended numbers (e.g. bitrates) and mis-rank links.

`re.search(r"(\d+)")` will return the first number in the title, which could be a duration, bitrate (e.g. `128kbps`), or other non-resolution value. That can cause incorrect ranking if a non-resolution number is larger than the actual resolution. If titles consistently encode resolution as `720p`, `1080p`, etc., consider a stricter pattern like `r"(\d{3,4})p"`, or otherwise choose the most likely resolution token (e.g. the last numeric token) instead of the first match.

```suggestion
    def _extract_quality(self, title: str) -> int:
        """Extract numeric quality from title like 'Video 720p'.

        Prefer explicit resolution patterns like '720p' or '1080p', and as a
        fallback, choose the last 3–4 digit numeric token which is most likely
        to represent the resolution rather than e.g. duration or bitrate.
        """
        if not title:
            return 0

        lowered = title.lower()

        # First, look for patterns like '720p', '1080p', etc.
        match = re.search(r"(\d{3,4})p\b", lowered)
        if match:
            return int(match.group(1))

        # Fallback: pick the last standalone 3–4 digit number token.
        candidates = re.findall(r"\b(\d{3,4})\b", lowered)
        if candidates:
            return int(candidates[-1])

        return 0
```
</issue_to_address>

### Comment 4
<location> `src/truelink/resolvers/xham.py:99-105` </location>
<code_context>
+                safe_title = re.sub(r"[^\w\-_. ]", "", title)
+                filename = f"{safe_title}.mp4"
+            else:
+                filename = basename(urlparse(link_url).path)
+
+            mime_type = "video/mp4"
</code_context>

<issue_to_address>
**suggestion:** Filename derivation from URL may yield an empty string for trailing-slash URLs.

For URLs with a trailing slash or no path, `basename(urlparse(link_url).path)` returns an empty string, which is then used as the filename. Consider falling back to `None` or a default name when this is empty so consumers don’t receive an invalid filename.

```suggestion
            if title:
                safe_title = re.sub(r"[^\w\-_. ]", "", title)
                filename = f"{safe_title}.mp4"
            else:
                # Derive filename from URL path; fall back to None for empty or trailing-slash URLs
                url_path = urlparse(link_url).path
                derived_filename = basename(url_path)
                filename = derived_filename or None

            mime_type = "video/mp4"
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/truelink/resolvers/xham.py
Comment thread src/truelink/resolvers/xham.py
Comment thread src/truelink/resolvers/xham.py
Comment thread src/truelink/resolvers/xham.py
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the XhamResolver to use the new vidquickly API, which is a great improvement. The changes simplify the implementation, remove a hardcoded API key, and introduce a more robust method for selecting the best video quality. The code is cleaner and more efficient.

I've added a couple of suggestions to further improve the code's maintainability and error handling structure. Specifically, I've pointed out an opportunity to define a constant at the class level to avoid recreation, and a way to refine the exception handling to avoid re-wrapping exceptions and produce clearer error messages.

Comment thread src/truelink/resolvers/xham.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant