︙ | | | ︙ | |
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# for empty grouping / categories
placeholder = [dict(genre="./.", title="Subcategory placeholder", playing="./.", url="none:", listeners=0, bitrate=0, homepage="", state="gtk-folder")]
empty_stub = [dict(genre="./.", title="No categories found (HTTP error)", playing="Try Channel→Reload Categories later..", url="none:", listeners=0, bitrate=0, homepage="", state="gtk-stop")]
# regex
rx_www_url = re.compile("""(www(\.\w+[\w-]+){2,}|(\w+[\w-]+[ ]?\.)+(com|FM|net|org|de|PL|fr|uk))""", re.I)
# constructor
def __init__(self, parent=None):
#self.streams = {}
self.gtk_list = None
self.gtk_cat = None
|
>
>
>
>
|
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# for empty grouping / categories
placeholder = [dict(genre="./.", title="Subcategory placeholder", playing="./.", url="none:", listeners=0, bitrate=0, homepage="", state="gtk-folder")]
empty_stub = [dict(genre="./.", title="No categories found (HTTP error)", playing="Try Channel→Reload Categories later..", url="none:", listeners=0, bitrate=0, homepage="", state="gtk-stop")]
# regex
rx_www_url = re.compile("""(www(\.\w+[\w-]+){2,}|(\w+[\w-]+[ ]?\.)+(com|FM|net|org|de|PL|fr|uk))""", re.I)
#--------------------------- initialization --------------------------------
# constructor
def __init__(self, parent=None):
#self.streams = {}
self.gtk_list = None
self.gtk_cat = None
|
︙ | | | ︙ | |
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
self.parent = stub_parent(None)
# only if streamtuner2 is run in graphical mode
if (parent):
self.cache()
self.gui(parent)
pass
# These are all implemented in main (where they don't belong!)
def stations(self):
return self.streams.get(self.current, [])
def rowno(self):
pass
def row(self):
pass
# read previous channel/stream data, if there is any
def cache(self):
# stream list
cache = conf.load("cache/" + self.module)
if (cache):
self.streams = cache
# categories
cache = conf.load("cache/categories_" + self.module)
if (cache):
self.categories = cache
# catmap (optional)
cache = conf.load("cache/catmap_" + self.module)
if (cache):
self.catmap = cache
pass
# initialize Gtk widgets / data objects
def gui(self, parent):
#print(self.module + ".gui()")
# save reference to main window/glade API
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
self.parent = stub_parent(None)
# only if streamtuner2 is run in graphical mode
if (parent):
self.cache()
self.gui(parent)
pass
# initialize Gtk widgets / data objects
def gui(self, parent):
#print(self.module + ".gui()")
# save reference to main window/glade API
|
︙ | | | ︙ | |
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
self.load(self.current)
else:
uikit.columns(self.gtk_list, self.datamap, [])
# add to main menu
uikit.add_menu([parent.channelmenuitems], self.meta["title"], lambda w: parent.channel_switch_by_name(self.module) or 1)
# make private copy of .datamap and modify field (title= only ATM)
def update_datamap(self, search="name", title=None):
if self.datamap == GenericChannel.datamap:
self.datamap = copy.deepcopy(self.datamap)
for i,row in enumerate(self.datamap):
if row[2][0] == search:
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
self.load(self.current)
else:
uikit.columns(self.gtk_list, self.datamap, [])
# add to main menu
uikit.add_menu([parent.channelmenuitems], self.meta["title"], lambda w: parent.channel_switch_by_name(self.module) or 1)
# Statusbar stub (defers to parent/main window, if in GUI mode)
def status(self, *v):
if self.parent: self.parent.status(*v)
else: __print__(dbg.INFO, "status():", *v)
#--------------------- streams/model data accesss ---------------------------
# Get list of stations in current category
def stations(self):
return self.streams.get(self.current, [])
# Convert ListStore iter to row number
def rowno(self):
(model, iter) = self.model_iter()
return model.get_path(iter)[0]
# Return ListStore object and Iterator for currently selected row in gtk.TreeView station list
def model_iter(self):
return self.gtk_list.get_selection().get_selected()
# Currently selected entry in stations list, return complete data dict
def row(self):
return self.stations() [self.rowno()]
# Fetches a single varname from currently selected station entry
def selected(self, name="url"):
return self.row().get(name)
# Inject status icon into currently selected row (used by main.bookmark() call)
def row_icon(self, gtkIcon = gtk.STOCK_ABOUT):
try:
# Updates gtk_list store, set icon in current display.
# Since it is used by bookmarks, would be reshown with next display() anyhow,
# and there's no need to invalidate the ls cache, because that's referenced by model anyhow.
(model,iter) = self.model_iter()
model.set_value(iter, 0, gtkIcon)
except:
pass
#------------------------ base implementations -----------------------------
# read previous channel/stream data, if there is any
def cache(self):
# stream list
cache = conf.load("cache/" + self.module)
if (cache):
self.streams = cache
# categories
cache = conf.load("cache/categories_" + self.module)
if (cache):
self.categories = cache
# catmap (optional)
cache = conf.load("cache/catmap_" + self.module)
if (cache):
self.catmap = cache
pass
# make private copy of .datamap and modify field (title= only ATM)
def update_datamap(self, search="name", title=None):
if self.datamap == GenericChannel.datamap:
self.datamap = copy.deepcopy(self.datamap)
for i,row in enumerate(self.datamap):
if row[2][0] == search:
|
︙ | | | ︙ | |
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
|
return self.current
#--------------------------- actions ---------------------------------
# invoke action.play,
# can be overridden to provide channel-specific "play" alternative
def play(self, row):
if row.get("url"):
# parameters
audioformat = row.get("format", self.audioformat)
listformat = row.get("listformat", self.listformat)
# invoke audio player
action.play(row["url"], audioformat, listformat)
#--------------------------- utility functions -----------------------
|
|
|
|
>
|
|
<
<
|
>
>
>
>
>
>
>
>
>
>
>
|
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
|
return self.current
#--------------------------- actions ---------------------------------
# Invoke action.play() for current station.
# Can be overridden to provide channel-specific "play" alternative
def play(self):
row = self.row()
if row:
# playlist and audio type
audioformat = row.get("format", self.audioformat)
listformat = row.get("listformat", self.listformat)
# invoke audio player
action.play(row["url"], audioformat, listformat, row)
else:
self.status("No station selected for playing.")
return row
# Start streamripper/youtube-dl/etc
def record(self):
row = self.row()
if row:
audioformat = row.get("format", self.audioformat)
listformat = row.get("listformat", self.listformat)
action.record(row.get("url"), audioformat, listformat, row=row)
return row
#--------------------------- utility functions -----------------------
|
︙ | | | ︙ | |