From 6df6a6b557d9bc4085d3f79b808fecad2cb1e9ef Mon Sep 17 00:00:00 2001 From: Mladen Mijatov Date: Wed, 9 Jan 2019 18:27:04 +0100 Subject: [PATCH] Common: Renamed functions. --- sunflower/associations.py | 16 +++++----- sunflower/common.py | 37 ++++++++++-------------- sunflower/emblems.py | 4 +-- sunflower/gui/input_dialog.py | 9 +++--- sunflower/gui/main_window.py | 2 +- sunflower/gui/properties_window.py | 3 +- sunflower/plugin_base/item_list.py | 2 +- sunflower/plugins/file_list/file_list.py | 13 +++++---- sunflower/tools/viewer.py | 4 +-- sunflower/widgets/breadcrumbs.py | 4 +-- sunflower/widgets/title_bar.py | 4 +-- 11 files changed, 47 insertions(+), 51 deletions(-) diff --git a/sunflower/associations.py b/sunflower/associations.py index 477fa384c..ee475296b 100644 --- a/sunflower/associations.py +++ b/sunflower/associations.py @@ -12,7 +12,7 @@ from gi.repository import Gtk, Gio from collections import namedtuple from urllib.request import pathname2url -from sunflower.common import is_x_app, disp_fn, encode_fn +from sunflower.common import is_gui_app, decode_file_name, encode_file_name from sunflower.parameters import Parameters from sunflower.plugin_base.provider import Mode from sunflower.plugin_base.terminal import TerminalType @@ -118,7 +118,7 @@ def get_mime_type(self, path=None, data=None): # detect content type based on file name # due to a bug in the GI bindings of GIO, we can't pass non-UTF-8 # file names in here. In this case, that probably doesn't matter. - path = disp_fn(path) + path = decode_file_name(path) result = Gio.content_type_guess(filename=path)[0] elif data is not None: @@ -220,12 +220,12 @@ def open_file(self, selection, application_info=None, exec_command=None): if application is not None: if application.supports_uris(): selection = [ - 'file://{0}'.format(pathname2url(encode_fn(path))) - if not path.startswith('file://') else encode_fn(path) + 'file://{0}'.format(pathname2url(encode_file_name(path))) + if not path.startswith('file://') else encode_file_name(path) for path in selection] application.launch_uris(selection) else: - application.launch([Gio.File.new_for_path(encode_fn(path)) for path in selection]) + application.launch([Gio.File.new_for_path(encode_file_name(path)) for path in selection]) elif exec_command is not None: # use specified command @@ -238,7 +238,7 @@ def open_file(self, selection, application_info=None, exec_command=None): split_command = shlex.split(exec_string, posix=False) test_command = split_command[0] if len(split_command) > 1 else exec_string - if is_x_app(test_command): + if is_gui_app(test_command): subprocess.Popen(split_command, cwd=os.path.dirname(selection[0])) else: @@ -264,7 +264,7 @@ def edit_file(self, selection): test_command = split_command[0] if len(split_command) > 1 else exec_string if (section.get('terminal_command') and section.get('type') == 1) \ - or not is_x_app(test_command): + or not is_gui_app(test_command): active_object = self._application.get_active_object() options = Parameters() @@ -296,7 +296,7 @@ def execute_file(self, path, provider=None): if Gio.content_type_can_be_executable(mime_type) and should_execute: # file type is executable - if is_x_app(path): + if is_gui_app(path): subprocess.Popen((path,), cwd=os.path.dirname(path)) else: diff --git a/sunflower/common.py b/sunflower/common.py index 87c334574..8e8abcdc8 100644 --- a/sunflower/common.py +++ b/sunflower/common.py @@ -135,8 +135,9 @@ def get_user_directory(directory): return result -def is_x_app(command): +def is_gui_app(command): """Checks if command uses graphical user interfaces.""" + # TODO: Add check for Wayland try: env = os.environ.copy() env.update({'LD_TRACE_LOADED_OBJECTS': '1'}) @@ -189,29 +190,21 @@ def load_translation(): 'ngettext': translation.ngettext }) -def disp_fn(fn): - """ - Replaces surrogate codepoints in a filename with a replacement character - to display non-UTF-8 filenames. - """ +def decode_file_name(file_name): + """Replace surrogate codepoints in a filename with a replacement character + to display non-UTF-8 filenames.""" if sys.version_info[0] == 2: - return fn + return file_name - if isinstance(fn, bytes): - return fn.decode('utf-8', 'replace') - else: - return disp_fn(encode_fn(fn)) + if isinstance(file_name, bytes): + return file_name.decode('utf-8', 'replace') -def display_basename(fn): - return disp_fn(os.path.basename(fn)) + return decode_file_name(encode_file_name(file_name)) -def encode_fn(fn): - """ - Encodes a filename to bytes so it can be passed to GI APIs that expect a - file name (and specify 'filename' as their argument type in the GIR - bindings) - """ +def encode_file_name(file_name): + """Encode filename to bytes so it can be passed to GI APIs that expect a file name + (and specify `filename` as their argument type in the GIR bindings).""" if sys.version_info[0] == 2: - return fn - else: - return str(fn).encode('utf-8', 'surrogateescape') + return file_name + + return str(file_name).encode('utf-8', 'surrogateescape') diff --git a/sunflower/emblems.py b/sunflower/emblems.py index f24a8010c..6994703a7 100644 --- a/sunflower/emblems.py +++ b/sunflower/emblems.py @@ -4,7 +4,7 @@ import sqlite3 as sql from gi.repository import Gtk -from sunflower.common import get_cache_directory, encode_fn +from sunflower.common import get_cache_directory, encode_file_name class EmblemManager: @@ -260,7 +260,7 @@ def get_emblems_for_path(self, path): cursor = self._get_cursor() # get all the items in path - cursor.execute('SELECT id, name FROM items WHERE path=?', (encode_fn(path),)) + cursor.execute('SELECT id, name FROM items WHERE path=?', (encode_file_name(path),)) items = cursor.fetchall() # exit if there are no items in path diff --git a/sunflower/gui/input_dialog.py b/sunflower/gui/input_dialog.py index 18964d93b..35830290d 100644 --- a/sunflower/gui/input_dialog.py +++ b/sunflower/gui/input_dialog.py @@ -7,7 +7,7 @@ from gi.repository import Gtk from sunflower.plugin_base.provider import FileType, Support as ProviderSupport -from sunflower.common import get_user_directory, UserDirectory, display_basename +from sunflower.common import get_user_directory, decode_file_name, UserDirectory from sunflower.widgets.completion_entry import PathCompletionEntry from sunflower.queue import OperationQueue @@ -165,7 +165,7 @@ def _browse_original_path(self, widget, data=None): # if link name is empty, add original path name if self._entry.get_text() == '': - self._entry.set_text(display_basename(dialog.get_filename())) + self._entry.set_text(decode_file_name(os.path.basename(dialog.get_filename()))) dialog.destroy() @@ -958,7 +958,7 @@ def _update_label(self, widget=None, data=None): else: icon = icon_manager.get_icon_for_file(item) - self._affected.append((icon, display_basename(item))) + self._affected.append((icon, decode_file_name(os.path.basename(item)))) def set_title(self, title_text): """Set dialog title""" @@ -1714,7 +1714,8 @@ def __init__(self, application, path=None): label_open_with.set_label(_('Select application:')) else: - label_open_with.set_label(_('Open {0} with:').format(display_basename(path))) + decoded_path = decode_file_name(os.path.basename(path)) + label_open_with.set_label(_('Open {0} with:').format(decoded_path)) # create application list list_container = Gtk.ScrolledWindow() diff --git a/sunflower/gui/main_window.py b/sunflower/gui/main_window.py index df3d3ea94..edbf943d9 100644 --- a/sunflower/gui/main_window.py +++ b/sunflower/gui/main_window.py @@ -1878,7 +1878,7 @@ def execute_command(self, widget, data=None): if not handled: # try executing command try: - if common.is_x_app(command[0]): + if common.is_gui_app(command[0]): # command is X based, just execute it process = subprocess.Popen(shlex.split(raw_command), cwd=active_object.path) diff --git a/sunflower/gui/properties_window.py b/sunflower/gui/properties_window.py index 58c8e66ed..5a668841c 100644 --- a/sunflower/gui/properties_window.py +++ b/sunflower/gui/properties_window.py @@ -199,7 +199,8 @@ def _rename_item(self, widget=None, data=None): def _create_monitor(self): """Create item monitor""" - self._monitor = Gio.File.new_for_path(common.encode_fn(self._path)).monitor(Gio.FileMonitorFlags.SEND_MOVED) + path = common.encode_file_name(self._path) + self._monitor = Gio.File.new_for_path(path).monitor(Gio.FileMonitorFlags.SEND_MOVED) self._monitor.connect('changed', self._item_changes) def _load_associated_applications(self): diff --git a/sunflower/plugin_base/item_list.py b/sunflower/plugin_base/item_list.py index 990b406b7..f506f9ce3 100644 --- a/sunflower/plugin_base/item_list.py +++ b/sunflower/plugin_base/item_list.py @@ -1271,7 +1271,7 @@ def _root_directory(self, widget=None, data=None): def _control_got_focus(self, widget, data=None): """List focus in event""" PluginBase._control_got_focus(self, widget, data) - self._parent.set_location_label(common.disp_fn(self.path)) + self._parent.set_location_label(common.decode_file_name(self.path)) def _locations_button_clicked(self, widget, data=None): """Handle clicking on locations button.""" diff --git a/sunflower/plugins/file_list/file_list.py b/sunflower/plugins/file_list/file_list.py index 04964ee42..d36683c53 100644 --- a/sunflower/plugins/file_list/file_list.py +++ b/sunflower/plugins/file_list/file_list.py @@ -991,8 +991,9 @@ def _rename_file(self, widget=None, data=None): if selection is None: return is_dir = self.get_provider().is_dir(selection) + # get base name from selection - selection = common.display_basename(selection) + selection = common.decode_file_name(os.path.basename(selection)) dialog = RenameDialog(self._parent, selection, is_dir) result = dialog.get_response() @@ -1697,8 +1698,8 @@ def _add_item(self, filename, parent=None, parent_path=None): data = ( os.path.join(parent_path, filename) if parent_path else filename, - common.disp_fn(file_info[0]), - common.disp_fn(file_info[1][1:]), + common.decode_file_name(file_info[0]), + common.decode_file_name(file_info[1][1:]), file_size, formated_file_size, file_mode, @@ -2309,11 +2310,11 @@ def change_path(self, path=None, selected=None): if path_name == "": path_name = self.path - self._change_tab_text(common.disp_fn(path_name)) + self._change_tab_text(common.decode_file_name(path_name)) self._change_title_text(self.path) if self._parent.get_active_object() is self: - self._parent.set_location_label(common.disp_fn(self.path)) + self._parent.set_location_label(common.decode_file_name(self.path)) # change list icon self._title_bar.set_icon_from_name(provider.get_protocol_icon()) @@ -2350,7 +2351,7 @@ def change_path(self, path=None, selected=None): _( "Error changing working directory to:" "\n{1}\n\n{0}\n\nWould you like to retry?" - ).format(error, common.disp_fn(path)) + ).format(error, common.decode_file_name(path)) ) dialog.set_default_response(Gtk.ResponseType.YES) result = dialog.run() diff --git a/sunflower/tools/viewer.py b/sunflower/tools/viewer.py index 3c95fcffd..9769acd82 100644 --- a/sunflower/tools/viewer.py +++ b/sunflower/tools/viewer.py @@ -6,7 +6,7 @@ import subprocess from gi.repository import Gtk, Gdk, Pango, GObject, GdkPixbuf -from sunflower.common import executable_exists, disp_fn +from sunflower.common import executable_exists, decode_file_name from sunflower.widgets.status_bar import StatusBar from sunflower.plugin_base.provider import Mode as FileMode @@ -32,7 +32,7 @@ def __init__(self, path, provider, parent): self._mime_type = associations_manager.get_mime_type(data=data) # configure window - display_filename = disp_fn(os.path.basename(self.path)) + display_filename = decode_file_name(os.path.basename(self.path)) self._window.set_title(_('{0} - Viewer').format(display_filename)) self._window.set_size_request(800, 600) self._window.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) diff --git a/sunflower/widgets/breadcrumbs.py b/sunflower/widgets/breadcrumbs.py index 635bbd92f..5ee22eb2b 100644 --- a/sunflower/widgets/breadcrumbs.py +++ b/sunflower/widgets/breadcrumbs.py @@ -3,7 +3,7 @@ import os from gi.repository import Gtk, GObject -from sunflower.common import disp_fn +from sunflower.common import decode_file_name class Breadcrumbs(Gtk.HBox): """Linked list of buttons navigating to different paths.""" @@ -77,7 +77,7 @@ def refresh(self, path): control = Gtk.RadioButton.new() control.set_focus_on_click(False) - control.set_label(disp_fn(element)) + control.set_label(decode_file_name(element)) control.set_mode(False) control.connect('clicked', self.__fragment_click) control.path = current_path diff --git a/sunflower/widgets/title_bar.py b/sunflower/widgets/title_bar.py index 46f49099c..c357d8592 100644 --- a/sunflower/widgets/title_bar.py +++ b/sunflower/widgets/title_bar.py @@ -5,7 +5,7 @@ from gi.repository import Gtk, Pango, Gdk from sunflower.widgets.breadcrumbs import Breadcrumbs from sunflower.widgets.context_menu import ContextMenu -from sunflower.common import disp_fn +from sunflower.common import decode_file_name class Mode: @@ -124,7 +124,7 @@ def set_title(self, path): if self._breadcrumbs is not None: self._breadcrumbs.refresh(path) else: - self._title_label.set_markup(disp_fn(path).replace('&', '&')) + self._title_label.set_markup(decode_file_name(path).replace('&', '&')) def set_subtitle(self, text): """Set subtitle text"""