diff --git a/atproto/models.py b/atproto/models.py index 8cc7811..aba16cb 100644 --- a/atproto/models.py +++ b/atproto/models.py @@ -1,3 +1,4 @@ +import json from abc import ABC, abstractmethod from dataclasses import dataclass, field from typing import Any @@ -7,6 +8,16 @@ URI = "at://" URI_LEN = len(URI) +def cid_from_json(data: str | None) -> str | None: + if not data: + return None + + try: + return str(json.loads(data)["cid"]) + except (json.JSONDecodeError, AttributeError, KeyError): + return None + + class AtUri: @classmethod def record_uri(cls, uri: str) -> tuple[str, str, str]: diff --git a/bluesky/output.py b/bluesky/output.py index 3a290da..f4d5829 100644 --- a/bluesky/output.py +++ b/bluesky/output.py @@ -14,6 +14,7 @@ from atproto.models import ( SelfLabel, SelfLabels, StrongRef, + cid_from_json, ) from atproto.store import get_store from bluesky.client import BlueskyClient @@ -224,16 +225,10 @@ class BlueskyOutputService(BlueskyService, OutputService): self.log.error("Skipping '%s': failed to fetch parent posts from db") return - try: - root_cid_data = root_post["extra_data"] - root_cid = ( - json.loads(root_cid_data).get("cid", "") if root_cid_data else "" - ) - reply_cid_data = reply_post["extra_data"] - reply_cid = ( - json.loads(reply_cid_data).get("cid", "") if reply_cid_data else "" - ) - except (json.JSONDecodeError, AttributeError, KeyError): + root_cid = cid_from_json(root_post["extra_data"]) + reply_cid = cid_from_json(reply_post["extra_data"]) + + if not root_cid or not reply_cid: self.log.error("Skipping '%s': failed to parse CID from db") return @@ -318,30 +313,19 @@ class BlueskyOutputService(BlueskyService, OutputService): ) if not quoted_post: self.log.error("Skipping '%s': quoted post not found in db!") - else: - quoted_mappings = self._get_mappings( - quoted_post["id"], self.url, self.did - ) - if not quoted_mappings: - self.log.error( - "Skipping '%s': failed to find mappings for quoted post" - ) - else: - bluesky_quoted_post = self._get_post( - self.url, self.did, quoted_mappings[0]["identifier"] - ) - if not bluesky_quoted_post: - self.log.error( - "Skipping '%s': Failed to find Bluesky quoted post!" - ) - else: - quoted_cid_data = bluesky_quoted_post["extra_data"] - quoted_cid = ( - json.loads(quoted_cid_data).get("cid", "") - if quoted_cid_data - else "" - ) - quoted_uri = quoted_mappings[0]["identifier"] + return + + quoted_mappings = self._get_mappings(quoted_post["id"], self.url, self.did) + if not quoted_mappings: + self.log.error("Skipping '%s': failed to find mappings for quoted post") + return + + quoted_cid = cid_from_json(quoted_mappings[0]["extra_data"]) + if not quoted_cid: + self.log.error("Skipping '%s': failed to parse CID from db") + return + + quoted_uri = quoted_mappings[0]["identifier"] splitter = TokenSplitter(max_chars=300, max_link_len=30) token_blocks = splitter.split(tokens) @@ -583,9 +567,8 @@ class BlueskyOutputService(BlueskyService, OutputService): if not mappings: return - try: - cid = json.loads(mappings[0]["extra_data"])["cid"] - except (json.JSONDecodeError, AttributeError, KeyError): + cid = cid_from_json(mappings[0]["extra_data"]) + if not cid: self.log.exception("Skipping '%s': failed to parse CID from extra_data") return