Skip to content

Instantly share code, notes, and snippets.

@flaviut
Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flaviut/9feb9a75bd452e6ddd03 to your computer and use it in GitHub Desktop.
Save flaviut/9feb9a75bd452e6ddd03 to your computer and use it in GitHub Desktop.
import osproc, strutils, pegs, os, parseopt2, sequtils
type Application = object
id: int
name: string
volume: float
var verbose = false
proc tryExec(cmd): auto =
if verbose: echo("executing $1" % [cmd])
let output = execCmdEx(cmd)
if output.exitCode != 0:
raise newException(EBase, "Failed to execute `$1` with error code $2\nOutput:\n===\n$3\n===" %
[cmd, $output.exitCode, output.output])
return output.output
iterator getPlayingApps(): auto =
let paOutput = tryExec("pactl list sink-inputs")
let sinkStrings = paOutput.split("\l\l")
for str in sinkStrings:
var num: int
var volume: float
var applicationName: string
var matches = ["", ""]
if str.find(peg"'Sink Input #'{\d+}", matches) != -1:
num = parseInt(matches[0])
else:
raise newException(EBase, "Could not find sink input number in \n===\n$1" % [str])
if str.find(peg"'Volume'@'/'\s*{\d+}'%'", matches) != -1:
volume = parseFloat(matches[0])
else:
raise newException(EBase, "Could not find application volume in \n===\n$1" % [str])
if str.find(peg"'application.name = ""'{[^""]+}'""'", matches) != -1:
applicationName = matches[0]
else:
raise newException(EBase, "Could not find application name in \n===\n$1" % [str])
yield Application(id: num, name: applicationName, volume: volume)
proc adjustAppVolume(app: Application, percent: float) =
let nextVol = min((app.volume + (app.volume * (percent - 100) / 100.0)).int, 100)
discard tryExec("pactl set-sink-input-volume $1 $2%" % [$app.id, $nextVol])
proc adjustName(name: string, percent: float) =
for app in getPlayingApps():
if app.name.contains(peg(name)):
adjustAppVolume(app, percent)
proc printInfo() =
for app in getPlayingApps():
echo("$1\t$2\t$3" % [$app.id, app.name, $app.volume])
var params: seq[string] = @[]
for kind, key, val in getopt():
case kind
of cmdArgument:
params.add(key)
of cmdLongOption, cmdShortOption:
case key
of "help", "h":
echo "usage: parsepa [-h|--help] [-v|--verbose] [<name expression> percent (-a|--adjust)] [-p|--print]"
quit(QuitSuccess)
of "verbose", "v":
verbose = true
of "adjust", "a":
adjustName(params[0], parseFloat(params[1]))
quit(QuitSuccess)
of "print", "p":
printInfo()
quit(QuitSuccess)
else:
echo "Invalid Argument"
quit(QuitFailure)
else:
echo "Invalid Argument"
quit(QuitFailure)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment