Check-in [6fab0e7170]
Overview
Comment: | Made channel tabs reorderable. Now kept in config/window.json as `tab_order` and current page saved as `tab_current` instead of pageno. Disabled progressbar changes for ahttp, made search_server search run in a thread so status can be shown. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
6fab0e71703f85523999aeb4cbf0db08 |
User & Date: | mario on 2015-04-03 20:43:42 |
Other Links: | manifest | tags |
Context
2015-04-03
| ||
20:46 | Removed Gtk `theme` configuration options. (Didn't work anymore.) -- Addendum: If anyone has been using this, please drop me a line; it could become a plugin now.. check-in: ad852f14fe user: mario tags: trunk | |
20:43 | Made channel tabs reorderable. Now kept in config/window.json as `tab_order` and current page saved as `tab_current` instead of pageno. Disabled progressbar changes for ahttp, made search_server search run in a thread so status can be shown. check-in: 6fab0e7170 user: mario tags: trunk | |
17:37 | Removed doubled radio button grouping in GtkBuilder file for search_dialog. check-in: 5377cdecb5 user: mario tags: trunk | |
Changes
Modified PACKAGERS from [3311a1cdd3] to [aedd6e0017].
1 2 | This is a short summary for distribution package maintainers. | | | | | | | | 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 | This is a short summary for distribution package maintainers. For regular end-user documentation please see the help/ pages. Structural changes from 2.1.5 onwards (2015-04-xx) -------------------------------------------------- โ There's a new `bin` script. It's a lightweight invocation wrapper, intended to be installed as /usr/bin/streamtuner2 now. Which hopefully avoids lengthy patches in the future. โ The previous `st2.py` still exists, but is now supposed to reside in `/usr/share/streamtuner2/st2.py` along with all other modules. โ Theoretically it's now possible to change the target path even (just edit `bin`). I'd still advise to use /usr/share/streamtuner2/ as main target directory though. It's not yet practical to extract into Python site-package directories. The channel PNG files have been soaked into the .py includes. Though one could still package any static *.png alongside. (Both will remain supported, for simplicity.) Renames ------- ยท bookmarks, configdialog, streamedit were extracted into channels/ - which is why the main module got lighter. |
︙ | ︙ | |||
45 46 47 48 49 50 51 | โ and `logo.png` is the pixmap/app icon Removed ------- | | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | โ and `logo.png` is the pixmap/app icon Removed ------- Most plugin PNGs may have been removed already. (Embedded binary data may violate some distro guidelines(?), but hey, fewer files are fewer files!) And the streamtuner2.png logo is now source-embedded instead, the `logo.py` module provides a `logo.png` base64-string. The old `gtk2.xml` file is gone. It probably became obsolete a long while back. The gtk3.xml is instead runtime-patched to work with PyGTK/gtk2. Dependencies |
︙ | ︙ | |||
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 | Lazy installation ----------------- The new .PYZ archive bundles everything into a ZIP file. Which, given the right shebang, could just be "installed" as literal /usr/bin/streamtuner2 even. I'm sure nobody is going to do so. But you know, it's at least a theoretical option now.. FPM/XPM packaging ----------------- You may have noticed (and scoffed at ;) the newer packaging method. It's now using http://fossil.include-once.org/xpm/ with the `src` filter. (That's what the meta comment blocks in the source modules were always meant for.) Repo ---- The source code is hosted in a Fossil repo. | > > > > > > > > > | 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 | Lazy installation ----------------- The new .PYZ archive bundles everything into a ZIP file. Which, given the right shebang, could just be "installed" as literal /usr/bin/streamtuner2 even. I'm sure nobody is going to do so. But you know, it's at least a theoretical option now.. And this PYZ-packaging scheme is the main reason for the restructuring, and embedded PNGs for example. (Albeit that wasn't strictly necessary.) FPM/XPM packaging ----------------- You may have noticed (and scoffed at ;) the newer packaging method. It's now using http://fossil.include-once.org/xpm/ with the `src` filter. (That's what the meta comment blocks in the source modules were always meant for.) Simplifies DEB and RPM packaging, as well as PYZ generation. (They're all workable, but decidedly rather crude packages. So yes, proper distro packages are very much still needed.) Repo ---- The source code is hosted in a Fossil repo. |
︙ | ︙ |
Modified ahttp.py from [20908d5cb6] to [eff6de2cac].
︙ | ︙ | |||
73 74 75 76 77 78 79 | r = session.get(url, params=params, headers=headers, timeout=9.75) __print__( dbg.HTTP, r.request.headers ); __print__( dbg.HTTP, r.headers ); # finish, clean statusbar #progress_feedback(0.9) | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | r = session.get(url, params=params, headers=headers, timeout=9.75) __print__( dbg.HTTP, r.request.headers ); __print__( dbg.HTTP, r.headers ); # finish, clean statusbar #progress_feedback(0.9) #progress_feedback("") # result __print__( dbg.INFO, "Content-Length", len(r.content) ) if not content: return r elif binary: return r.content |
︙ | ︙ |
Modified channels/__init__.py from [af174af9c9] to [98bda28d4c].
︙ | ︙ | |||
569 570 571 572 573 574 575 576 | # try to initialize superclass now, before adding to channel tabs GenericChannel.gui(self, parent) # add notebook tab tab = parent.notebook_channels.insert_page_menu(vbox, ev_label, plain_label, -1) | > | 569 570 571 572 573 574 575 576 577 | # try to initialize superclass now, before adding to channel tabs GenericChannel.gui(self, parent) # add notebook tab tab = parent.notebook_channels.insert_page_menu(vbox, ev_label, plain_label, -1) parent.notebook_channels.set_tab_reorderable(vbox, True) |
Modified channels/search.py from [0a5546848e] to [8e5b1ccd0f].
︙ | ︙ | |||
76 77 78 79 80 81 82 | 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) | > | > | 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 | 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.status("") self.main.channel_switch(self.main.notebook_channels, "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: self.main.status("Server searching: " + cn.module) __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: |
︙ | ︙ |
Modified config.py from [31dd5cfc2a] to [2f8e9d09d8].
︙ | ︙ | |||
137 138 139 140 141 142 143 | self.show_bookmarks = 1 self.show_favicons = 1 self.load_favicon = 1 self.heuristic_bookmark_update = 0 self.retain_deleted = 0 self.auto_save_appstate = 1 self.theme = "" #"MountainDew" | < | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | self.show_bookmarks = 1 self.show_favicons = 1 self.load_favicon = 1 self.heuristic_bookmark_update = 0 self.retain_deleted = 0 self.auto_save_appstate = 1 self.theme = "" #"MountainDew" self.reuse_m3u = 1 self.google_homepage = 0 self.windows = platform.system()=="Windows" self.pyquery = 1 self.debug = 0 |
︙ | ︙ |
Modified gtk3.xml from [3744082ff5] to [803063bf6c].
︙ | ︙ | |||
786 787 788 789 790 791 792 | <packing> <property name="expand">True</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> | < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 | <packing> <property name="expand">True</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <placeholder/> </child> <child> <object class="GtkHSeparator" id="hseparator1"> <property name="visible">True</property> <property name="can_focus">False</property> </object> <packing> |
︙ | ︙ | |||
1211 1212 1213 1214 1215 1216 1217 | <property name="label" translatable="yes">all channels</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="xalign">0.5</property> <property name="active">True</property> <property name="draw_indicator">True</property> | < | 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 | <property name="label" translatable="yes">all channels</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="xalign">0.5</property> <property name="active">True</property> <property name="draw_indicator">True</property> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> |
︙ | ︙ | |||
1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 | </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <object class="GtkEntry" id="timer_value"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="invisible_char">โ</property> <property name="text" translatable="yes">Fri,Sat 20:00-21:00</property> <property name="primary_icon_activatable">False</property> <property name="secondary_icon_activatable">False</property> </object> <packing> <property name="left_attach">1</property> <property name="right_attach">2</property> <property name="top_attach">1</property> <property name="bottom_attach">2</property> </packing> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 | </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <object class="GtkEntry" id="timer_value"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="invisible_char">โ</property> <property name="text" translatable="yes">Fri,Sat 20:00-21:00</property> <property name="primary_icon_activatable">False</property> <property name="secondary_icon_activatable">False</property> </object> <packing> <property name="left_attach">1</property> <property name="right_attach">2</property> <property name="top_attach">1</property> <property name="bottom_attach">2</property> </packing> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> <placeholder/> </child> <child> |
︙ | ︙ | |||
3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 | </object> <packing> <property name="resize">True</property> <property name="shrink">True</property> </packing> </child> </object> </child> <child type="tab"> <object class="GtkHBox" id="c_bookmarks"> <property name="visible">True</property> <property name="can_focus">False</property> <signal name="popup-menu" handler="on_homepage_channel_clicked" swapped="no"/> <child> | > > > | 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 | </object> <packing> <property name="resize">True</property> <property name="shrink">True</property> </packing> </child> </object> <packing> <property name="reorderable">True</property> </packing> </child> <child type="tab"> <object class="GtkHBox" id="c_bookmarks"> <property name="visible">True</property> <property name="can_focus">False</property> <signal name="popup-menu" handler="on_homepage_channel_clicked" swapped="no"/> <child> |
︙ | ︙ |
Modified st2.py from [1e504cb8ac] to [5fd894f832].
︙ | ︙ | |||
193 194 195 196 197 198 199 | # "menu_bugreport": lambda w: BugReport(), "menu_copy": self.menu_copy, "delete_entry": self.delete_entry, # search dialog "quicksearch_set": self.search.quicksearch_set, "search_open": self.search.menu_search, "search_go": self.search.cache_search, | | | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | # "menu_bugreport": lambda w: BugReport(), "menu_copy": self.menu_copy, "delete_entry": self.delete_entry, # search dialog "quicksearch_set": self.search.quicksearch_set, "search_open": self.search.menu_search, "search_go": self.search.cache_search, "search_srv": lambda *w: self.thread(lambda: self.search.server_search(None)), "search_cancel": self.search.cancel, "true": lambda w,*args: True, # win_streamedit "streamedit_open": self.streamedit.open, "streamedit_save": self.streamedit.save, "streamedit_new": self.streamedit.new, "streamedit_cancel": self.streamedit.cancel, |
︙ | ︙ | |||
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | # shortcut to statusbar # (hacked to work from within threads, circumvents the statusbar msg pool actually) def status(self, text="", sbar_msg=[]): # init sbar_cid = self.get_widget("statusbar").get_context_id("messages") # remove text while ((not text) and (type(text)==str) and len(sbar_msg)): sbar_msg.pop() uikit.do(lambda:self.statusbar.pop(sbar_cid)) # progressbar if (type(text)==float): if text >= 0.999 or text < 0.0: # completed uikit.do(lambda:self.progress.hide()) else: # show percentage | > | | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | # shortcut to statusbar # (hacked to work from within threads, circumvents the statusbar msg pool actually) def status(self, text="", sbar_msg=[]): __print__(dbg.ERR, "status(", text, ")") # init sbar_cid = self.get_widget("statusbar").get_context_id("messages") # remove text while ((not text) and (type(text)==str) and len(sbar_msg)): sbar_msg.pop() uikit.do(lambda:self.statusbar.pop(sbar_cid)) # progressbar if (type(text)==float): if text >= 0.999 or text < 0.0: # completed uikit.do(lambda:self.progress.hide()) else: # show percentage uikit.do(lambda:self.progress.show() or self.progress.set_fraction(text)) if (text <= 0): # unknown state uikit.do(lambda:self.progress.pulse()) # add text elif (type(text)==str): sbar_msg.append(1) uikit.do(lambda:self.statusbar.push(sbar_cid, text)) pass |
︙ | ︙ |
Modified uikit.py from [efa7474e76] to [2c0d4193cf].
︙ | ︙ | |||
297 298 299 300 301 302 303 | r[wn]["row:selected"] = paths[0] # gtk.Toolbar if t == gtk.Toolbar: r[wn]["icon_size"] = int(w.get_icon_size()) r[wn]["style"] = int(w.get_style()) # gtk.Notebook if t == gtk.Notebook: | < > > | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | r[wn]["row:selected"] = paths[0] # gtk.Toolbar if t == gtk.Toolbar: r[wn]["icon_size"] = int(w.get_icon_size()) r[wn]["style"] = int(w.get_style()) # gtk.Notebook if t == gtk.Notebook: r[wn]["tab_pos"] = int(w.get_tab_pos()) r[wn]["tab_order"] = [w.get_menu_label_text(w.get_nth_page(i)) for i in xrange(0, w.get_n_pages())] r[wn]["tab_current"] = w.get_menu_label_text(w.get_nth_page(w.get_current_page())) #print(r) return r gtk_position_type_enum = [gtk.POS_LEFT, gtk.POS_RIGHT, gtk.POS_TOP, gtk.POS_BOTTOM] #-- restore window and widget properties |
︙ | ︙ | |||
339 340 341 342 343 344 345 | w.get_selection().select_path(tuple(args)) # gtk.Toolbar if method == "icon_size": w.set_icon_size(args) if method == "style": w.set_style(args) # gtk.Notebook | | | | | | > > > > > > > > | 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | w.get_selection().select_path(tuple(args)) # gtk.Toolbar if method == "icon_size": w.set_icon_size(args) if method == "style": w.set_style(args) # gtk.Notebook if method == "tab_pos": w.set_tab_pos(r[wn]["tab_pos"]) if method == "tab_order": tab_current = r[wn].get("tab_current") for pos,ord_tabname in enumerate(args): # compare current label list on each reordering round for i in range(0, w.get_n_pages()): w_tab = w.get_nth_page(i) w_label = w.get_menu_label_text(w_tab) if w_label == ord_tabname: w.reorder_child(w_tab, pos) if tab_current == ord_tabname: w_set_current_page(pos) pass #-- Save-As dialog # @staticmethod |
︙ | ︙ |