diff --git a/plugins/dbus_plugin/plugin.py b/plugins/dbus_plugin/plugin.py index 98dda772c..8bf8d55a3 100644 --- a/plugins/dbus_plugin/plugin.py +++ b/plugins/dbus_plugin/plugin.py @@ -407,7 +407,7 @@ if dbus_support.supported: return DBUS_DICT_SV() jid = self._get_real_jid(jid) - cached_vcard = gajim.connections.values()[0].get_cached_vcard(jid) + cached_vcard = list(gajim.connections.values())[0].get_cached_vcard(jid) if cached_vcard: return get_dbus_struct(cached_vcard) diff --git a/src/advanced_configuration_window.py b/src/advanced_configuration_window.py index 84847b6d9..a2266a55f 100644 --- a/src/advanced_configuration_window.py +++ b/src/advanced_configuration_window.py @@ -311,7 +311,6 @@ class AdvancedConfigurationWindow(object): value = str(option) except: value = option - value = helpers.ensure_utf8_string(value) self.model.append(parent, [name, value, type_]) def visible_func(self, model, treeiter, data): diff --git a/src/chat_control.py b/src/chat_control.py index d13351b7c..61738933d 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -1785,7 +1785,7 @@ class ChatControl(ChatControlBase): pep = self.contact.pep img = self._pep_images[pep_type] if pep_type in pep: - img.set_from_pixbuf(pep[pep_type].asPixbufIcon()) + img.set_from_pixbuf(gtkgui_helpers.get_pep_as_pixbuf(pep[pep_type])) img.set_tooltip_markup(pep[pep_type].asMarkupText()) img.show() else: @@ -3020,7 +3020,7 @@ class ChatControl(ChatControlBase): # It's why I set it transparent. image = self.xml.get_object('avatar_image') pixbuf = image.get_pixbuf() - pixbuf.fill(0xffffff00L) # RGBA + pixbuf.fill(0xffffff00) # RGBA image.queue_draw() screen_w = Gdk.Screen.width() diff --git a/src/command_system/dispatcher.py b/src/command_system/dispatcher.py index 398edae9c..4b88e5fb3 100644 --- a/src/command_system/dispatcher.py +++ b/src/command_system/dispatcher.py @@ -31,7 +31,6 @@ to automatic discovery and dispatching, also features manual control over the process. """ -from types import NoneType from .tools import remove COMMANDS = {} @@ -71,7 +70,7 @@ def is_command(attribute): return isinstance(attribute, Command) def is_root(namespace): - metaclass = namespace.get("__metaclass__", NoneType) + metaclass = namespace.get("__metaclass__", None) return issubclass(metaclass, Dispatchable) def get_command(host, name): @@ -83,7 +82,7 @@ def get_command(host, name): def list_commands(host): for container in CONTAINERS[host]: commands = COMMANDS[container] - for name, command in commands.iteritems(): + for name, command in commands.items(): yield name, command class Dispatchable(type): diff --git a/src/command_system/framework.py b/src/command_system/framework.py index f410d594a..29ebe5c83 100644 --- a/src/command_system/framework.py +++ b/src/command_system/framework.py @@ -25,7 +25,7 @@ from inspect import getargspec, getdoc from .dispatcher import Host, Container from .dispatcher import get_command, list_commands -from mmapping import parse_arguments, adapt_arguments +from .mapping import parse_arguments, adapt_arguments from .errors import DefinitionError, CommandError, NoCommandError class CommandHost(object): @@ -153,7 +153,7 @@ class Command(object): # Automatically set all the properties passed to a constructor # by the command decorator. - for key, value in properties.iteritems(): + for key, value in properties.items(): setattr(self, key, value) def __call__(self, *args, **kwargs): diff --git a/src/command_system/implementation/execute.py b/src/command_system/implementation/execute.py index 48253dfae..688347a1f 100644 --- a/src/command_system/implementation/execute.py +++ b/src/command_system/implementation/execute.py @@ -35,7 +35,7 @@ commands as a frontend. from subprocess import Popen, PIPE from os.path import expanduser -from glib import timeout_add +from gi.repository import GObject from ..framework import CommandContainer, command, doc from .hosts import * @@ -64,7 +64,7 @@ class Execute(CommandContainer): @classmethod def monitor(cls, processor, popen): poller = cls.poller(processor, popen) - timeout_add(cls.POLL_INTERVAL, poller.next) + GObject.timeout_add(cls.POLL_INTERVAL, poller.next) @classmethod def poller(cls, processor, popen): diff --git a/src/command_system/implementation/middleware.py b/src/command_system/implementation/middleware.py index 64396d0f6..40e4bdf4e 100644 --- a/src/command_system/implementation/middleware.py +++ b/src/command_system/implementation/middleware.py @@ -31,7 +31,6 @@ support interaction between the two and a few utility methods so you don't need to dig up the code itself to write basic commands. """ -from types import StringTypes from traceback import print_exc from gi.repository import Pango @@ -98,7 +97,7 @@ class ChatCommandProcessor(CommandProcessor): def command_postprocessor(self, command, name, arguments, args, kwargs, value): # If command returns a string - print it to a user. A convenient # and sufficient in most simple cases shortcut to a using echo. - if value and isinstance(value, StringTypes): + if value and isinstance(value, str): self.echo(value) class CommandTools: diff --git a/src/command_system/mapping.py b/src/command_system/mapping.py index dcb7a96c2..82283df71 100644 --- a/src/command_system/mapping.py +++ b/src/command_system/mapping.py @@ -23,7 +23,6 @@ according to the command properties. """ import re -from types import BooleanType, UnicodeType from operator import itemgetter from .errors import DefinitionError, CommandError @@ -62,7 +61,7 @@ def parse_arguments(arguments): """ args, opts = [], [] - def intersects_opts((given_start, given_end)): + def intersects_opts(given_start, given_end): """ Check if given span intersects with any of options. """ @@ -71,7 +70,7 @@ def parse_arguments(arguments): return True return False - def intersects_args((given_start, given_end)): + def intersects_args(given_start, given_end): """ Check if given span intersects with any of arguments. """ @@ -97,14 +96,14 @@ def parse_arguments(arguments): # conflicted sectors. Remove any arguments that intersect with # options. for arg, position in args[:]: - if intersects_opts(position): + if intersects_opts(*position): args.remove((arg, position)) # Primitive but sufficiently effective way of disposing of # conflicted sectors. Remove any options that intersect with # arguments. for key, value, position in opts[:]: - if intersects_args(position): + if intersects_args(*position): opts.remove((key, value, position)) return args, opts @@ -207,7 +206,7 @@ def adapt_arguments(command, arguments, args, opts): # corresponding optin has been given. if command.expand: expanded = [] - for spec_key, spec_value in norm_kwargs.iteritems(): + for spec_key, spec_value in norm_kwargs.items(): letter = spec_key[0] if len(spec_key) > 1 else None if letter and letter not in expanded: for index, (key, value, position) in enumerate(opts): @@ -219,7 +218,7 @@ def adapt_arguments(command, arguments, args, opts): # Detect switches and set their values accordingly. If any of them # carries a value - append it to args. for index, (key, value, position) in enumerate(opts): - if isinstance(norm_kwargs.get(key), BooleanType): + if isinstance(norm_kwargs.get(key), bool): opts[index] = (key, True, position) if value: args.append((value, position)) @@ -231,8 +230,8 @@ def adapt_arguments(command, arguments, args, opts): # Stripping down position information supplied with arguments and # options as it won't be needed again. - args = map(lambda (arg, position): arg, args) - opts = map(lambda (key, value, position): (key, value), opts) + args = map(lambda t: t[0], t[1]) + opts = map(lambda t: (t[0], t[1]), opts) # If command has extra option enabled - collect all extra arguments # and pass them to a last positional argument command defines as a @@ -265,8 +264,8 @@ def adapt_arguments(command, arguments, args, opts): # Normally this does not happen unless overlapping is enabled. for key, value in opts: initial = norm_kwargs.get(key) - if isinstance(initial, BooleanType): - if not isinstance(value, BooleanType): + if isinstance(initial, bool): + if not isinstance(value, bool): raise CommandError("%s: Switch can not take an argument" % key, command) # Inject the source arguments as a string as a first argument, if @@ -299,7 +298,7 @@ def generate_usage(command, complete=True): letter = key[0] key = key.replace('_', '-') - if isinstance(value, BooleanType): + if isinstance(value, bool): value = str() else: value = '=%s' % value diff --git a/src/common/caps_cache.py b/src/common/caps_cache.py index 6c8286188..bbf25c477 100644 --- a/src/common/caps_cache.py +++ b/src/common/caps_cache.py @@ -130,7 +130,8 @@ def compute_caps_hash(identities, features, dataforms=[], hash_method='sha-1'): return 1 S = '' - identities.sort(cmp=sort_identities_func) + from functools import cmp_to_key + identities.sort(key=cmp_to_key(sort_identities_func)) for i in identities: c = i['category'] type_ = i.get('type', '') @@ -140,7 +141,7 @@ def compute_caps_hash(identities, features, dataforms=[], hash_method='sha-1'): features.sort() for f in features: S += '%s<' % f - dataforms.sort(cmp=sort_dataforms_func) + dataforms.sort(key=cmp_to_key(sort_dataforms_func)) for dataform in dataforms: # fields indexed by var fields = {} @@ -157,9 +158,9 @@ def compute_caps_hash(identities, features, dataforms=[], hash_method='sha-1'): S += '%s<' % value if hash_method == 'sha-1': - hash_ = hashlib.sha1(S) + hash_ = hashlib.sha1(S.encode('utf-8')) elif hash_method == 'md5': - hash_ = hashlib.md5(S) + hash_ = hashlib.md5(S.encode('utf-8')) else: return '' return base64.b64encode(hash_.digest()) diff --git a/src/common/check_paths.py b/src/common/check_paths.py index 9ea3bd898..f9ad30983 100644 --- a/src/common/check_paths.py +++ b/src/common/check_paths.py @@ -38,7 +38,7 @@ import sqlite3 as sqlite def create_log_db(): print(_('creating logs database')) con = sqlite.connect(logger.LOG_DB_PATH) - os.chmod(logger.LOG_DB_PATH, 0600) # rw only for us + os.chmod(logger.LOG_DB_PATH, 0o600) # rw only for us cur = con.cursor() # create the tables # kind can be @@ -86,7 +86,7 @@ def create_log_db(): def create_cache_db(): print(_('creating cache database')) con = sqlite.connect(logger.CACHE_DB_PATH) - os.chmod(logger.CACHE_DB_PATH, 0600) # rw only for us + os.chmod(logger.CACHE_DB_PATH, 0o600) # rw only for us cur = con.cursor() cur.executescript( ''' @@ -177,7 +177,7 @@ def check_and_possibly_move_config(): vars['MY_ICONSETS_PATH'] = gajim.MY_ICONSETS_PATH vars['MY_MOOD_ICONSETS_PATH'] = gajim.MY_MOOD_ICONSETS_PATH vars['MY_ACTIVITY_ICONSETS_PATH'] = gajim.MY_ACTIVITY_ICONSETS_PATH - import configpaths + from common import configpaths MY_DATA = configpaths.gajimpaths['MY_DATA'] MY_CONFIG = configpaths.gajimpaths['MY_CONFIG'] MY_CACHE = configpaths.gajimpaths['MY_CACHE'] @@ -263,7 +263,7 @@ def check_and_possibly_create_paths(): VCARD_PATH = gajim.VCARD_PATH AVATAR_PATH = gajim.AVATAR_PATH - import configpaths + from common import configpaths MY_DATA = configpaths.gajimpaths['MY_DATA'] MY_CONFIG = configpaths.gajimpaths['MY_CONFIG'] MY_CACHE = configpaths.gajimpaths['MY_CACHE'] @@ -364,4 +364,4 @@ def create_path(directory): if os.path.exists(directory): return print(('creating %s directory') % directory) - os.mkdir(directory, 0700) + os.mkdir(directory, 0o700) diff --git a/src/common/commands.py b/src/common/commands.py index 5fd067dc6..aaf6c8536 100644 --- a/src/common/commands.py +++ b/src/common/commands.py @@ -363,7 +363,7 @@ class ConnectionCommands: # buildReply don't copy the node attribute. Re-add it q.setAttr('node', nbxmpp.NS_COMMANDS) - for node, cmd in self.__commands.iteritems(): + for node, cmd in self.__commands.items(): if cmd.isVisibleFor(self.isSameJID(jid)): q.addChild('item', { # TODO: find the jid diff --git a/src/common/config.py b/src/common/config.py index c31003f45..d3eb50875 100644 --- a/src/common/config.py +++ b/src/common/config.py @@ -35,7 +35,7 @@ import sys import re import copy -import defs +from common import defs from gi.repository import GObject ( @@ -568,7 +568,7 @@ class Config: Tree-like interface """ if node is None: - for child, option in self.__options[1].iteritems(): + for child, option in self.__options[1].items(): yield (child, ), option for grandparent in self.__options_per_key: yield (grandparent, ), None @@ -579,7 +579,7 @@ class Config: elif len(node) == 2: grandparent, parent = node children = self.__options_per_key[grandparent][1][parent] - for child, option in children.iteritems(): + for child, option in children.items(): yield (grandparent, parent, child), option else: raise ValueError('Invalid node') @@ -625,11 +625,9 @@ class Config: def set(self, optname, value): if optname not in self.__options[1]: -# raise RuntimeError, 'option %s does not exist' % optname return value = self.is_valid(self.__options[0][optname][OPT_TYPE], value) if value is None: -# raise RuntimeError, 'value of %s cannot be None' % optname return self.__options[1][optname] = value @@ -666,7 +664,6 @@ class Config: def add_per(self, typename, name): # per_group_of_option if typename not in self.__options_per_key: -# raise RuntimeError, 'option %s does not exist' % typename return opt = self.__options_per_key[typename] @@ -680,7 +677,6 @@ class Config: def del_per(self, typename, name, subname = None): # per_group_of_option if typename not in self.__options_per_key: -# raise RuntimeError, 'option %s does not exist' % typename return opt = self.__options_per_key[typename] @@ -693,22 +689,18 @@ class Config: def set_per(self, optname, key, subname, value): # per_group_of_option if optname not in self.__options_per_key: -# raise RuntimeError, 'option %s does not exist' % optname return if not key: return dict_ = self.__options_per_key[optname][1] if key not in dict_: -# raise RuntimeError, '%s is not a key of %s' % (key, dict_) self.add_per(optname, key) obj = dict_[key] if subname not in obj: -# raise RuntimeError, '%s is not a key of %s' % (subname, obj) return typ = self.__options_per_key[optname][0][subname][OPT_TYPE] value = self.is_valid(typ, value) if value is None: -# raise RuntimeError, '%s of %s cannot be None' % optname return obj[subname] = value self._timeout_save() diff --git a/src/common/configpaths.py b/src/common/configpaths.py index 94550b988..75df82e42 100644 --- a/src/common/configpaths.py +++ b/src/common/configpaths.py @@ -25,7 +25,7 @@ import os import sys import tempfile -import defs +from common import defs HAVE_XDG = True try: __import__(xdg) @@ -130,7 +130,7 @@ class ConfigPaths: except KeyError: return default - def iteritems(self): + def items(self): for key in self.paths.iterkeys(): yield (key, self[key]) diff --git a/src/common/connection.py b/src/common/connection.py index 6734ede28..861b51d96 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -59,7 +59,7 @@ from common import gpg from common import passwords from common import exceptions from common import check_X509 -from connection_handlers import * +from common.connection_handlers import * from nbxmpp import Smacks from string import Template diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py index 5db5a96ac..11bc078fe 100644 --- a/src/common/connection_handlers.py +++ b/src/common/connection_handlers.py @@ -322,7 +322,7 @@ class ConnectionVcard: os.remove(path) # create folder if needed if not os.path.isdir(path): - os.mkdir(path, 0700) + os.mkdir(path, 0o700) puny_nick = helpers.sanitize_filename(nick) path_to_file = os.path.join(gajim.VCARD_PATH, puny_jid, puny_nick) else: @@ -706,7 +706,7 @@ class ConnectionVcard: puny_nick = helpers.sanitize_filename(resource) # create folder if needed if not os.path.isdir(begin_path): - os.mkdir(begin_path, 0700) + os.mkdir(begin_path, 0o700) begin_path = os.path.join(begin_path, puny_nick) frm_jid += '/' + resource if photo_decoded: diff --git a/src/common/connection_handlers_events.py b/src/common/connection_handlers_events.py index 5dd2690d8..2f1ae0932 100644 --- a/src/common/connection_handlers_events.py +++ b/src/common/connection_handlers_events.py @@ -39,8 +39,6 @@ from nbxmpp.protocol import NS_CHATSTATES from common.jingle_transport import JingleTransportSocks5 from common.file_props import FilesProp -from . import gtkgui_helpers - import logging log = logging.getLogger('gajim.c.connection_handlers_events') @@ -2181,8 +2179,6 @@ class NotificationEvent(nec.NetworkIncomingEvent): self.popup_title = _('New Message from %(nickname)s') % \ {'nickname': nick} - self.popup_image = gtkgui_helpers.get_icon_path(self.popup_image, 48) - if not gajim.config.get('notify_on_new_message') or \ not self.first_unread: self.do_popup = False @@ -2237,6 +2233,28 @@ class NotificationEvent(nec.NetworkIncomingEvent): self.do_popup = False + def get_path_to_generic_or_avatar(self, generic, jid=None, suffix=None): + """ + Choose between avatar image and default image + + Returns full path to the avatar image if it exists, otherwise returns full + path to the image. generic must be with extension and suffix without + """ + if jid: + # we want an avatar + puny_jid = helpers.sanitize_filename(jid) + path_to_file = os.path.join(gajim.AVATAR_PATH, puny_jid) + suffix + path_to_local_file = path_to_file + '_local' + for extension in ('.png', '.jpeg'): + path_to_local_file_full = path_to_local_file + extension + if os.path.exists(path_to_local_file_full): + return path_to_local_file_full + for extension in ('.png', '.jpeg'): + path_to_file_full = path_to_file + extension + if os.path.exists(path_to_file_full): + return path_to_file_full + return os.path.abspath(generic) + def handle_incoming_pres_event(self, pres_obj): if gajim.jid_is_transport(pres_obj.jid): return True @@ -2315,8 +2333,8 @@ class NotificationEvent(nec.NetworkIncomingEvent): iconset = gajim.config.get('iconset') img_path = os.path.join(helpers.get_iconset_path(iconset), '48x48', show_image) - self.popup_image = gtkgui_helpers.get_path_to_generic_or_avatar( - img_path, jid=self.jid, suffix=suffix) + self.popup_image = self.get_path_to_generic_or_avatar(img_path, + jid=self.jid, suffix=suffix) self.popup_timeout = gajim.config.get('notification_timeout') diff --git a/src/common/contacts.py b/src/common/contacts.py index 7f7ff283c..1d6f891b6 100644 --- a/src/common/contacts.py +++ b/src/common/contacts.py @@ -94,6 +94,8 @@ class Contact(CommonContact): sub='', ask='', resource='', priority=0, keyID='', client_caps=None, our_chatstate=None, chatstate=None, last_status_time=None, msg_id=None, last_activity_time=None): + if not isinstance(jid, str): + print('no str') CommonContact.__init__(self, jid, account, resource, show, status, name, our_chatstate, chatstate, client_caps=client_caps) @@ -494,7 +496,7 @@ class Contacts(): return self._contacts.keys() def get_contacts_jid_list(self): - return [jid for jid, contact in self._contacts.iteritems() if not + return [jid for jid, contact in self._contacts.items() if not contact[0].is_groupchat()] def get_contact_from_full_jid(self, fjid): diff --git a/src/common/gajim.py b/src/common/gajim.py index 8ccf9fc1a..b6f1db9ff 100644 --- a/src/common/gajim.py +++ b/src/common/gajim.py @@ -34,7 +34,7 @@ import locale from common import config import nbxmpp from common import defs -from common import ged +from common import ged as ged_module interface = None # The actual interface (the gtk one for the moment) thread_interface = None # Interface to run a thread and then a callback @@ -43,16 +43,15 @@ version = config.get('version') connections = {} # 'account name': 'account (connection.Connection) instance' ipython_window = None -ged = common.ged.GlobalEventsDispatcher() # Global Events Dispatcher +ged = ged_module.GlobalEventsDispatcher() # Global Events Dispatcher nec = None # Network Events Controller plugin_manager = None # Plugins Manager log = logging.getLogger('gajim') -import logger -logger = logger.Logger() # init the logger +logger = None -import configpaths +from common import configpaths gajimpaths = configpaths.gajimpaths VCARD_PATH = gajimpaths['VCARD'] @@ -84,8 +83,8 @@ else: os_info = None # used to cache os information -from contacts import LegacyContactsAPI -from events import Events +from common.contacts import LegacyContactsAPI +from common.events import Events gmail_domains = ['gmail.com', 'googlemail.com'] @@ -221,9 +220,6 @@ gajim_optional_features = {} # Capabilities hash per account caps_hash = {} -import caps_cache -caps_cache.initialize(logger) - global_id = 0 def get_an_id(): global global_id diff --git a/src/common/gpg.py b/src/common/gpg.py index b8a470284..fafb56333 100644 --- a/src/common/gpg.py +++ b/src/common/gpg.py @@ -22,7 +22,7 @@ ## along with Gajim. If not, see . ## -from gajim import HAVE_GPG +from common.gajim import HAVE_GPG import os if HAVE_GPG: diff --git a/src/common/helpers.py b/src/common/helpers.py index 6a86be88d..32c922400 100644 --- a/src/common/helpers.py +++ b/src/common/helpers.py @@ -35,7 +35,7 @@ import locale import os import subprocess import urllib -import urllib2 +import urllib import webbrowser import errno import select @@ -50,8 +50,8 @@ from gi.repository import GObject from encodings.punycode import punycode_encode from string import Template -from i18n import Q_ -from i18n import ngettext +from common.i18n import Q_ +from common.i18n import ngettext try: import winsound # windows-only built-in module for playing wav @@ -122,7 +122,7 @@ def idn_to_ascii(host): labels = idna.dots.split(host) converted_labels = [] for label in labels: - converted_labels.append(idna.ToASCII(label)) + converted_labels.append(idna.ToASCII(label).decode('utf-8')) return ".".join(converted_labels) def ascii_to_idn(host): @@ -146,7 +146,7 @@ def parse_resource(resource): from nbxmpp.stringprepare import resourceprep return resourceprep.prepare(resource) except UnicodeError: - raise InvalidFormat, 'Invalid character in resource.' + raise InvalidFormat('Invalid character in resource.') def prep(user, server, resource): """ @@ -156,34 +156,34 @@ def prep(user, server, resource): #http://svn.twistedmatrix.com/cvs/trunk/twisted/words/protocols/jabber/jid.py if user is not None: if len(user) < 1 or len(user) > 1023: - raise InvalidFormat, _('Username must be between 1 and 1023 chars') + raise InvalidFormat(_('Username must be between 1 and 1023 chars')) try: from nbxmpp.stringprepare import nodeprep user = nodeprep.prepare(user) except UnicodeError: - raise InvalidFormat, _('Invalid character in username.') + raise InvalidFormat(_('Invalid character in username.')) else: user = None if server is not None: if len(server) < 1 or len(server) > 1023: - raise InvalidFormat, _('Server must be between 1 and 1023 chars') + raise InvalidFormat(_('Server must be between 1 and 1023 chars')) try: from nbxmpp.stringprepare import nameprep server = nameprep.prepare(server) except UnicodeError: - raise InvalidFormat, _('Invalid character in hostname.') + raise InvalidFormat(_('Invalid character in hostname.')) else: - raise InvalidFormat, _('Server address required.') + raise InvalidFormat(_('Server address required.')) if resource is not None: if len(resource) < 1 or len(resource) > 1023: - raise InvalidFormat, _('Resource must be between 1 and 1023 chars') + raise InvalidFormat(_('Resource must be between 1 and 1023 chars')) try: from nbxmpp.stringprepare import resourceprep resource = resourceprep.prepare(resource) except UnicodeError: - raise InvalidFormat, _('Invalid character in resource.') + raise InvalidFormat(_('Invalid character in resource.')) else: resource = None @@ -493,7 +493,7 @@ def get_windows_reg_env(varname, default=''): 'AppData' = %USERPROFILE%\Application Data (also an ENV) 'Desktop' = %USERPROFILE%\Desktop 'Favorites' = %USERPROFILE%\Favorites - 'NetHood' = %USERPROFILE%\NetHood + 'NetHood' = %USERPROFILE%\ NetHood 'Personal' = D:\My Documents (PATH TO MY DOCUMENTS) 'PrintHood' = %USERPROFILE%\PrintHood 'Programs' = %USERPROFILE%\Start Menu\Programs @@ -555,7 +555,8 @@ def sanitize_filename(filename): hash = hashlib.md5(filename) filename = base64.b64encode(hash.digest()) - filename = punycode_encode(filename) # make it latin chars only + # make it latin chars only + filename = punycode_encode(filename).decode('utf-8') filename = filename.replace('/', '_') if os.name == 'nt': filename = filename.replace('?', '_').replace(':', '_')\ @@ -634,10 +635,10 @@ def datetime_tuple(timestamp): # import gajim only when needed (after decode_string is defined) see #4764 -import gajim +from common import gajim if gajim.HAVE_PYCURL: import pycurl - from cStringIO import StringIO + from io import StringIO def convert_bytes(string): suffix = '' @@ -1462,9 +1463,9 @@ def _get_img_direct(attrs): # Wait maximum 5s for connection socket.setdefaulttimeout(5) try: - req = urllib2.Request(attrs['src']) + req = urllib.request.Request(attrs['src']) req.add_header('User-Agent', 'Gajim ' + gajim.version) - f = urllib2.urlopen(req) + f = urllib.request.urlopen(req) except Exception as ex: log.debug('Error loading image %s ' % attrs['src'] + str(ex)) pixbuf = None diff --git a/src/common/i18n.py b/src/common/i18n.py index 1970e239e..9c3c3bb03 100644 --- a/src/common/i18n.py +++ b/src/common/i18n.py @@ -63,7 +63,7 @@ if os.name == 'nt': gettext.install(APP, DIR) if gettext._translations: - _translation = gettext._translations.values()[0] + _translation = list(gettext._translations.values())[0] else: _translation = gettext.NullTranslations() diff --git a/src/common/jingle.py b/src/common/jingle.py index 57e26c3b1..3fd311daa 100644 --- a/src/common/jingle.py +++ b/src/common/jingle.py @@ -27,14 +27,14 @@ Handles the jingle signalling protocol # - codecs import nbxmpp -import helpers -import gajim +from common import helpers +from common import gajim -from jingle_session import JingleSession, JingleStates +from common.jingle_session import JingleSession, JingleStates if gajim.HAVE_FARSTREAM: - from jingle_rtp import JingleAudio, JingleVideo -from jingle_ft import JingleFileTransfer -from jingle_transport import JingleTransportSocks5, JingleTransportIBB + from common.jingle_rtp import JingleAudio, JingleVideo +from common.jingle_ft import JingleFileTransfer +from common.jingle_transport import JingleTransportSocks5, JingleTransportIBB import logging logger = logging.getLogger('gajim.c.jingle') diff --git a/src/common/jingle_content.py b/src/common/jingle_content.py index df04d729f..04e3b8740 100644 --- a/src/common/jingle_content.py +++ b/src/common/jingle_content.py @@ -15,9 +15,9 @@ Handles Jingle contents (XEP 0166) """ -import gajim +from common import gajim import nbxmpp -from jingle_transport import JingleTransportIBB +from common.jingle_transport import JingleTransportIBB contents = {} diff --git a/src/common/jingle_ft.py b/src/common/jingle_ft.py index 8ac9330c4..c050cf6b3 100644 --- a/src/common/jingle_ft.py +++ b/src/common/jingle_ft.py @@ -20,16 +20,16 @@ Handles Jingle File Transfer (XEP 0234) """ import hashlib -import gajim +from common import gajim import nbxmpp -from jingle_content import contents, JingleContent -from jingle_transport import * +from common.jingle_content import contents, JingleContent +from common.jingle_transport import * from common import helpers from common.socks5 import Socks5ReceiverClient, Socks5SenderClient from common.connection_handlers_events import FileRequestReceivedEvent import threading import logging -from jingle_ftstates import * +from common.jingle_ftstates import * log = logging.getLogger('gajim.c.jingle_ft') STATE_NOT_STARTED = 0 diff --git a/src/common/jingle_ftstates.py b/src/common/jingle_ftstates.py index a83ab9e30..23e257392 100644 --- a/src/common/jingle_ftstates.py +++ b/src/common/jingle_ftstates.py @@ -11,9 +11,9 @@ ## GNU General Public License for more details. ## -import gajim +from common import gajim import nbxmpp -from jingle_transport import * +from common.jingle_transport import * from common.socks5 import Socks5ReceiverClient, Socks5SenderClient diff --git a/src/common/jingle_rtp.py b/src/common/jingle_rtp.py index 26ac22544..3897e48cc 100644 --- a/src/common/jingle_rtp.py +++ b/src/common/jingle_rtp.py @@ -21,14 +21,15 @@ from gi.repository import GObject import socket import nbxmpp -import farstream, gst +import farstream +import gst from glib import GError -import gajim +from common import gajim -from jingle_transport import JingleTransportICEUDP -from jingle_content import contents, JingleContent, JingleContentSetupException -from connection_handlers_events import InformationEvent +from common.jingle_transport import JingleTransportICEUDP +from common.jingle_content import contents, JingleContent, JingleContentSetupException +from common.connection_handlers_events import InformationEvent import logging diff --git a/src/common/jingle_session.py b/src/common/jingle_session.py index a19056f9b..bd9a0130b 100644 --- a/src/common/jingle_session.py +++ b/src/common/jingle_session.py @@ -26,12 +26,12 @@ Handles Jingle sessions (XEP 0166) # - Tie-breaking # * timeout -import gajim #Get rid of that? +from common import gajim import nbxmpp -from jingle_transport import get_jingle_transport, JingleTransportIBB -from jingle_content import get_jingle_content, JingleContentSetupException -from jingle_content import JingleContent -from jingle_ft import STATE_TRANSPORT_REPLACE +from common.jingle_transport import get_jingle_transport, JingleTransportIBB +from common.jingle_content import get_jingle_content, JingleContentSetupException +from common.jingle_content import JingleContent +from common.jingle_ft import STATE_TRANSPORT_REPLACE from common.connection_handlers_events import * import logging log = logging.getLogger("gajim.c.jingle_session") @@ -73,7 +73,6 @@ class JingleSession(object): self.contents = {} # negotiated contents self.connection = con # connection to use # our full jid - #FIXME: Get rid of gajim here? self.ourjid = gajim.get_jid_from_account(self.connection.name) if con.server_resource: self.ourjid = self.ourjid + '/' + con.server_resource diff --git a/src/common/jingle_transport.py b/src/common/jingle_transport.py index 64e4b5d02..a31a5d535 100644 --- a/src/common/jingle_transport.py +++ b/src/common/jingle_transport.py @@ -296,7 +296,7 @@ class JingleTransportSocks5(JingleTransport): cid = host['candidate_id'] break if cid is None: - raise Exception, 'cid is missing' + raise Exception('cid is missing') activated.setAttr('cid', cid) transport.addChild(node=activated) content.addChild(node=transport) diff --git a/src/common/jingle_xtls.py b/src/common/jingle_xtls.py index 3a251179f..1c61fb610 100644 --- a/src/common/jingle_xtls.py +++ b/src/common/jingle_xtls.py @@ -20,7 +20,6 @@ import os import nbxmpp import logging -import common from common import gajim log = logging.getLogger('gajim.c.jingle_xtls') @@ -201,7 +200,7 @@ def createCertRequest(pkey, digest="md5", **name): req.sign(pkey, digest) return req -def createCertificate(req, (issuerCert, issuerKey), serial, (notBefore, notAfter), digest="md5"): +def createCertificate(req, issuerCert, issuerKey, serial, notBefore, notAfter, digest="md5"): """ Generate a certificate given a certificate request. @@ -235,7 +234,7 @@ def make_certs(filepath, CN): """ key = createKeyPair(TYPE_RSA, 1024) req = createCertRequest(key, CN=CN) - cert = createCertificate(req, (req, key), 0, (0, 60*60*24*365*5)) # five years + cert = createCertificate(req, req, key, 0, 0, 60*60*24*365*5) # five years open(filepath + '.pkey', 'w').write(crypto.dump_privatekey( crypto.FILETYPE_PEM, key)) open(filepath + '.cert', 'w').write(crypto.dump_certificate( diff --git a/src/common/logger.py b/src/common/logger.py index 1f25d940e..3ce6fab62 100644 --- a/src/common/logger.py +++ b/src/common/logger.py @@ -33,16 +33,16 @@ import sys import time import datetime from gzip import GzipFile -from cStringIO import StringIO +from io import BytesIO from gi.repository import GObject -import exceptions -import gajim -import ged +from common import exceptions +from common import gajim +from common import ged import sqlite3 as sqlite -import configpaths +from common import configpaths LOG_DB_PATH = configpaths.gajimpaths['LOG_DB'] LOG_DB_FOLDER, LOG_DB_FILE = os.path.split(LOG_DB_PATH) CACHE_DB_PATH = configpaths.gajimpaths['CACHE_DB'] @@ -884,7 +884,7 @@ class Logger: # ..., 'FEAT', feature1, feature2, ...).join(' ')) # NOTE: if there's a need to do more gzip, put that to a function try: - data = GzipFile(fileobj=StringIO(str(data))).read().split('\0') + data = GzipFile(fileobj=BytesIO(data)).read().decode('utf-8').split('\0') except IOError: # This data is corrupted. It probably contains non-ascii chars to_be_removed.append((hash_method, hash_)) @@ -1046,8 +1046,8 @@ class Logger: FROM roster_entry re, jids j WHERE re.account_jid_id=? AND j.jid_id=re.jid_id''', (account_jid_id,)) for jid, jid_id, name, subscription, ask in self.cur: - jid = jid.encode('utf-8') - name = name.encode('utf-8') + jid = jid + name = name data[jid] = {} if name: data[jid]['name'] = name @@ -1071,7 +1071,7 @@ class Logger: WHERE account_jid_id=? AND jid_id=?''', (account_jid_id, data[jid]['id'])) for (group_name,) in self.cur: - group_name = group_name.encode('utf-8') + group_name = group_name data[jid]['groups'].append(group_name) del data[jid]['id'] diff --git a/src/common/nec.py b/src/common/nec.py index eb4fdccf0..b699085c1 100644 --- a/src/common/nec.py +++ b/src/common/nec.py @@ -153,7 +153,7 @@ class NetworkEvent(object): return True def _set_kwargs_as_attributes(self, **kwargs): - for k, v in kwargs.iteritems(): + for k, v in kwargs.items(): setattr(self, k, v) diff --git a/src/common/optparser.py b/src/common/optparser.py index 39a20c851..520bd94d0 100644 --- a/src/common/optparser.py +++ b/src/common/optparser.py @@ -36,7 +36,7 @@ from common import helpers from common import caps_cache import sqlite3 as sqlite -import logger +from common import logger class OptionsParser: def __init__(self, filename): @@ -60,10 +60,6 @@ class OptionsParser: regex = re.compile(r"(?P[^.]+)(?:(?:\.(?P.+))?\.(?P[^.]+))?\s=\s(?P.*)") for line in fd: - try: - line = helpers.ensure_utf8_string(line) - except UnicodeDecodeError: - line = line.decode(locale.getpreferredencoding()) optname, key, subname, value = regex.match(line).groups() if key is None: self.old_values[optname] = value @@ -122,7 +118,7 @@ class OptionsParser: os.rename(self.__tempfile, self.__filename) except IOError as e: return str(e) - os.chmod(self.__filename, 0600) + os.chmod(self.__filename, 0o600) def update_config(self, old_version, new_version): old_version_list = old_version.split('.') # convert '0.x.y' to (0, x, y) diff --git a/src/common/pep.py b/src/common/pep.py index a2cb84c8f..92bc962d7 100644 --- a/src/common/pep.py +++ b/src/common/pep.py @@ -225,8 +225,6 @@ from common import helpers import nbxmpp from common import gajim -import gtkgui_helpers - class AbstractPEP(object): @@ -269,10 +267,6 @@ class AbstractPEP(object): 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 '' @@ -300,13 +294,6 @@ class UserMoodPEP(AbstractPEP): 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'] @@ -346,11 +333,6 @@ class UserTunePEP(AbstractPEP): '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 GdkPixbuf.Pixbuf.new_from_file(path) - def asMarkupText(self): assert not self._retracted tune = self._pep_specific_data @@ -396,24 +378,6 @@ class UserActivityPEP(AbstractPEP): 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: - return gtkgui_helpers.load_activity_icon('unknown').get_pixbuf() - def asMarkupText(self): assert not self._retracted pep = self._pep_specific_data @@ -491,10 +455,6 @@ class UserLocationPEP(AbstractPEP): con = gajim.connections[account].location_info = \ self._pep_specific_data - def asPixbufIcon(self): - path = gtkgui_helpers.get_icon_path('gajim-earth') - return GdkPixbuf.Pixbuf.new_from_file(path) - def asMarkupText(self): assert not self._retracted location = self._pep_specific_data diff --git a/src/common/protocol/bytestream.py b/src/common/protocol/bytestream.py index e2b7e41fb..f46fb4342 100644 --- a/src/common/protocol/bytestream.py +++ b/src/common/protocol/bytestream.py @@ -898,7 +898,7 @@ class ConnectionIBBytestream(ConnectionBytestream): else: if not data: err = nbxmpp.ERR_BAD_REQUEST - elif seq <> file_props.seq: + elif seq != file_props.seq: err = nbxmpp.ERR_UNEXPECTED_REQUEST else: log.debug('Successfull receive sid->%s %s+%s bytes' % (sid, diff --git a/src/common/proxy65_manager.py b/src/common/proxy65_manager.py index ccf20d6c0..38464b578 100644 --- a/src/common/proxy65_manager.py +++ b/src/common/proxy65_manager.py @@ -29,7 +29,7 @@ log = logging.getLogger('gajim.c.proxy65_manager') import nbxmpp from common import gajim from common import helpers -from socks5 import Socks5 +from common.socks5 import Socks5 from nbxmpp.idlequeue import IdleObject from common.file_props import FilesProp diff --git a/src/common/pubsub.py b/src/common/pubsub.py index d2bde78ed..6028088ff 100644 --- a/src/common/pubsub.py +++ b/src/common/pubsub.py @@ -22,11 +22,13 @@ ## import nbxmpp -import gajim -import connection_handlers -import ged -from connection_handlers_events import PubsubReceivedEvent -from connection_handlers_events import PubsubBookmarksReceivedEvent +from common import gajim +#TODO: Doesn't work +#from common.connection_handlers import PEP_CONFIG +PEP_CONFIG = 'pep_config' +from common import ged +from common.connection_handlers_events import PubsubReceivedEvent +from common.connection_handlers_events import PubsubBookmarksReceivedEvent import logging log = logging.getLogger('gajim.c.pubsub') @@ -218,5 +220,5 @@ class ConnectionPubSub: e = e.addChild('configure', {'node': node}) id_ = self.connection.getAnID() query.setID(id_) - self.awaiting_answers[id_] = (connection_handlers.PEP_CONFIG,) + self.awaiting_answers[id_] = (PEP_CONFIG,) self.connection.send(query) diff --git a/src/common/sleepy.py b/src/common/sleepy.py index 14568cb5c..ed5fd2022 100644 --- a/src/common/sleepy.py +++ b/src/common/sleepy.py @@ -22,7 +22,8 @@ ## from common import gajim -import os, sys +import os +import sys STATE_UNKNOWN = 'OS probably not supported' diff --git a/src/common/socks5.py b/src/common/socks5.py index f7dae87a1..725ac73a1 100644 --- a/src/common/socks5.py +++ b/src/common/socks5.py @@ -33,9 +33,9 @@ from errno import EISCONN from errno import EINPROGRESS from errno import EAFNOSUPPORT from nbxmpp.idlequeue import IdleObject -from file_props import FilesProp +from common.file_props import FilesProp from common import gajim -import jingle_xtls +from common import jingle_xtls if jingle_xtls.PYOPENSSL_PRESENT: import OpenSSL import logging @@ -535,7 +535,7 @@ class Socks5: self.file_props.received_len = self.size except IOError as e: self.close_file() - raise IOError, e + raise IOError(str(e)) def close_file(self): if self.file: diff --git a/src/common/stanza_session.py b/src/common/stanza_session.py index 2dc4bf151..2cf146b74 100644 --- a/src/common/stanza_session.py +++ b/src/common/stanza_session.py @@ -45,7 +45,7 @@ if gajim.HAVE_PYCRYPTO: from Crypto.PublicKey import RSA from common import dh - import secrets + from . import secrets XmlDsig = 'http://www.w3.org/2000/09/xmldsig#' diff --git a/src/common/zeroconf/connection_zeroconf.py b/src/common/zeroconf/connection_zeroconf.py index 0f2319517..c3c5beaf9 100644 --- a/src/common/zeroconf/connection_zeroconf.py +++ b/src/common/zeroconf/connection_zeroconf.py @@ -46,7 +46,7 @@ from common import gajim from common import ged from common.zeroconf import client_zeroconf from common.zeroconf import zeroconf -from connection_handlers_zeroconf import * +from common.zeroconf.connection_handlers_zeroconf import * from common.connection_handlers_events import * import locale diff --git a/src/common/zeroconf/zeroconf_avahi.py b/src/common/zeroconf/zeroconf_avahi.py index acfa85885..73f091928 100644 --- a/src/common/zeroconf/zeroconf_avahi.py +++ b/src/common/zeroconf/zeroconf_avahi.py @@ -239,7 +239,7 @@ class Zeroconf: txt = {} # remove empty keys - for key, val in self.txt.iteritems(): + for key, val in self.txt.items(): if val: txt[key] = val diff --git a/src/config.py b/src/config.py index 9c748e58c..b5cbff3a8 100644 --- a/src/config.py +++ b/src/config.py @@ -455,8 +455,8 @@ class PreferencesWindow: else: config = gajim.config.get(opt_name + '_device') - for index, (name, value) in enumerate(sorted(device_dict.\ - iteritems(), key=key)): + for index, (name, value) in enumerate(sorted(device_dict.items(), + key=key)): model.append((name, value)) if config == value: combobox.set_active(index) diff --git a/src/conversation_textview.py b/src/conversation_textview.py index 2fbb89567..e1f308961 100644 --- a/src/conversation_textview.py +++ b/src/conversation_textview.py @@ -38,7 +38,7 @@ import os import tooltips import dialogs import locale -import Queue +import queue import urllib import gtkgui_helpers @@ -335,7 +335,7 @@ class ConversationTextview(GObject.GObject): # One mark at the begining then 2 marks between each lines size = gajim.config.get('max_conversation_lines') size = 2 * size - 1 - self.marks_queue = Queue.Queue(size) + self.marks_queue = queue.Queue(size) self.allow_focus_out_line = True # holds a mark at the end of --- line @@ -709,7 +709,7 @@ class ConversationTextview(GObject.GObject): buffer_.delete(start, end) size = gajim.config.get('max_conversation_lines') size = 2 * size - 1 - self.marks_queue = Queue.Queue(size) + self.marks_queue = queue.Queue(size) self.focus_out_end_mark = None self.just_cleared = True @@ -1171,7 +1171,7 @@ class ConversationTextview(GObject.GObject): all_tags = [(ttt.lookup(t) if isinstance(t, str) else t) for t in all_tags] buffer_.insert_with_tags(end_iter, special_text, *all_tags) if 'url' in tags: - puny_text = puny_encode(special_text) + puny_text = puny_encode(special_text).decode('utf-8') if not puny_text.endswith('-'): end_iter = buffer_.get_end_iter() buffer_.insert(end_iter, " (%s)" % puny_text) diff --git a/src/dialogs.py b/src/dialogs.py index f8f3402ce..e2b541daa 100644 --- a/src/dialogs.py +++ b/src/dialogs.py @@ -1297,13 +1297,12 @@ class AboutDialog: if thanks_file_path: authors.append('\n' + _('THANKS:')) - text = helpers.ensure_utf8_string(open(thanks_file_path).read()) + text = open(thanks_file_path).read() text_splitted = text.split('\n') text = '\n'.join(text_splitted[:-2]) # remove one english sentence # and add it manually as translatable - text += helpers.ensure_utf8_string('\n%s\n' % _('Last but not ' - 'least, we would like to thank all the package maintainers.' - )) + text += '\n%s\n' % _('Last but not least, we would like to ' + 'thank all the package maintainers.') authors.append(text) dlg.set_authors(authors) @@ -2322,13 +2321,13 @@ class JoinGroupchatWindow: if room_jid != '' and room_jid in gajim.gc_connected[account] and\ gajim.gc_connected[account][room_jid]: ErrorDialog(_('You are already in group chat %s') % room_jid) - raise GajimGeneralException, 'You are already in this group chat' + raise GajimGeneralException('You are already in this group chat') if nick == '': nick = gajim.nicks[account] if gajim.connections[account].connected < 2: ErrorDialog(_('You are not connected to the server'), _('You can not join a group chat unless you are connected.')) - raise GajimGeneralException, 'You must be connected to join a groupchat' + raise GajimGeneralException('You must be connected to join a groupchat') self.xml = gtkgui_helpers.get_gtk_builder('join_groupchat_window.ui') @@ -2565,7 +2564,7 @@ class SynchroniseSelectAccountDialog: if not account or gajim.connections[account].connected < 2: ErrorDialog(_('You are not connected to the server'), _('Without a connection, you can not synchronise your contacts.')) - raise GajimGeneralException, 'You are not connected to the server' + raise GajimGeneralException('You are not connected to the server') self.account = account self.xml = gtkgui_helpers.get_gtk_builder('synchronise_select_account_dialog.ui') self.dialog = self.xml.get_object('synchronise_select_account_dialog') @@ -2754,7 +2753,7 @@ class ChangePasswordDialog: if not account or gajim.connections[account].connected < 2: ErrorDialog(_('You are not connected to the server'), _('Without a connection, you can not change your password.')) - raise GajimGeneralException, 'You are not connected to the server' + raise GajimGeneralException('You are not connected to the server') self.account = account self.on_response = on_response self.xml = gtkgui_helpers.get_gtk_builder('change_password_dialog.ui') diff --git a/src/disco.py b/src/disco.py index 84e19f18c..12be18b34 100644 --- a/src/disco.py +++ b/src/disco.py @@ -223,7 +223,7 @@ class Closure(object): self.removeargs = removeargs if isinstance(cb, types.MethodType): self.meth_self = weakref.ref(cb.im_self, self._remove) - self.meth_name = cb.func_name + self.meth_name = cb.__name__ elif callable(cb): self.meth_self = None self.cb = weakref.ref(cb, self._remove) @@ -515,7 +515,7 @@ class ServiceDiscoveryWindow(object): if gajim.connections[account].connected < 2: dialogs.ErrorDialog(_('You are not connected to the server'), _('Without a connection, you can not browse available services')) - raise RuntimeError, 'You must be connected to browse services' + raise RuntimeError('You must be connected to browse services') # Get a ServicesCache object. try: diff --git a/src/gajim.py b/src/gajim.py index babf2e567..be2a01d00 100644 --- a/src/gajim.py +++ b/src/gajim.py @@ -219,6 +219,10 @@ except exceptions.DatabaseMalformed: 'http://trac.gajim.org/wiki/DatabaseBackup) or remove it (all history ' 'will be lost).') % common.logger.LOG_DB_PATH else: + from common import logger + gajim.logger = logger.Logger() + from common import caps_cache + caps_cache.initialize(gajim.logger) from common import dbus_support if dbus_support.supported: from music_track_listener import MusicTrackListener diff --git a/src/gtkexcepthook.py b/src/gtkexcepthook.py index 9ba17ba29..4ca60d8e3 100644 --- a/src/gtkexcepthook.py +++ b/src/gtkexcepthook.py @@ -29,9 +29,9 @@ from gi.repository import Gtk from gi.repository import Gdk from gi.repository import Pango from common import i18n # installs _() function -import dialogs +from dialogs import HigDialog -from cStringIO import StringIO +from io import StringIO from common import helpers _exception_in_progress = threading.Lock() @@ -43,7 +43,7 @@ def _info(type_, value, tb): _excepthook_save(type_, value, tb) return - dialog = dialogs.HigDialog(None, Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE, + dialog = HigDialog(None, Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE, _('A programming error has been detected'), _('It probably is not fatal, but should be reported ' 'to the developers nonetheless.')) diff --git a/src/gtkgui_helpers.py b/src/gtkgui_helpers.py index 824355cf0..7fdb46a78 100644 --- a/src/gtkgui_helpers.py +++ b/src/gtkgui_helpers.py @@ -41,6 +41,7 @@ log = logging.getLogger('gajim.gtkgui_helpers') from common import i18n from common import gajim +from common import pep gtk_icon_theme = Gtk.IconTheme.get_default() gtk_icon_theme.append_search_path(gajim.ICONS_DIR) @@ -384,7 +385,7 @@ def get_abspath_for_script(scriptname, want_type = False): script += '\nexec python -OOt gajim.py $0 $@\n' f.write(script) f.close() - os.chmod(path_to_script, 0700) + os.chmod(path_to_script, 0o700) except OSError: # do not traceback (could be a permission problem) #we talk about a file here s = _('Could not write to %s. Session Management support will ' @@ -607,7 +608,7 @@ def get_avatar_pixbuf_from_cache(fjid, use_local=True): if not os.path.isfile(path): return 'ask' - vcard_dict = gajim.connections.values()[0].get_cached_vcard(fjid, + vcard_dict = list(gajim.connections.values())[0].get_cached_vcard(fjid, is_groupchat_contact) if not vcard_dict: # This can happen if cached vcard is too old return 'ask' @@ -645,28 +646,6 @@ def make_pixbuf_grayscale(pixbuf): pixbuf.saturate_and_pixelate(pixbuf2, 0.0, False) return pixbuf2 -def get_path_to_generic_or_avatar(generic, jid = None, suffix = None): - """ - Choose between avatar image and default image - - Returns full path to the avatar image if it exists, otherwise returns full - path to the image. generic must be with extension and suffix without - """ - if jid: - # we want an avatar - puny_jid = helpers.sanitize_filename(jid) - path_to_file = os.path.join(gajim.AVATAR_PATH, puny_jid) + suffix - path_to_local_file = path_to_file + '_local' - for extension in ('.png', '.jpeg'): - path_to_local_file_full = path_to_local_file + extension - if os.path.exists(path_to_local_file_full): - return path_to_local_file_full - for extension in ('.png', '.jpeg'): - path_to_file_full = path_to_file + extension - if os.path.exists(path_to_file_full): - return path_to_file_full - return os.path.abspath(generic) - def decode_filechooser_file_paths(file_paths): """ Decode as UTF-8 under Windows and ask sys.getfilesystemencoding() in POSIX @@ -974,6 +953,38 @@ def load_activity_icon(category, activity = None): icon_list = _load_icon_list([activity], path) return icon_list[activity] +def get_pep_as_pixbuf(pep_class): + if isinstance(pep_class, pep.UserMoodPEP): + assert not pep_class._retracted + received_mood = pep_class._pep_specific_data['mood'] + mood = received_mood if received_mood in pep.MOODS else 'unknown' + pixbuf = load_mood_icon(mood).get_pixbuf() + return pixbuf + elif isinstance(pep_class, pep.UserTunePEP): + path = os.path.join(gajim.DATA_DIR, 'emoticons', 'static', 'music.png') + return GdkPixbuf.Pixbuf.new_from_file(path) + elif isinstance(pep_class, pep.UserActivityPEP): + assert not pep_class._retracted + pep_ = pep_class._pep_specific_data + activity = pep_['activity'] + + has_known_activity = activity in pep.ACTIVITIES + has_known_subactivity = (has_known_activity and ('subactivity' in pep_) + and (pep_['subactivity'] in pep.ACTIVITIES[activity])) + + if has_known_activity: + if has_known_subactivity: + subactivity = pep_['subactivity'] + return load_activity_icon(activity, subactivity).get_pixbuf() + else: + return load_activity_icon(activity).get_pixbuf() + else: + return load_activity_icon('unknown').get_pixbuf() + elif isinstance(pep_class, pep.UserLocationPEP): + path = get_icon_path('gajim-earth') + return GdkPixbuf.Pixbuf.new_from_file(path) + return None + def load_icons_meta(): """ Load and return - AND + small icons to put on top left of an icon for meta diff --git a/src/gui_interface.py b/src/gui_interface.py index ae4b8dbaf..401fabdcf 100644 --- a/src/gui_interface.py +++ b/src/gui_interface.py @@ -68,7 +68,7 @@ from groupchat_control import PrivateChatControl from atom_window import AtomWindow from session import ChatControlSession -import common.sleepy +from common import sleepy from nbxmpp import idlequeue from nbxmpp import Hashes @@ -93,7 +93,7 @@ import config from threading import Thread from common import ged -gajimpaths = common.configpaths.gajimpaths +from common.configpaths import gajimpaths config_filename = gajimpaths['CONFIG_FILE'] from common import optparser @@ -1111,11 +1111,11 @@ class Interface: # Ask offline status in 1 minute so w'are sure we got all online # presences GObject.timeout_add_seconds(60, self.ask_offline_status, account) - if state != common.sleepy.STATE_UNKNOWN and connected in (2, 3): + if state != sleepy.STATE_UNKNOWN and connected in (2, 3): # we go online or free for chat, so we activate auto status gajim.sleeper_state[account] = 'online' - elif not ((state == common.sleepy.STATE_AWAY and connected == 4) or \ - (state == common.sleepy.STATE_XA and connected == 5)): + elif not ((state == sleepy.STATE_AWAY and connected == 4) or \ + (state == sleepy.STATE_XA and connected == 5)): # If we are autoaway/xa and come back after a disconnection, do # nothing # Else disable autoaway @@ -1568,7 +1568,7 @@ class Interface: This is part of rewriting whole events handling system to use GED. """ - for event_name, event_handlers in self.handlers.iteritems(): + for event_name, event_handlers in self.handlers.items(): for event_handler in event_handlers: prio = ged.GUI1 if type(event_handler) == tuple: @@ -2341,14 +2341,14 @@ class Interface: if account not in gajim.sleeper_state or \ not gajim.sleeper_state[account]: continue - if state == common.sleepy.STATE_AWAKE and \ + if state == sleepy.STATE_AWAKE and \ gajim.sleeper_state[account] in ('autoaway', 'autoxa'): # we go online self.roster.send_status(account, 'online', gajim.status_before_autoaway[account]) gajim.status_before_autoaway[account] = '' gajim.sleeper_state[account] = 'online' - elif state == common.sleepy.STATE_AWAY and \ + elif state == sleepy.STATE_AWAY and \ gajim.sleeper_state[account] == 'online' and \ gajim.config.get('autoaway'): # we save out online status @@ -2368,7 +2368,7 @@ class Interface: self.roster.send_status(account, 'away', auto_message, auto=True) gajim.sleeper_state[account] = 'autoaway' - elif state == common.sleepy.STATE_XA and \ + elif state == sleepy.STATE_XA and \ gajim.sleeper_state[account] in ('online', 'autoaway', 'autoaway-forced') and gajim.config.get('autoxa'): # we go extended away [we pass True to auto param] @@ -2912,7 +2912,7 @@ class Interface: self.show_vcard_when_connect = [] - self.sleeper = common.sleepy.Sleepy( + self.sleeper = sleepy.Sleepy( gajim.config.get('autoawaytime') * 60, # make minutes to seconds gajim.config.get('autoxatime') * 60) diff --git a/src/htmltextview.py b/src/htmltextview.py index a34373dd5..84e7205a5 100644 --- a/src/htmltextview.py +++ b/src/htmltextview.py @@ -42,8 +42,8 @@ from gi.repository import Gdk from gi.repository import GdkPixbuf import xml.sax, xml.sax.handler import re -from cStringIO import StringIO -import urllib2 +from io import StringIO +import urllib import operator if __name__ == '__main__': @@ -491,9 +491,10 @@ class HtmlHandler(xml.sax.handler.ContentHandler): tag.title = title return tag - def _update_img(self, (mem, alt), attrs, img_mark): + def _update_img(self, output, attrs, img_mark): '''Callback function called after the function helpers.download_image. ''' + mem, alt = output self._process_img(attrs, (mem, alt, img_mark)) def _process_img(self, attrs, loaded=None): @@ -509,7 +510,7 @@ class HtmlHandler(xml.sax.handler.ContentHandler): # The "data" URL scheme http://tools.ietf.org/html/rfc2397 import base64 img = attrs['src'].split(',')[1] - mem = base64.standard_b64decode(urllib2.unquote(img)) + mem = base64.standard_b64decode(urllib.parse.unquote(img)) elif loaded is not None: (mem, alt, replace_mark) = loaded update = True diff --git a/src/notify.py b/src/notify.py index a9ca09216..6979235dd 100644 --- a/src/notify.py +++ b/src/notify.py @@ -156,6 +156,9 @@ class Notification: def _nec_notification(self, obj): if obj.do_popup: + if isinstance(obj.popup_image, str): + obj.popup_image = gtkgui_helpers.get_icon_path(obj.popup_image, + 48) popup(obj.popup_event_type, obj.jid, obj.conn.name, obj.popup_msg_type, path_to_image=obj.popup_image, title=obj.popup_title, text=obj.popup_text, diff --git a/src/plugins/__init__.py b/src/plugins/__init__.py index 0d5d18fda..07b0b6c56 100644 --- a/src/plugins/__init__.py +++ b/src/plugins/__init__.py @@ -24,7 +24,7 @@ Main file of plugins package. :license: GPL ''' -from pluginmanager import PluginManager -from plugin import GajimPlugin +from .pluginmanager import PluginManager +from .plugin import GajimPlugin __all__ = ['PluginManager', 'GajimPlugin'] diff --git a/src/plugins/helpers.py b/src/plugins/helpers.py index 18c747527..b37076a87 100644 --- a/src/plugins/helpers.py +++ b/src/plugins/helpers.py @@ -97,7 +97,7 @@ class log_calls(object): :rtype: function ''' - self.full_func_name += f.func_name + self.full_func_name += f.__name__ if self.log_this_class: @functools.wraps(f) def wrapper(*args, **kwargs): diff --git a/src/plugins/plugin.py b/src/plugins/plugin.py index 49de73cf0..b3a54a1cf 100644 --- a/src/plugins/plugin.py +++ b/src/plugins/plugin.py @@ -196,7 +196,7 @@ class GajimPlugin(object): def deactivate(self): pass -import cPickle +import pickle class GajimPluginConfig(): @log_calls('GajimPluginConfig') @@ -242,7 +242,7 @@ class GajimPluginConfig(): @log_calls('GajimPluginConfig') def save(self): fd = open(self.FILE_PATH, 'wb') - cPickle.dump(self.data, fd) + pickle.dump(self.data, fd) fd.close() @log_calls('GajimPluginConfig') @@ -250,14 +250,14 @@ class GajimPluginConfig(): if os.path.isfile(self.FILE_PATH): fd = open(self.FILE_PATH, 'rb') try: - self.data = cPickle.load(fd) + self.data = pickle.load(fd) fd.close() except: fd.close() try: import shelve s = shelve.open(self.FILE_PATH) - for (k, v) in s.iteritems(): + for (k, v) in s.items(): self.data[k] = v if not isinstance(self.data, dict): raise GajimPluginException diff --git a/src/plugins/pluginmanager.py b/src/plugins/pluginmanager.py index 4e7de9de2..71c0c2e61 100644 --- a/src/plugins/pluginmanager.py +++ b/src/plugins/pluginmanager.py @@ -31,7 +31,7 @@ import sys import fnmatch import zipfile from shutil import rmtree -import ConfigParser +import configparser from common import gajim from common import nec @@ -258,14 +258,14 @@ class PluginManager(object): handlers[0](*args) def _register_events_handlers_in_ged(self, plugin): - for event_name, handler in plugin.events_handlers.iteritems(): + for event_name, handler in plugin.events_handlers.items(): priority = handler[0] handler_function = handler[1] gajim.ged.register_event_handler(event_name, priority, handler_function) def _remove_events_handler_from_ged(self, plugin): - for event_name, handler in plugin.events_handlers.iteritems(): + for event_name, handler in plugin.events_handlers.items(): priority = handler[0] handler_function = handler[1] gajim.ged.remove_event_handler(event_name, priority, @@ -312,7 +312,7 @@ class PluginManager(object): # remove GUI extension points handlers (provided by plug-in) from # handlers list for gui_extpoint_name, gui_extpoint_handlers in \ - plugin.gui_extension_points.iteritems(): + plugin.gui_extension_points.items(): self.gui_extension_points_handlers[gui_extpoint_name].remove( gui_extpoint_handlers) @@ -320,7 +320,7 @@ class PluginManager(object): # cleaning up method that must be provided by plug-in developer # for each handled GUI extension point) for gui_extpoint_name, gui_extpoint_handlers in \ - plugin.gui_extension_points.iteritems(): + plugin.gui_extension_points.items(): if gui_extpoint_name in self.gui_extension_points: for gui_extension_point_args in self.gui_extension_points[ gui_extpoint_name]: @@ -344,14 +344,14 @@ class PluginManager(object): @log_calls('PluginManager') def _add_gui_extension_points_handlers_from_plugin(self, plugin): for gui_extpoint_name, gui_extpoint_handlers in \ - plugin.gui_extension_points.iteritems(): + plugin.gui_extension_points.items(): self.gui_extension_points_handlers.setdefault(gui_extpoint_name, []).append(gui_extpoint_handlers) @log_calls('PluginManager') def _handle_all_gui_extension_points_with_plugin(self, plugin): for gui_extpoint_name, gui_extpoint_handlers in \ - plugin.gui_extension_points.iteritems(): + plugin.gui_extension_points.items(): if gui_extpoint_name in self.gui_extension_points: for gui_extension_point_args in self.gui_extension_points[ gui_extpoint_name]: @@ -407,7 +407,7 @@ class PluginManager(object): ''' from plugins.plugins_i18n import _ plugins_found = [] - conf = ConfigParser.ConfigParser() + conf = configparser.ConfigParser() fields = ('name', 'short_name', 'version', 'description', 'authors', 'homepage') if not os.path.isdir(path): @@ -471,7 +471,7 @@ class PluginManager(object): conf.readfp(open(manifest_path, 'r')) for option in fields: if conf.get('info', option) is '': - raise ConfigParser.NoOptionError, 'field empty' + raise configparser.NoOptionError('field empty') setattr(module_attr, option, conf.get('info', option)) conf.remove_section('info') @@ -483,15 +483,15 @@ class PluginManager(object): module_attr._ = _ except AttributeError as type_error: pass - except ConfigParser.NoOptionError as type_error: + except configparser.NoOptionError as type_error: # all fields are required log.debug('%s : %s' % (module_attr_name, 'wrong manifest file. all fields are required!')) - except ConfigParser.NoSectionError as type_error: + except configparser.NoSectionError as type_error: # info section are required log.debug('%s : %s' % (module_attr_name, 'wrong manifest file. info section are required!')) - except ConfigParser.MissingSectionHeaderError as type_error: + except configparser.MissingSectionHeaderError as type_error: # info section are required log.debug('%s : %s' % (module_attr_name, 'wrong manifest file. section are required!')) diff --git a/src/remote_control.py b/src/remote_control.py index b2a193d32..60f22b7b1 100644 --- a/src/remote_control.py +++ b/src/remote_control.py @@ -619,7 +619,7 @@ class SignalObject(dbus.service.Object): raise dbus_support.MissingArgument() jid = self._get_real_jid(jid) - cached_vcard = gajim.connections.values()[0].get_cached_vcard(jid) + cached_vcard = list(gajim.connections.values())[0].get_cached_vcard(jid) if cached_vcard: return get_dbus_struct(cached_vcard) diff --git a/src/roster_window.py b/src/roster_window.py index f842027bd..990df3cf5 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -1062,28 +1062,28 @@ class RosterWindow: pep_dict = gajim.connections[account].pep if gajim.config.get('show_mood_in_roster') and 'mood' in pep_dict: - self.model[child_iter][C_MOOD_PIXBUF] = pep_dict['mood'].\ - asPixbufIcon() + self.model[child_iter][C_MOOD_PIXBUF] = \ + gtkgui_helpers.get_pep_as_pixbuf(pep_dict['mood']) else: self.model[child_iter][C_MOOD_PIXBUF] = empty_pixbuf if gajim.config.get('show_activity_in_roster') and 'activity' in \ pep_dict: - self.model[child_iter][C_ACTIVITY_PIXBUF] = pep_dict['activity'].\ - asPixbufIcon() + self.model[child_iter][C_ACTIVITY_PIXBUF] = \ + gtkgui_helpers.get_pep_as_pixbuf(pep_dict['activity']) else: self.model[child_iter][C_ACTIVITY_PIXBUF] = empty_pixbuf if gajim.config.get('show_tunes_in_roster') and 'tune' in pep_dict: - self.model[child_iter][C_TUNE_PIXBUF] = pep_dict['tune'].\ - asPixbufIcon() + self.model[child_iter][C_TUNE_PIXBUF] = \ + gtkgui_helpers.get_pep_as_pixbuf(pep_dict['tune']) else: self.model[child_iter][C_TUNE_PIXBUF] = empty_pixbuf if gajim.config.get('show_location_in_roster') and 'location' in \ pep_dict: - self.model[child_iter][C_LOCATION_PIXBUF] = pep_dict['location'].\ - asPixbufIcon() + self.model[child_iter][C_LOCATION_PIXBUF] = \ + gtkgui_helpers.get_pep_as_pixbuf(pep_dict['location']) else: self.model[child_iter][C_LOCATION_PIXBUF] = empty_pixbuf @@ -1340,7 +1340,7 @@ class RosterWindow: if not contact: contact = gajim.contacts.get_contact(account, jid) if pep_type in contact.pep: - pixbuf = contact.pep[pep_type].asPixbufIcon() + pixbuf = gtkgui_helpers.get_pep_as_pixbuf(contact.pep[pep_type]) else: pixbuf = empty_pixbuf for child_iter in iters: diff --git a/src/tooltips.py b/src/tooltips.py index 9e09e33e5..6fe799a89 100644 --- a/src/tooltips.py +++ b/src/tooltips.py @@ -637,9 +637,9 @@ class RosterTooltip(NotificationAreaTooltip): 'tooltip_idle_color') cs += '%s' properties.append((str(), None)) - idle_since = helpers.ensure_utf8_string(cs % _("Idle since %s")) + idle_since = cs % _("Idle since %s") properties.append((idle_since % formatted, None)) - idle_for = helpers.ensure_utf8_string(cs % _("Idle for %s")) + idle_for = cs % _("Idle for %s") properties.append((idle_for % str(diff), None)) while properties: diff --git a/test/lib/mock.py b/test/lib/mock.py index fdaf000db..e2a2b6c03 100644 --- a/test/lib/mock.py +++ b/test/lib/mock.py @@ -212,7 +212,7 @@ class MockCall: elif isinstance(n, str): return self.kwparams[n] else: - raise IndexError, 'illegal index type for getParam' + raise IndexError('illegal index type for getParam') def getNumParams(self): return len(self.params) diff --git a/test/unit/test_jingle.py b/test/unit/test_jingle.py index 438bdb2e0..ce9edeb66 100644 --- a/test/unit/test_jingle.py +++ b/test/unit/test_jingle.py @@ -135,8 +135,8 @@ class TestJingle(unittest.TestCase): self.dispatcher.RegisterHandler('iq', self.con._JingleCB, 'set' , common.xmpp.NS_JINGLE) self.dispatcher.ProcessNonBlocking(session_init) - session = self.con._sessions.values()[0] # The only session we have - jft = session.contents.values()[0] # jingleFT object + session = list(self.con._sessions.values())[0] # The only session we have + jft = list(session.contents.values())[0] # jingleFT object jft.file_props = self.recieve_file # We plug file_props manually # The user accepts to recieve the file # we have to manually simulate this behavior