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>2016-12-25 14:27:34 +0300
committerJohn Smith <mrdoctorwho@gmail.com>2016-12-25 14:27:34 +0300
commita5354a9f365dd3e18f10314d25dd36609671d640 (patch)
tree73ffaa31150b01a659c949f78662be8b456f387d
parent291eadf050602bc27ff9addbdf89bcc6d90e4304 (diff)
Make roster check xmpp-based
-rw-r--r--gateway.py29
-rw-r--r--library/utils.py36
-rw-r--r--modules/mod_prs_main.py52
3 files changed, 89 insertions, 28 deletions
diff --git a/gateway.py b/gateway.py
index 36794f2..68c34d0 100644
--- a/gateway.py
+++ b/gateway.py
@@ -194,7 +194,7 @@ def getGatewayRev():
"""
Gets gateway revision using git or custom revision number
"""
- number, hash = 317, 0
+ number, hash = 360, 0
shell = os.popen("git describe --always &"
"& git log --pretty=format:''").readlines()
if shell:
@@ -208,9 +208,9 @@ def vk2xmpp(id):
Args:
id: a Jabber or VK id
Returns:
- id@TransportID if parameter id is a number
- id if parameter "id" is id@TransportID
- TransportID if the given id is equal to TransportID
+ id@TransportID if parameter id is a number (String)
+ id if parameter "id" is id@TransportID (Integer)
+ TransportID if the given id is equal to TransportID (String)
"""
if not utils.isNumber(id) and "@" in id:
id = id.split("@")[0]
@@ -835,11 +835,9 @@ class User(object):
del self.typing[user]
sendMessage(self.source, vk2xmpp(user), typ="paused")
- def updateFriends(self, cTime):
+ def updateStatus(self, cTime):
"""
- Updates friends list.
- Compares the current friends list to the new list
- Takes a corresponding action if any difference found
+ Updates user's status
"""
if (cTime - self.last_udate) > 300 and not self.vk.engine.captcha:
if self.settings.keep_online:
@@ -847,19 +845,6 @@ class User(object):
else:
self.vk.setOffline()
self.last_udate = cTime
- friends = self.vk.getFriends()
- if not friends:
- logger.error("updateFriends: no friends received (jid: %s).",
- self.source)
- return None
-
- for uid in friends:
- if uid not in self.friends:
- self.sendSubPresence({uid: friends[uid]})
- for uid in self.friends:
- if uid not in friends:
- sendPresence(self.source, vk2xmpp(uid), "unsubscribe")
- self.friends = friends
def reauth(self):
"""
@@ -979,7 +964,7 @@ def updateCron():
for user in Users.values():
cTime = time.time()
user.updateTypingUsers(cTime)
- user.updateFriends(cTime)
+ user.updateStatus(cTime)
time.sleep(2)
def calcStats():
diff --git a/library/utils.py b/library/utils.py
index ef00d39..42d0711 100644
--- a/library/utils.py
+++ b/library/utils.py
@@ -200,4 +200,40 @@ def TimeMachine(text):
time += int(current[:-1]) * TIME_VALUES[x]
return time
+
+class ExpiringObject(object):
+ def __init__(self, obj, lifetime):
+ self.obj = obj
+ self.created = time.time()
+ self.lifetime = lifetime
+
+ def hasExpired(self):
+ return (time.time() >= (self.created + self.lifetime))
+
+ def __getattr__(self, attr):
+ try:
+ result = object.__getattribute__(self, attr)
+ except AttributeError:
+ result = getattr(self.obj, attr)
+ return result
+
+ def __iter__(self):
+ if hasattr(self.obj, "__iter__"):
+ return self.obj.__iter__()
+ raise TypeError("Not iterable")
+
+ def next(self):
+ if hasattr(self.obj, "next"):
+ return self.obj.next()
+ raise TypeError("Not iterable")
+
+ # TODO what if our object isn't iterable?
+ def __str__(self):
+ result = ""
+ for num, i in enumerate(self.obj):
+ result += str(i)
+ if num < (len(self.obj) -1):
+ result += ", "
+ return result
+
# Yay!
diff --git a/modules/mod_prs_main.py b/modules/mod_prs_main.py
index 9c9da11..b832880 100644
--- a/modules/mod_prs_main.py
+++ b/modules/mod_prs_main.py
@@ -8,8 +8,36 @@ Module purpose is to receive and handle presences
from __main__ import *
from __main__ import _
+from utils import *
-USERS_ON_INIT = set([])
+# keeps the user's roster
+USERS_ON_INIT = {}
+EXPIRING_OBJECT_LIFETIME = 600
+UPDATE_FRIENDS_DELAY = 60
+
+
+def updateFriends(user, local):
+ """
+ Compares the local (xmpp) and remote (vk) list of friends
+ """
+ if TransportID in local:
+ local.remove(TransportID)
+ if not user.vk.online:
+ return None
+
+ friends = user.friends or user.vk.getFriends()
+ if not friends or not local:
+ logger.error("updateFriends: no friends received (local: %s, remote: %s) (jid: %s).",
+ str(local), str(friends), user.source)
+ return None
+
+ for uid in friends:
+ if uid not in local:
+ user.sendSubPresence({uid: friends[uid]})
+ # TODO
+ # for uid in self.friends:
+ # if uid not in friends:
+ # sendPresence(self.source, vk2xmpp(uid), "unsubscribe")
def initializeUser(source, resource, prs):
@@ -30,10 +58,12 @@ def initializeUser(source, resource, prs):
report(crashLog("user.connect"))
else:
user.initialize(send=True, resource=resource) # probably we need to know resource a bit earlier than this time
+ utils.runThread(updateFriends, (user, list(USERS_ON_INIT[source])), # making a copy so we can remote it safely
+ delay=UPDATE_FRIENDS_DELAY)
utils.runThread(executeHandlers, ("prs01", (source, prs)))
if source in USERS_ON_INIT:
- USERS_ON_INIT.remove(source)
+ del USERS_ON_INIT[source]
def presence_handler(cl, prs):
@@ -50,6 +80,8 @@ def presence_handler(cl, prs):
logger.debug("Received presence %s from user. Calling sendInitPresence() (jid: %s)" % (pType, source))
user.resources.add(resource)
utils.runThread(user.sendInitPresence)
+ elif source in USERS_ON_INIT:
+ USERS_ON_INIT[source].add(vk2xmpp(destination))
elif pType == "unavailable":
if destination == TransportID and resource in user.resources:
@@ -85,11 +117,19 @@ def presence_handler(cl, prs):
removeUser(user, True, False)
executeHandlers("evt09", (source,))
- elif pType in ("available", None) and destination == TransportID:
+ # when user becomes online, we get subscribe as we don't have both subscription
+ elif pType not in ("error", "unavailable"):
# It's possible to receive more than one presence from @gmail.com
- if source not in USERS_ON_INIT:
- utils.runThread(initializeUser, args=(source, resource, prs))
- USERS_ON_INIT.add(source)
+ if source in USERS_ON_INIT:
+ roster = USERS_ON_INIT[source]
+ if destination == TransportID and TransportID not in roster and pType in ("available", "probe", None):
+ utils.runThread(initializeUser, args=(source, resource, prs))
+ else:
+ __set = set([])
+ USERS_ON_INIT[source] = ExpiringObject(__set, EXPIRING_OBJECT_LIFETIME)
+ if destination == TransportID:
+ utils.runThread(initializeUser, args=(source, resource, prs))
+ USERS_ON_INIT[source].add(vk2xmpp(destination))
utils.runThread(executeHandlers, ("prs01", (source, prs)))