Philipp Hörist pushed to branch master at gajim / gajim

Commits:

7 changed files:

Changes:

  • gajim/common/application.py
    ... ... @@ -40,6 +40,7 @@
    40 40
     from gajim.common import passwords
    
    41 41
     from gajim.common.commands import ChatCommands
    
    42 42
     from gajim.common.dbus import logind
    
    43
    +from gajim.common.dbus import file_manager
    
    43 44
     from gajim.common.events import AccountDisabled
    
    44 45
     from gajim.common.events import AccountDisconnected
    
    45 46
     from gajim.common.events import AccountEnabled
    
    ... ... @@ -114,6 +115,8 @@ def _init_core(self) -> None:
    114 115
             else:
    
    115 116
                 logind.enable()
    
    116 117
     
    
    118
    +        file_manager.init()
    
    119
    +
    
    117 120
             for account in app.settings.get_active_accounts():
    
    118 121
                 app.connections[account] = Client(account)
    
    119 122
                 app.to_be_removed[account] = []
    

  • gajim/common/dbus/file_manager.py
    1
    +# This file is part of Gajim.
    
    2
    +#
    
    3
    +# Gajim is free software; you can redistribute it and/or modify
    
    4
    +# it under the terms of the GNU General Public License as published
    
    5
    +# by the Free Software Foundation; version 3 only.
    
    6
    +#
    
    7
    +# Gajim is distributed in the hope that it will be useful,
    
    8
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    
    9
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    
    10
    +# GNU General Public License for more details.
    
    11
    +#
    
    12
    +# You should have received a copy of the GNU General Public License
    
    13
    +# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    14
    +
    
    15
    +from typing import Optional
    
    16
    +
    
    17
    +import logging
    
    18
    +
    
    19
    +from gi.repository import Gio
    
    20
    +from gi.repository import GLib
    
    21
    +
    
    22
    +from gajim.common.util.classes import Singleton
    
    23
    +
    
    24
    +log = logging.getLogger('gajim.c.dbus.file_manager')
    
    25
    +
    
    26
    +
    
    27
    +class DBusFileManager(metaclass=Singleton):
    
    28
    +    '''
    
    29
    +    (Partial) implementation of a client for
    
    30
    +    https://freedesktop.org/wiki/Specifications/file-manager-interface/
    
    31
    +    '''
    
    32
    +
    
    33
    +    def __init__(self) -> None:
    
    34
    +        self._proxy: Optional[Gio.DBusProxy]
    
    35
    +        Gio.DBusProxy.new_for_bus(
    
    36
    +            Gio.BusType.SESSION,
    
    37
    +            Gio.DBusProxyFlags.DO_NOT_AUTO_START_AT_CONSTRUCTION,
    
    38
    +            None,
    
    39
    +            'org.freedesktop.FileManager1',
    
    40
    +            '/org/freedesktop/FileManager1',
    
    41
    +            'org.freedesktop.FileManager1',
    
    42
    +            None,
    
    43
    +            self._on_proxy_ready,
    
    44
    +            )
    
    45
    +
    
    46
    +    def _on_proxy_ready(self, _: None, res: Gio.AsyncResult) -> None:
    
    47
    +        try:
    
    48
    +            self._proxy = Gio.DBusProxy.new_finish(res)
    
    49
    +        except GLib.Error as err:
    
    50
    +            log.warning('Couldn’t construct dbus proxy: %s', err.message)
    
    51
    +
    
    52
    +    def is_available(self) -> bool:
    
    53
    +        return self._proxy is not None
    
    54
    +
    
    55
    +    def show_items_sync(self,
    
    56
    +                        uris: list[str],
    
    57
    +                        startup_id: str = '',
    
    58
    +                        timeout_ms: int = 500,
    
    59
    +                        ) -> bool:
    
    60
    +        '''
    
    61
    +        Opens parent folder(s), selecting/highlighting the specified
    
    62
    +        files/folders.  E.g., for ['file:/home/user/Downloads/xyzzy.foo',
    
    63
    +        'file:/home/user/Downloads/Quuxes'], opens ~/Downloads with
    
    64
    +        xyzzy.foo and Quuxes items selected.
    
    65
    +
    
    66
    +        Returns True on success.
    
    67
    +
    
    68
    +        Fails if called too early after construction; check `is_available()`.
    
    69
    +        '''
    
    70
    +
    
    71
    +        if self._proxy is None:
    
    72
    +            log.debug('ShowItems: no dbus proxy')
    
    73
    +            return False
    
    74
    +
    
    75
    +        try:
    
    76
    +            self._proxy.call_sync(
    
    77
    +                'ShowItems',
    
    78
    +                GLib.Variant('(ass)', (uris, startup_id)),
    
    79
    +                Gio.DBusCallFlags.NONE,
    
    80
    +                timeout_ms,
    
    81
    +                None,
    
    82
    +                )
    
    83
    +            return True
    
    84
    +        except GLib.Error as err:
    
    85
    +            log.warning('ShowItems failed: %s', err.message)
    
    86
    +            return False
    
    87
    +
    
    88
    +
    
    89
    +def init() -> None:
    
    90
    +    DBusFileManager()

  • gajim/common/helpers.py
    ... ... @@ -100,6 +100,7 @@
    100 100
     from gajim.common.const import SHOW_LIST
    
    101 101
     from gajim.common.const import CONSONANTS
    
    102 102
     from gajim.common.const import VOWELS
    
    103
    +from gajim.common.dbus.file_manager import DBusFileManager
    
    103 104
     from gajim.common.structs import URI
    
    104 105
     from gajim.common import types
    
    105 106
     if TYPE_CHECKING:
    
    ... ... @@ -1102,6 +1103,16 @@ def open_file(path: Path) -> None:
    1102 1103
         open_file_uri(path.as_uri())
    
    1103 1104
     
    
    1104 1105
     
    
    1106
    +def open_directory(path: Path) -> None:
    
    1107
    +    return open_file(path)
    
    1108
    +
    
    1109
    +
    
    1110
    +def show_in_folder(path: Path) -> None:
    
    1111
    +    if not DBusFileManager().show_items_sync([path.as_uri()]):
    
    1112
    +        # Fall back to just opening the containing folder
    
    1113
    +        open_directory(path.parent)
    
    1114
    +
    
    1115
    +
    
    1105 1116
     def filesystem_path_from_uri(uri: str) -> Optional[Path]:
    
    1106 1117
         puri = parse_uri(uri)
    
    1107 1118
         if puri.type != URIType.FILE:
    

  • gajim/gtk/conversation/rows/file_transfer_jingle.py
    ... ... @@ -43,6 +43,7 @@
    43 43
     from gajim.common.file_props import FileProp
    
    44 44
     from gajim.common.file_props import FilesProp
    
    45 45
     from gajim.common.helpers import open_file
    
    46
    +from gajim.common.helpers import show_in_folder
    
    46 47
     from gajim.common.i18n import _
    
    47 48
     from gajim.common.modules.contacts import BareContact
    
    48 49
     from gajim.common.storage.archive import ConversationRow
    
    ... ... @@ -352,9 +353,7 @@ def _on_open_file(self, _button: Gtk.Button) -> None:
    352 353
         def _on_open_folder(self, _button: Gtk.Button) -> None:
    
    353 354
             assert self._file_props is not None
    
    354 355
             assert self._file_props.file_name is not None
    
    355
    -
    
    356
    -        folder = Path(self._file_props.file_name).parent
    
    357
    -        open_file(folder)
    
    356
    +        show_in_folder(Path(self._file_props.file_name))
    
    358 357
     
    
    359 358
         def _on_bad_hash_retry(self, _button: Gtk.Button) -> None:
    
    360 359
             app.interface.instances['file_transfers'].show_hash_error(
    

  • gajim/gtk/filetransfer.py
    ... ... @@ -47,9 +47,9 @@
    47 47
     from gajim.common.i18n import _
    
    48 48
     from gajim.common.file_props import FilesProp
    
    49 49
     from gajim.common.file_props import FileProp
    
    50
    -from gajim.common.helpers import open_file
    
    51 50
     from gajim.common.helpers import file_is_locked
    
    52 51
     from gajim.common.helpers import AdditionalDataDict
    
    52
    +from gajim.common.helpers import show_in_folder
    
    53 53
     from gajim.common.modules.bytestream import is_transfer_active
    
    54 54
     from gajim.common.modules.bytestream import is_transfer_paused
    
    55 55
     from gajim.common.modules.bytestream import is_transfer_stopped
    
    ... ... @@ -1026,8 +1026,7 @@ def _on_open_folder_menuitem_activate(self, widget):
    1026 1026
             if not file_props.file_name:
    
    1027 1027
                 return
    
    1028 1028
     
    
    1029
    -        folder = Path(file_props.file_name).parent
    
    1030
    -        open_file(folder)
    
    1029
    +        show_in_folder(Path(file_props.file_name))
    
    1031 1030
     
    
    1032 1031
         def _on_cancel_menuitem_activate(self, widget):
    
    1033 1032
             self._on_cancel_button_clicked(widget)
    

  • gajim/gtk/main.py
    ... ... @@ -43,6 +43,7 @@
    43 43
     from gajim.common.helpers import open_file
    
    44 44
     from gajim.common.helpers import open_uri
    
    45 45
     from gajim.common.helpers import play_sound
    
    46
    +from gajim.common.helpers import show_in_folder
    
    46 47
     from gajim.common.modules.bytestream import is_transfer_active
    
    47 48
     from gajim.common.modules.contacts import GroupchatContact
    
    48 49
     from gajim.plugins.pluginmanager import PluginManifest
    
    ... ... @@ -565,7 +566,7 @@ def _on_ok(paths: list[str]) -> None:
    565 566
                     return
    
    566 567
     
    
    567 568
                 assert preview.orig_path is not None
    
    568
    -            open_file(preview.orig_path.parent)
    
    569
    +            show_in_folder(preview.orig_path)
    
    569 570
     
    
    570 571
             elif action_name == 'preview-copy-link':
    
    571 572
                 display = Gdk.Display.get_default()
    

  • gajim/gtk/preferences.py
    ... ... @@ -28,7 +28,7 @@
    28 28
     from gajim.common import configpaths
    
    29 29
     from gajim.common.const import THRESHOLD_OPTIONS
    
    30 30
     from gajim.common.i18n import _
    
    31
    -from gajim.common.helpers import open_file
    
    31
    +from gajim.common.helpers import open_directory
    
    32 32
     from gajim.common.multimedia_helpers import AudioInputManager
    
    33 33
     from gajim.common.multimedia_helpers import AudioOutputManager
    
    34 34
     from gajim.common.multimedia_helpers import VideoInputManager
    
    ... ... @@ -978,7 +978,7 @@ def _on_debug_logging(value: bool, *args: Any) -> None:
    978 978
     
    
    979 979
         @staticmethod
    
    980 980
         def _on_open_debug_logs(*args: Any) -> None:
    
    981
    -        open_file(configpaths.get('DEBUG'))
    
    981
    +        open_directory(configpaths.get('DEBUG'))
    
    982 982
     
    
    983 983
         @staticmethod
    
    984 984
         def _on_advanced_config_editor(*args: Any) -> None: