Daniel Brötzmann pushed to branch mainwindow at gajim / gajim
Commits:
-
4dc79ca4
by wurstsalat at 2021-11-21T12:30:12+01:00
5 changed files:
- gajim/common/preview.py
- gajim/common/preview_helpers.py
- gajim/common/types.py
- gajim/gtk/preview.py
- gajim/gtk/preview_audio.py
Changes:
| ... | ... | @@ -23,7 +23,6 @@ |
| 23 | 23 |
from urllib.parse import urlparse
|
| 24 | 24 |
from urllib.parse import ParseResult
|
| 25 | 25 |
|
| 26 |
-from gi.repository import GdkPixbuf
|
|
| 27 | 26 |
from gi.repository import Gio
|
| 28 | 27 |
from gi.repository import GLib
|
| 29 | 28 |
from gi.repository import Soup
|
| ... | ... | @@ -45,6 +44,7 @@ |
| 45 | 44 |
from gajim.common.preview_helpers import get_image_paths
|
| 46 | 45 |
from gajim.common.preview_helpers import guess_mime_type
|
| 47 | 46 |
from gajim.common.preview_helpers import pixbuf_from_data
|
| 47 |
+from gajim.common.types import GdkPixbufType
|
|
| 48 | 48 |
|
| 49 | 49 |
log = logging.getLogger('gajim.c.preview')
|
| 50 | 50 |
|
| ... | ... | @@ -55,7 +55,7 @@ |
| 55 | 55 |
|
| 56 | 56 |
|
| 57 | 57 |
class Preview:
|
| 58 |
- def __init__(self,
|
|
| 58 |
+ def __init__(self,
|
|
| 59 | 59 |
uri: str,
|
| 60 | 60 |
urlparts: Optional[ParseResult],
|
| 61 | 61 |
orig_path: Optional[Path],
|
| ... | ... | @@ -139,7 +139,7 @@ def create_thumbnail(self, data: bytes) -> bool: |
| 139 | 139 |
return False
|
| 140 | 140 |
return True
|
| 141 | 141 |
|
| 142 |
- def update_widget(self, data: Optional[GdkPixbuf.Pixbuf] = None) -> None:
|
|
| 142 |
+ def update_widget(self, data: Optional[GdkPixbufType] = None) -> None:
|
|
| 143 | 143 |
self._widget.update(self, data)
|
| 144 | 144 |
|
| 145 | 145 |
|
| ... | ... | @@ -285,12 +285,9 @@ def get_image_paths(uri: str, urlparts: ParseResult, size: int, orig_dir: Path, |
| 285 | 285 |
|
| 286 | 286 |
name_hash = hashlib.sha1(str(uri).encode()).hexdigest()
|
| 287 | 287 |
|
| 288 |
- orig_filename = '%s_%s%s' % (web_stem, name_hash, extension)
|
|
| 288 |
+ orig_filename = f'{web_stem}_{name_hash}{extension}'
|
|
| 289 | 289 |
|
| 290 |
- thumb_filename = '%s_%s_thumb_%s%s' % (web_stem,
|
|
| 291 |
- name_hash,
|
|
| 292 |
- size,
|
|
| 293 |
- extension)
|
|
| 290 |
+ thumb_filename = f'{web_stem}_{name_hash}_thumb_{size}{extension}'
|
|
| 294 | 291 |
|
| 295 | 292 |
orig_path = orig_dir / orig_filename
|
| 296 | 293 |
thumb_path = thumb_dir / thumb_filename
|
| ... | ... | @@ -23,6 +23,9 @@ |
| 23 | 23 |
from typing import TYPE_CHECKING
|
| 24 | 24 |
|
| 25 | 25 |
from pathlib import Path
|
| 26 |
+ |
|
| 27 |
+from gi.repository import GdkPixbuf
|
|
| 28 |
+ |
|
| 26 | 29 |
import nbxmpp
|
| 27 | 30 |
from nbxmpp.protocol import JID
|
| 28 | 31 |
from nbxmpp.structs import BookmarkData
|
| ... | ... | @@ -61,9 +64,12 @@ |
| 61 | 64 |
# Plugins
|
| 62 | 65 |
PluginExtensionPoints = Dict[str, Tuple[Optional[Callable[..., None]],
|
| 63 | 66 |
Optional[Callable[..., None]]]]
|
| 64 |
-EventHandlersDict = Dict[str, Tuple[int, Callable[['NetworkEvent'], Optional[bool]]]]
|
|
| 67 |
+EventHandlersDict = Dict[
|
|
| 68 |
+ str, Tuple[int, Callable[['NetworkEvent'], Optional[bool]]]]
|
|
| 65 | 69 |
PluginEvents = List['NetworkEvent']
|
| 66 | 70 |
|
| 67 | 71 |
SettingsT = Union['Settings']
|
| 68 | 72 |
|
| 69 | 73 |
BookmarksDict = Dict[JID, BookmarkData]
|
| 74 |
+ |
|
| 75 |
+GdkPixbufType = Union[GdkPixbuf.Pixbuf, GdkPixbuf.PixbufAnimation]
|
| ... | ... | @@ -12,6 +12,8 @@ |
| 12 | 12 |
# You should have received a copy of the GNU General Public License
|
| 13 | 13 |
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
| 14 | 14 |
|
| 15 |
+from typing import Optional
|
|
| 16 |
+ |
|
| 15 | 17 |
import logging
|
| 16 | 18 |
import shutil
|
| 17 | 19 |
import os
|
| ... | ... | @@ -26,9 +28,11 @@ |
| 26 | 28 |
from gajim.common.helpers import open_file
|
| 27 | 29 |
from gajim.common.helpers import open_uri
|
| 28 | 30 |
from gajim.common.i18n import _
|
| 31 |
+from gajim.common.preview import Preview
|
|
| 29 | 32 |
from gajim.common.preview_helpers import split_geo_uri
|
| 30 | 33 |
from gajim.common.preview_helpers import contains_audio_streams
|
| 31 | 34 |
from gajim.common.preview_helpers import get_icon_for_mime_type
|
| 35 |
+from gajim.common.types import GdkPixbufType
|
|
| 32 | 36 |
|
| 33 | 37 |
from .dialogs import ErrorDialog
|
| 34 | 38 |
from .filechoosers import FileSaveDialog
|
| ... | ... | @@ -42,10 +46,10 @@ |
| 42 | 46 |
|
| 43 | 47 |
|
| 44 | 48 |
class PreviewWidget(Gtk.Box):
|
| 45 |
- def __init__(self, account):
|
|
| 49 |
+ def __init__(self, account: str) -> None:
|
|
| 46 | 50 |
Gtk.Box.__init__(self)
|
| 47 | 51 |
self.account = account
|
| 48 |
- self._preview = None
|
|
| 52 |
+ self._preview: Optional[Preview] = None
|
|
| 49 | 53 |
|
| 50 | 54 |
if app.settings.get('use_kib_mib'):
|
| 51 | 55 |
self._units = GLib.FormatSizeFlags.IEC_UNITS
|
| ... | ... | @@ -57,12 +61,12 @@ def __init__(self, account): |
| 57 | 61 |
self.add(self._ui.preview_box)
|
| 58 | 62 |
self.show_all()
|
| 59 | 63 |
|
| 60 |
- def get_text(self):
|
|
| 64 |
+ def get_text(self) -> str:
|
|
| 61 | 65 |
if self._preview is None:
|
| 62 | 66 |
return ''
|
| 63 | 67 |
return self._preview.uri
|
| 64 | 68 |
|
| 65 |
- def update(self, preview, data):
|
|
| 69 |
+ def update(self, preview: Preview, data: Optional[GdkPixbufType]) -> None:
|
|
| 66 | 70 |
self._preview = preview
|
| 67 | 71 |
|
| 68 | 72 |
if preview.is_geo_uri:
|
| ... | ... | @@ -114,7 +118,8 @@ def update(self, preview, data): |
| 114 | 118 |
self._ui.download_button.hide()
|
| 115 | 119 |
self._ui.open_folder_button.show()
|
| 116 | 120 |
self._ui.save_as_button.show()
|
| 117 |
- if (preview.is_audio and app.is_installed('GST') and
|
|
| 121 |
+ if (preview.orig_path is not None and preview.is_audio and
|
|
| 122 |
+ app.is_installed('GST') and
|
|
| 118 | 123 |
contains_audio_streams(preview.orig_path)):
|
| 119 | 124 |
self._ui.image_button.hide()
|
| 120 | 125 |
audio_widget = AudioWidget(preview.orig_path)
|
| ... | ... | @@ -223,7 +228,7 @@ def _on_open_link_in_browser(self, _menu): |
| 223 | 228 |
|
| 224 | 229 |
def _on_content_button_clicked(self, _button):
|
| 225 | 230 |
action = app.settings.get('preview_leftclick_action')
|
| 226 |
- method = getattr(self, '_on_%s' % action)
|
|
| 231 |
+ method = getattr(self, f'_on_{action}')
|
|
| 227 | 232 |
method(None)
|
| 228 | 233 |
|
| 229 | 234 |
def _on_button_press_event(self, _button, event):
|
| ... | ... | @@ -13,6 +13,7 @@ |
| 13 | 13 |
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
| 14 | 14 |
|
| 15 | 15 |
import logging
|
| 16 |
+from pathlib import Path
|
|
| 16 | 17 |
|
| 17 | 18 |
from gi.repository import GLib
|
| 18 | 19 |
from gi.repository import Gtk
|
| ... | ... | @@ -26,12 +27,18 @@ |
| 26 | 27 |
|
| 27 | 28 |
|
| 28 | 29 |
class AudioWidget(Gtk.Box):
|
| 29 |
- def __init__(self, file_path):
|
|
| 30 |
+ def __init__(self, file_path: Path) -> None:
|
|
| 30 | 31 |
Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL,
|
| 31 | 32 |
spacing=6)
|
| 32 |
- self._playbin = None
|
|
| 33 |
- self._query = None
|
|
| 34 |
- self._has_timeout = False
|
|
| 33 |
+ self._playbin = Gst.ElementFactory.make('playbin', 'bin')
|
|
| 34 |
+ if self._playbin is None:
|
|
| 35 |
+ label = Gtk.Label(label=_('Audio preview is not available'))
|
|
| 36 |
+ self.add(label)
|
|
| 37 |
+ log.debug('Could not create GST playbin')
|
|
| 38 |
+ return
|
|
| 39 |
+ |
|
| 40 |
+ self._query = Gst.Query.new_position(Gst.Format.TIME)
|
|
| 41 |
+ self._has_timeout: bool = False
|
|
| 35 | 42 |
|
| 36 | 43 |
self._build_audio_widget()
|
| 37 | 44 |
self._setup_audio_player(file_path)
|
| ... | ... | @@ -67,18 +74,13 @@ def _build_audio_widget(self): |
| 67 | 74 |
self.connect('destroy', self._on_destroy)
|
| 68 | 75 |
self.show_all()
|
| 69 | 76 |
|
| 70 |
- def _setup_audio_player(self, file_path):
|
|
| 71 |
- self._playbin = Gst.ElementFactory.make('playbin', 'bin')
|
|
| 72 |
- if self._playbin is None:
|
|
| 73 |
- log.debug('Could not create GST playbin')
|
|
| 74 |
- return
|
|
| 77 |
+ def _setup_audio_player(self, file_path: Path) -> None:
|
|
| 75 | 78 |
self._playbin.set_property('uri', f'file://{file_path}')
|
| 76 | 79 |
state_return = self._playbin.set_state(Gst.State.PAUSED)
|
| 77 | 80 |
if state_return == Gst.StateChangeReturn.FAILURE:
|
| 78 | 81 |
log.debug('Could not setup GST playbin')
|
| 79 | 82 |
return
|
| 80 | 83 |
|
| 81 |
- self._query = Gst.Query.new_position(Gst.Format.TIME)
|
|
| 82 | 84 |
bus = self._playbin.get_bus()
|
| 83 | 85 |
bus.add_signal_watch()
|
| 84 | 86 |
bus.connect('message', self._on_bus_message)
|
| ... | ... | @@ -111,11 +113,11 @@ def _on_play_clicked(self, _button): |
| 111 | 113 |
def _on_destroy(self, _widget):
|
| 112 | 114 |
self._playbin.set_state(Gst.State.NULL)
|
| 113 | 115 |
|
| 114 |
- def _get_paused(self):
|
|
| 116 |
+ def _get_paused(self) -> bool:
|
|
| 115 | 117 |
_, state, _ = self._playbin.get_state(20)
|
| 116 | 118 |
return state == Gst.State.PAUSED
|
| 117 | 119 |
|
| 118 |
- def _set_pause(self, paused):
|
|
| 120 |
+ def _set_pause(self, paused: bool) -> None:
|
|
| 119 | 121 |
if paused:
|
| 120 | 122 |
self._playbin.set_state(Gst.State.PAUSED)
|
| 121 | 123 |
self._play_icon.set_from_icon_name(
|
| ... | ... | @@ -127,7 +129,7 @@ def _set_pause(self, paused): |
| 127 | 129 |
'media-playback-pause-symbolic',
|
| 128 | 130 |
Gtk.IconSize.BUTTON)
|
| 129 | 131 |
|
| 130 |
- def _update_seek_bar(self):
|
|
| 132 |
+ def _update_seek_bar(self) -> bool:
|
|
| 131 | 133 |
if self._get_paused():
|
| 132 | 134 |
self._has_timeout = False
|
| 133 | 135 |
return False
|
| ... | ... | @@ -138,7 +140,7 @@ def _update_seek_bar(self): |
| 138 | 140 |
return True
|
| 139 | 141 |
|
| 140 | 142 |
@staticmethod
|
| 141 |
- def _format_audio_timestamp(_widget, ns):
|
|
| 143 |
+ def _format_audio_timestamp(_widget: Gtk.Widget, ns: int) -> str:
|
|
| 142 | 144 |
seconds = ns / 1000000000
|
| 143 | 145 |
minutes = seconds / 60
|
| 144 | 146 |
hours = minutes / 60
|