diff options
-rw-r--r-- | Config_example.txt | 4 | ||||
-rw-r--r-- | extensions/captcha_forms.py | 2 | ||||
-rw-r--r-- | extensions/forwardMessages.py | 12 | ||||
-rw-r--r-- | gateway.py | 55 | ||||
-rw-r--r-- | handlers/IQ.py | 17 | ||||
-rw-r--r-- | library/utils.py | 12 | ||||
-rw-r--r-- | locales/locale.ru | 2 |
7 files changed, 67 insertions, 37 deletions
diff --git a/Config_example.txt b/Config_example.txt index 0ccb955..04a774a 100644 --- a/Config_example.txt +++ b/Config_example.txt @@ -79,3 +79,7 @@ crashDir = "crash" ## Log level (logging.DEBUG, logging.ERROR, logging.CRITICAL) LOG_LEVEL = logging.DEBUG + + +## Stanza send interval (in seconds) +STANZA_SEND_INTERVAL = 0.03125
\ No newline at end of file diff --git a/extensions/captcha_forms.py b/extensions/captcha_forms.py index 05536b6..88b228a 100644 --- a/extensions/captcha_forms.py +++ b/extensions/captcha_forms.py @@ -12,7 +12,7 @@ def captchaSend(self): x = msg.setTag("x", namespace=xmpp.NS_OOB) x.setTagData("url", self.engine.captcha["img"]) captcha = msg.setTag("captcha", namespace=xmpp.NS_CAPTCHA) - image = vCardGetPhoto(self.engine.captcha["img"], False) + image = utils.getLinkData(self.engine.captcha["img"], False) if image: hash = sha1(image).hexdigest() encoded = image.encode("base64") diff --git a/extensions/forwardMessages.py b/extensions/forwardMessages.py index cc3e78f..445dfbb 100644 --- a/extensions/forwardMessages.py +++ b/extensions/forwardMessages.py @@ -1,6 +1,6 @@ # coding: utf-8 # This file is a part of VK4XMPP transport -# © simpleApps, 2013. +# © simpleApps, 2013 — 2014. from datetime import datetime @@ -8,9 +8,12 @@ if not require("attachments"): raise AssertionError("'forwardMessages' requires 'attachments'") def parseForwardMessages(self, msg, depth = 0): - body = "" + spacer = u" · " * depth + body = "\n" + spacer if msg.has_key("fwd_messages"): - body += _("\nForward messages:") + +# body += tab + body += _("Forward messages:") fwd_messages = sorted(msg["fwd_messages"], msgSort) for fwd in fwd_messages: idFrom = fwd["uid"] @@ -18,11 +21,12 @@ def parseForwardMessages(self, msg, depth = 0): fwdBody = escape("", uHTML(fwd["body"])) date = datetime.fromtimestamp(date).strftime("%d.%m.%Y %H:%M:%S") name = self.getUserData(idFrom)["name"] - body += "\n[%s] <%s> %s" % (date, name, fwdBody) + body += "\n%s[%s] <%s> %s" % (spacer, date, name, fwdBody) body += parseAttachments(self, fwd) if depth < MAXIMUM_FORWARD_DEPTH: depth += 1 body += parseForwardMessages(self, fwd, depth) return body + Handlers["msg01"].append(parseForwardMessages) @@ -69,7 +69,8 @@ SLICE_STEP = 8 USER_LIMIT = 0 DEBUG_XMPPPY = False THREAD_STACK_SIZE = 0 -MAXIMUM_FORWARD_DEPTH = 5 +MAXIMUM_FORWARD_DEPTH = 10 +STANZA_SEND_INTERVAL = 0.03125 pidFile = "pidFile.txt" logFile = "vk4xmpp.log" @@ -116,7 +117,7 @@ loggerHandler.setFormatter(Formatter) logger.addHandler(loggerHandler) def gatewayRev(): - revNumber, rev = 171, 0 + revNumber, rev = 175, 0 shell = os.popen("git describe --always && git log --pretty=format:''").readlines() if shell: revNumber, rev = len(shell), shell[0] @@ -148,11 +149,13 @@ def initDatabase(filename): def execute(handler, list=()): try: - handler(*list) + result = handler(*list) except SystemExit: - pass + result = 1 except Exception: + result = -1 crashLog(handler.func_name) + return result ## TODO: execute threaded handlers def executeHandlers(type, list=()): @@ -281,10 +284,7 @@ class VKLogin(object): roster = True elif e.message == "User authorization failed: invalid access_token.": msgSend(Component, self.source, _(e.message + " Please, register again"), TransportID) - try: - deleteUser(Transport.get(self.source, self), roster, False) - except KeyError: - pass + deleteUser(Transport.get(self.source, self), roster, False) self.Online = False logger.error("VKLogin: apiError %s for user %s" % (e.message, self.source)) @@ -327,15 +327,37 @@ class VKLogin(object): values["last_message_id"] = mid return self.method("messages.get", values) -def sendPresence(target, source, pType=None, nick=None, reason=None, caps=None): +def sendPresence(target, source, pType=None, nick=None, reason=None, caps=None, hash=None): Presence = xmpp.Presence(target, pType, frm=source, status=reason) if nick: Presence.setTag("nick", namespace=xmpp.NS_NICK) Presence.setTagData("nick", nick) if caps: Presence.setTag("c", {"node": "http://simpleapps.ru/caps/vk4xmpp", "ver": Revision}, xmpp.NS_CAPS) + if hash: + x = Presence.setTag("x", namespace=xmpp.NS_VCARD_UPDATE) + x.setTagData("photo", hash) Sender(Component, Presence) + +from hashlib import sha1 + +def hasher(user, list=None): + if not list: + list = user.vk.method("friends.getOnline") + user.hashes = {} + photos = [{"uid": TransportID, "photo": URL_VCARD_NO_IMAGE}] + else: + photos = [] + + list = ",".join((str(x) for x in list)) + photos = photos + user.vk.method("execute.getPhotos", {"users": list, "size": PhotoSize}) + + for key in photos: + user.hashes[key["uid"]] = sha1(utils.getLinkData(key["photo"], True)).hexdigest() + + + class User(object): def __init__(self, data=(), source=""): @@ -348,11 +370,12 @@ class User(object): self.lastMsgID = 0 self.rosterSet = None self.existsInDB = None - self.last_udate = time.time() self.typing = {} self.source = source self.resources = [] self.chatUsers = {} + self.hashes = {}#!!! + self.last_udate = time.time() self.__sync = threading._allocate_lock() self.vk = VKLogin(self.username, self.password, self.source) logger.debug("initializing User for %s" % self.source) @@ -425,6 +448,7 @@ class User(object): return self.UserID def init(self, force=False, send=True): + threadRun(hasher, (self,), "hasher-%s"%self.source)#!!! logger.debug("User: called init for user %s" % self.source) if not self.friends: self.friends = self.vk.getFriends() @@ -443,8 +467,8 @@ class User(object): (self.source, "exists" if self.friends else "empty")) for uid, value in self.friends.iteritems(): if value["online"]: - sendPresence(self.source, vk2xmpp(uid), None, value["name"], caps=True) - sendPresence(self.source, TransportID, None, IDentifier["name"], caps=True) + sendPresence(self.source, vk2xmpp(uid), None, value["name"], caps=True, hash=self.hashes.get(uid)) + sendPresence(self.source, TransportID, None, IDentifier["name"], caps=True,hash=self.hashes.get(uid)) def sendOutPresence(self, target, reason=None): logger.debug("User: sending out presence to %s" % self.source) @@ -545,7 +569,8 @@ class User(object): threadRun(self.sendMessages) elif typ == 8: # user online uid = abs(evt[0]) - sendPresence(self.source, vk2xmpp(uid), nick=self.getUserData(uid)["name"], caps=True) + hasher(self, [uid]) + sendPresence(self.source, vk2xmpp(uid), nick=self.getUserData(uid)["name"], caps=True, hash=self.hashes.get(uid)) elif typ == 9: # user leaved uid = abs(evt[0]) sendPresence(self.source, vk2xmpp(uid), "unavailable") @@ -802,7 +827,7 @@ class Poll: user = Transport.get(user.source) if not user: continue - result = user.processPollResult(opener) + result = execute(user.processPollResult, (opener,)) if result == -1: continue elif result: @@ -838,7 +863,7 @@ def main(): Component.RegisterHandler("presence", prsHandler) Component.RegisterHandler("message", msgHandler) Component.RegisterDisconnectHandler(disconnectHandler) - Component.set_send_interval(0.03125) # 32 messages per second + Component.set_send_interval(STANZA_SEND_INTERVAL) # 32 messages per second Print("#-# Initializing users", False) with Database(DatabaseFile) as db: users = db("select jid from users").fetchall() diff --git a/handlers/IQ.py b/handlers/IQ.py index c340d95..d7e24ac 100644 --- a/handlers/IQ.py +++ b/handlers/IQ.py @@ -178,7 +178,7 @@ def iqLastHandler(cl, iq): name = IDentifier["name"] elif source in Transport and id in Transport[source].friends: last = int(time.time() - Transport[source].vk.method("messages.getLastActivity", {"user_id": id}).get("time", -1)) - name = Transport[source].getUserData(id) + name = Transport[source].getUserData(id)["name"] else: raise xmpp.NodeProcessed() result = xmpp.Iq("result", to=jidFrom, frm=destination) @@ -298,24 +298,13 @@ def iqGatewayHandler(cl, iq): raise xmpp.NodeProcessed() Sender(cl, result) -def vCardGetPhoto(url, encode=True): - try: - opener = urllib.urlopen(url) - data = opener.read() - if data and encode: - data = data.encode("base64") - return data - except IOError: - pass - except Exception: - crashLog("vcard.getPhoto") def iqVcardBuild(tags): vCard = xmpp.Node("vCard", {"xmlns": xmpp.NS_VCARD}) for key in tags.keys(): if key == "PHOTO": - binVal = vCard.setTag("PHOTO") - binVal.setTagData("BINVAL", vCardGetPhoto(tags[key])) + photo = vCard.setTag("PHOTO") + photo.setTagData("BINVAL", utils.getLinkData(tags[key])) else: vCard.setTagData(key, tags[key]) return vCard diff --git a/library/utils.py b/library/utils.py index 3fe87e2..f817ea1 100644 --- a/library/utils.py +++ b/library/utils.py @@ -2,7 +2,7 @@ # This file is a part of VK4XMPP transport # © simpleApps, 2014. -import xmpp +import xmpp, urllib def buildDataForm(form=None, type="submit", fields=[]): form = form or xmpp.DataForm(type) @@ -12,4 +12,12 @@ def buildDataForm(form=None, type="submit", fields=[]): field.setPayload(key["payload"]) if key.get("label"): field.setLabel(key["label"]) - return form
\ No newline at end of file + return form + + +def getLinkData(url, encode=True): + opener = urllib.urlopen(url) + data = opener.read() + if data and encode: + data = data.encode("base64") + return data diff --git a/locales/locale.ru b/locales/locale.ru index 56b986b..aa32bb6 100644 --- a/locales/locale.ru +++ b/locales/locale.ru @@ -14,7 +14,7 @@ User is not your friend.=Пользователь не ваш друг! Your friend-list is empty.=Ваш список друзей пуст! You're not registered for this action.=Вы должны быть зарегистрированы для этого дейстия. Auth failed! If this error repeated, please register again. This incident will be reported.=Авторизация не удалась. Если эта ошибка повторяется, пожалуйста, зарегистрируйтесь заново. Об этом инциденте будет сообщено. -\nForward messages:=\nПересланные сообщения: +Forward messages:=Пересланные сообщения: \nAttachments:=\nВложения: Enter shown text=Введите показанный текст New user registered: %s=Зарегистрирован новый пользователь: %s |