Internet radio browser GUI for music/video streams from various directory services.

⌈⌋ ⎇ branch:  streamtuner2


Check-in [363dce5eb9]

Overview
Comment:Cover most catched exceptions with log messages.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 363dce5eb97bffc333a85e7f0d7f7e4fbc66996f
User & Date: mario on 2015-04-26 15:35:21
Other Links: manifest | tags
Context
2015-04-26
22:21
Fixed gtk.main_iteration() extraneous parameter in gui_startup. check-in: 748d2aaed8 user: mario tags: trunk
15:35
Cover most catched exceptions with log messages. check-in: 363dce5eb9 user: mario tags: trunk
15:34
More customized log categories/colorization. check-in: 0943cca27e user: mario tags: trunk
Changes

Modified channels/__init__.py from [b129e11a0f] to [5fc4a7eeff].

198
199
200
201
202
203
204
205
206


207
208
209
210
211
212
213
198
199
200
201
202
203
204


205
206
207
208
209
210
211
212
213







-
-
+
+







    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
        except Exception as e:
            log.ERR_UIKIT("Couldn't set row_icon()", e)

    

    #------------------------ base implementations -----------------------------

    # read previous channel/stream data, if there is any
    def cache(self):

Modified channels/links.py from [a70b7e1793] to [d2e4f35037].

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
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







-
+

