Check-in [24a5fe69a1]
Overview
Comment: | Add workaround for ArgumentParser, which tries to map config: descriptors onto AP.add_argument(*yikes) params. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
24a5fe69a17765e7fd94431b90884c19 |
User & Date: | mario on 2015-04-06 18:55:12 |
Original Comment: | Add workaround for ArgumentParser, which tries to map config: descriptors onto AP.add_argument() params. (yikes) |
Other Links: | manifest | tags |
Context
2015-04-07
| ||
05:51 | Move argv initialization to conf.apply_args(). Document config: format for argparse conversion. Enable file=sys.stderr for __print__/debug messages. check-in: 1eea3140f8 user: mario tags: trunk | |
2015-04-06
| ||
18:55 | Add workaround for ArgumentParser, which tries to map config: descriptors onto AP.add_argument(*yikes) params. check-in: 24a5fe69a1 user: mario tags: trunk | |
18:53 | Add UserAgentSwitcher plugin. (Just for experimenting really, not required.) check-in: e8c162f72a user: mario tags: trunk | |
Changes
Modified Makefile from [0d018ef979] to [d3f05bad3b].
1 2 3 4 5 6 7 8 9 10 | # Requires # ยท http://fossil.include-once.org/versionnum/ # ยท http://fossil.include-once.org/xpm/ SHELL := /bin/bash #(for brace expansion) NAME := streamtuner2 VERSION := $(shell version get:plugin st2.py || echo 2.1dev) DEST := /usr/share/streamtuner2 INST := install -m 644 PACK := xpm | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # Requires # ยท http://fossil.include-once.org/versionnum/ # ยท http://fossil.include-once.org/xpm/ SHELL := /bin/bash #(for brace expansion) NAME := streamtuner2 VERSION := $(shell version get:plugin st2.py || echo 2.1dev) DEST := /usr/share/streamtuner2 INST := install -m 644 PACK := xpm DEPS := -n $(NAME) -d python -d python-pyquery -d python-gtk2 -d python-requests -d python-keybinder OPTS := -s src -u man,fixperms -f --prefix=$(DEST) --deb-compression xz --rpm-compression xz --exe-autoextract .PHONY: bin all: gtk3 #(most used) pack: all ver docs xpm src gtk3: gtk3.xml.gz zip: pyz |
︙ | ︙ |
Modified cli.py from [b00bb5a675] to [436f001346].
︙ | ︙ | |||
37 38 39 40 41 42 43 | # channel plugins channel_modules = ["shoutcast", "xiph", "internet_radio", "jamendo", "myoggradio", "live365"] current_channel = "cli" plugins = {} # only populated sparsely by .stream() # start | | | | > | > > > | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | # channel plugins channel_modules = ["shoutcast", "xiph", "internet_radio", "jamendo", "myoggradio", "live365"] current_channel = "cli" plugins = {} # only populated sparsely by .stream() # start def __init__(self, actions): # fake init action.action.main = empty_parent() action.action.main.current_channel = self.current_channel # check if enough arguments, else help if not actions: a = self.help # first cmdline arg == action else: command = actions[0] if command in self.__dict__: cmd = self.__getattribute__(command) else: print "No such command:", command return # run result = cmd(*actions[1:]) if result: self.json(result) # show help def help(self, *args): print(""" |
︙ | ︙ |
Modified config.py from [2154593dfb] to [af23ce772a].
1 2 3 4 5 6 | # # encoding: UTF-8 # api: streamtuner2 # type: class # title: global config object # description: reads ~/.config/streamtuner/*.json files | | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # # encoding: UTF-8 # api: streamtuner2 # type: class # title: global config object # description: reads ~/.config/streamtuner/*.json files # config: # { arg: -d, type: str, name: plugin[], description: omit plugin from initialization } # { arg: --gtk3, type: boolean, name: gtk3, description: use gtk3 interface } # { arg: -D, type: boolean, name: debug, description: enable debug messages on console } # { arg: action, type: str*, name: action[], description: commandline actions } # { arg: -x, type: boolean, name: exit, description: terminate right away } # # In the main application or module files which need access # to a global conf.* object, just import this module as follows: # # from config import * # # Here conf is already an instantiation of the underlying |
︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import platform import re from compat2and3 import gzip_decode, find_executable import zlib import zipfile import inspect import pkgutil # export symbols __all__ = ["conf", "__print__", "dbg", "plugin_meta", "module_list", "get_data", "find_executable"] #-- create a stub instance of config object conf = object() | > | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | import platform import re from compat2and3 import gzip_decode, find_executable import zlib import zipfile import inspect import pkgutil import argparse # export symbols __all__ = ["conf", "__print__", "dbg", "plugin_meta", "module_list", "get_data", "find_executable"] #-- create a stub instance of config object conf = object() |
︙ | ︙ | |||
48 49 50 51 52 53 54 55 56 57 58 59 60 61 | # Global configuration store # # Autointializes itself on startup, makes conf.vars available. # Also provides .load() and .save() for JSON data/cache files. # class ConfigDict(dict): # start def __init__(self): # object==dict means conf.var is conf["var"] self.__dict__ = self # let's pray this won't leak memory due to recursion issues | > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | # Global configuration store # # Autointializes itself on startup, makes conf.vars available. # Also provides .load() and .save() for JSON data/cache files. # class ConfigDict(dict): args = {} # start def __init__(self): # object==dict means conf.var is conf["var"] self.__dict__ = self # let's pray this won't leak memory due to recursion issues |
︙ | ︙ | |||
73 74 75 76 77 78 79 80 81 82 83 84 85 86 | del last["share"] self.update(last) self.migrate() # store defaults in file else: self.save("settings") self.firstrun = 1 # some defaults def defaults(self): self.play = { "audio/mpeg": self.find_player(), "audio/ogg": self.find_player(), | > > > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | del last["share"] self.update(last) self.migrate() # store defaults in file else: self.save("settings") self.firstrun = 1 # add argv self.args = self.init_args(argparse.ArgumentParser()) # some defaults def defaults(self): self.play = { "audio/mpeg": self.find_player(), "audio/ogg": self.find_player(), |
︙ | ︙ | |||
245 246 247 248 249 250 251 | except: netrc = parser(self.xdg() + "/netrc").hosts except: pass for server in varhosts: if server in netrc: return netrc[server] | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | except: netrc = parser(self.xdg() + "/netrc").hosts except: pass for server in varhosts: if server in netrc: return netrc[server] # Use config: definitions for argv extraction def init_args(self, ap): for opt in plugin_meta(frame=0).get("config"): kwargs = self.argparse_map(opt) #print kwargs if kwargs: args = kwargs["args"] del kwargs["args"] ap.add_argument(*args, **kwargs) return ap.parse_args() # Transform config: description into quirky ArgumentParser list def argparse_map(self, opt): if not ("arg" in opt and opt["name"] and opt["type"]): return {} # Extract --flag names args = opt["arg"].split() + re.findall("-+\w+", opt["name"]) # Prepare mapping options typing = re.findall("bool|str|\[\]|store|append|const", opt["type"]) naming = re.findall("\[\]", opt["name"]) name = re.findall("(?<!-)\\b\\w+", opt["name"]) nargs = re.findall("\\b\d+\\b|\?|\*", opt["type"]) or [None] # Populate partially - ArgumentParser is highly fragile with combinations of named params kwargs = { "args": args, "dest": name[0] if not name[0] in args else None, "action": "append" if "[]" in (naming+typing) else ("store_true" if "bool" in typing else "store"), "nargs": nargs[0], "default": opt["value"], # "type": int if "int" in typing else bool if "bool" in typing else str, "choices": opt["select"].split("|") if "select" in opt else None, # "required": "required" in opt, "help": opt["description"] or "", } return dict((k,w) for k,w in kwargs.items() if w is not None) # Retrieve content from install path or pyzip archive (alias for pkgutil.get_data) # def get_data(fn, decode=False, gz=False, file_base="config"): try: bin = pkgutil.get_data(file_base, fn) |
︙ | ︙ |
Modified st2.py from [a62db5a28b] to [2915a6cb3f].
︙ | ︙ | |||
487 488 489 490 491 492 493 | # startup procedure def main(): | | | | | | | < < | | | | | 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 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | # startup procedure def main(): # process a few command line flags if conf.args.plugin: for p_id in conf.args.plugin: conf.plugins[p_id] = 0 if conf.args.debug conf.debug = conf.args.debug if conf.args.exit: return # graphical if not len(conf.args.action[0]): # prepare for threading in Gtk+ callbacks gobject.threads_init() # prepare main window main = StreamTunerTwo() # first invocation if (conf.get("firstrun")): main.configwin.open(None) del conf.firstrun # run gtk.main() __print__(dbg.PROC, r"[31m gtk_main_quit [0m") # invoke command-line interface else: import cli cli.StreamTunerCLI(conf.args.action[0]) # run if __name__ == "__main__": main() |
Modified uikit.py from [c920bbe1ed] to [594d66e076].
︙ | ︙ | |||
32 33 34 35 36 37 38 | import inspect from compat2and3 import unicode, xrange, PY3, gzip_decode # gtk version (2=gtk2, 3=gtk3, 7=tk;) ver = 2 # if running on Python3 or with commandline flag | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | import inspect from compat2and3 import unicode, xrange, PY3, gzip_decode # gtk version (2=gtk2, 3=gtk3, 7=tk;) ver = 2 # if running on Python3 or with commandline flag if PY3 or conf.args.gtk3: ver = 3 # load gtk modules if ver==3: from gi import pygtkcompat as pygtk pygtk.enable() pygtk.enable_gtk(version='3.0') from gi.repository import Gtk as gtk |
︙ | ︙ |