diff --git a/src/common/GnuPG.py b/src/common/GnuPG.py
index f6d8e7e2b..64abe75ce 100644
--- a/src/common/GnuPG.py
+++ b/src/common/GnuPG.py
@@ -213,7 +213,9 @@ if gajim.HAVE_GPG:
return self.get_keys(True)
def _stripHeaderFooter(self, data):
- """Remove header and footer from data"""
+ """
+ Remove header and footer from data
+ """
if not data: return ''
lines = data.split('\n')
while lines[0] != '':
@@ -229,7 +231,9 @@ if gajim.HAVE_GPG:
return line
def _addHeaderFooter(self, data, type_):
- """Add header and footer from data"""
+ """
+ Add header and footer from data
+ """
out = "-----BEGIN PGP %s-----\n" % type_
out = out + "Version: PGP\n"
out = out + "\n"
diff --git a/src/common/GnuPGInterface.py b/src/common/GnuPGInterface.py
index d91f776e3..aa4a9eeee 100644
--- a/src/common/GnuPGInterface.py
+++ b/src/common/GnuPGInterface.py
@@ -21,7 +21,8 @@
## along with Gajim. If not, see .
##
-"""Interface to GNU Privacy Guard (GnuPG)
+"""
+Interface to GNU Privacy Guard (GnuPG)
GnuPGInterface is a Python module to interface with GnuPG.
It concentrates on interacting with GnuPG via filehandles,
@@ -249,7 +250,8 @@ _fd_options = { 'passphrase': '--passphrase-fd',
'command': '--command-fd' }
class GnuPG:
- """Class instances represent GnuPG.
+ """
+ Class instances represent GnuPG
Instance attributes of a GnuPG object are:
@@ -275,8 +277,10 @@ class GnuPG:
self.options = Options()
def run(self, gnupg_commands, args=None, create_fhs=None, attach_fhs=None):
- """Calls GnuPG with the list of string commands gnupg_commands,
- complete with prefixing dashes.
+ """
+ Calls GnuPG with the list of string commands gnupg_commands, complete
+ with prefixing dashes
+
For example, gnupg_commands could be
'["--sign", "--encrypt"]'
Returns a GnuPGInterface.Process object.
@@ -336,7 +340,6 @@ class GnuPG:
is a FileObject connected to GnuPG's standard input,
and can be written to.
"""
-
if args is None: args = []
if create_fhs is None: create_fhs = []
if attach_fhs is None: attach_fhs = {}
@@ -367,9 +370,10 @@ class GnuPG:
def _attach_fork_exec(self, gnupg_commands, args, create_fhs, attach_fhs):
- """This is like run(), but without the passphrase-helping
- (note that run() calls this)."""
-
+ """
+ This is like run(), but without the passphrase-helping (note that run()
+ calls this)
+ """
process = Process()
for fh_name in create_fhs + attach_fhs.keys():
@@ -404,7 +408,9 @@ class GnuPG:
def _as_parent(self, process):
- """Stuff run after forking in parent"""
+ """
+ Stuff run after forking in parent
+ """
for k, p in process._pipes.items():
if not p.direct:
os.close(p.child)
@@ -417,7 +423,9 @@ class GnuPG:
def _as_child(self, process, gnupg_commands, args):
- """Stuff run after forking in child"""
+ """
+ Stuff run after forking in child
+ """
# child
for std in _stds:
p = process._pipes[std]
@@ -444,7 +452,10 @@ class GnuPG:
class Pipe:
- """simple struct holding stuff about pipes we use"""
+ """
+ Simple struct holding stuff about pipes we use
+ """
+
def __init__(self, parent, child, direct):
self.parent = parent
self.child = child
@@ -452,7 +463,8 @@ class Pipe:
class Options:
- """Objects of this class encompass options passed to GnuPG.
+ """
+ Objects of this class encompass options passed to GnuPG.
This class is responsible for determining command-line arguments
which are based on options. It can be said that a GnuPG
object has-a Options object in its options attribute.
@@ -522,7 +534,6 @@ class Options:
>>> gnupg.options.get_args()
['--armor', '--recipient', 'Alice', '--recipient', 'Bob', '--no-secmem-warning']
"""
-
def __init__(self):
# booleans
self.armor = 0
@@ -558,12 +569,15 @@ class Options:
self.extra_args = []
def get_args( self ):
- """Generate a list of GnuPG arguments based upon attributes."""
-
+ """
+ Generate a list of GnuPG arguments based upon attributes
+ """
return self.get_meta_args() + self.get_standard_args() + self.extra_args
def get_standard_args( self ):
- """Generate a list of standard, non-meta or extra arguments"""
+ """
+ Generate a list of standard, non-meta or extra arguments
+ """
args = []
if self.homedir is not None:
args.extend( [ '--homedir', self.homedir ] )
@@ -595,7 +609,9 @@ class Options:
return args
def get_meta_args( self ):
- """Get a list of generated meta-arguments"""
+ """
+ Get a list of generated meta-arguments
+ """
args = []
if self.meta_pgp_5_compatible: args.extend( [ '--compress-algo', '1',
@@ -608,8 +624,9 @@ class Options:
class Process:
- """Objects of this class encompass properties of a GnuPG
- process spawned by GnuPG.run().
+ """
+ Objects of this class encompass properties of a GnuPG process spawned by
+ GnuPG.run()
# gnupg is a GnuPG object
process = gnupg.run( [ '--decrypt' ], stdout = 1 )
@@ -637,9 +654,10 @@ class Process:
self._waited = None
def wait(self):
- """Wait on the process to exit, allowing for child cleanup.
- Will raise an IOError if the process exits non-zero."""
-
+ """
+ Wait on the process to exit, allowing for child cleanup. Will raise an
+ IOError if the process exits non-zero
+ """
e = os.waitpid(self.pid, 0)[1]
if e != 0:
raise IOError, "GnuPG exited non-zero, with code %d" % (e << 8)
diff --git a/src/common/account.py b/src/common/account.py
index 1c080cad8..4db660165 100644
--- a/src/common/account.py
+++ b/src/common/account.py
@@ -19,14 +19,14 @@
##
class Account(object):
-
+
def __init__(self, name, contacts, gc_contacts):
self.name = name
self.contacts = contacts
self.gc_contacts = gc_contacts
-
+
def __repr__(self):
return self.name
-
+
def __hash__(self):
- return self.name.__hash__()
\ No newline at end of file
+ return hash(self.name)
diff --git a/src/common/atom.py b/src/common/atom.py
index 18122e9d1..689df5cee 100644
--- a/src/common/atom.py
+++ b/src/common/atom.py
@@ -20,9 +20,11 @@
## along with Gajim. If not, see .
##
-''' Atom (rfc 4287) feed parser, used to read data from atom-over-pubsub transports
+"""
+Atom (rfc 4287) feed parser, used to read data from atom-over-pubsub transports
and services. Very simple. Actually implements only atom:entry. Implement more features
-if you need. '''
+if you need
+"""
# suggestion: rewrite functions that return dates to return standard python time tuples,
# exteneded to contain timezone
@@ -31,8 +33,11 @@ import xmpp
import time
class PersonConstruct(xmpp.Node, object):
- ''' Not used for now, as we don't need authors/contributors in pubsub.com feeds.
- They rarely exist there. '''
+ """
+ Not used for now, as we don't need authors/contributors in pubsub.com feeds.
+ They rarely exist there
+ """
+
def __init__(self, node):
''' Create person construct from node. '''
xmpp.Node.__init__(self, node=node)
@@ -60,15 +65,17 @@ class PersonConstruct(xmpp.Node, object):
class Entry(xmpp.Node, object):
def __init__(self, node=None):
- ''' Create new atom entry object. '''
xmpp.Node.__init__(self, 'entry', node=node)
def __repr__(self):
return '' % self.getAttr('id')
class OldEntry(xmpp.Node, object):
- ''' Parser for feeds from pubsub.com. They use old Atom 0.3 format with
- their extensions. '''
+ """
+ Parser for feeds from pubsub.com. They use old Atom 0.3 format with their
+ extensions
+ """
+
def __init__(self, node=None):
''' Create new Atom 0.3 entry object. '''
xmpp.Node.__init__(self, 'entry', node=node)
@@ -77,8 +84,10 @@ class OldEntry(xmpp.Node, object):
return '' % self.getAttr('id')
def get_feed_title(self):
- ''' Returns title of feed, where the entry was created. The result is the feed name
- concatenated with source-feed title. '''
+ """
+ Return title of feed, where the entry was created. The result is the feed
+ name concatenated with source-feed title
+ """
if self.parent is not None:
main_feed = self.parent.getTagData('title')
else:
@@ -104,7 +113,9 @@ class OldEntry(xmpp.Node, object):
which delivered this entry. ''')
def get_feed_link(self):
- ''' Get source link '''
+ """
+ Get source link
+ """
try:
return self.getTag('feed').getTags('link',{'rel':'alternate'})[1].getData()
except Exception:
@@ -114,15 +125,19 @@ class OldEntry(xmpp.Node, object):
''' Link to main webpage of the feed. ''')
def get_title(self):
- ''' Get an entry's title. '''
+ """
+ Get an entry's title
+ """
return self.getTagData('title')
title = property(get_title, None, None,
''' Entry's title. ''')
def get_uri(self):
- ''' Get the uri the entry points to (entry's first link element with rel='alternate'
- or without rel attribute). '''
+ """
+ Get the uri the entry points to (entry's first link element with
+ rel='alternate' or without rel attribute)
+ """
for element in self.getTags('link'):
if 'rel' in element.attrs and element.attrs['rel']!='alternate': continue
try:
@@ -135,12 +150,16 @@ class OldEntry(xmpp.Node, object):
''' URI that is pointed by the entry. ''')
def get_updated(self):
- ''' Get the time the entry was updated last time. This should be standarized,
- but pubsub.com sends it in human-readable format. We won't try to parse it.
- (Atom 0.3 uses the word «modified» for that).
+ """
+ Get the time the entry was updated last time
+
+ This should be standarized, but pubsub.com sends it in human-readable
+ format. We won't try to parse it. (Atom 0.3 uses the word «modified» for
+ that).
If there's no time given in the entry, we try with
- and elements. '''
+ and elements.
+ """
for name in ('updated', 'modified', 'published', 'issued'):
date = self.getTagData(name)
if date is not None: break
diff --git a/src/common/caps.py b/src/common/caps.py
index f34dfcda4..489123fb8 100644
--- a/src/common/caps.py
+++ b/src/common/caps.py
@@ -23,13 +23,13 @@
## along with Gajim. If not, see .
##
-'''
-Module containing all XEP-115 (Entity Capabilities) related classes
+"""
+Module containing all XEP-115 (Entity Capabilities) related classes
Basic Idea:
CapsCache caches features to hash relationships. The cache is queried
-through ClientCaps objects which are hold by contact instances.
-'''
+through ClientCaps objects which are hold by contact instances.
+"""
import gajim
import helpers
@@ -54,7 +54,9 @@ CACHED = 2 # got the answer
capscache = None
def initialize(logger):
- ''' Initializes this module '''
+ """
+ Initialize this module
+ """
global capscache
capscache = CapsCache(logger)
@@ -73,11 +75,12 @@ def client_supports(client_caps, requested_feature):
return False
def compute_caps_hash(identities, features, dataforms=[], hash_method='sha-1'):
- '''Compute caps hash according to XEP-0115, V1.5
+ """
+ Compute caps hash according to XEP-0115, V1.5
dataforms are xmpp.DataForms objects as common.dataforms don't allow several
- values without a field type list-multi'''
-
+ values without a field type list-multi
+ """
def sort_identities_func(i1, i2):
cat1 = i1['category']
cat2 = i2['category']
@@ -98,14 +101,14 @@ def compute_caps_hash(identities, features, dataforms=[], hash_method='sha-1'):
if lang1 > lang2:
return 1
return 0
-
+
def sort_dataforms_func(d1, d2):
f1 = d1.getField('FORM_TYPE')
f2 = d2.getField('FORM_TYPE')
if f1 and f2 and (f1.getValue() < f2.getValue()):
return -1
return 1
-
+
S = ''
identities.sort(cmp=sort_identities_func)
for i in identities:
@@ -140,108 +143,119 @@ def compute_caps_hash(identities, features, dataforms=[], hash_method='sha-1'):
else:
return ''
return base64.b64encode(hash_.digest())
-
+
################################################################################
### Internal classes of this module
################################################################################
class AbstractClientCaps(object):
- '''
- Base class representing a client and its capabilities as advertised by
- a caps tag in a presence.
- '''
+ """
+ Base class representing a client and its capabilities as advertised by a
+ caps tag in a presence
+ """
def __init__(self, caps_hash, node):
self._hash = caps_hash
self._node = node
-
+
def get_discover_strategy(self):
return self._discover
-
+
def _discover(self, connection, jid):
- ''' To be implemented by subclassess '''
- raise NotImplementedError()
-
+ """
+ To be implemented by subclassess
+ """
+ raise NotImplementedError
+
def get_cache_lookup_strategy(self):
return self._lookup_in_cache
-
+
def _lookup_in_cache(self, caps_cache):
- ''' To be implemented by subclassess '''
- raise NotImplementedError()
-
+ """
+ To be implemented by subclassess
+ """
+ raise NotImplementedError
+
def get_hash_validation_strategy(self):
return self._is_hash_valid
-
+
def _is_hash_valid(self, identities, features, dataforms):
- ''' To be implemented by subclassess '''
- raise NotImplementedError()
+ """
+ To be implemented by subclassess
+ """
+ raise NotImplementedError
class ClientCaps(AbstractClientCaps):
- ''' The current XEP-115 implementation '''
-
+ """
+ The current XEP-115 implementation
+ """
+
def __init__(self, caps_hash, node, hash_method):
AbstractClientCaps.__init__(self, caps_hash, node)
assert hash_method != 'old'
self._hash_method = hash_method
-
+
def _lookup_in_cache(self, caps_cache):
return caps_cache[(self._hash_method, self._hash)]
-
+
def _discover(self, connection, jid):
connection.discoverInfo(jid, '%s#%s' % (self._node, self._hash))
-
+
def _is_hash_valid(self, identities, features, dataforms):
computed_hash = compute_caps_hash(identities, features,
dataforms=dataforms, hash_method=self._hash_method)
- return computed_hash == self._hash
+ return computed_hash == self._hash
+
-
class OldClientCaps(AbstractClientCaps):
- ''' Old XEP-115 implemtation. Kept around for background competability. '''
-
+ """
+ Old XEP-115 implemtation. Kept around for background competability
+ """
+
def __init__(self, caps_hash, node):
AbstractClientCaps.__init__(self, caps_hash, node)
def _lookup_in_cache(self, caps_cache):
return caps_cache[('old', self._node + '#' + self._hash)]
-
+
def _discover(self, connection, jid):
connection.discoverInfo(jid)
-
- def _is_hash_valid(self, identities, features, dataforms):
- return True
-
+ def _is_hash_valid(self, identities, features, dataforms):
+ return True
+
+
class NullClientCaps(AbstractClientCaps):
- '''
+ """
This is a NULL-Object to streamline caps handling if a client has not
- advertised any caps or has advertised them in an improper way.
-
+ advertised any caps or has advertised them in an improper way
+
Assumes (almost) everything is supported.
- '''
-
+ """
+
def __init__(self):
AbstractClientCaps.__init__(self, None, None)
-
+
def _lookup_in_cache(self, caps_cache):
# lookup something which does not exist to get a new CacheItem created
cache_item = caps_cache[('dummy', '')]
assert cache_item.status != CACHED
return cache_item
-
+
def _discover(self, connection, jid):
pass
def _is_hash_valid(self, identities, features, dataforms):
- return False
+ return False
class CapsCache(object):
- '''
- This object keeps the mapping between caps data and real disco
- features they represent, and provides simple way to query that info.
- '''
+ """
+ This object keeps the mapping between caps data and real disco features they
+ represent, and provides simple way to query that info
+ """
+
def __init__(self, logger=None):
# our containers:
# __cache is a dictionary mapping: pair of hash method and hash maps
@@ -255,7 +269,7 @@ class CapsCache(object):
# another object, and we will have plenty of identical long
# strings. therefore we can cache them
__names = {}
-
+
def __init__(self, hash_method, hash_, logger):
# cached into db
self.hash_method = hash_method
@@ -274,7 +288,7 @@ class CapsCache(object):
self._features = []
for feature in value:
self._features.append(self.__names.setdefault(feature, feature))
-
+
features = property(_get_features, _set_features)
def _get_identities(self):
@@ -291,7 +305,7 @@ class CapsCache(object):
d['name'] = i[3]
list_.append(d)
return list_
-
+
def _set_identities(self, value):
self._identities = []
for identity in value:
@@ -299,7 +313,7 @@ class CapsCache(object):
t = (identity['category'], identity.get('type'),
identity.get('xml:lang'), identity.get('name'))
self._identities.append(self.__names.setdefault(t, t))
-
+
identities = property(_get_identities, _set_identities)
def set_and_store(self, identities, features):
@@ -308,7 +322,7 @@ class CapsCache(object):
self._logger.add_caps_entry(self.hash_method, self.hash,
identities, features)
self.status = CACHED
-
+
def update_last_seen(self):
if not self._recently_seen:
self._recently_seen = True
@@ -325,9 +339,11 @@ class CapsCache(object):
x.identities = identities
x.features = features
x.status = CACHED
-
+
def _remove_outdated_caps(self):
- '''Removes outdated values from the db'''
+ """
+ Remove outdated values from the db
+ """
self.logger.clean_caps_table()
def __getitem__(self, caps):
@@ -341,20 +357,20 @@ class CapsCache(object):
return x
def query_client_of_jid_if_unknown(self, connection, jid, client_caps):
- '''
- Start a disco query to determine caps (node, ver, exts).
- Won't query if the data is already in cache.
- '''
+ """
+ Start a disco query to determine caps (node, ver, exts). Won't query if
+ the data is already in cache
+ """
lookup_cache_item = client_caps.get_cache_lookup_strategy()
- q = lookup_cache_item(self)
-
+ q = lookup_cache_item(self)
+
if q.status == NEW:
# do query for bare node+hash pair
# this will create proper object
q.status = QUERIED
discover = client_caps.get_discover_strategy()
discover(connection, jid)
- else:
+ else:
q.update_last_seen()
################################################################################
@@ -362,14 +378,15 @@ class CapsCache(object):
################################################################################
class ConnectionCaps(object):
- '''
- This class highly depends on that it is a part of Connection class.
- '''
+ """
+ This class highly depends on that it is a part of Connection class
+ """
+
def _capsPresenceCB(self, con, presence):
- '''
+ """
Handle incoming presence stanzas... This is a callback for xmpp
registered in connection_handlers.py
- '''
+ """
# we will put these into proper Contact object and ask
# for disco... so that disco will learn how to interpret
# these caps
@@ -411,7 +428,7 @@ class ConnectionCaps(object):
if pm_ctrl:
pm_ctrl.update_contact()
- def _capsDiscoCB(self, jid, node, identities, features, dataforms):
+ def _capsDiscoCB(self, jid, node, identities, features, dataforms):
contact = gajim.contacts.get_contact_from_full_jid(self.name, jid)
if not contact:
room_jid, nick = gajim.get_room_and_nick_from_fjid(jid)
@@ -420,14 +437,14 @@ class ConnectionCaps(object):
return
lookup = contact.client_caps.get_cache_lookup_strategy()
- cache_item = lookup(capscache)
-
+ cache_item = lookup(capscache)
+
if cache_item.status == CACHED:
return
else:
validate = contact.client_caps.get_hash_validation_strategy()
hash_is_valid = validate(identities, features, dataforms)
-
+
if hash_is_valid:
cache_item.set_and_store(identities, features)
else:
diff --git a/src/common/commands.py b/src/common/commands.py
index 71b0300bc..07c866194 100644
--- a/src/common/commands.py
+++ b/src/common/commands.py
@@ -34,10 +34,13 @@ class AdHocCommand:
@staticmethod
def isVisibleFor(samejid):
- ''' This returns True if that command should be visible and invokable
- for others.
+ """
+ This returns True if that command should be visible and invokable for
+ others
+
samejid - True when command is invoked by an entity with the same bare
- jid.'''
+ jid.
+ """
return True
def __init__(self, conn, jid, sessionid):
@@ -80,7 +83,9 @@ class ChangeStatusCommand(AdHocCommand):
@staticmethod
def isVisibleFor(samejid):
- ''' Change status is visible only if the entity has the same bare jid. '''
+ """
+ Change status is visible only if the entity has the same bare jid
+ """
return samejid
def execute(self, request):
@@ -177,7 +182,9 @@ class LeaveGroupchatsCommand(AdHocCommand):
@staticmethod
def isVisibleFor(samejid):
- ''' Change status is visible only if the entity has the same bare jid. '''
+ """
+ Change status is visible only if the entity has the same bare jid
+ """
return samejid
def execute(self, request):
@@ -259,7 +266,9 @@ class ForwardMessagesCommand(AdHocCommand):
@staticmethod
def isVisibleFor(samejid):
- ''' Change status is visible only if the entity has the same bare jid. '''
+ """
+ Change status is visible only if the entity has the same bare jid
+ """
return samejid
def execute(self, request):
@@ -282,7 +291,10 @@ class ForwardMessagesCommand(AdHocCommand):
return False # finish the session
class ConnectionCommands:
- ''' This class depends on that it is a part of Connection() class. '''
+ """
+ This class depends on that it is a part of Connection() class
+ """
+
def __init__(self):
# a list of all commands exposed: node -> command class
self.__commands = {}
@@ -297,7 +309,9 @@ class ConnectionCommands:
return gajim.get_jid_from_account(self.name)
def isSameJID(self, jid):
- ''' Tests if the bare jid given is the same as our bare jid. '''
+ """
+ Test if the bare jid given is the same as our bare jid
+ """
return xmpp.JID(jid).getStripped() == self.getOurBareJID()
def commandListQuery(self, con, iq_obj):
@@ -318,8 +332,10 @@ class ConnectionCommands:
self.connection.send(iq)
def commandInfoQuery(self, con, iq_obj):
- ''' Send disco#info result for query for command (JEP-0050, example 6.).
- Return True if the result was sent, False if not. '''
+ """
+ Send disco#info result for query for command (JEP-0050, example 6.).
+ Return True if the result was sent, False if not
+ """
jid = helpers.get_full_jid_from_iq(iq_obj)
node = iq_obj.getTagAttr('query', 'node')
@@ -342,8 +358,10 @@ class ConnectionCommands:
return False
def commandItemsQuery(self, con, iq_obj):
- ''' Send disco#items result for query for command.
- Return True if the result was sent, False if not. '''
+ """
+ Send disco#items result for query for command. Return True if the result
+ was sent, False if not.
+ """
jid = helpers.get_full_jid_from_iq(iq_obj)
node = iq_obj.getTagAttr('query', 'node')
diff --git a/src/common/config.py b/src/common/config.py
index 92279c6d3..831b2b1eb 100644
--- a/src/common/config.py
+++ b/src/common/config.py
@@ -512,7 +512,9 @@ class Config:
cb(data, opt3, [opt, opt2], dict_[opt2][opt3])
def get_children(self, node=None):
- ''' Tree-like interface '''
+ """
+ Tree-like interface
+ """
if node is None:
for child, option in self.__options.iteritems():
yield (child, ), option
@@ -698,8 +700,9 @@ class Config:
return False
def should_log(self, account, jid):
- '''should conversations between a local account and a remote jid be
- logged?'''
+ """
+ Should conversations between a local account and a remote jid be logged?
+ """
no_log_for = self.get_per('accounts', account, 'no_log_for')
if not no_log_for:
diff --git a/src/common/configpaths.py b/src/common/configpaths.py
index 19e45aef3..bf1372970 100644
--- a/src/common/configpaths.py
+++ b/src/common/configpaths.py
@@ -46,7 +46,9 @@ import tempfile
# not displayed to the user, Unicode is not really necessary here.
def fse(s):
- '''Convert from filesystem encoding if not already Unicode'''
+ """
+ Convert from filesystem encoding if not already Unicode
+ """
return unicode(s, sys.getfilesystemencoding())
def windowsify(s):
diff --git a/src/common/connection.py b/src/common/connection.py
index 823f56824..31e2b0ba4 100644
--- a/src/common/connection.py
+++ b/src/common/connection.py
@@ -100,10 +100,11 @@ ssl_error = {
}
class CommonConnection:
- '''
+ """
Common connection class, can be derivated for normal connection or zeroconf
connection
- '''
+ """
+
def __init__(self, name):
self.name = name
# self.connected:
@@ -162,11 +163,15 @@ class CommonConnection:
return resource
def dispatch(self, event, data):
- '''always passes account name as first param'''
+ """
+ Always passes account name as first param
+ """
gajim.interface.dispatch(event, self.name, data)
def _reconnect(self):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def quit(self, kill_core):
@@ -174,7 +179,9 @@ class CommonConnection:
self.disconnect(on_purpose=True)
def test_gpg_passphrase(self, password):
- '''Returns 'ok', 'bad_pass' or 'expired' '''
+ """
+ Returns 'ok', 'bad_pass' or 'expired'
+ """
if not self.gpg:
return False
self.gpg.passphrase = password
@@ -188,10 +195,12 @@ class CommonConnection:
return 'ok'
def get_signed_msg(self, msg, callback = None):
- '''returns the signed message if possible
- or an empty string if gpg is not used
- or None if waiting for passphrase.
- callback is the function to call when user give the passphrase'''
+ """
+ Returns the signed message if possible or an empty string if gpg is not
+ used or None if waiting for passphrase
+
+ callback is the function to call when user give the passphrase
+ """
signed = ''
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
if keyID and self.USE_GPG:
@@ -208,7 +217,9 @@ class CommonConnection:
return signed
def _on_disconnected(self):
- ''' called when a disconnect request has completed successfully'''
+ """
+ Called when a disconnect request has completed successfully
+ """
self.disconnect(on_purpose=True)
self.dispatch('STATUS', 'offline')
@@ -216,9 +227,10 @@ class CommonConnection:
return gajim.SHOW_LIST[self.connected]
def check_jid(self, jid):
- '''this function must be implemented by derivated classes.
- It has to return the valid jid, or raise a helpers.InvalidFormat exception
- '''
+ """
+ This function must be implemented by derivated classes. It has to return
+ the valid jid, or raise a helpers.InvalidFormat exception
+ """
raise NotImplementedError
def _prepare_message(self, jid, msg, keyID, type_='chat', subject='',
@@ -424,32 +436,46 @@ class CommonConnection:
common.logger.LOG_DB_PATH
def ack_subscribed(self, jid):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def ack_unsubscribed(self, jid):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def request_subscription(self, jid, msg='', name='', groups=[],
- auto_auth=False):
- '''To be implemented by derivated classes'''
+ auto_auth=False):
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def send_authorization(self, jid):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def refuse_authorization(self, jid):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def unsubscribe(self, jid, remove_auth = True):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def unsubscribe_agent(self, agent):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def update_contact(self, jid, name, groups):
@@ -457,47 +483,67 @@ class CommonConnection:
self.connection.getRoster().setItem(jid=jid, name=name, groups=groups)
def update_contacts(self, contacts):
- '''update multiple roster items'''
+ """
+ Update multiple roster items
+ """
if self.connection:
self.connection.getRoster().setItemMulti(contacts)
def new_account(self, name, config, sync=False):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def _on_new_account(self, con=None, con_type=None):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def account_changed(self, new_name):
self.name = new_name
def request_last_status_time(self, jid, resource):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def request_os_info(self, jid, resource):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def get_settings(self):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def get_bookmarks(self):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def store_bookmarks(self):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def get_metacontacts(self):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def send_agent_status(self, agent, ptype):
- '''To be implemented by derivated classes'''
+ """
+ To be implemented by derivated classes
+ """
raise NotImplementedError
def gpg_passphrase(self, passphrase):
@@ -581,7 +627,6 @@ class CommonConnection:
self._update_status(show, msg)
class Connection(CommonConnection, ConnectionHandlers):
- '''Connection class'''
def __init__(self, name):
CommonConnection.__init__(self, name)
ConnectionHandlers.__init__(self)
@@ -672,7 +717,9 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection = None
def _disconnectedReconnCB(self):
- '''Called when we are disconnected'''
+ """
+ Called when we are disconnected
+ """
log.info('disconnectedReconnCB called')
if gajim.account_is_connected(self.name):
# we cannot change our status to offline or connecting
@@ -830,11 +877,11 @@ class Connection(CommonConnection, ConnectionHandlers):
self.dispatch('PRIVACY_LISTS_ACTIVE_DEFAULT', (data))
def _select_next_host(self, hosts):
- '''Selects the next host according to RFC2782 p.3 based on it's
- priority. Chooses between hosts with the same priority randomly,
- where the probability of being selected is proportional to the weight
- of the host.'''
-
+ """
+ Selects the next host according to RFC2782 p.3 based on it's priority.
+ Chooses between hosts with the same priority randomly, where the
+ probability of being selected is proportional to the weight of the host
+ """
hosts_by_prio = sorted(hosts, key=operator.itemgetter('prio'))
try:
@@ -856,10 +903,13 @@ class Connection(CommonConnection, ConnectionHandlers):
return host
def connect(self, data = None):
- ''' Start a connection to the Jabber server.
- Returns connection, and connection type ('tls', 'ssl', 'plain', '')
- data MUST contain hostname, usessl, proxy, use_custom_host,
- custom_host (if use_custom_host), custom_port (if use_custom_host)'''
+ """
+ Start a connection to the Jabber server
+
+ Returns connection, and connection type ('tls', 'ssl', 'plain', '') data
+ MUST contain hostname, usessl, proxy, use_custom_host, custom_host (if
+ use_custom_host), custom_port (if use_custom_host)
+ """
if self.connection:
return self.connection, ''
@@ -1256,8 +1306,10 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(' ')
def sendPing(self, pingTo=None):
- '''Send XMPP Ping (XEP-0199) request. If pingTo is not set, ping is sent
- to server to detect connection failure at application level.'''
+ """
+ Send XMPP Ping (XEP-0199) request. If pingTo is not set, ping is sent to
+ server to detect connection failure at application level
+ """
if not self.connection:
return
id_ = self.connection.getAnID()
@@ -1325,7 +1377,9 @@ class Connection(CommonConnection, ConnectionHandlers):
common.xmpp.features_nb.setDefaultPrivacyList(self.connection, listname)
def build_privacy_rule(self, name, action, order=1):
- '''Build a Privacy rule stanza for invisibility'''
+ """
+ Build a Privacy rule stanza for invisibility
+ """
iq = common.xmpp.Iq('set', common.xmpp.NS_PRIVACY, xmlns = '')
l = iq.getTag('query').setTag('list', {'name': name})
i = l.setTag('item', {'action': action, 'order': str(order)})
@@ -1358,7 +1412,9 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(iq)
def activate_privacy_rule(self, name):
- '''activate a privacy rule'''
+ """
+ Activate a privacy rule
+ """
if not self.connection:
return
iq = common.xmpp.Iq('set', common.xmpp.NS_PRIVACY, xmlns = '')
@@ -1534,7 +1590,9 @@ class Connection(CommonConnection, ConnectionHandlers):
original_message=original_message, delayed=delayed, callback=cb)
def send_contacts(self, contacts, jid):
- '''Send contacts with RosterX (Xep-0144)'''
+ """
+ Send contacts with RosterX (Xep-0144)
+ """
if not self.connection:
return
if len(contacts) == 1:
@@ -1553,7 +1611,9 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(msg_iq)
def send_stanza(self, stanza):
- ''' send a stanza untouched '''
+ """
+ Send a stanza untouched
+ """
if not self.connection:
return
self.connection.send(stanza)
@@ -1573,7 +1633,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(p)
def request_subscription(self, jid, msg = '', name = '', groups = [],
- auto_auth = False, user_nick = ''):
+ auto_auth = False, user_nick = ''):
if not self.connection:
return
log.debug('subscription request for %s' % jid)
@@ -1677,8 +1737,10 @@ class Connection(CommonConnection, ConnectionHandlers):
common.xmpp.features_nb.getRegInfo(con, self._hostname)
def request_last_status_time(self, jid, resource, groupchat_jid=None):
- '''groupchat_jid is used when we want to send a request to a real jid
- and act as if the answer comes from the groupchat_jid'''
+ """
+ groupchat_jid is used when we want to send a request to a real jid and
+ act as if the answer comes from the groupchat_jid
+ """
if not self.connection:
return
to_whom_jid = jid
@@ -1694,8 +1756,10 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(iq)
def request_os_info(self, jid, resource, groupchat_jid=None):
- '''groupchat_jid is used when we want to send a request to a real jid
- and act as if the answer comes from the groupchat_jid'''
+ """
+ groupchat_jid is used when we want to send a request to a real jid and
+ act as if the answer comes from the groupchat_jid
+ """
if not self.connection:
return
# If we are invisible, do not request
@@ -1715,8 +1779,10 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(iq)
def request_entity_time(self, jid, resource, groupchat_jid=None):
- '''groupchat_jid is used when we want to send a request to a real jid
- and act as if the answer comes from the groupchat_jid'''
+ """
+ groupchat_jid is used when we want to send a request to a real jid and
+ act as if the answer comes from the groupchat_jid
+ """
if not self.connection:
return
# If we are invisible, do not request
@@ -1736,7 +1802,9 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(iq)
def get_settings(self):
- ''' Get Gajim settings as described in XEP 0049 '''
+ """
+ Get Gajim settings as described in XEP 0049
+ """
if not self.connection:
return
iq = common.xmpp.Iq(typ='get')
@@ -1757,9 +1825,12 @@ class Connection(CommonConnection, ConnectionHandlers):
self._request_bookmarks_xml()
def get_bookmarks(self, storage_type=None):
- '''Get Bookmarks from storage or PubSub if supported as described in
- XEP 0048
- storage_type can be set to xml to force request to xml storage'''
+ """
+ Get Bookmarks from storage or PubSub if supported as described in XEP
+ 0048
+
+ storage_type can be set to xml to force request to xml storage
+ """
if not self.connection:
return
if self.pubsub_supported and storage_type != 'xml':
@@ -1771,9 +1842,12 @@ class Connection(CommonConnection, ConnectionHandlers):
self._request_bookmarks_xml()
def store_bookmarks(self, storage_type=None):
- ''' Send bookmarks to the storage namespace or PubSub if supported
+ """
+ Send bookmarks to the storage namespace or PubSub if supported
+
storage_type can be set to 'pubsub' or 'xml' so store in only one method
- else it will be stored on both'''
+ else it will be stored on both
+ """
if not self.connection:
return
iq = common.xmpp.Node(tag='storage', attrs={'xmlns': 'storage:bookmarks'})
@@ -1815,7 +1889,9 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(iqA)
def get_annotations(self):
- '''Get Annonations from storage as described in XEP 0048, and XEP 0145'''
+ """
+ Get Annonations from storage as described in XEP 0048, and XEP 0145
+ """
self.annotations = {}
if not self.connection:
return
@@ -1825,7 +1901,9 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(iq)
def store_annotations(self):
- '''Set Annonations in private storage as described in XEP 0048, and XEP 0145'''
+ """
+ Set Annonations in private storage as described in XEP 0048, and XEP 0145
+ """
if not self.connection:
return
iq = common.xmpp.Iq(typ='set')
@@ -1840,7 +1918,9 @@ class Connection(CommonConnection, ConnectionHandlers):
def get_metacontacts(self):
- '''Get metacontacts list from storage as described in XEP 0049'''
+ """
+ Get metacontacts list from storage as described in XEP 0049
+ """
if not self.connection:
return
iq = common.xmpp.Iq(typ='get')
@@ -1852,7 +1932,9 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(iq)
def store_metacontacts(self, tags_list):
- ''' Send meta contacts to the storage namespace '''
+ """
+ Send meta contacts to the storage namespace
+ """
if not self.connection:
return
iq = common.xmpp.Iq(typ='set')
@@ -2000,16 +2082,20 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(p)
def gc_got_disconnected(self, room_jid):
- ''' A groupchat got disconnected. This can be or purpose or not.
+ """
+ A groupchat got disconnected. This can be or purpose or not
+
Save the time we quit to avoid duplicate logs AND be faster than get that
date from DB. Save it in mem AND in a small table (with fast access)
- '''
+ """
log_time = time_time()
self.last_history_time[room_jid] = log_time
gajim.logger.set_room_last_message_time(room_jid, log_time)
def gc_set_role(self, room_jid, nick, role, reason = ''):
- '''role is for all the life of the room so it's based on nick'''
+ """
+ Role is for all the life of the room so it's based on nick
+ """
if not self.connection:
return
iq = common.xmpp.Iq(typ = 'set', to = room_jid, queryNS =\
@@ -2022,7 +2108,9 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(iq)
def gc_set_affiliation(self, room_jid, jid, affiliation, reason = ''):
- '''affiliation is for all the life of the room so it's based on jid'''
+ """
+ Affiliation is for all the life of the room so it's based on jid
+ """
if not self.connection:
return
iq = common.xmpp.Iq(typ = 'set', to = room_jid, queryNS =\
@@ -2117,7 +2205,9 @@ class Connection(CommonConnection, ConnectionHandlers):
_on_unregister_account_connect(self.connection)
def send_invite(self, room, to, reason='', continue_tag=False):
- '''sends invitation'''
+ """
+ Send invitation
+ """
message=common.xmpp.Message(to = room)
c = message.addChild(name = 'x', namespace = common.xmpp.NS_MUC_USER)
c = c.addChild(name = 'invite', attrs={'to' : to})
diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py
index 2dbff985b..13547358e 100644
--- a/src/common/connection_handlers.py
+++ b/src/common/connection_handlers.py
@@ -100,9 +100,9 @@ class ConnectionBytestream:
return True
def send_success_connect_reply(self, streamhost):
- ''' send reply to the initiator of FT that we
- made a connection
- '''
+ """
+ Send reply to the initiator of FT that we made a connection
+ """
if not self.connection or self.connected < 2:
return
if streamhost is None:
@@ -117,7 +117,9 @@ class ConnectionBytestream:
self.connection.send(iq)
def remove_transfers_for_contact(self, contact):
- ''' stop all active transfer for contact '''
+ """
+ Stop all active transfer for contact
+ """
for file_props in self.files_props.values():
if self.is_transfer_stopped(file_props):
continue
@@ -132,7 +134,9 @@ class ConnectionBytestream:
self.remove_transfer(file_props)
def remove_all_transfers(self):
- ''' stops and removes all active connections from the socks5 pool '''
+ """
+ Stop and remove all active connections from the socks5 pool
+ """
for file_props in self.files_props.values():
self.remove_transfer(file_props, remove_from_list = False)
del(self.files_props)
@@ -161,9 +165,11 @@ class ConnectionBytestream:
gajim.socks5queue.remove_receiver(host['idx'])
gajim.socks5queue.remove_sender(host['idx'])
- def send_socks5_info(self, file_props, fast = True, receiver = None,
- sender = None):
- ''' send iq for the present streamhosts and proxies '''
+ def send_socks5_info(self, file_props, fast = True, receiver = None, sender
+ = None):
+ """
+ Send iq for the present streamhosts and proxies
+ """
if not self.connection or self.connected < 2:
return
if not isinstance(self.peerhost, tuple):
@@ -269,9 +275,12 @@ class ConnectionBytestream:
self.connection.send(iq)
def send_file_rejection(self, file_props, code='403', typ=None):
- ''' informs sender that we refuse to download the file
+ """
+ Inform sender that we refuse to download the file
+
typ is used when code = '400', in this case typ can be 'strean' for
- invalid stream or 'profile' for invalid profile'''
+ invalid stream or 'profile' for invalid profile
+ """
# user response to ConfirmationDialog may come after we've disconneted
if not self.connection or self.connected < 2:
return
@@ -294,7 +303,9 @@ class ConnectionBytestream:
self.connection.send(iq)
def send_file_approval(self, file_props):
- ''' send iq, confirming that we want to download the file '''
+ """
+ Send iq, confirming that we want to download the file
+ """
# user response to ConfirmationDialog may come after we've disconneted
if not self.connection or self.connected < 2:
return
@@ -326,7 +337,9 @@ class ConnectionBytestream:
return file_props['receiver'].jid + '/' + file_props['receiver'].resource
def send_file_request(self, file_props):
- ''' send iq for new FT request '''
+ """
+ Send iq for new FT request
+ """
if not self.connection or self.connected < 2:
return
file_props['sender'] = self._ft_get_our_jid()
@@ -357,7 +370,9 @@ class ConnectionBytestream:
self.connection.send(iq)
def _result_socks5_sid(self, sid, hash_id):
- ''' store the result of sha message from auth. '''
+ """
+ Store the result of SHA message from auth
+ """
if sid not in self.files_props:
return
file_props = self.files_props[sid]
@@ -365,8 +380,10 @@ class ConnectionBytestream:
return
def _connect_error(self, to, _id, sid, code=404):
- ''' cb, when there is an error establishing BS connection, or
- when connection is rejected'''
+ """
+ Called when there is an error establishing BS connection, or when
+ connection is rejected
+ """
if not self.connection or self.connected < 2:
return
msg_dict = {
@@ -391,7 +408,9 @@ class ConnectionBytestream:
self.dispatch('FILE_REQUEST_ERROR', (to, file_props, msg))
def _proxy_auth_ok(self, proxy):
- '''cb, called after authentication to proxy server '''
+ """
+ Called after authentication to proxy server
+ """
if not self.connection or self.connected < 2:
return
file_props = self.files_props[proxy['sid']]
@@ -673,16 +692,24 @@ class ConnectionBytestream:
raise common.xmpp.NodeProcessed
class ConnectionDisco:
- ''' hold xmpppy handlers and public methods for discover services'''
+ """
+ Holds xmpppy handlers and public methods for discover services
+ """
+
def discoverItems(self, jid, node = None, id_prefix = None):
- '''According to XEP-0030: jid is mandatory,
- name, node, action is optional.'''
+ """
+ According to XEP-0030:
+ jid is mandatory;
+ name, node, action is optional.
+ """
self._discover(common.xmpp.NS_DISCO_ITEMS, jid, node, id_prefix)
def discoverInfo(self, jid, node = None, id_prefix = None):
- '''According to XEP-0030:
+ """
+ According to XEP-0030:
For identity: category, type is mandatory, name is optional.
- For feature: var is mandatory'''
+ For feature: var is mandatory.
+ """
self._discover(common.xmpp.NS_DISCO_INFO, jid, node, id_prefix)
def request_register_agent_info(self, agent):
@@ -738,7 +765,9 @@ class ConnectionDisco:
self._IqCB(con, resp)
def _discoGetCB(self, con, iq_obj):
- ''' get disco info '''
+ """
+ Get disco info
+ """
if not self.connection or self.connected < 2:
return
frm = helpers.get_full_jid_from_iq(iq_obj)
@@ -1008,9 +1037,11 @@ class ConnectionVcard:
self.dispatch('ERROR', (_('Disk Write Error'), str(e)))
def get_cached_vcard(self, fjid, is_fake_jid = False):
- '''return the vcard as a dict
- return {} if vcard was too old
- return None if we don't have cached vcard'''
+ """
+ Return the vcard as a dict.
+ Return {} if vcard was too old.
+ Return None if we don't have cached vcard.
+ """
jid, nick = gajim.get_room_and_nick_from_fjid(fjid)
puny_jid = helpers.sanitize_filename(jid)
if is_fake_jid:
@@ -1045,9 +1076,13 @@ class ConnectionVcard:
return vcard
def request_vcard(self, jid = None, groupchat_jid = None):
- '''request the VCARD. If groupchat_jid is not nul, it means we request a vcard
- to a fake jid, like in private messages in groupchat. jid can be the
- real jid of the contact, but we want to consider it comes from a fake jid'''
+ """
+ Request the VCARD
+
+ If groupchat_jid is not nul, it means we request a vcard to a fake jid,
+ like in private messages in groupchat. jid can be the real jid of the
+ contact, but we want to consider it comes from a fake jid
+ """
if not self.connection or self.connected < 2:
return
iq = common.xmpp.Iq(typ = 'get')
@@ -1238,8 +1273,9 @@ class ConnectionVcard:
del self.awaiting_answers[id_]
def _vCardCB(self, con, vc):
- '''Called when we receive a vCard
- Parse the vCard and send it to plugins'''
+ """
+ Called when we receive a vCard Parse the vCard and send it to plugins
+ """
if not vc.getTag('vCard'):
return
if not vc.getTag('vCard').getNamespace() == common.xmpp.NS_VCARD:
@@ -1345,8 +1381,9 @@ class ConnectionHandlersBase:
self.sessions = {}
def get_sessions(self, jid):
- '''get all sessions for the given full jid'''
-
+ """
+ Get all sessions for the given full jid
+ """
if not gajim.interface.is_pm_contact(jid, self.name):
jid = gajim.get_jid_without_resource(jid)
@@ -1356,9 +1393,10 @@ class ConnectionHandlersBase:
return []
def get_or_create_session(self, fjid, thread_id):
- '''returns an existing session between this connection and 'jid', returns a
- new one if none exist.'''
-
+ """
+ Return an existing session between this connection and 'jid', returns a
+ new one if none exist
+ """
pm = True
jid = fjid
@@ -1386,7 +1424,9 @@ class ConnectionHandlersBase:
return None
def terminate_sessions(self, send_termination=False):
- '''send termination messages and delete all active sessions'''
+ """
+ Send termination messages and delete all active sessions
+ """
for jid in self.sessions:
for thread_id in self.sessions[jid]:
self.sessions[jid][thread_id].terminate(send_termination)
@@ -1405,10 +1445,11 @@ class ConnectionHandlersBase:
del self.sessions[jid]
def find_null_session(self, jid):
- '''finds all of the sessions between us and a remote jid in which we
-haven't received a thread_id yet and returns the session that we last
-sent a message to.'''
-
+ """
+ Find all of the sessions between us and a remote jid in which we haven't
+ received a thread_id yet and returns the session that we last sent a
+ message to
+ """
sessions = self.sessions[jid].values()
# sessions that we haven't received a thread ID in
@@ -1425,8 +1466,9 @@ sent a message to.'''
return None
def find_controlless_session(self, jid, resource=None):
- '''find an active session that doesn't have a control attached'''
-
+ """
+ Find an active session that doesn't have a control attached
+ """
try:
sessions = self.sessions[jid].values()
@@ -1444,8 +1486,12 @@ sent a message to.'''
return None
def make_new_session(self, jid, thread_id=None, type_='chat', cls=None):
- '''create and register a new session. thread_id=None to generate one.
- type_ should be 'chat' or 'pm'.'''
+ """
+ Create and register a new session
+
+ thread_id=None to generate one.
+ type_ should be 'chat' or 'pm'.
+ """
if not cls:
cls = gajim.default_session_type
@@ -1463,7 +1509,9 @@ sent a message to.'''
return sess
-class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, ConnectionCommands, ConnectionPubSub, ConnectionPEP, ConnectionCaps, ConnectionHandlersBase, ConnectionJingle):
+class ConnectionHandlers(ConnectionVcard, ConnectionBytestream,
+ ConnectionDisco, ConnectionCommands, ConnectionPubSub, ConnectionPEP,
+ ConnectionCaps, ConnectionHandlersBase, ConnectionJingle):
def __init__(self):
ConnectionVcard.__init__(self)
ConnectionBytestream.__init__(self)
@@ -1544,9 +1592,9 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
self.dispatch('ERROR_ANSWER', (id_, jid_from, errmsg, errcode))
def _PrivateCB(self, con, iq_obj):
- '''
+ """
Private Data (XEP 048 and 049)
- '''
+ """
log.debug('PrivateCB')
query = iq_obj.getTag('query')
storage = query.getTag('storage')
@@ -1573,8 +1621,9 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
self.annotations[jid] = annotation
def _parse_bookmarks(self, storage, storage_type):
- '''storage_type can be 'pubsub' or 'xml' to tell from where we got
- bookmarks'''
+ """
+ storage_type can be 'pubsub' or 'xml' to tell from where we got bookmarks
+ """
# Bookmarked URLs and Conferences
# http://www.xmpp.org/extensions/xep-0048.html
resend_to_pubsub = False
@@ -1788,7 +1837,9 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
self.dispatch('ENTITY_TIME', (jid_stripped, resource, time_info))
def _gMailNewMailCB(self, con, gm):
- '''Called when we get notified of new mail messages in gmail account'''
+ """
+ Called when we get notified of new mail messages in gmail account
+ """
if not self.connection or self.connected < 2:
return
if not gm.getTag('new-mail'):
@@ -1810,7 +1861,10 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
raise common.xmpp.NodeProcessed
def _gMailQueryCB(self, con, gm):
- '''Called when we receive results from Querying the server for mail messages in gmail account'''
+ """
+ Called when we receive results from Querying the server for mail messages
+ in gmail account
+ """
if not gm.getTag('mailbox'):
return
self.gmail_url = gm.getTag('mailbox').getAttr('url')
@@ -1856,7 +1910,9 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
raise common.xmpp.NodeProcessed
def _rosterItemExchangeCB(self, con, msg):
- ''' XEP-0144 Roster Item Echange '''
+ """
+ XEP-0144 Roster Item Echange
+ """
exchange_items_list = {}
jid_from = helpers.get_full_jid_from_iq(msg)
items_list = msg.getTag('x').getChildren()
@@ -1898,7 +1954,9 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
raise common.xmpp.NodeProcessed
def _messageCB(self, con, msg):
- '''Called when we receive a message'''
+ """
+ Called when we receive a message
+ """
log.debug('MessageCB')
mtype = msg.getType()
@@ -2167,7 +2225,9 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
is_continued))
def _presenceCB(self, con, prs):
- '''Called when we receive a presence'''
+ """
+ Called when we receive a presence
+ """
ptype = prs.getType()
if ptype == 'available':
ptype = None
@@ -2269,7 +2329,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
gc_control = gajim.interface.msg_win_mgr.get_gc_control(room_jid,
self.name)
-
+
# If gc_control is missing - it may be minimized. Try to get it from
# there. If it's not there - then it's missing anyway and will
# remain set to None.
@@ -2550,11 +2610,11 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
raise common.xmpp.NodeProcessed
def _PrivacySetCB(self, con, iq_obj):
- '''
+ """
Privacy lists (XEP 016)
- A list has been set
- '''
+ A list has been set.
+ """
log.debug('PrivacySetCB')
if not self.connection or self.connected < 2:
return
diff --git a/src/common/contacts.py b/src/common/contacts.py
index 5a9df3499..fbc49b229 100644
--- a/src/common/contacts.py
+++ b/src/common/contacts.py
@@ -33,26 +33,28 @@ import caps
from account import Account
class XMPPEntity(object):
- '''Base representation of entities in XMPP'''
-
+ """
+ Base representation of entities in XMPP
+ """
+
def __init__(self, jid, account, resource):
self.jid = jid
self.resource = resource
self.account = account
class CommonContact(XMPPEntity):
-
- def __init__(self, jid, account, resource, show, status, name, our_chatstate,
- composing_xep, chatstate, client_caps=None):
-
+
+ def __init__(self, jid, account, resource, show, status, name,
+ our_chatstate, composing_xep, chatstate, client_caps=None):
+
XMPPEntity.__init__(self, jid, account, resource)
-
+
self.show = show
self.status = status
self.name = name
-
+
self.client_caps = client_caps or caps.NullClientCaps()
-
+
# please read xep-85 http://www.xmpp.org/extensions/xep-0085.html
# we keep track of xep85 support with the peer by three extra states:
# None, False and 'ask'
@@ -67,18 +69,18 @@ class CommonContact(XMPPEntity):
self.composing_xep = composing_xep
# this is contact's chatstate
self.chatstate = chatstate
-
+
def get_full_jid(self):
raise NotImplementedError
-
+
def get_shown_name(self):
raise NotImplementedError
def supports(self, requested_feature):
- '''
- Returns True if the contact has advertised to support the feature
+ """
+ Return True if the contact has advertised to support the feature
identified by the given namespace. False otherwise.
- '''
+ """
if self.show == 'offline':
# Unfortunately, if all resources are offline, the contact
# includes the last resource that was online. Check for its
@@ -90,26 +92,29 @@ class CommonContact(XMPPEntity):
class Contact(CommonContact):
- '''Information concerning each contact'''
- def __init__(self, jid, account, name='', groups=[], show='', status='', sub='',
- ask='', resource='', priority=0, keyID='', client_caps=None,
- our_chatstate=None, chatstate=None, last_status_time=None, msg_id = None,
- composing_xep=None):
-
- CommonContact.__init__(self, jid, account, resource, show, status, name,
+ """
+ Information concerning each contact
+ """
+
+ def __init__(self, jid, account, name='', groups=[], show='', status='',
+ sub='', ask='', resource='', priority=0, keyID='', client_caps=None,
+ our_chatstate=None, chatstate=None, last_status_time=None, msg_id =
+ None, composing_xep=None):
+
+ CommonContact.__init__(self, jid, account, resource, show, status, name,
our_chatstate, composing_xep, chatstate, client_caps=client_caps)
-
+
self.contact_name = '' # nick choosen by contact
self.groups = [i for i in set(groups)] # filter duplicate values
self.sub = sub
self.ask = ask
-
+
self.priority = priority
self.keyID = keyID
self.msg_id = msg_id
self.last_status_time = last_status_time
-
+
self.pep = {}
def get_full_jid(self):
@@ -137,7 +142,9 @@ class Contact(CommonContact):
return self.groups
def is_hidden_from_roster(self):
- '''if contact should not be visible in roster'''
+ """
+ If contact should not be visible in roster
+ """
# XEP-0162: http://www.xmpp.org/extensions/xep-0162.html
if self.is_transport():
return False
@@ -173,43 +180,50 @@ class Contact(CommonContact):
class GC_Contact(CommonContact):
- '''Information concerning each groupchat contact'''
+ """
+ Information concerning each groupchat contact
+ """
+
def __init__(self, room_jid, account, name='', show='', status='', role='',
- affiliation='', jid='', resource='', our_chatstate=None,
- composing_xep=None, chatstate=None):
-
+ affiliation='', jid='', resource='', our_chatstate=None,
+ composing_xep=None, chatstate=None):
+
CommonContact.__init__(self, jid, account, resource, show, status, name,
our_chatstate, composing_xep, chatstate)
-
+
self.room_jid = room_jid
self.role = role
self.affiliation = affiliation
-
+
def get_full_jid(self):
return self.room_jid + '/' + self.name
def get_shown_name(self):
return self.name
-
+
def as_contact(self):
- '''Create a Contact instance from this GC_Contact instance'''
+ """
+ Create a Contact instance from this GC_Contact instance
+ """
return Contact(jid=self.get_full_jid(), account=self.account,
resource=self.resource, name=self.name, groups=[], show=self.show,
status=self.status, sub='none', client_caps=self.client_caps)
-
+
class Contacts:
- '''Information concerning all contacts and groupchat contacts'''
+ """
+ Information concerning all contacts and groupchat contacts
+ """
+
def __init__(self):
-
self._metacontact_manager = MetacontactManager(self)
self._accounts = {}
-
- def change_account_name(self, old_name, new_name):
+
+ def change_account_name(self, old_name, new_name):
self._accounts[new_name] = self._accounts[old_name]
self._accounts[new_name].name = new_name
del self._accounts[old_name]
-
+
self._metacontact_manager.change_account_name(old_name, new_name)
def add_account(self, account_name):
@@ -234,7 +248,7 @@ class Contacts:
keyID=keyID, client_caps=client_caps, our_chatstate=our_chatstate,
chatstate=chatstate, last_status_time=last_status_time,
composing_xep=composing_xep)
-
+
def create_self_contact(self, jid, account, resource, show, status, priority,
name='', keyID=''):
conn = common.gajim.connections[account]
@@ -246,7 +260,7 @@ class Contacts:
resource=resource)
self_contact.pep = conn.pep
return self_contact
-
+
def create_not_in_roster_contact(self, jid, account, resource='', name='', keyID=''):
account = self._accounts.get(account, account) # Use Account object if available
return self.create_contact(jid=jid, account=account, resource=resource,
@@ -275,7 +289,7 @@ class Contacts:
self._accounts[account].contacts.remove_jid(jid)
if remove_meta:
self._metacontact_manager.remove_metacontact(account, jid)
-
+
def get_contacts(self, account, jid):
return self._accounts[account].contacts.get_contacts(jid)
@@ -288,13 +302,13 @@ class Contacts:
def get_contact_from_full_jid(self, account, fjid):
return self._accounts[account].contacts.get_contact_from_full_jid(fjid)
-
+
def get_first_contact_from_jid(self, account, jid):
return self._accounts[account].contacts.get_first_contact_from_jid(jid)
def get_contacts_from_group(self, account, group):
return self._accounts[account].contacts.get_contacts_from_group(group)
-
+
def get_jid_list(self, account):
return self._accounts[account].contacts.get_jid_list()
@@ -318,10 +332,11 @@ class Contacts:
contact = self.get_gc_contact(account, room, nick)
return contact
return self.get_highest_prio_contact_from_contacts(contacts)
-
+
def get_nb_online_total_contacts(self, accounts=[], groups=[]):
- '''Returns the number of online contacts and the total number of
- contacts'''
+ """
+ Return the number of online contacts and the total number of contacts
+ """
if accounts == []:
accounts = self.get_accounts()
nbr_online = 0
@@ -358,24 +373,28 @@ class Contacts:
return nbr_online, nbr_total
def is_pm_from_jid(self, account, jid):
- '''Returns True if the given jid is a private message jid'''
+ """
+ Return True if the given jid is a private message jid
+ """
if jid in self._contacts[account]:
return False
return True
def is_pm_from_contact(self, account, contact):
- '''Returns True if the given contact is a private message contact'''
+ """
+ Return True if the given contact is a private message contact
+ """
if isinstance(contact, Contact):
return False
return True
-
+
def __getattr__(self, attr_name):
# Only called if self has no attr_name
if hasattr(self._metacontact_manager, attr_name):
return getattr(self._metacontact_manager, attr_name)
else:
raise AttributeError(attr_name)
-
+
def create_gc_contact(self, room_jid, account, name='', show='', status='',
role='', affiliation='', jid='', resource=''):
account = self._accounts.get(account, account) # Use Account object if available
@@ -402,15 +421,15 @@ class Contacts:
def get_nb_role_total_gc_contacts(self, account, room_jid, role):
return self._accounts[account].gc_contacts.get_nb_role_total_gc_contacts(room_jid, role)
-
-
+
+
class Contacts_New():
-
+
def __init__(self):
# list of contacts {jid1: [C1, C2]}, } one Contact per resource
self._contacts = {}
-
- def add_contact(self, contact):
+
+ def add_contact(self, contact):
if contact.jid not in self._contacts:
self._contacts[contact.jid] = [contact]
return
@@ -426,7 +445,7 @@ class Contacts_New():
self.remove_contact(c)
break
contacts.append(contact)
-
+
def remove_contact(self, contact):
if contact.jid not in self._contacts:
return
@@ -434,28 +453,34 @@ class Contacts_New():
self._contacts[contact.jid].remove(contact)
if len(self._contacts[contact.jid]) == 0:
del self._contacts[contact.jid]
-
+
def remove_jid(self, jid):
- '''Removes all contacts for a given jid'''
+ """
+ Remove all contacts for a given jid
+ """
if jid not in self._contacts:
return
del self._contacts[jid]
-
+
def get_contacts(self, jid):
- '''Returns the list of contact instances for this jid.'''
+ """
+ Return the list of contact instances for this jid
+ """
if jid in self._contacts:
return self._contacts[jid]
else:
return []
-
+
def get_contact(self, jid, resource=None):
### WARNING ###
# This function returns a *RANDOM* resource if resource = None!
# Do *NOT* use if you need to get the contact to which you
# send a message for example, as a bare JID in Jabber means
# highest available resource, which this function ignores!
- '''Returns the contact instance for the given resource if it's given else
- the first contact is no resource is given or None if there is not'''
+ """
+ Return the contact instance for the given resource if it's given else the
+ first contact is no resource is given or None if there is not
+ """
if jid in self._contacts:
if not resource:
return self._contacts[jid][0]
@@ -468,22 +493,26 @@ class Contacts_New():
for jid in self._contacts.keys():
for contact in self._contacts[jid][:]:
yield contact
-
+
def get_jid_list(self):
return self._contacts.keys()
-
+
def get_contact_from_full_jid(self, fjid):
- ''' Get Contact object for specific resource of given jid'''
+ """
+ Get Contact object for specific resource of given jid
+ """
barejid, resource = common.gajim.get_room_and_nick_from_fjid(fjid)
return self.get_contact(barejid, resource)
-
+
def get_first_contact_from_jid(self, jid):
if jid in self._contacts:
return self._contacts[jid][0]
return None
def get_contacts_from_group(self, group):
- '''Returns all contacts in the given group'''
+ """
+ Return all contacts in the given group
+ """
group_contacts = []
for jid in self._contacts:
contacts = self.get_contacts(jid)
@@ -502,11 +531,11 @@ class Contacts_New():
class GC_Contacts():
-
+
def __init__(self):
# list of contacts that are in gc {room_jid: {nick: C}}}
self._rooms = {}
-
+
def add_gc_contact(self, gc_contact):
if gc_contact.room_jid not in self._rooms:
self._rooms[gc_contact.room_jid] = {gc_contact.name: gc_contact}
@@ -544,8 +573,10 @@ class GC_Contacts():
return self._rooms[room_jid][nick]
def get_nb_role_total_gc_contacts(self, room_jid, role):
- '''Returns the number of group chat contacts for the given role and the
- total number of group chat contacts'''
+ """
+ Return the number of group chat contacts for the given role and the total
+ number of group chat contacts
+ """
if room_jid not in self._rooms:
return 0, 0
nb_role = nb_total = 0
@@ -554,25 +585,25 @@ class GC_Contacts():
nb_role += 1
nb_total += 1
return nb_role, nb_total
-
+
class MetacontactManager():
-
+
def __init__(self, contacts):
self._metacontacts_tags = {}
self._contacts = contacts
-
+
def change_account_name(self, old_name, new_name):
self._metacontacts_tags[new_name] = self._metacontacts_tags[old_name]
del self._metacontacts_tags[old_name]
-
+
def add_account(self, account):
if account not in self._metacontacts_tags:
self._metacontacts_tags[account] = {}
-
+
def remove_account(self, account):
del self._metacontacts_tags[account]
-
+
def define_metacontacts(self, account, tags_list):
self._metacontacts_tags[account] = tags_list
@@ -582,13 +613,15 @@ class MetacontactManager():
#FIXME: can this append ?
assert False
- def iter_metacontacts_families(self, account):
+ def iter_metacontacts_families(self, account):
for tag in self._metacontacts_tags[account]:
family = self._get_metacontacts_family_from_tag(account, tag)
yield family
def _get_metacontacts_tag(self, account, jid):
- '''Returns the tag of a jid'''
+ """
+ Return the tag of a jid
+ """
if not account in self._metacontacts_tags:
return None
for tag in self._metacontacts_tags[account]:
@@ -626,7 +659,7 @@ class MetacontactManager():
def remove_metacontact(self, account, jid):
if not account in self._metacontacts_tags:
return None
-
+
found = None
for tag in self._metacontacts_tags[account]:
for data in self._metacontacts_tags[account][tag]:
@@ -657,7 +690,9 @@ class MetacontactManager():
return False
def _get_metacontacts_jids(self, tag, accounts):
- '''Returns all jid for the given tag in the form {acct: [jid1, jid2],.}'''
+ """
+ Return all jid for the given tag in the form {acct: [jid1, jid2],.}
+ """
answers = {}
for account in self._metacontacts_tags:
if tag in self._metacontacts_tags[account]:
@@ -669,9 +704,10 @@ class MetacontactManager():
return answers
def get_metacontacts_family(self, account, jid):
- '''return the family of the given jid, including jid in the form:
- [{'account': acct, 'jid': jid, 'order': order}, ]
- 'order' is optional'''
+ """
+ Return the family of the given jid, including jid in the form:
+ [{'account': acct, 'jid': jid, 'order': order}, ] 'order' is optional
+ """
tag = self._get_metacontacts_tag(account, jid)
return self._get_metacontacts_family_from_tag(account, tag)
@@ -687,9 +723,12 @@ class MetacontactManager():
return answers
def _compare_metacontacts(self, data1, data2):
- '''compare 2 metacontacts.
- Data is {'jid': jid, 'account': account, 'order': order}
- order is optional'''
+ """
+ Compare 2 metacontacts
+
+ Data is {'jid': jid, 'account': account, 'order': order} order is
+ optional
+ """
jid1 = data1['jid']
jid2 = data2['jid']
account1 = data1['account']
@@ -765,16 +804,17 @@ class MetacontactManager():
if account2 > account1:
return -1
return 0
-
- def get_nearby_family_and_big_brother(self, family, account):
- '''Return the nearby family and its Big Brother
- Nearby family is the part of the family that is grouped with the metacontact.
- A metacontact may be over different accounts. If accounts are not merged
- then the given family is split account wise.
+ def get_nearby_family_and_big_brother(self, family, account):
+ """
+ Return the nearby family and its Big Brother
+
+ Nearby family is the part of the family that is grouped with the
+ metacontact. A metacontact may be over different accounts. If accounts
+ are not merged then the given family is split account wise.
(nearby_family, big_brother_jid, big_brother_account)
- '''
+ """
if common.gajim.config.get('mergeaccounts'):
# group all together
nearby_family = family
@@ -789,9 +829,11 @@ class MetacontactManager():
return (nearby_family, big_brother_jid, big_brother_account)
def _get_metacontacts_big_brother(self, family):
- '''which of the family will be the big brother under wich all
- others will be ?'''
+ """
+ Which of the family will be the big brother under wich all others will be
+ ?
+ """
family.sort(cmp=self._compare_metacontacts)
return family[-1]
-
+
# vim: se ts=3: