Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mrDoctorWho/vk4xmpp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrDoctorWho <mrdoctorwho@gmail.com>2014-05-26 12:53:05 +0400
committermrDoctorWho <mrdoctorwho@gmail.com>2014-05-26 12:53:05 +0400
commit58d81c8af25ca7e6d18f1a1894b019bd22ef1e0e (patch)
treee3f70f53d5733f6d8fd0124c5f309fe8f644e941
parent6f88a7054f5a4e7c5c98c657cae1b564282b6f81 (diff)
fixed: html-escape in attachments
fixed: groupchats are members-only again fixed: ignore error-cods 1,9,100 added: xhtml-im in groupchats added: groupchats deletion when user ungregistered also: a little code cleanup
-rw-r--r--extensions/attachments.py4
-rw-r--r--extensions/captcha_forms.py36
-rw-r--r--extensions/groupchats.py104
-rw-r--r--gateway.py126
-rw-r--r--handlers/IQ.py4
-rw-r--r--handlers/Message.py26
-rw-r--r--handlers/Presence.py3
-rw-r--r--library/utils.py15
-rw-r--r--library/vkapi.py12
-rw-r--r--library/webtools.py35
10 files changed, 186 insertions, 179 deletions
diff --git a/extensions/attachments.py b/extensions/attachments.py
index abf3e2d..3ee4aca 100644
--- a/extensions/attachments.py
+++ b/extensions/attachments.py
@@ -25,6 +25,10 @@ def parseAttachments(self, msg):
elif key == "video":
body += "\nVideo: http://vk.com/video%(owner_id)s_%(vid)s — %(title)s"
elif key == "audio":
+ for _key in ("performer", "title"):
+ if att[key].has_key(_key):
+ att[key][_key] = uHTML(att[key][_key])
+
url = searchlink % urllib.quote(str("%(performer)s %(title)s" % att[key]))
att[key]["url"] = url
body += "\nAudio: %(performer)s — %(title)s — %(url)s"
diff --git a/extensions/captcha_forms.py b/extensions/captcha_forms.py
new file mode 100644
index 0000000..05536b6
--- /dev/null
+++ b/extensions/captcha_forms.py
@@ -0,0 +1,36 @@
+# coding: utf-8
+# This file is a part of VK4XMPP transport
+
+from hashlib import sha1
+
+def captchaSend(self):
+ logger.debug("VKLogin: sending message with captcha to %s" % self.source)
+ body = _("WARNING: VK sent captcha to you."
+ " Please, go to %s and enter text from image to chat."
+ " Example: !captcha my_captcha_key. Tnx") % self.engine.captcha["img"]
+ msg = xmpp.Message(self.source, body, "chat", frm = TransportID)
+ 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)
+ if image:
+ hash = sha1(image).hexdigest()
+ encoded = image.encode("base64")
+ form = utils.buildDataForm(type="form", fields = [{"var": "FORM_TYPE", "value": xmpp.NS_CAPTCHA, "type": "hidden"},
+ {"var": "from", "value": TransportID, "type": "hidden"},
+ {"var": "ocr", "label": _("Enter shown text"),
+ "payload": [xmpp.Node("required"), xmpp.Node("media", {"xmlns": xmpp.NS_MEDIA},
+ [xmpp.Node("uri", {"type": "image/jpg"},
+ ["cid:sha1+%s@bob.xmpp.org" % hash])])]}])
+ captcha.addChild(node=form)
+ oob = msg.setTag("data", {"cid": "sha1+%s@bob.xmpp.org" % hash, "type": "image/jpg", "max-age": "0"}, xmpp.NS_URN_OOB)
+ oob.setData(encoded)
+ else:
+ logger.critical("VKLogin: can't add captcha image to message url:%s" % self.engine.captcha["img"])
+ Sender(Component, msg)
+ Presence = xmpp.protocol.Presence(self.source, frm=TransportID)
+ Presence.setStatus(body)
+ Presence.setShow("xa")
+ Sender(Component, Presence)
+
+Handlers["evt04"].append(captchaSend) \ No newline at end of file
diff --git a/extensions/groupchats.py b/extensions/groupchats.py
index ba37696..c5eb202 100644
--- a/extensions/groupchats.py
+++ b/extensions/groupchats.py
@@ -25,31 +25,27 @@ def inviteUser(chat, jidTo, jidFrom, name):
invite.addChild(node=x)
Sender(Component, invite)
-def buildConfigForm(form=None, type="sumbit", fields=[]):
- form = form or xmpp.DataForm(type)
- for key in fields:
- field = form.setField(key["var"], key.get("value"), key.get("type"))
- return form
## TODO: Set chatroom's name
-def groupchatSetConfig(chat, jidFrom, exterminate=False):
- iq = xmpp.Iq("set", to=chat, frm=jidFrom, xmlns="jabber:component:accept")
+def chatSetConfig(chat, jidFrom, exterminate=False):
+ iq = xmpp.Iq("set", to=chat, frm=jidFrom)
query = iq.addChild("query", namespace=xmpp.NS_MUC_OWNER)
if exterminate:
query.addChild("destroy")
else:
- form = buildConfigForm(fields = [{"var": "FORM_TYPE", "type": "hidden", "value": xmpp.NS_MUC_ROOMCONFIG},
+ form = utils.buildDataForm(fields = [{"var": "FORM_TYPE", "type": "hidden", "value": xmpp.NS_MUC_ROOMCONFIG},
{"var": "muc#roomconfig_membersonly", "type": "boolean", "value": "1"},
{"var": "muc#roomconfig_publicroom", "type": "boolean", "value": "1"},
{"var": "muc#roomconfig_whois", "value": "anyone"}])
query.addChild(node=form)
Sender(Component, iq)
-def groupchatPresence(chat, name, jidFrom, type=None):
+def chatPresence(chat, name, jidFrom, type=None):
prs = xmpp.Presence("%s/%s" % (chat, name), type, frm=jidFrom)
+ prs.setTag("c", {"node": "http://simpleapps.ru/caps/vk4xmpp", "ver": Revision}, xmpp.NS_CAPS)
Sender(Component, prs)
-def groupchatMessage(chat, text, jidFrom, subj=None, timestamp=0):
+def chatMessage(chat, text, jidFrom, subj=None, timestamp=0):
message = xmpp.Message(chat, typ="groupchat")
if timestamp:
timestamp = time.gmtime(timestamp)
@@ -61,90 +57,96 @@ def groupchatMessage(chat, text, jidFrom, subj=None, timestamp=0):
message.setFrom(jidFrom)
Sender(Component, message)
-def handleChatMessages(self, msg):
+def outgoungChatMessageHandler(self, msg):
if msg.has_key("chat_id"):
idFrom = msg["uid"]
owner = msg["admin_id"]
_owner = vk2xmpp(owner)
- chatID = "%s_chat#%s" % (self.UserID, msg["chat_id"]) ## Maybe better to use owner id for chat
+ chatID = "%s_chat#%s" % (self.UserID, msg["chat_id"])
chat = "%s@%s" % (chatID, ConferenceServer)
- users = msg["chat_active"].split(",") ## Why chat owner isn't in a chat? It may cause problems. Or not?
+ users = msg["chat_active"].split(",")
users.append(self.UserID)
if not users: ## is it possible?
logger.debug("groupchats: all users exterminated in chat: %s" % chat)
if chat in self.chatUsers:
- groupchatPresence(chat, self.getUserData(owner)["name"], vk2xmpp(self.UserID), "unavailable")
+ chatPresence(chat, self.getUserData(owner)["name"], vk2xmpp(self.UserID), "unavailable")
del self.chatUsers[chat]
- return None # Maybe true?
+ return None
if chat not in self.chatUsers:
logger.debug("groupchats: creating %s. Users: %s; owner: %s" % (chat, msg["chat_active"], owner))
self.chatUsers[chat] = []
for usr in (owner, self.UserID):
- groupchatPresence(chat, self.getUserData(usr)["name"], vk2xmpp(usr))
- groupchatSetConfig(chat, _owner)
+ chatPresence(chat, self.getUserData(usr)["name"], vk2xmpp(usr))
+ chatSetConfig(chat, _owner)
member(chat, self.source, _owner)
- inviteUser(chat, self.source, _owner, self.getUserData(owner)["name"]) ## TODO: Handle WHO invited me. Yes, i know that it'll be never happen. But maybe someone another do it for himself? You're welcome!
- groupchatMessage(chat, msg["title"], _owner, True, msg["date"])
+ inviteUser(chat, self.source, _owner, self.getUserData(owner)["name"])
+ chatMessage(chat, msg["title"], _owner, True, msg["date"])
- for user in users: ## BURN IT!
+ for user in users:
if not user in self.chatUsers[chat]:
logger.debug("groupchats: user %s has joined the chat %s" % (user, chat))
self.chatUsers[chat].append(user)
uName = self.getUserData(user)["name"]
user = vk2xmpp(user)
member(chat, user, _owner)
- groupchatPresence(chat, uName, user)
+ chatPresence(chat, uName, user)
- for user in self.chatUsers[chat]: ## BURN IT MORE!
+ for user in self.chatUsers[chat]:
if not user in users:
logger.debug("groupchats: user %s has left the chat %s" % (user, chat))
self.chatUsers[chat].remove(user)
uName = self.getUserData(user)["name"]
- groupchatPresence(chat, uName, vk2xmpp(user), "unavailable")
-
- # This code will not work because function can be called only at message in chat
- if not self.chatUsers[chat]: # Impossible
- logger.debug("groupchats: %s would be exterminated right now!" % chat)
- groupchatSetConfig(chat, _owner, exterminate=True) # EXTERMINATE!!!
+ chatPresence(chat, uName, vk2xmpp(user), "unavailable")
body = escape("", uHTML(msg["body"]))
body += parseAttachments(self, msg)
body += parseForwardMessages(self, msg)
if body:
- groupchatMessage(chat, body, vk2xmpp(idFrom), None, msg["date"])
+ chatMessage(chat, body, vk2xmpp(idFrom), None, msg["date"])
return None
return ""
-def incomingGroupchatMessageHandler(msg):
+def incomingChatMessageHandler(msg):
if msg.getType() == "groupchat":
body = msg.getBody()
- jidToStr = msg.getTo().getStripped()
- jidFromStr = msg.getFrom().getStripped()
- xTag = msg.getTag("x", {"xmlns": "http://jabber.org/protocol/muc#user"})
- if xTag and xTag.getTagAttr("status", "code") == "100":
+ destination = msg.getTo().getStripped()
+ source = msg.getFrom().getStripped()
+ html = msg.getTag("html")
+ x = msg.getTag("x", {"xmlns": "http://jabber.org/protocol/muc#user"})
+
+ if x and x.getTagAttr("status", "code") == "100":
raise xmpp.NodeProcessed()
if not msg.getTimestamp() and body:
- Node, Domain = jidFromStr.split("@")
+ Node, Domain = source.split("@")
if Domain == ConferenceServer:
- jidToStr = vk2xmpp(jidToStr)
- if jidToStr in jidToID:
- jid = jidToID[jidToStr]
- user = Transport[jid]
- user.msg(body, Node.split("#")[1], "chat_id")
-
-
-## TODO:
-##def onShutdown():
-## for user in Transport.values():
-## if user.chatUsers
-##
+ destination = vk2xmpp(destination)
+ if destination in jidToID:
+ jid = jidToID[destination]
+ if jid in Transport:
+ user = Transport[jid]
+ if html and html.getTag("body"): ## XHTML-IM!
+ logger.debug("groupchats: fetched xhtml image from %s" % source)
+ try:
+ xhtml = xhtmlParse(user, html, source, source, "chat_id")
+ except Exception:
+ xhtml = False
+ if xhtml:
+ raise xmpp.NodeProcessed()
+ user.msg(body, Node.split("#")[1], "chat_id")
+
+
+def chatDestroy(user):
+ chats = user.vk.method("execute.getChats")
+ for chat in chats:
+ chatSetConfig("%s_chat#%s@%s" % (user.UserID, chat["chat_id"], ConferenceServer), vk2xmpp(chat["admin_id"]), True)
if ConferenceServer:
TransportFeatures.append(xmpp.NS_GROUPCHAT)
- Handlers["msg01"].append(handleChatMessages)
- Handlers["msg02"].append(incomingGroupchatMessageHandler)
-## Handlers["shutdown"] TODO
+ Handlers["msg01"].append(outgoungChatMessageHandler)
+ Handlers["msg02"].append(incomingChatMessageHandler)
+ Handlers["evt03"].append(chatDestroy)
+
else:
- del incomingGroupchatMessageHandler, handleChatMessages, inviteUser, groupchatPresence, groupchatMessage
+ del incomingChatMessageHandler, outgoungChatMessageHandler, inviteUser, chatPresence, chatMessage
diff --git a/gateway.py b/gateway.py
index 6f67c61..ca9ce49 100644
--- a/gateway.py
+++ b/gateway.py
@@ -17,8 +17,6 @@ import sys
import threading
import time
-from hashlib import sha1
-
core = getattr(sys.modules["__main__"], "__file__", None)
if core:
core = os.path.abspath(core)
@@ -31,6 +29,7 @@ reload(sys).setdefaultencoding("utf-8")
import vkapi as api
import xmpp
+import utils
from itypes import Database
from webtools import *
@@ -116,7 +115,7 @@ loggerHandler.setFormatter(Formatter)
logger.addHandler(loggerHandler)
def gatewayRev():
- revNumber, rev = 163, 0 # 0. means testing.
+ revNumber, rev = 167, 0 # 0. means testing.
shell = os.popen("git describe --always && git log --pretty=format:''").readlines()
if shell:
revNumber, rev = len(shell), shell[0]
@@ -126,8 +125,14 @@ OS = "{0} {2:.16} [{4}]".format(*os.uname())
Python = "{0} {1}.{2}.{3}".format(sys.subversion[0], *sys.version_info)
Revision = gatewayRev()
+## Events (not finished yet so not sorted):
+## 01 - start
+## 02 - shutdown
+## 03 - user deletion
+## 04 - captcha
Handlers = {"msg01": [], "msg02": [],
- "evt01": [], "evt02": []}
+ "evt01": [], "evt02": [],
+ "evt03": [], "evt04": []}
Stats = {"msgin": 0, ## from vk
"msgout": 0} ## to vk
@@ -139,7 +144,7 @@ def initDatabase(filename):
db.commit()
return True
-def executeFunction(handler, list = ()):
+def execute(handler, list = ()):
try:
handler(*list)
except SystemExit:
@@ -147,6 +152,11 @@ def executeFunction(handler, list = ()):
except Exception:
crashLog(handler.func_name)
+## TODO: execute threaded handlers
+def executeHandlers(type, list = ()):
+ for handler in Handlers[type]:
+ execute(handler, list)
+
def startThr(thr, number = 0):
if number > 2:
raise RuntimeError("exit")
@@ -156,7 +166,7 @@ def startThr(thr, number = 0):
startThr(thr, (number + 1))
def threadRun(func, args = (), name = None):
- thr = threading.Thread(target = executeFunction, args = (func, args), name = name or func.func_name)
+ thr = threading.Thread(target = execute, args = (func, args), name = name or func.func_name)
try:
thr.start()
except threading.ThreadError:
@@ -167,34 +177,10 @@ def threadRun(func, args = (), name = None):
badChars = [x for x in xrange(32) if x not in (9, 10, 13)] + [57003, 65535]
escape = re.compile("|".join(unichr(x) for x in badChars), re.IGNORECASE | re.UNICODE | re.DOTALL).sub
+msgSort = lambda msgOne, msgTwo: msgOne.get("mid", 0) - msgTwo.get("mid", 0)
require = lambda name: os.path.exists("extensions/%s.py" % name)
-def deleteUser(user, roster = False, semph = Semaphore):
- logger.debug("User: deleting user %s from db." % user.source)
- with Database(DatabaseFile, semph) as db: ## WARNING: this may cause main thread lock
- db("delete from users where jid=?", (user.source,))
- db.commit()
- user.existsInDB = False
- friends = getattr(user, "friends")
- if roster and friends:
- logger.debug("User: deleting me from %s roster" % user.source)
- for id in friends.keys():
- jid = vk2xmpp(id)
- sendPresence(user.source, jid, "unsubscribe")
- sendPresence(user.source, jid, "unsubscribed")
-
- elif roster:
- sendPresence(user.source, TransportID, "unsubscribe")
- sendPresence(user.source, TransportID, "unsubscribed")
-
- vk = getattr(user, "vk") or user
- if user.source in Transport:
- vk.Online = False
- del Transport[user.source]
- Poll.remove(user)
-
-
class VKLogin(object):
def __init__(self, number, password = None, source = None):
@@ -286,14 +272,14 @@ class VKLogin(object):
if self.engine.lastMethod[0] == "messages.send":
msgSend(Component, self.source, _("You're not allowed to perform this action."), vk2xmpp(args.get("user_id", TransportID)))
except api.VkApiError as e:
- db = False
+ roster = False
if e.message == "User authorization failed: user revoke access for this token.":
logger.critical("VKLogin: %s" % e.message)
- db = True
+ 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), db)
+ deleteUser(Transport.get(self.source, self), roster, False)
except KeyError:
pass
@@ -306,38 +292,7 @@ class VKLogin(object):
def captchaChallenge(self):
if self.engine.captcha:
- logger.debug("VKLogin: sending message with captcha to %s" % self.source)
- body = _("WARNING: VK sent captcha to you."
- " Please, go to %s and enter text from image to chat."
- " Example: !captcha my_captcha_key. Tnx") % self.engine.captcha["img"]
- msg = xmpp.Message(self.source, body, "chat", frm = TransportID)
- xTag = msg.setTag("x", {}, xmpp.NS_OOB)
- xTag.setTagData("url", self.engine.captcha["img"])
- cTag = msg.setTag("captcha", {}, xmpp.NS_CAPTCHA)
- imgData = vCardGetPhoto(self.engine.captcha["img"], False)
- if imgData:
- imgHash = sha1(imgData).hexdigest()
- imgEncoded = imgData.encode("base64")
- form = xmpp.DataForm("form")
- form.setField("FORM_TYPE", xmpp.NS_CAPTCHA, "hidden")
- form.setField("from", TransportID, "hidden")
- field = form.setField("ocr")
- field.setLabel(_("Enter shown text"))
-## field.delAttr("type")
- field.setPayload([xmpp.Node("required"),
- xmpp.Node("media", {"xmlns": xmpp.NS_MEDIA},
- [xmpp.Node("uri", {"type": "image/jpg"},
- ["cid:sha1+%s@bob.xmpp.org" % imgHash])])])
- cTag.addChild(node=form)
- obTag = msg.setTag("data", {"cid": "sha1+%s@bob.xmpp.org" % imgHash, "type": "image/jpg", "max-age": "0"}, xmpp.NS_URN_OOB)
- obTag.setData(imgEncoded)
- else:
- logger.critical("VKLogin: can't add captcha image to message url:%s" % self.engine.captcha["img"])
- Sender(Component, msg)
- Presence = xmpp.protocol.Presence(self.source, frm = TransportID)
- Presence.setStatus(body)
- Presence.setShow("xa")
- Sender(Component, Presence)
+ executeHandlers("evt04", (self,))
else:
logger.error("VKLogin: captchaChallenge called without captcha for user %s" % self.source)
@@ -369,7 +324,6 @@ class VKLogin(object):
values["last_message_id"] = lastMsgID
return self.method("messages.get", values)
-
def sendPresence(target, source, pType = None, nick = None, reason = None, caps = None):
Presence = xmpp.Presence(target, pType, frm = source, status = reason)
if nick:
@@ -407,7 +361,7 @@ class User(object):
logger.debug("User: %s exists in db. Have to use it." % self.source)
self.existsInDB = True
self.source, self.username, self.token, self.lastMsgID, self.rosterSet = desc
- elif self.password or self.token: ## Warning: this may work wrong. If user exists in db we shouldn't delete him, we just should replace his token
+ elif self.password or self.token:
logger.debug("User: %s exists in db. Record would be deleted." % self.source)
threadRun(deleteUser, (self,))
@@ -520,7 +474,6 @@ class User(object):
else:
data = data.pop()
data["name"] = escape("", u"%s %s" % (data.pop("first_name"), data.pop("last_name")))
-
return data
def sendMessages(self, init=False):
@@ -616,7 +569,7 @@ class User(object):
if not friends:
logger.error("updateFriends: no friends received (user: %s)." % self.source)
return None
- if friends and set(friends) != set(self.friends):
+ if friends:
for uid in friends:
if uid not in self.friends:
self.rosterSubscribe({uid: friends[uid]})
@@ -635,7 +588,30 @@ class User(object):
except Exception:
crashLog("tryAgain")
-msgSort = lambda msgOne, msgTwo: msgOne.get("mid", 0) - msgTwo.get("mid", 0)
+def deleteUser(user, roster = False, semph = Semaphore):
+ logger.debug("User: deleting user %s from db." % user.source)
+ with Database(DatabaseFile, semph) as db: ## WARNING: this may cause main thread lock
+ db("delete from users where jid=?", (user.source,))
+ db.commit()
+ user.existsInDB = False
+ friends = getattr(user, "friends", {})
+ if roster and friends:
+ logger.debug("User: deleting me from %s roster" % user.source)
+ for id in friends.keys():
+ jid = vk2xmpp(id)
+ sendPresence(user.source, jid, "unsubscribe")
+ sendPresence(user.source, jid, "unsubscribed")
+
+ elif roster:
+ sendPresence(user.source, TransportID, "unsubscribe")
+ sendPresence(user.source, TransportID, "unsubscribed")
+ executeHandlers("evt03", (user,))
+
+ vk = getattr(user, "vk", user)
+ if user.source in Transport:
+ vk.Online = False
+ del Transport[user.source]
+ Poll.remove(user)
def Sender(cl, stanza):
try:
@@ -697,6 +673,8 @@ def userTyping(target, instance, typ = "composing"):
message.setTag(typ, namespace = xmpp.NS_CHATSTATES)
Sender(Component, message)
+
+## TODO: make it as extension
def watcherMsg(text):
for jid in WatcherList:
msgSend(Component, jid, text, TransportID)
@@ -710,8 +688,7 @@ def disconnectHandler(crash = True):
Component.disconnect()
except (NameError, AttributeError):
pass
- for event in Handlers["evt02"]:
- event()
+ executeHandlers("evt02")
Print("Reconnecting...")
time.sleep(5)
os.execl(sys.executable, sys.executable, *sys.argv)
@@ -887,8 +864,7 @@ def exit(signal = None, frame = None):
user.sendOutPresence(user.source, status)
Print("." * len(user.friends), False)
Print("\n")
- for event in Handlers["evt02"]:
- event()
+ executeHandlers("evt02")
try:
os.remove(pidFile)
except OSError:
diff --git a/handlers/IQ.py b/handlers/IQ.py
index 85df324..bb0b738 100644
--- a/handlers/IQ.py
+++ b/handlers/IQ.py
@@ -42,7 +42,6 @@ def iqHandler(cl, iq):
if jidTo == TransportID:
Sender(cl, iq.buildReply("result"))
- raise xmpp.NodeProcessed()
def iqBuildError(stanza, error = None, text = None):
if not error:
@@ -177,7 +176,6 @@ def iqUptimeHandler(cl, iq):
result.setTag("query", {"seconds": str(uptime)}, xmpp.NS_LAST)
result.setTagData("query", IDentifier["name"])
Sender(cl, result)
- raise xmpp.NodeProcessed()
def iqVersionHandler(cl, iq):
iType = iq.getType()
@@ -189,7 +187,6 @@ def iqVersionHandler(cl, iq):
Query.setTagData("version", Revision)
Query.setTagData("os", "%s / %s" % (OS, Python))
Sender(cl, result)
- raise xmpp.NodeProcessed()
sDict = {
"users/total": "users",
@@ -263,7 +260,6 @@ def iqDiscoHandler(cl, iq):
result.setQueryPayload(QueryPayload)
Sender(cl, result)
- raise xmpp.NodeProcessed()
def iqGatewayHandler(cl, iq):
jidTo = iq.getTo()
diff --git a/handlers/Message.py b/handlers/Message.py
index e99e8c6..955ae92 100644
--- a/handlers/Message.py
+++ b/handlers/Message.py
@@ -14,8 +14,17 @@ def msgRecieved(msg, jidFrom, jidTo):
answer.setID(msg.getID())
return answer
-def sendPhoto(user, data, type, address):
+def sendPhoto(user, data, type, address, mType):
mask = user.vk.method("account.getAppPermissions")
+
+ if mType == "chat_id":
+ address = address.split("@")[0].split("#")[1]
+ send = False
+ else:
+ destination = address
+ address = vk2xmpp(address)
+ send = True
+
if address == TransportID:
answer = _("Are you kidding me?")
elif mask:
@@ -30,7 +39,8 @@ def sendPhoto(user, data, type, address):
photo = user.vk.method("photos.saveMessagesPhoto", response)[0]
id = photo["id"]
- user.msg("", vk2xmpp(address), more = {"attachment": id})
+
+ user.msg("", address, mType, {"attachment": id})
logger.debug("sendPhoto: image was successfully sent by user %s" % user.source)
answer = _("Your image was successfully sent.")
else:
@@ -38,12 +48,13 @@ def sendPhoto(user, data, type, address):
" Seems you haven't enough permissions. Your token should be updated, register again.")
else:
answer = _("Something went wrong. We are so sorry.")
- msgSend(Component, user.source, answer, address, timestamp = 1)
+ if send:
+ msgSend(Component, user.source, answer, destination, timestamp = 1)
-def xhtmlParse(user, html, source, destination):
+def xhtmlParse(user, html, source, destination, mType = "user_id"):
body = html.getTag("body")
if body:
- ## TODO: Maybe would be better if use regular expressions?
+ ## TODO: Maybe would be better use regular expressions?
src = body.getTagAttr("img", "src")
raw_data = src.split("data:")[1]
mime_type = raw_data.split(";")[0]
@@ -52,9 +63,9 @@ def xhtmlParse(user, html, source, destination):
try:
data = urllib.unquote(data).decode("base64")
except Exception:
- logger.error("msgHandler: fetched wrong xhtml image from %s" % source)
+ logger.error("xhmtlParse: fetched wrong xhtml image from %s" % source)
return False
- threadRun(sendPhoto, (user, data, mime_type, destination))
+ threadRun(sendPhoto, (user, data, mime_type, destination, mType))
return True
def msgHandler(cl, msg):
@@ -136,7 +147,6 @@ def captchaAccept(cl, args, jidTo, source):
answer = _("Captcha valid.")
Poll.add(user)
Presence = xmpp.protocol.Presence(source, frm = TransportID)
- #Presence.setStatus("") # is it needed?
Presence.setShow("available")
Sender(Component, Presence)
user.tryAgain()
diff --git a/handlers/Presence.py b/handlers/Presence.py
index 8d008c7..f0aba07 100644
--- a/handlers/Presence.py
+++ b/handlers/Presence.py
@@ -2,6 +2,7 @@
# This file is a part of VK4XMPP transport
# © simpleApps, 2013 — 2014.
+
def prsHandler(cl, prs):
pType = prs.getType()
jidFrom = prs.getFrom()
@@ -60,7 +61,7 @@ def prsHandler(cl, prs):
db("select jid,username from users where jid=?", (source,))
data = db.fetchone()
if data:
- logger.debug("User %s found in db" % source)
+ logger.debug("User %s has been found in db" % source)
jid, phone = data
Transport[jid] = user = User((phone, None), jid)
try:
diff --git a/library/utils.py b/library/utils.py
new file mode 100644
index 0000000..3fe87e2
--- /dev/null
+++ b/library/utils.py
@@ -0,0 +1,15 @@
+# coding: utf-8
+# This file is a part of VK4XMPP transport
+# © simpleApps, 2014.
+
+import xmpp
+
+def buildDataForm(form=None, type="submit", fields=[]):
+ form = form or xmpp.DataForm(type)
+ for key in fields:
+ field = form.setField(key["var"], key.get("value"), key.get("type"))
+ if key.get("payload"):
+ field.setPayload(key["payload"])
+ if key.get("label"):
+ field.setLabel(key["label"])
+ return form \ No newline at end of file
diff --git a/library/vkapi.py b/library/vkapi.py
index 41be1e8..86902e1 100644
--- a/library/vkapi.py
+++ b/library/vkapi.py
@@ -115,13 +115,13 @@ class RequestProcessor(object):
request = urllib2.Request(url, data, headers)
return request
- @attemptTo(5, tuple, urllib2.URLError, ssl.SSLError, socket.timeout)
+ @attemptTo(5, tuple, urllib2.URLError, ssl.SSLError, socket.timeout, httplib.BadStatusLine)
def post(self, url, data="", urlencode=True):
resp = self.open(self.request(url, data, urlencode=urlencode))
body = resp.read()
return (body, resp)
- @attemptTo(5, tuple, urllib2.URLError, ssl.SSLError, socket.timeout)
+ @attemptTo(5, tuple, urllib2.URLError, ssl.SSLError, socket.timeout, httplib.BadStatusLine)
def get(self, url, query={}):
if query:
url += "?%s" % urllib.urlencode(query)
@@ -246,7 +246,7 @@ class APIBinding:
if (self.last.pop() - self.last.pop(0)) < 1.1:
time.sleep(0.3)
- response = self.RIP.post(url, values) # Next func should handle NetworkNotFound
+ response = self.RIP.post(url, values)
if response and not nodecode:
body, response = response
if body:
@@ -281,14 +281,14 @@ class APIBinding:
raise VkApiError("Logged out")
elif eCode == 7: # not allowed
raise NotAllowed()
- elif eCode == 9: # ????
- return {}
elif eCode == 10: # internal server error
raise InternalServerError()
- if eCode == 14: # captcha
+ elif eCode == 14: # captcha
if "captcha_sid" in error:
self.captcha = {"sid": error["captcha_sid"], "img": error["captcha_img"]}
raise CaptchaNeeded()
+ elif eCode in (1, 9, 100): ## 1 is an unknown error / 100 is wrong method or parameters loss
+ return {"error": eCode}
raise VkApiError(body["error"])
def retry(self):
diff --git a/library/webtools.py b/library/webtools.py
index d4dc6e8..eb986b0 100644
--- a/library/webtools.py
+++ b/library/webtools.py
@@ -3,9 +3,7 @@
# BlackSmith-bot module.
# © simpleApps, 21.05.2012.
-import urllib, urllib2, re
-
-## HTML Unescape and <br> tag replace.
+import re
import htmlentitydefs
edefs = dict()
@@ -41,25 +39,6 @@ def uHTML(data):
data = re.sub("</?br */?>", "\n", data)
return data
-# TODO: remove this function
-def regexp(reg, string, findall = 1):
- reg = re.compile(reg, re.IGNORECASE | re.DOTALL)
- if findall:
- reg = reg.findall(string)
- else:
- return reg.search(string)
- return reg
-
-## Get HTML tag.
-def getTagData(tag, data, close_tag = 0):
- if not close_tag:
- close_tag = tag
- pattern = re.compile("<%(tag)s.*?>(.*?)</%(close_tag)s>" % vars(), flags = re.DOTALL | re.IGNORECASE)
- tagData = pattern.search(data)
- if tagData:
- tagData = tagData.group(1)
- return tagData or " "
-
def getTagArg(tag, argv, data, close_tag = 0):
if not close_tag:
close_tag = tag
@@ -68,15 +47,3 @@ def getTagArg(tag, argv, data, close_tag = 0):
if tagData:
tagData = tagData.group(1)
return tagData or " "
-
-def stripTags(data, subBy = str(), pattern = "<[^<>]+>"):
- pattern = re.compile(pattern)
- return pattern.sub(subBy, data)
-
-## Format size.
-def byteFormat(size):
- if size < 1024: return '%sb' % int(size)
- for t in ('kB','MB','GB'):
- size = size / 1024.0
- if size < 1024: break
- return '%.2f%s' % (size,t)