From 6bf2246de5c3c0c548d7c081841a4f1c608ca650 Mon Sep 17 00:00:00 2001 From: Alexander Cherniuk Date: Thu, 26 Nov 2009 13:58:12 +0200 Subject: [PATCH] A big portion of doc-string refactoring --- src/common/dataforms.py | 132 ++++++++++++----- src/common/dbus_support.py | 22 ++- src/common/dh.py | 7 +- src/common/events.py | 93 ++++++++---- src/common/exceptions.py | 52 +++++-- src/common/fuzzyclock.py | 6 +- src/common/gajim.py | 60 +++++--- src/common/helpers.py | 229 +++++++++++++++++++----------- src/common/i18n.py | 11 +- src/common/idle.py | 4 +- src/common/jingle.py | 32 +++-- src/common/jingle_content.py | 30 +++- src/common/jingle_rtp.py | 34 +++-- src/common/jingle_session.py | 171 +++++++++++++--------- src/common/jingle_transport.py | 29 ++-- src/common/kwalletbinding.py | 12 +- src/common/latex.py | 5 +- src/common/logger.py | 204 +++++++++++++++++--------- src/common/logging_helpers.py | 6 +- src/common/optparser.py | 59 +++++--- src/common/pep.py | 128 ++++++++--------- src/common/proxy65_manager.py | 63 +++++--- src/common/pubsub.py | 32 +++-- src/common/resolver.py | 29 ++-- src/common/rst_xhtml_generator.py | 39 ++--- src/common/sleepy.py | 8 +- src/common/socks5.py | 179 +++++++++++++++-------- src/common/stanza_session.py | 72 ++++++---- 28 files changed, 1133 insertions(+), 615 deletions(-) diff --git a/src/common/dataforms.py b/src/common/dataforms.py index bd9c3e15f..048077a74 100644 --- a/src/common/dataforms.py +++ b/src/common/dataforms.py @@ -21,8 +21,10 @@ ## along with Gajim. If not, see . ## -""" This module contains wrappers for different parts of data forms (JEP 0004). -For information how to use them, read documentation. """ +""" +This module contains wrappers for different parts of data forms (JEP 0004). For +information how to use them, read documentation +""" import xmpp @@ -72,7 +74,9 @@ def Field(typ, **attrs): return f def ExtendField(node): - ''' Helper function to extend a node to field of appropriate type. ''' + """ + Helper function to extend a node to field of appropriate type + """ # when validation (XEP-122) will go in, we could have another classes # like DateTimeField - so that dicts in Field() and ExtendField() will # be different... @@ -94,19 +98,23 @@ def ExtendField(node): return f[typ](extend=node) def ExtendForm(node): - ''' Helper function to extend a node to form of appropriate type. ''' + """ + Helper function to extend a node to form of appropriate type + """ if node.getTag('reported') is not None: return MultipleDataForm(extend=node) else: return SimpleDataForm(extend=node) class DataField(ExtendedNode): - """ Keeps data about one field - var, field type, labels, instructions... - Base class for different kinds of fields. Use Field() function to - construct one of these. """ + """ + Keeps data about one field - var, field type, labels, instructions... Base + class for different kinds of fields. Use Field() function to construct one + of these + """ def __init__(self, typ=None, var=None, value=None, label=None, desc=None, - required=False, options=None, extend=None): + required=False, options=None, extend=None): if extend is None: ExtendedNode.__init__(self, 'field') @@ -124,10 +132,12 @@ class DataField(ExtendedNode): @nested_property def type(): - '''Type of field. Recognized values are: 'boolean', 'fixed', 'hidden', + """ + Type of field. Recognized values are: 'boolean', 'fixed', 'hidden', 'jid-multi', 'jid-single', 'list-multi', 'list-single', 'text-multi', 'text-private', 'text-single'. If you set this to something different, - DataField will store given name, but treat all data as text-single.''' + DataField will store given name, but treat all data as text-single + """ def fget(self): t = self.getAttr('type') if t is None: @@ -142,7 +152,9 @@ class DataField(ExtendedNode): @nested_property def var(): - '''Field identifier.''' + """ + Field identifier + """ def fget(self): return self.getAttr('var') @@ -157,7 +169,9 @@ class DataField(ExtendedNode): @nested_property def label(): - '''Human-readable field name.''' + """ + Human-readable field name + """ def fget(self): l = self.getAttr('label') if not l: @@ -176,7 +190,9 @@ class DataField(ExtendedNode): @nested_property def description(): - '''Human-readable description of field meaning.''' + """ + Human-readable description of field meaning + """ def fget(self): return self.getTagData('desc') or u'' @@ -196,7 +212,9 @@ class DataField(ExtendedNode): @nested_property def required(): - '''Controls whether this field required to fill. Boolean.''' + """ + Controls whether this field required to fill. Boolean + """ def fget(self): return bool(self.getTag('required')) @@ -212,7 +230,9 @@ class DataField(ExtendedNode): class BooleanField(DataField): @nested_property def value(): - '''Value of field. May contain True, False or None.''' + """ + Value of field. May contain True, False or None + """ def fget(self): v = self.getTagData('value') if v in ('0', 'false'): @@ -234,10 +254,15 @@ class BooleanField(DataField): return locals() class StringField(DataField): - ''' Covers fields of types: fixed, hidden, text-private, text-single. ''' + """ + Covers fields of types: fixed, hidden, text-private, text-single + """ + @nested_property def value(): - '''Value of field. May be any unicode string.''' + """ + Value of field. May be any unicode string + """ def fget(self): return self.getTagData('value') or u'' @@ -256,10 +281,15 @@ class StringField(DataField): return locals() class ListField(DataField): - '''Covers fields of types: jid-multi, jid-single, list-multi, list-single.''' + """ + Covers fields of types: jid-multi, jid-single, list-multi, list-single + """ + @nested_property def options(): - '''Options.''' + """ + Options + """ def fget(self): options = [] for element in self.getTags('option'): @@ -294,14 +324,21 @@ class ListField(DataField): yield (v, l) class ListSingleField(ListField, StringField): - '''Covers list-single and jid-single fields.''' + """ + Covers list-single and jid-single fields + """ pass class ListMultiField(ListField): - '''Covers list-multi and jid-multi fields.''' + """ + Covers list-multi and jid-multi fields + """ + @nested_property def values(): - '''Values held in field.''' + """ + Values held in field + """ def fget(self): values = [] for element in self.getTags('value'): @@ -326,7 +363,9 @@ class ListMultiField(ListField): class TextMultiField(DataField): @nested_property def value(): - '''Value held in field.''' + """ + Value held in field + """ def fget(self): value = u'' for element in self.iterTags('value'): @@ -347,8 +386,10 @@ class TextMultiField(DataField): return locals() class DataRecord(ExtendedNode): - '''The container for data fields - an xml element which has DataField - elements as children.''' + """ + The container for data fields - an xml element which has DataField elements + as children + """ def __init__(self, fields=None, associated=None, extend=None): self.associated = associated self.vars = {} @@ -373,7 +414,9 @@ class DataRecord(ExtendedNode): @nested_property def fields(): - '''List of fields in this record.''' + """ + List of fields in this record + """ def fget(self): return self.getTags('field') @@ -391,14 +434,17 @@ class DataRecord(ExtendedNode): return locals() def iter_fields(self): - ''' Iterate over fields in this record. Do not take associated - into account. ''' + """ + Iterate over fields in this record. Do not take associated into account + """ for field in self.iterTags('field'): yield field def iter_with_associated(self): - ''' Iterate over associated, yielding both our field and - associated one together. ''' + """ + Iterate over associated, yielding both our field and associated one + together + """ for field in self.associated.iter_fields(): yield self[field.var], field @@ -420,9 +466,11 @@ class DataForm(ExtendedNode): @nested_property def type(): - ''' Type of the form. Must be one of: 'form', 'submit', 'cancel', 'result'. + """ + Type of the form. Must be one of: 'form', 'submit', 'cancel', 'result'. 'form' - this form is to be filled in; you will be able soon to do: - filledform = DataForm(replyto=thisform)...''' + filledform = DataForm(replyto=thisform) + """ def fget(self): return self.getAttr('type') @@ -434,7 +482,11 @@ class DataForm(ExtendedNode): @nested_property def title(): - ''' Title of the form. Human-readable, should not contain any \\r\\n.''' + """ + Title of the form + + Human-readable, should not contain any \\r\\n. + """ def fget(self): return self.getTagData('title') @@ -451,7 +503,11 @@ class DataForm(ExtendedNode): @nested_property def instructions(): - ''' Instructions for this form. Human-readable, may contain \\r\\n. ''' + """ + Instructions for this form + + Human-readable, may contain \\r\\n. + """ # TODO: the same code is in TextMultiField. join them def fget(self): value = u'' @@ -520,7 +576,9 @@ class MultipleDataForm(DataForm): @nested_property def items(): - ''' A list of all records. ''' + """ + A list of all records + """ def fget(self): return list(self.iter_records()) @@ -543,7 +601,9 @@ class MultipleDataForm(DataForm): # @nested_property # def reported(): -# ''' DataRecord that contains descriptions of fields in records.''' +# """ +# DataRecord that contains descriptions of fields in records +# """ # def fget(self): # return self.getTag('reported') # def fset(self, record): diff --git a/src/common/dbus_support.py b/src/common/dbus_support.py index ae2016603..24d4525ac 100644 --- a/src/common/dbus_support.py +++ b/src/common/dbus_support.py @@ -51,7 +51,10 @@ else: print _('D-Bus capabilities of Gajim cannot be used') class SystemBus: - '''A Singleton for the DBus SystemBus''' + """ + A Singleton for the DBus SystemBus + """ + def __init__(self): self.system_bus = None @@ -84,7 +87,10 @@ class SystemBus: system_bus = SystemBus() class SessionBus: - '''A Singleton for the D-Bus SessionBus''' + """ + A Singleton for the D-Bus SessionBus + """ + def __init__(self): self.session_bus = None @@ -115,8 +121,10 @@ class SessionBus: session_bus = SessionBus() def get_interface(interface, path, start_service=True): - '''Returns an interface on the current SessionBus. If the interface isn\'t - running, it tries to start it first.''' + """ + Get an interface on the current SessionBus. If the interface isn't running, + try to start it first + """ if not supported: return None if session_bus.present(): @@ -144,9 +152,11 @@ def get_interface(interface, path, start_service=True): def get_notifications_interface(notif=None): - '''Returns the notifications interface. + """ + Get the notifications interface - :param notif: DesktopNotification instance''' + :param notif: DesktopNotification instance + """ # try to see if KDE notifications are available iface = get_interface('org.kde.VisualNotifications', '/VisualNotifications', start_service=False) diff --git a/src/common/dh.py b/src/common/dh.py index 4b038ea93..b13cdefc0 100644 --- a/src/common/dh.py +++ b/src/common/dh.py @@ -19,12 +19,13 @@ ## along with Gajim. If not, see . ## -''' +""" This module defines a number of constants; specifically, large primes suitable -for use with the Diffie-Hellman key exchange. +for use with the Diffie-Hellman key exchange These constants have been obtained from RFC2409 and RFC3526. -''' +""" + import string generators = [ None, # one to get the right offset diff --git a/src/common/events.py b/src/common/events.py index 4e5068652..ccf5744f1 100644 --- a/src/common/events.py +++ b/src/common/events.py @@ -27,13 +27,18 @@ import time class Event: - '''Information concerning each event''' + """ + Information concerning each event + """ + def __init__(self, type_, time_, parameters, show_in_roster=False, - show_in_systray=True): - ''' type_ in chat, normal, file-request, file-error, file-completed, + show_in_systray=True): + """ + type_ in chat, normal, file-request, file-error, file-completed, file-request-error, file-send-error, file-stopped, gc_msg, pm, printed_chat, printed_gc_msg, printed_marked_gc_msg, printed_pm, gc-invitation, subscription_request, unsubscribedm jingle-incoming + parameters is (per type_): chat, normal, pm: [message, subject, kind, time, encrypted, resource, msg_id] @@ -47,7 +52,7 @@ class Event: subscription_request: [text, nick] unsubscribed: contact jingle-incoming: (fulljid, sessionid, content_types) - ''' + """ self.type_ = type_ self.time_ = time_ self.parameters = parameters @@ -58,29 +63,40 @@ class Event: self.account = None class Events: - '''Information concerning all events''' + """ + Information concerning all events + """ + def __init__(self): self._events = {} # list of events {acct: {jid1: [E1, E2]}, } self._event_added_listeners = [] self._event_removed_listeners = [] def event_added_subscribe(self, listener): - '''Add a listener when an event is added to the queue''' + """ + Add a listener when an event is added to the queue + """ if not listener in self._event_added_listeners: self._event_added_listeners.append(listener) def event_added_unsubscribe(self, listener): - '''Remove a listener when an event is added to the queue''' + """ + Remove a listener when an event is added to the queue + """ if listener in self._event_added_listeners: self._event_added_listeners.remove(listener) def event_removed_subscribe(self, listener): - '''Add a listener when an event is removed from the queue''' + """ + Add a listener when an event is removed from the queue + """ if not listener in self._event_removed_listeners: self._event_removed_listeners.append(listener) def event_removed_unsubscribe(self, listener): - '''Remove a listener when an event is removed from the queue''' + """ + Remove a listener when an event is removed from the queue + """ if listener in self._event_removed_listeners: self._event_removed_listeners.remove(listener) @@ -125,9 +141,10 @@ class Events: self.fire_event_added(event) def remove_events(self, account, jid, event = None, types = []): - '''if event is not specified, remove all events from this jid, - optionally only from given type - return True if no such event found''' + """ + If event is not specified, remove all events from this jid, optionally + only from given type return True if no such event found + """ if account not in self._events: return True if jid not in self._events[account]: @@ -177,10 +194,11 @@ class Events: return self._get_nb_events(types = types, account = account) def get_events(self, account, jid = None, types = []): - '''returns all events from the given account of the form - {jid1: [], jid2: []} - if jid is given, returns all events from the given jid in a list: [] - optionally only from given type''' + """ + Return all events from the given account of the form {jid1: [], jid2: + []}. If jid is given, returns all events from the given jid in a list: [] + optionally only from given type + """ if account not in self._events: return [] if not jid: @@ -202,7 +220,9 @@ class Events: return events_list def get_first_event(self, account, jid = None, type_ = None): - '''Return the first event of type type_ if given''' + """ + Return the first event of type type_ if given + """ events_list = self.get_events(account, jid, type_) # be sure it's bigger than latest event first_event_time = time.time() + 1 @@ -213,9 +233,11 @@ class Events: first_event = event return first_event - def _get_nb_events(self, account = None, jid = None, attribute = None, - types = []): - '''return the number of pending events''' + def _get_nb_events(self, account = None, jid = None, attribute = None, types + = []): + """ + Return the number of pending events + """ nb = 0 if account: accounts = [account] @@ -241,7 +263,9 @@ class Events: return nb def _get_some_events(self, attribute): - '''attribute in systray, roster''' + """ + Attribute in systray, roster + """ events = {} for account in self._events: events[account] = {} @@ -258,8 +282,11 @@ class Events: return events def _get_first_event_with_attribute(self, events): - '''get the first event - events is in the form {account1: {jid1: [ev1, ev2], },. }''' + """ + Get the first event + + events is in the form {account1: {jid1: [ev1, ev2], },. } + """ # be sure it's bigger than latest event first_event_time = time.time() + 1 first_account = None @@ -276,12 +303,16 @@ class Events: return first_account, first_jid, first_event def get_nb_systray_events(self, types = []): - '''returns the number of events displayed in roster''' + """ + Return the number of events displayed in roster + """ return self._get_nb_events(attribute = 'systray', types = types) def get_systray_events(self): - '''return all events that must be displayed in systray: - {account1: {jid1: [ev1, ev2], },. }''' + """ + Return all events that must be displayed in systray: + {account1: {jid1: [ev1, ev2], },. } + """ return self._get_some_events('systray') def get_first_systray_event(self): @@ -289,13 +320,17 @@ class Events: return self._get_first_event_with_attribute(events) def get_nb_roster_events(self, account = None, jid = None, types = []): - '''returns the number of events displayed in roster''' + """ + Return the number of events displayed in roster + """ return self._get_nb_events(attribute = 'roster', account = account, jid = jid, types = types) def get_roster_events(self): - '''return all events that must be displayed in roster: - {account1: {jid1: [ev1, ev2], },. }''' + """ + Return all events that must be displayed in roster: + {account1: {jid1: [ev1, ev2], },. } + """ return self._get_some_events('roster') # vim: se ts=3: diff --git a/src/common/exceptions.py b/src/common/exceptions.py index 9f20e1d97..75f5b8913 100644 --- a/src/common/exceptions.py +++ b/src/common/exceptions.py @@ -22,7 +22,10 @@ ## class PysqliteNotAvailable(Exception): - '''sqlite2 is not installed or python bindings are missing''' + """ + Sqlite2 is not installed or python bindings are missing + """ + def __init__(self): Exception.__init__(self) @@ -30,7 +33,10 @@ class PysqliteNotAvailable(Exception): return _('pysqlite2 (aka python-pysqlite2) dependency is missing. Exiting...') class PysqliteOperationalError(Exception): - '''sqlite2 raised pysqlite2.dbapi2.OperationalError''' + """ + Sqlite2 raised pysqlite2.dbapi2.OperationalError + """ + def __init__(self, text=''): Exception.__init__(self) self.text = text @@ -39,7 +45,10 @@ class PysqliteOperationalError(Exception): return self.text class DatabaseMalformed(Exception): - '''The databas can't be read''' + """ + The databas can't be read + """ + def __init__(self): Exception.__init__(self) @@ -47,7 +56,10 @@ class DatabaseMalformed(Exception): return _('Database cannot be read.') class ServiceNotAvailable(Exception): - '''This exception is raised when we cannot use Gajim remotely''' + """ + This exception is raised when we cannot use Gajim remotely' + """ + def __init__(self): Exception.__init__(self) @@ -55,7 +67,10 @@ class ServiceNotAvailable(Exception): return _('Service not available: Gajim is not running, or remote_control is False') class DbusNotSupported(Exception): - '''D-Bus is not installed or python bindings are missing''' + """ + D-Bus is not installed or python bindings are missing + """ + def __init__(self): Exception.__init__(self) @@ -63,7 +78,10 @@ class DbusNotSupported(Exception): return _('D-Bus is not present on this machine or python module is missing') class SessionBusNotPresent(Exception): - '''This exception indicates that there is no session daemon''' + """ + This exception indicates that there is no session daemon + """ + def __init__(self): Exception.__init__(self) @@ -71,19 +89,28 @@ class SessionBusNotPresent(Exception): return _('Session bus is not available.\nTry reading http://trac.gajim.org/wiki/GajimDBus') class NegotiationError(Exception): - '''A session negotiation failed''' + """ + A session negotiation failed + """ pass class DecryptionError(Exception): - '''A message couldn't be decrypted into usable XML''' + """ + A message couldn't be decrypted into usable XML + """ pass class Cancelled(Exception): - '''The user cancelled an operation''' + """ + The user cancelled an operation + """ pass class LatexError(Exception): - '''LaTeX processing failed for some reason''' + """ + LaTeX processing failed for some reason + """ + def __init__(self, text=''): Exception.__init__(self) self.text = text @@ -92,7 +119,10 @@ class LatexError(Exception): return self.text class GajimGeneralException(Exception): - '''This exception is our general exception''' + """ + This exception is our general exception + """ + def __init__(self, text=''): Exception.__init__(self) self.text = text diff --git a/src/common/fuzzyclock.py b/src/common/fuzzyclock.py index fc285fd8f..3adad66d1 100755 --- a/src/common/fuzzyclock.py +++ b/src/common/fuzzyclock.py @@ -21,7 +21,7 @@ ## along with Gajim. If not, see . ## -''' +""" Python class to show a "fuzzy clock". Homepage of the original: http://home.gna.org/fuzzyclock/ Project Page of the original: http://gna.org/projects/fuzzyclock @@ -30,7 +30,7 @@ The class is based on a port from PHP code by Henrique Recidive which was in turn based on the Fuzzy Clock Applet of Frerich Raabe (KDE). So most of the credit goes to this guys, thanks :-) -''' +""" import time @@ -46,7 +46,7 @@ class FuzzyClock: _('half past %(0)s'), _('twenty five to %(1)s'), _('twenty to %(1)s'), _('quarter to %(1)s'), _('ten to %(1)s'), _('five to %(1)s'), _("%(1)s o'clock") ] - FUZZY_DAYTIME = [ _('Night'), _('Early morning'), _('Morning'), + FUZZY_DAYTIME = [ _('Night'), _('Early morning'), _('Morning'), _('Almost noon'), _('Noon'), _('Afternoon'), _('Evening'), _('Late evening'), _('Night') ] diff --git a/src/common/gajim.py b/src/common/gajim.py index d9181c2de..ba43cff68 100644 --- a/src/common/gajim.py +++ b/src/common/gajim.py @@ -241,8 +241,9 @@ def get_room_and_nick_from_fjid(jid): return l def get_real_jid_from_fjid(account, fjid): - '''returns real jid or returns None - if we don't know the real jid''' + """ + Return real jid or returns None, if we don't know the real jid + """ room_jid, nick = get_room_and_nick_from_fjid(fjid) if not nick: # It's not a fake_jid, it is a real jid return fjid # we return the real jid @@ -267,7 +268,9 @@ def get_jid_without_resource(jid): return jid.split('/')[0] def construct_fjid(room_jid, nick): - ''' nick is in utf8 (taken from treeview); room_jid is in unicode''' + """ + Nick is in UTF-8 (taken from treeview); room_jid is in unicode + """ # fake jid is the jid for a contact in a room # gaim@conference.jabber.org/nick if isinstance(nick, str): @@ -281,19 +284,17 @@ def get_resource_from_jid(jid): else: return '' -# [15:34:28] we should add contact.fake_jid I think -# [15:34:46] so if we know real jid, it wil be in contact.jid, or we look in contact.fake_jid -# [15:32:54] they can have resource if we know the real jid -# [15:33:07] and that resource is in contact.resource - def get_number_of_accounts(): - '''returns the number of ALL accounts''' + """ + Return the number of ALL accounts + """ return len(connections.keys()) def get_number_of_connected_accounts(accounts_list = None): - '''returns the number of CONNECTED accounts - you can optionally pass an accounts_list - and if you do those will be checked, else all will be checked''' + """ + Returns the number of CONNECTED accounts. Uou can optionally pass an + accounts_list and if you do those will be checked, else all will be checked + """ connected_accounts = 0 if accounts_list is None: accounts = connections.keys() @@ -320,7 +321,9 @@ def zeroconf_is_connected(): config.get_per('accounts', ZEROCONF_ACC_NAME, 'is_zeroconf') def get_number_of_securely_connected_accounts(): - '''returns the number of the accounts that are SSL/TLS connected''' + """ + Return the number of the accounts that are SSL/TLS connected + """ num_of_secured = 0 for account in connections.keys(): if account_is_securely_connected(account): @@ -335,8 +338,11 @@ def account_is_securely_connected(account): return False def get_transport_name_from_jid(jid, use_config_setting = True): - '''returns 'aim', 'gg', 'irc' etc - if JID is not from transport returns None''' + """ + Returns 'aim', 'gg', 'irc' etc + + If JID is not from transport returns None. + """ #FIXME: jid can be None! one TB I saw had this problem: # in the code block # it is a groupchat presence in handle_event_notify # jid was None. Yann why? @@ -372,21 +378,27 @@ def jid_is_transport(jid): return False def get_jid_from_account(account_name): - '''return the jid we use in the given account''' + """ + Return the jid we use in the given account + """ name = config.get_per('accounts', account_name, 'name') hostname = config.get_per('accounts', account_name, 'hostname') jid = name + '@' + hostname return jid def get_our_jids(): - '''returns a list of the jids we use in our accounts''' + """ + Returns a list of the jids we use in our accounts + """ our_jids = list() for account in contacts.get_accounts(): our_jids.append(get_jid_from_account(account)) return our_jids def get_hostname_from_account(account_name, use_srv = False): - '''returns hostname (if custom hostname is used, that is returned)''' + """ + Returns hostname (if custom hostname is used, that is returned) + """ if use_srv and connections[account_name].connected_hostname: return connections[account_name].connected_hostname if config.get_per('accounts', account_name, 'use_custom_host'): @@ -394,7 +406,9 @@ def get_hostname_from_account(account_name, use_srv = False): return config.get_per('accounts', account_name, 'hostname') def get_notification_image_prefix(jid): - '''returns the prefix for the notification images''' + """ + Returns the prefix for the notification images + """ transport_name = get_transport_name_from_jid(jid) if transport_name in ('aim', 'icq', 'msn', 'yahoo', 'facebook'): prefix = transport_name @@ -403,7 +417,9 @@ def get_notification_image_prefix(jid): return prefix def get_name_from_jid(account, jid): - '''returns from JID's shown name and if no contact returns jids''' + """ + Return from JID's shown name and if no contact returns jids + """ contact = contacts.get_first_contact_from_jid(account, jid) if contact: actor = contact.get_shown_name() @@ -412,7 +428,9 @@ def get_name_from_jid(account, jid): return actor def get_priority(account, show): - '''return the priority an account must have''' + """ + Return the priority an account must have + """ if not show: show = 'online' diff --git a/src/common/helpers.py b/src/common/helpers.py index 341ebb15f..a938f38d7 100644 --- a/src/common/helpers.py +++ b/src/common/helpers.py @@ -92,15 +92,19 @@ def decompose_jid(jidstring): return user, server, resource def parse_jid(jidstring): - '''Perform stringprep on all JID fragments from a string - and return the full jid''' + """ + Perform stringprep on all JID fragments from a string and return the full + jid + """ # This function comes from http://svn.twistedmatrix.com/cvs/trunk/twisted/words/protocols/jabber/jid.py return prep(*decompose_jid(jidstring)) def idn_to_ascii(host): - '''convert IDN (Internationalized Domain Names) to ACE - (ASCII-compatible encoding)''' + """ + Convert IDN (Internationalized Domain Names) to ACE (ASCII-compatible + encoding) + """ from encodings import idna labels = idna.dots.split(host) converted_labels = [] @@ -109,8 +113,10 @@ def idn_to_ascii(host): return ".".join(converted_labels) def ascii_to_idn(host): - '''convert ACE (ASCII-compatible encoding) to IDN - (Internationalized Domain Names)''' + """ + Convert ACE (ASCII-compatible encoding) to IDN (Internationalized Domain + Names) + """ from encodings import idna labels = idna.dots.split(host) converted_labels = [] @@ -119,7 +125,9 @@ def ascii_to_idn(host): return ".".join(converted_labels) def parse_resource(resource): - '''Perform stringprep on resource and return it''' + """ + Perform stringprep on resource and return it + """ if resource: try: from xmpp.stringprepare import resourceprep @@ -128,10 +136,11 @@ def parse_resource(resource): raise InvalidFormat, 'Invalid character in resource.' def prep(user, server, resource): - '''Perform stringprep on all JID fragments and return the full jid''' + """ + Perform stringprep on all JID fragments and return the full jid + """ # This function comes from #http://svn.twistedmatrix.com/cvs/trunk/twisted/words/protocols/jabber/jid.py - if user: try: from xmpp.stringprepare import nodeprep @@ -186,10 +195,13 @@ def temp_failure_retry(func, *args, **kwargs): raise def get_uf_show(show, use_mnemonic = False): - '''returns a userfriendly string for dnd/xa/chat - and makes all strings translatable - if use_mnemonic is True, it adds _ so GUI should call with True - for accessibility issues''' + """ + Return a userfriendly string for dnd/xa/chat and make all strings + translatable + + If use_mnemonic is True, it adds _ so GUI should call with True for + accessibility issues + """ if show == 'dnd': if use_mnemonic: uf_show = _('_Busy') @@ -324,7 +336,9 @@ def from_one_line(msg): return msg def get_uf_chatstate(chatstate): - '''removes chatstate jargon and returns user friendly messages''' + """ + Remove chatstate jargon and returns user friendly messages + """ if chatstate == 'active': return _('is paying attention to the conversation') elif chatstate == 'inactive': @@ -339,10 +353,11 @@ def get_uf_chatstate(chatstate): return '' def is_in_path(command, return_abs_path=False): - '''Returns True if 'command' is found in one of the directories in the - user's path. If 'return_abs_path' is True, returns the absolute path of - the first found command instead. Returns False otherwise and on errors.''' - + """ + Return True if 'command' is found in one of the directories in the user's + path. If 'return_abs_path' is True, return the absolute path of the first + found command instead. Return False otherwise and on errors + """ for directory in os.getenv('PATH').split(os.pathsep): try: if command in os.listdir(directory): @@ -405,7 +420,9 @@ def get_output_of_command(command): return output def decode_string(string): - '''try to decode (to make it Unicode instance) given string''' + """ + Try to decode (to make it Unicode instance) given string + """ if isinstance(string, unicode): return string # by the time we go to iso15 it better be the one else we show bad characters @@ -420,7 +437,9 @@ def decode_string(string): return string def ensure_utf8_string(string): - '''make sure string is in UTF-8''' + """ + Make sure string is in UTF-8 + """ try: string = decode_string(string).encode('utf-8') except Exception: @@ -428,28 +447,28 @@ def ensure_utf8_string(string): return string def get_windows_reg_env(varname, default=''): - '''asks for paths commonly used but not exposed as ENVs - in english Windows 2003 those are: - 'AppData' = %USERPROFILE%\Application Data (also an ENV) - 'Desktop' = %USERPROFILE%\Desktop - 'Favorites' = %USERPROFILE%\Favorites - 'NetHood' = %USERPROFILE%\NetHood - 'Personal' = D:\My Documents (PATH TO MY DOCUMENTS) - 'PrintHood' = %USERPROFILE%\PrintHood - 'Programs' = %USERPROFILE%\Start Menu\Programs - 'Recent' = %USERPROFILE%\Recent - 'SendTo' = %USERPROFILE%\SendTo - 'Start Menu' = %USERPROFILE%\Start Menu - 'Startup' = %USERPROFILE%\Start Menu\Programs\Startup - 'Templates' = %USERPROFILE%\Templates - 'My Pictures' = D:\My Documents\My Pictures - 'Local Settings' = %USERPROFILE%\Local Settings - 'Local AppData' = %USERPROFILE%\Local Settings\Application Data - 'Cache' = %USERPROFILE%\Local Settings\Temporary Internet Files - 'Cookies' = %USERPROFILE%\Cookies - 'History' = %USERPROFILE%\Local Settings\History - ''' - + """ + Ask for paths commonly used but not exposed as ENVs in english Windows 2003 + those are: + 'AppData' = %USERPROFILE%\Application Data (also an ENV) + 'Desktop' = %USERPROFILE%\Desktop + 'Favorites' = %USERPROFILE%\Favorites + 'NetHood' = %USERPROFILE%\NetHood + 'Personal' = D:\My Documents (PATH TO MY DOCUMENTS) + 'PrintHood' = %USERPROFILE%\PrintHood + 'Programs' = %USERPROFILE%\Start Menu\Programs + 'Recent' = %USERPROFILE%\Recent + 'SendTo' = %USERPROFILE%\SendTo + 'Start Menu' = %USERPROFILE%\Start Menu + 'Startup' = %USERPROFILE%\Start Menu\Programs\Startup + 'Templates' = %USERPROFILE%\Templates + 'My Pictures' = D:\My Documents\My Pictures + 'Local Settings' = %USERPROFILE%\Local Settings + 'Local AppData' = %USERPROFILE%\Local Settings\Application Data + 'Cache' = %USERPROFILE%\Local Settings\Temporary Internet Files + 'Cookies' = %USERPROFILE%\Cookies + 'History' = %USERPROFILE%\Local Settings\History + """ if os.name != 'nt': return '' @@ -467,7 +486,9 @@ r'Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders') return val def get_my_pictures_path(): - '''windows-only atm. [Unix lives in the past]''' + """ + Windows-only atm + """ return get_windows_reg_env('My Pictures') def get_desktop_path(): @@ -485,8 +506,10 @@ def get_documents_path(): return path def sanitize_filename(filename): - '''makes sure the filename we will write does contain only acceptable and - latin characters, and is not too long (in that case hash it)''' + """ + Make sure the filename we will write does contain only acceptable and latin + characters, and is not too long (in that case hash it) + """ # 48 is the limit if len(filename) > 48: hash = hashlib.md5(filename) @@ -502,11 +525,13 @@ def sanitize_filename(filename): return filename def reduce_chars_newlines(text, max_chars = 0, max_lines = 0): - '''Cut the chars after 'max_chars' on each line - and show only the first 'max_lines'. - If any of the params is not present (None or 0) the action - on it is not performed''' + """ + Cut the chars after 'max_chars' on each line and show only the first + 'max_lines' + If any of the params is not present (None or 0) the action on it is not + performed + """ def _cut_if_long(string): if len(string) > max_chars: string = string[:max_chars - 3] + '...' @@ -535,10 +560,11 @@ def get_account_status(account): return status def get_avatar_path(prefix): - '''Returns the filename of the avatar, distinguishes between user- and - contact-provided one. Returns None if no avatar was found at all. - prefix is the path to the requested avatar just before the ".png" or - ".jpeg".''' + """ + Return the filename of the avatar, distinguishes between user- and contact- + provided one. Return None if no avatar was found at all. prefix is the path + to the requested avatar just before the ".png" or ".jpeg" + """ # First, scan for a local, user-set avatar for type_ in ('jpeg', 'png'): file_ = prefix + '_local.' + type_ @@ -552,13 +578,16 @@ def get_avatar_path(prefix): return None def datetime_tuple(timestamp): - '''Converts timestamp using strptime and the format: %Y%m%dT%H:%M:%S + """ + Convert timestamp using strptime and the format: %Y%m%dT%H:%M:%S + Because of various datetime formats are used the following exceptions are handled: - Optional milliseconds appened to the string are removed - Optional Z (that means UTC) appened to the string are removed - XEP-082 datetime strings have all '-' cahrs removed to meet - the above format.''' + the above format. + """ timestamp = timestamp.split('.')[0] timestamp = timestamp.replace('-', '') timestamp = timestamp.replace('z', '') @@ -609,8 +638,11 @@ def convert_bytes(string): return suffix % unicode(bytes) def get_contact_dict_for_account(account): - ''' create a dict of jid, nick -> contact with all contacts of account. - Can be used for completion lists''' + """ + Create a dict of jid, nick -> contact with all contacts of account. + + Can be used for completion lists + """ contacts_dict = {} for jid in gajim.contacts.get_jid_list(account): contact = gajim.contacts.get_contact_with_highest_priority(account, @@ -692,13 +724,15 @@ def play_sound(event): path_to_soundfile = gajim.config.get_per('soundevents', event, 'path') play_sound_file(path_to_soundfile) -def check_soundfile_path(file, - dirs=(gajim.gajimpaths.root, gajim.DATA_DIR)): - '''Check if the sound file exists. +def check_soundfile_path(file, dirs=(gajim.gajimpaths.root, gajim.DATA_DIR)): + """ + Check if the sound file exists + :param file: the file to check, absolute or relative to 'dirs' path :param dirs: list of knows paths to fallback if the file doesn't exists (eg: ~/.gajim/sounds/, DATADIR/sounds...). - :return the path to file or None if it doesn't exists.''' + :return the path to file or None if it doesn't exists. + """ if not file: return None elif os.path.exists(file): @@ -710,16 +744,17 @@ def check_soundfile_path(file, return d return None -def strip_soundfile_path(file, - dirs=(gajim.gajimpaths.root, gajim.DATA_DIR), - abs=True): - '''Remove knowns paths from a sound file: +def strip_soundfile_path(file, dirs=(gajim.gajimpaths.root, gajim.DATA_DIR), + abs=True): + """ + Remove knowns paths from a sound file + Filechooser returns absolute path. If path is a known fallback path, we remove it. So config have no hardcoded path to DATA_DIR and text in textfield is shorther. param: file: the filename to strip. param: dirs: list of knowns paths from which the filename should be stripped. param: abs: force absolute path on dirs - ''' + """ if not file: return None @@ -777,7 +812,9 @@ def get_global_status(): def statuses_unified(): - '''testing if all statuses are the same.''' + """ + Test if all statuses are the same + """ reference = None for account in gajim.connections: if not gajim.config.get_per('accounts', account, @@ -790,7 +827,9 @@ def statuses_unified(): return True def get_icon_name_to_show(contact, account = None): - '''Get the icon name to show in online, away, requested, ...''' + """ + Get the icon name to show in online, away, requested, etc + """ if account and gajim.events.get_nb_roster_events(account, contact.jid): return 'event' if account and gajim.events.get_nb_roster_events(account, @@ -819,16 +858,22 @@ def get_icon_name_to_show(contact, account = None): return 'not in roster' def get_full_jid_from_iq(iq_obj): - '''return the full jid (with resource) from an iq as unicode''' + """ + Return the full jid (with resource) from an iq as unicode + """ return parse_jid(str(iq_obj.getFrom())) def get_jid_from_iq(iq_obj): - '''return the jid (without resource) from an iq as unicode''' + """ + Return the jid (without resource) from an iq as unicode + """ jid = get_full_jid_from_iq(iq_obj) return gajim.get_jid_without_resource(jid) def get_auth_sha(sid, initiator, target): - ''' return sha of sid + initiator + target used for proxy auth''' + """ + Return sha of sid + initiator + target used for proxy auth + """ return hashlib.sha1("%s%s%s" % (sid, initiator, target)).hexdigest() def remove_invalid_xml_chars(string): @@ -861,7 +906,9 @@ distro_info = { } def get_random_string_16(): - ''' create random string of length 16''' + """ + Create random string of length 16 + """ rng = range(65, 90) rng.extend(range(48, 57)) char_sequence = [chr(e) for e in rng] @@ -946,11 +993,14 @@ def get_os_info(): def allow_showing_notification(account, type_ = 'notify_on_new_message', -advanced_notif_num = None, is_first_message = True): - '''is it allowed to show nofication? - check OUR status and if we allow notifications for that status - type is the option that need to be True e.g.: notify_on_signing - is_first_message: set it to false when it's not the first message''' + advanced_notif_num = None, is_first_message = True): + """ + Is it allowed to show nofication? + + Check OUR status and if we allow notifications for that status type is the + option that need to be True e.g.: notify_on_signing is_first_message: set it + to false when it's not the first message + """ if advanced_notif_num is not None: popup = gajim.config.get_per('notifications', str(advanced_notif_num), 'popup') @@ -967,7 +1017,9 @@ advanced_notif_num = None, is_first_message = True): return False def allow_popup_window(account, advanced_notif_num = None): - '''is it allowed to popup windows?''' + """ + Is it allowed to popup windows? + """ if advanced_notif_num is not None: popup = gajim.config.get_per('notifications', str(advanced_notif_num), 'auto_open') @@ -1018,8 +1070,10 @@ def get_chat_control(account, contact): return gajim.interface.msg_win_mgr.get_control(contact.jid, account) def get_notification_icon_tooltip_dict(): - '''returns a dict of the form {acct: {'show': show, 'message': message, - 'event_lines': [list of text lines to show in tooltip]}''' + """ + Return a dict of the form {acct: {'show': show, 'message': message, + 'event_lines': [list of text lines to show in tooltip]} + """ # How many events must there be before they're shown summarized, not per-user max_ungrouped_events = 10 @@ -1131,7 +1185,9 @@ def get_notification_icon_tooltip_text(): return text def get_accounts_info(): - '''helper for notification icon tooltip''' + """ + Helper for notification icon tooltip + """ accounts = [] accounts_list = sorted(gajim.contacts.get_accounts()) for account in accounts_list: @@ -1182,9 +1238,14 @@ def get_transport_path(transport): return get_iconset_path(gajim.config.get('iconset')) def prepare_and_validate_gpg_keyID(account, jid, keyID): - '''Returns an eight char long keyID that can be used with for GPG encryption with this contact. - If the given keyID is None, return UNKNOWN; if the key does not match the assigned key - XXXXXXXXMISMATCH is returned. If the key is trusted and not yet assigned, assign it''' + """ + Return an eight char long keyID that can be used with for GPG encryption + with this contact + + If the given keyID is None, return UNKNOWN; if the key does not match the + assigned key XXXXXXXXMISMATCH is returned. If the key is trusted and not yet + assigned, assign it. + """ if gajim.connections[account].USE_GPG: if keyID and len(keyID) == 16: keyID = keyID[8:] diff --git a/src/common/i18n.py b/src/common/i18n.py index 3c47d3da3..7b9e8dab3 100644 --- a/src/common/i18n.py +++ b/src/common/i18n.py @@ -32,7 +32,7 @@ def paragraph_direction_mark(text): """ Determine paragraph writing direction according to http://www.unicode.org/reports/tr9/#The_Paragraph_Level - + Returns either Unicode LTR mark or RTL mark. """ for char in text: @@ -84,11 +84,12 @@ def Q_(s): return s def ngettext(s_sing, s_plural, n, replace_sing = None, replace_plural = None): - '''use as: - i18n.ngettext('leave room %s', 'leave rooms %s', len(rooms), 'a', 'a, b, c') + """ + Use as: + i18n.ngettext('leave room %s', 'leave rooms %s', len(rooms), 'a', 'a, b, c') - in other words this is a hack to ngettext() to support %s %d etc.. - ''' + In other words this is a hack to ngettext() to support %s %d etc.. + """ text = _translation.ungettext(s_sing, s_plural, n) if n == 1 and replace_sing is not None: text = text % replace_sing diff --git a/src/common/idle.py b/src/common/idle.py index eb7e1be6a..ccdfa5a79 100644 --- a/src/common/idle.py +++ b/src/common/idle.py @@ -73,7 +73,9 @@ except OSError, e: xss_available = False def getIdleSec(): - """Returns the idle time in seconds""" + """ + Return the idle time in seconds + """ if not xss_available: return 0 if libXss.XScreenSaverQueryInfo(dpy_p, rootwindow, xss_info_p) == 0: diff --git a/src/common/jingle.py b/src/common/jingle.py index 8a369ff7e..c4f7bc22d 100644 --- a/src/common/jingle.py +++ b/src/common/jingle.py @@ -10,7 +10,9 @@ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## -''' Handles the jingle signalling protocol. ''' +""" +Handles the jingle signalling protocol +""" #TODO: # * things in XEP 0176, including: @@ -37,7 +39,10 @@ from jingle_rtp import JingleAudio, JingleVideo class ConnectionJingle(object): - ''' This object depends on that it is a part of Connection class. ''' + """ + This object depends on that it is a part of Connection class. + """ + def __init__(self): # dictionary: (jid, sessionid) => JingleSession object self.__sessions = {} @@ -47,13 +52,17 @@ class ConnectionJingle(object): self.__iq_responses = {} def add_jingle(self, jingle): - ''' Add a jingle session to a jingle stanza dispatcher + """ + Add a jingle session to a jingle stanza dispatcher + jingle - a JingleSession object. - ''' + """ self.__sessions[(jingle.peerjid, jingle.sid)] = jingle def delete_jingle_session(self, peerjid, sid): - ''' Remove a jingle session from a jingle stanza dispatcher ''' + """ + Remove a jingle session from a jingle stanza dispatcher + """ key = (peerjid, sid) if key in self.__sessions: #FIXME: Move this elsewhere? @@ -63,12 +72,15 @@ class ConnectionJingle(object): del self.__sessions[key] def _JingleCB(self, con, stanza): - ''' The jingle stanza dispatcher. - Route jingle stanza to proper JingleSession object, - or create one if it is a new session. - TODO: Also check if the stanza isn't an error stanza, if so - route it adequatelly.''' + """ + The jingle stanza dispatcher + Route jingle stanza to proper JingleSession object, or create one if it + is a new session. + + TODO: Also check if the stanza isn't an error stanza, if so route it + adequatelly. + """ # get data jid = helpers.get_full_jid_from_iq(stanza) id = stanza.getID() diff --git a/src/common/jingle_content.py b/src/common/jingle_content.py index 2feb5d8de..8aa19b45c 100644 --- a/src/common/jingle_content.py +++ b/src/common/jingle_content.py @@ -10,7 +10,10 @@ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## -''' Handles Jingle contents (XEP 0166). ''' + +""" +Handles Jingle contents (XEP 0166) +""" contents = {} @@ -23,7 +26,10 @@ def get_jingle_content(node): class JingleContent(object): - ''' An abstraction of content in Jingle sessions. ''' + """ + An abstraction of content in Jingle sessions + """ + def __init__(self, session, transport): self.session = session self.transport = transport @@ -71,24 +77,32 @@ class JingleContent(object): return (self.accepted and not self.sent) def add_remote_candidates(self, candidates): - ''' Add a list of candidates to the list of remote candidates. ''' + """ + Add a list of candidates to the list of remote candidates + """ pass def stanzaCB(self, stanza, content, error, action): - ''' Called when something related to our content was sent by peer. ''' + """ + Called when something related to our content was sent by peer + """ if action in self.callbacks: for callback in self.callbacks[action]: callback(stanza, content, error, action) def __transportInfoCB(self, stanza, content, error, action): - ''' Got a new transport candidate. ''' + """ + Got a new transport candidate + """ candidates = self.transport.parse_transport_stanza( content.getTag('transport')) if candidates: self.add_remote_candidates(candidates) def __content(self, payload=[]): - ''' Build a XML content-wrapper for our data. ''' + """ + Build a XML content-wrapper for our data + """ return xmpp.Node('content', attrs={'name': self.name, 'creator': self.creator}, payload=payload) @@ -99,7 +113,9 @@ class JingleContent(object): self.session.send_transport_info(content) def __fillJingleStanza(self, stanza, content, error, action): - ''' Add our things to session-initiate stanza. ''' + """ + Add our things to session-initiate stanza + """ self._fillContent(content) self.sent = True content.addChild(node=self.transport.make_transport()) diff --git a/src/common/jingle_rtp.py b/src/common/jingle_rtp.py index d67b0f465..879bf4a2b 100644 --- a/src/common/jingle_rtp.py +++ b/src/common/jingle_rtp.py @@ -10,8 +10,10 @@ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## -''' Handles Jingle RTP sessions (XEP 0167). ''' +""" +Handles Jingle RTP sessions (XEP 0167) +""" import gobject @@ -23,7 +25,9 @@ from jingle_content import contents, JingleContent # TODO: Will that be even used? def get_first_gst_element(elements): - ''' Returns, if it exists, the first available element of the list. ''' + """ + Return, if it exists, the first available element of the list + """ for name in elements: factory = gst.element_factory_find(name) if factory: @@ -70,7 +74,7 @@ class JingleRTPContent(JingleContent): self.p2psession = self.conference.new_session(self.farsight_media) participant = self.conference.new_participant(self.session.peerjid) - #FIXME: Consider a workaround, here... + # FIXME: Consider a workaround, here... # pidgin and telepathy-gabble don't follow the XEP, and it won't work # due to bad controlling-mode params = {'controlling-mode': self.session.weinitiate,# 'debug': False} @@ -85,14 +89,14 @@ class JingleRTPContent(JingleContent): def add_remote_candidates(self, candidates): JingleContent.add_remote_candidates(self, candidates) - #FIXME: connectivity should not be etablished yet + # FIXME: connectivity should not be etablished yet # Instead, it should be etablished after session-accept! if self.sent: self.p2pstream.set_remote_candidates(candidates) def batch_dtmf(self, events): if self._dtmf_running: - raise Exception #TODO: Proper exception + raise Exception # TODO: Proper exception self._dtmf_running = True self._start_dtmf(events.pop(0)) gobject.timeout_add(500, self._next_dtmf, events) @@ -143,7 +147,7 @@ class JingleRTPContent(JingleContent): elif name == 'farsight-codecs-changed': if self.is_ready(): self.session.on_session_state_changed(self) - #TODO: description-info + # TODO: description-info elif name == 'farsight-local-candidates-prepared': self.candidates_ready = True if self.is_ready(): @@ -152,7 +156,7 @@ class JingleRTPContent(JingleContent): candidate = message.structure['candidate'] self.transport.candidates.append(candidate) if self.candidates_ready: - #FIXME: Is this case even possible? + # FIXME: Is this case even possible? self.send_candidate(candidate) elif name == 'farsight-component-state-changed': state = message.structure['state'] @@ -173,7 +177,7 @@ class JingleRTPContent(JingleContent): if self.transport.remote_candidates: self.p2pstream.set_remote_candidates(self.transport.remote_candidates) self.transport.remote_candidates = [] - #TODO: farsight.DIRECTION_BOTH only if senders='both' + # TODO: farsight.DIRECTION_BOTH only if senders='both' self.p2pstream.set_property('direction', farsight.DIRECTION_BOTH) self.session.content_negociated(self.media) @@ -195,7 +199,7 @@ class JingleRTPContent(JingleContent): codecs.append(c) if len(codecs) > 0: - #FIXME: Handle this case: + # FIXME: Handle this case: # glib.GError: There was no intersection between the remote codecs and # the local ones self.p2pstream.set_remote_codecs(codecs) @@ -228,14 +232,15 @@ class JingleRTPContent(JingleContent): class JingleAudio(JingleRTPContent): - ''' Jingle VoIP sessions consist of audio content transported - over an ICE UDP protocol. ''' + """ + Jingle VoIP sessions consist of audio content transported over an ICE UDP + protocol + """ + def __init__(self, session, transport=None): JingleRTPContent.__init__(self, session, 'audio', transport) self.setup_stream() - - ''' Things to control the gstreamer's pipeline ''' def setup_stream(self): JingleRTPContent.setup_stream(self) @@ -283,9 +288,8 @@ class JingleVideo(JingleRTPContent): JingleRTPContent.__init__(self, session, 'video', transport) self.setup_stream() - ''' Things to control the gstreamer's pipeline ''' def setup_stream(self): - #TODO: Everything is not working properly: + # TODO: Everything is not working properly: # sometimes, one window won't show up, # sometimes it'll freeze... JingleRTPContent.setup_stream(self) diff --git a/src/common/jingle_session.py b/src/common/jingle_session.py index 9118affdf..b6238319a 100644 --- a/src/common/jingle_session.py +++ b/src/common/jingle_session.py @@ -10,7 +10,10 @@ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## -''' Handles Jingle sessions (XEP 0166). ''' + +""" +Handles Jingle sessions (XEP 0166) +""" #TODO: # * Have JingleContent here @@ -29,25 +32,38 @@ import xmpp from jingle_transport import get_jingle_transport from jingle_content import get_jingle_content -#FIXME: Move it to JingleSession.States? +# FIXME: Move it to JingleSession.States? class JingleStates(object): - ''' States in which jingle session may exist. ''' + """ + States in which jingle session may exist + """ ended = 0 pending = 1 active = 2 class OutOfOrder(Exception): - ''' Exception that should be raised when an action is received when in the wrong state. ''' + """ + Exception that should be raised when an action is received when in the wrong + state + """ class TieBreak(Exception): - ''' Exception that should be raised in case of a tie, when we overrule the other action. ''' + """ + Exception that should be raised in case of a tie, when we overrule the other + action + """ class JingleSession(object): - ''' This represents one jingle session. ''' + """ + This represents one jingle session + """ + def __init__(self, con, weinitiate, jid, sid=None): - ''' con -- connection object, - weinitiate -- boolean, are we the initiator? - jid - jid of the other entity''' + """ + con -- connection object, + weinitiate -- boolean, are we the initiator? + jid - jid of the other entity + """ self.contents = {} # negotiated contents self.connection = con # connection to use # our full jid @@ -97,15 +113,16 @@ class JingleSession(object): 'iq-error': [self.__errorCB], } - ''' Interaction with user ''' def approve_session(self): - ''' Called when user accepts session in UI (when we aren't the initiator). - ''' + """ + Called when user accepts session in UI (when we aren't the initiator) + """ self.accept_session() def decline_session(self): - ''' Called when user declines session in UI (when we aren't the initiator) - ''' + """ + Called when user declines session in UI (when we aren't the initiator) + """ reason = xmpp.Node('reason') reason.addChild('decline') self._session_terminate(reason) @@ -125,7 +142,9 @@ class JingleSession(object): self.on_session_state_changed() def end_session(self): - ''' Called when user stops or cancel session in UI. ''' + """ + Called when user stops or cancel session in UI + """ reason = xmpp.Node('reason') if self.state == JingleStates.active: reason.addChild('success') @@ -133,8 +152,6 @@ class JingleSession(object): reason.addChild('cancel') self._session_terminate(reason) - ''' Middle-level functions to manage contents. Handle local content - cache and send change notifications. ''' def get_content(self, media=None): if media is None: return None @@ -144,9 +161,12 @@ class JingleSession(object): return content def add_content(self, name, content, creator='we'): - ''' Add new content to session. If the session is active, - this will send proper stanza to update session. - Creator must be one of ('we', 'peer', 'initiator', 'responder')''' + """ + Add new content to session. If the session is active, this will send + proper stanza to update session + + Creator must be one of ('we', 'peer', 'initiator', 'responder') + """ assert creator in ('we', 'peer', 'initiator', 'responder') if (creator == 'we' and self.weinitiate) or (creator == 'peer' and \ @@ -164,7 +184,9 @@ class JingleSession(object): content.accepted = True def remove_content(self, creator, name): - ''' We do not need this now ''' + """ + We do not need this now + """ #TODO: if (creator, name) in self.contents: content = self.contents[(creator, name)] @@ -175,7 +197,9 @@ class JingleSession(object): self.end_session() def modify_content(self, creator, name, *someother): - ''' We do not need this now ''' + """ + We do not need this now + """ pass def on_session_state_changed(self, content=None): @@ -203,19 +227,23 @@ class JingleSession(object): self.__content_accept(content) def is_ready(self): - ''' Returns True when all codecs and candidates are ready - (for all contents). ''' + """ + Return True when all codecs and candidates are ready (for all contents) + """ return (all((content.is_ready() for content in self.contents.itervalues())) and self.accepted) - ''' Middle-level function to do stanza exchange. ''' def accept_session(self): - ''' Mark the session as accepted. ''' + """ + Mark the session as accepted + """ self.accepted = True self.on_session_state_changed() def start_session(self): - ''' Mark the session as ready to be started. ''' + """ + Mark the session as ready to be started + """ self.accepted = True self.on_session_state_changed() @@ -234,11 +262,12 @@ class JingleSession(object): jingle.addChild(node=content) self.connection.connection.send(stanza) - ''' Session callbacks. ''' def stanzaCB(self, stanza): - ''' A callback for ConnectionJingle. It gets stanza, then - tries to send it to all internally registered callbacks. - First one to raise xmpp.NodeProcessed breaks function.''' + """ + A callback for ConnectionJingle. It gets stanza, then tries to send it to + all internally registered callbacks. First one to raise + xmpp.NodeProcessed breaks function + """ jingle = stanza.getTag('jingle') error = stanza.getTag('error') if error: @@ -250,7 +279,7 @@ class JingleSession(object): if action not in self.callbacks: self.__send_error(stanza, 'bad_request') return - #FIXME: If we aren't initiated and it's not a session-initiate... + # FIXME: If we aren't initiated and it's not a session-initiate... if action != 'session-initiate' and self.state == JingleStates.ended: self.__send_error(stanza, 'item-not-found', 'unknown-session') return @@ -268,16 +297,18 @@ class JingleSession(object): except TieBreak: self.__send_error(stanza, 'conflict', 'tiebreak') except OutOfOrder: - self.__send_error(stanza, 'unexpected-request', 'out-of-order')#FIXME + # FIXME + self.__send_error(stanza, 'unexpected-request', 'out-of-order') def __defaultCB(self, stanza, jingle, error, action): - ''' Default callback for action stanzas -- simple ack - and stop processing. ''' + """ + Default callback for action stanzas -- simple ack and stop processing + """ response = stanza.buildReply('result') self.connection.connection.send(response) def __errorCB(self, stanza, jingle, error, action): - #FIXME + # FIXME text = error.getTagData('text') jingle_error = None xmpp_error = None @@ -287,7 +318,7 @@ class JingleSession(object): elif child.getNamespace() == xmpp.NS_STANZAS: xmpp_error = child.getName() self.__dispatch_error(xmpp_error, jingle_error, text) - #FIXME: Not sure when we would want to do that... + # FIXME: Not sure when we would want to do that... if xmpp_error == 'item-not-found': self.connection.delete_jingle_session(self.peerjid, self.sid) @@ -298,9 +329,9 @@ class JingleSession(object): if (creator, name) in self.contents: transport_ns = content.getTag('transport').getNamespace() if transport_ns == xmpp.JINGLE_ICE_UDP: - #FIXME: We don't manage anything else than ICE-UDP now... - #What was the previous transport?!? - #Anyway, content's transport is not modifiable yet + # FIXME: We don't manage anything else than ICE-UDP now... + # What was the previous transport?!? + # Anyway, content's transport is not modifiable yet pass else: stanza, jingle = self.__make_jingle('transport-reject') @@ -310,8 +341,8 @@ class JingleSession(object): self.connection.connection.send(stanza) raise xmpp.NodeProcessed else: - #FIXME: This ressource is unknown to us, what should we do? - #For now, reject the transport + # FIXME: This ressource is unknown to us, what should we do? + # For now, reject the transport stanza, jingle = self.__make_jingle('transport-reject') c = jingle.setTag('content', attrs={'creator': creator, 'name': name}) @@ -320,7 +351,7 @@ class JingleSession(object): raise xmpp.NodeProcessed def __sessionInfoCB(self, stanza, jingle, error, action): - #TODO: ringing, active, (un)hold, (un)mute + # TODO: ringing, active, (un)hold, (un)mute payload = jingle.getPayload() if len(payload) > 0: self.__send_error(stanza, 'feature-not-implemented', 'unsupported-info') @@ -332,7 +363,7 @@ class JingleSession(object): name = content['name'] if (creator, name) in self.contents: content = self.contents[(creator, name)] - #TODO: this will fail if content is not an RTP content + # TODO: this will fail if content is not an RTP content self.connection.dispatch('JINGLE_DISCONNECTED', (self.peerjid, self.sid, content.media, 'removed')) content.destroy() @@ -342,17 +373,21 @@ class JingleSession(object): self._session_terminate(reason) def __sessionAcceptCB(self, stanza, jingle, error, action): - if self.state != JingleStates.pending: #FIXME + # FIXME + if self.state != JingleStates.pending: raise OutOfOrder self.state = JingleStates.active def __contentAcceptCB(self, stanza, jingle, error, action): - ''' Called when we get content-accept stanza or equivalent one - (like session-accept).''' + """ + Called when we get content-accept stanza or equivalent one (like + session-accept) + """ # check which contents are accepted for content in jingle.iterTags('content'): creator = content['creator'] - name = content['name']#TODO... + # TODO + name = content['name'] def __contentAddCB(self, stanza, jingle, error, action): if self.state == JingleStates.ended: @@ -363,7 +398,7 @@ class JingleSession(object): rejected_contents = parse_result[3] for name, creator in rejected_contents: - #TODO: + # TODO content = JingleContent() self.add_content(name, content, creator) self.__content_reject(content) @@ -373,10 +408,10 @@ class JingleSession(object): contents)) def __sessionInitiateCB(self, stanza, jingle, error, action): - ''' We got a jingle session request from other entity, - therefore we are the receiver... Unpack the data, - inform the user. ''' - + """ + We got a jingle session request from other entity, therefore we are the + receiver... Unpack the data, inform the user + """ if self.state != JingleStates.ended: raise OutOfOrder @@ -417,7 +452,9 @@ class JingleSession(object): contents)) def __broadcastCB(self, stanza, jingle, error, action): - ''' Broadcast the stanza contents to proper content handlers. ''' + """ + Broadcast the stanza contents to proper content handlers + """ for content in jingle.iterTags('content'): name = content['name'] creator = content['creator'] @@ -437,11 +474,12 @@ class JingleSession(object): (self.peerjid, self.sid, None, text)) def __broadcastAllCB(self, stanza, jingle, error, action): - ''' Broadcast the stanza to all content handlers. ''' + """ + Broadcast the stanza to all content handlers + """ for content in self.contents.itervalues(): content.stanzaCB(stanza, None, error, action) - ''' Internal methods. ''' def __parse_contents(self, jingle): #TODO: Needs some reworking contents = [] @@ -492,8 +530,6 @@ class JingleSession(object): break return (reason, text) - ''' Methods that make/send proper pieces of XML. They check if the session - is in appropriate state. ''' def __make_jingle(self, action): stanza = xmpp.Iq(typ='set', to=xmpp.JID(self.peerjid)) attrs = {'action': action, @@ -516,14 +552,17 @@ class JingleSession(object): self.__dispatch_error(error, jingle_error, text) def __append_content(self, jingle, content): - ''' Append element to element, - with (full=True) or without (full=False) - children. ''' + """ + Append element to element, with (full=True) or + without (full=False) children + """ jingle.addChild('content', attrs={'name': content.name, 'creator': content.creator}) def __append_contents(self, jingle): - ''' Append all elements to .''' + """ + Append all elements to + """ # TODO: integrate with __appendContent? # TODO: parameters 'name', 'content'? for content in self.contents.values(): @@ -571,7 +610,7 @@ class JingleSession(object): (self.peerjid, self.sid, None, text)) def __content_add(self, content): - #TODO: test + # TODO: test assert self.state != JingleStates.ended stanza, jingle = self.__make_jingle('content-add') self.__append_content(jingle, content) @@ -579,7 +618,7 @@ class JingleSession(object): self.connection.connection.send(stanza) def __content_accept(self, content): - #TODO: test + # TODO: test assert self.state != JingleStates.ended stanza, jingle = self.__make_jingle('content-accept') self.__append_content(jingle, content) @@ -591,7 +630,7 @@ class JingleSession(object): stanza, jingle = self.__make_jingle('content-reject') self.__append_content(jingle, content) self.connection.connection.send(stanza) - #TODO: this will fail if content is not an RTP content + # TODO: this will fail if content is not an RTP content self.connection.dispatch('JINGLE_DISCONNECTED', (self.peerjid, self.sid, content.media, 'rejected')) @@ -603,7 +642,7 @@ class JingleSession(object): stanza, jingle = self.__make_jingle('content-remove') self.__append_content(jingle, content) self.connection.connection.send(stanza) - #TODO: this will fail if content is not an RTP content + # TODO: this will fail if content is not an RTP content self.connection.dispatch('JINGLE_DISCONNECTED', (self.peerjid, self.sid, content.media, 'removed')) diff --git a/src/common/jingle_transport.py b/src/common/jingle_transport.py index 487c66d70..888f6e473 100644 --- a/src/common/jingle_transport.py +++ b/src/common/jingle_transport.py @@ -10,7 +10,10 @@ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## -''' Handles Jingle Transports (currently only ICE-UDP). ''' + +""" +Handles Jingle Transports (currently only ICE-UDP) +""" import xmpp @@ -25,13 +28,18 @@ def get_jingle_transport(node): class TransportType(object): - ''' Possible types of a JingleTransport ''' + """ + Possible types of a JingleTransport + """ datagram = 1 streaming = 2 class JingleTransport(object): - ''' An abstraction of a transport in Jingle sessions. ''' + """ + An abstraction of a transport in Jingle sessions + """ + def __init__(self, type_): self.type = type_ self.candidates = [] @@ -42,19 +50,25 @@ class JingleTransport(object): yield self.make_candidate(candidate) def make_candidate(self, candidate): - ''' Build a candidate stanza for the given candidate. ''' + """ + Build a candidate stanza for the given candidate + """ pass def make_transport(self, candidates=None): - ''' Build a transport stanza with the given candidates (or - self.candidates if candidates is None). ''' + """ + Build a transport stanza with the given candidates (or self.candidates if + candidates is None) + """ if not candidates: candidates = self._iter_candidates() transport = xmpp.Node('transport', payload=candidates) return transport def parse_transport_stanza(self, transport): - ''' Returns the list of transport candidates from a transport stanza. ''' + """ + Return the list of transport candidates from a transport stanza + """ return [] @@ -132,4 +146,3 @@ class JingleTransportICEUDP(JingleTransport): return candidates transports[xmpp.NS_JINGLE_ICE_UDP] = JingleTransportICEUDP - diff --git a/src/common/kwalletbinding.py b/src/common/kwalletbinding.py index 0de030bd8..842aff8b9 100644 --- a/src/common/kwalletbinding.py +++ b/src/common/kwalletbinding.py @@ -25,7 +25,9 @@ import subprocess def kwallet_available(): - """Return True if kwalletcli can be run, False otherwise.""" + """ + Return True if kwalletcli can be run, False otherwise + """ try: p = subprocess.Popen(["kwalletcli", "-qV"]) except Exception: @@ -37,7 +39,8 @@ def kwallet_available(): def kwallet_get(folder, entry): - """Retrieve a passphrase from the KDE Wallet via kwalletcli. + """ + Retrieve a passphrase from the KDE Wallet via kwalletcli Arguments: • folder: The top-level category to use (normally the programme name) @@ -45,7 +48,6 @@ def kwallet_get(folder, entry): Returns the passphrase as unicode, False if it cannot be found, or None if an error occured. - """ p = subprocess.Popen(["kwalletcli", "-q", "-f", folder.encode('utf-8'), "-e", entry.encode('utf-8')], stdout=subprocess.PIPE) @@ -60,7 +62,8 @@ def kwallet_get(folder, entry): def kwallet_put(folder, entry, passphrase): - """Store a passphrase into the KDE Wallet via kwalletcli. + """ + Store a passphrase into the KDE Wallet via kwalletcli Arguments: • folder: The top-level category to use (normally the programme name) @@ -68,7 +71,6 @@ def kwallet_put(folder, entry, passphrase): • passphrase: The value to store Returns True on success, False otherwise. - """ p = subprocess.Popen(["kwalletcli", "-q", "-f", folder.encode('utf-8'), "-e", entry.encode('utf-8'), "-P"], stdin=subprocess.PIPE) diff --git a/src/common/latex.py b/src/common/latex.py index 777577d1c..492f04c39 100644 --- a/src/common/latex.py +++ b/src/common/latex.py @@ -86,8 +86,9 @@ def popen_nt_friendly(command): return Popen(command, cwd=gettempdir(), stdout=PIPE) def check_for_latex_support(): - '''check is latex is available and if it can create a picture.''' - + """ + Check if latex is available and if it can create a picture + """ try: filename = latex_to_image("test") if filename: diff --git a/src/common/logger.py b/src/common/logger.py index c96282743..c484246db 100644 --- a/src/common/logger.py +++ b/src/common/logger.py @@ -24,7 +24,9 @@ ## along with Gajim. If not, see . ## -''' This module allows to access the on-disk database of logs. ''' +""" +This module allows to access the on-disk database of logs +""" import os import sys @@ -150,7 +152,9 @@ class Logger: self.get_jids_already_in_db() def simple_commit(self, sql_to_commit): - '''helper to commit''' + """ + Helper to commit + """ self.cur.execute(sql_to_commit) try: self.con.commit() @@ -177,14 +181,14 @@ class Logger: return self.jids_already_in def jid_is_from_pm(self, jid): - '''if jid is gajim@conf/nkour it's likely a pm one, how we know - gajim@conf is not a normal guy and nkour is not his resource? - we ask if gajim@conf is already in jids (with type room jid) - this fails if user disables logging for room and only enables for - pm (so higly unlikely) and if we fail we do not go chaos - (user will see the first pm as if it was message in room's public chat) - and after that all okay''' - + """ + If jid is gajim@conf/nkour it's likely a pm one, how we know gajim@conf + is not a normal guy and nkour is not his resource? we ask if gajim@conf + is already in jids (with type room jid) this fails if user disables + logging for room and only enables for pm (so higly unlikely) and if we + fail we do not go chaos (user will see the first pm as if it was message + in room's public chat) and after that all okay + """ if jid.find('/') > -1: possible_room_jid = jid.split('/', 1)[0] return self.jid_is_room_jid(possible_room_jid) @@ -202,13 +206,14 @@ class Logger: return True def get_jid_id(self, jid, typestr=None): - '''jids table has jid and jid_id - logs table has log_id, jid_id, contact_name, time, kind, show, message - so to ask logs we need jid_id that matches our jid in jids table - this method wants jid and returns the jid_id for later sql-ing on logs - typestr can be 'ROOM' or anything else depending on the type of JID - and is only needed to be specified when the JID is new in DB - ''' + """ + jids table has jid and jid_id logs table has log_id, jid_id, + contact_name, time, kind, show, message so to ask logs we need jid_id + that matches our jid in jids table this method wants jid and returns the + jid_id for later sql-ing on logs typestr can be 'ROOM' or anything else + depending on the type of JID and is only needed to be specified when the + JID is new in DB + """ if jid.find('/') != -1: # if it has a / jid_is_from_pm = self.jid_is_from_pm(jid) if not jid_is_from_pm: # it's normal jid with resource @@ -238,7 +243,9 @@ class Logger: return jid_id def convert_human_values_to_db_api_values(self, kind, show): - '''coverts from string style to constant ints for db''' + """ + Convert from string style to constant ints for db + """ if kind == 'status': kind_col = constants.KIND_STATUS elif kind == 'gcstatus': @@ -277,7 +284,9 @@ class Logger: return kind_col, show_col def convert_human_transport_type_to_db_api_values(self, type_): - '''converts from string style to constant ints for db''' + """ + Convert from string style to constant ints for db + """ if type_ == 'aim': return constants.TYPE_AIM if type_ == 'gadu-gadu': @@ -309,7 +318,9 @@ class Logger: return None def convert_api_values_to_human_transport_type(self, type_id): - '''converts from constant ints for db to string style''' + """ + Convert from constant ints for db to string style + """ if type_id == constants.TYPE_AIM: return 'aim' if type_id == constants.TYPE_GG: @@ -340,7 +351,9 @@ class Logger: return 'mrim' def convert_human_subscription_values_to_db_api_values(self, sub): - '''converts from string style to constant ints for db''' + """ + Convert from string style to constant ints for db + """ if sub == 'none': return constants.SUBSCRIPTION_NONE if sub == 'to': @@ -351,7 +364,9 @@ class Logger: return constants.SUBSCRIPTION_BOTH def convert_db_api_values_to_human_subscription_values(self, sub): - '''converts from constant ints for db to string style''' + """ + Convert from constant ints for db to string style + """ if sub == constants.SUBSCRIPTION_NONE: return 'none' if sub == constants.SUBSCRIPTION_TO: @@ -382,30 +397,40 @@ class Logger: return message_id def insert_unread_events(self, message_id, jid_id): - ''' add unread message with id: message_id''' + """ + Add unread message with id: message_id + """ sql = 'INSERT INTO unread_messages VALUES (%d, %d, 0)' % (message_id, jid_id) self.simple_commit(sql) def set_read_messages(self, message_ids): - ''' mark all messages with ids in message_ids as read''' + """ + Mark all messages with ids in message_ids as read + """ ids = ','.join([str(i) for i in message_ids]) sql = 'DELETE FROM unread_messages WHERE message_id IN (%s)' % ids self.simple_commit(sql) def set_shown_unread_msgs(self, msg_id): - ''' mark unread message as shown un GUI ''' + """ + Mark unread message as shown un GUI + """ sql = 'UPDATE unread_messages SET shown = 1 where message_id = %s' % \ msg_id self.simple_commit(sql) def reset_shown_unread_messages(self): - ''' Set shown field to False in unread_messages table ''' + """ + Set shown field to False in unread_messages table + """ sql = 'UPDATE unread_messages SET shown = 0' self.simple_commit(sql) def get_unread_msgs(self): - ''' get all unread messages ''' + """ + Get all unread messages + """ all_messages = [] try: self.cur.execute( @@ -435,15 +460,18 @@ class Logger: return all_messages def write(self, kind, jid, message=None, show=None, tim=None, subject=None): - '''write a row (status, gcstatus, message etc) to logs database - kind can be status, gcstatus, gc_msg, (we only recv for those 3), - single_msg_recv, chat_msg_recv, chat_msg_sent, single_msg_sent - we cannot know if it is pm or normal chat message, we try to guess - see jid_is_from_pm() + """ + Write a row (status, gcstatus, message etc) to logs database - we analyze jid and store it as follows: - jids.jid text column will hold JID if TC-related, room_jid if GC-related, - ROOM_JID/nick if pm-related.''' + kind can be status, gcstatus, gc_msg, (we only recv for those 3), + single_msg_recv, chat_msg_recv, chat_msg_sent, single_msg_sent we cannot + know if it is pm or normal chat message, we try to guess see + jid_is_from_pm() + + We analyze jid and store it as follows: + jids.jid text column will hold JID if TC-related, room_jid if GC-related, + ROOM_JID/nick if pm-related. + """ if self.jids_already_in == []: # only happens if we just created the db self.open_db() @@ -516,12 +544,14 @@ class Logger: return self.commit_to_db(values, write_unread) def get_last_conversation_lines(self, jid, restore_how_many_rows, - pending_how_many, timeout, account): - '''accepts how many rows to restore and when to time them out (in minutes) - (mark them as too old) and number of messages that are in queue - and are already logged but pending to be viewed, - returns a list of tupples containg time, kind, message, - list with empty tupple if nothing found to meet our demands''' + pending_how_many, timeout, account): + """ + Accept how many rows to restore and when to time them out (in minutes) + (mark them as too old) and number of messages that are in queue and are + already logged but pending to be viewed, returns a list of tupples + containg time, kind, message, list with empty tupple if nothing found to + meet our demands + """ try: self.get_jid_id(jid) except exceptions.PysqliteOperationalError, e: @@ -561,9 +591,12 @@ class Logger: return start_of_day def get_conversation_for_date(self, jid, year, month, day, account): - '''returns contact_name, time, kind, show, message, subject - for each row in a list of tupples, - returns list with empty tupple if we found nothing to meet our demands''' + """ + Return contact_name, time, kind, show, message, subject + + For each row in a list of tupples, returns list with empty tupple if we + found nothing to meet our demands + """ try: self.get_jid_id(jid) except exceptions.PysqliteOperationalError, e: @@ -586,9 +619,12 @@ class Logger: return results def get_search_results_for_query(self, jid, query, account): - '''returns contact_name, time, kind, show, message - for each row in a list of tupples, - returns list with empty tupple if we found nothing to meet our demands''' + """ + Returns contact_name, time, kind, show, message + + For each row in a list of tupples, returns list with empty tupple if we + found nothing to meet our demands + """ try: self.get_jid_id(jid) except exceptions.PysqliteOperationalError, e: @@ -615,7 +651,9 @@ class Logger: return results def get_days_with_logs(self, jid, year, month, max_day, account): - '''returns the list of days that have logs (not status messages)''' + """ + Return the list of days that have logs (not status messages) + """ try: self.get_jid_id(jid) except exceptions.PysqliteOperationalError, e: @@ -650,8 +688,10 @@ class Logger: return days_with_logs def get_last_date_that_has_logs(self, jid, account=None, is_room=False): - '''returns last time (in seconds since EPOCH) for which - we had logs (excluding statuses)''' + """ + Return last time (in seconds since EPOCH) for which we had logs + (excluding statuses) + """ where_sql = '' if not is_room: where_sql = self._build_contact_where(account, jid) @@ -676,8 +716,10 @@ class Logger: return result def get_room_last_message_time(self, jid): - '''returns FASTLY last time (in seconds since EPOCH) for which - we had logs for that room from rooms_last_message_time table''' + """ + Return FASTLY last time (in seconds since EPOCH) for which we had logs + for that room from rooms_last_message_time table + """ try: jid_id = self.get_jid_id(jid, 'ROOM') except exceptions.PysqliteOperationalError, e: @@ -697,8 +739,10 @@ class Logger: return result def set_room_last_message_time(self, jid, time): - '''set last time (in seconds since EPOCH) for which - we had logs for that room in rooms_last_message_time table''' + """ + Set last time (in seconds since EPOCH) for which we had logs for that + room in rooms_last_message_time table + """ jid_id = self.get_jid_id(jid, 'ROOM') # jid_id is unique in this table, create or update : sql = 'REPLACE INTO rooms_last_message_time VALUES (%d, %d)' % \ @@ -706,8 +750,9 @@ class Logger: self.simple_commit(sql) def _build_contact_where(self, account, jid): - '''build the where clause for a jid, including metacontacts - jid(s) if any''' + """ + Build the where clause for a jid, including metacontacts jid(s) if any + """ where_sql = '' # will return empty list if jid is not associated with # any metacontacts @@ -727,7 +772,9 @@ class Logger: return where_sql def save_transport_type(self, jid, type_): - '''save the type of the transport in DB''' + """ + Save the type of the transport in DB + """ type_id = self.convert_human_transport_type_to_db_api_values(type_) if not type_id: # unknown type @@ -747,7 +794,9 @@ class Logger: self.simple_commit(sql) def get_transports_type(self): - '''return all the type of the transports in DB''' + """ + Return all the type of the transports in DB + """ self.cur.execute( 'SELECT * from transports_cache') results = self.cur.fetchall() @@ -767,11 +816,13 @@ class Logger: # (2) # GzipFile needs a file-like object, StringIO emulates file for plain strings def iter_caps_data(self): - ''' Iterate over caps cache data stored in the database. + """ + Iterate over caps cache data stored in the database + The iterator values are pairs of (node, ver, ext, identities, features): identities == {'category':'foo', 'type':'bar', 'name':'boo'}, - features being a list of feature namespaces. ''' - + features being a list of feature namespaces. + """ # get data from table # the data field contains binary object (gzipped data), this is a hack # to get that data without trying to convert it to unicode @@ -854,16 +905,21 @@ class Logger: self.simple_commit(sql) def clean_caps_table(self): - '''Remove caps which was not seen for 3 months''' + """ + Remove caps which was not seen for 3 months + """ sql = '''DELETE FROM caps_cache WHERE last_seen < %d''' % \ int(time.time() - 3*30*24*3600) self.simple_commit(sql) def replace_roster(self, account_name, roster_version, roster): - ''' Replace current roster in DB by a new one. - accout_name is the name of the account to change - roster_version is the version of the new roster - roster is the new version ''' + """ + Replace current roster in DB by a new one + + accout_name is the name of the account to change. + roster_version is the version of the new roster. + roster is the new version. + """ # First we must reset roster_version value to ensure that the server # sends back all the roster at the next connexion if the replacement # didn't work properly. @@ -887,7 +943,9 @@ class Logger: roster_version) def del_contact(self, account_jid, jid): - ''' Remove jid from account_jid roster. ''' + """ + Remove jid from account_jid roster + """ try: account_jid_id = self.get_jid_id(account_jid) jid_id = self.get_jid_id(jid) @@ -902,7 +960,9 @@ class Logger: self.con.commit() def add_or_update_contact(self, account_jid, jid, name, sub, ask, groups): - ''' Add or update a contact from account_jid roster. ''' + """ + Add or update a contact from account_jid roster + """ if sub == 'remove': self.del_contact(account_jid, jid) return @@ -933,7 +993,9 @@ class Logger: self.con.commit() def get_roster(self, account_jid): - ''' Return the accound_jid roster in NonBlockingRoster format. ''' + """ + Return the accound_jid roster in NonBlockingRoster format + """ data = {} account_jid_id = self.get_jid_id(account_jid) @@ -972,7 +1034,9 @@ class Logger: return data def remove_roster(self, account_jid): - ''' Remove all entry from account_jid roster. ''' + """ + Remove all entry from account_jid roster + """ account_jid_id = self.get_jid_id(account_jid) self.cur.execute('DELETE FROM roster_entry WHERE account_jid_id=?', diff --git a/src/common/logging_helpers.py b/src/common/logging_helpers.py index ae5d1da3e..733958b2e 100644 --- a/src/common/logging_helpers.py +++ b/src/common/logging_helpers.py @@ -23,7 +23,7 @@ import i18n def parseLogLevel(arg): """ - eiter numeric value or level name from logging module + Eiter numeric value or level name from logging module """ if arg.isdigit(): return int(arg) @@ -98,7 +98,7 @@ def colorize(text, color): class FancyFormatter(logging.Formatter): """ - A Eye-candy formatter with colors + An eye-candy formatter with colors """ colors_mapping = { 'DEBUG': colors.BLUE, @@ -134,7 +134,7 @@ class FancyFormatter(logging.Formatter): def init(use_color=False): """ - initialize the logging system + Iinitialize the logging system """ consoleloghandler = logging.StreamHandler() consoleloghandler.setFormatter( diff --git a/src/common/optparser.py b/src/common/optparser.py index f9f738d5e..33aaa8c9d 100644 --- a/src/common/optparser.py +++ b/src/common/optparser.py @@ -228,7 +228,9 @@ class OptionsParser: caps.capscache.initialize_from_db() def assert_unread_msgs_table_exists(self): - '''create table unread_messages if there is no such table''' + """ + Create table unread_messages if there is no such table + """ back = os.getcwd() os.chdir(logger.LOG_DB_FOLDER) con = sqlite.connect(logger.LOG_DB_FILE) @@ -346,8 +348,10 @@ class OptionsParser: gajim.config.set('version', '0.10.1.2') def update_config_to_01013(self): - '''create table transports_cache if there is no such table''' - #FIXME see #2812 + """ + Create table transports_cache if there is no such table + """ + # FIXME see #2812 back = os.getcwd() os.chdir(logger.LOG_DB_FOLDER) con = sqlite.connect(logger.LOG_DB_FILE) @@ -369,9 +373,11 @@ class OptionsParser: gajim.config.set('version', '0.10.1.3') def update_config_to_01014(self): - '''apply indeces to the logs database''' + """ + Apply indeces to the logs database + """ print _('migrating logs database to indices') - #FIXME see #2812 + # FIXME see #2812 back = os.getcwd() os.chdir(logger.LOG_DB_FOLDER) con = sqlite.connect(logger.LOG_DB_FILE) @@ -393,7 +399,9 @@ class OptionsParser: gajim.config.set('version', '0.10.1.4') def update_config_to_01015(self): - '''clean show values in logs database''' + """ + Clean show values in logs database + """ #FIXME see #2812 back = os.getcwd() os.chdir(logger.LOG_DB_FOLDER) @@ -412,8 +420,10 @@ class OptionsParser: gajim.config.set('version', '0.10.1.5') def update_config_to_01016(self): - '''#2494 : Now we play gc_received_message sound even if - notify_on_all_muc_messages is false. Keep precedent behaviour.''' + """ + #2494 : Now we play gc_received_message sound even if + notify_on_all_muc_messages is false. Keep precedent behaviour + """ if 'notify_on_all_muc_messages' in self.old_values and \ self.old_values['notify_on_all_muc_messages'] == 'False' and \ gajim.config.get_per('soundevents', 'muc_message_received', 'enabled'): @@ -422,36 +432,45 @@ class OptionsParser: gajim.config.set('version', '0.10.1.6') def update_config_to_01017(self): - '''trayicon_notification_on_new_messages -> - trayicon_notification_on_events ''' + """ + trayicon_notification_on_new_messages -> trayicon_notification_on_events + """ if 'trayicon_notification_on_new_messages' in self.old_values: gajim.config.set('trayicon_notification_on_events', self.old_values['trayicon_notification_on_new_messages']) gajim.config.set('version', '0.10.1.7') def update_config_to_01018(self): - '''chat_state_notifications -> outgoing_chat_state_notifications''' + """ + chat_state_notifications -> outgoing_chat_state_notifications + """ if 'chat_state_notifications' in self.old_values: gajim.config.set('outgoing_chat_state_notifications', self.old_values['chat_state_notifications']) gajim.config.set('version', '0.10.1.8') def update_config_to_01101(self): - '''fill time_stamp from before_time and after_time''' + """ + Fill time_stamp from before_time and after_time + """ if 'before_time' in self.old_values: gajim.config.set('time_stamp', '%s%%X%s ' % ( self.old_values['before_time'], self.old_values['after_time'])) gajim.config.set('version', '0.11.0.1') def update_config_to_01102(self): - '''fill time_stamp from before_time and after_time''' + """ + Fill time_stamp from before_time and after_time + """ if 'ft_override_host_to_send' in self.old_values: gajim.config.set('ft_add_hosts_to_send', self.old_values['ft_override_host_to_send']) gajim.config.set('version', '0.11.0.2') def update_config_to_01111(self): - '''always_hide_chatbuttons -> compact_view''' + """ + Always_hide_chatbuttons -> compact_view + """ if 'always_hide_groupchat_buttons' in self.old_values and \ 'always_hide_chat_buttons' in self.old_values: gajim.config.set('compact_view', self.old_values['always_hide_groupchat_buttons'] and \ @@ -459,7 +478,9 @@ class OptionsParser: gajim.config.set('version', '0.11.1.1') def update_config_to_01112(self): - '''gtk+ theme is renamed to default''' + """ + GTK+ theme is renamed to default + """ if 'roster_theme' in self.old_values and \ self.old_values['roster_theme'] == 'gtk+': gajim.config.set('roster_theme', _('default')) @@ -568,7 +589,9 @@ class OptionsParser: gajim.config.set('version', '0.11.4.1') def update_config_to_01142(self): - '''next_message_received sound event is splittedin 2 events''' + """ + next_message_received sound event is splittedin 2 events + """ gajim.config.add_per('soundevents', 'next_message_received_focused') gajim.config.add_per('soundevents', 'next_message_received_unfocused') if gajim.config.get_per('soundevents', 'next_message_received'): @@ -681,7 +704,9 @@ class OptionsParser: gajim.config.set('version', '0.12.1.4') def update_config_to_01215(self): - '''Remove hardcoded ../data/sounds from config''' + """ + Remove hardcoded ../data/sounds from config + """ dirs = ('../data', gajim.gajimpaths.root, gajim.DATA_DIR) for evt in gajim.config.get_per('soundevents'): path = gajim.config.get_per('soundevents', evt ,'path') diff --git a/src/common/pep.py b/src/common/pep.py index 5ba476c0c..8e994b82a 100644 --- a/src/common/pep.py +++ b/src/common/pep.py @@ -206,64 +206,64 @@ import gtkgui_helpers class AbstractPEP(object): - + type = '' namespace = '' - + @classmethod def get_tag_as_PEP(cls, jid, account, event_tag): items = event_tag.getTag('items', {'node': cls.namespace}) if items: - log.debug("Received PEP 'user %s' from %s" % (cls.type, jid)) + log.debug("Received PEP 'user %s' from %s" % (cls.type, jid)) return cls(jid, account, items) else: - return None - + return None + def __init__(self, jid, account, items): self._pep_specific_data, self._retracted = self._extract_info(items) - + self._update_contacts(jid, account) if jid == gajim.get_jid_from_account(account): self._update_account(account) - + def _extract_info(self, items): '''To be implemented by subclasses''' raise NotImplementedError - - def _update_contacts(self, jid, account): - for contact in gajim.contacts.get_contacts(account, jid): + + def _update_contacts(self, jid, account): + for contact in gajim.contacts.get_contacts(account, jid): if self._retracted: if self.type in contact.pep: del contact.pep[self.type] else: contact.pep[self.type] = self - - def _update_account(self, account): - acc = gajim.connections[account] + + def _update_account(self, account): + acc = gajim.connections[account] if self._retracted: if self.type in acc.pep: del acc.pep[self.type] else: acc.pep[self.type] = self - + def asPixbufIcon(self): '''SHOULD be implemented by subclasses''' return None - + def asMarkupText(self): '''SHOULD be implemented by subclasses''' return '' - - + + class UserMoodPEP(AbstractPEP): '''XEP-0107: User Mood''' - + type = 'mood' namespace = xmpp.NS_MOOD - + def _extract_info(self, items): mood_dict = {} - + for item in items.getTags('item'): mood_tag = item.getTag('mood') if mood_tag: @@ -273,22 +273,22 @@ class UserMoodPEP(AbstractPEP): mood_dict['text'] = child.getData() else: mood_dict['mood'] = name - - retracted = items.getTag('retract') or not 'mood' in mood_dict + + retracted = items.getTag('retract') or not 'mood' in mood_dict return (mood_dict, retracted) - + def asPixbufIcon(self): assert not self._retracted received_mood = self._pep_specific_data['mood'] mood = received_mood if received_mood in MOODS else 'unknown' pixbuf = gtkgui_helpers.load_mood_icon(mood).get_pixbuf() return pixbuf - + def asMarkupText(self): assert not self._retracted untranslated_mood = self._pep_specific_data['mood'] mood = self._translate_mood(untranslated_mood) - markuptext = '%s' % gobject.markup_escape_text(mood) + markuptext = '%s' % gobject.markup_escape_text(mood) if 'text' in self._pep_specific_data: text = self._pep_specific_data['text'] markuptext += ' (%s)' % gobject.markup_escape_text(text) @@ -303,13 +303,13 @@ class UserMoodPEP(AbstractPEP): class UserTunePEP(AbstractPEP): '''XEP-0118: User Tune''' - + type = 'tune' namespace = xmpp.NS_TUNE - - def _extract_info(self, items): + + def _extract_info(self, items): tune_dict = {} - + for item in items.getTags('item'): tune_tag = item.getTag('tune') if tune_tag: @@ -318,23 +318,23 @@ class UserTunePEP(AbstractPEP): data = child.getData().strip() if child.getName() in TUNE_DATA: tune_dict[name] = data - - retracted = items.getTag('retract') or not ('artist' in tune_dict or + + retracted = items.getTag('retract') or not ('artist' in tune_dict or 'title' in tune_dict) return (tune_dict, retracted) - + def asPixbufIcon(self): import os path = os.path.join(gajim.DATA_DIR, 'emoticons', 'static', 'music.png') return gtk.gdk.pixbuf_new_from_file(path) - + def asMarkupText(self): assert not self._retracted tune = self._pep_specific_data artist = tune.get('artist', _('Unknown Artist')) artist = gobject.markup_escape_text(artist) - + title = tune.get('title', _('Unknown Title')) title = gobject.markup_escape_text(title) @@ -345,17 +345,17 @@ class UserTunePEP(AbstractPEP): 'from %(source)s') % {'title': title, 'artist': artist, 'source': source} return tune_string - + class UserActivityPEP(AbstractPEP): '''XEP-0108: User Activity''' - + type = 'activity' namespace = xmpp.NS_ACTIVITY - + def _extract_info(self, items): activity_dict = {} - + for item in items.getTags('item'): activity_tag = item.getTag('activity') if activity_tag: @@ -369,28 +369,28 @@ class UserActivityPEP(AbstractPEP): for subactivity in child.getChildren(): subactivity_name = subactivity.getName().strip() activity_dict['subactivity'] = subactivity_name - + retracted = items.getTag('retract') or not 'activity' in activity_dict return (activity_dict, retracted) - + def asPixbufIcon(self): assert not self._retracted pep = self._pep_specific_data activity = pep['activity'] - + has_known_activity = activity in ACTIVITIES has_known_subactivity = (has_known_activity and ('subactivity' in pep) and (pep['subactivity'] in ACTIVITIES[activity])) - + if has_known_activity: if has_known_subactivity: subactivity = pep['subactivity'] return gtkgui_helpers.load_activity_icon(activity, subactivity).get_pixbuf() else: return gtkgui_helpers.load_activity_icon(activity).get_pixbuf() - else: + else: return gtkgui_helpers.load_activity_icon('unknown').get_pixbuf() - + def asMarkupText(self): assert not self._retracted pep = self._pep_specific_data @@ -403,45 +403,45 @@ class UserActivityPEP(AbstractPEP): if subactivity in ACTIVITIES[activity]: subactivity = ACTIVITIES[activity][subactivity] activity = ACTIVITIES[activity]['category'] - + markuptext = '' + gobject.markup_escape_text(activity) if subactivity: markuptext += ': ' + gobject.markup_escape_text(subactivity) markuptext += '' if text: markuptext += ' (%s)' % gobject.markup_escape_text(text) - return markuptext - - + return markuptext + + class UserNicknamePEP(AbstractPEP): '''XEP-0172: User Nickname''' - + type = 'nickname' namespace = xmpp.NS_NICK - - def _extract_info(self, items): + + def _extract_info(self, items): nick = '' for item in items.getTags('item'): child = item.getTag('nick') if child: nick = child.getData() break - + retracted = items.getTag('retract') or not nick - return (nick, retracted) - + return (nick, retracted) + def _update_contacts(self, jid, account): nick = '' if self._retracted else self._pep_specific_data for contact in gajim.contacts.get_contacts(account, jid): contact.contact_name = nick - + def _update_account(self, account): if self._retracted: gajim.nicks[account] = gajim.config.get_per('accounts', account, 'name') else: gajim.nicks[account] = self._pep_specific_data - + SUPPORTED_PERSONAL_USER_EVENTS = [UserMoodPEP, UserTunePEP, UserActivityPEP, UserNicknamePEP] @@ -451,7 +451,7 @@ class ConnectionPEP(object): self._account = account self._dispatcher = dispatcher self._pubsub_connection = pubsub_connection - + def _pubsubEventCB(self, xmpp_dispatcher, msg): ''' Called when we receive with pubsub event. ''' if not msg.getTag('event'): @@ -459,7 +459,7 @@ class ConnectionPEP(object): if msg.getTag('error'): log.debug('PubsubEventCB received error stanza. Ignoring') raise xmpp.NodeProcessed - + jid = helpers.get_full_jid_from_iq(msg) event_tag = msg.getTag('event') @@ -467,7 +467,7 @@ class ConnectionPEP(object): pep = pep_class.get_tag_as_PEP(jid, self._account, event_tag) if pep: self._dispatcher.dispatch('PEP_RECEIVED', (jid, pep.type)) - + items = event_tag.getTag('items') if items: for item in items.getTags('item'): @@ -477,9 +477,9 @@ class ConnectionPEP(object): # but to be sure... self._dispatcher.dispatch('ATOM_ENTRY', (atom.OldEntry(node=entry),)) - + raise xmpp.NodeProcessed - + def send_activity(self, activity, subactivity=None, message=None): if not self.pep_supported: return @@ -492,7 +492,7 @@ class ConnectionPEP(object): i = item.addChild('text') i.addData(message) self._pubsub_connection.send_pb_publish('', xmpp.NS_ACTIVITY, item, '0') - + def retract_activity(self): if not self.pep_supported: return @@ -510,13 +510,13 @@ class ConnectionPEP(object): i = item.addChild('text') i.addData(message) self._pubsub_connection.send_pb_publish('', xmpp.NS_MOOD, item, '0') - + def retract_mood(self): if not self.pep_supported: return self.send_mood(None) self._pubsub_connection.send_pb_retract('', xmpp.NS_MOOD, '0') - + def send_tune(self, artist='', title='', source='', track=0, length=0, items=None): if not self.pep_supported: diff --git a/src/common/proxy65_manager.py b/src/common/proxy65_manager.py index b1bbea79d..5c4420839 100644 --- a/src/common/proxy65_manager.py +++ b/src/common/proxy65_manager.py @@ -41,10 +41,13 @@ S_FINISHED = 4 CONNECT_TIMEOUT = 20 class Proxy65Manager: - ''' keep records for file transfer proxies. Each time account - establishes a connection to its server call proxy65manger.resolve(proxy) - for every proxy that is convigured within the account. The class takes - care to resolve and test each proxy only once.''' + """ + Keep records for file transfer proxies. Each time account establishes a + connection to its server call proxy65manger.resolve(proxy) for every proxy + that is convigured within the account. The class takes care to resolve and + test each proxy only once + """ + def __init__(self, idlequeue): # dict {proxy: proxy properties} self.idlequeue = idlequeue @@ -53,7 +56,9 @@ class Proxy65Manager: self.default_proxies = {} def resolve(self, proxy, connection, sender_jid, default=None): - ''' start ''' + """ + Start + """ if proxy in self.proxies: resolver = self.proxies[proxy] else: @@ -102,7 +107,9 @@ class Proxy65Manager: class ProxyResolver: def resolve_result(self, host, port, jid): - ''' test if host has a real proxy65 listening on port ''' + """ + Test if host has a real proxy65 listening on port + """ self.host = str(host) self.port = int(port) self.jid = unicode(jid) @@ -175,19 +182,25 @@ class ProxyResolver: self.try_next_connection() def try_next_connection(self): - ''' try to resolve proxy with the next possible connection ''' + """ + Try to resolve proxy with the next possible connection + """ if self.connections: connection = self.connections.pop(0) self.start_resolve(connection) def add_connection(self, connection): - ''' add a new connection in case the first fails ''' + """ + Add a new connection in case the first fails + """ self.connections.append(connection) if self.state == S_INITIAL: self.start_resolve(connection) def start_resolve(self, connection): - ''' request network address from proxy ''' + """ + Request network address from proxy + """ self.state = S_STARTED self.active_connection = connection iq = common.xmpp.Protocol(name='iq', to=self.proxy, typ='get') @@ -209,10 +222,16 @@ class ProxyResolver: self.sender_jid = sender_jid class HostTester(Socks5, IdleObject): - ''' fake proxy tester. ''' + """ + Fake proxy tester + """ + def __init__(self, host, port, jid, sid, sender_jid, on_success, on_failure): - ''' try to establish and auth to proxy at (host, port) - call on_success, or on_failure according to the result''' + """ + Try to establish and auth to proxy at (host, port) + + Calls on_success, or on_failure according to the result. + """ self.host = host self.port = port self.jid = jid @@ -226,7 +245,9 @@ class HostTester(Socks5, IdleObject): self.sid = sid def connect(self): - ''' create the socket and plug it to the idlequeue ''' + """ + Create the socket and plug it to the idlequeue + """ if self.host is None: self.on_failure() return None @@ -320,10 +341,16 @@ class HostTester(Socks5, IdleObject): return class ReceiverTester(Socks5, IdleObject): - ''' fake proxy tester. ''' + """ + Fake proxy tester + """ + def __init__(self, host, port, jid, sid, sender_jid, on_success, on_failure): - ''' try to establish and auth to proxy at (host, port) - call on_success, or on_failure according to the result''' + """ + Try to establish and auth to proxy at (host, port) + + Call on_success, or on_failure according to the result. + """ self.host = host self.port = port self.jid = jid @@ -337,7 +364,9 @@ class ReceiverTester(Socks5, IdleObject): self.sid = sid def connect(self): - ''' create the socket and plug it to the idlequeue ''' + """ + Create the socket and plug it to the idlequeue + """ if self.host is None: self.on_failure() return None diff --git a/src/common/pubsub.py b/src/common/pubsub.py index 8f65ff1a8..d2dbf88e1 100644 --- a/src/common/pubsub.py +++ b/src/common/pubsub.py @@ -67,7 +67,9 @@ class ConnectionPubSub: self.__callbacks[id_]=(cb, args, kwargs) def send_pb_publish(self, jid, node, item, id_, options=None): - '''Publish item to a node.''' + """ + Publish item to a node + """ if not self.connection or self.connected < 2: return query = xmpp.Iq('set', to=jid) @@ -80,20 +82,24 @@ class ConnectionPubSub: self.connection.send(query) - def send_pb_retrieve(self, jid, node, cb=None, *args, **kwargs): - '''Get items from a node''' - if not self.connection or self.connected < 2: - return - query = xmpp.Iq('get', to=jid) - r = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB) - r = r.addChild('items', {'node': node}) + def send_pb_retrieve(self, jid, node, cb=None, *args, **kwargs): + """ + Get items from a node + """ + if not self.connection or self.connected < 2: + return + query = xmpp.Iq('get', to=jid) + r = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB) + r = r.addChild('items', {'node': node}) id_ = self.connection.send(query) if cb: self.__callbacks[id_]=(cb, args, kwargs) def send_pb_retract(self, jid, node, id_): - '''Delete item from a node''' + """ + Delete item from a node + """ if not self.connection or self.connected < 2: return query = xmpp.Iq('set', to=jid) @@ -104,7 +110,9 @@ class ConnectionPubSub: self.connection.send(query) def send_pb_delete(self, jid, node): - '''Deletes node.''' + """ + Delete node + """ if not self.connection or self.connected < 2: return query = xmpp.Iq('set', to=jid) @@ -122,7 +130,9 @@ class ConnectionPubSub: 'node': node}) def send_pb_create(self, jid, node, configure = False, configure_form = None): - '''Creates new node.''' + """ + Create a new node + """ if not self.connection or self.connected < 2: return query = xmpp.Iq('set', to=jid) diff --git a/src/common/resolver.py b/src/common/resolver.py index b11abcd98..3ffd5430d 100644 --- a/src/common/resolver.py +++ b/src/common/resolver.py @@ -88,11 +88,12 @@ class CommonResolver(): # FIXME: API usage is not consistent! This one requires that process is called class LibAsyncNSResolver(CommonResolver): - ''' + """ Asynchronous resolver using libasyncns-python. process() method has to be - called in order to proceed the pending requests. - Based on patch submitted by Damien Thebault. - ''' + called in order to proceed the pending requests. Based on patch submitted by + Damien Thebault. + """ + def __init__(self): self.asyncns = libasyncns.Asyncns() CommonResolver.__init__(self) @@ -146,20 +147,22 @@ class LibAsyncNSResolver(CommonResolver): class NSLookupResolver(CommonResolver): - ''' + """ Asynchronous DNS resolver calling nslookup. Processing of pending requests - is invoked from idlequeue which is watching file descriptor of pipe of stdout - of nslookup process. - ''' + is invoked from idlequeue which is watching file descriptor of pipe of + stdout of nslookup process. + """ + def __init__(self, idlequeue): self.idlequeue = idlequeue self.process = False CommonResolver.__init__(self) def parse_srv_result(self, fqdn, result): - ''' parse the output of nslookup command and return list of - properties: 'host', 'port','weight', 'priority' corresponding to the found - srv hosts ''' + """ + Parse the output of nslookup command and return list of properties: + 'host', 'port','weight', 'priority' corresponding to the found srv hosts + """ if os.name == 'nt': return self._parse_srv_result_nt(fqdn, result) elif os.name == 'posix': @@ -260,7 +263,9 @@ class NSLookupResolver(CommonResolver): CommonResolver._on_ready(self, host, type, result_list) def start_resolve(self, host, type): - ''' spawn new nslookup process and start waiting for results ''' + """ + Spawn new nslookup process and start waiting for results + """ ns = NsLookup(self._on_ready, host, type) ns.set_idlequeue(self.idlequeue) ns.commandtimeout = 10 diff --git a/src/common/rst_xhtml_generator.py b/src/common/rst_xhtml_generator.py index 8f57bb698..7211e8a1d 100644 --- a/src/common/rst_xhtml_generator.py +++ b/src/common/rst_xhtml_generator.py @@ -33,17 +33,19 @@ except ImportError: return None else: def pos_int_validator(text): - """Validates that text can be evaluated as a positive integer.""" + """ + Validates that text can be evaluated as a positive integer + """ result = int(text) if result < 0: raise ValueError("Error: value '%(text)s' " "must be a positive integer") return result - def generate_uri_role( role_name, aliases, - anchor_text, base_url, - interpret_url, validator): - '''Creates and register a uri based "interpreted role". + def generate_uri_role( role_name, aliases, anchor_text, base_url, + interpret_url, validator): + """ + Create and register a uri based "interpreted role" Those are similar to the RFC, and PEP ones, and take role_name: @@ -58,7 +60,7 @@ else: this, modulo the validated text, will be added to it validator: should return the validated text, or raise ValueError - ''' + """ def uri_reference_role(role, rawtext, text, lineno, inliner, options={}, content=[]): try: @@ -94,15 +96,15 @@ else: pos_int_validator) class HTMLGenerator: - '''Really simple HTMLGenerator starting from publish_parts. + """ + Really simple HTMLGenerator starting from publish_parts It reuses the docutils.core.Publisher class, which means it is *not* threadsafe. - ''' - def __init__(self, - settings_spec=None, - settings_overrides=dict(report_level=5, halt_level=5), - config_section='general'): + """ + def __init__(self, settings_spec=None, + settings_overrides=dict(report_level=5, halt_level=5), + config_section='general'): self.pub = Publisher(reader=None, parser=None, writer=None, settings=None, source_class=io.StringInput, @@ -124,13 +126,12 @@ else: config_section) - def create_xhtml(self, text, - destination=None, - destination_path=None, - enable_exit_status=None): - ''' Create xhtml for a fragment of IM dialog. - We can use the source_name to store info about - the message.''' + def create_xhtml(self, text, destination=None, destination_path=None, + enable_exit_status=None): + """ + Create xhtml for a fragment of IM dialog. We can use the source_name + to store info about the message + """ self.pub.set_source(text, None) self.pub.set_destination(destination, destination_path) output = self.pub.publish(enable_exit_status=enable_exit_status) diff --git a/src/common/sleepy.py b/src/common/sleepy.py index 507452ea9..0116faefb 100644 --- a/src/common/sleepy.py +++ b/src/common/sleepy.py @@ -66,7 +66,9 @@ class SleepyWindows: return idleDelta def poll(self): - '''checks to see if we should change state''' + """ + Check to see if we should change state + """ if not SUPPORTED: return False @@ -113,7 +115,9 @@ class SleepyUnix: return idle.getIdleSec() def poll(self): - '''checks to see if we should change state''' + """ + Check to see if we should change state + """ if not SUPPORTED: return False diff --git a/src/common/socks5.py b/src/common/socks5.py index e1c1099ad..d6e8b9707 100644 --- a/src/common/socks5.py +++ b/src/common/socks5.py @@ -52,9 +52,12 @@ READ_TIMEOUT = 180 SEND_TIMEOUT = 180 class SocksQueue: - ''' queue for all file requests objects ''' + """ + Queue for all file requests objects + """ + def __init__(self, idlequeue, complete_transfer_cb=None, - progress_transfer_cb=None, error_cb=None): + progress_transfer_cb=None, error_cb=None): self.connected = 0 self.readers = {} self.files_props = {} @@ -72,9 +75,10 @@ class SocksQueue: self.on_failure = None def start_listener(self, port, sha_str, sha_handler, sid): - ''' start waiting for incomming connections on (host, port) - and do a socks5 authentication using sid for generated sha - ''' + """ + Start waiting for incomming connections on (host, port) and do a socks5 + authentication using sid for generated SHA + """ self.sha_handlers[sha_str] = (sha_handler, sid) if self.listener is None: self.listener = Socks5Listener(self.idlequeue, port) @@ -121,8 +125,10 @@ class SocksQueue: streamhost['idx'] = receiver.queue_idx def _socket_connected(self, streamhost, file_props): - ''' called when there is a host connected to one of the - senders's streamhosts. Stop othere attempts for connections ''' + """ + Called when there is a host connected to one of the senders's + streamhosts. Stop othere attempts for connections + """ for host in file_props['streamhosts']: if host != streamhost and 'idx' in host: if host['state'] == 1: @@ -137,10 +143,11 @@ class SocksQueue: host['state'] = -2 def reconnect_receiver(self, receiver, streamhost): - ''' Check the state of all streamhosts and if all has failed, then - emit connection failure cb. If there are some which are still - not connected try to establish connection to one of them. - ''' + """ + Check the state of all streamhosts and if all has failed, then emit + connection failure cb. If there are some which are still not connected + try to establish connection to one of them + """ self.idlequeue.remove_timeout(receiver.fd) self.idlequeue.unplug_idle(receiver.fd) file_props = receiver.file_props @@ -173,7 +180,9 @@ class SocksQueue: self.process_result(-1, receiver) def _connection_refused(self, streamhost, file_props, idx): - ''' cb, called when we loose connection during transfer''' + """ + Called when we loose connection during transfer + """ if file_props is None: return streamhost['state'] = -1 @@ -189,7 +198,9 @@ class SocksQueue: del(file_props['failure_cb']) def add_receiver(self, account, sock5_receiver): - ''' add new file request ''' + """ + Add new file request + """ self.readers[self.idx] = sock5_receiver sock5_receiver.queue_idx = self.idx sock5_receiver.queue = self @@ -259,9 +270,10 @@ class SocksQueue: sender.file_props = file_props def add_file_props(self, account, file_props): - ''' file_prop to the dict of current file_props. - It is identified by account name and sid - ''' + """ + File_prop to the dict of current file_props. It is identified by account + name and sid + """ if file_props is None or ('sid' in file_props) is False: return _id = file_props['sid'] @@ -279,7 +291,9 @@ class SocksQueue: self.connected = 0 def get_file_props(self, account, sid): - ''' get fil_prop by account name and session id ''' + """ + Get fil_prop by account name and session id + """ if account in self.files_props: fl_props = self.files_props[account] if sid in fl_props: @@ -294,11 +308,12 @@ class SocksQueue: self.connected += 1 def process_result(self, result, actor): - ''' Take appropriate actions upon the result: - [ 0, - 1 ] complete/end transfer - [ > 0 ] send progress message - [ None ] do nothing - ''' + """ + Take appropriate actions upon the result: + [ 0, - 1 ] complete/end transfer + [ > 0 ] send progress message + [ None ] do nothing + """ if result is None: return if result in (0, -1) and self.complete_transfer_cb is not None: @@ -310,8 +325,10 @@ class SocksQueue: self.progress_transfer_cb(actor.account, actor.file_props) def remove_receiver(self, idx, do_disconnect=True): - ''' Remove reciver from the list and decrease - the number of active connections with 1''' + """ + Remove reciver from the list and decrease the number of active + connections with 1 + """ if idx != -1: if idx in self.readers: reader = self.readers[idx] @@ -325,8 +342,10 @@ class SocksQueue: del(self.readers[idx]) def remove_sender(self, idx, do_disconnect=True): - ''' Remove sender from the list of senders and decrease the - number of active connections with 1''' + """ + Remove sender from the list of senders and decrease the number of active + connections with 1 + """ if idx != -1: if idx in self.senders: if do_disconnect: @@ -386,9 +405,10 @@ class Socks5: self.file = None def get_fd(self): - ''' Test if file is already open and return its fd, - or just open the file and return the fd. - ''' + """ + Test if file is already open and return its fd, or just open the file and + return the fd + """ if 'fd' in self.file_props: fd = self.file_props['fd'] else: @@ -413,8 +433,10 @@ class Socks5: pass def receive(self): - ''' Reads small chunks of data. - Calls owner's disconnected() method if appropriate.''' + """ + Read small chunks of data. Call owner's disconnected() method if + appropriate + """ received = '' try: add = self._recv(64) @@ -426,7 +448,9 @@ class Socks5: return add def send_raw(self,raw_data): - ''' Writes raw outgoing data. ''' + """ + Write raw outgoing data + """ try: self._send(raw_data) except Exception: @@ -483,7 +507,9 @@ class Socks5: return -1 def get_file_contents(self, timeout): - ''' read file contents from socket and write them to file ''' + """ + Read file contents from socket and write them to file + """ if self.file_props is None or ('file-name' in self.file_props) is False: self.file_props['error'] = -2 return None @@ -557,7 +583,9 @@ class Socks5: return None def disconnect(self): - ''' Closes open descriptors and remover socket descr. from idleque ''' + """ + Close open descriptors and remover socket descr. from idleque + """ # be sure that we don't leave open file self.close_file() self.idlequeue.remove_timeout(self.fd) @@ -573,13 +601,15 @@ class Socks5: self.state = -1 def _get_auth_buff(self): - ''' Message, that we support 1 one auth mechanism: - the 'no auth' mechanism. ''' + """ + Message, that we support 1 one auth mechanism: the 'no auth' mechanism + """ return struct.pack('!BBB', 0x05, 0x01, 0x00) def _parse_auth_buff(self, buff): - ''' Parse the initial message and create a list of auth - mechanisms ''' + """ + Parse the initial message and create a list of auth mechanisms + """ auth_mechanisms = [] try: num_auth = struct.unpack('!xB', buff[:2])[0] @@ -591,9 +621,9 @@ class Socks5: return auth_mechanisms def _get_auth_response(self): - ''' socks version(5), number of extra auth methods (we send - 0x00 - no auth - ) ''' + """ + Socks version(5), number of extra auth methods (we send 0x00 - no auth) + """ return struct.pack('!BB', 0x05, 0x00) def _get_connect_buff(self): @@ -604,8 +634,10 @@ class Socks5: return buff def _get_request_buff(self, msg, command = 0x01): - ''' Connect request by domain name, - sid sha, instead of domain name (jep 0096) ''' + """ + Connect request by domain name, sid sha, instead of domain name (jep + 0096) + """ buff = struct.pack('!BBBBB%dsBB' % len(msg), 0x05, command, 0x00, 0x03, len(msg), msg, 0, 0) return buff @@ -634,7 +666,9 @@ class Socks5: return (req_type, host, port) def read_connect(self): - ''' connect responce: version, auth method ''' + """ + Connect response: version, auth method + """ buff = self._recv() try: version, method = struct.unpack('!BB', buff) @@ -652,7 +686,9 @@ class Socks5: self.idlequeue.plug_idle(self, True, False) def _get_sha1_auth(self): - ''' get sha of sid + Initiator jid + Target jid ''' + """ + Get sha of sid + Initiator jid + Target jid + """ if 'is_a_proxy' in self.file_props: del(self.file_props['is_a_proxy']) return hashlib.sha1('%s%s%s' % (self.sid, @@ -662,9 +698,12 @@ class Socks5: hexdigest() class Socks5Sender(Socks5, IdleObject): - ''' class for sending file to socket over socks5 ''' + """ + Class for sending file to socket over socks5 + """ + def __init__(self, idlequeue, sock_hash, parent, _sock, host=None, - port=None): + port=None): self.queue_idx = sock_hash self.queue = parent Socks5.__init__(self, idlequeue, host, port, None, None, None) @@ -745,7 +784,9 @@ class Socks5Sender(Socks5, IdleObject): self.disconnect() def send_file(self): - ''' start sending the file over verified connection ''' + """ + Start sending the file over verified connection + """ if self.file_props['started']: return self.file_props['error'] = 0 @@ -766,7 +807,9 @@ class Socks5Sender(Socks5, IdleObject): return self.write_next() # initial for nl byte def main(self): - ''' initial requests for verifying the connection ''' + """ + Initial requests for verifying the connection + """ if self.state == 1: # initial read buff = self.receive() if not self.connected: @@ -785,7 +828,9 @@ class Socks5Sender(Socks5, IdleObject): return None def disconnect(self, cb=True): - ''' Closes the socket. ''' + """ + Close the socket + """ # close connection and remove us from the queue Socks5.disconnect(self) if self.file_props is not None: @@ -796,10 +841,12 @@ class Socks5Sender(Socks5, IdleObject): class Socks5Listener(IdleObject): def __init__(self, idlequeue, port): - ''' handle all incomming connections on (0.0.0.0, port) + """ + Handle all incomming connections on (0.0.0.0, port) + This class implements IdleObject, but we will expect only pollin events though - ''' + """ self.port = port self.ais = socket.getaddrinfo(None, port, socket.AF_UNSPEC, socket.SOCK_STREAM, socket.SOL_TCP, socket.AI_PASSIVE) @@ -843,16 +890,22 @@ class Socks5Listener(IdleObject): self.started = True def pollend(self): - ''' called when we stop listening on (host, port) ''' + """ + Called when we stop listening on (host, port) + """ self.disconnect() def pollin(self): - ''' accept a new incomming connection and notify queue''' + """ + Accept a new incomming connection and notify queue + """ sock = self.accept_conn() self.queue.on_connection_accepted(sock) def disconnect(self): - ''' free all resources, we are not listening anymore ''' + """ + Free all resources, we are not listening anymore + """ self.idlequeue.remove_timeout(self.fd) self.idlequeue.unplug_idle(self.fd) self.fd = -1 @@ -864,7 +917,9 @@ class Socks5Listener(IdleObject): pass def accept_conn(self): - ''' accepts a new incomming connection ''' + """ + Accept a new incomming connection + """ _sock = self._serv.accept() _sock[0].setblocking(False) return _sock @@ -909,7 +964,9 @@ class Socks5Receiver(Socks5, IdleObject): self.queue.reconnect_receiver(self, self.streamhost) def connect(self): - ''' create the socket and plug it to the idlequeue ''' + """ + Create the socket and plug it to the idlequeue + """ if self.ais is None: return None @@ -1018,7 +1075,9 @@ class Socks5Receiver(Socks5, IdleObject): return 1 # we are connected def main(self, timeout=0): - ''' begin negotiation. on success 'address' != 0 ''' + """ + Begin negotiation. on success 'address' != 0 + """ result = 1 buff = self.receive() if buff == '': @@ -1087,7 +1146,9 @@ class Socks5Receiver(Socks5, IdleObject): return None def disconnect(self, cb=True): - ''' Closes the socket. Remove self from queue if cb is True''' + """ + Close the socket. Remove self from queue if cb is True + """ # close connection Socks5.disconnect(self) if cb is True: diff --git a/src/common/stanza_session.py b/src/common/stanza_session.py index 3cb1a13cf..a85155efd 100644 --- a/src/common/stanza_session.py +++ b/src/common/stanza_session.py @@ -84,10 +84,11 @@ class StanzaSession(object): return to def remove_events(self, types): - ''' - Remove events associated with this session from the queue. - returns True if any events were removed (unlike events.py remove_events) - ''' + """ + Remove events associated with this session from the queue + + Returns True if any events were removed (unlike events.py remove_events) + """ any_removed = False for j in (self.jid, self.jid.getStripped()): @@ -140,10 +141,10 @@ class StanzaSession(object): self.cancelled_negotiation() def cancelled_negotiation(self): - ''' + """ A negotiation has been cancelled, so reset this session to its default - state. - ''' + state + """ if self.control: self.control.on_cancel_session_negotiation() @@ -175,7 +176,7 @@ class StanzaSession(object): class EncryptedStanzaSession(StanzaSession): - ''' + """ An encrypted stanza negotiation has several states. They arerepresented as the following values in the 'status' attribute of the session object: @@ -198,7 +199,8 @@ class EncryptedStanzaSession(StanzaSession): The transition between these states is handled in gajim.py's handle_session_negotiation method. - ''' + """ + def __init__(self, conn, jid, thread_id, type_='chat'): StanzaSession.__init__(self, conn, jid, thread_id, type_='chat') @@ -228,9 +230,9 @@ class EncryptedStanzaSession(StanzaSession): return True def set_kc_s(self, value): - ''' - keep the encrypter updated with my latest cipher key - ''' + """ + Keep the encrypter updated with my latest cipher key + """ self._kc_s = value self.encrypter = self.cipher.new(self._kc_s, self.cipher.MODE_CTR, counter=self.encryptcounter) @@ -239,9 +241,9 @@ class EncryptedStanzaSession(StanzaSession): return self._kc_s def set_kc_o(self, value): - ''' - keep the decrypter updated with the other party's latest cipher key - ''' + """ + Keep the decrypter updated with the other party's latest cipher key + """ self._kc_o = value self.decrypter = self.cipher.new(self._kc_o, self.cipher.MODE_CTR, counter=self.decryptcounter) @@ -335,7 +337,9 @@ class EncryptedStanzaSession(StanzaSession): return self.encrypter.encrypt(padded) def decrypt_stanza(self, stanza): - ''' delete the unencrypted explanation body, if it exists ''' + """ + Delete the unencrypted explanation body, if it exists + """ orig_body = stanza.getTag('body') if orig_body: stanza.delChild(orig_body) @@ -584,7 +588,9 @@ class EncryptedStanzaSession(StanzaSession): self.send(request) def verify_options_bob(self, form): - ''' 4.3 esession response (bob) ''' + """ + 4.3 esession response (bob) + """ negotiated = {'recv_pubkey': None, 'send_pubkey': None} not_acceptable = [] ask_user = {} @@ -653,7 +659,9 @@ class EncryptedStanzaSession(StanzaSession): return (negotiated, not_acceptable, ask_user) def respond_e2e_bob(self, form, negotiated, not_acceptable): - ''' 4.3 esession response (bob) ''' + """ + 4.3 esession response (bob) + """ response = xmpp.Message() feature = response.NT.feature feature.setNamespace(xmpp.NS_FEATURE) @@ -728,7 +736,9 @@ class EncryptedStanzaSession(StanzaSession): self.send(response) def verify_options_alice(self, form): - ''' 'Alice Accepts' ''' + """ + 'Alice Accepts' + """ negotiated = {} ask_user = {} not_acceptable = [] @@ -756,11 +766,13 @@ class EncryptedStanzaSession(StanzaSession): return (negotiated, not_acceptable, ask_user) def accept_e2e_alice(self, form, negotiated): - ''' 'Alice Accepts', continued ''' + """ + 'Alice Accepts', continued + """ self.encryptable_stanzas = ['message'] self.sas_algs = 'sas28x5' self.cipher = AES - self.hash_alg = sha256 + self.hash_alg = sha256 self.compression = None self.negotiated = negotiated @@ -828,7 +840,9 @@ class EncryptedStanzaSession(StanzaSession): self.status = 'identified-alice' def accept_e2e_bob(self, form): - ''' 4.5 esession accept (bob) ''' + """ + 4.5 esession accept (bob) + """ response = xmpp.Message() init = response.NT.init @@ -948,11 +962,11 @@ class EncryptedStanzaSession(StanzaSession): self.control.print_esession_details() def do_retained_secret(self, k, old_srs): - ''' + """ Calculate the new retained secret. determine if the user needs to check the remote party's identity. Set up callbacks for when the identity has - been verified. - ''' + been verified + """ new_srs = self.hmac(k, 'New Retained Secret') self.srs = new_srs @@ -1017,12 +1031,12 @@ class EncryptedStanzaSession(StanzaSession): self.enable_encryption = False def fail_bad_negotiation(self, reason, fields=None): - ''' - Sends an error and cancels everything. + """ + Send an error and cancels everything If fields is None, the remote party has given us a bad cryptographic - value of some kind. Otherwise, list the fields we haven't implemented - ''' + value of some kind. Otherwise, list the fields we haven't implemented. + """ err = xmpp.Error(xmpp.Message(), xmpp.ERR_FEATURE_NOT_IMPLEMENTED) err.T.error.T.text.setData(reason)