forked from albertlauncher/python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path__init__.py
More file actions
121 lines (99 loc) · 4.08 KB
/
__init__.py
File metadata and controls
121 lines (99 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# -*- coding: utf-8 -*-
"""
Takes arguments in the form of '`[[hrs:]mins:]secs [name]`'. Empty fields resolve to `0`. \
Fields exceeding the maximum amount of the time interval are automatically refactorized.
Examples:
- `5:` starts a 5 minutes timer
- `1:: ` starts a 1 hour timer
- `120:` starts a 2 hours timer
"""
import threading
from datetime import timedelta
from pathlib import Path
from time import strftime, time, localtime
from albert import *
md_iid = '2.0'
md_version = "1.7"
md_name = "Timer"
md_description = "Set up timers"
md_license = "BSD-2"
md_url = "https://github.com/albertlauncher/python/tree/master/timer"
md_maintainers = ["@manuelschneid3r", "@googol42", "@uztnus"]
class Timer(threading.Timer):
def __init__(self, interval, name, callback):
super().__init__(interval=interval,
function=lambda: callback(self))
self.name = name
self.begin = int(time())
self.end = self.begin + interval
self.start()
class Plugin(PluginInstance, TriggerQueryHandler):
def __init__(self):
TriggerQueryHandler.__init__(self,
id=md_id,
name=md_name,
description=md_description,
synopsis='[[hrs:]mins:]secs [name]',
defaultTrigger='timer ')
PluginInstance.__init__(self, extensions=[self])
self.iconUrls = [f"file:{Path(__file__).parent}/time.svg"]
self.soundPath = Path(__file__).parent / "bing.wav"
self.timers = []
self.notification = None
def finalize(self):
for timer in self.timers:
timer.cancel()
self.timers.clear()
def startTimer(self, interval, name):
self.timers.append(Timer(interval, name, self.onTimerTimeout))
def deleteTimer(self, timer):
self.timers.remove(timer)
timer.cancel()
def onTimerTimeout(self, timer):
self.notification = Notification(
title=f"Timer '{timer.name if timer.name else 'Timer'}'",
body=f"Timed out at {strftime('%X', localtime(timer.end))}"
)
self.deleteTimer(timer)
def handleTriggerQuery(self, query):
if not query.isValid:
return
if query.string.strip():
args = query.string.strip().split(maxsplit=1)
fields = args[0].split(":")
name = args[1] if 1 < len(args) else ''
if not all(field.isdigit() or field == '' for field in fields):
return StandardItem(
id=self.name,
text="Invalid input",
subtext="Enter a query in the form of '%s[[hours:]minutes:]seconds [name]'" % self.defaultTrigger(),
iconUrls=self.iconUrls,
)
seconds = 0
fields.reverse()
for i in range(len(fields)):
seconds += int(fields[i] if fields[i] else 0)*(60**i)
query.add(StandardItem(
id=self.name,
text=str(timedelta(seconds=seconds)),
subtext='Set a timer with name "%s"' % name if name else 'Set a timer',
iconUrls=self.iconUrls,
actions=[Action("set-timer", "Set timer", lambda sec=seconds: self.startTimer(sec, name))]
))
return
# List timers
items = []
for timer in self.timers:
m, s = divmod(timer.interval, 60)
h, m = divmod(m, 60)
identifier = "%d:%02d:%02d" % (h, m, s)
timer_name_with_quotes = '"%s"' % timer.name if timer.name else ''
items.append(StandardItem(
id=self.name,
text='Delete timer %s [%s]' % (timer_name_with_quotes, identifier),
subtext="Times out %s" % strftime("%X", localtime(timer.end)),
iconUrls=self.iconUrls,
actions=[Action("delete-timer", "Delete timer", lambda t=timer: self.deleteTimer(t))]
))
if items:
query.add(items)