Added length in RSS

This commit is contained in:
Guillem Hernandez Sola
2026-04-24 09:27:25 +02:00
parent 1691a15904
commit 90938f65b4

View File

@@ -37,7 +37,7 @@ DEFAULT_COOLDOWN_STATE_PATH = "rss2bsky_cooldowns.json"
@dataclass(frozen=True) @dataclass(frozen=True)
class LimitsConfig: class LimitsConfig:
dedupe_bsky_limit: int = 30 dedupe_bsky_limit: int = 30
bsky_text_max_length: int = 275 bsky_text_max_length: int = 300
external_thumb_max_bytes: int = 750 * 1024 external_thumb_max_bytes: int = 750 * 1024
external_thumb_target_bytes: int = 500 * 1024 external_thumb_target_bytes: int = 500 * 1024
@@ -402,7 +402,7 @@ def process_title(title: str) -> str:
return title_text return title_text
def build_post_text_variants(title_text: str, link: str): def build_post_text_variants(title_text: str, link: str, max_length: int = 300):
title_text = clean_whitespace(title_text) title_text = clean_whitespace(title_text)
link = canonicalize_url(link) or link or "" link = canonicalize_url(link) or link or ""
@@ -415,16 +415,34 @@ def build_post_text_variants(title_text: str, link: str):
seen.add(cleaned) seen.add(cleaned)
variants.append(cleaned) variants.append(cleaned)
# Variant 1: títol + link (si cap sencer)
if title_text and link: if title_text and link:
add_variant(f"{title_text}\n\n{link}") full = f"{title_text}\n\n{link}"
if len(full) <= max_length:
add_variant(full)
else:
# Trunca el títol per fer-hi lloc al link
# Reserva espai per "\n\n" + link
reserve = len(link) + 2
available = max_length - reserve
if available > 20:
truncated_title = title_text[:available - 3].rstrip() + "..."
add_variant(f"{truncated_title}\n\n{link}")
# Variant 2: només títol (truncat si cal)
if title_text: if title_text:
add_variant(title_text) if len(title_text) <= max_length:
add_variant(title_text)
else:
truncated = title_text[:max_length - 3].rstrip() + "..."
add_variant(truncated)
# Variant 3: només link (si no hi ha títol)
if link and not title_text: if link and not title_text:
add_variant(link) add_variant(link)
return variants return variants
def is_x_or_twitter_domain(url: str) -> bool: def is_x_or_twitter_domain(url: str) -> bool:
try: try:
hostname = (urlparse(url).hostname or "").lower() hostname = (urlparse(url).hostname or "").lower()
@@ -800,7 +818,7 @@ def try_send_post_with_variants(client: Client, text_variants: List[str], embed,
reset_str = format_cooldown_until(get_global_post_cooldown_until(cooldown_path)) reset_str = format_cooldown_until(get_global_post_cooldown_until(cooldown_path))
raise RuntimeError(f"Posting skipped because global post cooldown is active until {reset_str}") raise RuntimeError(f"Posting skipped because global post cooldown is active until {reset_str}")
logging.info(f"📝 Trying post text variant {idx}/{len(text_variants)} (length={len(variant)})") logging.info(f"📝 Trying post text variant {idx}/{len(text_variants)} "f"(length={len(variant)} chars)")
rich_text = make_rich(variant) rich_text = make_rich(variant)
result = client.send_post(text=rich_text, embed=embed, langs=[post_lang]) result = client.send_post(text=rich_text, embed=embed, langs=[post_lang])
return result, variant return result, variant
@@ -1019,7 +1037,7 @@ def fetch_feed_content(feed_url: str, http_client: httpx.Client, cfg: AppConfig)
return response.content.decode("utf-8", errors="ignore") return response.content.decode("utf-8", errors="ignore")
def build_candidates_from_feed(feed) -> List[EntryCandidate]: def build_candidates_from_feed(feed, max_length: int = 300) -> List[EntryCandidate]:
candidates: List[EntryCandidate] = [] candidates: List[EntryCandidate] = []
for item in getattr(feed, "entries", []): for item in getattr(feed, "entries", []):
@@ -1043,7 +1061,7 @@ def build_candidates_from_feed(feed) -> List[EntryCandidate]:
published_at=published_at.isoformat() if published_at else None, published_at=published_at.isoformat() if published_at else None,
published_arrow=published_at, published_arrow=published_at,
entry_fingerprint=entry_fingerprint, entry_fingerprint=entry_fingerprint,
post_text_variants=build_post_text_variants(title_text, link), post_text_variants=build_post_text_variants(title_text, link, max_length=max_length),
)) ))
except Exception as e: except Exception as e:
@@ -1168,7 +1186,7 @@ def run_once(
with httpx.Client() as http_client: with httpx.Client() as http_client:
feed_content = fetch_feed_content(rss_feed, http_client, cfg) feed_content = fetch_feed_content(rss_feed, http_client, cfg)
feed = fastfeedparser.parse(feed_content) feed = fastfeedparser.parse(feed_content)
candidates = build_candidates_from_feed(feed) candidates = build_candidates_from_feed(feed, max_length=cfg.limits.bsky_text_max_length)
logging.info(f"📰 Prepared {len(candidates)} feed entry candidates for duplicate comparison.") logging.info(f"📰 Prepared {len(candidates)} feed entry candidates for duplicate comparison.")