ADDED channels/search.py Index: channels/search.py ================================================================== --- channels/search.py +++ channels/search.py @@ -0,0 +1,146 @@ +# api: streamtuner2 +# title: Search feature +# description: Provides the quick search box, and server/cache search window. +# version: 0.9 +# type: feature +# category: ui +# config: - +# priority: core +# +# Configuration dialog for audio applications, +# general settings, and plugin activation and +# associated options. +# + + +from uikit import * +import channels +from config import * +from copy import copy + + +# Search window, and quicksearch box handler. +# +# Aux win: search dialog - keeps search text in self.q +# Quick search textbox - uses main.q instead +# +class search (AuxiliaryWindow): + + # either current channel, or last channel (avoid searching in bookmarks) + current = None + + # show search dialog + def menu_search(self, w): + self.search_dialog.show(); + if not self.current or self.main.current_channel != "bookmarks": + self.current = self.main.current_channel + self.search_dialog_current.set_label("just %s" % self.main.channels[self.current].meta["title"]) + + + # hide dialog box again + def cancel(self, *args): + self.search_dialog.hide() + return True # stop any other gtk handlers + + + # prepare variables + def prepare_search(self): + self.main.status("Searching... Stand back.") + self.cancel() + self.q = self.search_full.get_text().lower() + if self.search_dialog_all.get_active(): + self.targets = self.main.channels.keys() + else: + self.targets = [self.current] + self.main.bookmarks.streams["search"] = [] + + # perform search + def cache_search(self, *w): + self.prepare_search() + entries = [] + # which fields? + fields = ["title", "playing", "homepage"] + for i,cn in enumerate([self.main.channels[c] for c in self.targets]): + if cn.streams: # skip disabled plugins + # categories + for cat in cn.streams.keys(): + # stations + for row in cn.streams[cat]: + # assemble text fields to compare + text = " ".join([str(row.get(f, " ")) for f in fields]) + if text.lower().find(self.q) >= 0: + row = copy(row) + row["genre"] = c + " " + row.get("genre", "") + entries.append(row) + self.show_results(entries) + + # display "search" in "bookmarks" + def show_results(self, entries): + self.main.status(1.0) + self.main.channel_switch(None, "bookmarks", 0) + self.main.bookmarks.set_category("search") + # insert data and show + self.main.channels["bookmarks"].streams["search"] = entries # we have to set it here, else .currentcat() might reset it + self.main.bookmarks.load("search") + + + # live search on directory server homepages + def server_search(self, w): + self.prepare_search() + entries = [] + for i,cn in enumerate([self.main.channels[c] for c in self.targets]): + if cn.has_search: # "search" in cn.update_streams.func_code.co_varnames: + __print__(dbg.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) + self.show_results(entries) + + + # search text edited in text entry box + def quicksearch_set(self, w, *eat, **up): + + # keep query string + self.main.q = self.search_quick.get_text().lower() + + # get streams + c = self.main.channel() + rows = c.stations() + col = c.rowmap.index("search_col") # this is the gtk.ListStore index # which contains the highlighting color + + # callback to compare (+highlight) rows + m = c.gtk_list.get_model() + m.foreach(self.quicksearch_treestore, (rows, self.main.q, col, col+1)) + search_set = quicksearch_set + + + + # callback that iterates over whole gtk treelist, + # looks for search string and applies TreeList color and flag if found + def quicksearch_treestore(self, model, path, iter, extra_data): + i = path[0] + (rows, q, color, flag) = extra_data + + # compare against interesting content fields: + text = rows[i].get("title", "") + " " + rows[i].get("homepage", "") + # config.quicksearch_fields + text = text.lower() + + # simple string match (probably doesn't need full search expression support) + if len(q) and text.find(q) >= 0: + model.set_value(iter, color, "#fe9") # highlighting color + model.set_value(iter, flag, True) # background-set flag + # color = 12 in liststore, flag = 13th position + else: + model.set_value(iter, color, "") # for some reason the cellrenderer colors get applied to all rows, even if we specify an iter (=treelist position?, not?) + model.set_value(iter, flag, False) # that's why we need the secondary -set option + + #?? + return False + + ADDED channels/streamedit.py Index: channels/streamedit.py ================================================================== --- channels/streamedit.py +++ channels/streamedit.py @@ -0,0 +1,47 @@ +# api: streamtuner2 +# title: Stream entry editor +# description: Allows to inspect and modify station/stream entries. +# version: 0.5 +# type: feature +# category: ui +# config: - +# priority: core +# +# Editing dialog for stream entries. Available in +# the context and main menu. Most useful for +# changing bookmarks, or even creating new ones. +# + +from uikit import * +import channels +from config import * +from copy import copy + + +# aux win: stream data editing dialog +class streamedit (AuxiliaryWindow): + + # show stream data editing dialog + def open(self, mw): + self.main.configwin.load_config(self.main.row(), "streamedit_") + self.win_streamedit.show() + + # copy widget contents to stream + def save(self, w): + self.main.configwin.save_config(self.main.row(), "streamedit_") + self.main.channel().save() + self.cancel(w) + + # add a new list entry, update window + def new(self, w): + s = self.main.channel().stations() + s.append({"title":"new", "url":"", "format":"audio/mpeg", "genre":"", "listeners":1}); + self.main.channel().switch() # update display + selfmain.channel().gtk_list.get_selection().select_path(str(len(s)-1)); # set cursor to last row + self.open(w) + + # hide window + def cancel(self, *w): + self.win_streamedit.hide() + return True +