fork of https://f-hub.org/XMPP/xmpp-discord-bridge

misc: Fix general things

+48 -23
+1 -1
setup.py
··· 22 22 zip_safe = True, 23 23 entry_points = { 24 24 "console_scripts": [ 25 - "discord-xmpp-bridge = discord_xmpp_bridge.main:main" 25 + "xmpp-discord-bridge = xmpp_discord_bridge.main:main" 26 26 ] 27 27 } 28 28 )
+19 -4
xmpp_discord_bridge/avatar.py
··· 1 1 import logging 2 + import hashlib 3 + import os 2 4 3 5 from slixmpp.exceptions import IqError 4 6 5 7 class AvatarManager: 8 + """ 9 + The AvatarManager class is responsible for aquiring the XMPP avatars 10 + using the means of either XEP-0153 (XEP-0054), XEP-0084 or (in the future) 11 + XEP-0292, storing and providing a publicly available URL to those avatars. 12 + """ 6 13 def __init__(self, xmpp, config): 7 14 self._xmpp = xmpp 8 15 self._path = config["avatars"]["path"] ··· 12 19 13 20 self._logger = logging.getLogger("xmpp.avatar") 14 21 15 - def save_avatar(self, jid, data, type_): 22 + def _save_avatar(self, jid, data, type_): 16 23 filename = hashlib.sha1(data).hexdigest() + "." + type_.split("/")[1] 17 24 path = os.path.join(self._path, filename) 18 25 ··· 31 38 ifrom=self._xmpp._bot_jid_full) 32 39 type_ = iq["vcard_temp"]["PHOTO"]["TYPE"] 33 40 data = iq["vcard_temp"]["PHOTO"]["BINVAL"] 34 - self.save_avatar(jid, data, type_) 41 + self._save_avatar(jid, data, type_) 35 42 return True 36 43 except IqError: 37 44 self._logger.debug("Avatar retrieval via XEP-0054/XEP-0153 failed. Probably no vCard for XEP-0054 published") ··· 43 50 node="urn:xmpp:avatar:data", 44 51 max_items=1, 45 52 ifrom=self._xmpp._bot_jid_full) 53 + data = iq["pubsub"]["items"]["substanzas"][0]["data"] 54 + self._save_avatar(jid, data, "image/png") 55 + return True 46 56 except IqError: 47 57 self._logger.debug("Avatar retrieval via XEP-0084 failed. Probably no avatar published or subscription model not fulfilled.") 48 58 return False 49 59 50 60 async def aquire_avatar(self, jid): 51 - # First try vCard via 0054/0153 61 + """ 62 + Attempt to request the avatar of @jid 63 + """ 52 64 for f in [self.try_xep_0153, self.try_xep_0084]: 53 65 if await f(jid): 54 66 self._logger.debug("Avatar retrieval successful for %s", ··· 58 70 self._logger.debug("Avatar retrieval failed for %s. Giving up.", 59 71 jid) 60 72 61 - def get_avatar(self, jid): 73 + def get_avatar_url(self, jid): 74 + """ 75 + Returns either the URL to the avatar of @jid or None. 76 + """ 62 77 return self._avatars.get(jid, None)
+8 -6
xmpp_discord_bridge/helpers.py
··· 1 + from discord import Status 2 + 1 3 def discord_status_to_xmpp_show(status): 2 4 return { 3 - discord.Status.online: "available", 4 - discord.Status.idle: "away", 5 - discord.Status.dnd: "dnd", 6 - discord.Status.do_not_disturb: "dnd", 7 - discord.Status.invisible: "xa", # TODO: Kinda 8 - discord.Status.offline: "unavailable" 5 + Status.online: "available", 6 + Status.idle: "away", 7 + Status.dnd: "dnd", 8 + Status.do_not_disturb: "dnd", 9 + Status.invisible: "xa", # TODO: Kinda 10 + Status.offline: "unavailable" 9 11 }.get(status, "available")
+20 -12
xmpp_discord_bridge/main.py
··· 16 16 from slixmpp.exceptions import XMPPError, IqError 17 17 from slixmpp.xmlstream import register_stanza_plugin 18 18 from slixmpp.jid import JID 19 + from discord import Status 19 20 import requests 20 21 21 22 from xmpp_discord_bridge.slixmpp.oob import OOBData ··· 124 125 self._virtual_muc_users[muc] = [] 125 126 self._virtual_muc_nicks[muc] = {} 126 127 for member in dchannel.members: 127 - if member.status == discord.Status.offline: 128 + if member.status == Status.offline and not self._dont_ignore_offline: 128 129 continue 129 130 130 131 self._virtual_muc_users[muc].append(member.display_name) ··· 208 209 "username": message["from"].resource 209 210 } 210 211 211 - if self._relay_xmpp_avatars and self._avatars.get_avatar(message["from"]): 212 - webhook["avatar_url"] = self._avatar.get_avatar(message["from"]) 212 + if self._relay_xmpp_avatars and self._avatars.get_avatar_url(message["from"]): 213 + webhook["avatar_url"] = self._avatar.get_avatar_url(message["from"]) 213 214 214 215 # Look for mentions and replace them 215 216 guild, channel = self._muc_map[muc] ··· 230 231 requests.post(self._webhooks[muc], 231 232 data=webhook) 232 233 233 - def virtual_user_update_presence(self, muc, uid, pshow): 234 + def virtual_user_update_presence(self, muc, uid, pshow, pstatus=None): 234 235 """ 235 236 Change the status of a virtual MUC member. 236 237 NOTE: This assumes that the user is in the MUC 237 238 """ 238 239 self.send_presence(pshow=pshow, 240 + pstatus=pstatus, 239 241 pto="%s/%s" % (muc, self._virtual_muc_nicks[muc][uid]), 240 242 pfrom=self.spoof_member_jid(uid)) 241 243 ··· 246 248 247 249 If update_state_tracking is True, then _virtual_muc_... gets updates. 248 250 """ 249 - if member.status == discord.Status.offline and not self._dont_ignore_offline: 251 + if member.status == Status.offline and not self._dont_ignore_offline: 250 252 return 251 253 252 254 if update_state_tracking: ··· 256 258 # Prevent offline users from getting an unavailable presence by 257 259 # accident 258 260 pshow = discord_status_to_xmpp_show(member.status) 259 - if member.status == discord.Status.offline: 261 + pstatus = "" 262 + if member.status == Status.offline: 260 263 pshow = "xa" 261 264 265 + if self._dont_ignore_offline: 266 + pstatus = "Offline" 267 + 262 268 self.plugin["xep_0045"].join_muc(muc, 263 269 nick=member.display_name, 264 270 pfrom=self.spoof_member_jid(member.id), 265 - pshow=pshow) 271 + pshow=pshow, 272 + pstatus=pstatus) 266 273 267 274 async def on_discord_member_join(self, member): 268 275 guild = member.guild.id ··· 300 307 # Handle a status change 301 308 for channel in self._guild_map[guild]: 302 309 muc = self._guild_map[guild][channel] 303 - if after.status == discord.Status.offline: 310 + if after.status == Status.offline: 304 311 if self._dont_ignore_offline: 305 312 self.virtual_user_update_presence(muc, 306 313 after.id, 307 - "xa") 314 + "xa", 315 + "Offline") 308 316 else: 309 317 self._logger.debug("%s went offline. Removing from state tracking.", 310 318 after.display_name) ··· 315 323 # Remove from all state tracking 316 324 self._virtual_muc_users[muc].remove(after.display_name) 317 325 del self._virtual_muc_nicks[muc][after.id] 318 - elif before.status == discord.Status.offline and after.status != discord.Status.offline: 326 + elif before.status == Status.offline and after.status != Status.offline and not self._dont_ignore_offline: 319 327 self.virtual_user_join_muc(muc, after, update_state_tracking=True) 320 328 else: 321 329 self.virtual_user_update_presence(muc, ··· 425 433 self._real_muc_users[muc].append(resource) 426 434 427 435 async def on_session_start(self, event): 428 - self._discord = DiscordClient(self, config) 436 + self._discord = DiscordClient(self, self._config) 429 437 asyncio.ensure_future(self._discord.start(self._token)) 430 438 431 439 def main(): ··· 441 449 "-d", "--debug", dest="debug", help="Enable debug logging", action="store_true" 442 450 ) 443 451 444 - (option, args) = parser.parse_args() 452 + (options, args) = parser.parse_args() 445 453 verbosity = logging.DEBUG if options.debug else logging.INFO 446 454 447 455 general = config["general"]