diff options
| author | Craig Jennings <c@cjennings.net> | 2026-02-05 00:20:37 -0600 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-02-05 00:20:37 -0600 |
| commit | 337fd002603dbaeb25a682983f10fe4bb4e3a976 (patch) | |
| tree | 916d20b2693a60a886369c6db9ab8901524268f1 | |
| parent | 314ea2272c0f4ce4631cb2de0f03f6e3c67c1f1b (diff) | |
| -rw-r--r-- | assets/2026-02-01-gcalcli-setup.org | 192 | ||||
| -rw-r--r-- | assets/2026-02-03-languagetool-emacs.txt | 37 | ||||
| -rw-r--r-- | assets/2026-02-03-obs-studio-wayland.md | 22 | ||||
| -rw-r--r-- | assets/2026-02-03-yt-sync-improvements-obsolete.md | 100 | ||||
| -rw-r--r-- | assets/2026-02-04-gpg-encrypt-decrypt-scripts.md | 91 |
5 files changed, 442 insertions, 0 deletions
diff --git a/assets/2026-02-01-gcalcli-setup.org b/assets/2026-02-01-gcalcli-setup.org new file mode 100644 index 0000000..38b13d4 --- /dev/null +++ b/assets/2026-02-01-gcalcli-setup.org @@ -0,0 +1,192 @@ +#+TITLE: gcalcli Setup for Calendar CLI Workflows +#+DATE: 2026-02-01 + +* Overview + +gcalcli is a Python CLI tool for managing Google Calendar from the command line. This enables calendar CRUD operations (create, read, edit, delete) via scripts and Claude Code workflows. + +* Installation + +#+begin_src bash +pipx install gcalcli +#+end_src + +* Authentication + +gcalcli requires your own Google Cloud OAuth credentials. + +** Prerequisites + +- Google Cloud project with Calendar API enabled +- OAuth 2.0 credentials (Desktop application type) +- Credentials stored in =~/.authinfo.gpg= (already configured for org-gcal) + +** Setup Steps + +1. Extract credentials from authinfo: + #+begin_src bash + gpg -d ~/.authinfo.gpg | grep org-gcal + # Format: machine org-gcal login CLIENT_ID password CLIENT_SECRET + #+end_src + +2. Initialize gcalcli with your client ID: + #+begin_src bash + gcalcli --client-id=YOUR_CLIENT_ID.apps.googleusercontent.com init + #+end_src + +3. When prompted, enter the client secret from authinfo + +4. Complete OAuth flow in browser (will open automatically) + +5. Token is stored in =~/.local/share/gcalcli/oauth= + +** Verify Setup + +#+begin_src bash +gcalcli list # List available calendars +gcalcli agenda # View upcoming events +#+end_src + +* Test Calendar + +Create a calendar named "Test Calendar" in Google Calendar for running automated tests. This keeps test events separate from real data. + +* Workflows Created + +Four calendar workflows in =~/projects/homelab/docs/workflows/=: + +| Workflow | Triggers | +|----------------------------+---------------------------------------------| +| add-calendar-event.org | "create event", "add appointment" | +| read-calendar-events.org | "what's on my calendar", "show schedule" | +| edit-calendar-event.org | "edit meeting", "reschedule" | +| delete-calendar-event.org | "delete meeting", "cancel appointment" | + +* Test Suite + +Test files in =~/projects/homelab/docs/scripts/tests/=: + +| Test File | Purpose | +|--------------------------------+----------------------------------| +| test-gcalcli-setup.sh | Verify installation and auth | +| test-gcalcli-add-event.sh | Event creation tests | +| test-gcalcli-read-events.sh | Read/query tests | +| test-gcalcli-edit-event.sh | Edit workflow tests | +| test-gcalcli-delete-event.sh | Deletion tests | +| test-gcalcli-integration.sh | Full CRUD lifecycle | + +Run tests: +#+begin_src bash +bash ~/projects/homelab/docs/scripts/tests/test-gcalcli-setup.sh +bash ~/projects/homelab/docs/scripts/tests/test-gcalcli-integration.sh +#+end_src + +* Configuration + +** Config File Location + +=~/.config/gcalcli/config.toml= + +** Edit Config + +#+begin_src bash +gcalcli config edit +#+end_src + +** Example Configuration + +#+begin_src toml +[gcalcli] +# Default calendar for operations +default-calendar = "Personal" + +# Calendars to ignore in listings +ignore-calendars = ["Holidays in United States", "Birthdays"] + +# Week starts on Monday (default: Sunday) +week-start = "monday" + +# Default event duration in minutes +default-duration = 60 + +# Color output +use-color = true +#+end_src + +** OAuth Token Location + +=~/.local/share/gcalcli/oauth= + +This file contains the OAuth refresh token. If authentication breaks, delete this file and run =gcalcli init= again. + +** Environment Variables + +#+begin_src bash +# Override config file location +export GCALCLI_CONFIG=~/.config/gcalcli/config.toml + +# Disable color output +export GCALCLI_NOCOLOR=1 +#+end_src + +** Calendar-Specific Defaults + +Use =--calendar= flag to override default: + +#+begin_src bash +gcalcli --calendar "Work" agenda +gcalcli --calendar "Test Calendar" add --title "Test" --when "tomorrow 3pm" --duration 30 --noprompt +#+end_src + +** Reminder Defaults + +Default reminders can be set per-calendar in Google Calendar settings. gcalcli respects these unless overridden with =--reminder= flags. + +Workflow default: =--reminder 5 --reminder 0= (5 minutes before, at event time) + +* Key Commands + +#+begin_src bash +# List calendars +gcalcli list + +# View agenda +gcalcli agenda +gcalcli agenda "today" "next week" + +# Calendar views +gcalcli calw # Weekly +gcalcli calm # Monthly + +# Add event +gcalcli add --title "Meeting" --when "tomorrow 3pm" --duration 60 --noprompt + +# Quick add (natural language) +gcalcli quick "Dinner with Bob 7pm Friday" + +# Search +gcalcli search "meeting" + +# Delete +gcalcli delete "Event Title" --iamaexpert +#+end_src + +* archsetup Integration + +Consider adding to archsetup: + +1. =pipx install gcalcli= in package installation +2. gcalcli init instructions in post-install docs +3. OAuth credentials setup reminder + +* Dependencies + +- pipx (for installation) +- Google Cloud project with Calendar API enabled +- OAuth credentials in =~/.authinfo.gpg= + +* Reference + +- gcalcli GitHub: https://github.com/insanum/gcalcli +- Auth docs: https://github.com/insanum/gcalcli/blob/HEAD/docs/api-auth.md +- Homelab research: =~/projects/homelab/docs/calendar-api-research.org= diff --git a/assets/2026-02-03-languagetool-emacs.txt b/assets/2026-02-03-languagetool-emacs.txt new file mode 100644 index 0000000..10431d9 --- /dev/null +++ b/assets/2026-02-03-languagetool-emacs.txt @@ -0,0 +1,37 @@ +LanguageTool - Grammar Checker for Emacs +======================================== + +REQUIREMENT +----------- +LanguageTool is used by Emacs for on-demand grammar checking in prose +files (org-mode, markdown, text-mode). It integrates with Flycheck to +provide comprehensive grammar and style suggestions. + +USAGE IN EMACS +-------------- +- Press C-; ? in an org buffer to run grammar check +- Errors appear in the *Flycheck errors* buffer +- Catches issues like "This are wrong" -> "This is wrong" + +INSTALLATION +------------ +Arch Linux: + sudo pacman -S languagetool + +Note: This will also install a Java runtime (JDK) as a dependency, +approximately 900 MB total. + +VERIFICATION +------------ +After installation, verify with: + languagetool --version + +FILES +----- +- ~/.emacs.d/modules/flycheck-config.el (Flycheck integration) +- ~/.emacs.d/scripts/languagetool-flycheck (Python wrapper script) +- ~/.emacs.d/tests/test-flycheck-languagetool-setup.el (Unit tests) +- ~/.emacs.d/tests/test-integration-grammar-checking.el (Integration tests) + +The wrapper script converts LanguageTool's JSON output to Flycheck's +expected format (filename:line:column: message). diff --git a/assets/2026-02-03-obs-studio-wayland.md b/assets/2026-02-03-obs-studio-wayland.md new file mode 100644 index 0000000..9a2a665 --- /dev/null +++ b/assets/2026-02-03-obs-studio-wayland.md @@ -0,0 +1,22 @@ +# OBS Studio on Wayland/Hyprland + +## Installation +```bash +sudo pacman -S obs-studio +``` + +## Required packages (should already be present on Hyprland) +- pipewire +- xdg-desktop-portal +- xdg-desktop-portal-hyprland + +## Hyprland config +Add to `~/.config/hypr/hyprland.conf`: +``` +exec-once = dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP +``` + +## Usage +- Use "Screen Capture (PipeWire)" source for monitors/windows +- Portal dialog appears on first capture to select screen/window +- PipeWire handles audio capture automatically diff --git a/assets/2026-02-03-yt-sync-improvements-obsolete.md b/assets/2026-02-03-yt-sync-improvements-obsolete.md new file mode 100644 index 0000000..0db1161 --- /dev/null +++ b/assets/2026-02-03-yt-sync-improvements-obsolete.md @@ -0,0 +1,100 @@ +# yt-sync.sh Improvements + +## Problem +- Current scan takes 1-2 hours +- Scans 200 videos × 15 channels = 3000 metadata fetches +- Most videos are skipped (already downloaded or too old) +- Cron running hourly causes overlap + +## Speed Improvements for yt-dlp + +### 1. Break on existing (RECOMMENDED) +```bash +--break-on-existing +``` +Stops scanning when it hits a video already in archive. Since playlists are chronological, once we hit an old video, all subsequent are old too. + +### 2. Break on date reject +```bash +--break-on-reject +``` +Stops when hitting a video outside the --dateafter range. Combined with chronological order, stops at first old video. + +### 3. Reduce playlist scan depth +```bash +--playlist-end 50 # Instead of 200 +``` +Most channels don't post 50 videos in 30 days. + +### 4. Track last sync timestamp +Store last successful sync time and use tighter --dateafter: +```bash +LAST_SYNC_FILE="$YOUTUBE_DIR/.last_sync" +if [[ -f "$LAST_SYNC_FILE" ]]; then + LAST_SYNC=$(cat "$LAST_SYNC_FILE") + DATE_AFTER="--dateafter $LAST_SYNC" +else + DATE_AFTER="--dateafter $(date -d '30 days ago' '+%Y%m%d')" +fi +# After successful sync: +date '+%Y%m%d' > "$LAST_SYNC_FILE" +``` + +### 5. Parallel channel downloads (aggressive) +Use GNU parallel to download multiple channels simultaneously: +```bash +parallel -j 3 yt-dlp [opts] ::: "${CHANNELS[@]}" +``` +Risk: More likely to trigger rate limiting. + +## Scheduling Options + +### Option A: Systemd timer (prevents overlap) +```ini +# ~/.config/systemd/user/yt-sync.timer +[Unit] +Description=YouTube Sync Timer + +[Timer] +OnCalendar=*-*-* 00,06,12,18:00:00 +Persistent=true + +[Install] +WantedBy=timers.target +``` + +```ini +# ~/.config/systemd/user/yt-sync.service +[Unit] +Description=YouTube Sync + +[Service] +Type=oneshot +ExecStart=/home/cjennings/.local/bin/yt-sync.sh all +ExecStartPost=/home/cjennings/.local/bin/yt-sync.sh sync +``` + +Systemd won't start a new run if previous is still running. + +### Option B: Lock file wrapper +```bash +#!/bin/bash +LOCKFILE="/tmp/yt-sync.lock" +exec 200>"$LOCKFILE" +flock -n 200 || { echo "Already running"; exit 1; } +# ... run sync ... +``` + +### Option C: Longer cron interval +```cron +# Every 4 hours during off-peak +0 0,4,20 * * * /home/cjennings/.local/bin/yt-sync.sh all && yt-sync.sh sync +``` + +## Recommended Changes + +1. Add `--break-on-existing` to YT_OPTS (biggest win) +2. Add `--break-on-reject` to YT_OPTS +3. Reduce `--playlist-end` to 50 +4. Use systemd timer instead of cron +5. Optionally track last sync date for tighter filtering diff --git a/assets/2026-02-04-gpg-encrypt-decrypt-scripts.md b/assets/2026-02-04-gpg-encrypt-decrypt-scripts.md new file mode 100644 index 0000000..c4fffbe --- /dev/null +++ b/assets/2026-02-04-gpg-encrypt-decrypt-scripts.md @@ -0,0 +1,91 @@ +# GPG Encrypt/Decrypt Scripts + +Created 2026-02-04. Two utility scripts for symmetric GPG encryption with clipboard support. + +## Scripts + +### encryptfile + +Location: `~/.local/bin/encryptfile` + +Encrypts a file using symmetric GPG (password-based, no key required). + +```bash +#!/bin/bash +# Encrypt a file with symmetric GPG (password-based) +# Usage: encryptfile <file> + +if [ -z "$1" ]; then + echo "Usage: encryptfile <file>" + exit 1 +fi + +if [ ! -f "$1" ]; then + echo "File not found: $1" + exit 1 +fi + +gpg --symmetric --cipher-algo AES256 --armor -o "${1}.gpg" "$1" && \ + echo "Encrypted to ${1}.gpg" && \ + rm -i "$1" +``` + +### decryptfile + +Location: `~/.local/bin/decryptfile` + +Decrypts a GPG file and copies content to system clipboard. Supports both Wayland (wl-copy) and X11 (xclip). + +```bash +#!/bin/bash +# Decrypt a GPG file to clipboard (symmetric) +# Usage: decryptfile <file.gpg> + +if [ -z "$1" ]; then + echo "Usage: decryptfile <file.gpg>" + exit 1 +fi + +if [ ! -f "$1" ]; then + echo "File not found: $1" + exit 1 +fi + +# Decrypt and copy to clipboard +if command -v wl-copy &> /dev/null; then + # Wayland + gpg --decrypt "$1" 2>/dev/null | wl-copy + echo "Decrypted content copied to clipboard (Wayland)" +elif command -v xclip &> /dev/null; then + # X11 + gpg --decrypt "$1" 2>/dev/null | xclip -selection clipboard + echo "Decrypted content copied to clipboard (X11)" +else + echo "No clipboard tool found (need wl-copy or xclip)" + echo "Decrypting to stdout instead:" + gpg --decrypt "$1" +fi +``` + +## Usage + +```bash +# Encrypt a file (prompts for password, deletes original) +encryptfile ~/.secrets/some-password + +# Decrypt to clipboard (prompts for password) +decryptfile ~/.secrets/some-password.gpg +``` + +## Notes + +- Uses AES256 cipher for encryption +- Outputs armored (ASCII) format for portability +- Prompts to delete original file after encryption +- Clipboard copy clears automatically on some systems +- Consider using `pass` (standard unix password manager) for more robust solution - wraps GPG with better UX + +## Dependencies + +- `gpg` +- `wl-copy` (Wayland) or `xclip` (X11) for clipboard support |
