Merge branch 'unicode-fixes' of https://github.com/moyamo/transwhat into moyamo-unicode-fixes
Conflicts: session.py
This commit is contained in:
commit
b518fb07af
10
README.md
10
README.md
|
@ -2,6 +2,16 @@
|
||||||
|
|
||||||
transWhat is a WhatsApp XMPP Gateway based on [Spectrum 2](http://www.spectrum.im) and [Yowsup 2](https://github.com/tgalal/yowsup).
|
transWhat is a WhatsApp XMPP Gateway based on [Spectrum 2](http://www.spectrum.im) and [Yowsup 2](https://github.com/tgalal/yowsup).
|
||||||
|
|
||||||
|
#### Branches
|
||||||
|
|
||||||
|
- [yowsup-1](http://github.com/stv0g/transwhat/tree/yowsup-1) My original version which is based on @tgalal first Yowsup version (**deprecated** and broken).
|
||||||
|
- [yowsup-2](http://github.com/stv0g/transwhat/tree/yowsup-2) Major rewrite from @moyamo for @tgalal's new Yowsup 2 (**recommended**).
|
||||||
|
- [develop](http://github.com/stv0g/transwhat/tree/develop) A develop branch with the latest fixes and improvements. This branch is based on `yowsup-2`.
|
||||||
|
|
||||||
|
For production, please use the `yowsup-2` branch.
|
||||||
|
|
||||||
|
Please file bugreports against the `develop` branch.
|
||||||
|
|
||||||
## [Installation](INSTALL.md)
|
## [Installation](INSTALL.md)
|
||||||
## [Usage](USAGE.md)
|
## [Usage](USAGE.md)
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ import os
|
||||||
import logging
|
import logging
|
||||||
import google.protobuf
|
import google.protobuf
|
||||||
|
|
||||||
|
import resource
|
||||||
|
|
||||||
def WRAP(MESSAGE, TYPE):
|
def WRAP(MESSAGE, TYPE):
|
||||||
wrap = protocol_pb2.WrapperMessage()
|
wrap = protocol_pb2.WrapperMessage()
|
||||||
wrap.type = TYPE
|
wrap.type = TYPE
|
||||||
|
@ -621,7 +623,7 @@ class SpectrumBackend:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def handleMemoryUsage(self):
|
def handleMemoryUsage(self):
|
||||||
return (0,0)
|
return (resource.getrusage(resource.RUSAGE_SELF).ru_maxrss, 0)
|
||||||
|
|
||||||
def handleExitRequest(self):
|
def handleExitRequest(self):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
2
bot.py
2
bot.py
|
@ -45,7 +45,7 @@ class Bot():
|
||||||
args = message.strip().split(" ")
|
args = message.strip().split(" ")
|
||||||
cmd = args.pop(0)
|
cmd = args.pop(0)
|
||||||
|
|
||||||
if cmd[0] == '\\':
|
if len(cmd) > 0 and cmd[0] == '\\':
|
||||||
try:
|
try:
|
||||||
self.call(cmd[1:], args)
|
self.call(cmd[1:], args)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
11
contrib/spectrum@.service
Normal file
11
contrib/spectrum@.service
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[Unit]
|
||||||
|
description=spectrum2 whatsapp
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/bin/spectrum2 --no-daemonize -j whatsapp.example.com --config /etc/spectrum2/transports/whatsapp.cfg
|
||||||
|
Restart=always
|
||||||
|
User=spectrum2
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
33
session.py
33
session.py
|
@ -211,10 +211,10 @@ class Session(YowsupApp):
|
||||||
else:
|
else:
|
||||||
self.onPresenceUnavailable(number)
|
self.onPresenceUnavailable(number)
|
||||||
def sendReadReceipts(self, buddy):
|
def sendReadReceipts(self, buddy):
|
||||||
for _id, _from, participant in self.recvMsgIDs:
|
for _id, _from, participant, t in self.recvMsgIDs:
|
||||||
if _from.split('@')[0] == buddy:
|
if _from.split('@')[0] == buddy:
|
||||||
self.sendReceipt(_id, _from, 'read', participant)
|
self.sendReceipt(_id, _from, 'read', participant, t)
|
||||||
self.recvMsgIDs.remove((_id, _from, participant))
|
self.recvMsgIDs.remove((_id, _from, participant, t))
|
||||||
self.logger.debug("Send read receipt to %s (ID: %s)", _from, _id)
|
self.logger.debug("Send read receipt to %s (ID: %s)", _from, _id)
|
||||||
|
|
||||||
# Called by superclass
|
# Called by superclass
|
||||||
|
@ -291,10 +291,9 @@ class Session(YowsupApp):
|
||||||
# ]))
|
# ]))
|
||||||
#)
|
#)
|
||||||
buddy = _from.split('@')[0]
|
buddy = _from.split('@')[0]
|
||||||
messageContent = body #utils.softToUni(body)
|
messageContent = utils.softToUni(body)
|
||||||
self.logger.debug('received TextMessage 2')
|
self.sendReceipt(_id, _from, None, participant, timestamp)
|
||||||
self.sendReceipt(_id, _from, None, participant)
|
self.recvMsgIDs.append((_id, _from, participant, timestamp))
|
||||||
self.recvMsgIDs.append((_id, _from, participant))
|
|
||||||
self.logger.info("Message received from %s to %s: %s (at ts=%s)",
|
self.logger.info("Message received from %s to %s: %s (at ts=%s)",
|
||||||
buddy, self.legacyName, messageContent, timestamp)
|
buddy, self.legacyName, messageContent, timestamp)
|
||||||
if participant is not None: # Group message or broadcast
|
if participant is not None: # Group message or broadcast
|
||||||
|
@ -339,8 +338,8 @@ class Session(YowsupApp):
|
||||||
else:
|
else:
|
||||||
self.sendMessageToXMPP(buddy, url, image.timestamp)
|
self.sendMessageToXMPP(buddy, url, image.timestamp)
|
||||||
self.sendMessageToXMPP(buddy, image.caption, image.timestamp)
|
self.sendMessageToXMPP(buddy, image.caption, image.timestamp)
|
||||||
self.sendReceipt(image._id, image._from, None, image.participant)
|
self.sendReceipt(image._id, image._from, None, image.participant, image.timestamp)
|
||||||
self.recvMsgIDs.append((image._id, image._from, image.participant))
|
self.recvMsgIDs.append((image._id, image._from, image.participant, image.timestamp))
|
||||||
|
|
||||||
|
|
||||||
# Called by superclass
|
# Called by superclass
|
||||||
|
@ -358,8 +357,8 @@ class Session(YowsupApp):
|
||||||
self.sendGroupMessageToXMPP(buddy, partname, message, audio.timestamp)
|
self.sendGroupMessageToXMPP(buddy, partname, message, audio.timestamp)
|
||||||
else:
|
else:
|
||||||
self.sendMessageToXMPP(buddy, message, audio.timestamp)
|
self.sendMessageToXMPP(buddy, message, audio.timestamp)
|
||||||
self.sendReceipt(audio._id, audio._from, None, audio.participant)
|
self.sendReceipt(audio._id, audio._from, None, audio.participant, audio.timestamp)
|
||||||
self.recvMsgIDs.append((audio._id, audio._from, audio.participant))
|
self.recvMsgIDs.append((audio._id, audio._from, audio.participant, audio.timestamp))
|
||||||
|
|
||||||
|
|
||||||
# Called by superclass
|
# Called by superclass
|
||||||
|
@ -378,8 +377,8 @@ class Session(YowsupApp):
|
||||||
self.sendGroupMessageToXMPP(buddy, partname, message, video.timestamp)
|
self.sendGroupMessageToXMPP(buddy, partname, message, video.timestamp)
|
||||||
else:
|
else:
|
||||||
self.sendMessageToXMPP(buddy, message, video.timestamp)
|
self.sendMessageToXMPP(buddy, message, video.timestamp)
|
||||||
self.sendReceipt(video._id, video._from, None, video.participant)
|
self.sendReceipt(video._id, video._from, None, video.participant, video.timestamp)
|
||||||
self.recvMsgIDs.append((video._id, video._from, video.participant))
|
self.recvMsgIDs.append((video._id, video._from, video.participant, video.timestamp))
|
||||||
|
|
||||||
|
|
||||||
def onLocation(self, location):
|
def onLocation(self, location):
|
||||||
|
@ -409,8 +408,8 @@ class Session(YowsupApp):
|
||||||
if url is not None:
|
if url is not None:
|
||||||
self.sendMessageToXMPP(buddy, url, location.timestamp)
|
self.sendMessageToXMPP(buddy, url, location.timestamp)
|
||||||
self.sendMessageToXMPP(buddy, latlong, location.timestamp)
|
self.sendMessageToXMPP(buddy, latlong, location.timestamp)
|
||||||
self.sendReceipt(location._id, location._from, None, location.participant)
|
self.sendReceipt(location._id, location._from, None, location.participant, location.timestamp)
|
||||||
self.recvMsgIDs.append((loaction._id, location._from, location.participant))
|
self.recvMsgIDs.append((location._id, location._from, location.participant, location.timestamp))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -434,8 +433,8 @@ class Session(YowsupApp):
|
||||||
self.sendMessageToXMPP(buddy, message, timestamp)
|
self.sendMessageToXMPP(buddy, message, timestamp)
|
||||||
# self.sendMessageToXMPP(buddy, card_data)
|
# self.sendMessageToXMPP(buddy, card_data)
|
||||||
#self.transferFile(buddy, str(name), card_data)
|
#self.transferFile(buddy, str(name), card_data)
|
||||||
self.sendReceipt(_id, _from, None, participant)
|
self.sendReceipt(_id, _from, None, participant, timestamp)
|
||||||
self.recvMsgIDs.append((_id, _from, participant))
|
self.recvMsgIDs.append((_id, _from, participant, timestamp))
|
||||||
|
|
||||||
|
|
||||||
def transferFile(self, buddy, name, data):
|
def transferFile(self, buddy, name, data):
|
||||||
|
|
14
transwhat.py
14
transwhat.py
|
@ -43,6 +43,7 @@ from yowsup.stacks import YowStack
|
||||||
# Arguments
|
# Arguments
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('--debug', action='store_true')
|
parser.add_argument('--debug', action='store_true')
|
||||||
|
parser.add_argument('--log', type=str)
|
||||||
parser.add_argument('--host', type=str, required=True)
|
parser.add_argument('--host', type=str, required=True)
|
||||||
parser.add_argument('--port', type=int, required=True)
|
parser.add_argument('--port', type=int, required=True)
|
||||||
parser.add_argument('--service.backend_id', metavar="ID", type=int, required=True)
|
parser.add_argument('--service.backend_id', metavar="ID", type=int, required=True)
|
||||||
|
@ -52,12 +53,15 @@ parser.add_argument('-j', type=str, required=True)
|
||||||
args, unknown = parser.parse_known_args()
|
args, unknown = parser.parse_known_args()
|
||||||
|
|
||||||
YowConstants.PATH_STORAGE='/var/lib/spectrum2/' + args.j
|
YowConstants.PATH_STORAGE='/var/lib/spectrum2/' + args.j
|
||||||
loggingfile = '/var/log/spectrum2/' + args.j + '/backends/backend.log'
|
|
||||||
|
if args.log is None:
|
||||||
|
args.log = '/var/log/spectrum2/' + args.j + '/backends/backend.log'
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
logging.basicConfig( \
|
logging.basicConfig(
|
||||||
filename=loggingfile,\
|
filename=args.log,
|
||||||
format = "%(asctime)-15s %(levelname)s %(name)s: %(message)s", \
|
format = "%(asctime)-15s %(levelname)s %(name)s: %(message)s",
|
||||||
level = logging.DEBUG if args.debug else logging.INFO \
|
level = logging.DEBUG if args.debug else logging.INFO
|
||||||
)
|
)
|
||||||
|
|
||||||
# Handler
|
# Handler
|
||||||
|
|
2
utils.py
2
utils.py
|
@ -50,4 +50,4 @@ def decodePassword(password):
|
||||||
return base64.b64decode(bytes(password.encode("utf-8")))
|
return base64.b64decode(bytes(password.encode("utf-8")))
|
||||||
|
|
||||||
def sha1hash(data):
|
def sha1hash(data):
|
||||||
return hashlib.sha1(data).hexdigest()
|
return hashlib.sha1(data).hexdigest()
|
||||||
|
|
|
@ -118,8 +118,8 @@ class WhatsAppBackend(SpectrumBackend):
|
||||||
self.sessions[user].requestVCard(buddy, ID)
|
self.sessions[user].requestVCard(buddy, ID)
|
||||||
|
|
||||||
def handleVCardUpdatedRequest(self, user, photo, nickname):
|
def handleVCardUpdatedRequest(self, user, photo, nickname):
|
||||||
self.logger.debug("handleVCardUpdatedRequest(user=%s, nickname=%s)", user, nickname)
|
self.logger.debug("handleVCardUpdatedRequest(user=%s, nickname=%s) not implemented", user, nickname)
|
||||||
self.sessions[user].setProfilePicture(photo)
|
#self.sessions[user].setProfilePicture(photo)
|
||||||
|
|
||||||
def handleBuddyBlockToggled(self, user, buddy, blocked):
|
def handleBuddyBlockToggled(self, user, buddy, blocked):
|
||||||
self.logger.debug("handleBuddyBlockedToggled(user=%s, buddy=%s, blocked=%s)", user, buddy, blocked)
|
self.logger.debug("handleBuddyBlockedToggled(user=%s, buddy=%s, blocked=%s)", user, buddy, blocked)
|
||||||
|
|
|
@ -124,7 +124,7 @@ class YowsupApp(object):
|
||||||
"""
|
"""
|
||||||
self.stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_DISCONNECT))
|
self.stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_DISCONNECT))
|
||||||
|
|
||||||
def sendReceipt(self, _id, _from, read, participant):
|
def sendReceipt(self, _id, _from, read, participant, t):
|
||||||
"""
|
"""
|
||||||
Send a receipt (delivered: double-tick, read: blue-ticks)
|
Send a receipt (delivered: double-tick, read: blue-ticks)
|
||||||
|
|
||||||
|
@ -133,8 +133,10 @@ class YowsupApp(object):
|
||||||
- _from: jid of person who sent the message
|
- _from: jid of person who sent the message
|
||||||
- read: ('read' or None) None is just delivered, 'read' is read
|
- read: ('read' or None) None is just delivered, 'read' is read
|
||||||
- participant
|
- participant
|
||||||
|
- t: The time the original message was sent.
|
||||||
"""
|
"""
|
||||||
receipt = OutgoingReceiptProtocolEntity(_id, _from, read, participant)
|
self.logger.debug(u'Sending receipt to whatsapp: %s', [_id, _from, read, participant, t])
|
||||||
|
receipt = OutgoingReceiptProtocolEntity(_id, _from, read, participant, t=t)
|
||||||
self.sendEntity(receipt)
|
self.sendEntity(receipt)
|
||||||
|
|
||||||
def downloadMedia(self, url, onSuccess = None, onFailure = None):
|
def downloadMedia(self, url, onSuccess = None, onFailure = None):
|
||||||
|
|
Loading…
Reference in a new issue