-
Notifications
You must be signed in to change notification settings - Fork 0
/
screentime.nu
executable file
·112 lines (93 loc) · 2.92 KB
/
screentime.nu
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
#!/usr/bin/env nu
# Set your configuration here!
const USERS: list<string> = []
# A list of the usernames to terminate upon exceeding time limits.
# Other users will remain unaffected.
# Examples:
# - ['alice']
# - ['bob' 'carl' 'dan']
# Note that there's no comma between list items!
const ALLOWED_HOURS = 6..16
# Hour range in which the device can be used. Examples:
# - 6..21 (A range denoted as start..end)
# - [7 8 9 10 20 21] (You can use a list too!)
const TIMEZONE: string = "Europe/London"
# Your timezone. See a list of timezones by running this script with:
# ./screentime.nu list-timezones
# Example: "Europe/London"
const MAX_OFFLINE: duration = 15min
# Maximum allowed offline usage time per day.
const EXTRA_MINS: duration = 30min
# Maximum allowed extra time per day outside of $ALLOWED_HOURS you have defined.
# That's it! You can also change the following optional settings:
const LIMIT_RESET_HOUR: string = "6am"
# The hour at which the extra time and offline time limit counters reset every day.
# const DIR: path = '/var/lib/screentime-nixos'
const DIR: path = './hehe/'
# The directory in which data files are saved.
-----------------------------------------------------------
mkdir $DIR
let data_file: path = ($DIR | path join 'data.nuon')
if not ($data_file | path exists) {
{
extra: 0min,
offline: 0min,
last_reset: ($LIMIT_RESET_HOUR | into datetime | into int)
} | save $data_file
}
def main [] nothing -> nothing {
alias notify = try { notify -a "screentime-nixos" -s "1 minute left to termination" -t "Your user session will be terminated in 60 seconds." --timeout 60sec }
notify
let last_reset = (v last_reset | into datetime)
mut next_reset = $last_reset + 1day
loop {
let online: bool = try {
ping -c 1 8.8.8.8 | ignore
true
} catch { false }
if $online {
let hour: int = (date now | format date '%H' | into int)
if $hour not-in $ALLOWED_HOURS {
set extra ((v extra) + 1min)
if (v extra) == 1min or (v extra) > $EXTRA_MINS {
block
} else if (v extra) == $EXTRA_MINS {
notify
}
}
if (date now) > $next_reset {
set last_reset ($next_reset | into int)
$next_reset = $next_reset + 1day
set extra 0min
set offline 0min
}
} else if not $online {
set offline ((v offline) + 1min)
if (v offline) > $MAX_OFFLINE {
block
} else if (v offline) == $MAX_OFFLINE {
notify
}
}
sleep 1min
}
}
def "main list-timezones" []: nothing -> table<timezone: string> {
date list-timezone
}
def "set" [field: string, value: any] nothing -> nothing {
open $data_file | update $field $value | save -f $data_file
}
def v [field: string]: nothing -> any {
open $data_file | get $field
}
def block []: nothing -> nothing {
if (sys host).uptime >= 3min {
$USERS | each {
let user: string = $in
print $"User \"($user)\" is terminated."
try { loginctl kill-user $user }
try { systemctl suspend }
}
}
}