This commit is contained in:
Noam
2018-09-02 18:51:19 +03:00
parent 4a4e4c58d0
commit efc32d9935
8 changed files with 362 additions and 0 deletions

141
main.py Normal file
View File

@@ -0,0 +1,141 @@
import os
import logging
import distutils.spawn
from ulauncher.api.client.Extension import Extension
from ulauncher.api.client.EventListener import EventListener
from ulauncher.api.shared.event import KeywordQueryEvent
from ulauncher.api.shared.item.ExtensionResultItem import ExtensionResultItem
from ulauncher.api.shared.item.SmallResultItem import SmallResultItem
from ulauncher.api.shared.action.RenderResultListAction import RenderResultListAction
from ulauncher.api.shared.action.RunScriptAction import RunScriptAction
logging.basicConfig()
logger = logging.getLogger(__name__)
# Initialize items cache and Remmina profiles path
remmina_bin = ''
# Locate Remmina profiles and binary
remmina_profiles_path = "{}/.local/share/remmina".format(os.environ.get('HOME'))
remmina_bin = distutils.spawn.find_executable('remmina')
# This extension is useless without remmina
if remmina_bin is None or remmina_bin == '':
logger.error('Remmina executable path could not be determined')
exit()
# Check if Remmina profiles directory exists
if not os.path.isdir(remmina_profiles_path):
logger.error("Remmina profiles directory doesn't exist ({})".format(remmina_profiles_path))
exit()
class RemminaExtension(Extension):
def __init__(self):
super(RemminaExtension, self).__init__()
self.subscribe(KeywordQueryEvent, KeywordQueryEventListener())
def list_profiles(self, query):
profiles = []
items_cache = []
try:
# Get list of profile files from Remmina directory
for profile in os.listdir(remmina_profiles_path):
if profile.endswith(".remmina"):
profiles.append(os.path.join(remmina_profiles_path, profile))
# Get sorted list of profiles
temp = profiles
profiles = sorted(temp)
except Exception as e:
print('Failed getting profile files')
for p in profiles:
base = os.path.basename(p)
title = os.path.splitext(base)[0]
desc, proto = profile_details(p)
# Search for query inside filename and profile description
# Multiple strings can be used to search in description
# all() is used to achieve a AND search (include all keywords)
keywords = query.split(" ")
# if (query in base.lower()) or (query in desc.lower()):
if (query in base.lower()) or all(x in desc for x in keywords):
items_cache.append(create_item(title, proto, p, desc, p))
return items_cache
class KeywordQueryEventListener(EventListener):
def on_event(self, event, extension):
# Get query
term = (event.get_argument() or '').lower()
# Display all items when query empty
profiles_list = extension.list_profiles(term)
return RenderResultListAction(profiles_list)
def create_item(name, icon, keyword, description, on_enter):
return ExtensionResultItem(
name=name,
description=description,
icon='images/{}.svg'.format(icon),
on_enter=RunScriptAction('#!/usr/bin/env bash\n{} -c {}\n'.format(remmina_bin, on_enter), None)
)
def profile_details(profile_path):
if os.path.isfile(profile_path):
with open(profile_path, "r") as f:
# Read profile file lines
lines = f.read().split("\n")
# Initialize strings
desc = name = username = group = proto = ""
# Parse lines for relevant details
for line in lines:
# Profile name
if line.startswith("name="):
elem = line.split("name=")
if len(elem[1]) > 0:
name = elem[1]
# Profile username (optional)
if "username=" in line:
elem = line.split("username=")
# if len(elem) > 1:
if len(elem[0]) == 0 and len(elem[1]) > 0:
username = elem[1]
elif len(elem[0]) > 0 and len(elem[1]) > 0:
username = elem[1]
# Profile server and port
if line.startswith("server="):
elem = line.split("server=")
if len(elem[1]) > 0:
server = elem[1]
# Profile group name
if line.startswith("group="):
elem = line.split("group=")
if len(elem[1]) > 0:
group = elem[1]
# Profile protocol (for different icons)
if line.startswith("protocol="):
elem = line.split("protocol=")
if len(elem[1]) > 0:
proto = elem[1].strip().lower()
else:
pass
if len(username) > 0:
server = "{username}@{server}".format(username=username,
server=server)
if len(proto) > 0:
server = "{proto}://{server}".format(proto=proto,
server=server)
if len(group) > 0:
group = " | {group}".format(group=group)
desc = "{name} | {server} {group}".format(name=name,
server=server,
group=group)
return desc, proto
else:
# Default values
return "", "rdp"
if __name__ == '__main__':
RemminaExtension().run()