Rebuild dotfiles as one branch with per-host layers

Replaces the previous repo, which had split into two histories that never
met (mainframe on a dead GitLab remote, the laptops on Gitea) with 146
dirty files across three machines and the NAS never enrolled at all.

Branch-per-machine is gone. One main, with host differences expressed as
small files under hosts/<hostname>/ rather than as branches, so there is
nothing to merge. The reconciled zsh layer reduces 15-33 line forks to
1-7 effective lines per host; distro differences (oh-my-zsh prefix,
syntax-highlighting path, fd vs fdfind) are probed in common/ instead.

Fresh history: the old one carried six plaintext credentials, 45 MB of
mail caches, browser caches and vendored binaries. 5,096 tracked files
and 144 MB become 462 files and 2.6 MB. The .gitignore is now an
allowlist, which is what keeps that true.

Root cause of the rot: ~/.local/bin was a symlink to scripts/ with GOPATH
inside it, so every go install wrote into version control (2.2 GB on the
work laptop). PATH now points at the repo instead of the reverse.

Also: Hyprland replaces sway and is sourced in two halves so $browser is
defined before use; singleton automations carry ConditionHost= alongside
host-layer-only placement; ddns moves from cron to a guarded timer;
package manifests and pkg-snapshot/pkg-restore replace the X11-era
install_scripts/; networkmanager-dmenu added to system76 (the binding
always existed, the package never did).
This commit is contained in:
connor committed 2026-09-14 14:24:37 -04:00
commit e6644d0616
462 files changed
+23524

No files matched your search

