diff --git a/matrix_puppeteer_line/portal.py b/matrix_puppeteer_line/portal.py index 746084a..be357db 100644 --- a/matrix_puppeteer_line/portal.py +++ b/matrix_puppeteer_line/portal.py @@ -447,18 +447,33 @@ class Portal(DBPortal, BasePortal): return False async def _update_icon(self, icon: Optional[PathImage], client: Client) -> bool: - icon_path = icon.path if icon else None + if icon: + if icon.url and not icon.path: + self.log.warn(f"Using URL as path for room icon of {self.name}") + icon_path = icon_url = icon.url + else: + icon_path = icon.path + icon_url = icon.url + else: + icon_path = icon_url = None + if icon_path != self.icon_path: + self.log.info(f"Updating room icon of {self.name}") self.icon_path = icon_path - if icon and icon.url: + if icon_url: resp = await client.read_image(icon.url) self.icon_mxc = await self.main_intent.upload_media(resp.data, mime_type=resp.mime) else: self.icon_mxc = ContentURI("") if self.mxid: - await self.main_intent.set_room_avatar(self.mxid, self.icon_mxc) + try: + await self.main_intent.set_room_avatar(self.mxid, self.icon_mxc) + except Exception as e: + self.log.exception(f"Failed to set room icon: {e}") return True - return False + else: + self.log.debug(f"No need to update room icon of {self.name}, new icon has same path as old one") + return False async def _update_participants(self, participants: List[Participant]) -> None: if not self.mxid: diff --git a/matrix_puppeteer_line/puppet.py b/matrix_puppeteer_line/puppet.py index 97c7976..9a3c626 100644 --- a/matrix_puppeteer_line/puppet.py +++ b/matrix_puppeteer_line/puppet.py @@ -85,14 +85,24 @@ class Puppet(DBPuppet, BasePuppet): return False async def _update_avatar(self, avatar: Optional[PathImage], client: Client) -> bool: - if avatar and avatar.url and not avatar.path: - # Avatar exists, but in a form that cannot be uniquely identified. - # Skip it for now. - return False - avatar_path = avatar.path if avatar else None - if avatar_path != self.avatar_path or not self.avatar_set: + if avatar: + if avatar.url and not avatar.path: + if self.avatar_set and self.avatar_path: + self.log.warn(f"Not updating user avatar of {self.name}: new avatar exists, but in a form that cannot be uniquely identified") + return False + else: + self.log.warn(f"Using URL as path for user avatar of {self.name}: no previous avatar exists") + avatar_path = avatar_url = avatar.url + else: + avatar_path = avatar.path + avatar_url = avatar.url + else: + avatar_path = avatar_url = None + + if not self.avatar_set or avatar_path != self.avatar_path: + self.log.info(f"Updating user avatar of {self.name}") self.avatar_path = avatar_path - if avatar and avatar.url: + if avatar_url: resp = await client.read_image(avatar.url) self.avatar_mxc = await self.intent.upload_media(resp.data, mime_type=resp.mime) else: @@ -100,11 +110,13 @@ class Puppet(DBPuppet, BasePuppet): try: await self.intent.set_avatar_url(self.avatar_mxc) self.avatar_set = True - except Exception: - self.log.exception("Failed to set user avatar") + except Exception as e: + self.log.exception(f"Failed to set user avatar: {e}") self.avatar_set = False return True - return False + else: + self.log.debug(f"No need to update user avatar of {self.name}, new avatar has same path as old one") + return False def _add_to_cache(self) -> None: self.by_mid[self.mid] = self diff --git a/matrix_puppeteer_line/rpc/types.py b/matrix_puppeteer_line/rpc/types.py index 9fdcebf..9b96413 100644 --- a/matrix_puppeteer_line/rpc/types.py +++ b/matrix_puppeteer_line/rpc/types.py @@ -26,7 +26,7 @@ class RPCError(Exception): @dataclass class PathImage(SerializableAttrs['PathImage']): - path: str + path: Optional[str] url: str diff --git a/puppet/src/contentscript.js b/puppet/src/contentscript.js index aa946ba..10a2c6a 100644 --- a/puppet/src/contentscript.js +++ b/puppet/src/contentscript.js @@ -166,8 +166,8 @@ class MautrixController { /** * Try to match a user against an entry in the friends list to get their ID. * - * @param {Element} element - The display name of the user to find the ID for. - * @return {?string} - The user's ID if found. + * @param {string} senderName - The display name of the user to find the ID for. + * @return {?string} - The user's ID if found. */ getUserIdFromFriendsList(senderName) { return document.querySelector(`#contact_wrap_friends > ul > li[title='${senderName}']`)?.getAttribute("data-mid") @@ -518,10 +518,14 @@ class MautrixController { /** * @typedef PathImage * @type object - * @property {string} path - The virtual path of the image (behaves like an ID) - * @property {string} src - The URL of the image + * @property {?string} path - The virtual path of the image (behaves like an ID). Optional. + * @property {string} src - The URL of the image. Mandatory. */ + /** + * @param {Element} img - The image element to get the URL and path of. + * @return {?PathImage} - The image URL and its path, if found. + */ _getPathImage(img) { if (img && img.src.startsWith("blob:")) { // NOTE Having a blob but no path means the image exists, @@ -539,9 +543,9 @@ class MautrixController { /** * @typedef Participant * @type object - * @property {string} id - The member ID for the participant - * @property {PathImage} avatar - The path and blob URL of the participant's avatar - * @property {string} name - The contact list name of the participant + * @property {string} id - The member ID for the participant + * @property {?PathImage} avatar - The path and blob URL of the participant's avatar + * @property {string} name - The contact list name of the participant */ getParticipantListItemName(element) {