Merge pull request 'fix(extension): Add-to-FC button on subscribed Patreon creators + v1.0.8 (#1485)' (#230) from dev into main
CI / lint (push) Successful in 3s
Build images / build-agent (push) Successful in 8s
Build images / build-ml (push) Successful in 8s
extension / lint (push) Successful in 8s
CI / frontend-build (push) Successful in 20s
CI / backend-lint-and-test (push) Successful in 30s
CI / integration (push) Successful in 3m46s
Build images / sign-extension (push) Successful in 5m8s
Build images / build-web (push) Successful in 10s
CI / lint (push) Successful in 3s
Build images / build-agent (push) Successful in 8s
Build images / build-ml (push) Successful in 8s
extension / lint (push) Successful in 8s
CI / frontend-build (push) Successful in 20s
CI / backend-lint-and-test (push) Successful in 30s
CI / integration (push) Successful in 3m46s
Build images / sign-extension (push) Successful in 5m8s
Build images / build-web (push) Successful in 10s
This commit was merged in pull request #230.
This commit is contained in:
@@ -35,9 +35,14 @@ class InvalidUrlError(Exception):
|
||||
# reviewers catch drift.
|
||||
_PLATFORM_PATTERNS: list[tuple[str, re.Pattern[str]]] = [
|
||||
("patreon", re.compile(
|
||||
# Three creator URL shapes — bare (patreon.com/Atole), `c/`, and `cw/`
|
||||
# (the "creator workspace" URL served once subscribed, see
|
||||
# patreon_resolver._VANITY_RE). A trailing sub-path is allowed so a
|
||||
# creator's inner page still derives the slug. Nav pages stay excluded.
|
||||
r"^https?://(?:www\.)?patreon\.com/"
|
||||
r"(?!home$|search\b|messages\b|notifications\b|library\b|settings\b|posts\b|c/)"
|
||||
r"(?P<slug>[^/?#]+)/?$",
|
||||
r"(?:cw/|c/)?"
|
||||
r"(?!(?:home|search|messages|notifications|library|settings|posts)(?:[/?#]|$))"
|
||||
r"(?P<slug>[^/?#]+)",
|
||||
re.IGNORECASE,
|
||||
)),
|
||||
("subscribestar", re.compile(
|
||||
|
||||
@@ -86,7 +86,16 @@ const PLATFORMS = {
|
||||
* script to decide whether to show the floating "Add as source" button.
|
||||
*/
|
||||
const PLATFORM_ARTIST_PATTERNS = {
|
||||
patreon: /^https?:\/\/(www\.)?patreon\.com\/(?!home$|search\b|messages\b|notifications\b|library\b|settings\b|posts\b|c\/)[^/?#]+\/?$/i,
|
||||
// Patreon serves the same creator under three URL shapes (see backend
|
||||
// patreon_resolver._VANITY_RE): bare `patreon.com/Atole`, `c/` prefix, and
|
||||
// `cw/` "creator workspace" — the last is the URL you land on once you're
|
||||
// SUBSCRIBED, which is exactly when the button matters. Match all three, and
|
||||
// drop the single-segment end-anchor so a creator's inner page
|
||||
// (…/cw/Atole/posts, …/Atole/membership) also injects the button. Nav pages
|
||||
// (home/search/…/posts permalink) stay excluded. Mirrors extension_service
|
||||
// ._PLATFORM_PATTERNS — keep in sync (operator-flagged 2026-07-13: button
|
||||
// vanished once subscribed because the old pattern only matched the bare root).
|
||||
patreon: /^https?:\/\/(www\.)?patreon\.com\/(?:cw\/|c\/)?(?!(?:home|search|messages|notifications|library|settings|posts)(?:[\/?#]|$))[^/?#]+/i,
|
||||
subscribestar: /^https?:\/\/(www\.)?subscribestar\.(com|adult)\/(?!feed$|messages$|library$)[^/?#]+\/?$/i,
|
||||
hentaifoundry: /^https?:\/\/(www\.)?hentai-foundry\.com\/user\/[^/?#]+/i,
|
||||
deviantart: /^https?:\/\/(www\.)?deviantart\.com\/(?!home$|watch\b|tag\b|browse\b)[^/?#]+\/?$/i,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "FabledCurator",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.8",
|
||||
"description": "Export cookies from supported platforms to FabledCurator and add creators as sources in one click.",
|
||||
|
||||
"browser_specific_settings": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fabledcurator-extension",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.8",
|
||||
"private": true,
|
||||
"description": "Firefox extension for FabledCurator",
|
||||
"scripts": {
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
"""Unit tests for ExtensionService._derive — the URL → (platform, slug)
|
||||
parser that gates the browser extension's "Add as source" button and pulls
|
||||
the creator slug on probe/add.
|
||||
|
||||
Regression cover for #1485: Patreon serves the same creator under three URL
|
||||
shapes — bare `patreon.com/Atole`, `c/`, and `cw/` (the "creator workspace"
|
||||
URL you land on once SUBSCRIBED). The button used to vanish while subscribed
|
||||
because the pattern only matched the bare root and excluded `c/`.
|
||||
|
||||
_derive is pure URL parsing (no DB / no async), so a session-less instance is
|
||||
fine to exercise directly.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from backend.app.services.extension_service import (
|
||||
ExtensionService,
|
||||
InvalidUrlError,
|
||||
UnknownPlatformError,
|
||||
)
|
||||
|
||||
_svc = ExtensionService(None)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"url, slug",
|
||||
[
|
||||
# All three Patreon creator prefixes resolve to the same vanity slug.
|
||||
("https://www.patreon.com/Atole", "Atole"),
|
||||
("https://www.patreon.com/c/Atole", "Atole"),
|
||||
("https://www.patreon.com/cw/Atole", "Atole"), # subscribed-view URL
|
||||
# A creator's inner page still derives the slug (trailing sub-path).
|
||||
("https://www.patreon.com/cw/Atole/posts", "Atole"),
|
||||
("https://www.patreon.com/Atole/membership", "Atole"),
|
||||
("https://patreon.com/c/Atole", "Atole"), # bare host, no www
|
||||
],
|
||||
)
|
||||
def test_derive_patreon_creator_urls(url, slug):
|
||||
platform, got = _svc._derive(url)
|
||||
assert platform == "patreon"
|
||||
assert got == slug
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"url",
|
||||
[
|
||||
# Patreon's own nav pages must never read as a creator slug.
|
||||
"https://www.patreon.com/home",
|
||||
"https://www.patreon.com/settings",
|
||||
"https://www.patreon.com/search",
|
||||
"https://www.patreon.com/messages",
|
||||
"https://www.patreon.com/library",
|
||||
"https://www.patreon.com/notifications",
|
||||
"https://www.patreon.com/posts/12345", # post permalink
|
||||
"https://www.patreon.com/settings/billing", # nav sub-page
|
||||
],
|
||||
)
|
||||
def test_derive_patreon_nav_pages_rejected(url):
|
||||
with pytest.raises(UnknownPlatformError):
|
||||
_svc._derive(url)
|
||||
|
||||
|
||||
def test_derive_rejects_missing_scheme():
|
||||
with pytest.raises(InvalidUrlError):
|
||||
_svc._derive("patreon.com/Atole")
|
||||
Reference in New Issue
Block a user