Skip to content

feat(Clips4Sale): reimplement Clips4Sale scraper in python#2631

Merged
feederbox826 merged 5 commits intostashapp:masterfrom
xantror:xantror/update-clips4sale
Feb 21, 2026
Merged

feat(Clips4Sale): reimplement Clips4Sale scraper in python#2631
feederbox826 merged 5 commits intostashapp:masterfrom
xantror:xantror/update-clips4sale

Conversation

@xantror
Copy link
Copy Markdown
Contributor

@xantror xantror commented Dec 28, 2025

Scraper type(s)

  • performerByName
  • performerByFragment
  • performerByURL
  • sceneByName
  • sceneByQueryFragment
  • sceneByFragment
  • sceneByURL

Short description

  • Reimplemented Clips4Sale scraper in python, update needed to deal with new fields (tags bleeding into performers, etc.)
  • Added support for scraping performers.
  • Discussion on Discord

Merge after: #2628

Signed-off-by: xantror <69341873+xantror@users.noreply.github.com>
Signed-off-by: xantror <69341873+xantror@users.noreply.github.com>
…base64 options

Signed-off-by: xantror <69341873+xantror@users.noreply.github.com>
Signed-off-by: xantror <69341873+xantror@users.noreply.github.com>
@xantror xantror force-pushed the xantror/update-clips4sale branch from 45d9baf to 00ff0c0 Compare December 28, 2025 14:46
@DogmaDragon

This comment was marked as resolved.

Copy link
Copy Markdown
Member

@feederbox826 feederbox826 left a comment

Choose a reason for hiding this comment

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

A lot of really odd and inconsistent style choices

text = str(text)
# Unescape HTML entities first (e.g. &lt;br&gt; -> <br>)
text = html.unescape(text)
text = re.sub(r'data-\w+="[^"]*"\s*', "", text)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why strip data attributes if you're just going to get_text()?

Comment thread scrapers/Clips4Sale/Clips4Sale.py Outdated
Comment thread scrapers/Clips4Sale/Clips4Sale.py Outdated
if p_tags := p_data.get("tags"):
performer["tags"] = p_tags
else:
performer["urls"] = [performer_url]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

performer[urls] is in both conditions, why nest it?

if lower not in unique_tags:
unique_tags[lower] = original
else:
# Prefer the version with more uppercase letters
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why?

res["tags"] = tags
if performers:
res["performers"] = performers
return res
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why switch up nullish check style? stash handles it just fine if it's given NoneType

if details := clean_text(dig(clip, "description")):
scene["details"] = details

scene["studio"] = studio_obj
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

see comment above on nullish typings

Comment thread scrapers/Clips4Sale/Clips4Sale.py Outdated
Comment thread scrapers/Clips4Sale/Clips4Sale.py Outdated
Comment thread scrapers/Clips4Sale/Clips4Sale.py Outdated
use response.ok instead of checking status code
@feederbox826 feederbox826 merged commit 91d1e11 into stashapp:master Feb 21, 2026
1 check passed
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.

3 participants