diff --git a/squeaknode/admin/messages.py b/squeaknode/admin/messages.py index 984c8c02..4e9666af 100644 --- a/squeaknode/admin/messages.py +++ b/squeaknode/admin/messages.py @@ -12,7 +12,7 @@ from squeaknode.core.received_payment_summary import ReceivedPaymentSummary from squeaknode.core.sent_offer import SentOffer from squeaknode.core.sent_payment import SentPayment from squeaknode.core.sent_payment_summary import SentPaymentSummary -from squeaknode.core.squeak_entry_with_profile import SqueakEntryWithProfile +from squeaknode.core.squeak_entry import SqueakEntry from squeaknode.core.squeak_peer import SqueakPeer from squeaknode.core.squeak_profile import SqueakProfile from squeaknode.network.peer import Peer @@ -22,13 +22,9 @@ logger = logging.getLogger(__name__) DEFAULT_PROFILE_IMAGE = load_default_profile_image() -# TODO: Remove this after reply is nullable column -# EMPTY_HASH = b'\x00' * 32 - -def squeak_entry_to_message(squeak_entry_with_profile: SqueakEntryWithProfile) -> squeak_admin_pb2.SqueakDisplayEntry: - squeak_entry = squeak_entry_with_profile.squeak_entry - squeak_profile = squeak_entry_with_profile.squeak_profile +def squeak_entry_to_message(squeak_entry: SqueakEntry) -> squeak_admin_pb2.SqueakDisplayEntry: + squeak_profile = squeak_entry.squeak_profile is_reply = bool(squeak_entry.reply_to) reply_to = squeak_entry.reply_to.hex() if squeak_entry.reply_to else None is_author_known = False diff --git a/squeaknode/admin/squeak_admin_server_handler.py b/squeaknode/admin/squeak_admin_server_handler.py index a897f6b3..0dd61ed5 100644 --- a/squeaknode/admin/squeak_admin_server_handler.py +++ b/squeaknode/admin/squeak_admin_server_handler.py @@ -267,33 +267,33 @@ class SqueakAdminServerHandler(object): squeak_hash = bytes.fromhex(squeak_hash_str) logger.info( "Handle get squeak display entry for hash: {}".format(squeak_hash_str)) - squeak_entry_with_profile = ( - self.squeak_controller.get_squeak_entry_with_profile( + squeak_entry = ( + self.squeak_controller.get_squeak_entry( squeak_hash ) ) - if squeak_entry_with_profile is None: + if squeak_entry is None: return squeak_admin_pb2.GetSqueakDisplayReply( squeak_display_entry=None ) display_message = squeak_entry_to_message( - squeak_entry_with_profile) + squeak_entry) return squeak_admin_pb2.GetSqueakDisplayReply( squeak_display_entry=display_message ) def handle_get_timeline_squeak_display_entries(self, request): logger.info("Handle get timeline squeak display entries.") - squeak_entries_with_profile = ( - self.squeak_controller.get_timeline_squeak_entries_with_profile() + squeak_entries = ( + self.squeak_controller.get_timeline_squeak_entries() ) logger.info( "Got number of timeline squeak entries: {}".format( - len(squeak_entries_with_profile) + len(squeak_entries) ) ) squeak_display_msgs = [ - squeak_entry_to_message(entry) for entry in squeak_entries_with_profile + squeak_entry_to_message(entry) for entry in squeak_entries ] return squeak_admin_pb2.GetTimelineSqueakDisplaysReply( squeak_display_entries=squeak_display_msgs @@ -305,8 +305,8 @@ class SqueakAdminServerHandler(object): max_block = sys.maxsize logger.info( "Handle get squeak display entries for address: {}".format(address)) - squeak_entries_with_profile = ( - self.squeak_controller.get_squeak_entries_with_profile_for_address( + squeak_entries = ( + self.squeak_controller.get_squeak_entries_for_address( address, min_block, max_block, @@ -314,11 +314,11 @@ class SqueakAdminServerHandler(object): ) logger.info( "Got number of squeak entries for address: {}".format( - len(squeak_entries_with_profile) + len(squeak_entries) ) ) squeak_display_msgs = [ - squeak_entry_to_message(entry) for entry in squeak_entries_with_profile + squeak_entry_to_message(entry) for entry in squeak_entries ] return squeak_admin_pb2.GetAddressSqueakDisplaysReply( squeak_display_entries=squeak_display_msgs @@ -332,18 +332,18 @@ class SqueakAdminServerHandler(object): squeak_hash_str ) ) - squeak_entries_with_profile = ( - self.squeak_controller.get_ancestor_squeak_entries_with_profile( + squeak_entries = ( + self.squeak_controller.get_ancestor_squeak_entries( squeak_hash, ) ) logger.info( "Got number of ancestor squeak entries: {}".format( - len(squeak_entries_with_profile) + len(squeak_entries) ) ) squeak_display_msgs = [ - squeak_entry_to_message(entry) for entry in squeak_entries_with_profile + squeak_entry_to_message(entry) for entry in squeak_entries ] return squeak_admin_pb2.GetAncestorSqueakDisplaysReply( squeak_display_entries=squeak_display_msgs @@ -357,18 +357,18 @@ class SqueakAdminServerHandler(object): squeak_hash_str ) ) - squeak_entries_with_profile = ( - self.squeak_controller.get_reply_squeak_entries_with_profile( + squeak_entries = ( + self.squeak_controller.get_reply_squeak_entries( squeak_hash, ) ) logger.info( "Got number of reply squeak entries: {}".format( - len(squeak_entries_with_profile) + len(squeak_entries) ) ) squeak_display_msgs = [ - squeak_entry_to_message(entry) for entry in squeak_entries_with_profile + squeak_entry_to_message(entry) for entry in squeak_entries ] return squeak_admin_pb2.GetReplySqueakDisplaysReply( squeak_display_entries=squeak_display_msgs @@ -643,11 +643,11 @@ class SqueakAdminServerHandler(object): def handle_get_liked_squeak_display_entries(self, request): logger.info("Handle get liked squeak display entries.") - squeak_entries_with_profile = ( - self.squeak_controller.get_liked_squeak_entries_with_profile() + squeak_entries = ( + self.squeak_controller.get_liked_squeak_entries() ) squeak_display_msgs = [ - squeak_entry_to_message(entry) for entry in squeak_entries_with_profile + squeak_entry_to_message(entry) for entry in squeak_entries ] return squeak_admin_pb2.GetTimelineSqueakDisplaysReply( squeak_display_entries=squeak_display_msgs diff --git a/squeaknode/core/squeak_entry.py b/squeaknode/core/squeak_entry.py index e6d527a8..1fed789f 100644 --- a/squeaknode/core/squeak_entry.py +++ b/squeaknode/core/squeak_entry.py @@ -1,6 +1,8 @@ from typing import NamedTuple from typing import Optional +from squeaknode.core.squeak_profile import SqueakProfile + class SqueakEntry(NamedTuple): squeak_hash: bytes @@ -10,5 +12,6 @@ class SqueakEntry(NamedTuple): block_time: int reply_to: Optional[bytes] is_unlocked: bool + squeak_profile: Optional[SqueakProfile] liked_time: Optional[int] = None content: Optional[str] = None diff --git a/squeaknode/core/squeak_entry_with_profile.py b/squeaknode/core/squeak_entry_with_profile.py deleted file mode 100644 index 9536d05c..00000000 --- a/squeaknode/core/squeak_entry_with_profile.py +++ /dev/null @@ -1,10 +0,0 @@ -from typing import NamedTuple -from typing import Optional - -from squeaknode.core.squeak_entry import SqueakEntry -from squeaknode.core.squeak_profile import SqueakProfile - - -class SqueakEntryWithProfile(NamedTuple): - squeak_entry: SqueakEntry - squeak_profile: Optional[SqueakProfile] diff --git a/squeaknode/db/squeak_db.py b/squeaknode/db/squeak_db.py index b7bc223f..9530a94c 100644 --- a/squeaknode/db/squeak_db.py +++ b/squeaknode/db/squeak_db.py @@ -23,7 +23,6 @@ from squeaknode.core.sent_offer import SentOffer from squeaknode.core.sent_payment import SentPayment from squeaknode.core.sent_payment_summary import SentPaymentSummary from squeaknode.core.squeak_entry import SqueakEntry -from squeaknode.core.squeak_entry_with_profile import SqueakEntryWithProfile from squeaknode.core.squeak_peer import SqueakPeer from squeaknode.core.squeak_profile import SqueakProfile from squeaknode.core.util import get_hash @@ -195,17 +194,6 @@ class SqueakDb: return self._parse_squeak(row) def get_squeak_entry(self, squeak_hash: bytes) -> Optional[SqueakEntry]: - """ Get a squeak. """ - s = select([self.squeaks]).where( - self.squeaks.c.hash == squeak_hash) - with self.get_connection() as connection: - result = connection.execute(s) - row = result.fetchone() - if row is None: - return None - return self._parse_squeak_entry(row) - - def get_squeak_entry_with_profile(self, squeak_hash: bytes) -> Optional[SqueakEntryWithProfile]: """ Get a squeak with the author profile. """ s = ( select([self.squeaks, self.profiles]) @@ -222,9 +210,9 @@ class SqueakDb: row = result.fetchone() if row is None: return None - return self._parse_squeak_entry_with_profile(row) + return self._parse_squeak_entry(row) - def get_timeline_squeak_entries_with_profile(self) -> List[SqueakEntryWithProfile]: + def get_timeline_squeak_entries(self) -> List[SqueakEntry]: """ Get all followed squeaks. """ s = ( select([self.squeaks, self.profiles]) @@ -242,9 +230,9 @@ class SqueakDb: with self.get_connection() as connection: result = connection.execute(s) rows = result.fetchall() - return [self._parse_squeak_entry_with_profile(row) for row in rows] + return [self._parse_squeak_entry(row) for row in rows] - def get_liked_squeak_entries_with_profile(self) -> List[SqueakEntryWithProfile]: + def get_liked_squeak_entries(self) -> List[SqueakEntry]: """ Get liked squeaks. """ s = ( select([self.squeaks, self.profiles]) @@ -264,11 +252,11 @@ class SqueakDb: with self.get_connection() as connection: result = connection.execute(s) rows = result.fetchall() - return [self._parse_squeak_entry_with_profile(row) for row in rows] + return [self._parse_squeak_entry(row) for row in rows] - def get_squeak_entries_with_profile_for_address( + def get_squeak_entries_for_address( self, address: str, min_block: int, max_block: int - ) -> List[SqueakEntryWithProfile]: + ) -> List[SqueakEntry]: """ Get a squeak. """ s = ( select([self.squeaks, self.profiles]) @@ -289,9 +277,9 @@ class SqueakDb: with self.get_connection() as connection: result = connection.execute(s) rows = result.fetchall() - return [self._parse_squeak_entry_with_profile(row) for row in rows] + return [self._parse_squeak_entry(row) for row in rows] - def get_thread_ancestor_squeak_entries_with_profile(self, squeak_hash: bytes) -> List[SqueakEntryWithProfile]: + def get_thread_ancestor_squeak_entries(self, squeak_hash: bytes) -> List[SqueakEntry]: """ Get all reply ancestors of squeak hash. """ ancestors = ( select( @@ -335,7 +323,7 @@ class SqueakDb: with self.get_connection() as connection: result = connection.execute(s) rows = result.fetchall() - return [self._parse_squeak_entry_with_profile(row) for row in rows] + return [self._parse_squeak_entry(row) for row in rows] # sql = """ # WITH RECURSIVE is_thread_ancestor(hash, depth) AS ( @@ -357,7 +345,7 @@ class SqueakDb: # rows = curs.fetchall() # return [self._parse_squeak_entry_with_profile(row) for row in rows] - def get_thread_reply_squeak_entries_with_profile(self, squeak_hash: bytes) -> List[SqueakEntryWithProfile]: + def get_thread_reply_squeak_entries(self, squeak_hash: bytes) -> List[SqueakEntry]: """ Get all replies for a squeak hash. """ s = ( select([self.squeaks, self.profiles]) @@ -376,7 +364,7 @@ class SqueakDb: with self.get_connection() as connection: result = connection.execute(s) rows = result.fetchall() - return [self._parse_squeak_entry_with_profile(row) for row in rows] + return [self._parse_squeak_entry(row) for row in rows] def lookup_squeaks( self, @@ -495,7 +483,7 @@ class SqueakDb: def get_old_squeaks_to_delete( self, interval_s: int, - ) -> List[SqueakEntryWithProfile]: + ) -> List[bytes]: """ Get squeaks older than retention that meet the criteria for deletion. """ @@ -514,7 +502,8 @@ class SqueakDb: with self.get_connection() as connection: result = connection.execute(s) rows = result.fetchall() - return [self._parse_squeak_entry_with_profile(row) for row in rows] + hashes = [(row["hash"]) for row in rows] + return hashes def insert_profile(self, squeak_profile: SqueakProfile) -> int: """ Insert a new squeak profile. """ @@ -1107,6 +1096,7 @@ class SqueakDb: row["hash_reply_sqk"]) if row["hash_reply_sqk"] else None liked_time = row["liked_time"] liked_time_s = int(liked_time.timestamp()) if liked_time else None + profile = self._try_parse_squeak_profile(row) return SqueakEntry( squeak_hash=(row["hash"]), address=row["author_address"], @@ -1117,6 +1107,7 @@ class SqueakDb: is_unlocked=is_locked, liked_time=liked_time_s, content=row["content"], + squeak_profile=profile, ) def _parse_squeak_profile(self, row) -> SqueakProfile: @@ -1131,16 +1122,10 @@ class SqueakDb: profile_image=row["profile_image"], ) - def _parse_squeak_entry_with_profile(self, row) -> SqueakEntryWithProfile: - squeak_entry = self._parse_squeak_entry(row) + def _try_parse_squeak_profile(self, row) -> Optional[SqueakProfile]: if row["profile_id"] is None: - squeak_profile = None - else: - squeak_profile = self._parse_squeak_profile(row) - return SqueakEntryWithProfile( - squeak_entry=squeak_entry, - squeak_profile=squeak_profile, - ) + return None + return self._parse_squeak_profile(row) def _parse_squeak_peer(self, row) -> SqueakPeer: return SqueakPeer( diff --git a/squeaknode/node/squeak_controller.py b/squeaknode/node/squeak_controller.py index cb0a4dfd..931156be 100644 --- a/squeaknode/node/squeak_controller.py +++ b/squeaknode/node/squeak_controller.py @@ -24,10 +24,9 @@ from squeaknode.core.received_payment_summary import ReceivedPaymentSummary from squeaknode.core.sent_offer import SentOffer from squeaknode.core.sent_payment import SentPayment from squeaknode.core.sent_payment_summary import SentPaymentSummary -from squeaknode.core.squeak_entry_with_profile import SqueakEntryWithProfile +from squeaknode.core.squeak_entry import SqueakEntry from squeaknode.core.squeak_peer import SqueakPeer from squeaknode.core.squeak_profile import SqueakProfile -from squeaknode.core.util import get_hash from squeaknode.core.util import is_address_valid from squeaknode.node.new_squeak_listener import NewSqueakListener from squeaknode.node.new_squeak_listener import NewSqueakSubscriptionClient @@ -371,35 +370,35 @@ class SqueakController: def get_offer(self, squeak: CSqueak, offer: Offer, peer_address: PeerAddress) -> ReceivedOffer: return self.squeak_core.unpack_offer(squeak, offer, peer_address) - def get_squeak_entry_with_profile(self, squeak_hash: bytes) -> Optional[SqueakEntryWithProfile]: - return self.squeak_db.get_squeak_entry_with_profile(squeak_hash) + def get_squeak_entry(self, squeak_hash: bytes) -> Optional[SqueakEntry]: + return self.squeak_db.get_squeak_entry(squeak_hash) - def get_timeline_squeak_entries_with_profile(self): - return self.squeak_db.get_timeline_squeak_entries_with_profile() + def get_timeline_squeak_entries(self) -> List[SqueakEntry]: + return self.squeak_db.get_timeline_squeak_entries() - def get_liked_squeak_entries_with_profile(self): - return self.squeak_db.get_liked_squeak_entries_with_profile() + def get_liked_squeak_entries(self) -> List[SqueakEntry]: + return self.squeak_db.get_liked_squeak_entries() - def get_squeak_entries_with_profile_for_address( + def get_squeak_entries_for_address( self, address: str, min_block: int, max_block: int - ): - return self.squeak_db.get_squeak_entries_with_profile_for_address( + ) -> List[SqueakEntry]: + return self.squeak_db.get_squeak_entries_for_address( address, min_block, max_block, ) - def get_ancestor_squeak_entries_with_profile(self, squeak_hash: bytes): - return self.squeak_db.get_thread_ancestor_squeak_entries_with_profile( + def get_ancestor_squeak_entries(self, squeak_hash: bytes) -> List[SqueakEntry]: + return self.squeak_db.get_thread_ancestor_squeak_entries( squeak_hash, ) - def get_reply_squeak_entries_with_profile(self, squeak_hash: bytes): - return self.squeak_db.get_thread_reply_squeak_entries_with_profile( + def get_reply_squeak_entries(self, squeak_hash: bytes) -> List[SqueakEntry]: + return self.squeak_db.get_thread_reply_squeak_entries( squeak_hash, ) - def lookup_squeaks(self, addresses: List[str], min_block: int, max_block: int): + def lookup_squeaks(self, addresses: List[str], min_block: int, max_block: int) -> List[bytes]: return self.squeak_db.lookup_squeaks( addresses, min_block, @@ -434,9 +433,7 @@ class SqueakController: squeaks_to_delete = self.squeak_db.get_old_squeaks_to_delete( self.config.node.squeak_retention_s, ) - for squeak_entry_with_profile in squeaks_to_delete: - squeak = squeak_entry_with_profile.squeak_entry.squeak - squeak_hash = get_hash(squeak) + for squeak_hash in squeaks_to_delete: self.squeak_db.delete_squeak( squeak_hash, )