-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
176 additions
and
63 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.cache | ||
*.pyc | ||
__pycache__ |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,4 @@ | ||
from ulauncher.extension.client.Extension import Extension | ||
from ulauncher.extension.client.EventListener import EventListener | ||
from ulauncher.extension.shared.event import KeywordQueryEvent, ItemEnterEvent | ||
from ulauncher.extension.shared.result_item.ExtensionResultItem import ExtensionResultItem | ||
from ulauncher.result_list.item_action.RenderResultListAction import RenderResultListAction | ||
|
||
|
||
class FileFindExtension(Extension): | ||
|
||
def __init__(self, *args, **kw): | ||
super(FileFindExtension, self).__init__(*args, **kw) | ||
self.file_db = FileDb() | ||
dirs = '\n'.split(config.prefs.get('watch_dirs')) | ||
watcher = FileWatcher(self.file_db) | ||
watcher.watch(dirs) | ||
self.subscribe(KeywordQueryEvent, ExtensionKeywordListener(self.file_db, config)) | ||
self.subscribe(ItemEnterEvent, ItemEnterEventListener(self.file_db, config)) | ||
|
||
|
||
class ExtensionKeywordListener(EventListener): | ||
|
||
def __init__(self, file_db, config): | ||
self.file_db = file_db | ||
super(ExtensionKeywordListener, self).__init__() | ||
|
||
def on_event(self, event): | ||
query = event.get_query() | ||
files = self.file_db.find(query, limit=9) | ||
result_list = [] | ||
for file in files: | ||
result_list.append(ExtensionResultItem(name=file.get_name(), | ||
icon=file.get_icon(), | ||
description=file.get_path(), | ||
enter_action=ExtensionCustomAction(file, True))) | ||
|
||
return RenderResultListAction(result_list) | ||
|
||
|
||
class ItemEnterEventListener(EventListener): | ||
|
||
def __init__(self, file_db, config): | ||
self.file_db = file_db | ||
super(ItemEnterEventListener, self).__init__() | ||
|
||
def on_event(self, event): | ||
file = event.get_data() | ||
OpenAction(file.get_path()).run() # or return action? | ||
|
||
from timer.TimerExtension import TimerExtension | ||
|
||
if __name__ == '__main__': | ||
Extension().run() | ||
TimerExtension().run() |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[tool:pytest] | ||
pep8maxlinelength = 120 | ||
pep8ignore = E402 |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash | ||
|
||
eval "PYTHONPATH=`pwd` py.test --pep8 $@" |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import pytest | ||
from timer.query_parser import parse_query, ParseQueryError | ||
|
||
|
||
def test_parse_query__5m_hello_world__correct_result_returned(): | ||
assert parse_query('5m hello world') == (5 * 60, '5 minutes', 'hello world') | ||
|
||
|
||
def test_parse_query__5h_hello_world__correct_result_returned(): | ||
assert parse_query('5h hello world') == (5 * 60 * 60, '5 hours', 'hello world') | ||
|
||
|
||
def test_parse_query__5__is_correct_query(): | ||
assert parse_query('5') == (5 * 60, '5 minutes', 'Time is up!') | ||
|
||
|
||
def test_parse_query__incorrect_query__ParseQueryError(): | ||
with pytest.raises(ParseQueryError): | ||
assert parse_query('wfa') |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
from ulauncher.extension.client.EventListener import EventListener | ||
from ulauncher.extension.shared.result_item.ExtensionResultItem import ExtensionResultItem | ||
from ulauncher.result_list.item_action.RenderResultListAction import RenderResultListAction | ||
from ulauncher.result_list.item_action.CloseAppAction import CloseAppAction | ||
from ulauncher.result_list.item_action.DoNothingAction import DoNothingAction | ||
from ulauncher.result_list.item_action.ExtensionCustomAction import ExtensionCustomAction | ||
from .query_parser import parse_query, ParseQueryError | ||
|
||
|
||
class ExtensionKeywordListener(EventListener): | ||
|
||
def __init__(self, icon_file): | ||
self.icon_file = icon_file | ||
|
||
def get_action_to_render(self, name, description, on_enter=None): | ||
item = ExtensionResultItem(name=name, | ||
description=description, | ||
icon=self.icon_file, | ||
on_enter=on_enter or DoNothingAction()) | ||
|
||
return RenderResultListAction([item]) | ||
|
||
def on_event(self, event, extension): | ||
query = event.get_argument() | ||
if query: | ||
try: | ||
time_sec, delta, message = parse_query(query) | ||
return self.get_action_to_render(name="Set timer for %s" % delta, | ||
description="Message: %s" % message, | ||
on_enter=ExtensionCustomAction((time_sec, message))) | ||
except ParseQueryError: | ||
return self.get_action_to_render(name="Incorrect request", | ||
description="Example: ti 10m Eggs are ready!") | ||
else: | ||
return self.get_action_to_render(name="Type in your query", | ||
description="Example: ti 10m Eggs are ready!") |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import logging | ||
from ulauncher.extension.client.EventListener import EventListener | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class ItemEnterEventListener(EventListener): | ||
|
||
def on_event(self, event, extension): | ||
delay, message = event.get_data() | ||
extension.set_timer(delay, message) | ||
extension.show_notification('Timer is set', make_sound=False) | ||
logger.debug('Timer is set. Delay %s' % delay) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import os | ||
import subprocess | ||
import gi | ||
import logging | ||
|
||
gi.require_version('Gtk', '3.0') | ||
gi.require_version('Notify', '0.7') | ||
|
||
from gi.repository import Notify | ||
from threading import Timer | ||
|
||
from ulauncher.extension.shared.event import KeywordQueryEvent, ItemEnterEvent | ||
from ulauncher.extension.client.Extension import Extension | ||
from .ExtensionKeywordListener import ExtensionKeywordListener | ||
from .ItemEnterEventListener import ItemEnterEventListener | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class TimerExtension(Extension): | ||
|
||
SOUND_FILE = "/usr/share/sounds/freedesktop/stereo/complete.oga" | ||
ICON_FILE = 'images/timer.png' | ||
|
||
timer = None | ||
|
||
def __init__(self): | ||
super(TimerExtension, self).__init__() | ||
self.icon_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), self.ICON_FILE) | ||
self.subscribe(KeywordQueryEvent, ExtensionKeywordListener(self.ICON_FILE)) | ||
self.subscribe(ItemEnterEvent, ItemEnterEventListener()) | ||
|
||
def set_timer(self, delay, text): | ||
self.timer = Timer(delay, self.show_notification, args=[text]) | ||
self.timer.setDaemon(True) | ||
self.timer.start() | ||
|
||
def stop_timer(self): | ||
if self.timer: | ||
self.timer.stop() | ||
self.timer = None | ||
|
||
def show_notification(self, text, make_sound=True): | ||
logger.debug('Show notification: %s' % text) | ||
Notify.init("TimerExtension") | ||
Notify.Notification.new("Timer", text, self.icon_path).show() | ||
if make_sound: | ||
subprocess.call(("paplay", self.SOUND_FILE)) |
Empty file.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import re | ||
from dateutil.relativedelta import relativedelta | ||
|
||
|
||
TIME_MULT = { | ||
'h': 60 * 60, | ||
'm': 60, | ||
's': 1 | ||
} | ||
ATTRS = ['years', 'months', 'days', 'hours', 'minutes', 'seconds'] | ||
|
||
|
||
def parse_query(query, default_text='Time is up!'): | ||
""" | ||
>>> '5m hello world' | ||
<<< (300, '5 minutes', 'hello world') | ||
>>> '3h Go' | ||
<<< (3*60*60, '3 hours', 'Go') | ||
>>> '5' | ||
<<< (300, '5 minutes', 'Time is up!') | ||
""" | ||
try: | ||
time_arg = query.split(' ')[0] | ||
assert time_arg, "Incorrect time" | ||
m = re.match(r'^(?P<time>\d+)(?P<measure>[mhs])?$', time_arg, re.I) | ||
time_sec = int(m.group('time')) * TIME_MULT[(m.group('measure') or 'm').lower()] | ||
|
||
message = ' '.join(query.split(' ')[1:]).strip() | ||
message = message or default_text | ||
|
||
return (time_sec, ' '.join(human_readable(time_sec)), message) | ||
except Exception as e: | ||
raise ParseQueryError(e.message) | ||
|
||
|
||
def human_readable(seconds): | ||
""" | ||
>>> 125 | ||
<<< ['2 hours', '5 minutes'] | ||
""" | ||
delta = relativedelta(seconds=seconds) | ||
return ['%d %s' % (getattr(delta, attr), getattr(delta, attr) > 1 and attr or attr[:-1]) | ||
for attr in ATTRS if getattr(delta, attr)] | ||
|
||
|
||
class ParseQueryError(Exception): | ||
pass |