Browse Source

v0.0.2 - Added sorting by usage

Noam 5 years ago
parent
commit
b0027edf5f
3 changed files with 57 additions and 6 deletions
  1. 2 1
      .gitignore
  2. 1 1
      README.md
  3. 54 4
      main.py

+ 2 - 1
.gitignore

@@ -1,2 +1,3 @@
 *tmp*
 *tmp*
-*.gvd*
+*.gvd*
+usage.json

+ 1 - 1
README.md

@@ -1,6 +1,6 @@
 # ulauncher-remmina
 # ulauncher-remmina
 
 
-🖥 Ulauncher extension for quick access to [Remmina](https://remmina.org) profiles.
+🖥 [Ulauncher](https://ulauncher.io) extension for quick access to [Remmina](https://remmina.org) profiles.
 
 
 You can enter several queries to match strings in profiles' descriptions (e.g. `r ssh stan`)
 You can enter several queries to match strings in profiles' descriptions (e.g. `r ssh stan`)
 
 

+ 54 - 4
main.py

@@ -1,17 +1,32 @@
 import os
 import os
+import json
 import logging
 import logging
 import distutils.spawn
 import distutils.spawn
 from ulauncher.api.client.Extension import Extension
 from ulauncher.api.client.Extension import Extension
 from ulauncher.api.client.EventListener import EventListener
 from ulauncher.api.client.EventListener import EventListener
-from ulauncher.api.shared.event import KeywordQueryEvent
+from ulauncher.api.shared.event import KeywordQueryEvent, ItemEnterEvent
 from ulauncher.api.shared.item.ExtensionResultItem import ExtensionResultItem
 from ulauncher.api.shared.item.ExtensionResultItem import ExtensionResultItem
 from ulauncher.api.shared.item.SmallResultItem import SmallResultItem
 from ulauncher.api.shared.item.SmallResultItem import SmallResultItem
 from ulauncher.api.shared.action.RenderResultListAction import RenderResultListAction
 from ulauncher.api.shared.action.RenderResultListAction import RenderResultListAction
 from ulauncher.api.shared.action.RunScriptAction import RunScriptAction
 from ulauncher.api.shared.action.RunScriptAction import RunScriptAction
+from ulauncher.api.shared.action.ExtensionCustomAction import ExtensionCustomAction
 
 
 logging.basicConfig()
 logging.basicConfig()
 logger = logging.getLogger(__name__)
 logger = logging.getLogger(__name__)
 
 
+global usage_cache
+usage_cache = {}
+
+# Usage tracking
+script_directory = os.path.dirname(os.path.realpath(__file__))
+usage_db = os.path.join(script_directory, 'usage.json')
+if os.path.exists(usage_db):
+    with open(usage_db, 'r') as db:
+        # Read JSON string
+        raw = db.read()
+        # JSON to dict
+        usage_cache = json.loads(raw)
+
 # Initialize items cache and Remmina profiles path
 # Initialize items cache and Remmina profiles path
 remmina_bin = ''
 remmina_bin = ''
 # Locate Remmina profiles and binary
 # Locate Remmina profiles and binary
@@ -32,6 +47,7 @@ class RemminaExtension(Extension):
 
 
         super(RemminaExtension, self).__init__()
         super(RemminaExtension, self).__init__()
         self.subscribe(KeywordQueryEvent, KeywordQueryEventListener())
         self.subscribe(KeywordQueryEvent, KeywordQueryEventListener())
+        self.subscribe(ItemEnterEvent, ItemEnterEventListener())
 
 
     def list_profiles(self, query):
     def list_profiles(self, query):
         profiles = []
         profiles = []
@@ -59,6 +75,7 @@ class RemminaExtension(Extension):
             if (query in base.lower()) or all(x in desc for x in keywords):
             if (query in base.lower()) or all(x in desc for x in keywords):
                 items_cache.append(create_item(title, proto, p, desc, p))
                 items_cache.append(create_item(title, proto, p, desc, p))
 
 
+        items_cache = sorted(items_cache, key=sort_by_usage, reverse=True)
         return items_cache
         return items_cache
 
 
 
 
@@ -69,7 +86,28 @@ class KeywordQueryEventListener(EventListener):
         # Display all items when query empty
         # Display all items when query empty
         profiles_list = extension.list_profiles(term)
         profiles_list = extension.list_profiles(term)
 
 
-        return RenderResultListAction(profiles_list)
+        return RenderResultListAction(profiles_list[:8])
+
+
+class ItemEnterEventListener(EventListener):
+    def on_event(self, event, extension):
+        global usage_cache
+        # Get query
+        data = event.get_data()
+        on_enter = data['id']
+        # The profilefile name is the ID
+        base = os.path.basename(on_enter)
+        b = os.path.splitext(base)[0]
+        # Check usage and increment
+        if b in usage_cache:
+            usage_cache[b] = usage_cache[b]+1
+        else:
+            usage_cache[b] = 1
+        # Update usage JSON
+        with open(usage_db, 'w') as db:
+            db.write(json.dumps(usage_cache, indent=2))
+
+        return RunScriptAction('#!/usr/bin/env bash\n{} -c {}\n'.format(remmina_bin, on_enter), None).run()
 
 
 
 
 def create_item(name, icon, keyword, description, on_enter):
 def create_item(name, icon, keyword, description, on_enter):
@@ -77,8 +115,20 @@ def create_item(name, icon, keyword, description, on_enter):
             name=name,
             name=name,
             description=description,
             description=description,
             icon='images/{}.svg'.format(icon),
             icon='images/{}.svg'.format(icon),
-            on_enter=RunScriptAction('#!/usr/bin/env bash\n{} -c {}\n'.format(remmina_bin, on_enter), None)
-    )
+            on_enter=ExtensionCustomAction(
+                 {'id': on_enter})
+            )
+
+
+def sort_by_usage(i):
+    global usage_cache
+    # Convert item name to ID format
+    j = i._name.lower()
+    # Return score according to usage
+    if j in usage_cache:
+        return usage_cache[j]
+    # Default is 0 (no usage rank / unused)
+    return 0
 
 
 
 
 def profile_details(profile_path):
 def profile_details(profile_path):