diff options
28 files changed, 1132 insertions, 614 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 <http://www.gnu.org/licenses/>. ## -""" 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 <http://www.gnu.org/licenses/>. ## -''' +""" 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 <http://www.gnu.org/licenses/>. ## -''' +""" 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 <henrique at recidive.com> 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] <asterix> we should add contact.fake_jid I think -# [15:34:46] <asterix> so if we know real jid, it wil be in contact.jid, or we look in contact.fake_jid -# [15:32:54] <asterix> they can have resource if we know the real jid -# [15:33:07] <asterix> 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 <content/> element to <jingle/> element, - with (full=True) or without (full=False) <content/> - children. ''' + """ + Append <content/> element to <jingle/> element, with (full=True) or + without (full=False) <content/> children + """ jingle.addChild('content', attrs={'name': content.name, 'creator': content.creator}) def __append_contents(self, jingle): - ''' Append all <content/> elements to <jingle/>.''' + """ + Append all <content/> elements to <jingle/> + """ # 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 <http://www.gnu.org/licenses/>. ## -''' 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 + """ + 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() + 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.''' + 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 = '<b>%s</b>' % gobject.markup_escape_text(mood) + markuptext = '<b>%s</b>' % 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 <i>%(source)s</i>') % {'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 = '<b>' + gobject.markup_escape_text(activity) if subactivity: markuptext += ': ' + gobject.markup_escape_text(subactivity) markuptext += '</b>' 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 <message /> 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) |