Created
November 13, 2016 14:03
-
-
Save offensivelyaverage/637dbc7a88121775f14843de1fbce324 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import signal | |
import gi | |
gi.require_version('Gtk', '3.0') | |
gi.require_version('AppIndicator3', '0.1') | |
from gi.repository import Gtk, AppIndicator3, GObject | |
import time | |
from threading import Thread | |
import os | |
import subprocess | |
# --- set the number of recently used files to appear below | |
n = 10 | |
# --- | |
home = os.environ["HOME"] | |
recdata = os.path.join(home, ".local/share/recently-used.xbel") | |
currpath = os.path.dirname(os.path.realpath(__file__)) | |
class Indicator(): | |
def __init__(self): | |
self.app = 'show_recent' | |
iconpath = os.path.join(currpath, "recent.png") | |
self.indicator = AppIndicator3.Indicator.new( | |
self.app, iconpath, | |
AppIndicator3.IndicatorCategory.OTHER) | |
self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE) | |
self.indicator.set_menu(self.create_menu()) | |
# the thread: | |
self.update = Thread(target=self.check_recent) | |
# daemonize the thread to make the indicator stopable | |
self.update.setDaemon(True) | |
self.update.start() | |
def get_files(self): | |
# create the list of recently used files | |
used = [l for l in open(recdata) if \ | |
all([ | |
'<bookmark href="file://' in l, | |
not "/tmp" in l, | |
"." in l, | |
])] | |
relevant = [l.split('="') for l in set(used)] | |
relevant = [[it[1][7:-7], it[-2][:-10]] for it in relevant] | |
relevant.sort(key=lambda x: x[1]) | |
return [item[0].replace("%20", " ") for item in relevant[::-1][:n]] | |
def create_menu(self): | |
# creates the (initial) menu | |
self.menu = Gtk.Menu() | |
# separator | |
menu_sep = Gtk.SeparatorMenuItem() | |
self.menu.append(menu_sep) | |
# item_quit.show() | |
self.menu.show_all() | |
return self.menu | |
def open_file(self, *args): | |
# opens the file with the default application | |
index = self.menu.get_children().index(self.menu.get_active()) | |
selection = self.menu_items2[index] | |
subprocess.Popen(["xdg-open", selection]) | |
def set_new(self): | |
# update the list, appearing in the menu | |
for i in self.menu.get_children(): | |
self.menu.remove(i) | |
for file in self.menu_items2: | |
sub = Gtk.MenuItem(file) | |
self.menu.append(sub) | |
sub.connect('activate', self.open_file) | |
# separator | |
menu_sep = Gtk.SeparatorMenuItem() | |
self.menu.append(menu_sep) | |
# quit | |
item_quit = Gtk.MenuItem('Quit') | |
item_quit.connect('activate', self.stop) | |
self.menu.append(item_quit) | |
self.menu.show_all() | |
def check_recent(self): | |
self.menu_items1 = [] | |
while True: | |
time.sleep(3) | |
self.menu_items2 = self.get_files() | |
if self.menu_items2 != self.menu_items1: | |
GObject.idle_add( | |
self.set_new, | |
priority=GObject.PRIORITY_DEFAULT | |
) | |
self.menu_items1 = self.menu_items2 | |
def stop(self, source): | |
Gtk.main_quit() | |
Indicator() | |
# this is where we call GObject.threads_init() | |
GObject.threads_init() | |
signal.signal(signal.SIGINT, signal.SIG_DFL) | |
Gtk.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment