Check-in [4061ff33a6]
Overview
Comment: | Add a shell version, new flags; some more docs. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4061ff33a63455493ea1f283f99aab4b |
User & Date: | mario on 2017-10-13 21:29:20 |
Other Links: | manifest | tags |
Context
2017-10-14
| ||
11:42 | Fix/merge popen and shell variant check-in: 7aa0a47c0b user: mario tags: trunk | |
2017-10-13
| ||
21:29 | Add a shell version, new flags; some more docs. check-in: 4061ff33a6 user: mario tags: trunk | |
18:13 | new plugin: st2subprocess: Alternative process start (player/recording app) methods: subprocess.*, or exec/spawn, and win32 api methods. check-in: 1e00cde4e2 user: mario tags: trunk | |
Changes
Modified contrib/st2subprocess.py from [3aa97fd8d5] to [90d8471ab8].
1 2 3 4 | # encoding: utf-8 # api: streamtuner2 # title: win32/subprocess # description: Utilizes subprocess spawning or win32 API instead of os.system | | | | | | | | | | | > | | | | | | | < > > | | < | | | | | | > > | > < < < < < < < < < | < > | > | > | 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 35 36 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 71 72 73 74 75 76 77 78 79 80 81 | # encoding: utf-8 # api: streamtuner2 # title: win32/subprocess # description: Utilizes subprocess spawning or win32 API instead of os.system # version: 0.3 # depends: streamtuner2 > 2.2.0, python >= 2.7 # priority: optional # config: # { name: cmd_spawn, type: select, select: "popen|shell|call|execv|spawnv|pywin32|win32api|system", value: popen, description: Spawn method } # { name: cmd_flags, type: select, select: "none|nowait|detached|nowaito|all|sw_hide||sw_minimize|sw_show", value: nowait, description: Process creation flags (win32) } # type: handler # category: io # # Overrides the action.run method with subprocess.Popen() and a bit # cmdline parsing. Which mostly makes sense on Windows to avoid some # `start` bugs, such as "http://.." arguments getting misinterpreted. # Also works on Linux, though with few advantages and some gotchas. # # +------------------+-----+------+---------+-------+----------------------+ # | VARIANT | SYS | ARGS | FLAGS | PATHS | NOTES | # +------------------+-----+------+---------+-------+----------------------+ # | subprocess.popen | * | [] | all | base | Most compatible | # | subprocess.shell | lnx | str | all | base | Linux only? | # | subprocess.call | * | [] | all | base& | May block Gtk thread | # | os.execv | w32 | s/[] | - | full& | fork+exec | # | os.spawnv | lnx | s/[] | nowait | full& | ? | # | pywin32.CreatePr | w32 | str | detached| full | Few parameters used | # | win32api.WinExec | w32 | str | sw_show | base | Mostly like `start`? | # | system/default | * | str | - | base | normal action.run() | # +------------------+-----+------+---------+-------+----------------------+ # # ยท The flags are only supported on Windows. The FLAGS column just lists # recommended defaults. Will implicitly be `none` for Linux. # ยท Note that for Linux, you should decorate player commands with "&" and # use absolute paths for call/exec/spawn to work as expected. # ยท streamripper calls will always use the default action.run/os.system # ยท cmdline parsing may not reproduce the original arguments on Windows, # in particular if list2cmdline was used. # ยท Does not yet check for modules being load # ยท Testing mostly. Though might replace action.run someday. Command and # argument parsing is the holdup for not having this earlier. # ยท Unlike action.run() none of the methods does interpret shell variables # or features obviously. Unless you wrap player commands with `sh -c โฆ` # import subprocess import os import shlex import re from config import * from channels import FeaturePlugin import action try: import win32process import win32api except Exception as e: log.ERR("pywin32/win32api not available", e) # hook action.run class st2subprocess (FeaturePlugin): # option strings to creationflags flagmap = { "nowait": os.P_NOWAIT, "detached": 0x00000008, # https://stackoverflow.com/a/13593257/345031 "nowait0": os.P_NOWAITO, "all": 8 | os.P_NOWAIT | os.P_NOWAITO, "wait": os.P_WAIT, "none": 0, "sw_hide": 0, # https://docs.python.org/2.7/library/subprocess.html#subprocess.STARTUPINFO "sw_minimize": 2, # or 6 "sw_show": 5, # https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx } # swap out action.run() def init2(self, parent, *k, **kw): self.osrun = action.run |
︙ | ︙ | |||
99 100 101 102 103 104 105 | args = [re.sub(r'\^(?=[()<>"&^])', '', s) for s in args] # flags flags = self.flagmap[conf.cmd_flags] if conf.windows and conf.cmd_flags in self.flagmap else 0 # debug log.EXEC("st2subprocess:", args, "creationflags=%s"%flags) #-- Popen โ https://docs.python.org/2/library/subprocess.html#popen-constructor | | > | > > > > > > | | | | | | | | 96 97 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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | args = [re.sub(r'\^(?=[()<>"&^])', '', s) for s in args] # flags flags = self.flagmap[conf.cmd_flags] if conf.windows and conf.cmd_flags in self.flagmap else 0 # debug log.EXEC("st2subprocess:", args, "creationflags=%s"%flags) #-- Popen โ https://docs.python.org/2/library/subprocess.html#popen-constructor v = conf.cmd_spawn if v in ("popen"): log.POPEN( subprocess.Popen(args, shell=(v=="shell"), creationflags=flags).__dict__ ) #-- Popen w/ shell=True and string cmd v = conf.cmd_spawn if v in ("popen", "shell"): log.POPEN_SHELL( subprocess.Popen(cmd, shell=(v=="shell"), creationflags=flags).__dict__ ) #-- call โ https://docs.python.org/2/library/subprocess.html#replacing-os-system elif v == "call": log.CALL( subprocess.call(args, creationflags=flags).__dict__ ) #-- execv โ https://docs.python.org/2/library/os.html#os.execv elif v == "execv": log.OS_EXECV( os.execv(args[0], args) if os.fork() == 0 else "..." ) #-- spawnv โ https://docs.python.org/2/library/os.html#os.spawnv elif v == "spawnv": log.OS_SPAWNV( os.spawnv(flags, args[0], args) ) #-- pywin32 โ https://www.programcreek.com/python/example/8489/win32process.CreateProcess elif v == "pywin32": log.WIN32PROCESS_CreateProcess( win32process.CreateProcess( None, cmd, None, None, 0, flags, None, None, win32process.STARTUPINFO() ) ) #-- win32api elif conf.cmd_spawn == "win32api": log.WIN32API_WinExec( win32api.WinExec(cmd, flags) ) # fallback else: return self.osrun(cmd) |
Modified help/contrib_features.page from [6fc33c8f27] to [1559a77213].
︙ | ︙ | |||
229 230 231 232 233 234 235 236 237 238 239 | <section> <subtitle>๐ OGG Icon</subtitle> <p>Introduces small state icons to make higher-quality Vorbis and Opus stations stand out. (Not all channels provide exact format information, so you'll mostly notice for Jamendo and Xiph.) </p> </section> </section> </page> | > > > > > > > > > | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | <section> <subtitle>๐ OGG Icon</subtitle> <p>Introduces small state icons to make higher-quality Vorbis and Opus stations stand out. (Not all channels provide exact format information, so you'll mostly notice for Jamendo and Xiph.) </p> </section> <section> <subtitle>๐ Win32/subprocess</subtitle> <p>Wraps the player/application exec() method. Instead of simple shell execution, uses the Python subprocess module or win32 API functions. This is mostly unneeded on Linux (kills a few features even), but avoids the cmd.exe popup and delay on Windows. Highly experimental at the moment.</p> </section> </section> </page> |