Changeset b73409f


Ignore:
Timestamp:
2015-05-28T05:34:16Z (9 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Children:
50ddfad
Parents:
eb89823
Message:

Misc: Media messages, topic changes, and killed the stupid YowPing thread.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • python/wa.py

    reb89823 rb73409f  
    11#!/usr/bin/python
    22
     3import collections
    34import logging
    45import threading
     
    5556logger.addHandler(ch)
    5657
     58# Yowsup starts an entire THREAD just to do pings. I'll do them myself TYVM.
     59from yowsup.layers.protocol_iq.layer import YowPingThread
     60YowPingThread.start = lambda x: None
    5761
    5862# Tried this but yowsup is not passing back the result, will have to update the library. :-(
     
    130134
    131135        def onEvent(self, event):
    132                 print "Received event: %s name %s" % (event, event.getName())
    133                 if event.getName() == "disconnect":
     136                # TODO: Make this work without, hmm, over-recursing. (This handler
     137                # getting called when we initiated the disconnect, which upsets yowsup.)
     138                if event.getName() == "orgopenwhatsapp.yowsup.event.network.disconnected":
     139                        self.cb.error(event.getArg("reason"))
     140                        self.cb.logout(True)
    134141                        self.getStack().execDetached(self.daemon.StopDaemon)
     142                else:
     143                        print "Received event: %s name %s" % (event, event.getName())
    135144       
    136145        @ProtocolEntityCallback("presence")
     
    155164        @ProtocolEntityCallback("message")
    156165        def onMessage(self, msg):
    157                 receipt = OutgoingReceiptProtocolEntity(msg.getId(), msg.getFrom())
    158                 self.toLower(receipt)
     166                if hasattr(msg, "getBody"):
     167                        text = msg.getBody()
     168                elif hasattr(msg, "getCaption") and hasattr(msg, "getMediaUrl"):
     169                        lines = []
     170                        if msg.getMediaUrl():
     171                                lines.append(msg.getMediaUrl())
     172                        else:
     173                                lines.append("<Broken link>")
     174                        if msg.getCaption():
     175                                lines.append(msg.getCaption())
     176                        text = "\n".join(lines)
    159177
    160178                if msg.getParticipant():
    161                         group = self.b.groups.get(msg.getFrom(), None)
    162                         if not group or "id" not in group:
     179                        group = self.b.groups[msg.getFrom()]
     180                        if "id" in group:
     181                                self.cb.chat_msg(group["id"], msg.getParticipant(), text, 0, msg.getTimestamp())
     182                        else:
    163183                                self.cb.log("Warning: Activity in room %s" % msg.getFrom())
    164                                 self.b.groups.setdefault(msg.getFrom(), {}).setdefault("queue", []).append(msg)
    165                                 return
    166                         self.cb.chat_msg(group["id"], msg.getParticipant(), msg.getBody(), 0, msg.getTimestamp())
     184                                self.b.groups[msg.getFrom()].setdefault("queue", []).append(msg)
    167185                else:
    168                         self.cb.buddy_msg(msg.getFrom(), msg.getBody(), 0, msg.getTimestamp())
     186                        self.cb.buddy_msg(msg.getFrom(), text, 0, msg.getTimestamp())
     187
     188                # ACK is required! So only use return above in case of errors.
     189                # (So that we will/might get a retry after restarting.)
     190                self.toLower(OutgoingReceiptProtocolEntity(msg.getId(), msg.getFrom()))
    169191
    170192        @ProtocolEntityCallback("receipt")
     
    209231                        if "@" not in jid:
    210232                                jid += "@g.us"
    211                         group = self.b.groups.setdefault(jid, {})
    212                         group["info"] = g
     233                        group = self.b.groups[jid]
     234                       
     235                        # Save it. We're going to mix ListGroups elements and
     236                        # Group-Subject notifications there, which don't have
     237                        # consistent fieldnames for the same bits of info \o/
     238                        g.getSubjectTimestamp = g.getSubjectTime
     239                        group["topic"] = g
    213240
    214241                self.check_connected("groups")
     
    218245                if isinstance(ent, StatusNotificationProtocolEntity):
    219246                        return self.onStatusNotification(ent)
     247                elif isinstance(ent, SubjectGroupsNotificationProtocolEntity):
     248                        return self.onGroupSubjectNotification(ent)
    220249
    221250        def onStatusNotification(self, status):
    222251                print "New status for %s: %s" % (status.getFrom(), status.status)
    223252                self.bee.buddy_status_msg(status.getFrom(), status.status)
     253       
     254        def onGroupSubjectNotification(self, sub):
     255                print "New /topic for %s: %s" % (sub.getFrom(), sub.getSubject())
     256                group = self.b.groups[sub.getFrom()]
     257                group["topic"] = sub
     258                id = group.get("id", None)
     259                if id is not None:
     260                        self.cb.chat_topic(id, sub.getSubjectOwner(),
     261                                           sub.getSubject(), sub.getSubjectTimestamp())
    224262
    225263        @ProtocolEntityCallback("media")
     
    267305        AWAY_STATES = ["Away"]
    268306        ACCOUNT_FLAGS = 14 # HANDLE_DOMAINS + STATUS_MESSAGE + LOCAL_CONTACTS
    269         # TODO: LOCAL LIST CAUSES CRASH!
    270307        # TODO: HANDLE_DOMAIN in right place (add ... ... nick bug)
    271         # TODO? Allow set_away (for status msg) even if AWAY_STATES not set?
    272         #   and/or, see why with the current value set_away state is None.
    273308
    274309        def login(self, account):
     
    279314                self.bee.log("Started yowsup thread")
    280315               
    281                 self.groups = {}
     316                self.groups = collections.defaultdict(dict)
    282317                self.groups_by_id = {}
    283318
    284319        def keepalive(self):
    285320                # Too noisy while debugging
     321                # WTF yowsup is SPAWNING A THREAD just for this. Figure out
     322                # how to kill that nonsense.
    286323                pass
    287324                #self.yow.Ship(PingIqProtocolEntity(to="s.whatsapp.net"))
     
    317354        def chat_join(self, id, name, _nick, _password, settings):
    318355                print "New chat created with id: %d" % id
    319                 self.groups.setdefault(name, {}).update({"id": id, "name": name})
    320356                group = self.groups[name]
     357                group.update({"id": id, "name": name})
    321358                self.groups_by_id[id] = group
    322359               
    323                 gi = group.get("info", None)
     360                gi = group.get("topic", None)
    324361                if gi:
    325362                        self.bee.chat_topic(id, gi.getSubjectOwner(),
    326                                             gi.getSubject(), gi.getSubjectTime())
     363                                            gi.getSubject(), gi.getSubjectTimestamp())
    327364               
    328365                # WA doesn't really have a concept of joined or not, just
    329                 # long-term membership. Let's just get a list of members and
    330                 # pretend we've "joined" then.
     366                # long-term membership. Let's just sync state (we have
     367                # basic info but not yet a member list) and ACK the join
     368                # once that's done.
    331369                self.yow.Ship(ParticipantsGroupsIqProtocolEntity(name))
    332370
     
    372410                return stack
    373411
     412
    374413implugin.RunPlugin(YowsupIMPlugin, debug=True)
Note: See TracChangeset for help on using the changeset viewer.