+36
View File
@@ -0,0 +1,36 @@
# If a config.py file exists, this file is ignored unless it's explicitly loaded
# via config.load_autoconfig(). For more information, see:
# https://github.com/qutebrowser/qutebrowser/blob/main/doc/help/configuring.asciidoc#loading-autoconfigyml
# DO NOT edit this file by hand, qutebrowser will overwrite it.
# Instead, create a config.py - see :help for details.
config_version: 2
settings:
auto_save.session:
global: true
content.desktop_capture:
global: true
content.javascript.clipboard:
https://ai.rcjohnstone.com: access-paste
https://chatgpt.com: access-paste
https://claude.ai: access-paste
https://huggingface.co: access-paste
https://www.google.com: access-paste
content.media.audio_capture:
global: true
https://voice.google.com: true
content.media.audio_video_capture:
global: true
https://gov.teams.microsoft.us: true
content.media.video_capture:
global: true
content.notifications.enabled:
https://mail.proton.me: false
https://runway.rcjohnstone.com: true
https://voice.google.com: false
https://www.chess.com: false
https://www.italki.com: true
content.register_protocol_handler:
https://mail.proton.me#mailto=%25s: false
tabs.show:
global: always
+28
View File
@@ -0,0 +1,28 @@
https://www.codecademy.com/paths/web-development/tracks/getting-started-with-javascript/modules/learn-javascript-introduction/lessons/introduction-to-javascript/exercises/libraries Learn JavaScript: Introduction | Codecademy
https://docs.google.com/spreadsheets/d/1izX7ZJX_ATHFUEuRw-tFlyV1dWhMwJb9PkEGh6p-wrU/edit#gid=0 Air Composition Bounds - Google Sheets
https://hangouts.google.com/ Google Hangouts
https://docs.google.com/spreadsheets/d/1ep7lTi1iSDn6wBlDLUWstPsxuKIIxYUGRiIC4fg7mnY/edit#gid=0 Untitled spreadsheet - Google Sheets
https://gitlab.palskichat.com/usspacetraining/simulator/merge_requests/3 Sim announce creation/destruction (!3) · Merge Requests · US Space Training / simulator · GitLab
https://sts.digitalglobe.com/adfs/ls/?login_hint=connor.johnstone%40sslmda.com&client-request-id=a7cda4d2-77e1-4095-8e2a-ab7e63e54b09&username=connor.johnstone%40sslmda.com&wa=wsignin1.0&wtrealm=urn%3Afederation%3Amicrosoftonline.us&wreply=https%3A%2F%2Flogin.microsoftonline.us%2Flogin.srf&wctx=estsredirect%3D5%26estsrequest%3DrQIIAYWUP8jcdBjHe-9b39pWahUHQZAODlLI9Zf_yTs1ufy5y5vk7nK5yyUIIf8u_3-5N8ld7m5wFgcpQhdHES11Eafi6FgQiqPgoCCIk3Rx9aq4OOjyDA_fhw_P8P3cuEb18T7og7unaB89f4fACdKjfRZhPQpHCBYFiEdgFIKTOIVjAA1JgNev37j9_WffffFT9_D-R3e_fD_45eL6497bSduum_N797qu61erVRpE_aAq7xUeDFMYP-n1nvV6v_Z6H5-8FVQQVnU_qxLYtBWM7jdNUYbei_jjk4bCaYyiMBrHCAIcsSTWdwQl10x7PxaCVs-KTB8AYJd6ploiqR-4VhOCvWbOu7GQ7xxLA1oWo7qpF_ZBazUzKbXZMW-NCNXMUU3gWl3gDo452jtCToxNqfzh5NUxt2kT7MWo6vQQPT-5vqrq0l1XTfvJ6VfX6uloxNnWbGtvTZsTZBVBQ3ZOG_NdJ04tssuVce6zJMMOq7hUN2DZVmU7h1RqCJ4u4jMFQp_U8CJvJGeoGRIPAkMKsWCnD3dTnh92c4kXB-EOhENKomMGdJMJR7urXVxGdppwcQQYM5TpBZrKpO0VcydvBLyUHa0Bo1HQkGIp23gsc7DWuJnNbOkhyUSQJlFklhxWG59GKBun6ppmcjVr7AM1Ce1MUsR4rSuX5Ho-8_cpS3SyuuFd244niSCGhEJAaXPg6ot2G-ykiTQeTDhWFWTDafhDPBLmU--gOzQV6iAwL1CluUQ6AayspUdJNqEY405VLte1GpnrLKZlaBQjkW2tVlzUpKtYuh0uWc9yPVrUt1NHtZvBIp8mMpLMxgkPfWm8Rdbs3iHbQcbjhIoKldN6W3xSiYlP7IydhMAhMk_BZm8SF5vmEDATuYoLJwASdZlx7GI9kCVBk_jMEohApxUsmq0XgeZT3tKsi2aaI4DGNbVwlnR82YFO3KiDPTaOJmw62vr-htj5scDtSbExnG5hSLRItonrpFGI7EHJzjTDwHyl5fztPDV3isdP564cBNDqYLmscGB4q4UItw7QAFRXF6OtQE3XqhRNqI2WY8NVADw1CyHvL6bHntWUHdW2GmLmZNHOmmMLpJGBTyPSKxn1chzNHC7BDx6dlIuS5i4sd8eXhYM2ydyXU29hpRBVunXU8YWSuzgJxySsvfJQ8jkdtCwCZ0xjr6pqrFGr6VKrAy30mR2vLzWXKms2r1KeG5kLyUz4RJJivGqyw47RXURAGjFjLZNkGn9sb-ty3y5VwB22O0dxqEadYpQb-UmD0m7o4tKlsfIh4obWoYguQM3Oajmj4_jSnNgy9IeT5ayxIob3Mk2smMLws3BZpuOtpHv5qG70EMllPpK4ajvYBEcBHQxe9lQ1YHV6UI2FagMVXZxSsCpTopEWvOSNBis-UjepY-GUyxjsjEG_Pj072qSs4NPTW9U6gml4Z11Xq7SIfj79L_88u9r77eorL5_dPn3zyp0r774Bbj2_-j9m-_Slow_fe_Lw86X9x8Wjm4_u_vjhh1cenPUenJ19e_Z6mQZ11VSrI6dIYdTfNE_PXhsJri6aM5M7isgQMBf8fnbywbUr31y__w-qqOIU9v99_IL691v3dK9NK-gVg6LahFIURvVfix9uvIEBDCCAQgB6B6XOSfIcZ5wPbvb-BA2# Sign In
https://todoist.com/app/?r=1567192910424#project%2F955568460%2Ffull Personal: Todoist
https://mxrgcc-my.sharepoint.us/:x:/r/personal/nick_staehler_digitalglobe_com/_layouts/15/guestaccess.aspx?e=ibkRBn&share=ERV-6_TTNV1Hi9YKbLzArMYB-plW6Oez81y3Z9kaFg8raw Book.xlsx
https://app.youneedabudget.com/44b49b05-e87e-4e1c-9bb2-8f239df455b7/budget/202007 Budget | 2018 | YNAB
https://todoist.com/app/?r=1567192910424#upcoming Upcoming: Todoist
https://todoist.com/app/#start Upcoming: Todoist
https://docs.google.com/document/d/1Xpq1i5eRtg77f6eGAeNhYr1UK_fUCx-IXUn-qO_vcpg/edit Spring 21 Thesis Starting Point - Google Docs
https://voice.google.com/u/0/messages?itemId=t.%2B15024424023 Voice - Ben Schardein
https://rconnorjohnstone.com/ Richard Connor Johnstone
https://confluence.nyxatlas.com/pages/resumedraft.action?draftId=21004570&draftShareId=1a28a278-63b5-41fa-bd45-04c3ad3aa1c1& Edit - D-Region Absorption Model - SET4D Mission - SET4D
https://confluence.nyxatlas.com/pages/resumedraft.action?draftId=21954601&draftShareId=91c77ddc-8628-484c-bd56-129354a53c69& Plotting Page - SET4D Mission - SET4D
https://tasks.rconnorjohnstone.com/login Login | Vikunja
https://cronometer.com/#custom-foods Cronometer
https://arcfield.sharepoint.us/:x:/r/teams/RROCI-2/_layouts/15/Doc.aspx?sourcedoc=%7B6F6B1842-D840-43ED-B36A-8984742B48B3%7D&file=Measurement%20Mode%20Orientation%20Tracking.xlsx&fromShare=true&action=default&mobileredirect=true Measurement Mode Orientation Tracking.xlsx
https://rdweb.wvd.azure.us/arm/webclient/index.html Remote Desktop Web Client
https://onestop.registration.ky.gov/ers/TaxRegistration/AdditionalInformation AdditionalInformation - KY OneStop Tax Registration
https://web.whatsapp.com/ WhatsApp
https://www.youtube.com/watch?v=TOs5cR-10xA (207) An Italian Tries CATHY MITCHELL's Pasta Recipes (it didn't go well) - YouTube
https://arcfield.sharepoint.us/:p:/r/teams/Ouija1/_layouts/15/Doc.aspx?sourcedoc=%7B7637D81B-64ED-4C72-A77F-D9AED88D0236%7D&file=OUIJA%20Re-entry%20Analysis%20August%202025%20with%20Copper%20Pucks.pptx&action=edit&mobileredirect=true OUIJA Re-entry Analysis August 2025 with Copper Pucks.pptx
https://voice.google.com/u/0/messages?itemId=t.%2B15025541141 Voice - Messages
https://claude.ai/chat/bd163dd2-45ab-4376-9c8e-3560230dd2a3 Makefile shell command best practices - Claude
https://arcfield-my.sharepoint.us/:p:/r/personal/matthew_cooper_arcfield_com/_layouts/15/Doc.aspx?sourcedoc=%7BB5C78A7E-B47D-4DA6-92A2-C2F5F7E62088%7D&file=2026_HORUS-OSIRIS_IRaD_KickoffSlides.pptx&fromShare=true&action=edit&mobileredirect=true 2026_HORUS-OSIRIS_IRaD_KickoffSlides.pptx
https://claude.ai/chat/28944c2b-f3a4-47d9-9854-aab012449b34 C++ for loop iteration range - Claude
+25
View File
@@ -0,0 +1,25 @@
# Qutebrowser color scheme from wallust
# You can use this template by adding the following to wallust.toml:
# qutebrowser = { src = "qutebrowser.py", dst = "~/.config/qutebrowser/colors.py" }
# and then on config.py:
# from colors import *
foreground = "#E8EFFC"
background = "#171917"
color0 = "#414441"
color1 = "#718B81"
color2 = "#86B4C4"
color3 = "#DCA0D2"
color4 = "#9CBBDA"
color5 = "#E3B0CE"
color6 = "#BED0F7"
color7 = "#D6DFF2"
color8 = "#969CAA"
color9 = "#718B81"
color10 = "#86B4C4"
color11 = "#DCA0D2"
color12 = "#9CBBDA"
color13 = "#E3B0CE"
color14 = "#BED0F7"
color15 = "#D6DFF2"
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,31 @@
// ==UserScript==
// @name Userstyle (dreamingspanish.css)
// @include *dreaming.com*
// ==/UserScript==
GM_addStyle(`.ds-page {
max-width: 95%;
}
.ds-form-calendar {
gap: 0.6rem;
}
.ds-form-calendar__row {
height: 3.5rem;
}
.ds-form-calendar__column {
height: 100%;
font-size: 1rem;
font-weight: 700;
}
.ds-form-calendar__column-wrapper {
width: 90%;
}
.ds-form-calendar__column-time {
font-size: 0.65rem;
line-height: 1.4rem;
}
`)
@@ -0,0 +1,12 @@
// ==UserScript==
// @name Userstyle (italki.css)
// @include *italki.com*
// ==/UserScript==
GM_addStyle(`.MessageList-main {
padding-bottom: 250px !important;
}
#app .min-h-10 {
min-height: 200px !important;
}
`)
@@ -0,0 +1,41 @@
// ==UserScript==
// @name Userstyle (qute.help.css)
// @include qute://help*
// @include *someotherdomain.xyz*
// ==/UserScript==
GM_addStyle(`html {
background-color: #041E39;
}
html > body, html ul > li > * {
color: #EBEBD3;
font-family: sans-serif;
}
html a {
color: #F78764;
}
html a:visited {
color: #2D8CF0;
}
.monospaced, code, pre {
color: #F4D35E;
}
div.admonitionblock {
color: #FAB49E;
font-weight: bold;
}
html em, html dt {
color: #FAB49E;
font-weight: bold;
}
html div.listingblock > div.content, div.listingblock .highlight {
background-color: #611B05;
}
`)
@@ -0,0 +1,8 @@
// ==UserScript==
// @name Userstyle (readthedocs.css)
// @include *readthedocs.io*
// ==/UserScript==
GM_addStyle(`.wy-nav-content {
max-width: 1200px;
}
`)
@@ -0,0 +1,8 @@
// ==UserScript==
// @name Userstyle (twitch.css)
// @include *twitch.tv*
// ==/UserScript==
GM_addStyle(`body {
width: 80% !important;
}
`)
@@ -0,0 +1,8 @@
[FileDialog]
history=file:///home/connorjohnstone/scout/projects/gnsuite_temp, file:///home/connorjohnstone/docs/dnd/one_shots/tress/guide/build, file:///home/connorjohnstone/downloads, file:///home/connorjohnstone, file:///home/connorjohnstone/scout/projects/sim_prototype
lastVisited=file:///home/connorjohnstone
qtVersion=6.11.1
shortcuts=file:, file:///home/connorjohnstone, file:///home/connorjohnstone/scout, file:///tmp, file:///mnt
sidebarWidth=110
treeViewHeader=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2Q\0\0\0\x4\x1\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x4\0\0\x1V\0\0\0\x1\0\0\0\0\0\0\0\x62\0\0\0\x1\0\0\0\0\0\0\0\x38\0\0\0\x1\0\0\0\0\0\0\0\x61\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1)
viewMode=Detail
+134
View File
@@ -0,0 +1,134 @@
ynab https://app.youneedabudget.com/44b49b05-e87e-4e1c-9bb2-8f239df455b7/budget
schwab https://www.schwab.com/
538 https://fivethirtyeight.com/
chase https://www.chase.com/
discover https://www.discover.com/
reddit https://www.reddit.com/
mtn https://www.mountainproject.com/
khc https://kyhousing.estatusconnect.com/index.html#/home/login
netflix https://www.netflix.com/browse
digitalocean https://cloud.digitalocean.com/projects/a159e12a-d207-4870-a787-9b8e1f0bcfe8/resources?i=c279e6
plotlyjs https://plot.ly/javascript/reference/#scatter
yt https://www.youtube.com/
photos https://photo.rcjohnstone.com/photos
maps https://www.google.com/maps
rent https://realiantcincinnati.appfolio.com/connect
nyt https://www.nytimes.com/
reuters https://www.reuters.com/
ap https://apnews.com/
files https://files.rcjohnstone.com/
baikal https://baikal.rcjohnstone.com/
spotify https://open.spotify.com/collection/tracks
cal_inspirations https://uicookies.com/css-calendar/
pomodoro https://pomofocus.io/
weather https://www.accuweather.com/en/us/cincinnati/45202/weather-forecast/350126
bw https://bw.rcjohnstone.com/#/vault
cronometer https://cronometer.com/
boa https://www.bankofamerica.com/
ascii https://textkool.com/en/ascii-art-generator?hl=default&vl=default&font=ANSI%20Regular&text=Connor%20Johnstone
host https://check-host.net/
git_work https://gitserver.idm.orionspace.com/users/sign_in
tsheets https://tsheets.intuit.com/page/login_oii
tasks https://tasks.rconnorjohnstone.com/login
unifi https://localhost:8443/manage/default/dashboard
mail https://mail.proton.me/u/0/inbox
home https://home.rcjohnstone.com/
radarr https://radarr.rcjohnstone.com/
lidarr https://lidarr.rcjohnstone.com/
sonarr https://sonarr.rcjohnstone.com/
readarr https://readarr.rcjohnstone.com/
prowlarr https://prowlarr.rcjohnstone.com/
deluge https://deluge.rcjohnstone.com/
jellyfin https://jellyfin.rcjohnstone.com/web/#/home.html
gov_outlook https://outlook.office365.us/mail/inbox
outlook https://outlook.office365.us/mail/
office https://www.office.com/?auth=2
pw https://cloud.parallel.works/u
navidrome https://music.rcjohnstone.com/app/#/album/recentlyAdded?sort=recently_added&order=DESC&filter=%7B%7D
aws https://d-9a6717b3d2.awsapps.com/start/#/?tab=accounts
jira https://arcfield.atlassian.net/jira/your-work
powerpoint https://www.office365.us/launch/powerpoint?home=1&auth=2
idp https://us-east-2.signin.aws.amazon.com/oauth?client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&code_challenge=hI-YTRoJe-q_Opf7U6MJ3j8VMH1kKcu0lvHNb2s6KlI&code_challenge_method=SHA-256&response_type=code&redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3FhashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-east-2_8a19eb167a21c928&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEKX%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMiJIMEYCIQDqnVwz2X34AZVABzKtfHEPE%2F59u9rQQEkJ0o6gDV%2BO8QIhAOSZJo6tpkb60bJizA%2BO5Zi1kqzgQ1%2B7IJGHxZtX5Gy2KpMCCN7%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEQARoMOTE0NTM5MTg3MDEzIgxl8i0DimVmLyH8BGQq5wEuNonk7zorfA97NzhaMzmw%2FqWpkQDhId%2Bc7t2zDHa%2FLJd3UFX6WFJc0yZ7vV1ALw5HdYbAyKHp7F9DLY7GGsnSoZPyaEFgufyXGrK%2B0TKy%2FNKnzoQhkAPeV39sXSLLzPGy409dKwo%2FwwdOv6q7XTK%2FpgdBlnmq3EtVRfGjGTDbLtBKwOPD2DU%2FE%2Fc0%2FPv8GJVVZuL3iPblbiprdnAKh5MKtZiXuYLQpEanD0ep9qjLZfkDhlz6kkzRGOlZuzcADAvduDNNu4bAv060coXws9HqBZmTvP9Y0oR1iDPKZU15Y9XrP6mP4KAwxJm1qgY6jgF7YtgvKj9LsOY%2B8mKzAUtm%2BiRAmCVNAE%2FRmqaiUqTLdMwPf1NuLuzoDMl92r9C1FjinI4B2YzLiFT1QhldZy1PaqiwZ3A6heGl6Ukjc%2BykLWGkKX7udDPE6t%2FwF%2BRB%2Bll84WsdrDzDgfnWWXt2avODw3aZIbyHd1LYG2LTXBYfKW0S05QQ8GFOh5pb8QBk&X-Amz-Date=20231109T213036Z&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIA5J3WIRNCUZKZXBV6%2F20231109%2Fus-east-2%2Fsignin%2Faws4_request&X-Amz-SignedHeaders=host&X-Amz-Signature=2fb29f68a471103ac445233ac6c66bdaac91cd5a4cf8e38b7a7b47872517b250
rroci_grafana http://10.10.201.55:3000/login
confluence https://scout-space.atlassian.net/wiki/spaces/SCOUTSPACE/pages/250642433/Weekly+TACFI+Owl?contentRecommendation=on&popular=true
colorschemes http://gogh-co.github.io/Gogh/
gitlab https://gitlab.rcjohnstone.com/users/sign_in
chatgpt https://chat.openai.com/
git_idp https://gitlab.orionspacestation.com/users/sign_in
apps https://myapplications.azure.us/
vdi https://rdweb.wvd.azure.us/arm/webclient/index.html
grafana https://3.30.135.27:3000/
teams https://gov.teams.microsoft.us/v2
voice https://voice.google.com/u/0/messages
cal https://cal.rcjohnstone.com/
aero https://filespace.aero.org/human.aspx?r=4292318470
whatsapp https://web.whatsapp.com/
sedaro_onedrive https://sedarocorp-my.sharepoint.us/personal/robbie_robertson_sedaro_com/_layouts/15/onedrive.aspx?id=%2Fpersonal%2Frobbie_robertson_sedaro_com%2FDocuments%2F00%20Sedaro%20Drive%2F06%20Contracts%2F15%20RROCI%2FDeliverables%2FOrion_Sedaro_Fileshare&ga=1
sedaro_sharepoint https://sedarocorp-my.sharepoint.us/personal/robbie_robertson_sedaro_com/_layouts/15/onedrive.aspx?id=%2Fpersonal%2Frobbie_robertson_sedaro_com%2FDocuments%2F00%20Sedaro%20Drive%2F06%20Contracts%2F15%20RROCI%2FDeliverables%2FOrion_Sedaro_Fileshare&ga=1
jellyseerr https://jellyseerr.rcjohnstone.com/
e https://192.168.1.101:8006/#v1:0:=qemu%2F101:4:::::8::
element https://element.rcjohnstone.com/
aws access portal https://start.us-gov-east-1.us-gov-home.awsapps.com/directory/d-c267218df8#/?tab=accounts
aws portal https://start.us-gov-east-1.us-gov-home.awsapps.com/directory/d-c267218df8#/?tab=accounts
satrs https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main
vorago https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/embassy/src/time_driver.rs
jelly https://jellyfin.rcjohnstone.com/web/#/home.html
transmission https://transmission.rcjohnstone.com/transmission/web/
boxes.py https://boxes.hackerspace-bamberg.de/
router https://10.0.0.1/
laser templates https://www.templatemaker.nl/en/
laser_puzzles https://draradech.github.io/jigsaw/jigsaw.html
fte https://arcfield.sharepoint.us/:x:/r/sites/ProgramMissionManagementOfficePM2O/_layouts/15/doc2.aspx?sourcedoc=%7B344DE6A2-BC95-4BFE-8D73-81C0803EB62C%7D&file=Orion%20FTE%20Tracker%20Base%20-%20ACTIVE%20FILE.xlsm&action=default&mobileredirect=true
ai https://ai.rcjohnstone.com/
dsa_cal https://www.dsalouisville.org/events/events-calendar
sftp https://sftp.rcjohnstone.com/web/client/login
wled http://192.168.1.182/#Colors
kraken/requirements https://arcfield.sharepoint.us/:x:/r/teams/Ouija1/_layouts/15/Doc.aspx?sourcedoc=%7B369FB775-26A9-4C95-9FC7-8EF0BA0B015B%7D&file=402SPEC100%20-%20Kraken%20Requirements%20Verification%20Matrix%2009092024.xlsx&action=default&mobileredirect=true
kraken/trr https://arcfield.sharepoint.us/:p:/r/teams/Ouija1/_layouts/15/Doc.aspx?sourcedoc=%7B0DED2C57-DC24-4C97-8B1A-ABF8B9210319%7D&file=CUI-OUIJA-Kraken-TA1-Full%20System%20Test%20Readiness%20Review.pptx&action=edit&mobileredirect=true&previoussessionid=822b8401-6b37-130b-a7cb-bcc1eb9e7398
kraken/flexcore_icd https://arcfield.sharepoint.us/teams/Ouija1/Shared%20Documents/Forms/AllItems.aspx?id=%2Fteams%2FOuija1%2FShared%20Documents%2FTA1%20%28Kraken%29%20Phase%201%2FSystems%20Engineering%2FICDs%2FEXTERNAL%2FADCS%2FFlexcore%2F30ICD4249revB%20-%20FleXcore%20Gen3.1%20Interface%20Control%20Document%20%28ICD%29%20%284%29.pdf&parent=%2Fteams%2FOuija1%2FShared%20Documents%2FTA1%20%28Kraken%29%20Phase%201%2FSystems%20Engineering%2FICDs%2FEXTERNAL%2FADCS%2FFlexcore
kraken/rsso qute://pdfjs/web/viewer.html?filename=tmpluv5gspz_PPD_1011_RC_FINAL.pdf&file=&source=https://ntrs.nasa.gov/api/citations/20230001348/downloads/PPD_1011_RC_FINAL.pdf
lisird_f107 https://lasp.colorado.edu/lisird/data/display?lz=N4IgDgNg9gLgziAXCYAdc17sQbTSAEwEMYi4BTLJPdY0imASQO3QGMI4B9AJyIICWULgDMIAVwAeogIwAGAOzoANOj4A7AObkAakR5xsNEOqIBbcqxD8AVuLgxyBWYq5sVtAXEhEAngDlzSyR0AGEoHh5yNkcCAAIAQQI7Byc4gCV%2BITiAMQlJdABfAF0S1RAoMBghdUMkYEKy9AA3KxkAOgAmdrkikGUQTWgAIyIIAHkqmoRkfCGoUYgAWXJ1cUnqqFrsBsKQQqA
books1 https://annas-archive.org/
books2 http://libgen.rs/
books3 https://www.reddit.com/r/Piracy/comments/2oftbu/guide_the_idiot_proof_guide_to_downloading_ebooks/
kvm https://pikvm/login/
aws_gov https://start.us-gov-east-1.us-gov-home.awsapps.com/directory/d-c267218df8#/?tab=accounts
gitea https://git.rcjohnstone.com/
wenzel_water https://louisvilleky.watersmart.com/index.php/home/index
wenzel_lge https://my.lge-ku.com/cs/doStart.sap
wenzel_internet https://www.att.com/acctmgmt/overview?authNState=Y&haloSuccess=true&lt=QHVBdylFK25HdGFncnh8dmd5a0x8ZCZRNDgmPiVPPGpuJiJnPyhbSzY0ODduPiZGVCRxeVoiJkA%3D
box https://console.hetzner.com/projects/11834759/storage-boxes/474410/overview
git_arcfield https://gitlab.arcfield.com/users/sign_in
lazylibrarian https://lazylibrarian.rcjohnstone.com/authors
ll https://lazylibrarian.rcjohnstone.com/authors
drawers https://www.printables.com/model/1149008-improved-modular-gridfinity-drawers/files
gridfinity https://gridfinity.tools/
itatorrents https://itatorrents.xyz/
insta https://www.instagram.com/
ha http://10.0.0.2:8123/auth/authorize?response_type=code&redirect_uri=http%3A%2F%2F10.0.0.2%3A8123%2F%3Fauth_callback%3D1&client_id=http%3A%2F%2F10.0.0.2%3A8123%2F&state=eyJoYXNzVXJsIjoiaHR0cDovLzEwLjAuMC4yOjgxMjMiLCJjbGllbnRJZCI6Imh0dHA6Ly8xMC4wLjAuMjo4MTIzLyJ9
conferences https://spaceindustrydatabase.com/events
camera https://camera.rcjohnstone.com/
authentik https://bus-auth.ntc.dsausa.org/if/user/#/library
lichess_time https://ra314.github.io/lichess-time-tracker/
maproulette https://maproulette.org/browse/challenges/53913
spanish_notes https://www.tldraw.com/f/M4_Lwl178dtCuMz6mbbnC?d=v-147.199.2156.1157.page
whisparr https://whisparr.rcjohnstone.com/
scout/github https://github.com/SCOUTdotspace
gusto https://app.gusto.com/
scout/sharepoint https://scoutspacegcchigh.sharepoint.us/_layouts/15/sharepoint.aspx
scout/thrivepass https://app.thrivepass.com/dashboard
shanty https://shanty.rcjohnstone.com/
greenhouse https://app8.greenhouse.io/dashboard
scout/owl/icd_sheet https://scoutspacegcchigh.sharepoint.us/:x:/s/ScoutPrograms/IQBD2Qz4VNIaSqArGE1jyCCzAcyeSs-A0CBFq35ZsRabZTk?e=PIphpz&isSPOFile=1&ovuser=f50f4fcc-38ea-4525-a42e-e89136a91fed%2Cconnor.johnstone%40scout.space&clickparams=eyJBcHBOYW1lIjoiVGVhbXMtRGVza3RvcCIsIkFwcFZlcnNpb24iOiIxNDE1LzI2MDIyNzA0MjE1IiwiSGFzRmVkZXJhdGVkVXNlciI6ZmFsc2V9
scout/tailscale https://login.tailscale.com/admin/machines
wordle https://www.nytimes.com/games/wordle/index.html
contexto https://contexto.me/en/
sim http://localhost:5173/
conjugaciones https://spanish.rcjohnstone.com/
time https://time.rcjohnstone.com/#/dashboard/4/Spanish
kimi https://platform.kimi.ai/console/general
openai https://platform.openai.com/home
anthropic https://platform.claude.com/dashboard
moey_rent https://moeyproperties.managebuilding.com/Resident/portal/
jessica https://meet.google.com/pez-pnzg-nxo
dashboard https://docs.google.com/spreadsheets/d/1vwAxNKKzGNAPbqasXk52l8O0v4WfCXaxZmDd4ZzQYl8/edit?gid=1259809999#gid=1259809999
+119
View File
@@ -0,0 +1,119 @@
# import json
# import os
#
# qutewal_dynamic_loading = False
#
# home = os.getenv('HOME')
# colors_relative = '.cache/wal/colors.json'
# daemon_relative = '.config/qutebrowser/qutewald.py'
# colors_absolute = os.path.join(home, colors_relative)
# daemon_absolute = os.path.join(home, daemon_relative)
#
# if os.path.isfile(colors_absolute):
# with open(colors_absolute) as colorfile:
# colors = json.load(colorfile)
# cursor = colors['special']['cursor']
# background = colors['special']['background']
# foreground = colors['special']['foreground']
# black = colors['colors']['color0']
# white = colors['colors']['color7']
# gray = colors['colors']['color8']
# red = colors['colors']['color1']
# green = colors['colors']['color2']
# yellow = colors['colors']['color3']
# blue = colors['colors']['color4']
# magenta = colors['colors']['color5']
# cyan = colors['colors']['color6']
#
# c.colors.completion.category.bg = background
# c.colors.completion.category.border.bottom = background
# c.colors.completion.category.border.top = background
# c.colors.completion.category.fg = foreground
# c.colors.completion.even.bg = background
# c.colors.completion.odd.bg = background
# c.colors.completion.fg = foreground
# c.colors.completion.item.selected.bg = gray
# c.colors.completion.item.selected.border.bottom = background
# c.colors.completion.item.selected.border.top = background
# c.colors.completion.item.selected.fg = foreground
# c.colors.completion.match.fg = yellow
# c.colors.completion.scrollbar.bg = background
# c.colors.completion.scrollbar.fg = gray
# c.colors.downloads.bar.bg = background
# c.colors.downloads.error.bg = red
# c.colors.downloads.error.fg = foreground
# c.colors.downloads.stop.bg = cyan
# c.colors.downloads.system.bg = 'none'
# c.colors.hints.bg = yellow
# c.colors.hints.fg = background
# c.colors.hints.match.fg = blue
# c.colors.keyhint.bg = background
# c.colors.keyhint.fg = foreground
# c.colors.keyhint.suffix.fg = yellow
# c.colors.messages.error.bg = red
# c.colors.messages.error.border = red
# c.colors.messages.error.fg = foreground
# c.colors.messages.info.bg = blue
# c.colors.messages.info.border = blue
# c.colors.messages.info.fg = foreground
# c.colors.messages.warning.bg = red
# c.colors.messages.warning.border = red
# c.colors.messages.warning.fg = foreground
# c.colors.prompts.bg = background
# c.colors.prompts.border = '1px solid ' + background
# c.colors.prompts.fg = foreground
# c.colors.prompts.selected.bg = magenta
# c.colors.statusbar.caret.bg = cyan
# c.colors.statusbar.caret.fg = cursor
# c.colors.statusbar.caret.selection.bg = cyan
# c.colors.statusbar.caret.selection.fg = foreground
# c.colors.statusbar.command.bg = background
# c.colors.statusbar.command.fg = foreground
# c.colors.statusbar.command.private.bg = background
# c.colors.statusbar.command.private.fg = foreground
# c.colors.statusbar.insert.bg = green
# c.colors.statusbar.insert.fg = background
# c.colors.statusbar.normal.bg = background
# c.colors.statusbar.normal.fg = foreground
# c.colors.statusbar.passthrough.bg = blue
# c.colors.statusbar.passthrough.fg = foreground
# c.colors.statusbar.private.bg = background
# c.colors.statusbar.private.fg = foreground
# c.colors.statusbar.progress.bg = foreground
# c.colors.statusbar.url.error.fg = red
# c.colors.statusbar.url.fg = foreground
# c.colors.statusbar.url.hover.fg = blue
# c.colors.statusbar.url.success.http.fg = foreground
# c.colors.statusbar.url.success.https.fg = gray
# c.colors.statusbar.url.warn.fg = red
# c.colors.tabs.bar.bg = background
# c.colors.tabs.even.bg = background
# c.colors.tabs.even.fg = foreground
# c.colors.tabs.indicator.error = red
# # c.colors.tabs.indicator.start = magenta
# # c.colors.tabs.indicator.stop = red
# c.colors.tabs.indicator.system = 'none'
# c.colors.tabs.odd.bg = background
# c.colors.tabs.odd.fg = foreground
# c.colors.tabs.selected.even.bg = blue
# c.colors.tabs.selected.even.fg = foreground
# c.colors.tabs.selected.odd.bg = blue
# c.colors.tabs.selected.odd.fg = foreground
# c.colors.webpage.bg = foreground
# c.colors.tabs.pinned.even.bg = background
# c.colors.tabs.pinned.even.fg = foreground
# c.colors.tabs.pinned.odd.bg = background
# c.colors.tabs.pinned.odd.fg = foreground
# c.colors.tabs.pinned.selected.even.bg = blue
# c.colors.tabs.pinned.selected.even.fg = foreground
# c.colors.tabs.pinned.selected.odd.bg = blue
# c.colors.tabs.pinned.selected.odd.fg = foreground
# if qutewal_dynamic_loading or bool(os.getenv('QUTEWAL_DYNAMIC_LOADING')):
# import signal
# import subprocess
# import prctl
#
# # start iqutefy to refresh colors on the fly
# qutewald = subprocess.Popen(
# [daemon_absolute, colors_absolute],
# preexec_fn=lambda: prctl.set_pdeathsig(signal.SIGTERM))
+45
View File
@@ -0,0 +1,45 @@
# #!/usr/bin/env python3
#
# import os
# import signal
# import sys
# from pathlib import Path
#
# import daemon
# import psutil
# from daemon.pidfile import PIDLockFile
# from inotify_simple import INotify, flags
#
#
# def cleanup():
# os.remove(pidfile)
# sys.exit()
#
#
# pidfile = '/tmp/iqutefy.pid'
#
# # check if pidfile refers to dead process
# # if so, remove it
# if os.path.isfile(pidfile):
# with open(pidfile) as pf:
# pid = int(pf.readline())
# if not psutil.pid_exists(pid):
# os.remove(pidfile)
#
# with daemon.DaemonContext(
# detach_process=False,
# pidfile=PIDLockFile(pidfile),
# signal_map={signal.SIGTERM: cleanup}):
# inotify = INotify()
# watch_flags = flags.CREATE | flags.MODIFY
# wd = inotify.add_watch(sys.argv[1], watch_flags)
# process = psutil.Process()
#
# # inotify iterator runs out immediately
# while True:
# for event in inotify.read():
# os.system('qutebrowser :config-source')
#
# # kill after qutebrowser exits
# # not reached on SIGKILL
# cleanup()
+7
View File
@@ -0,0 +1,7 @@
styles = {
'qute.help.css': ['qute://help*', '*someotherdomain.xyz*'],
'twitch.css': ['*twitch.tv*'],
'dreamingspanish.css': ['*dreaming.com*'],
'readthedocs.css': ['*readthedocs.io*'],
'italki.css': ['*italki.com*']
}
+3
View File
@@ -0,0 +1,3 @@
.max-w-3xl {
max-width: 65vw;
}
@@ -0,0 +1,26 @@
.ds-page {
max-width: 95%;
}
.ds-form-calendar {
gap: 0.6rem;
}
.ds-form-calendar__row {
height: 3.5rem;
}
.ds-form-calendar__column {
height: 100%;
font-size: 1rem;
font-weight: 700;
}
.ds-form-calendar__column-wrapper {
width: 90%;
}
.ds-form-calendar__column-time {
font-size: 0.65rem;
line-height: 1.4rem;
}
+7
View File
@@ -0,0 +1,7 @@
.MessageList-main {
padding-bottom: 250px !important;
}
#app .min-h-10 {
min-height: 200px !important;
}
+35
View File
@@ -0,0 +1,35 @@
html {
background-color: #041E39;
}
html > body, html ul > li > * {
color: #EBEBD3;
font-family: sans-serif;
}
html a {
color: #F78764;
}
html a:visited {
color: #2D8CF0;
}
.monospaced, code, pre {
color: #F4D35E;
}
div.admonitionblock {
color: #FAB49E;
font-weight: bold;
}
html em, html dt {
color: #FAB49E;
font-weight: bold;
}
html div.listingblock > div.content, div.listingblock .highlight {
background-color: #611B05;
}
@@ -0,0 +1,39 @@
// ==UserScript==
// @name Userstyle (qute.help.css)
// @include qute://help*
// ==/UserScript==
GM_addStyle(`html {
background-color: #041E39;
}
html > body, html ul > li > * {
color: #EBEBD3;
font-family: sans-serif;
}
html a {
color: #F78764;
}
html a:visited {
color: #2D8CF0;
}
.monospaced, code, pre {
color: #F4D35E;
}
div.admonitionblock {
color: #FAB49E;
font-weight: bold;
}
html em, html dt {
color: #FAB49E;
font-weight: bold;
}
html div.listingblock > div.content, div.listingblock .highlight {
background-color: #611B05;
}
`)
@@ -0,0 +1,3 @@
.wy-nav-content {
max-width: 1200px;
}
+3
View File
@@ -0,0 +1,3 @@
body {
width: 80% !important;
}
@@ -0,0 +1,69 @@
#!/usr/bin/env python
import os
import importlib.machinery as im
import importlib.util as iu
class RebuildGreaseStyles(object):
def __init__(self):
self.config_dir = self.get_config_dir()
self.stylemap = self.import_stylemap(self.config_dir)
def get_config_dir(self):
config_dir = os.getenv('QUTE_CONFIG_DIR')
if config_dir: return config_dir
dir = os.getenv('XDG_CONFIG_HOME')
if dir: return dir + '/qutebrowser'
dir = os.getenv('HOME', '~')
return dir + '/.config/qutebrowser'
def import_stylemap(self, config_dir):
loader = im.SourceFileLoader('stylemap', f"{config_dir}/stylemap.py")
spec = iu.spec_from_loader( 'stylemap', loader )
if spec:
stylemap = iu.module_from_spec( spec )
loader.exec_module( stylemap )
return stylemap.styles
def create_grease_scripts_from_css_files(self):
if not self.stylemap: return
for css_filename, patterns in self.stylemap.items():
self.create_grease_script_from_css_file(css_filename, patterns)
def create_grease_script_from_css_file(self, css_filename, patterns):
with open(f'{self.config_dir}/styles/{css_filename}') as css_file:
css = css_file.read()
grease = self.css_to_grease(css_filename, css, patterns)
grease_script_path = f'{self.config_dir}/greasemonkey/{css_filename}.js'
with open(grease_script_path, 'w') as grease_file:
grease_file.write(grease)
def css_to_grease(self, css_filename, css, patterns):
includes = '\n'.join([f'// @include {p}' for p in patterns])
return (
'// ==UserScript==\n'
+ f'// @name Userstyle ({css_filename})\n'
+ includes + '\n'
+ '// ==/UserScript==\n'
+ f'GM_addStyle(`{css}`)'
)
def reload():
fifo = os.getenv('QUTE_FIFO')
if not fifo: return
with open(fifo, 'w') as feefifofam:
feefifofam.write('greasemonkey-reload -q\n')
feefifofam.write('reload\n')
if __name__ == "__main__":
RebuildGreaseStyles().create_grease_scripts_from_css_files()
reload()
+170
View File
@@ -0,0 +1,170 @@
#!/usr/bin/env python3
"""Log the full length of the current page's video to Traggo as one finished span."""
import json
import os
import re
import shlex
import shutil
import subprocess
import sys
import urllib.error
import urllib.request
from datetime import datetime, timedelta
from html import unescape
API = "https://time.rcjohnstone.com/graphql"
TOKEN_PATH = os.path.expanduser("~/.config/traggo/token")
TAGS = [
{"key": "language", "value": "spanish"},
{"key": "mode", "value": "listening"},
]
YTDLP_TIMEOUT = 45
HTTP_TIMEOUT = 20
UA = ("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/124.0.0.0 Safari/537.36")
FIFO = os.environ.get("QUTE_FIFO")
class ProbeError(Exception):
pass
def report(kind, text):
text = " ".join(text.split())
line = "message-{} {}\n".format(kind, shlex.quote(text))
if FIFO:
with open(FIFO, "a") as fh:
fh.write(line)
else:
sys.stderr.write(line)
def die(text):
report("error", "traggo: " + text)
sys.exit(1)
def human(secs):
hours, rem = divmod(secs, 3600)
mins, s = divmod(rem, 60)
if hours:
return "{}h{:02d}m".format(hours, mins)
if mins:
return "{}m".format(mins)
return "{}s".format(s)
def ytdlp_argv():
local = shutil.which("yt-dlp")
if local:
return [local]
# qutebrowser runs inside distrobox, so reach the host's copy if the container lacks one.
host = shutil.which("distrobox-host-exec")
if host:
return [host, "yt-dlp"]
raise ProbeError("yt-dlp not found")
def probe_ytdlp(url):
argv = ytdlp_argv() + [
"--skip-download", "--no-warnings",
# We only ever want metadata, so a stale extractor failing on formats must not abort.
"--ignore-no-formats-error",
"--print", "%(duration)s|%(title)s", url,
]
try:
proc = subprocess.run(argv, capture_output=True, text=True,
timeout=YTDLP_TIMEOUT)
except subprocess.TimeoutExpired:
raise ProbeError("yt-dlp timed out after {}s".format(YTDLP_TIMEOUT))
except OSError as exc:
raise ProbeError("yt-dlp failed to start: {}".format(exc))
line = next((ln for ln in reversed(proc.stdout.splitlines()) if "|" in ln), "")
if not line:
detail = " ".join(proc.stderr.split())[:160] or "no output"
raise ProbeError("yt-dlp: " + detail)
raw, _, title = line.partition("|")
raw = raw.strip()
if not raw.isdigit() or int(raw) <= 0:
raise ProbeError("yt-dlp gave no duration (got {!r})".format(raw))
return int(raw), title.strip()
def probe_html(url):
req = urllib.request.Request(url, headers={
"User-Agent": UA, "Accept-Language": "en-US,en;q=0.9"})
try:
page = urllib.request.urlopen(req, timeout=HTTP_TIMEOUT).read().decode(
"utf-8", "replace")
except Exception as exc:
raise ProbeError("page fetch failed: {}".format(exc))
match = re.search(r'"lengthSeconds":"(\d+)"', page)
if not match:
raise ProbeError("no lengthSeconds in page")
secs = int(match.group(1))
if secs <= 0:
raise ProbeError("page reported zero length")
title = re.search(r'<meta name="title" content="([^"]*)"', page)
return secs, unescape(title.group(1)) if title else ""
def qute_title():
return re.sub(r"\s+-\s+YouTube$", "", os.environ.get("QUTE_TITLE", "")).strip()
def create_span(token, start, end, note):
query = ("mutation($s:Time!,$e:Time!,$t:[InputTimeSpanTag!],$n:String!){"
"createTimeSpan(start:$s,end:$e,tags:$t,note:$n){id}}")
body = json.dumps({"query": query, "variables": {
"s": start, "e": end, "t": TAGS, "n": note}}).encode()
req = urllib.request.Request(API, data=body, headers={
"Content-Type": "application/json",
"Authorization": "traggo " + token})
try:
raw = urllib.request.urlopen(req, timeout=HTTP_TIMEOUT).read().decode()
except urllib.error.HTTPError as exc:
die("server returned HTTP {}: {}".format(
exc.code, exc.read().decode("utf-8", "replace")[:160]))
except Exception as exc:
die("cannot reach server: {}".format(exc))
data = json.loads(raw)
if data.get("errors"):
die("api: {}".format(data["errors"][0].get("message", "unknown error")))
return data["data"]["createTimeSpan"]["id"]
def main():
url = os.environ.get("QUTE_URL", "").strip()
if not url:
die("no QUTE_URL in environment")
try:
token = open(TOKEN_PATH).read().strip()
except OSError as exc:
die("cannot read token: {}".format(exc))
if not token:
die("token file {} is empty".format(TOKEN_PATH))
try:
secs, title = probe_ytdlp(url)
except ProbeError as primary:
try:
secs, title = probe_html(url)
except ProbeError as fallback:
die("no duration. {} / fallback: {}".format(primary, fallback))
note = title or qute_title() or url
end = datetime.now().astimezone().replace(microsecond=0)
start = end - timedelta(seconds=secs)
span = create_span(token, start.isoformat(), end.isoformat(), note)
report("info", "traggo: logged {} [{}] - {}".format(human(secs), span, note))
if __name__ == "__main__":
main()