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







|
|







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 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
            
            # fill it up later
            parent.hooks["init"].append(self.populate)


    def populate(self, parent):
    
        # 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



        for row in self.default:
            (genre, title, homepage) = row
            self.streams.append({
                "genre": genre,
                "title": title,
                "homepage": homepage,
                "type": "text/html",







|

|
|
|
|
|
|
|
|
|
>
>
>







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
        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 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
                for bookmark in group.findall("bookmark"):
                    r.append({
                        "genre": group.attrib["name"],
                        "title": bookmark.attrib["name"],
                        "url": bookmark.attrib["url"],
                        "playing": "",
                    })
        except:
            pass
        return r


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







|
|







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

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







>







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
    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)
    # resize
    if image.size[0] > 16:
        image.resize((16, 16), Image.ANTIALIAS)
    # .png format
    image.save(png_fn, "PNG", quality=98)









|







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.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
    # 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)):
            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







<









|







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

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

    # 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

        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)

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







|





|







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

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







|







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





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







|
>







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