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:
authorJohn Smith <mrdoctorwho@gmail.com>2017-03-14 16:17:04 +0300
committerJohn Smith <mrdoctorwho@gmail.com>2017-03-14 16:17:04 +0300
commit26a9ce51183269acacbf4cdb7cf91d06682985ab (patch)
tree67304b96f7335392b9fe35582f5e1f6eae294d63
parentf6bf2b50a9391b685b9e59d4996ba72565923a6e (diff)
Make the gateway work for communitiesgroups
-rw-r--r--extensions/attachments.py6
-rw-r--r--extensions/forwarded_messages.py2
-rw-r--r--extensions/groupchats.py556
-rw-r--r--extensions/interpreter.py5
-rw-r--r--extensions/subscribe_on_message.py17
-rw-r--r--extensions/user_nickname.py2
-rw-r--r--gateway.py28
-rw-r--r--library/forms.py4
-rw-r--r--modules/mod_groupchat_msg.py65
-rw-r--r--modules/mod_groupchat_prs.py111
-rw-r--r--modules/mod_iq_register.py3
11 files changed, 39 insertions, 760 deletions
diff --git a/extensions/attachments.py b/extensions/attachments.py
index 16400de..f925e1e 100644
--- a/extensions/attachments.py
+++ b/extensions/attachments.py
@@ -47,9 +47,9 @@ def parseAttachments(self, msg, spacer=""):
if self.settings.parse_wall:
tid = current.get("to_id", 1)
if tid > 0:
- name = "%s's" % self.vk.getUserData(tid)["name"]
+ name = "%s's" % self.vk.getUserData(tid, notoken=True)["name"]
else:
- name = "“%s”" % self.vk.getGroupData(tid)["name"]
+ name = "“%s”" % self.vk.getGroupData(tid, notoken=True)["name"]
body += "Post on %s wall:\n" % name
if current.get("text") or current.get("copy_text"):
body += spacer + uhtml(compile_eol.sub("\n" + spacer, current["text"] or current.get("copy_text"))) + "\n"
@@ -79,7 +79,7 @@ def parseAttachments(self, msg, spacer=""):
elif type == "wall_reply":
# TODO: What if it's a community? from_id will be negative.
# TODO: Remove "[idxxx|Name]," from the text or make it a link if XHTML is allowed
- current["name"] = self.vk.getUserData(current["uid"])["name"]
+ current["name"] = self.vk.getUserData(current["uid"], notoken=True)["name"]
current["text"] = uhtml(compile_eol.sub("\n" + spacer, current["text"]))
current["url"] = WALL_COMMENT_LINK % current
diff --git a/extensions/forwarded_messages.py b/extensions/forwarded_messages.py
index 43148b6..24c3fa8 100644
--- a/extensions/forwarded_messages.py
+++ b/extensions/forwarded_messages.py
@@ -22,7 +22,7 @@ def parseForwardedMessages(self, msg, depth=0):
date = fwd["date"]
fwdBody = escape("", uhtml(compile_eol.sub("\n" + spacer + BASE_SPACER, fwd["body"])))
date = datetime.fromtimestamp(date).strftime("%d.%m.%Y %H:%M:%S")
- name = self.vk.getUserData(source)["name"]
+ name = self.vk.getUserData(source, notoken=True)["name"]
body += "\n%s[%s] <%s> %s" % (spacer + BASE_SPACER, date, name, fwdBody)
body += parseAttachments(self, fwd, spacer + (BASE_SPACER * 2))
if depth < MAXIMUM_FORWARD_DEPTH:
diff --git a/extensions/groupchats.py b/extensions/groupchats.py
deleted file mode 100644
index 454e935..0000000
--- a/extensions/groupchats.py
+++ /dev/null
@@ -1,556 +0,0 @@
-# coding: utf-8
-# This file is a part of VK4XMPP transport
-# © simpleApps, 2013 — 2015.
-# File contains parts of code from
-# BlackSmith mark.1 XMPP Bot, © simpleApps 2011 — 2014.
-
-# Installation:
-# The extension requires up to 2 fields in the main config:
-# 1. ConferenceServer - the address of your (or not yours?) conference server
-# Bear in mind that there can be limits on the jabber server for conference per jid. Read the wiki for more details.
-# 2. CHAT_LIFETIME_LIMIT - the limit of the time after that user considered inactive and will be removed.
-# Time must be formatted as text and contain the time variable measurement.
-# For example: CHAT_LIFETIME_LIMIT = "28y09M21d" means chat will be removed after 28 years 9 Months 21 days from now
-# You can wheter ignore or use any of these chars: smdMy.
-# Used chars: s for seconds, m for minutes, d for days, M for months, y for years. The number MUST contain 2 digits as well.
-# Note: if you won't set the field, plugin won't remove any chat, but still will be gathering statistics.
-
-
-"""
-Handles VK Multi-Dialogs
-Implements XEP-0045: Multi-User Chat (over an exsisting chat)
-Note: This file contains only outgoing-specific stuff (vk->xmpp)
-along with the Chat class and other useful functions
-The code which handles incoming stuff (xmpp->vk) is placed in the following modules:
-mod_groupchat_prs for presence handling
-mod_groupchat_msg for message handling
-"""
-
-MAX_UPDATE_DELAY = 3600 # 1 hour
-CHAT_CLEANUP_DELAY = 86400 # 24 hours
-
-if not require("attachments") or not require("forwarded_messages"):
- raise AssertionError("extension 'groupchats' requires 'forwarded_messages' and 'attachments'")
-
-
-def setAffiliation(chat, afl, jid, jidFrom=TransportID, reason=None):
- """
- Set user affiliation in a chat.
- Parameters:
- * chat - the chat to set affiliation in
- * afl - the affiliation to set to
- * jid - the user's jid whose affiliation needs to be changed
- * jidFrom - the chat's owner jid (or anyone who can set users roles)
- * reason - special reason
- """
- stanza = xmpp.Iq("set", to=chat, frm=jidFrom)
- query = xmpp.Node("query", {"xmlns": xmpp.NS_MUC_ADMIN})
- arole = query.addChild("item", {"jid": jid, "affiliation": afl})
- if reason:
- arole.setTagData("reason", reason)
- stanza.addChild(node=query)
- sender(Component, stanza)
-
-
-def inviteUser(chat, jidTo, jidFrom, name):
- """
- Invite user to a chat.
- Parameters:
- * chat - the chat to invite to
- * jidTo - the user's jid who needs to be invited
- * jidFrom - the inviter's jid
- * name - the inviter's name
- """
- invite = xmpp.Message(to=chat, frm=jidFrom)
- x = xmpp.Node("x", {"xmlns": xmpp.NS_MUC_USER})
- inv = x.addChild("invite", {"to": jidTo})
- inv.setTagData("reason", _("You're invited by user «%s»") % name)
- invite.addChild(node=x)
- sender(Component, invite)
-
-
-def joinChat(chat, name, jidFrom, status=None):
- """
- Join a chat.
- Parameters:
- * chat - the chat to join in
- * name - nickname
- * jidFrom - jid which will be displayed when joined
- * status - special status
- """
- prs = xmpp.Presence("%s/%s" % (chat, name), frm=jidFrom, status=status)
- prs.setTag("c", {"node": TRANSPORT_CAPS_HASH, "ver": hash, "hash": "sha-1"},
- xmpp.NS_CAPS)
- sender(Component, prs)
-
-
-def leaveChat(chat, jidFrom, reason=None):
- """
- Leave chat.
- Parameters:
- * chat - chat to leave from
- * jidFrom - jid to leave with
- * reason - special reason
- """
- prs = xmpp.Presence(chat, "unavailable", frm=jidFrom, status=reason)
- sender(Component, prs)
-
-
-def chatMessage(chat, text, jidFrom, subj=None, timestamp=0):
- """
- Sends a message to the chat
- """
- message = xmpp.Message(chat, typ="groupchat")
- if timestamp:
- timestamp = time.gmtime(timestamp)
- message.setTimestamp(time.strftime("%Y%m%dT%H:%M:%S", timestamp))
- if not subj:
- message.setBody(text)
- else:
- message.setSubject(text)
- message.setFrom(jidFrom)
- executeHandlers("msg03g", (message, chat, jidFrom))
- sender(Component, message)
-
-
-def setChatConfig(chat, jidFrom, exterminate=False, cb=None, args={}):
- """
- Sets the chat config
- """
- iq = xmpp.Iq("set", to=chat, frm=jidFrom)
- query = iq.addChild("query", namespace=xmpp.NS_MUC_OWNER)
- if exterminate:
- query.addChild("destroy")
- else:
- 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": "0"},
- {"var": "muc#roomconfig_persistentroom", "type": "boolean", "value": "1"},
- {"var": "muc#roomconfig_whois", "value": "anyone"}],
- type="submit")
- query.addChild(node=form)
- sender(Component, iq, cb, args)
-
-
-def handleOutgoingChatMessage(user, vkChat):
- """
- Handles outging VK messages and sends them to XMPP
- """
- if "chat_id" in vkChat:
- # check if the groupchats support enabled in user's settings
- if not user.settings.groupchats:
- return None
-
- if not hasattr(user, "chats"):
- user.chats = {}
-
- # TODO: make this happen in the kernel, so we don't need to check it here
- if not user.vk.userID:
- logger.warning("groupchats: we didn't receive user id, trying again after 10 seconds (jid: %s)", user.source)
- user.vk.getUserID()
- utils.runThread(handleOutgoingChatMessage, (user, vkChat), delay=10)
- return None
-
- owner = vkChat.get("admin_id", "1")
- chatID = vkChat["chat_id"]
- chatJID = "%s_chat#%s@%s" % (user.vk.userID, chatID, ConferenceServer)
- chat = createChat(user, chatJID)
- if not chat.initialized:
- chat.init(owner, chatID, chatJID, vkChat["title"], vkChat["date"], vkChat["chat_active"].split(","))
- if not chat.created:
- if chat.creation_failed:
- return None
- # we can add user, vkChat to the create() method to prevent losing or messing up the messages
- chat.create(user)
- # read the comments above the handleMessage function
- if not chat.created:
- time.sleep(1.5)
- chat.handleMessage(user, vkChat)
- return None
- return ""
-
-
-def createChat(user, source):
- """
- Creates a chat
- Args:
- user: the User object
- source: the chat's jid
- """
- if not hasattr(user, "chats"):
- user.chats = {}
- if source in user.chats:
- chat = user.chats[source]
- else:
- user.chats[source] = chat = Chat()
- return chat
-
-
-class Chat(object):
- """
- Class used to handle multi-user dialogs
- """
- def __init__(self):
- self.created = False
- self.invited = False
- self.initialized = False
- self.exists = False
- self.creation_failed = False
- self.owner_nickname = None
- self.source = None
- self.jid = None
- self.owner = None
- self.subject = None
- self.creation_date = None
- self.id = 0
- self.last_update = 0
- self.raw_users = {}
- self.users = {}
-
- def init(self, owner, id, jid, subject, date, users=[]):
- """
- Assigns an id and other needed attributes to the class object
- Args:
- owner: owner's id (str)
- id: chat's id (int)
- jid: chat's jid (str)
- subject: chat's subject
- date: the chat creation date
- users: dictionary of ids, id: {"name": nickname, "jid": jid}
- """
- self.id = id
- self.jid = jid
- self.owner = owner
- self.raw_users = users
- self.subject = subject
- self.creation_date = date
- self.initialized = True
-
- def create(self, user):
- """
- Creates a chat, joins it and sets the config
- """
- logger.debug("groupchats: creating %s. Users: %s; owner: %s (jid: %s)",
- self.jid, self.raw_users, self.owner, user.source)
- exists = runDatabaseQuery("select user from groupchats where jid=?", (self.jid,), many=True)
- if exists:
- self.exists = True
- logger.debug("groupchats: groupchat %s exists in the database (jid: %s)",
- self.jid, user.source)
- else:
- logger.debug("groupchats: groupchat %s will be added to the database (jid: %s)",
- self.jid, user.source)
- runDatabaseQuery("insert into groupchats (jid, owner, user, last_used) values (?,?,?,?)",
- (self.jid, TransportID, user.source, time.time()), True)
-
- name = user.vk.getUserData(self.owner)["name"]
- self.users[TransportID] = {"name": name, "jid": TransportID}
- # We join to the chat with the room owner's name to set the room subject from their name.
- joinChat(self.jid, name, TransportID, "Lost in time.")
- setChatConfig(self.jid, TransportID, False, self.onConfigSet, {"user": user})
-
- def initialize(self, user, chat):
- """
- Initializes chat object:
- 1) requests users list if required
- 2) makes them members
- 3) invites the user
- 4) sets the chat subject
- Parameters:
- chat: chat's jid
- """
- if not self.raw_users:
- vkChat = self.getVKChat(user, self.id) # getting the chat users
- if not vkChat and not self.invited:
- logger.error("groupchats: damn vk didn't answer to the chat list "
- "request, starting timer to try again (jid: %s)", user.source)
- utils.runThread(self.initialize, (user, chat), delay=10)
- return False
- self.raw_users = vkChat.get("users")
-
- name = "@%s" % TransportID
- setAffiliation(chat, "member", user.source)
- if not self.invited:
- inviteUser(chat, user.source, TransportID, user.vk.getUserData(self.owner)["name"])
- logger.debug("groupchats: user has been invited to chat %s (jid: %s)", chat, user.source)
- self.invited = True
- self.setSubject(self.subject, self.creation_date)
- joinChat(chat, name, TransportID, "Lost in time.") # let's rename ourselves
- self.users[TransportID] = {"name": name, "jid": TransportID}
-
- def update(self, userObject, vkChat):
- """
- Updates chat users and sends messages
- Uses two user lists to prevent losing of any of them
- """
- all_users = vkChat["chat_active"].split(",")
- all_users = [int(user) for user in all_users if user]
- if userObject.settings.show_all_chat_users:
- users = self.getVKChat(userObject, self.id)
- if users:
- all_users = users.get("users", [])
- old_users = self.users.keys()
- buddies = all_users + old_users
- if TransportID in buddies:
- buddies.remove(TransportID)
- if userObject.vk.getUserID() in buddies:
- buddies.remove(userObject.vk.getUserID())
-
- for user in buddies:
- jid = vk2xmpp(user)
- if user not in old_users:
- logger.debug("groupchats: user %s has joined the chat %s (jid: %s)",
- user, self.jid, userObject.source)
- name = userObject.vk.getUserData(user)["name"]
- self.users[int(user)] = {"name": name, "jid": jid}
- setAffiliation(self.jid, "member", jid)
- joinChat(self.jid, name, jid)
-
- elif user not in all_users:
- logger.debug("groupchats: user %s has left the chat %s (jid: %s)",
- user, self.jid, userObject.source)
- leaveChat(self.jid, jid)
- del self.users[user]
-
- subject = vkChat["title"]
- if subject and subject != self.subject:
- self.setSubject(subject)
- self.raw_users = all_users
-
-
- def setSubject(self, subject, date=None):
- """
- Changes the chat subject
- """
- chatMessage(self.jid, subject, TransportID, True, date)
- self.subject = subject
-
- def onConfigSet(self, cl, stanza, user):
- """
- A callback which called after attempt to create the chat
- """
- chat = stanza.getFrom().getStripped()
- if xmpp.isResultNode(stanza):
- self.created = True
- logger.debug("groupchats: stanza \"result\" received from %s, "
- "continuing initialization (jid: %s)", chat, user.source)
- utils.execute(self.initialize, (user, chat))
- else:
- logger.error("groupchats: couldn't set room %s config, the answer is: %s (jid: %s)",
- chat, str(stanza), user.source)
- self.creation_failed = True
-
- # there's a possibility to mess up here if many messages were sent before we created the chat
- # we have to send the messages immendiately as soon as possible, so delay can mess the messages up
- def handleMessage(self, user, vkChat, retry=True):
- """
- Handle incoming (VK -> XMPP) messages
- """
- if self.created:
- self.update(user, vkChat)
- body = escape("", uhtml(vkChat["body"]))
- body += parseAttachments(user, vkChat)
- body += parseForwardedMessages(user, vkChat)
- if body:
- chatMessage(self.jid, body, vk2xmpp(vkChat["uid"]), None)
- else:
- source = "unknown"
- userObject = self.getUserObject(self.jid)
- if userObject:
- source = userObject.source
- # todo: FULL leave on error and try to create the chat again
- logger.warning("groupchats: chat %s wasn't created well, so trying to create it again (jid: %s)", self.jid, source)
- logger.warning("groupchats: is there any groupchat limit on the server?")
- if retry:
- # TODO: We repeat it twice on each message. We shouldn't.
- self.handleMessage(user, vkChat, False)
-
- def isUpdateRequired(self):
- """
- Tells whether it's required to update the chat's last_used time
- Returns:
- True if required
- """
- if not self.source:
- return False
- if not self.last_update:
- return True
- if (time.time() - self.last_update) > MAX_UPDATE_DELAY:
- return True
- return False
-
- @api.attemptTo(3, dict, RuntimeError)
- def getVKChat(cls, user, id):
- """
- Get vk chat by id
- """
- chat = user.vk.method("messages.getChat", {"chat_id": id})
- if not chat:
- raise RuntimeError("Unable to get a chat!")
- return chat
-
- @classmethod
- def getParts(cls, source):
- """
- Split the source and return required parts
- """
- node, domain = source.split("@")
- if "_chat#" in node:
- creator, id = node.split("_chat#")
- else:
- return (None, None, None)
- return (int(creator), int(id), domain)
-
- @classmethod
- def getUserObject(cls, source):
- """
- Gets user object by chat jid
- """
- user = None
- jid = None
- creator, id, domain = cls.getParts(source)
- if domain == ConferenceServer and creator:
- jid = cls.getJIDByID(id)
- if not jid:
- jid = runDatabaseQuery("select user from groupchats where jid=?", (source,), many=False)
- if jid:
- jid = jid[0]
- if jid and jid in Users:
- user = Users[jid]
- return user
-
- @staticmethod
- def getJIDByID(id):
- for key, value in Users.iteritems():
- if key == id:
- return value
- return None
-
-
-def updateLastUsed(chat):
- """
- Updates the last_used field in the database
- Args:
- chat: the Chat object
- """
- runDatabaseQuery("update groupchats set last_used=? where jid=?", (time.time(), chat.source), set=True)
-
-
-def exterminateChats(user=None, chats=[]):
- """
- Calls a Dalek for exterminate the chat
- The chats argument must be a list of tuples
- """
- def exterminated(cl, stanza, jid):
- """
- The callback that's being called when the stanza we sent's got an answer
- Args:
- cl: the xmpp.Client object
- stanza: the result stanza
- jid: the jid stanza's sent from (?)
- """
- chat = stanza.getFrom().getStripped()
- if xmpp.isResultNode(stanza):
- logger.debug("groupchats: target exterminated! Yay! target:%s (jid: %s)", chat, jid)
- else:
- logger.debug("groupchats: explain! Explain! "
- "The chat wasn't exterminated! Target: %s (jid: %s)", chat, jid)
- logger.error("groupchats: got stanza: %s (jid: %s)", str(stanza), jid)
-
- if user and not chats:
- chats = runDatabaseQuery("select jid, owner, user from groupchats where user=?", (user.source,))
-
- # current chats
- userChats = getattr(user, "chats", [])
- for (jid, owner, source) in chats:
- server = owner
- if "@" in owner:
- server = owner.split("@")[1]
- if server == TransportID:
- joinChat(jid, "Dalek", owner, "Exterminate!")
- logger.debug("groupchats: going to exterminate %s, owner:%s (jid: %s)", jid, owner, source)
- setChatConfig(jid, owner, True, exterminated, {"jid": jid})
- # remove the chat from current
- if jid in userChats:
- del userChats[jid]
- else:
- # if we try to send from another jid with prosody, we'll be killed
- logger.warning("Warning: Was the transport moved from other domain? Groupchat %s deletion skipped.", jid)
- runDatabaseQuery("delete from groupchats where jid=?", (jid,), set=True)
-
-
-def initChatsTable():
- """
- Initializes database if it doesn't exist
- """
- def checkColumns():
- """
- Checks and adds additional column(s) into the groupchats table
- """
- info = runDatabaseQuery("pragma table_info(groupchats)")
- names = [col[1] for col in info]
- if "nick" not in names:
- logger.warning("groupchats: adding \"nick\" column to groupchats table")
- runDatabaseQuery("alter table groupchats add column nick text", set=True)
-
- runDatabaseQuery("create table if not exists groupchats "
- "(jid text, owner text,"
- "user text, last_used integer, nick text)", set=True)
- checkColumns()
- return True
-
-
-def cleanTheChatsUp():
- """
- Calls Dalek(s) to exterminate inactive users or their chats, whatever they catch
- """
- chats = runDatabaseQuery("select jid, owner, last_used, user from groupchats")
- result = []
- for (jid, owner, last_used, user) in chats:
- if (time.time() - last_used) >= utils.TimeMachine(CHAT_LIFETIME_LIMIT):
- result.append((jid, owner, user))
- logger.debug("groupchats: time for %s expired (jid: %s)", jid, user)
- if result:
- exterminateChats(chats=result)
- utils.runThread(cleanTheChatsUp, delay=CHAT_CLEANUP_DELAY)
-
-
-def initChatExtension():
- """
- Initializes the extension"
- """
- global mod_xhtml
- try:
- import mod_xhtml
- except ImportError:
- mod_xhtml = None
- if initChatsTable():
- if isdef("CHAT_LIFETIME_LIMIT"):
- cleanTheChatsUp()
- else:
- logger.warning("not starting chats cleaner because CHAT_LIFETIME_LIMIT is not set")
-
-
-if isdef("ConferenceServer") and ConferenceServer:
- # G is for Groupchats. That's it.
- Handlers["msg03g"] = []
-
- GLOBAL_USER_SETTINGS["groupchats"] = {"label": "Handle groupchats",
- "desc": "If set, transport would create xmpp-chatrooms for VK Multi-Dialogs", "value": 1}
-
- GLOBAL_USER_SETTINGS["show_all_chat_users"] = {"label": "Show all chat users",
- "desc": "If set, transport will show ALL users in a conference", "value": 0}
-
- TRANSPORT_SETTINGS["destroy_on_leave"] = {"label": "Destroy groupchat if user leaves it", "value": 0}
-
- TransportFeatures.add(xmpp.NS_GROUPCHAT)
- registerHandler("msg01", handleOutgoingChatMessage)
- registerHandler("evt01", initChatExtension)
- registerHandler("evt03", exterminateChats)
- logger.info("extension groupchats is loaded")
-
-else:
- del setAffiliation, inviteUser, joinChat, leaveChat, \
- handleOutgoingChatMessage, chatMessage, Chat, \
- exterminateChats, cleanTheChatsUp, initChatExtension
diff --git a/extensions/interpreter.py b/extensions/interpreter.py
index 1c20fd9..0ce5694 100644
--- a/extensions/interpreter.py
+++ b/extensions/interpreter.py
@@ -2,6 +2,7 @@
# This file is a part of VK4XMPP transport
# © simpleApps, 2015.
+import traceback
def interpreter_msg02(msg):
body = msg.getBody()
@@ -19,14 +20,14 @@ def interpreter_msg02(msg):
try:
result = unicode(eval(args))
except Exception:
- result = returnExc()
+ result = traceback.format_exc()
sendMessage(source, destination, result)
elif text == "!exec" and args and source in ADMIN_JIDS:
try:
exec (unicode(args + "\n"), globals())
except Exception:
- result = returnExc()
+ result = traceback.format_exc()
else:
result = "Done."
sendMessage(source, destination, result)
diff --git a/extensions/subscribe_on_message.py b/extensions/subscribe_on_message.py
new file mode 100644
index 0000000..62b1073
--- /dev/null
+++ b/extensions/subscribe_on_message.py
@@ -0,0 +1,17 @@
+# coding: utf-8
+# This file is a part of VK4XMPP transport
+# © simpleApps, 2017.
+
+
+known_sources = [] # TODO: database
+
+def subscribe_msg03(msg, destination, source):
+ if source not in known_sources and destination in Users:
+ user = Users[destination]
+ id = vk2xmpp(source)
+ data = user.vk.getUserData(id, notoken=True)
+ dict = {id: {"name":data.get("name", "Anonymous User")}}
+ user.sendSubPresence(dict)
+ known_sources.append(source)
+
+registerHandler("msg03", subscribe_msg03) \ No newline at end of file
diff --git a/extensions/user_nickname.py b/extensions/user_nickname.py
index e13a43b..308606b 100644
--- a/extensions/user_nickname.py
+++ b/extensions/user_nickname.py
@@ -15,7 +15,7 @@ def add_username(stanza, user, uid):
key = "name"
if user.settings.use_nicknames:
key = "screen_name"
- name = user.vk.getUserData(uid)[key]
+ name = user.vk.getUserData(uid, notoken=True)[key]
else:
name = IDENTIFIER["name"]
stanza.setTag("nick", namespace=xmpp.NS_NICK)
diff --git a/gateway.py b/gateway.py
index 8161f2a..4aba5d3 100644
--- a/gateway.py
+++ b/gateway.py
@@ -286,8 +286,6 @@ class VK(object):
"""
logger.debug("VK going to authenticate (jid: %s)", self.source)
self.engine = api.APIBinding(self.token, DEBUG_API, self.source)
- if not self.checkToken():
- raise api.TokenError("The token is invalid (jid: %s, token: %s)" % (self.source, self.token))
self.online = True
return True
@@ -370,14 +368,15 @@ class VK(object):
roster = False
m = e.message
# TODO: Make new exceptions for each of the conditions below
- if m == "User authorization failed: user revoke access for this token.":
+ if m.endswith("user revoke access for this token."):
roster = True
- elif m == "User authorization failed: invalid access_token.":
+ elif m.endswith("invalid access_token."):
sendMessage(self.source, TransportID,
- m + " Please, register again")
- utils.runThread(removeUser, (self.source, roster))
+ m11 + " Please, register again")
+ # don't do this for now
+# utils.runThread(removeUser, (self.source, roster))
+# self.online = False
logger.error("VK: apiError %s (jid: %s)", m, self.source)
- self.online = False
else:
return result
logger.error("VK: error %s occurred while executing"
@@ -393,7 +392,6 @@ class VK(object):
self.online = False
logger.debug("VK: user %s has left", self.source)
executeHandlers("evt06", (self,))
- self.setOffline()
def setOffline(self):
"""
@@ -491,7 +489,7 @@ class VK(object):
return self.permissions
@utils.cache
- def getGroupData(self, gid, fields=None):
+ def getGroupData(self, gid, fields=None, **kwargs):
"""
Gets group data (only name so far)
Args:
@@ -501,13 +499,12 @@ class VK(object):
The group information
"""
fields = fields or ["name"]
- data = self.method("groups.getById", {"group_id": abs(gid), "fields": str.join(",", fields)})
+ data = self.method("groups.getById", {"group_id": abs(gid), "fields": str.join(",", fields)}, **kwargs)
if data:
data = data[0]
return data
- @utils.cache
- def getUserData(self, uid, fields=None):
+ def getUserData(self, uid, fields=None, **kwargs):
"""
Gets user data. Such as name, photo, etc
Args:
@@ -521,7 +518,7 @@ class VK(object):
if user and uid in user.friends:
return user.friends[uid]
fields = ["screen_name"]
- data = self.method("users.get", {"user_ids": uid, "fields": str.join(",", fields)})
+ data = self.method("users.get", {"user_ids": uid, "fields": str.join(",", fields)}, **kwargs)
if data:
data = data[0]
data["name"] = self.formatName(data)
@@ -768,10 +765,6 @@ class User(object):
Takes a corresponding action if any difference found
"""
if (cTime - self.last_udate) > 300 and not self.vk.engine.captcha:
- if self.settings.keep_online:
- self.vk.setOnline()
- else:
- self.vk.setOffline()
self.last_udate = cTime
friends = self.vk.getFriends()
if not friends:
@@ -905,7 +898,6 @@ def updateCron():
for user in Users.values():
cTime = time.time()
user.updateTypingUsers(cTime)
- user.updateFriends(cTime)
time.sleep(2)
def calcStats():
diff --git a/library/forms.py b/library/forms.py
index 2791969..049b9a6 100644
--- a/library/forms.py
+++ b/library/forms.py
@@ -9,8 +9,8 @@ class Forms:
@classmethod
def getSimpleForm(cls):
form = []
- form.append({"var": "link", "type": "text-single",
- "label": _("Autorization page"), "value": URL_ACCEPT_APP})
+ # form.append({"var": "link", "type": "text-single",
+ # "label": _("Autorization page"), "value": URL_ACCEPT_APP})
form.append({"var": "password", "type": "text-private",
"label": _("Access-token"),
"desc": _("Enter the access token")})
diff --git a/modules/mod_groupchat_msg.py b/modules/mod_groupchat_msg.py
deleted file mode 100644
index 0257b97..0000000
--- a/modules/mod_groupchat_msg.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# coding: utf-8
-# This file is a part of VK4XMPP transport
-# © simpleApps, 2013 — 2015.
-
-"""
-Module purpose is to handle messages from groupchats
-"""
-
-from __main__ import *
-
-
-def incoming_message_handler(cl, msg):
- """
- Handles incoming (xmpp) messages and sends them to VK
- """
- if msg.getType() == "groupchat":
- body = msg.getBody()
- destination = msg.getTo().getStripped()
- nick = msg.getFrom().getResource()
- source = msg.getFrom().getStripped()
- if mod_xhtml:
- html = msg.getTag("html")
- else:
- html = None
-
- x = msg.getTag("x", {"xmlns": xmpp.NS_MUC_USER})
- if x and x.getTagAttr("status", "code") == "100":
- raise xmpp.NodeProcessed()
-
- if not msg.getTimestamp() and body and destination == TransportID:
- user = Chat.getUserObject(source)
- creator, id, domain = Chat.getParts(source)
- owner_nickname = None
- if user:
- if source in getattr(user, "chats", {}):
- owner_nickname = user.chats[source].owner_nickname
- if not owner_nickname:
- owner_nickname = runDatabaseQuery("select nick from groupchats where jid=?",
- (source,), many=False)[0]
- # None of “normal” clients will send messages with timestamp
- # If we do (as we set in force_vk_date_group), then the message received from a user
- # If we don't and nick (as in settings) is tied to the chat, then we can determine who sent the message
- send = (nick == owner_nickname)
- chat = createChat(user, source)
- chat.invited = True # the user has joined themselves, so we don't need to invite them
- if html and html.getTag("body"):
- logger.debug("groupchats: fetched xhtml image (jid: %s)" % source)
- try:
- mod_xhtml.parseXHTML(user, html, source, source, "chat_id")
- except Exception:
- pass
- else:
- # Don't send a message if there's an image
- raise xmpp.NodeProcessed()
- if send:
- with user.sync:
- user.vk.sendMessage(body, id, "chat_id")
- if chat.isUpdateRequired():
- updateLastUsed(chat)
- raise xmpp.NodeProcessed()
-
-
-MOD_TYPE = "message"
-MOD_HANDLERS = ((incoming_message_handler, "", "", False),)
-MOD_FEATURES = []
diff --git a/modules/mod_groupchat_prs.py b/modules/mod_groupchat_prs.py
deleted file mode 100644
index 88486b6..0000000
--- a/modules/mod_groupchat_prs.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# coding: utf-8
-# This file is a part of VK4XMPP transport
-# © simpleApps, 2013 — 2016.
-
-"""
-Module purpose is to handle presences from groupchats
-"""
-
-from __main__ import *
-from __main__ import _
-
-
-def handleChatErrors(source, prs):
- """
- Handles error presences from groupchats
- Args:
- source: the source jid
- prs: the xmpp.Presence object
- """
- # todo: leave on 401, 403, 405
- # and rejoin timer on 404, 503
- destination = prs.getTo().getStripped()
- error = prs.getErrorCode()
- status = prs.getStatusCode()
- nick = prs.getFrom().getResource()
- jid = prs.getJid()
- errorType = prs.getTagAttr("error", "type")
- user = Chat.getUserObject(source)
- if user and source in getattr(user, "chats", {}):
- chat = user.chats[source]
- if chat.creation_failed:
- raise xmpp.NodeProcessed()
-
- if error == "409" and errorType == "cancel":
- id = vk2xmpp(destination)
- if id in chat.users:
- nick += "."
- if not chat.created and id == TransportID:
- chat.users[id]["name"] = nick
- chat.create(user)
- else:
- joinChat(source, nick, destination)
-
- if status == "303":
- if jid == user.source:
- chat.owner_nickname = prs.getNick()
- runDatabaseQuery("update groupchats where jid=? set nick=?",
- (source, chat.owner_nickname), set=True)
- elif error or status:
- logger.debug("groupchats: presence error (error #%s, status #%s) "
- "from source %s (jid: %s)" % (error, status, source, user.source if user else "unknown"))
- raise xmpp.NodeProcessed()
-
-
-def handleChatPresences(source, prs):
- """
- Makes the old users leave
- Args:
- source: stanza source
- prs: xmpp.Presence object
- """
- jid = prs.getJid() or ""
- if "@" in jid:
- user = Chat.getUserObject(source)
- if user and source in getattr(user, "chats", {}):
- chat = user.chats[source]
- if jid.split("@")[1] == TransportID and chat.created:
- id = vk2xmpp(jid)
- if id != TransportID and id not in chat.users.keys():
- if (time.gmtime().tm_mon, time.gmtime().tm_mday) == (4, 1):
- setAffiliation(source, "outcast", jid, reason=_("Get the hell outta here!"))
- else:
- leaveChat(source, jid, _("I am not welcomed here"))
-
- if (prs.getRole(), prs.getAffiliation()) == ("moderator", "owner"):
- if jid != TransportID:
- runDatabaseQuery("update groupchats set owner=? where jid=?", (source, jid), set=True)
-
- if chat.isUpdateRequired():
- updateLastUsed(chat)
-
- # TODO: don't rewrite it every time we get a presence
- if jid.split("/")[0] == user.source:
- chat.owner_nickname = prs.getFrom().getResource()
- runDatabaseQuery("update groupchats set nick=? where jid=? ", (chat.owner_nickname, source), set=True)
- raise xmpp.NodeProcessed()
-
- elif user and prs.getType() != "unavailable":
- chat = createChat(user, source)
- chat.invited = True # assume the user's joined themselves
-
-
-
-@utils.safe
-def presence_handler(cl, prs):
- """
- xmpppy presence callback
- Args:
- cl: the xmpp.Client object
- prs: the xmpp.Presence object
- """
- source = prs.getFrom().getStripped()
- status = prs.getStatus()
- if status or prs.getType() == "error":
- handleChatErrors(source, prs)
- handleChatPresences(source, prs) # It won't be called if handleChatErrors was called in the first time
-
-
-MOD_TYPE = "presence"
-MOD_HANDLERS = ((presence_handler, "", "", True),)
-MOD_FEATURES = []
diff --git a/modules/mod_iq_register.py b/modules/mod_iq_register.py
index fa5092e..239a72c 100644
--- a/modules/mod_iq_register.py
+++ b/modules/mod_iq_register.py
@@ -92,7 +92,8 @@ def register_handler(cl, iq):
def sendRegisterForm(cl, iq):
logger.debug("Send registration form to user (jid: %s)", iq.getFrom().getStripped())
- form = utils.buildDataForm(fields=forms.Forms.getComlicatedForm(), data=[_("Fill the fields below")])
+ form = utils.buildDataForm(fields=forms.Forms.getSimpleForm(), data=[_("Fill the fields below")])
+ form.setTag("next")
result = iq.buildReply("result")
result.setQueryPayload([form])
sender(cl, result)