summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-02-05 00:20:37 -0600
committerCraig Jennings <c@cjennings.net>2026-02-05 00:20:37 -0600
commit337fd002603dbaeb25a682983f10fe4bb4e3a976 (patch)
tree916d20b2693a60a886369c6db9ab8901524268f1
parent314ea2272c0f4ce4631cb2de0f03f6e3c67c1f1b (diff)
chore(assets): archive processed inbox itemsHEADmain
-rw-r--r--assets/2026-02-01-gcalcli-setup.org192
-rw-r--r--assets/2026-02-03-languagetool-emacs.txt37
-rw-r--r--assets/2026-02-03-obs-studio-wayland.md22
-rw-r--r--assets/2026-02-03-yt-sync-improvements-obsolete.md100
-rw-r--r--assets/2026-02-04-gpg-encrypt-decrypt-scripts.md91
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