/
gotobed
executable file
·111 lines (90 loc) · 3.39 KB
/
gotobed
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
#!/usr/bin/env python3
# Copyright (c) 2018, Nikita Leshenko <nikita@leshenko.net>
# SPDX-License-Identifier: GPL-2.0
import argparse
from datetime import datetime, timedelta
NOW = datetime.now ()
class GotoBedError (Exception):
pass
def time (arg):
arg = arg.split (':', maxsplit=1)
hour = int (arg[0])
minute = int (arg[1]) if len (arg) > 1 else 0
if hour == 24:
hour = 0
time = NOW.replace (hour=hour, minute=minute, second=0, microsecond=0)
if time < NOW:
# Time refers to tomorrow
time += timedelta (days=1)
return time
def parse_args ():
parser = argparse.ArgumentParser ()
parser.add_argument ('time', metavar='hh[:mm]',
nargs='?', type=time,
help='Set time to go to bed')
parser.add_argument ('-f', '--force',
action='store_true',
help="Don't confirm time adjustment")
return parser.parse_args ()
def get_current_bedtime ():
try:
with open ('/sys/kernel/seconds_to_bed') as f:
seconds = f.read ()
except FileNotFoundError:
raise GotoBedError ('Failed to open driver file. Is kgotobed loaded?')
except PermissionError:
raise GotoBedError ('Permission error while reading from driver')
if not seconds:
return None
return NOW + timedelta(seconds=int(seconds))
def set_bedtime (time):
# take datetime.now again instead of using NOW because time might have
# passed while we waited for user confirmation
seconds = (time - datetime.now ()).total_seconds ()
seconds = int (seconds)
try:
with open ('/sys/kernel/seconds_to_bed', 'w') as f:
f.write (str (seconds))
except FileNotFoundError:
raise GotoBedError ('Failed to open driver file. Is kgotobed loaded?')
except PermissionError:
raise GotoBedError ('Permission error while writing to driver')
def main ():
args = parse_args ()
current_bedtime = get_current_bedtime ()
if current_bedtime:
rounded_bedtime = current_bedtime + timedelta (seconds=30)
rounded_bedtime = rounded_bedtime.replace (second=0, microsecond=0)
print ('Current bedtime is {}'.format (rounded_bedtime))
else:
print ('Currently no bedtime is set')
if args.time is None:
return
if current_bedtime and not args.force:
if current_bedtime < NOW:
print ('Warning: Past bedtime. The driver should have already'
' killed the computer. Strange bug...')
if args.time > current_bedtime:
raise GotoBedError ("Attempting to postpone bed time, it doesn't"
" work like this...")
print ('Setting bedtime to {}'.format (args.time))
hours, minutes = divmod (args.time - NOW, timedelta (hours=1))
minutes //= timedelta (minutes=1)
print ('Bedtime will be in {:d} hours {:02d} minutes'.format(hours, minutes))
if not args.force:
try:
if input ('Confirm? [Y/n] ').lower () not in ('', 'y', 'yes'):
raise GotoBedError ('Not confirmed')
except KeyboardInterrupt:
print ('')
exit (1)
except EOFError:
print ('')
exit (1)
set_bedtime (args.time)
if __name__ == '__main__':
try:
main ()
except GotoBedError as e:
print ('Error:', e)
exit (1)