indented and fixed
This commit is contained in:
@@ -2819,7 +2819,6 @@ def candidate_matches_existing_bsky(candidate, recent_bsky_posts):
|
|||||||
|
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
|
|
||||||
# --- Main Sync Logic ---
|
# --- Main Sync Logic ---
|
||||||
def sync_feeds(args):
|
def sync_feeds(args):
|
||||||
logging.info("🔄 Starting sync cycle...")
|
logging.info("🔄 Starting sync cycle...")
|
||||||
@@ -3202,149 +3201,144 @@ def sync_feeds(args):
|
|||||||
"posted. Skipping photo fallback for this tweet."
|
"posted. Skipping photo fallback for this tweet."
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if tweet.media:
|
if tweet.media:
|
||||||
for media in tweet.media:
|
for media in tweet.media:
|
||||||
if media.type == "photo":
|
if media.type == "photo":
|
||||||
blob = get_blob_from_url(
|
blob = get_blob_from_url(
|
||||||
media.media_url_https,
|
media.media_url_https,
|
||||||
bsky_client,
|
bsky_client,
|
||||||
media_http_client,
|
media_http_client,
|
||||||
)
|
)
|
||||||
if blob:
|
if blob:
|
||||||
image_embeds.append(
|
image_embeds.append(
|
||||||
models.AppBskyEmbedImages.Image(
|
models.AppBskyEmbedImages.Image(
|
||||||
alt=dynamic_alt,
|
alt=dynamic_alt,
|
||||||
image=blob,
|
image=blob,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
media_upload_failures.append(
|
||||||
|
f"photo:{media.media_url_https}"
|
||||||
)
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
media_upload_failures.append(
|
|
||||||
f"photo:{media.media_url_https}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# --- External link card logic ---
|
# --- External link card logic ---
|
||||||
if not video_embed and not image_embeds:
|
if not video_embed and not image_embeds:
|
||||||
candidate_url = candidate.get("resolved_primary_external_url")
|
candidate_url = candidate.get("resolved_primary_external_url")
|
||||||
|
|
||||||
if candidate_url:
|
if candidate_url:
|
||||||
if candidate.get("looks_like_title_plus_url"):
|
if candidate.get("looks_like_title_plus_url"):
|
||||||
logging.info(
|
logging.info(
|
||||||
f"🔗 Detected title+URL post style. "
|
f"🔗 Detected title+URL post style. "
|
||||||
f"Using resolved URL for external card: {candidate_url}"
|
f"Using resolved URL for external card: {candidate_url}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logging.info(
|
||||||
|
f"🔗 Using resolved first external URL for "
|
||||||
|
f"external card: {candidate_url}"
|
||||||
|
)
|
||||||
|
|
||||||
|
external_embed = build_external_link_embed(
|
||||||
|
candidate_url,
|
||||||
|
bsky_client,
|
||||||
|
media_http_client,
|
||||||
|
fallback_title="Link",
|
||||||
|
prefetched_metadata=link_meta_for_alt or None,
|
||||||
|
)
|
||||||
|
|
||||||
|
if external_embed:
|
||||||
|
logging.info(
|
||||||
|
f"✅ Built external link card for URL: {candidate_url}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logging.info(
|
||||||
|
f"ℹ️ Could not build external link card metadata "
|
||||||
|
f"for URL: {candidate_url}"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
post_result = None
|
||||||
|
post_mode = "text"
|
||||||
|
|
||||||
|
if video_embed:
|
||||||
|
post_result = send_post_with_retry(
|
||||||
|
bsky_client,
|
||||||
|
text=rich_text,
|
||||||
|
embed=video_embed,
|
||||||
|
langs=bsky_langs,
|
||||||
|
)
|
||||||
|
post_mode = "video"
|
||||||
|
elif image_embeds:
|
||||||
|
embed = models.AppBskyEmbedImages.Main(images=image_embeds)
|
||||||
|
post_result = send_post_with_retry(
|
||||||
|
bsky_client,
|
||||||
|
text=rich_text,
|
||||||
|
embed=embed,
|
||||||
|
langs=bsky_langs,
|
||||||
|
)
|
||||||
|
post_mode = f"images:{len(image_embeds)}"
|
||||||
|
elif external_embed:
|
||||||
|
post_result = send_post_with_retry(
|
||||||
|
bsky_client,
|
||||||
|
text=rich_text,
|
||||||
|
embed=external_embed,
|
||||||
|
langs=bsky_langs,
|
||||||
|
)
|
||||||
|
post_mode = "external_link_card"
|
||||||
|
else:
|
||||||
|
post_result = send_post_with_retry(
|
||||||
|
bsky_client,
|
||||||
|
text=rich_text,
|
||||||
|
langs=bsky_langs,
|
||||||
|
)
|
||||||
|
post_mode = "text_only"
|
||||||
|
|
||||||
|
bsky_uri = getattr(post_result, "uri", None)
|
||||||
|
|
||||||
|
remember_posted_tweet(state, candidate, bsky_uri=bsky_uri)
|
||||||
|
state = prune_state(state, max_entries=5000)
|
||||||
|
save_state(state, STATE_PATH)
|
||||||
|
|
||||||
|
recent_bsky_posts.insert(
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
"uri": bsky_uri,
|
||||||
|
"text": raw_text,
|
||||||
|
"normalized_text": candidate["normalized_text"],
|
||||||
|
"canonical_non_x_urls": candidate["canonical_non_x_urls"],
|
||||||
|
"media_fingerprint": candidate["media_fingerprint"],
|
||||||
|
"text_media_key": candidate["text_media_key"],
|
||||||
|
"created_at": arrow.utcnow().isoformat(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
recent_bsky_posts = recent_bsky_posts[:DEDUPE_BSKY_LIMIT]
|
||||||
|
|
||||||
|
new_posts += 1
|
||||||
|
|
||||||
|
if media_upload_failures:
|
||||||
|
logging.warning(
|
||||||
|
f"✅ Posted tweet to Bluesky with degraded media "
|
||||||
|
f"mode ({post_mode}). "
|
||||||
|
f"Failed media items: {media_upload_failures}"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logging.info(
|
logging.info(
|
||||||
f"🔗 Using resolved first external URL for "
|
f"✅ Posted new tweet to Bluesky with mode "
|
||||||
f"external card: {candidate_url}"
|
f"{post_mode}: {raw_text}"
|
||||||
)
|
)
|
||||||
|
|
||||||
external_embed = build_external_link_embed(
|
time.sleep(5)
|
||||||
candidate_url,
|
|
||||||
bsky_client,
|
|
||||||
media_http_client,
|
|
||||||
fallback_title="Link",
|
|
||||||
prefetched_metadata=link_meta_for_alt or None,
|
|
||||||
)
|
|
||||||
|
|
||||||
if external_embed:
|
|
||||||
logging.info(
|
|
||||||
f"✅ Built external link card for URL: {candidate_url}"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
logging.info(
|
|
||||||
f"ℹ️ Could not build external link card metadata "
|
|
||||||
f"for URL: {candidate_url}"
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
post_result = None
|
|
||||||
post_mode = "text"
|
|
||||||
|
|
||||||
if video_embed:
|
|
||||||
post_result = send_post_with_retry(
|
|
||||||
bsky_client,
|
|
||||||
text=rich_text,
|
|
||||||
embed=video_embed,
|
|
||||||
langs=bsky_langs,
|
|
||||||
)
|
|
||||||
post_mode = "video"
|
|
||||||
elif image_embeds:
|
|
||||||
embed = models.AppBskyEmbedImages.Main(images=image_embeds)
|
|
||||||
post_result = send_post_with_retry(
|
|
||||||
bsky_client,
|
|
||||||
text=rich_text,
|
|
||||||
embed=embed,
|
|
||||||
langs=bsky_langs,
|
|
||||||
)
|
|
||||||
post_mode = f"images:{len(image_embeds)}"
|
|
||||||
elif external_embed:
|
|
||||||
post_result = send_post_with_retry(
|
|
||||||
bsky_client,
|
|
||||||
text=rich_text,
|
|
||||||
embed=external_embed,
|
|
||||||
langs=bsky_langs,
|
|
||||||
)
|
|
||||||
post_mode = "external_link_card"
|
|
||||||
else:
|
|
||||||
post_result = send_post_with_retry(
|
|
||||||
bsky_client,
|
|
||||||
text=rich_text,
|
|
||||||
langs=bsky_langs,
|
|
||||||
)
|
|
||||||
post_mode = "text_only"
|
|
||||||
|
|
||||||
bsky_uri = getattr(post_result, "uri", None)
|
|
||||||
|
|
||||||
remember_posted_tweet(state, candidate, bsky_uri=bsky_uri)
|
|
||||||
state = prune_state(state, max_entries=5000)
|
|
||||||
save_state(state, STATE_PATH)
|
|
||||||
|
|
||||||
recent_bsky_posts.insert(
|
|
||||||
0,
|
|
||||||
{
|
|
||||||
"uri": bsky_uri,
|
|
||||||
"text": raw_text,
|
|
||||||
"normalized_text": candidate["normalized_text"],
|
|
||||||
"canonical_non_x_urls": candidate["canonical_non_x_urls"],
|
|
||||||
"media_fingerprint": candidate["media_fingerprint"],
|
|
||||||
"text_media_key": candidate["text_media_key"],
|
|
||||||
"created_at": arrow.utcnow().isoformat(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
recent_bsky_posts = recent_bsky_posts[:DEDUPE_BSKY_LIMIT]
|
|
||||||
|
|
||||||
new_posts += 1
|
|
||||||
|
|
||||||
if media_upload_failures:
|
|
||||||
logging.warning(
|
|
||||||
f"✅ Posted tweet to Bluesky with degraded media "
|
|
||||||
f"mode ({post_mode}). "
|
|
||||||
f"Failed media items: {media_upload_failures}"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
logging.info(
|
|
||||||
f"✅ Posted new tweet to Bluesky with mode "
|
|
||||||
f"{post_mode}: {raw_text}"
|
|
||||||
)
|
|
||||||
|
|
||||||
time.sleep(5)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logging.error(f"❌ Failed to post tweet to Bluesky: {e}")
|
|
||||||
|
|
||||||
browser.close()
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"❌ Failed to post tweet to Bluesky: {e}")
|
logging.error(f"❌ Failed to post tweet to Bluesky: {e}")
|
||||||
|
|
||||||
# Closes the Playwright browser (Indented 12 spaces, matches 'browser = ...')
|
# Closes Playwright browser (Indented 12 spaces, matches 'browser = ...')
|
||||||
browser.close()
|
browser.close()
|
||||||
|
|
||||||
# Logs the final count (Indented 8 spaces, matches the 'with sync_playwright():' block)
|
# Logs final count (Indented 8 spaces, inside the main 'try' block)
|
||||||
logging.info(f"✅ Sync complete. Posted {new_posts} new updates.")
|
logging.info(f"✅ Sync complete. Posted {new_posts} new updates.")
|
||||||
|
|
||||||
# Catches fatal sync errors (Indented 4 spaces, matches the 'try:' at the very top of sync_feeds)
|
# Catches fatal sync errors (Indented 4 spaces, matches the 'try:' at the top of sync_feeds)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"❌ Error during sync cycle: {e}")
|
logging.error(f"❌ Error during sync cycle: {e}")
|
||||||
|
|
||||||
@@ -3431,3 +3425,4 @@ def main():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user