diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..bee8a64b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/autorandr/__init__.py b/autorandr/__init__.py new file mode 100644 index 00000000..f29eb418 --- /dev/null +++ b/autorandr/__init__.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- + +"""Load and save autorandr configs. + +Load and save configs. Requires autorandr to be installed. + +Synopsis: [load|save] """ + +from albertv0 import * +import os +import subprocess +from time import sleep + + +__iid__ = "PythonInterface/v0.2" +__prettyname__ = "Autorandr" +__version__ = "1.0" +__trigger__ = "ar " +__author__ = "Rhys Tyers" +__dependencies__ = ["autorandr"] + +configurations = [] + +def initialize(): + global configurations + result = subprocess.run(["autorandr", "--detected"], stdout=subprocess.PIPE) + result.stdout.decode('utf-8') + configurations = result.stdout.decode().split() + +def handleQuery(query): + if not query.isTriggered: + return + + queryList = query.string.split() + results = [] + + # Load + if queryList[0] != 'load' and 'load'.startswith(queryList[0]): + item = Item(id=__prettyname__, + icon=os.path.dirname(__file__)+"/monitor.svg", + text="Load", + subtext="Load a saved xrandr configuration", + completion=__trigger__ + 'load ', + urgency=ItemBase.Alert, + actions=[]) + results.append(item) + if queryList[0] == 'load': + for configuration in configurations: + if len(queryList) < 2 or configuration.startswith(queryList[1]): + item = Item(id=__prettyname__, + icon=os.path.dirname(__file__)+"/monitor.svg", + text="Load " + configuration, + subtext="Load the " + configuration + " xrandr configuration", + completion=__trigger__ + 'load ' + configuration, + urgency=ItemBase.Alert, + actions=[ + ProcAction(text="ProcAction", + commandline=["autorandr", "--change", configuration], + ) + ]) + results.append(item) + + # Save + if queryList[0] != 'save' and 'save'.startswith(queryList[0]): + item = Item(id=__prettyname__, + icon=os.path.dirname(__file__)+"/monitor.svg", + text="Save", + subtext="Save the current xrandr configuration", + completion=__trigger__ + 'save ', + urgency=ItemBase.Alert, + actions=[]) + results.append(item) + if queryList[0] == 'save': + item = Item(id=__prettyname__, + icon=os.path.dirname(__file__)+"/monitor.svg", + text="Save " + queryList[1], + subtext="Save the current xrandr configuration as " + queryList[1], + urgency=ItemBase.Alert, + completion=__trigger__ + 'save ', + actions=[ + ProcAction(text="ProcAction", + commandline=["autorandr", "--save", queryList[1]], + ) + ]) + results.append(item) + + # refresh + if 'refresh'.startswith(queryList[0]): + item = Item(id=__prettyname__, + icon=os.path.dirname(__file__)+"/monitor.svg", + text="Refresh", + subtext="Refresh xrandr configuration", + completion=__trigger__ + 'refresh ', + urgency=ItemBase.Alert, + actions=[ + FuncAction(initialize) + ]) + results.append(item) + + return results diff --git a/autorandr/monitor.svg b/autorandr/monitor.svg new file mode 100644 index 00000000..bc4b4567 --- /dev/null +++ b/autorandr/monitor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/vpn.py b/vpn.py new file mode 100644 index 00000000..97d6e4ab --- /dev/null +++ b/vpn.py @@ -0,0 +1,65 @@ +"""VPN Extension + +Connect or disconnect from a network manager VPN profile""" + + +import subprocess +from collections import namedtuple +from albertv0 import * +from shutil import which + + +__iid__ = "PythonInterface/v0.2" +__prettyname__ = "VPN" +__version__ = "1.0" +__trigger__ = "vpn " +__author__ = "janeklb" +__dependencies__ = ['nmcli'] + + +iconPath = iconLookup('network-wireless') +if not iconPath: + iconPath = ":python_module" + +VPNConnection = namedtuple('VPNConnection', ['name', 'connected']) + + +def getVPNConnections(): + consStr = subprocess.check_output( + 'nmcli -t connection show', + shell=True, + encoding='UTF-8' + ) + for conStr in consStr.splitlines(): + con = conStr.split(':') + if con[2] == 'vpn': + yield VPNConnection(name=con[0], connected=con[3] != '') + + +def buildItem(con): + name = con.name + command = 'down' if con.connected else 'up' + text = f'Connect to {name}' if command == 'up' else f'Disconnect from {name}' + commandline = ['nmcli', 'connection', command, 'id', name] + return Item( + id=f'vpn-{command}-{name}', + text=name, + subtext=text, + icon=iconPath, + completion=name, + actions=[ ProcAction(text=text, commandline=commandline) ] + ) + + +def initialize(): + if which('nmcli') is None: + raise Exception("'nmcli' is not in $PATH") + + +def handleQuery(query): + if query.isValid and query.isTriggered: + connections = getVPNConnections() + if query.string: + connections = [ con for con in connections if query.string.lower() in con.name.lower() ] + return [ buildItem(con) for con in connections ] + return []