summaryrefslogtreecommitdiff
path: root/overlays
diff options
context:
space:
mode:
Diffstat (limited to 'overlays')
-rw-r--r--overlays/swayosd/default.nix (renamed from overlays/swayosd.nix)3
-rw-r--r--overlays/swayosd/exponential.patch57
-rwxr-xr-xoverlays/worktime/worktime/__main__.py80
3 files changed, 121 insertions, 19 deletions
diff --git a/overlays/swayosd.nix b/overlays/swayosd/default.nix
index 61c865e7..28c8f1b9 100644
--- a/overlays/swayosd.nix
+++ b/overlays/swayosd/default.nix
@@ -23,5 +23,8 @@
23 udev 23 udev
24 sassc 24 sassc
25 ]; 25 ];
26 patches = (oldAttrs.patches or []) ++ [
27 ./exponential.patch
28 ];
26 }); 29 });
27} 30}
diff --git a/overlays/swayosd/exponential.patch b/overlays/swayosd/exponential.patch
new file mode 100644
index 00000000..eb90d739
--- /dev/null
+++ b/overlays/swayosd/exponential.patch
@@ -0,0 +1,57 @@
1diff --git a/src/brightness_backend/brightnessctl.rs b/src/brightness_backend/brightnessctl.rs
2index ccb0e11..740fdb6 100644
3--- a/src/brightness_backend/brightnessctl.rs
4+++ b/src/brightness_backend/brightnessctl.rs
5@@ -107,10 +107,21 @@ impl VirtualDevice {
6 }
7 }
8
9- fn set_percent(&mut self, mut val: u32) -> anyhow::Result<()> {
10- val = val.clamp(0, 100);
11- self.current = self.max.map(|max| val * max / 100);
12- let _: String = self.run(("set", &*format!("{val}%")))?;
13+ fn val_to_percent(&mut self, val: u32) -> u32 {
14+ return ((val as f64 / self.get_max() as f64).powf(0.25) * 100_f64).round() as u32;
15+ }
16+ fn percent_to_val(&mut self, perc: u32) -> u32 {
17+ return ((perc as f64 / 100_f64).powf(4_f64) * self.get_max() as f64).round() as u32;
18+ }
19+
20+ fn set_percent(&mut self, val: u32) -> anyhow::Result<()> {
21+ let new = self.percent_to_val(val);
22+ self.set_val(new)
23+ }
24+ fn set_val(&mut self, val: u32) -> anyhow::Result<()> {
25+ let curr = val.clamp(0, self.get_max());
26+ self.current = Some(curr);
27+ let _: String = self.run(("set", &*format!("{curr}")))?;
28 Ok(())
29 }
30 }
31@@ -134,20 +145,18 @@ impl BrightnessBackend for BrightnessCtl {
32
33 fn lower(&mut self, by: u32) -> anyhow::Result<()> {
34 let curr = self.get_current();
35- let max = self.get_max();
36-
37- let curr = curr * 100 / max;
38+ let mut new = self.device.val_to_percent(curr).saturating_sub(by);
39+ new = self.device.percent_to_val(new).min(curr.saturating_sub(1));
40
41- self.device.set_percent(curr.saturating_sub(by))
42+ self.device.set_val(new)
43 }
44
45 fn raise(&mut self, by: u32) -> anyhow::Result<()> {
46 let curr = self.get_current();
47- let max = self.get_max();
48-
49- let curr = curr * 100 / max;
50+ let mut new = self.device.val_to_percent(curr) + by;
51+ new = self.device.percent_to_val(new).max(curr + 1);
52
53- self.device.set_percent(curr + by)
54+ self.device.set_val(new)
55 }
56
57 fn set(&mut self, val: u32) -> anyhow::Result<()> {
diff --git a/overlays/worktime/worktime/__main__.py b/overlays/worktime/worktime/__main__.py
index 4c623acd..ba6c5ff6 100755
--- a/overlays/worktime/worktime/__main__.py
+++ b/overlays/worktime/worktime/__main__.py
@@ -23,7 +23,7 @@ import argparse
23from copy import deepcopy 23from copy import deepcopy
24 24
25import sys 25import sys
26from sys import stderr 26from sys import stderr, stdout
27 27
28from tabulate import tabulate 28from tabulate import tabulate
29 29
@@ -38,6 +38,7 @@ from collections import defaultdict
38 38
39import jsonpickle 39import jsonpickle
40from hashlib import blake2s 40from hashlib import blake2s
41import json
41 42
42class TogglAPISection(Enum): 43class TogglAPISection(Enum):
43 TOGGL = '/api/v9' 44 TOGGL = '/api/v9'
@@ -223,6 +224,7 @@ class Worktime(object):
223 leave_budget = dict() 224 leave_budget = dict()
224 time_per_day = None 225 time_per_day = None
225 workdays = None 226 workdays = None
227 pull_forward = dict()
226 228
227 @staticmethod 229 @staticmethod
228 @cache 230 @cache
@@ -390,8 +392,6 @@ class Worktime(object):
390 if e.errno != 2: 392 if e.errno != 2:
391 raise e 393 raise e
392 394
393 pull_forward = dict()
394
395 start_day = self.start_date.date() 395 start_day = self.start_date.date()
396 end_day = self.end_date.date() 396 end_day = self.end_date.date()
397 397
@@ -418,15 +418,15 @@ class Worktime(object):
418 if not d == datetime.strptime(c, date_format).replace(tzinfo=tzlocal()).date(): break 418 if not d == datetime.strptime(c, date_format).replace(tzinfo=tzlocal()).date(): break
419 else: 419 else:
420 if d >= self.end_date.date(): 420 if d >= self.end_date.date():
421 pull_forward[d] = min(timedelta(hours = float(hours)), self.time_per_day(d) - (holidays[d] if d in holidays else timedelta())) 421 self.pull_forward[d] = min(timedelta(hours = float(hours)), self.time_per_day(d) - (holidays[d] if d in holidays else timedelta()))
422 except IOError as e: 422 except IOError as e:
423 if e.errno != 2: 423 if e.errno != 2:
424 raise e 424 raise e
425 425
426 self.days_to_work = dict() 426 self.days_to_work = dict()
427 427
428 if pull_forward: 428 if self.pull_forward:
429 end_day = max(end_day, max(list(pull_forward))) 429 end_day = max(end_day, max(list(self.pull_forward)))
430 430
431 for day in [start_day + timedelta(days = x) for x in range(0, (end_day - start_day).days + 1)]: 431 for day in [start_day + timedelta(days = x) for x in range(0, (end_day - start_day).days + 1)]:
432 if day.isoweekday() in self.workdays: 432 if day.isoweekday() in self.workdays:
@@ -470,17 +470,17 @@ class Worktime(object):
470 self.extra_days_to_work[self.now.date()] = timedelta() 470 self.extra_days_to_work[self.now.date()] = timedelta()
471 471
472 self.time_to_work = sum([self.days_to_work[day] for day in self.days_to_work.keys() if day <= self.end_date.date()], timedelta()) 472 self.time_to_work = sum([self.days_to_work[day] for day in self.days_to_work.keys() if day <= self.end_date.date()], timedelta())
473 for day in [d for d in list(pull_forward) if d > self.end_date.date()]: 473 for day in [d for d in list(self.pull_forward) if d > self.end_date.date()]:
474 days_forward = set([d for d in self.days_to_work.keys() if d >= self.end_date.date() and d < day and (not d in pull_forward or d == self.end_date.date())]) 474 days_forward = set([d for d in self.days_to_work.keys() if d >= self.end_date.date() and d < day and (not d in self.pull_forward or d == self.end_date.date())])
475 extra_days_forward = set([d for d in self.extra_days_to_work.keys() if d >= self.end_date.date() and d < day and (not d in pull_forward or d == self.end_date.date())]) 475 extra_days_forward = set([d for d in self.extra_days_to_work.keys() if d >= self.end_date.date() and d < day and (not d in self.pull_forward or d == self.end_date.date())])
476 days_forward = days_forward.union(extra_days_forward) 476 days_forward = days_forward.union(extra_days_forward)
477 477
478 extra_day_time_left = timedelta() 478 extra_day_time_left = timedelta()
479 for extra_day in extra_days_forward: 479 for extra_day in extra_days_forward:
480 day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day]) 480 day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day])
481 extra_day_time_left += day_time 481 extra_day_time_left += day_time
482 extra_day_time = min(extra_day_time_left, pull_forward[day]) 482 extra_day_time = min(extra_day_time_left, self.pull_forward[day])
483 time_forward = pull_forward[day] - extra_day_time 483 time_forward = self.pull_forward[day] - extra_day_time
484 if extra_day_time_left > timedelta(): 484 if extra_day_time_left > timedelta():
485 for extra_day in extra_days_forward: 485 for extra_day in extra_days_forward:
486 day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day]) 486 day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day])
@@ -518,7 +518,14 @@ def format_days(worktime, days, date_format=None):
518 return ', '.join(map(lambda group: ','.join(map(format_group, group)), groups)) 518 return ', '.join(map(lambda group: ','.join(map(format_group, group)), groups))
519 519
520 520
521def worktime(pull_forward_cutoff, **args): 521def tooltip_timedelta(td):
522 if td < timedelta(seconds = 0):
523 return "-" + tooltip_timedelta(-td)
524 mm, ss = divmod(td.total_seconds(), 60)
525 hh, mm = divmod(mm, 60)
526 return "%d:%02d:%02d" % (hh, mm, ss)
527
528def worktime(pull_forward_cutoff, waybar, **args):
522 worktime = Worktime(**args) 529 worktime = Worktime(**args)
523 530
524 def format_worktime(worktime): 531 def format_worktime(worktime):
@@ -562,7 +569,12 @@ def worktime(pull_forward_cutoff, **args):
562 else: 569 else:
563 return f"({difference_string})" 570 return f"({difference_string})"
564 571
565 if worktime.time_pulled_forward >= pull_forward_cutoff: 572 out_class = "running" if worktime.running_entry else "stopped"
573 difference = worktime.time_to_work - worktime.time_worked
574 if worktime.running_entry and -min(timedelta(milliseconds=0), difference) > sum(worktime.pull_forward.values(), start=timedelta(milliseconds=0)) or not worktime.running_entry and max(timedelta(milliseconds=0), difference) > worktime.time_per_day(worktime.now.date()) and worktime.now_is_workday:
575 out_class = "over"
576 tooltip = tooltip_timedelta(difference)
577 if worktime.time_pulled_forward >= min(pull_forward_cutoff, timedelta(seconds = 1)):
566 worktime_no_pulled_forward = deepcopy(worktime) 578 worktime_no_pulled_forward = deepcopy(worktime)
567 worktime_no_pulled_forward.time_to_work -= worktime_no_pulled_forward.time_pulled_forward 579 worktime_no_pulled_forward.time_to_work -= worktime_no_pulled_forward.time_pulled_forward
568 worktime_no_pulled_forward.time_pulled_forward = timedelta() 580 worktime_no_pulled_forward.time_pulled_forward = timedelta()
@@ -570,11 +582,24 @@ def worktime(pull_forward_cutoff, **args):
570 difference_string = format_worktime(worktime) 582 difference_string = format_worktime(worktime)
571 difference_string_no_pulled_forward = format_worktime(worktime_no_pulled_forward) 583 difference_string_no_pulled_forward = format_worktime(worktime_no_pulled_forward)
572 584
573 print(f"{difference_string_no_pulled_forward}…{difference_string}") 585 tooltip = tooltip_timedelta(worktime_no_pulled_forward.time_to_work - worktime_no_pulled_forward.time_worked) + "…" + tooltip
586 if worktime.time_pulled_forward >= pull_forward_cutoff:
587 out_text = f"{difference_string_no_pulled_forward}…{difference_string}"
588 else:
589 out_text = format_worktime(worktime)
590 else:
591 out_text = format_worktime(worktime)
592
593 if waybar:
594 json.dump({"text": out_text, "class": out_class, "tooltip": tooltip}, stdout)
574 else: 595 else:
575 print(format_worktime(worktime)) 596 print(out_text)
576 597
577def time_worked(now, **args): 598def pull_forward(**args):
599 worktime = Worktime(**args)
600 print(tooltip_timedelta(sum(worktime.pull_forward.values(), start=timedelta(milliseconds=0))))
601
602def time_worked(now, waybar, **args):
578 then = now.replace(hour = 0, minute = 0, second = 0, microsecond = 0) 603 then = now.replace(hour = 0, minute = 0, second = 0, microsecond = 0)
579 if now.time() == time(): 604 if now.time() == time():
580 now = now + timedelta(days = 1) 605 now = now + timedelta(days = 1)
@@ -584,6 +609,9 @@ def time_worked(now, **args):
584 609
585 worked = now.time_worked - then.time_worked 610 worked = now.time_worked - then.time_worked
586 611
612 out_text = None
613 out_class = "stopped"
614 tooltip = tooltip_timedelta(worked)
587 if args['do_round']: 615 if args['do_round']:
588 total_minutes_difference = 5 * ceil(worked / timedelta(minutes = 5)) 616 total_minutes_difference = 5 * ceil(worked / timedelta(minutes = 5))
589 (hours_difference, minutes_difference) = divmod(abs(total_minutes_difference), 60) 617 (hours_difference, minutes_difference) = divmod(abs(total_minutes_difference), 60)
@@ -602,15 +630,25 @@ def time_worked(now, **args):
602 difference = target_time - worked 630 difference = target_time - worked
603 clockout_difference = 5 * ceil(difference / timedelta(minutes = 5)) 631 clockout_difference = 5 * ceil(difference / timedelta(minutes = 5))
604 clockout_time = now.now + difference 632 clockout_time = now.now + difference
633 exact_clockout_time = clockout_time
605 clockout_time += (5 - clockout_time.minute % 5) * timedelta(minutes = 1) 634 clockout_time += (5 - clockout_time.minute % 5) * timedelta(minutes = 1)
606 clockout_time = clockout_time.replace(second = 0, microsecond = 0) 635 clockout_time = clockout_time.replace(second = 0, microsecond = 0)
607 636
608 if now.running_entry and clockout_time and clockout_difference >= 0: 637 if now.running_entry and clockout_time and clockout_difference >= 0:
609 print(f"{difference_string}/{clockout_time:%H:%M}") 638 out_class = "running"
639 out_text = f"{difference_string}/{clockout_time:%H:%M}"
640 tooltip = f"{tooltip_timedelta(worked)}/{exact_clockout_time:%H:%M}"
610 else: 641 else:
611 print(difference_string) 642 if now.running_entry:
643 out_class = "over"
644 out_text = difference_string
645 else:
646 out_text = str(worked)
647
648 if waybar:
649 json.dump({"text": out_text, "class": out_class, "tooltip": tooltip}, stdout)
612 else: 650 else:
613 print(worked) 651 print(out_text)
614 652
615def diff(now, **args): 653def diff(now, **args):
616 now = now.replace(hour = 0, minute = 0, second = 0, microsecond = 0) 654 now = now.replace(hour = 0, minute = 0, second = 0, microsecond = 0)
@@ -841,9 +879,11 @@ def main():
841 subparsers = parser.add_subparsers(help = 'Subcommands') 879 subparsers = parser.add_subparsers(help = 'Subcommands')
842 worktime_parser = subparsers.add_parser('time_worked', aliases = ['time', 'worked']) 880 worktime_parser = subparsers.add_parser('time_worked', aliases = ['time', 'worked'])
843 worktime_parser.add_argument('--pull-forward-cutoff', dest = 'pull_forward_cutoff', metavar = 'MINUTES', type = duration_minutes, default = timedelta(minutes = 15)) 881 worktime_parser.add_argument('--pull-forward-cutoff', dest = 'pull_forward_cutoff', metavar = 'MINUTES', type = duration_minutes, default = timedelta(minutes = 15))
882 worktime_parser.add_argument('--waybar', action='store_true')
844 worktime_parser.set_defaults(cmd = worktime) 883 worktime_parser.set_defaults(cmd = worktime)
845 time_worked_parser = subparsers.add_parser('today') 884 time_worked_parser = subparsers.add_parser('today')
846 time_worked_parser.add_argument('--no-round', dest = 'do_round', action = 'store_false') 885 time_worked_parser.add_argument('--no-round', dest = 'do_round', action = 'store_false')
886 time_worked_parser.add_argument('--waybar', action='store_true')
847 time_worked_parser.set_defaults(cmd = time_worked) 887 time_worked_parser.set_defaults(cmd = time_worked)
848 diff_parser = subparsers.add_parser('diff') 888 diff_parser = subparsers.add_parser('diff')
849 diff_parser.set_defaults(cmd = diff) 889 diff_parser.set_defaults(cmd = diff)
@@ -861,6 +901,8 @@ def main():
861 classification_parser.add_argument('--table', action = 'store_true') 901 classification_parser.add_argument('--table', action = 'store_true')
862 classification_parser.add_argument('--table-format', dest='table_format', type=str, default='fancy_grid') 902 classification_parser.add_argument('--table-format', dest='table_format', type=str, default='fancy_grid')
863 classification_parser.set_defaults(cmd = partial(classification, classification_name=classification_name)) 903 classification_parser.set_defaults(cmd = partial(classification, classification_name=classification_name))
904 pull_forward_parser = subparsers.add_parser('pull-forward')
905 pull_forward_parser.set_defaults(cmd = pull_forward)
864 parser.set_default_subparser('time_worked') 906 parser.set_default_subparser('time_worked')
865 args = parser.parse_args() 907 args = parser.parse_args()
866 908