-
Notifications
You must be signed in to change notification settings - Fork 2
/
TelegramEntry.py
141 lines (115 loc) · 5.03 KB
/
TelegramEntry.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# rhythmbox-telegram
# Copyright (C) 2023-2024 Andrey Izman <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from gi.repository import RB, GLib, GObject
from TelegramStorage import TgAudio
from common import file_uri, get_location_data, is_same_entry, get_entry_state
class TelegramEntryType(RB.RhythmDBEntryType):
__gsignals__ = {
'entry_downloaded': (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)),
}
def __init__(self, plugin):
RB.RhythmDBEntryType.__init__(self, name='TelegramEntryType')
self.source = None
self.plugin = plugin
self.shell = plugin.shell
self.db = plugin.db
self.shell_player = self.shell.props.shell_player
self._pending_playback_entry = None
self._entry_error_id = None
self._entry_downloaded_id = None
def activate(self):
self._entry_error_id = self.shell_player.props.player.connect('error', self._on_player_error)
self._entry_downloaded_id = self.connect('entry_downloaded', self._on_entry_downloaded)
def deactivate(self):
self.shell_player.props.player.disconnect(self._entry_error_id)
self.disconnect(self._entry_downloaded_id)
def _on_entry_downloaded(self, entry_type, entry):
if not self._pending_playback_entry:
return
if is_same_entry(entry, self._pending_playback_entry):
self._pending_playback_entry = None
self.shell_player.play_entry(entry, self.plugin.source)
# GLib.timeout_add(100, self.shell.props.shell_player.emit, "playing-changed", True)
def _on_player_error(self, *args):
self.shell.props.shell_player.stop()
def setup(self, source):
self.source = source
@staticmethod
def entry_view_iter_prev(model, iter):
path = model.get_path(iter)
if path.prev():
return model.get_iter(path)
return None
def get_prev_entry(self, current_entry):
entry_view = self.source.props.query_model
iter = entry_view.get_iter_first()
found = False
while iter:
entry = entry_view.get_value(iter, 0)
if found:
return entry
if entry == current_entry:
found = True
iter = self.entry_view_iter_prev(entry_view, iter)
else:
iter = entry_view.iter_next(iter)
return None
def get_next_entry(self, current_entry):
entry_view = self.source.props.query_model
iter = entry_view.get_iter_first()
found = False
while iter:
entry = entry_view.get_value(iter, 0)
if found:
return entry
if entry == current_entry:
found = True
iter = entry_view.iter_next(iter)
return None
def _load_entry_audio(self, entry):
self.plugin.loader.add_entry(entry).start()
def do_get_playback_uri(self, entry):
location = entry.get_string(RB.RhythmDBPropType.LOCATION)
chat_id, message_id = get_location_data(location)
audio = self.plugin.storage.get_audio(chat_id, message_id)
if not audio:
return None
prev_entry = self.get_prev_entry(entry)
next_entry = self.get_next_entry(entry)
prev_audio = self.plugin.storage.get_entry_audio(prev_entry) if prev_entry else None
next_audio = self.plugin.storage.get_entry_audio(next_entry) if next_entry else None
if prev_audio and not prev_audio.is_file_exists():
GLib.idle_add(self._load_entry_audio, prev_entry)
if next_audio and not next_audio.is_file_exists():
GLib.idle_add(self._load_entry_audio, next_entry)
if audio.is_file_exists():
self._pending_playback_entry = None
return file_uri(audio.local_path)
return_uri = None
playing_entry = self.shell.props.shell_player.get_playing_entry()
if playing_entry:
playing_location = playing_entry.get_string(RB.RhythmDBPropType.LOCATION)
if playing_location == location:
GLib.idle_add(self.shell.props.shell_player.stop)
return_uri = 'invalid'
state = get_entry_state(entry)
if state == TgAudio.STATE_LOADING:
return return_uri
self._pending_playback_entry = entry
self._load_entry_audio(entry)
return return_uri
def do_can_sync_metadata(self, entry): # noqa
return True