From d395bd510fa4f4376dc5237ab2f8d190a920d35d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 19 Feb 2023 16:05:49 +0100 Subject: Adding upstream version 2.1.1. Signed-off-by: Daniel Baumann --- deluge/ui/gtk3/common.py | 128 +++++++++++++++++++++++++++++++---------------- 1 file changed, 84 insertions(+), 44 deletions(-) (limited to 'deluge/ui/gtk3/common.py') diff --git a/deluge/ui/gtk3/common.py b/deluge/ui/gtk3/common.py index 8359327..42a14b4 100644 --- a/deluge/ui/gtk3/common.py +++ b/deluge/ui/gtk3/common.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # Copyright (C) 2008 Marcos Mobley ('markybob') # @@ -7,16 +6,14 @@ # See LICENSE for more details. # """Common functions for various parts of gtkui to use.""" -from __future__ import unicode_literals - import contextlib import logging import os +import pickle import shutil import sys -import six.moves.cPickle as pickle # noqa: N813 -from gi.repository.Gdk import SELECTION_CLIPBOARD, Display +from gi.repository.Gdk import SELECTION_CLIPBOARD, SELECTION_PRIMARY, Display from gi.repository.GdkPixbuf import Colorspace, Pixbuf from gi.repository.GLib import GError from gi.repository.Gtk import ( @@ -29,7 +26,7 @@ from gi.repository.Gtk import ( SortType, ) -from deluge.common import PY2, get_pixmap, osx_check, windows_check +from deluge.common import get_pixmap, is_ip, osx_check, windows_check log = logging.getLogger(__name__) @@ -42,7 +39,18 @@ def cmp(x, y): and strictly positive if x > y. """ - return (x > y) - (x < y) + try: + return (x > y) - (x < y) + except TypeError: + # Handle NoneType comparison + if x is None: + if y is None: + return 0 + return -1 + elif y is None: + return 1 + else: + raise def create_blank_pixbuf(size=16): @@ -51,12 +59,36 @@ def create_blank_pixbuf(size=16): return pix -def get_pixbuf(filename): +def get_pixbuf(filename: str, size: int = 0) -> Pixbuf: + """Creates a new pixbuf by loading an image from file + + Args: + filename: An image file to load + size: Specify a size constraint (equal aspect ratio) + + Returns: + A newly created pixbuf + + """ + # Skip ico and gif that cause Pixbuf crash on Windows + # https://dev.deluge-torrent.org/ticket/3501 + if windows_check() and filename.endswith(('.ico', '.gif')): + return create_blank_pixbuf(size) + + if not os.path.isabs(filename): + filename = get_pixmap(filename) + + pixbuf = None try: - return Pixbuf.new_from_file(get_pixmap(filename)) + if size: + pixbuf = Pixbuf.new_from_file_at_size(filename, size, size) + else: + pixbuf = Pixbuf.new_from_file(filename) except GError as ex: + # Failed to load the pixbuf (Bad image file), so return a blank pixbuf. log.warning(ex) - return create_blank_pixbuf() + + return pixbuf or create_blank_pixbuf(size or 16) # Status icons.. Create them from file only once to avoid constantly re-creating them. @@ -68,17 +100,6 @@ icon_queued = get_pixbuf('queued16.png') icon_checking = get_pixbuf('checking16.png') -def get_pixbuf_at_size(filename, size): - if not os.path.isabs(filename): - filename = get_pixmap(filename) - try: - return Pixbuf.new_from_file_at_size(filename, size, size) - except GError as ex: - # Failed to load the pixbuf (Bad image file), so return a blank pixbuf. - log.warning(ex) - return create_blank_pixbuf(size) - - def get_logo(size): """A Deluge logo. @@ -91,7 +112,7 @@ def get_logo(size): filename = 'deluge.svg' if windows_check(): filename = 'deluge.png' - return get_pixbuf_at_size(filename, size) + return get_pixbuf(filename, size) def build_menu_radio_list( @@ -221,14 +242,11 @@ def associate_magnet_links(overwrite=False): """ if windows_check(): - try: - import winreg - except ImportError: - import _winreg as winreg # For Python 2. + import winreg try: hkey = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, 'Magnet') - except WindowsError: + except OSError: overwrite = True else: winreg.CloseKey(hkey) @@ -237,7 +255,7 @@ def associate_magnet_links(overwrite=False): deluge_exe = os.path.join(os.path.dirname(sys.executable), 'deluge.exe') try: magnet_key = winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, 'Magnet') - except WindowsError: + except OSError: # Could not create for all users, falling back to current user magnet_key = winreg.CreateKey( winreg.HKEY_CURRENT_USER, 'Software\\Classes\\Magnet' @@ -246,14 +264,12 @@ def associate_magnet_links(overwrite=False): winreg.SetValue(magnet_key, '', winreg.REG_SZ, 'URL:Magnet Protocol') winreg.SetValueEx(magnet_key, 'URL Protocol', 0, winreg.REG_SZ, '') winreg.SetValueEx(magnet_key, 'BrowserFlags', 0, winreg.REG_DWORD, 0x8) - winreg.SetValue( - magnet_key, 'DefaultIcon', winreg.REG_SZ, '{},0'.format(deluge_exe) - ) + winreg.SetValue(magnet_key, 'DefaultIcon', winreg.REG_SZ, f'{deluge_exe},0') winreg.SetValue( magnet_key, r'shell\open\command', winreg.REG_SZ, - '"{}" "%1"'.format(deluge_exe), + f'"{deluge_exe}" "%1"', ) winreg.CloseKey(magnet_key) @@ -267,7 +283,7 @@ def associate_magnet_links(overwrite=False): from gi.repository import GConf except ValueError: log.debug( - 'gconf not available, so will not attempt to register magnet uri handler' + 'gconf not available, so will not attempt to register magnet URI handler' ) return False else: @@ -282,11 +298,11 @@ def associate_magnet_links(overwrite=False): gconf_client.set_bool( '/desktop/gnome/url-handlers/magnet/enabled', True ) - log.info('Deluge registered as default magnet uri handler!') + log.info('Deluge registered as default magnet URI handler!') return True else: log.error( - 'Unable to register Deluge as default magnet uri handler.' + 'Unable to register Deluge as default magnet URI handler.' ) return False return False @@ -309,7 +325,7 @@ def save_pickled_state_file(filename, state): if os.path.isfile(filepath): log.debug('Creating backup of %s at: %s', filename, filepath_bak) shutil.copy2(filepath, filepath_bak) - except IOError as ex: + except OSError as ex: log.error('Unable to backup %s to %s: %s', filepath, filepath_bak, ex) else: log.info('Saving the %s at: %s', filename, filepath) @@ -320,7 +336,7 @@ def save_pickled_state_file(filename, state): _file.flush() os.fsync(_file.fileno()) shutil.move(filepath_tmp, filepath) - except (IOError, EOFError, pickle.PicklingError) as ex: + except (OSError, EOFError, pickle.PicklingError) as ex: log.error('Unable to save %s: %s', filename, ex) if os.path.isfile(filepath_bak): log.info('Restoring backup of %s from: %s', filename, filepath_bak) @@ -345,11 +361,8 @@ def load_pickled_state_file(filename): log.info('Opening %s for load: %s', filename, _filepath) try: with open(_filepath, 'rb') as _file: - if PY2: - state = pickle.load(_file) - else: - state = pickle.load(_file, encoding='utf8') - except (IOError, pickle.UnpicklingError) as ex: + state = pickle.load(_file, encoding='utf8') + except (OSError, pickle.UnpicklingError) as ex: log.warning('Unable to load %s: %s', _filepath, ex) else: log.info('Successfully loaded %s: %s', filename, _filepath) @@ -384,8 +397,8 @@ def listview_replace_treestore(listview): def get_clipboard_text(): text = ( - Clipboard.get(selection=SELECTION_CLIPBOARD).wait_for_text() - or Clipboard.get().wait_for_text() + Clipboard.get(SELECTION_CLIPBOARD).wait_for_text() + or Clipboard.get(SELECTION_PRIMARY).wait_for_text() ) if text: return text.strip() @@ -393,3 +406,30 @@ def get_clipboard_text(): def windowing(like): return like.lower() in str(type(Display.get_default())).lower() + + +def parse_ip_port(text): + """Return an IP and port from text. + + Parses both IPv4 and IPv6. + + Params: + text (str): Text to be parsed for IP and port. + + Returns: + tuple: (ip (str), port (int)) + + """ + if '.' in text: + # ipv4 + ip, __, port = text.rpartition(':') + elif '[' in text: + # ipv6 + ip, __, port = text.partition('[')[2].partition(']:') + else: + return None, None + + if ip and is_ip(ip) and port.isdigit(): + return ip, int(port) + else: + return None, None -- cgit v1.2.3