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