Skip to content
Snippets Groups Projects
Commit f85fcdce authored by Tulir Asokan's avatar Tulir Asokan :cat2:
Browse files

Fix same photo detection when updating info

parent 05817034
No related branches found
No related tags found
No related merge requests found
......@@ -14,10 +14,12 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from typing import Dict, Optional, Tuple, Union, TYPE_CHECKING
import aiohttp
import asyncio
import logging
from yarl import URL
import aiohttp
from fbchat import (ThreadType, Thread, User as FBUser, Group as FBGroup, Page as FBPage,
Message as FBMessage)
from mautrix.types import RoomID, EventType, ContentURI, MessageEventContent, EventID
......@@ -47,27 +49,29 @@ class Portal:
mxid: Optional[RoomID]
name: str
photo: str
photo_id: str
avatar_uri: ContentURI
messages_by_fbid: Dict[str, EventID]
messages_by_mxid: Dict[EventID, str]
messages_by_fbid: Dict[str, Optional[EventID]]
messages_by_mxid: Dict[EventID, Optional[str]]
_main_intent: Optional[IntentAPI]
_create_room_lock: asyncio.Lock
def __init__(self, fbid: str, fb_receiver: str, fb_type: ThreadType,
mxid: Optional[RoomID] = None,
name: str = "", photo: str = "", avatar_uri: ContentURI = "") -> None:
name: str = "", photo_id: str = "", avatar_uri: ContentURI = "") -> None:
self.fbid = fbid
self.fb_receiver = fb_receiver
self.fb_type = fb_type
self.mxid = mxid
self.name = name
self.photo = photo
self.photo_id = photo_id
self.avatar_uri = avatar_uri
self._main_intent = None
self._create_room_lock = asyncio.Lock()
self.messages_by_fbid = {}
self.messages_by_mxid = {}
......@@ -85,7 +89,7 @@ class Portal:
"fb_receiver": self.fb_receiver,
"mxid": self.mxid,
"name": self.name,
"photo": self.photo,
"photo_id": self.photo_id,
"avatar_uri": self.avatar_uri,
}
......@@ -93,7 +97,7 @@ class Portal:
def from_dict(cls, data: Dict[str, str]) -> 'Portal':
return cls(fbid=data["fbid"], fb_receiver=data["fb_receiver"],
fb_type=ThreadType(data["fb_type"]), mxid=RoomID(data["mxid"]),
name=data["name"], photo=data["photo"],
name=data["name"], photo_id=data["photo_id"],
avatar_uri=ContentURI(data["avatar_uri"]))
@property
......@@ -129,20 +133,31 @@ class Portal:
loop=self.loop)
return info
@staticmethod
def _get_photo_id(url: str) -> str:
path = URL(url).path
return path[path.rfind("/") + 1:]
@staticmethod
async def _reupload_photo(url: str, client: IntentAPI) -> ContentURI:
async with aiohttp.ClientSession() as session:
resp = await session.get(url)
data = await resp.read()
return await client.upload_media(data)
async def _update_name(self, name: str) -> None:
if self.name != name:
self.name = name
if self.mxid and not self.is_direct:
await self.main_intent.set_room_name(self.mxid, self.name)
async def _update_photo(self, photo: str) -> None:
if self.photo != photo or len(self.avatar_uri) == 0:
self.photo = photo
async def _update_photo(self, photo_url: str) -> None:
photo_id = self._get_photo_id(photo_url)
print(photo_id, self.photo_id)
if self.photo_id != photo_id or len(self.avatar_uri) == 0:
self.photo_id = photo_id
if self.mxid and not self.is_direct:
async with aiohttp.ClientSession() as session:
resp = await session.get(self.photo)
data = await resp.read()
self.avatar_uri = await self.main_intent.upload_media(data)
self.avatar_uri = await self._reupload_photo(photo_url, self.main_intent)
await self.main_intent.set_room_avatar(self.mxid, self.avatar_uri)
async def _update_participants(self, source: 'u.User', info: ThreadClass) -> None:
......@@ -158,9 +173,22 @@ class Portal:
await asyncio.gather(*[puppet.intent.ensure_joined(self.mxid)
for puppet in puppets.values()])
async def create_matrix_room(self, source: 'u.User', info: Optional[Thread] = None) -> RoomID:
async def _update_matrix_room(self, source: 'u.User',
info: Optional[ThreadClass] = None) -> None:
await self.main_intent.invite_user(self.mxid, source.mxid)
async def create_matrix_room(self, source: 'u.User', info: Optional[ThreadClass] = None
) -> RoomID:
if self.mxid:
await self._update_matrix_room(source, info)
return self.mxid
async with self._create_room_lock:
await self._create_matrix_room(source, info)
async def _create_matrix_room(self, source: 'u.User', info: Optional[ThreadClass] = None
) -> RoomID:
if self.mxid:
await self.main_intent.invite_user(self.mxid, source.mxid)
await self._update_matrix_room(source, info)
return self.mxid
info = await self.update_info(source=source, info=info)
......@@ -176,7 +204,7 @@ class Portal:
invitees=[source.mxid])
self.log.debug(f"Matrix room created: {self.mxid}")
if not self.mxid:
raise Exception("Failed to create room")
raise Exception("Failed to create room: no mxid required")
self.by_mxid[self.mxid] = self
if not self.is_direct:
await self._update_participants(source, info)
......
......@@ -23,7 +23,7 @@ from mautrix.types import UserID, ContentURI
from mautrix.appservice import AppService, IntentAPI
from .config import Config
from . import user as u
from . import user as u, portal as p
if TYPE_CHECKING:
from .context import Context
......@@ -41,15 +41,15 @@ class Puppet:
fbid: str
name: str
photo: str
photo_id: str
avatar_uri: ContentURI
intent: IntentAPI
def __init__(self, fbid: str, name: str = "", photo: str = "", avatar_uri: ContentURI = ""):
def __init__(self, fbid: str, name: str = "", photo_id: str = "", avatar_uri: ContentURI = ""):
self.fbid = fbid
self.name = name
self.photo = photo
self.photo_id = photo_id
self.avatar_uri = avatar_uri
self.mxid = self.get_mxid_from_id(fbid)
......@@ -61,13 +61,13 @@ class Puppet:
return {
"fbid": self.fbid,
"name": self.name,
"photo": self.photo,
"photo_id": self.photo_id,
"avatar_uri": self.avatar_uri,
}
@classmethod
def from_dict(cls, data: Dict[str, str]) -> 'Puppet':
return cls(fbid=data["fbid"], name=data["name"], photo=data["photo"],
return cls(fbid=data["fbid"], name=data["name"], photo_id=data["photo_id"],
avatar_uri=ContentURI(data["avatar_uri"]))
async def update_info(self, source: Optional['u.User'] = None, info: Optional[FBUser] = None
......@@ -80,17 +80,17 @@ class Puppet:
async def _update_name(self, info: FBUser) -> None:
# TODO more precise name control
print(info.name, self.name)
if info.name != self.name:
self.name = info.name
await self.intent.set_displayname(self.name)
async def _update_photo(self, photo: str) -> None:
if photo != self.photo or len(self.avatar_uri) == 0:
self.photo = photo
async with aiohttp.ClientSession() as session:
resp = await session.get(self.photo)
data = await resp.read()
self.avatar_uri = await self.intent.upload_media(data)
async def _update_photo(self, photo_url: str) -> None:
photo_id = p.Portal._get_photo_id(photo_url)
print(photo_id, self.photo_id)
if photo_id != self.photo_id or len(self.avatar_uri) == 0:
self.photo_id = photo_id
self.avatar_uri = await p.Portal._reupload_photo(photo_url, self.intent)
await self.intent.set_avatar_url(self.avatar_uri)
@classmethod
......
......@@ -32,7 +32,6 @@ if TYPE_CHECKING:
config: Config
GREEN = "\u001b[32m"
YELLOW = "\u001b[33m"
MAGENTA = "\u001b[35m"
......@@ -106,6 +105,10 @@ class User(Client):
async def post_login(self) -> None:
await self.sync_threads()
self.log.debug("Updating own puppet info")
own_info = (await self.fetchUserInfo(self.uid))[self.uid]
puppet = pu.Puppet.get(self.uid, create=True)
await puppet.update_info(source=self, info=own_info)
async def sync_threads(self) -> None:
try:
......@@ -171,7 +174,7 @@ class User(Client):
async def onMessage(self, mid: str = None, author_id: str = None, message: str = None,
message_object: Message = None, thread_id: str = None,
thread_type: ThreadType = ThreadType.USER, ts: int = None,
metadata: Any = None, msg: Any = None):
metadata: Any = None, msg: Any = None) -> None:
"""
Called when the client is listening, and somebody sends a message
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment