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-11-02 08:33:43 +0300
committerJohn Smith <mrdoctorwho@gmail.com>2016-11-02 08:33:43 +0300
commitbbc960130ad0e7550feaed76d4121e269731494f (patch)
treea2dae5eb308b4415fb10e342eb463f279c8f6216
parent32b5e6b62974177edb961a65f296d6555d3b191b (diff)
Code cleanup, fix NameError in groupchats
-rw-r--r--.gitignore5
-rw-r--r--Config_example.txt10
-rw-r--r--extensions/groupchats.py4
-rw-r--r--gateway.py3
-rw-r--r--library/longpoll.py134
-rw-r--r--library/settings.py15
-rw-r--r--library/vkapi.py26
7 files changed, 107 insertions, 90 deletions
diff --git a/.gitignore b/.gitignore
index ce6d8e0..8703759 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,9 @@ pidFile.txt
# exclude custom users.db names
*users.db
vk4xmpp.log
+vk4xmpp.db
+vk4xmpp.sqlite
+vk4xmpp.pid
# exclude log file created after init.d/vk4xmpp start
gateway.log
gateway_v5.0.py
@@ -12,4 +15,4 @@ gateway_v5.0.py
.*project
# exclude ~ bak files
*~
-/.settings
+/.settings
diff --git a/Config_example.txt b/Config_example.txt
index dbf8e15..138d697 100644
--- a/Config_example.txt
+++ b/Config_example.txt
@@ -72,19 +72,19 @@ URL_VCARD_NO_IMAGE = "https://raw.githubusercontent.com/mrDoctorWho/vk4xmpp/mast
THREAD_STACK_SIZE = 0
# Database file (anything you like).
-DatabaseFile = "/var/lib/vk4xmpp/vk4xmpp.db"
+DatabaseFile = "vk4xmpp.sqlite"
# File to store PID in.
-pidFile = "/run/vk4xmpp/vk4xmpp.pid"
+pidFile = "vk4xmpp.pid"
# Log file.
-logFile = "/var/log/vk4xmpp/vk4xmpp.log"
+logFile = "vk4xmpp.log"
# Directory where transport will write crash logs.
-crashDir = "/var/log/vk4xmpp/crash"
+crashDir = "crash"
# Directory for users settings.
-settingsDir = "/var/lib/vk4xmpp/settings"
+settingsDir = "settings"
# Stanza send interval (in seconds).
STANZA_SEND_INTERVAL = 0.03125
diff --git a/extensions/groupchats.py b/extensions/groupchats.py
index 467748d..28bbd26 100644
--- a/extensions/groupchats.py
+++ b/extensions/groupchats.py
@@ -144,7 +144,7 @@ def handleOutgoingChatMessage(user, vkChat):
# 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)" % self.source)
+ 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
@@ -164,7 +164,7 @@ def handleOutgoingChatMessage(user, vkChat):
if not chat.created:
if chat.creation_failed:
return None
- # we can add self, vkChat to the create() function to prevent losing or messing up the messages
+ # we can add user, vkChat to the create() function to prevent losing or messing up the messages
chat.create(user)
# read the comments above the handleMessage function
if not chat.created:
diff --git a/gateway.py b/gateway.py
index bda3dd9..18c3e5f 100644
--- a/gateway.py
+++ b/gateway.py
@@ -311,8 +311,7 @@ class VK(object):
"""
if not self.pollInitialized:
raise api.LongPollError("The Poll wasn't initialized yet")
- opener = api.AsyncHTTPRequest.getOpener(self.pollServer, self.pollConfig)
- return opener
+ return api.AsyncHTTPRequest.getOpener(self.pollServer, self.pollConfig)
def method(self, method, args=None, force=False, notoken=False):
"""
diff --git a/library/longpoll.py b/library/longpoll.py
index 3470323..7970feb 100644
--- a/library/longpoll.py
+++ b/library/longpoll.py
@@ -1,11 +1,8 @@
# coding: utf-8
-# © simpleApps, 2014 — 2015.
+# © simpleApps, 2014 — 2016.
-# Big THANKS to AlKogrun who made it possible
-# to write a single-threaded longpoll client
-
-__authors__ = ("AlKorgun <alkorgun@gmail.com>", "mrDoctorWho <mrdoctorwho@gmail.com>")
-__version__ = "2.2.1"
+__authors__ = ("Al Korgun <alkorgun@gmail.com>", "John Smith <mrdoctorwho@gmail.com>")
+__version__ = "2.2.2"
__license__ = "MIT"
"""
@@ -24,6 +21,7 @@ LONGPOLL_RETRY_COUNT = 10
LONGPOLL_RETRY_TIMEOUT = 10
+# TODO: make it an abstract, to reuse in Steampunk
class Poll(object):
"""
Class used to handle longpoll
@@ -31,6 +29,7 @@ class Poll(object):
__list = {}
__buff = set()
__lock = threading.Lock()
+ clear = staticmethod(__list.clear)
@classmethod
def __add(cls, user):
@@ -39,24 +38,18 @@ class Poll(object):
Adds user in buffer on error occurred
Adds user in self.__list if no errors
"""
- if DEBUG_POLL:
- logger.debug("longpoll: really adding user to poll (jid: %s)", user.source)
- opener = user.vk.makePoll()
- if DEBUG_POLL:
- logger.debug("longpoll: user has been added to poll (jid: %s)", user.source)
- cls.__list[opener.sock] = (user, opener)
- return opener
-
- @classmethod
- def __addToBuff(cls, user):
- """
- Adds user to the list of "bad" users
- The list is mostly contain users whose poll
- request was failed for some reasons
- """
- cls.__buff.add(user)
- logger.debug("longpoll: adding user to the init buffer (jid: %s)", user.source)
- utils.runThread(cls.__initPoll, (user,), "__initPoll-%s" % user.source)
+ if user.source in Transport:
+ # in case the new instance was created
+ user = Transport[user.source]
+ opener = user.vk.makePoll()
+ if DEBUG_POLL:
+ logger.debug("longpoll: user has been added to poll (jid: %s)", user.source)
+ if opener:
+ cls.__list[opener.sock] = (user, opener)
+ return opener
+ logger.warning("longpoll: got null opener! (jid: %s)", user.source)
+ cls.__addToBuffer(user)
+ return None
@classmethod
def add(cls, some_user):
@@ -68,52 +61,77 @@ class Poll(object):
with cls.__lock:
if some_user in cls.__buff:
return None
+ # check if someone tries to add an already existing user
for sock, (user, opener) in cls.__list.iteritems():
if some_user == user:
break
else:
try:
cls.__add(some_user)
- except Exception as e:
- if not isinstance(e, api.LongPollError):
- crashLog("poll.add")
+ except api.LongPollError:
logger.error("longpoll: failed to make poll (jid: %s)", some_user.source)
- cls.__addToBuff(some_user)
+ cls.__addToBuffer(some_user)
+ except Exception:
+ crashLog("poll.add")
- clear = staticmethod(__list.clear)
+ @classmethod
+ def __addToBuffer(cls, user):
+ """
+ Adds user to the list of "bad" users
+ The list is mostly contain users whose poll
+ request was failed for some reasons
+ Args:
+ user: the user object
+ """
+ cls.__buff.add(user)
+ logger.debug("longpoll: adding user to the init buffer (jid: %s)", user.source)
+ utils.runThread(cls.handleUser, (user,), "handleBuffer-%s" % user.source)
+
+ @classmethod
+ def __removeFromBuffer(cls, user):
+ """
+ Instantly removes a user from the buffer
+ Args:
+ user: the user object
+ """
+ if user in cls.__buff:
+ cls.__buff.remove(user)
+
+ @classmethod
+ def removeFromBuffer(cls, user):
+ """
+ Removes a user from the buffer
+ Args:
+ user: the user object
+ """
+ with cls.__lock:
+ cls.__removeFromBuffer(user)
@classmethod
- def __initPoll(cls, user):
+ def handleUser(cls, user):
"""
- Tries to reinitialize poll if needed in 10 times (each 10 seconds)
- As soon as poll initialized user will be removed from buffer
+ Tries to reinitialize poll for LONGPOLL_RETRY_COUNT every LONGPOLL_RETRY_TIMEOUT seconds
+ As soon as poll is initialized the user will be removed from buffer
+ Args:
+ user: the user object
"""
- for x in xrange(LONGPOLL_RETRY_COUNT):
- if user.source not in Transport:
+ for i in xrange(LONGPOLL_RETRY_COUNT):
+ if user.source in Transport:
+ user = Transport[user.source] # we might have a new instance here
+ if user.vk.initPoll():
+ with cls.__lock:
+ logger.debug("longpoll: successfully initialized longpoll (jid: %s)", user.source)
+ cls.__add(user)
+ cls.__removeFromBuffer(user)
+ break
+ else:
logger.debug("longpoll: while we were wasting our time"
", the user has left (jid: %s)", user.source)
- with cls.__lock:
- if user in cls.__buff:
- cls.__buff.remove(user)
+ cls.removeFromBuffer(user)
return None
-
- if Transport[user.source].vk.initPoll():
- with cls.__lock:
- logger.debug("longpoll: successfully initialized longpoll"
- " (jid: %s)", user.source)
- if user not in cls.__buff:
- return None
- cls.__buff.remove(user)
- # Check if user still in transport when we finally came down here
- if user.source in Transport:
- cls.__add(Transport[user.source])
- break
time.sleep(LONGPOLL_RETRY_TIMEOUT)
else:
- with cls.__lock:
- if user not in cls.__buff:
- return None
- cls.__buff.remove(user)
+ cls.removeFromBuffer(user)
logger.error("longpoll: failed to add user to poll in 10 retries"
" (jid: %s)", user.source)
@@ -121,8 +139,7 @@ class Poll(object):
def process(cls):
"""
Processes poll sockets by select.select()
- As soon as socket will be ready to be read
- will be called user.processPollResult() function
+ As soon as socket will be ready for reading, user.processPollResult() is called
Read processPollResult.__doc__ to learn more about status codes
"""
while ALIVE:
@@ -153,12 +170,8 @@ class Poll(object):
except KeyError:
continue
- # Check if user is still in the memory
+ # Update the user instance
user = Transport.get(user.source)
- # Check if the user haven't left yet
- if not hasattr(user, "vk") or not user.vk.online:
- continue
-
utils.runThread(cls.processResult, (user, opener),
"poll.processResult-%s" % user.source)
@@ -191,4 +204,3 @@ class Poll(object):
user.vk.pollInitialized = False
cls.add(user)
-
diff --git a/library/settings.py b/library/settings.py
index 6e9524a..893753a 100644
--- a/library/settings.py
+++ b/library/settings.py
@@ -1,12 +1,12 @@
# coding: utf-8
# This file is a part of VK4XMPP transport
-# © simpleApps, 2015.
+# © simpleApps, 2015 — 2016.
"""
Provides a way to manage user's and transport's settings
"""
-__author__ = "mrDoctorWho <mrdoctorwho@gmail.com>"
+__author__ = "John Smith <mrdoctorwho@gmail.com>"
from __main__ import settingsDir, rFile, wFile
from copy import deepcopy
@@ -19,8 +19,8 @@ GLOBAL_USER_SETTINGS = {"keep_online": {"label": "Keep my status online",
"use_nicknames": {"label": "Use nicknames instead of real names",
"value": 0}}
-TRANSPORT_SETTINGS = {"send_unavailable": {"label": "Send unavailable from " \
- "friends when user logs off",
+TRANSPORT_SETTINGS = {"send_unavailable": {"label": "Send unavailable from "
+ "friends when a user logs off",
"value": 0}}
@@ -38,7 +38,7 @@ class Settings(object):
self.settings = deepcopy(GLOBAL_USER_SETTINGS)
else:
self.settings = TRANSPORT_SETTINGS
- userSettings = eval(rFile(self.filename)) or {}
+ userSettings = eval(rFile(self.filename)) or {} # TODO: json
for key, values in userSettings.iteritems():
if key in self.settings:
self.settings[key]["value"] = values["value"]
@@ -62,10 +62,7 @@ class Settings(object):
return self.settings[attr]["value"]
elif not hasattr(self, attr):
return False
- elif not self.settings.has_key(attr):
- return False
- else:
- return object.__getattribute__(self, attr)
+ return object.__getattribute__(self, attr)
def exterminate(self):
"""
diff --git a/library/vkapi.py b/library/vkapi.py
index 86fc60f..3546684 100644
--- a/library/vkapi.py
+++ b/library/vkapi.py
@@ -78,7 +78,7 @@ def attemptTo(maxRetries, resultType, *errors):
else:
break
else:
- if hasattr(exc, "errno") and exc.errno == 101:
+ if getattr(exc, "errno", 0) == 101:
raise NetworkNotFound()
data = resultType()
logger.warning("vkapi: Error %s occurred on executing %s(*%s, **%s)",
@@ -96,10 +96,9 @@ def attemptTo(maxRetries, resultType, *errors):
class AsyncHTTPRequest(httplib.HTTPSConnection):
"""
- A method to make asynchronous http request
+ A method to make asynchronous http requests
Provides a way to get a socket object to use in select()
"""
-
def __init__(self, url, data=None, headers=(), timeout=SOCKET_TIMEOUT):
host = urllib.splithost(urllib.splittype(url)[1])[0]
httplib.HTTPSConnection.__init__(self, host, timeout=timeout)
@@ -125,9 +124,10 @@ class AsyncHTTPRequest(httplib.HTTPSConnection):
self.close()
@classmethod
- def getOpener(cls, url, query={}):
+ def getOpener(cls, url, query=None):
"""
Opens a connection to url and returns AsyncHTTPRequest() object
+ Args: query a dict() of query parameters
"""
if query:
url += "?%s" % urllib.urlencode(query)
@@ -190,7 +190,7 @@ class RequestProcessor(object):
return request
@attemptTo(REQUEST_RETRIES, tuple, *ERRORS)
- def post(self, url, data="", urlencode=True):
+ def post(self, url, data=None, urlencode=True):
"""
POST request
"""
@@ -198,9 +198,11 @@ class RequestProcessor(object):
body = resp.read()
return (body, resp)
- def get(self, url, query={}):
+ def get(self, url, query=None):
"""
GET request
+ Args:
+ query: a dict() of query parameters
"""
if query:
url += "?%s" % urllib.urlencode(query)
@@ -287,7 +289,7 @@ class APIBinding(RequestProcessor):
Translates VK errors to python exceptions
Allows to make a password authorization
"""
- def __init__(self, token, debug=[], logline=""):
+ def __init__(self, token, debug=None, logline=""):
self.token = token
self.debug = debug
self.last = []
@@ -301,9 +303,12 @@ class APIBinding(RequestProcessor):
def method(self, method, values=None, notoken=False):
"""
Issues a VK method
- Parameters:
+ Args:
method: vk method
values: method parameters
+ notoken: whether to cut the token out of the request
+ Returns:
+ The method execution result
"""
url = "https://api.vk.com/method/%s" % method
values = values or {}
@@ -379,6 +384,7 @@ class APIBinding(RequestProcessor):
raise ValidationRequired(eMsg)
# 1 - unknown error / 100 - wrong method or parameters loss
+ # todo: where we going we NEED constants
elif eCode in (1, 6, 9, 100):
if eCode in (6, 9): # 6 - too fast / 9 - flood control
self.timeout += 0.05
@@ -409,7 +415,7 @@ class APIBinding(RequestProcessor):
class NetworkNotFound(Exception):
"""
- This happens in a very weird situations
+ This happens in very weird situations
Happened just once at 10.01.2014 (vk.com was down)
"""
pass
@@ -479,4 +485,4 @@ class ValidationRequired(VkApiError):
Happens if VK thinks we're
logging in from an unusual location
"""
- pass \ No newline at end of file
+ pass