-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+







            
            # fill it up later
            parent.hooks["init"].append(self.populate)


    def populate(self, parent):
    
        # collect links from channel plugins
        # Collect links from channel plugins
        for name,channel in parent.channels.items():
          try:
            self.streams.append({
                "favourite": 1,
                "genre": "channel",
                "title": channel.meta.get("title", channel.module),
                "homepage": channel.meta.get("url", ""),
                "type": "text/html",
            })
          except: pass
            try:
                self.streams.append({
                    "favourite": 1,
                    "genre": "channel",
                    "title": channel.meta.get("title", channel.module),
                    "homepage": channel.meta.get("url", ""),
                    "type": "text/html",
                })
            except Exception as e:
                log.ERR("links: adding entry failed:", e)

        # Add built-in link list
        for row in self.default:
            (genre, title, homepage) = row
            self.streams.append({
                "genre": genre,
                "title": title,
                "homepage": homepage,
                "type": "text/html",

Modified channels/radiotray.py from [60345f8f8f] to [f195cf603e].

87
88
89
90
91
92
93
94
95


96
97
98
99
100
101
102
87
88
89
90
91
92
93


94
95
96
97
98
99
100
101
102







-
-
+
+







                for bookmark in group.findall("bookmark"):
                    r.append({
                        "genre": group.attrib["name"],
                        "title": bookmark.attrib["name"],
                        "url": bookmark.attrib["url"],
                        "playing": "",
                    })
        except:
            pass
        except Exception as e:
            log.DATA("Extracting from radiotray bookmarks.xml failed:", e)
        return r


    # send to 
    def share(self, *w):
        row = self.parent.row()
        if row:

Modified channels/search.py from [14f30d1313] to [21f830ba0a].

105
106
107
108
109
110
111

112
113
114
115
116
117
118
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119







+







                log.PROC("has_search:", cn.module)
                try:
                    add = cn.update_streams(cat=None, search=self.q)
                    for row in add:
                        row["genre"] = cn.meta["title"] + " " + row.get("genre", "")
                    entries += add
                except:
                    log.WARN("server_search: update_streams error in {}:".format(cn.module), e)
                    continue
            #main.status(main, 1.0 * i / 15)
        uikit.do(self.show_results, entries)


    # search text edited in text entry box
    def quicksearch_set(self, w, *eat, **up):

Modified favicon.py from [0e317dc343] to [f1c4f8f20a].

260
261
262
263
264
265
266
267

268
269
270
271
272
273
274
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274







-
+







    direct_download(favicon, file(url))



# convert .ico file to .png format
def ico2png(ico, png_fn):
    image = Image.open(ico)
    log.ICO2PNG(ico, png, image)
    log.FAVICON_ICO2PNG(ico, png, image)
    # resize
    if image.size[0] > 16:
        image.resize((16, 16), Image.ANTIALIAS)
    # .png format
    image.save(png_fn, "PNG", quality=98)


Modified st2.py from [3eb72c0f83] to [a5bfd28a13].

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

380
381
382
383
384
385
386
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
377

378
379
380
381
382
383
384
385







-









-
+







    # Either pass a string "" or a float 0.5, the message and pulse will be automatically
    # removed after 5 seconds now.
    def status(self, text=None, timeout=3):
        self.status_last = time.time() + timeout

        # progressbar
        if isinstance(text, (int, float)):
            log.FLOAT(text)
            if (text <= 0):  # unknown state
                uikit.do(self.progress.pulse, immediate=1)
            elif text >= 0.999 or text < 0.0:  # completed
                uikit.do(self.progress.hide)
            else:  # show percentage
                uikit.do(self.progress.show, immediate=1)
                uikit.do(self.progress.set_fraction, text, immediate=1)

        # add text
        elif isinstance(text, (str, unicode)):
        elif isinstance(text, (str)):
            uikit.do(self.statusbar.set_text, text)

        # timeout
        if not text or time.time() >= self.status_last:
            self.statusbar.set_text("")
            self.progress.hide()
            return False
430
431
432
433
434
435
436
437

438
439
440
441
442
443

444
445
446
447
448
449
450
429
430
431
432
433
434
435

436
437
438
439
440
441

442
443
444
445
446
447
448
449







-
+





-
+








    # load application state (widget sizes, selections, etc.)
    def init_app_state(self):

        winlayout = conf.load("window")
        if (winlayout):
            try: uikit.app_restore(self, winlayout)
            except Exception as e: log.APPRESTORE(e) # may fail for disabled/reordered plugin channels
            except Exception as e: log.APPSTATE_RESTORE(e) # may fail for disabled/reordered plugin channels

        winstate = conf.load("state")
        if (winstate):
            for id,prev in winstate.items():
                try: self.channels[id].current = prev["current"]
                except Exception as e: log.APPSTATE(e)
                except Exception as e: log.APPSTATE_RESTORE(e)

    # store window/widget states (sizes, selections, etc.)
    def save_app_state(self, widget):
        # gtk widget states
        widgetnames = ["win_streamtuner2", "toolbar", "notebook_channels", ] \
                    + [id+"_list" for id in self.channel_names] \
                    + [id+"_cat" for id in self.channel_names]
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472







-
+








    # end application and gtk+ main loop
    def gtk_main_quit(self, widget, *x):
        if conf.auto_save_appstate:
            try:  # doesn't work with gtk3 yet (probably just hooking at the wrong time)
                self.save_app_state(widget)
            except Exception as e:
                log.ERR(e)
                log.ERR("st2.gtk_main_quit", e)
        gtk.main_quit()


    # Right clicking a stream/station in the treeview to make context menu pop out.
    def station_context_menu(self, treeview, event):
        if treeview and event and event.button >= 3:
            path = treeview.get_path_at_pos(int(event.x), int(event.y))

Modified uikit.py from [0b23e6b513] to [09bab8deb1].

664
665
666
667
668
669
670
671


672
673
674
675
676
677
678
664
665
666
667
668
669
670

671
672
673
674
675
676
677
678
679







-
+
+







        pass
      elif p < 1.0:
        progressbar.set_fraction(p)
        progressbar.set_property("text", msg)
        while gtk.events_pending(): gtk.main_iteration(False)
      else:
        progresswin.hide()
    except: return
    except Exception as e:
        log.ERR("gui_startup()", e)




# Encapsulates references to gtk objects AND properties in main window,
# which allows to use self. and main. almost interchangably.
#