no hypr folder + waybar cclock, nx_gcal_event
This commit is contained in:
22
.vscode/launch.json
vendored
Normal file
22
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "Python Debugger: Current File with Arguments",
|
||||||
|
"type": "debugpy",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${file}",
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"args": "${command:pickArgs}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -50,42 +50,6 @@ in
|
|||||||
pkgs-unstable.hyprlock
|
pkgs-unstable.hyprlock
|
||||||
pkgs-unstable.hypridle
|
pkgs-unstable.hypridle
|
||||||
|
|
||||||
(pkgs.writeShellScriptBin "waybar_mode" ''
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Function to print help message
|
|
||||||
print_help() {
|
|
||||||
echo "Usage: waybar_mode {set <string>|unset}"
|
|
||||||
}
|
|
||||||
if [ $# -lt 1 ]; then
|
|
||||||
print_help; exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
set)
|
|
||||||
# Check if there is a second argument for the 'set' operation
|
|
||||||
if [ $# -eq 2 ]; then
|
|
||||||
echo "$2" > /tmp/waybar-mode
|
|
||||||
pkill -RTMIN+8 waybar
|
|
||||||
else
|
|
||||||
echo "Error: 'set' operation requires exactly one string argument."
|
|
||||||
print_help
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
unset)
|
|
||||||
echo "" > /tmp/waybar-mode
|
|
||||||
pkill -RTMIN+8 waybar
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Error: Unknown command '$1'"
|
|
||||||
print_help
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
'')
|
|
||||||
];
|
];
|
||||||
|
|
||||||
wayland.windowManager.hyprland = {
|
wayland.windowManager.hyprland = {
|
||||||
222
home-modules/nx-gcal-event.nix
Normal file
222
home-modules/nx-gcal-event.nix
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
{ config, pkgs, secrets, ... }:
|
||||||
|
let in
|
||||||
|
{
|
||||||
|
home = {
|
||||||
|
file."${config.xdg.dataHome}/nx-gcal-event-credentials.json".text = ''
|
||||||
|
{
|
||||||
|
"installed": {
|
||||||
|
"client_id": "${secrets.nx-gcal-event.client-client-id}",
|
||||||
|
"project_id": "my-own-cal",
|
||||||
|
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||||
|
"token_uri": "https://oauth2.googleapis.com/token",
|
||||||
|
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||||
|
"client_secret": "${secrets.nx-gcal-event.client-secret}",
|
||||||
|
"redirect_uris": [
|
||||||
|
"http://localhost"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
packages = with pkgs; [
|
||||||
|
# TODO: make into real package, currently dependencies are in home.nix
|
||||||
|
# (pkgs.python311.withPackages (python-pkgs: [
|
||||||
|
# python-pkgs.google
|
||||||
|
# ]))
|
||||||
|
(writeScriptBin "nx_gcal_event" ''
|
||||||
|
#!${pkgs.python3}/bin/python3
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
import pickle
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from google.auth.transport.requests import Request
|
||||||
|
from google.oauth2.credentials import Credentials
|
||||||
|
from google_auth_oauthlib.flow import InstalledAppFlow
|
||||||
|
from googleapiclient.discovery import build
|
||||||
|
from googleapiclient.errors import HttpError
|
||||||
|
from html import escape
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CREDENTIALS_PATH = f"{os.environ['XDG_DATA_HOME']}/nx-gcal-event-credentials.json"
|
||||||
|
TOKEN_PATH = f"{os.environ['XDG_CACHE_HOME']}/nx-gcal-event-token.json"
|
||||||
|
PICKLE_PATH = "/tmp/nx-gcal-event.pickle"
|
||||||
|
|
||||||
|
|
||||||
|
def sec_to_nice_string(seconds: int):
|
||||||
|
(hours, rsec) = divmod(seconds, 3600)
|
||||||
|
minutes = rsec // 60
|
||||||
|
sep = " "
|
||||||
|
if hours == 0:
|
||||||
|
s_hours = f""
|
||||||
|
sep = ""
|
||||||
|
elif hours == 1: s_hours = f"{hours} hour"
|
||||||
|
else: s_hours = f"{hours} hours"
|
||||||
|
if minutes == 0:
|
||||||
|
s_minutes = f""
|
||||||
|
sep = ""
|
||||||
|
elif minutes == 1: s_minutes = f"{minutes} minute"
|
||||||
|
else: s_minutes = f"{minutes} minutes"
|
||||||
|
if hours + minutes == 0:
|
||||||
|
s_minutes = "~ No time"
|
||||||
|
os.remove(PICKLE_PATH)
|
||||||
|
|
||||||
|
return f"{s_hours}{sep}{s_minutes}"
|
||||||
|
|
||||||
|
def get_event_from_api():
|
||||||
|
creds = None
|
||||||
|
SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"]
|
||||||
|
|
||||||
|
if os.path.exists(TOKEN_PATH):
|
||||||
|
creds = Credentials.from_authorized_user_file(TOKEN_PATH, SCOPES)
|
||||||
|
|
||||||
|
if not creds or not creds.valid:
|
||||||
|
if creds and creds.expired and creds.refresh_token:
|
||||||
|
creds.refresh(Request())
|
||||||
|
else:
|
||||||
|
flow = InstalledAppFlow.from_client_secrets_file(CREDENTIALS_PATH, SCOPES)
|
||||||
|
creds = flow.run_local_server(port=0)
|
||||||
|
# Save the credentials for the next run
|
||||||
|
with open(TOKEN_PATH, "w") as token:
|
||||||
|
token.write(creds.to_json())
|
||||||
|
|
||||||
|
try:
|
||||||
|
service = build("calendar", "v3", credentials=creds)
|
||||||
|
now = datetime.datetime.utcnow().isoformat() + "Z" # 'Z' indicates UTC time
|
||||||
|
in_24_h = (datetime.datetime.utcnow() + datetime.timedelta(days=1)).isoformat() + "Z"
|
||||||
|
calendar_list = service.calendarList().list().execute()
|
||||||
|
calendars = calendar_list.get("items", [])
|
||||||
|
|
||||||
|
# List events from all calendars
|
||||||
|
all_events = []
|
||||||
|
for calendar in calendars:
|
||||||
|
calendar_id = calendar["id"]
|
||||||
|
events_result = service.events().list(
|
||||||
|
calendarId=calendar_id,
|
||||||
|
timeMin=now,
|
||||||
|
timeMax=in_24_h,
|
||||||
|
singleEvents=True,
|
||||||
|
orderBy="startTime",
|
||||||
|
).execute()
|
||||||
|
events = events_result.get("items", [])
|
||||||
|
|
||||||
|
all_events.extend(events)
|
||||||
|
|
||||||
|
# Filter out all-day events
|
||||||
|
all_events = [event for event in all_events if "dateTime" in event["start"]]
|
||||||
|
|
||||||
|
# Find the earliest event
|
||||||
|
earliest_event = None
|
||||||
|
for event in all_events:
|
||||||
|
event_start = event["start"]["dateTime"]
|
||||||
|
if not earliest_event or event_start < earliest_event["start"]["dateTime"]:
|
||||||
|
earliest_event = event
|
||||||
|
|
||||||
|
# Now earliest_event contains the event that starts earliest
|
||||||
|
return earliest_event
|
||||||
|
|
||||||
|
except HttpError as error:
|
||||||
|
print("An error occurred: %s" % error)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
def dump_dict_to_file(event, now):
|
||||||
|
if not event:
|
||||||
|
event = {}
|
||||||
|
event['nxWriteTime'] = now
|
||||||
|
with open(PICKLE_PATH, 'wb') as f:
|
||||||
|
pickle.dump(event, f)
|
||||||
|
|
||||||
|
def load_dict_from_file(now):
|
||||||
|
with open(PICKLE_PATH, 'rb') as f:
|
||||||
|
event = pickle.load(f)
|
||||||
|
# recheck all 15 minutes
|
||||||
|
if (now - event['nxWriteTime']).seconds > 900:
|
||||||
|
event = get_event_from_api()
|
||||||
|
os.remove(PICKLE_PATH)
|
||||||
|
return event
|
||||||
|
|
||||||
|
def lookup():
|
||||||
|
# set now (timezone CEST)
|
||||||
|
now = datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=2)))
|
||||||
|
|
||||||
|
no_event_string = "~ Zen ~"
|
||||||
|
|
||||||
|
if os.path.exists(PICKLE_PATH):
|
||||||
|
event = load_dict_from_file(now)
|
||||||
|
else:
|
||||||
|
event = get_event_from_api()
|
||||||
|
if not event:
|
||||||
|
print(no_event_string)
|
||||||
|
dump_dict_to_file(event, now)
|
||||||
|
exit(0)
|
||||||
|
dump_dict_to_file(event, now)
|
||||||
|
|
||||||
|
try: # when the saved even was empty (there was no event)
|
||||||
|
end = datetime.datetime.strptime(event["end"]["dateTime"], "%Y-%m-%dT%H:%M:%S%z")
|
||||||
|
start = datetime.datetime.strptime(event["start"]["dateTime"], "%Y-%m-%dT%H:%M:%S%z")
|
||||||
|
except:
|
||||||
|
if (now - event['nxWriteTime']).seconds > 900:
|
||||||
|
event = get_event_from_api()
|
||||||
|
os.remove(PICKLE_PATH)
|
||||||
|
else:
|
||||||
|
print(no_event_string)
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
# set mode, remaining
|
||||||
|
if start.day != now.day: # event start tomorrow
|
||||||
|
print(no_event_string)
|
||||||
|
exit(0)
|
||||||
|
elif (start - now).days < 0: # today, started alredy
|
||||||
|
remaining = end - now
|
||||||
|
mode = " remaining in "
|
||||||
|
else: # today, not started yet
|
||||||
|
remaining = start - now
|
||||||
|
mode = " until the start of "
|
||||||
|
|
||||||
|
name = escape(event['summary'])
|
||||||
|
|
||||||
|
print(f" {sec_to_nice_string(remaining.seconds)}{mode}\'{name}\'")
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
def print_help():
|
||||||
|
print("Usage: nx_gcal_event [lookup|force-lookup|reauthenicate|help]")
|
||||||
|
|
||||||
|
def forece_lookup():
|
||||||
|
try:
|
||||||
|
os.remove(PICKLE_PATH)
|
||||||
|
os.system('notify-send --app-name="nx_gcal_event" "Saved event deleted!"')
|
||||||
|
except:
|
||||||
|
os.system('notify-send --app-name="nx_gcal_event" "No saved event found!"')
|
||||||
|
finally:
|
||||||
|
lookup()
|
||||||
|
|
||||||
|
def reauthenicate():
|
||||||
|
os.remove(PICKLE_PATH)
|
||||||
|
os.remove(TOKEN_PATH)
|
||||||
|
os.system('notify-send --app-name="nx_gcal_event" "Deleted Token"')
|
||||||
|
lookup()
|
||||||
|
|
||||||
|
def print_help():
|
||||||
|
print("Usage: nx_gcal_event [lookup|force-lookup|reauthenicate|help]")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("Incorrect number of arguments.")
|
||||||
|
print_help()
|
||||||
|
else:
|
||||||
|
arg = sys.argv[1]
|
||||||
|
if arg == "lookup":
|
||||||
|
lookup()
|
||||||
|
elif arg == "force-lookup":
|
||||||
|
forece_lookup()
|
||||||
|
elif arg == "reauthenticate":
|
||||||
|
reauthenicate()
|
||||||
|
elif arg == "help":
|
||||||
|
print_help()
|
||||||
|
else:
|
||||||
|
print_help()
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
18
home-modules/python.nix
Normal file
18
home-modules/python.nix
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{ config, pkgs, ... }:
|
||||||
|
let
|
||||||
|
python-with-packages = pkgs.python3.withPackages (pp: with pp; [
|
||||||
|
ipython
|
||||||
|
pipdeptree
|
||||||
|
requests
|
||||||
|
google google-api-python-client google-auth-httplib2 google-auth-oauthlib
|
||||||
|
]);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
python-with-packages
|
||||||
|
];
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
PYTHONPATH = "${python-with-packages}/${python-with-packages.sitePackages}";
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -2,8 +2,56 @@
|
|||||||
let
|
let
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
imports = [
|
||||||
|
./nx-gcal-event.nix
|
||||||
|
];
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
waybar
|
waybar
|
||||||
|
|
||||||
|
(pkgs.writeShellScriptBin "waybar_mode" ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
print_help() {
|
||||||
|
echo "Usage: waybar_mode {set <string>|unset}"
|
||||||
|
}
|
||||||
|
if [ $# -lt 1 ]; then
|
||||||
|
print_help; exit 1;
|
||||||
|
fi
|
||||||
|
case "$1" in
|
||||||
|
set)
|
||||||
|
# Check if there is a second argument for the 'set' operation
|
||||||
|
if [ $# -eq 2 ]; then
|
||||||
|
echo "$2" > /tmp/waybar-mode
|
||||||
|
pkill -RTMIN+8 waybar
|
||||||
|
else
|
||||||
|
echo "Error: 'set' operation requires exactly one string argument."
|
||||||
|
print_help
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
unset)
|
||||||
|
echo "" > /tmp/waybar-mode
|
||||||
|
pkill -RTMIN+8 waybar
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Error: Unknown command '$1'"
|
||||||
|
print_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
exit 0
|
||||||
|
'')
|
||||||
|
(pkgs.writeShellScriptBin "cclock" ''
|
||||||
|
#!/bin/bash
|
||||||
|
#ord=$(date +"%e" | awk '{printf("%d%s\n", $1, substr("thstndrd", ($1%100-20)%10*2+1, 2))}')
|
||||||
|
ord=$(date +"%e" | awk '{printf("%d%s\n", $1, ($1==11||$1==12||$1==13)?"th":((($1%10)==1)?"st":((($1%10)==2)?"nd":((($1%10)==3)?"rd":"th"))))}')
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
echo " $(date +'%A the')" "$ord" "of" "$(date +'%B')" " " "$(date +'%R')"
|
||||||
|
elif [ "$1" = "--no-icons" ]; then
|
||||||
|
echo "$(date +'%A the')" "$ord" "of" "$(date +'%B')" "$(date +'%R')"
|
||||||
|
fi
|
||||||
|
'')
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
programs.waybar = {
|
programs.waybar = {
|
||||||
@@ -48,11 +96,11 @@ in
|
|||||||
separate-outputs = true;
|
separate-outputs = true;
|
||||||
};
|
};
|
||||||
"custom/cclock" = {
|
"custom/cclock" = {
|
||||||
exec = "/home/nx2/scripts/cclock.sh";
|
exec = "cclock";
|
||||||
restart-interval = 60;
|
restart-interval = 60;
|
||||||
};
|
};
|
||||||
"custom/ctimeremaining" = {
|
"custom/ctimeremaining" = {
|
||||||
exec = "python /home/nx2/scripts/NxGCalEvent/get-remaining-time.py";
|
exec = "nx_gcal_event lookup";
|
||||||
restart-interval = 60;
|
restart-interval = 60;
|
||||||
};
|
};
|
||||||
"custom/mode" = {
|
"custom/mode" = {
|
||||||
20
home.nix
20
home.nix
@@ -14,9 +14,9 @@
|
|||||||
./home-modules/pnx/pnx.nix
|
./home-modules/pnx/pnx.nix
|
||||||
# ./home-modules/hsmw.nix
|
# ./home-modules/hsmw.nix
|
||||||
|
|
||||||
./home-modules/hyprland/hyprland.nix
|
./home-modules/hyprland.nix
|
||||||
./home-modules/hyprland/hyprland-autoname-workspaces.nix
|
./home-modules/hyprland-autoname-workspaces.nix
|
||||||
./home-modules/hyprland/waybar.nix
|
./home-modules/waybar.nix
|
||||||
./home-modules/wlogout.nix
|
./home-modules/wlogout.nix
|
||||||
|
|
||||||
./home-modules/kitty.nix
|
./home-modules/kitty.nix
|
||||||
@@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
./home-modules/theme/gtk.nix
|
./home-modules/theme/gtk.nix
|
||||||
./home-modules/theme/qt.nix
|
./home-modules/theme/qt.nix
|
||||||
|
|
||||||
|
./home-modules/python.nix
|
||||||
];
|
];
|
||||||
home.username = "nx2";
|
home.username = "nx2";
|
||||||
home.homeDirectory = "/home/nx2";
|
home.homeDirectory = "/home/nx2";
|
||||||
@@ -66,18 +68,6 @@
|
|||||||
gnumake
|
gnumake
|
||||||
|
|
||||||
speedtest-go
|
speedtest-go
|
||||||
|
|
||||||
(pkgs.python3.withPackages (python-pkgs: [
|
|
||||||
python-pkgs.ipython
|
|
||||||
python-pkgs.pipdeptree
|
|
||||||
python-pkgs.requests
|
|
||||||
]))
|
|
||||||
# (writeShellScriptBin "nxrbs-nix" ''
|
|
||||||
# set -e
|
|
||||||
# pushd ~/.nix-dots/
|
|
||||||
# git diff
|
|
||||||
# '')
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
xdg = {
|
xdg = {
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user