feat: add multi-language support to rss2bsky via --lang flag
- Changed `post_lang: str` to `post_langs: List[str]` in `run_once` and `try_send_post_with_variants` to support multiple BCP-47 language tags passed to Bluesky's `langs=` field. - Updated `--lang` CLI argument to accept comma-separated language codes (e.g. `--lang ca,es`), parsed into a list at startup. Defaults to `["ca"]`. - Added startup log line reporting the configured language(s) per run.
This commit is contained in:
@@ -51,7 +51,8 @@ pipeline {
|
|||||||
"$BSKY_CRUNCHYROLL_HANDLE" \
|
"$BSKY_CRUNCHYROLL_HANDLE" \
|
||||||
"$TWITTER_CRUNCHY_EMAIL" \
|
"$TWITTER_CRUNCHY_EMAIL" \
|
||||||
"$BSKY_CRUNCHYROLL_APP_PASSWORD" \
|
"$BSKY_CRUNCHYROLL_APP_PASSWORD" \
|
||||||
--service "https://eurosky.social"
|
--service "https://eurosky.social" \
|
||||||
|
--lang es
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
33
rss2bsky.py
33
rss2bsky.py
@@ -806,7 +806,7 @@ def upload_blob_with_retry(
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def try_send_post_with_variants(client: Client, text_variants: List[str], embed, post_lang: str, cooldown_path: str, cfg: AppConfig):
|
def try_send_post_with_variants(client: Client, text_variants: List[str], embed, post_langs: List[str], cooldown_path: str, cfg: AppConfig):
|
||||||
if is_global_post_cooldown_active(cooldown_path):
|
if is_global_post_cooldown_active(cooldown_path):
|
||||||
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}")
|
||||||
@@ -819,9 +819,12 @@ 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)} "f"(length={len(variant)} chars)")
|
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_langs)
|
||||||
return result, variant
|
return result, variant
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -1144,15 +1147,13 @@ def login_with_backoff(
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def run_once(
|
def run_once(
|
||||||
rss_feed: str,
|
rss_feed: str,
|
||||||
bsky_handle: str,
|
bsky_handle: str,
|
||||||
bsky_username: str,
|
bsky_username: str,
|
||||||
bsky_password: str,
|
bsky_password: str,
|
||||||
service_url: str,
|
service_url: str,
|
||||||
post_lang: str,
|
post_langs: List[str], # ← changed from post_lang: str
|
||||||
state_path: str,
|
state_path: str,
|
||||||
cooldown_path: str,
|
cooldown_path: str,
|
||||||
cfg: AppConfig
|
cfg: AppConfig
|
||||||
@@ -1160,6 +1161,8 @@ def run_once(
|
|||||||
if not PIL_AVAILABLE:
|
if not PIL_AVAILABLE:
|
||||||
logging.warning("🟡 Pillow is not installed. External card thumbnail compression is disabled.")
|
logging.warning("🟡 Pillow is not installed. External card thumbnail compression is disabled.")
|
||||||
|
|
||||||
|
logging.info(f"🌍 Posting language(s): {post_langs}")
|
||||||
|
|
||||||
if check_post_cooldown_or_log(cooldown_path):
|
if check_post_cooldown_or_log(cooldown_path):
|
||||||
return RunResult(published_count=0, stopped_reason="global_post_cooldown_active")
|
return RunResult(published_count=0, stopped_reason="global_post_cooldown_active")
|
||||||
|
|
||||||
@@ -1245,7 +1248,7 @@ def run_once(
|
|||||||
client=client,
|
client=client,
|
||||||
text_variants=text_variants,
|
text_variants=text_variants,
|
||||||
embed=embed,
|
embed=embed,
|
||||||
post_lang=post_lang,
|
post_langs=post_langs, # ← changed
|
||||||
cooldown_path=cooldown_path,
|
cooldown_path=cooldown_path,
|
||||||
cfg=cfg
|
cfg=cfg
|
||||||
)
|
)
|
||||||
@@ -1296,7 +1299,6 @@ def run_once(
|
|||||||
|
|
||||||
return RunResult(published_count=published)
|
return RunResult(published_count=published)
|
||||||
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# CLI
|
# CLI
|
||||||
# ============================================================
|
# ============================================================
|
||||||
@@ -1309,11 +1311,22 @@ def main():
|
|||||||
parser.add_argument("bsky_username", help="Bluesky username")
|
parser.add_argument("bsky_username", help="Bluesky username")
|
||||||
parser.add_argument("bsky_app_password", help="Bluesky app password")
|
parser.add_argument("bsky_app_password", help="Bluesky app password")
|
||||||
parser.add_argument("--service", default="https://bsky.social", help="Bluesky server URL")
|
parser.add_argument("--service", default="https://bsky.social", help="Bluesky server URL")
|
||||||
parser.add_argument("--lang", default="ca", help="Language code for the post")
|
parser.add_argument(
|
||||||
|
"--lang",
|
||||||
|
default="ca",
|
||||||
|
help="Comma-separated language codes for Bluesky posts (default: ca). Example: ca,es",
|
||||||
|
)
|
||||||
parser.add_argument("--state-path", default=DEFAULT_STATE_PATH, help="Path to local JSON state file")
|
parser.add_argument("--state-path", default=DEFAULT_STATE_PATH, help="Path to local JSON state file")
|
||||||
parser.add_argument("--cooldown-path", default=DEFAULT_COOLDOWN_STATE_PATH, help="Path to shared cooldown JSON state file")
|
parser.add_argument("--cooldown-path", default=DEFAULT_COOLDOWN_STATE_PATH, help="Path to shared cooldown JSON state file")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Parse comma-separated langs: "ca,es" → ["ca", "es"]
|
||||||
|
post_langs = [lang.strip() for lang in args.lang.split(",") if lang.strip()]
|
||||||
|
if not post_langs:
|
||||||
|
post_langs = ["ca"]
|
||||||
|
|
||||||
|
logging.info(f"🌍 Using configured Bluesky language(s): {post_langs}")
|
||||||
|
|
||||||
cfg = AppConfig()
|
cfg = AppConfig()
|
||||||
|
|
||||||
run_once(
|
run_once(
|
||||||
@@ -1322,7 +1335,7 @@ def main():
|
|||||||
bsky_username=args.bsky_username,
|
bsky_username=args.bsky_username,
|
||||||
bsky_password=args.bsky_app_password,
|
bsky_password=args.bsky_app_password,
|
||||||
service_url=args.service,
|
service_url=args.service,
|
||||||
post_lang=args.lang,
|
post_langs=post_langs, # ← changed
|
||||||
state_path=args.state_path,
|
state_path=args.state_path,
|
||||||
cooldown_path=args.cooldown_path,
|
cooldown_path=args.cooldown_path,
|
||||||
cfg=cfg
|
cfg=cfg
|
||||||
|
|||||||
Reference in New Issue
Block a user