Converting the pages to markdown with sed

This commit is contained in:
David Thurstenson 2021-02-12 15:14:09 -06:00
parent b585649fc4
commit 619736be2a
31 changed files with 2063 additions and 0 deletions

View File

@ -0,0 +1,38 @@
# Add spaces to == headers such as "=header="
s/^\(=\+\)\([^=]*\)\(=\+\)$/\1 \2 \3/
# Replace comments
s/# \(.*\)$/* \1/g
# Replace == headers with # headers
s/^= \(.*\) =$/# \1/g
s/^== \(.*\) ==$/## \1/g
s/^=== \(.*\) ===$/### \1/g
s/^==== \(.*\) ====$/#### \1/g
s/^===== \(.*\) =====$/##### \1/g
s/^====== \(.*\) ======$/###### \1/g
# Replace code tags
s/{{{class="brush: *\([^"]*\)"/\`\`\`\1/g
s/{{{class="\([^"]*\)"/\`\`\`\1/g
s/{{{/\`\`\`/g
s/}}}/\`\`\`/g
# Replace * bullets with - bullets
s/^\(\s*\)\*/\1-/g
# Replace partially-finished checklist items with unfinished checklist items
s/^\(\s*\)- \(\[[.oO]\]\)/\1- [ ]/g
# Replace URLs
s/\[\[\(.*\)|\(.*\)\]\]/\[\2\](\1)/g
s/\[\[\([^]]\{1,\}\)\]\]/[\1](\1.md)/g
# Replace comments
s/%% \(.*\)/<!-- \1 -->/g
# Replace TOC, Title, and draft status
/%toc.*/d
s/%title \(.*\)/# \1/g
s/%nohtml/- status: draft/g

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
newdir=./new
[[ ! -d $newdir ]] && mkdir $newdir
for i in ./*.wiki; do
newname=${i/.wiki/.md}
sed -f "$1" "$i" > "$newdir/$newname"
done

9
new/Archive.md Normal file
View File

@ -0,0 +1,9 @@
# Archived Pages
- [Audiobook RSS Feed](Audiobook RSS Feed.md)
### Configuration/Dotfiles
- [i3](i3.md) -- Moved to Sway
- [Xinitrc](Xinitrc.md) -- Moved to Sway
- [Pkglists](Pkglists.md) -- Project abandoned. I install as I go nowadays.

View File

@ -0,0 +1,7 @@
# Serving Audiobooks as an RSS Feed
I want to serve my library of audiobooks as an RSS feed so that I can use my favorite podcast app as the player.
Packages used:
- python-pyrss2gen: RSS generation
- python-mutagen: metadata extraction

View File

@ -0,0 +1,187 @@
# Automated Android App Builds
Goal: Get a compiled apk of [AsteroidOS Sync](https://github.com/asteroidos/AsteroidOSSync) from the latest git commit.
I wanted to do this without untracked software clutter on my main machine, so I decided to do it in a systemd-nspawn container on my home server. The container and build turned out better than I expected, so I went ahead with automating the whole setup to check daily for new commits, building the app if there is a new commit, and dumping it in a folder outside of the container.
## Setting up systemd-nspawn
Arch makes this step super easy with the `arch-install-scripts` package:
```prettyprint
- pacstrap -icd container/ base --ignore linux base-devel
```
- `-i`: Avoid auto-confirmation of package selections
- `-c`: Use the package cache on the host rather than the target
- `-d`: Allow installation to a non-mountpoint directory
- `container/`: Path to your desired container location
- `base --ignore linux base-devel`: Install the base and base-devel groups, ignoring the `linux` package. The kernel is not necessary inside this container, so might as well save the bandwidth
This will get you a container with the latest packages ready to spin up. After that, all you need to do is:
```prettyprint
- systemd-nspawn -bD container/
```
This will boot the container and leave you at a login prompt. For Arch, root will be passwordless. Start here, and configure your new container for what you need. For my setup, I created an unprivileged user, added my `~/.bashrc` and `~/.vimrc`, and installed the android-sdk package from the AUR.
Next, we need to automate bringing the new container up with a systemd service. Easiest way to get a service ready for a systemd-nspawn is to use the existing systemd-nspawn@.service, and tweak it for this specific use. To get a copy of this unit and start editing it right away, run `systemctl edit --full systemd-nspawn@containername.service`. This is the end product of my unit:
```prettyprint
- /etc/systemd/system/systemd-nspawn@asteroid.service
- This file is part of systemd.
#
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
[Unit]
Description=Container %i
Documentation=man:systemd-nspawn(1)
PartOf=machines.target
Before=machines.target
After=network.target
[Service]
ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest -U --settings=override --machine=%i -D /storage/containers/asteroid/sync-app/ --bind=/storage/containers/asteroid/output:/home/thurstylark/output
KillMode=mixed
Type=notify
RestartForceExitStatus=133
SuccessExitStatus=133
Slice=machine.slice
Delegate=yes
TasksMax=16384
- Enforce a strict device policy, similar to the one nspawn configures
- when it allocates its own scope unit. Make sure to keep these
- policies in sync if you change them!
DevicePolicy=closed
DeviceAllow=/dev/net/tun rwm
DeviceAllow=char-pts rw
- nspawn itself needs access to /dev/loop-control and /dev/loop, to
- implement the --image= option. Add these here, too.
DeviceAllow=/dev/loop-control rw
DeviceAllow=block-loop rw
DeviceAllow=block-blkext rw
[Install]
WantedBy=machines.target
```
The only things changed from the original are all in `ExecStart=`:
- `-D /storage/containers/asteroid/sync-app/`: Boot the nspawn from a directory instead of from an image, and the path to that directory
- `--bind=/storage/containers/asteroid/output:/home/thurstylark/output`: Create a bind mount between the host and the container. The format is `/host/dir:/container/dir` where `/container/dir` is specified with `/` at the root of the container, not of the host.
- Removed `--network-veth` to use the networking from the host instead of creating a virtual ethernet link.
Check the systemd-nspawn manpage for more info.
To start your container, run `systemctl start systemd-nspawn@containername.service`. Confirm it's running with `machinectl list` and `systemctl status systemd-nspawn@containername.service`.
### Reference
- https://wiki.archlinux.org/index.php/Systemd-nspawn
----
## Interacting With Your New Container
When your systemd-nspawn is booted, most interaction is done using `machinectl(1)`. I will only be covering what's necessary for this setup. Check machinectl's manpage for more detailed info.
To get a shell:
```prettyprint
- machinectl shell user@containername
```
This will bypass the login prompt, and start user's shell. If no user is specified, you will be logged in as root.
The actual building is done by a script in the container. This means we need either a) a way to execute that script from outside the container, or b) put the script on a timer within the container. Since I don't want the container running the whole time, I opted for option A. This allows the machine to be started and stopped as necessary.
To execute the script from outside the container:
```prettyprint
- machinectl shell user@containername /path/to/script
```
Note: This path is relative to the root of the container, not of the host.
All that's left is to make a service unit for this command. Here's how my unit stands at the time of writing:
```prettyprint
- /etc/systemd/system/build-aos-sync.service
[Unit]
Description=Build latest commit of AsteroidOS Sync
Requires=systemd-nspawn@asteroid.service
After=systemd-nspawn@asteroid.service
[Service]
Type=oneshot
ExecStart=/usr/bin/machinectl shell thurstylark@asteroid /home/thurstylark/buildapp.sh
```
This unit is set up to boot our container automatically by using `Requires=` and `After=`. This way, we don't have to manage how our container is started. This also enables us to manually trigger a build by starting this unit.
The last part of the actual automation is done with a timer for our new service. It doesn't have to be super complicated, but you can tweak it how you like it:
```prettyprint
- /etc/systemd/system/build-aos-sync.timer
[Unit]
Description=Timer for automated AsteroidOS Sync build
[Timer]
OnCalendar=daily
[Install]
WantedBy=timers.target
```
This timer is set for `OnCalendar=daily`, which will trigger every day at midnight. When the timer triggers, it will start our service, which will start our container if it's not already started, then it will run our build script. More options for this timer can be found in the `systemd.timer` manpage.
----
## Build Script
The last peice of the puzzle for this is to actually compile the app in question. Before any of this can be done or tested, your Android build environment should be set up. Check the Android Building page for more info.
Here's the script I ended up with:
```prettyprint linenums
#!/bin/bash
pkgname=asteroid-os-sync
project_root=/home/thurstylark/AsteroidOSSync
bind_mount=/home/thurstylark/output
output=$project_root/app/build/outputs/apk/app-debug.apk
build_app() {
- Reference: https://developer.android.com/studio/build/building-cmdline.html
cd $project_root
git remote update
if [ "$(git rev-parse @)" == "$(git rev-parse @{u})" ]( "$(git rev-parse @)" == "$(git rev-parse @{u})" .md); then
echo "App up to date." >&2
exit 0
else
git pull origin master
rm -r app/src/main/res/values-ca-rES@valencia/
ANDROID_HOME=/opt/android-sdk ./gradlew assembleDebug
fi
copy_output
}
pkgver() {
cd $project_root
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
copy_output() {
cp ${output} ${bind_mount}/${pkgname}-$(pkgver).apk
}
build_app
```
This script is not incredibly intelligent, but it gets the job done. One thing to point out is the test on line 11. This if statement checks whether our local copy of the git repo is up to date. If it's up to date, the script exits with a little message. This way we are only building if there are changes to be built.
I also use `copy_output()` to rename the resulting apk with the revision number and short commit id (compiled using `pkgver()`) for clarity.

337
new/Bashrc.md Normal file
View File

@ -0,0 +1,337 @@
# Bashrc
Source: https://git.thurstylark.com/vcsh/bashrc.git
## Profile
Bash chooses which dotfile to source based on how it gets run. If starting from a login shell, `~/.bash_profile` will get sourced, but if there's not a command in there to source your `~/.bashrc`, you may find yourself having to `exec bash` after starting bash. This can be fixed by adding the following line to your `~/.bash_profile`:
```prettyprint
[ -f ~/.bashrc ]( -f ~/.bashrc .md) && . ~/.bashrc
```
I also use `~/.bash_profile` for setting numlock while in a tty:
```prettyprint
case $(tty) in /dev/tty[0-9]*)
setleds -D +num * (numlock for X is set in ~/.xinitrc)
;;
esac
```
The last thing of note in my `~/.bash_profile` is a warning:
```prettyprint
- Temporary fix for a systemd bug related to systemd --user timers that run on login
[ -z "$DBUS_SESSION_BUS_ADDRESS" ]( -z "$DBUS_SESSION_BUS_ADDRESS" .md) && printf "%bWARNING: \$DBUS_SESSION_BUS_ADDRESS is unset! %b\n" "$(tput bold)$(tput setab 1)" "$(tput sgr0)"
```
----
## Main bashrc
Things started getting a little too expansive, so I split off relevant sections into their own files. Now all my individual utilities have their own file, making troubleshooting and adding functionality much easier. You can find info for each file and what it does in its own section on this page.
### General config
I'm not going in to detail about every line, but I'll hilight the important parts. The rest should be documented in the script itself.
First off, if we're not running bash interactively, there's no use for any of the rest of this, so just skip it.
```prettyprint
- If not running interactively, don't do anything
[ $- != *i* ]( $- != *i* .md) && return
```
Another cool option is actually built in to bash: If you call for a directory without any command before it, just `cd` into that directory.
```prettyprint
- If a directory is given without any command, CD into it.
shopt -s autocd
```
This is where all the other utilities, aliases, and functions get pulled in. Anything in `~/.bashrc.d/` ending in `.sh` will get pulled in.
```prettyprint
for f in ~/.bashrc.d/*.sh; do source "$f"; done
```
This also removes the need for the local bashrc sourcing that I [had in this file previously](https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc?id=30c53ca7224b583ed5068038b697653810e3b94b#n45). If that functionality is needed, simply make a new script in `~/.bashrc.d/` and don't track it with `vcsh`.
Ordering can be done by adding numbers to the beginning of filenames. For example: `10-prompt.sh`. Currently, nothing that I use requires that kind of functionality.
----
## Prompt
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/prompt.sh
I originally built my prompt using http://bashrcgenerator.com and, while it's a nice tool for visually building a prompt, it has several limitations on what you're able to create with it. But more importantly to me, it generates a rediculously long string, defines and resets color for every single character, uses both a color and bold escape sequence to use light/bright colors, mixes raw escape sequences and subshells running tput, and as a result is utterly unreadable and unmaintainable.
So, I replaced it:
```prettyprint
promptsetup() {
- Color definitions for prompt
local fg_brightred='\[$(tput setaf 9)\]'
local fg_blue='\[$(tput setaf 4)\]'
local fg_magenta='\[$(tput setaf 13)\]'
local fg_cyan='\[$(tput setaf 6)\]'
local fg_brightcyan='\[$(tput setaf 14)\]'
local fg_green='\[$(tput setaf 2)\]'
local reset='\[$(tput sgr0)\]'
local hostname='\h'
local mixin
- [hh:mm][username@hostname pwd]$
- Remotely, hostname is red.
[ -n "$SSH_CLIENT" ] && hostname="${fg_brightred}\h${reset}"
- If in a python venv, add venv name in green.
[ -n "$VIRTUAL_ENV" ] && mixin=" ${fg_green}$(basename "$VIRTUAL_ENV")${reset}"
- If in a vcsh repo env, add repo name in magenta.
[ -n "$VCSH_REPO_NAME" ] && mixin=" ${fg_magenta}$VCSH_REPO_NAME${reset}"
PS1="${fg_blue}[\A]${fg_cyan}[${fg_brightcyan}\u${fg_cyan}@${hostname}${mixin} ${fg_cyan}\W]${reset}\$ "
}
promptsetup
```
I intentionally put everything in a function and call it immediately so I may use local vars for the color definitions. I didn't really want to leave them around just in case.
----
## Aliases
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/alias.sh
Most of these are just creature comforts and fairly self-explanitory:
```prettyprint
##* ALIASES ###
- Colorize all `ls` output:
alias ls='ls -AF --color=auto'
- Map "la" to `ls -la`
alias la='ls -laFh --color=auto'
- Colorize `grep` output
alias grep='grep --color=auto'
- Change layout of lsblk to include FSTYPE and remove MAJ:MIN, RM, and RO collumns.
alias lsblk='lsblk -o NAME,FSTYPE,SIZE,TYPE,MOUNTPOINT'
- Always use sudo when using nmap.
alias nmap='sudo -E nmap'
- Switch $TERM temporarily (for logging into machines that don't have tmux-256color terminfo)
alias screenterm='TERM=screen-256color'
```
----
## Colored man Pages
Some color changes in `man` are almost essential for readability for me, so here's how I achieve that:
```prettyprint
- Enables colored Man pages:
man() {
env LESS_TERMCAP_mb=$'\E[01;31m' \
LESS_TERMCAP_md=$'\E[01;38;5;74m' \
LESS_TERMCAP_me=$'\E[0m' \
LESS_TERMCAP_se=$'\E[0m' \
LESS_TERMCAP_so=$'\E[38;5;246m' \
LESS_TERMCAP_ue=$'\E[0m' \
LESS_TERMCAP_us=$'\E[04;38;5;146m' \
man "$@"
}
```
This can also be done for any similar program that uses `less` as its pager.
----
## Get Dell Service Tag
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/getdst.sh
I work with Dell machines a lot, and when dealing with hardware problems, it's nice to have the service tag handy. Lucky for me, the service tag is easily retrieveable using `dmidecode(1)`, so I made a function for it.
```prettyprint
getdst() {
if [ "$1" = "-l" ]( "$1" = "-l" .md); then
printf "http://www.dell.com/support/home/us/en/04/product-support/servicetag/%s/configuration\n" "$(getdst)"
else
sudo dmidecode -s system-serial-number
fi
}
```
As an added bonus, the `-l` option will print the url for that product's support page.
----
## Screenshot
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/shot.sh
This function wraps `maim(1)` and `fb(1)` to simplify my most used options. It uses maim to capture either the full screen, the active window, or a mouse selection to a file, or directly to a pastebin.
```prettyprint
shot() {
- Usage: shot XY
local destdir="$HOME/Pictures/screenshots"
local fname
local pb="fb"
local paste msgt msgd opts
fname="shot-$(date +%F-%T).png"
if [ -z "$1" ]; then
printf "
Usage: shot XY
X: Target
Y: Destination
Valid Targets:
w Active Window
a All displays
s Mouse Selection
Valid Destinations:
f Save to file (defined in function)
p Upload to a pastebin (defined in function)
"
return
fi
- X: What to capture
case ${1:0:1} in
- Active window
w) printf "Focus target window now...\n"
opts="-i $(xdotool getactivewindow)"
msgt="active window"
;;
- All
a) msgt="all displays"
;;
- Mouse selection
s) opts="-s --noopengl"
msgt="mouse selection"
;;
-) printf "Invalid target: %s\n" "${1:0:1}"
return
;;
esac
- Y: Where to put the result
case ${1:1:1} in
- Save to file
f) msgd="file: $destdir/$fname"
;;
- Post to a pastebin
p) destdir=$destdir/pasted
msgd="pastebin"
paste=1;;
-) printf "Invalid destination: %s\n" "${1:1:1}"
return
;;
esac
- Make sure destination directory will exist
[ ! -d "$destdir" ]( ! -d "$destdir" .md) && mkdir -p "$destdir"
local fpath="${destdir}/${fname}"
- If target is active window, give a 5 second countdown before running maim
[ "$msgt" = "active window" ]( "$msgt" = "active window" .md) && countdown 5
maim "$opts" "$fpath"
printf "Captured %s -> %s\n" "$msgt" "$msgd"
- If destination is a pastebin, do the needful
[ "$paste" ]( "$paste" .md) && $pb "$fpath"
}
```
This probably isn't the most robust solution, but it works pretty well. Patches welcome.
----
## Countdown
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/countdown.sh
Found this little function when I wanted to add functionality to `shot()`. It takes an integer as an argument, then counts down that number of seconds visually.
```prettyprint
countdown() {
if [ -z "$1" ]; then
printf "
countdown: Count down while printing progress on the terminal
Usage: countdown <seconds>
"
fi
local secs="$1"
while [ "$secs" -gt 0 ]; do
echo -ne "$secs\033[0K\r"
sleep 1
: $((secs--))
done
}
```
This probably isn't the sanest or safest solution to the problem, but it gets the job done. Patches welcome.
----
## FontFind
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/fontfind.sh
Sometimes you just need to figure out what font provides a specific character. This function provides that solution:
```prettyprint
fontfind() {
if [ ${#1} -gt 1 ]( -z $1 |); then
printf "E: only one character accepted"
fi
local glyph=$1
FC_DEBUG=4 pango-view -qt "$glyph" 2>&1 | awk -F \" '/family: / { m = $2 } END { print m }'
}
```
----
## Vactivate
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/vactivate.sh
I started needing more than one python virtualenv, and I wanted easy access to my own specific file structure. Additionally, I wanted the ability to deactivate the venv like I would exit a child shell. This is the solution that I came up with:
```prettyprint
vactivate() {
local path=~/.venv/$1
if [ ! -d $path ]( ! -d $path .md); then
python -m venv $path --prompt "venv: $1"
fi
source $path/bin/activate; bash; deactivate
}
```
A caveat to this is that the prompt modification that venv usually applies is not available using this method. If a prompt modification is desired, it needs to be taken care of elsewhere. I take care of it in my prompt setup detailed [here](https://wiki.thurstylark.com/Bashrc.html#Prompt).
----
## Weechat
https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc.d/weechat.sh
See: [Weechat](Weechat.md).

72
new/Cgit.md Normal file
View File

@ -0,0 +1,72 @@
# CGit
Current configuration can always be found at https://git.thurstylark.com/cgit.git/tree
### Push To Deploy
The remote repo is set up to deploy the entire contents of the repo to `/srv/cgit` by using the `post-receive` hook in the git repo.
```prettyprint
#!/bin/bash
GIT_WORK_TREE=/srv/cgit git checkout -f
```
This allows configuration changes to be edited on a local repo, committed, then pushed to the remote to apply changes.
### About Page
Had a problem with the about page not showing when the appropriate file names are definied as readme files. Here was the problematic config:
```prettyprint linenums
#css=/cgit-css/cgit.css
#logo=/cgit-css/cgit.png
root-title=Thurstylark
root-desc=Projects and Dotfiles
source-filter=/srv/cgit/syntax-highlighting.py
about-filter=/usr/lib/cgit/filters/about-formatting.sh
enable-git-config=1
scan-path=/srv/git
enable-http-clone=1
clone-url=https://git.thurstylark.com/$CGIT_REPO_URL
#
- Search for these files in the root of the default branch of repositories
- for coming up with the about page:
#
readme=:README.md
readme=:readme.md
readme=:README.mkd
readme=:readme.mkd
readme=:README.rst
readme=:readme.rst
readme=:README.html
readme=:readme.html
readme=:README.htm
readme=:readme.htm
readme=:README.txt
readme=:readme.txt
readme=:README
readme=:readme
readme=:INSTALL.md
readme=:install.md
readme=:INSTALL.mkd
readme=:install.mkd
readme=:INSTALL.rst
readme=:install.rst
readme=:INSTALL.html
readme=:install.html
readme=:INSTALL.htm
readme=:install.htm
readme=:INSTALL.txt
readme=:install.txt
readme=:INSTALL
readme=:install
```
The solution was to move the `scan-path` directive to the end of my cgitrc. See the [cgitrc manpage](https://git.zx2c4.com/cgit/tree/cgitrc.5.txt#n392) for details.

View File

@ -0,0 +1,10 @@
# Chrome Search Shortcuts
| Service | Trigger | URL | Description |
|-----------------------------|---------|-----------------------------------------------------------------------------|-------------------------------------------------------|
| Arch Wiki Search | aw | https://wiki.archlinux.org/index.php?title=Special%3ASearch&search=%s&go=Go | |
| Arch Package Search | ap | https://www.archlinux.org/packages/?sort=&q=%s&maintainer=&flagged= | |
| Arch User Repository Search | aur | https://aur.archlinux.org/packages/?O=0&K=%s | |
| Arch Linux Bug Lookup | fs | https://bugs.archlinux.org/task/%s | Go directly to bug number |
| Dell Service Tag Lookup | dell | http://www.dell.com/support/home/us/en/04/product-support/servicetag/%s | Go directly to the Dell Support page of a service tag |
| ShellCheck Code Search | sc | https://github.com/koalaman/shellcheck/wiki/SC%s | Look up ShellCheck code. (sc<tab><number>) |

View File

@ -0,0 +1,92 @@
# Formatting Cheat Sheet
# Header1
## Header2
### Header3
-bold* -- bold text
_italic_ -- italic text
~~strikeout~~ -- strikeout text
`code without syntax`
super^script^
sub,,script,,
[wiki link](wiki link.md) -- wiki link
[description](wiki link) -- wiki link with description
## Lists
- bullet list item 1
- bullet list item 2
- bullet list item 3
- bullet list item 4
- bullet list item 5
- bullet list item 6
- bullet list item 7
- bullet list item 8
- bullet list item 9
1. numbered list item 1
2. numbered list item 2
a) numbered list item 3
b) numbered list item 4
- [ ] Unchecked item 1
- [X] Checked item 2
## Definitions
Term 1:: Definition 1
Term 2::
:: Definition 2
:: Definition 3
## Tables
| Column 1 | Column 2 | Column 3 |
|-----------------------|----------------------------------------------------------------------------------|----------|
| Data 1 | Data 2 | Data 3 |
| this takes rows below | this takes the next collumn as well and will not wrap this text to the next line | > |
| \/ | Data 5 | > |
| Data 4 | | |
## Preformatted Text
Without syntax highlighting
```
Here is some text
there is some text
```
With syntax highlighting
```prettyprint lang-python linenums >
def hello(world):
for x in range(10):
print("Hello {0} number {1}".format(world, x))
```
## Blockquotes
Text that starts with 4 or more spaces is a Blockquote.
It won't be highlighted in Vim, but will be styled
on the HTML site.
## Comments
A line that starts with `%%` won't show up in the HTML page
<!-- This is a comment and will be skipped when rendering to HTML -->
## Horizontal line
----

74
new/Keyboard Mapping.md Normal file
View File

@ -0,0 +1,74 @@
# Keyboard Mapping
References:
- https://wiki.archlinux.org/index.php/Map_scancodes_to_keycodes
- https://github.com/Earnestly/pkgbuilds/blob/master/system-config/hwdb-capslock-as-control.hwdb
Maping keys is pretty simple, and if it's done at the udev level, it's universal, so it doesn't require any X or Wayland specific configuration.
As an example, I map my compose key (menu key) to right meta (aka super, logo, windows, apple, or command key), and CapsLock to left Control.
## Get Scancode
First, get the scancode(s) of the key(s) you wish to change. Easiest way is to use `evteest(1)`. For each keypress, you'll get information similar to the following:
```class='prettyprint'
Event: time 1496690003.603531, -------------- SYN_REPORT ------------
Event: time 1496690003.723467, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70065
Event: time 1496690003.723467, type 1 (EV_KEY), code 127 (KEY_COMPOSE), value 0
```
The code you will need to use in the udev hwdb config file is the `MSC_SCAN` value (in this case: 70065).
## Get Hardware ID
Next you will need the hardware Vendor and Product ids from `lsusb(1)`. These are two sets of four hexidecimal digits separated by a colon (:) printed right before the device name.
```class='prettyprint'
Bus 001 Device 005: ID 258a:1006 <keyboard name here>
```
In this example, the Vendor ID is `258a`, and the Product ID is `1006`.
## Create udev hwdb Configuration
Then create `/etc/udev/hwdb.d/61-custom-keyboard.hwdb` with the following contents:
```class='prettyprint'
evdev:input:b0003v258Ap1006*
KEYBOARD_KEY_70065=rightmeta
KEYBOARD_KEY_70039=leftctrl
```
A few notes on the format of this file:
- The format for the device identifying line for usb devices is `evdev:input:b0003v<Vendor ID>p<ProductID>*`.
- If `<Product ID>` and `<Vendor ID>` contain letters, they must be capitalized
- These scancodes can be quite device-specific, so it is wise to be specific to *at least* the vendor and product IDs
- There are methods for identifying atk keyboards as well. Check the Arch Wiki page listed in the references above for more info
- Defining a key to change is done with `KEYBOARD_KEY_<scancode>=<new keycode>`
- `<scancode>` is the code we pulled from evtest earlier
- `<new keycode>` is the keycode we want to emit when the key is pressed. Names of keycodes are listed in `/usr/include/linux/input-event-codes.h`, and should be all lowercased in your udev config.
- The filename `61-custom-keyboard.hwdb` is somewhat arbitrary, but make sure that you order your file *after* the existing `60-keyboard.hwdb`.
## Update Hardware Database Index
After changing the config files, the hwdb needs to be rebuilt:
```class='prettyprint'
- systemd-hwdb update
```
To start using this new hwdb, either reboot or tell udev to reload:
```class='prettyprint'
- udevadm trigger
```
Note that this will only work for adding or modifying existing key mappings. Deleted key mappings are kept in the kernel until a reboot.
## Testing the New Mappings
A simple test can be run before trying the keys directly:
```class='prettyprint'
- udevadm info /dev/input/by-path/*-usb-*-kbd | grep KEYBOARD_KEY
```

93
new/LetsEncrypt.md Normal file
View File

@ -0,0 +1,93 @@
# LetsEncrypt
## Certbot Usage
Create a cert using the interactive menu:
```prettyprint
- certbot certonly
```
## Automating Renewal
LetsEncrypt Certs are good for a max of 90 days, so automating renewal is a must.
Do a dry-run renewal with certbot:
```prettyprint
- certbot renew --dry-run
```
This will test, and possibly renew all certs that certbot knows about
Now you can use `certbot renew --quiet` for scripting this renewal. I do mine with a simple systemd script:
```prettyprint
- /etc/systemd/system/certbot.service
[Unit]
Description=Let's Encrypt renewal
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --agree-tos
ExecStartPost=/bin/systemctl reload httpd.service
```
## Apache Configuration
There's a couple of considerations when using ssl certs with Apache. The first is to enable the appropriate modules in httpd.conf:
```prettyprint
LoadModule ssl_module modules/mod_ssl.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
```
Also, make sure to configure apache to listen on port 443:
```prettyprint
Listen 443
```
That will get the basic framework ready for your virtualhost definition. Here is a very simple virtualhost configuration:
```prettyprint linenums
<VirtualHost wiki.thurstylark.com:80>
ServerName wiki.thurstylark.com
DocumentRoot "/srv/wiki/"
<Directory "/srv/wiki/">
AllowOverride None
Options None
Require all granted
</Directory>
- Redirect all except the '.wellk-known' path to https.
- This allows automated renewal of ssl certs by certbot
RedirectMatch permanent ^/(?!\.well-known)(.*) https://wiki.thurstylark.com/$1
</VirtualHost>
<VirtualHost wiki.thurstylark.com:443>
ServerName wiki.thurstylark.com
ServerAdmin thurstylark@gmail.com
DocumentRoot "/srv/wiki/"
<Directory "/srv/wiki/">
AllowOverride None
Options None
Require all granted
</Directory>
SSLEngine on
SSLCertificateChainFile "/etc/letsencrypt/live/wiki.thurstylark.com/fullchain.pem"
SSLCertificateKeyFile "/etc/letsencrypt/live/wiki.thurstylark.com/privkey.pem"
</VirtualHost>
```
A couple things to note here: First, this defines two virtualhosts, one for port 80 and one for port 443. This is in order to redirect _all_ traffic to HTTPS except for a very small exception.
This exception is what you see on line 12 in the code above. Only `*/.well-known/*` is not redirected because this is the dir that certbot uses for domain validation. Certbot will only validate over http, and will fail if given a 301 redirect. This allows validation to complete successfuly without a configuration change, thus aiding our automation efforts. Everything else gets a 301 redirect to HTTPS. Be sure to define `DocumentRoot` with the correct location for *both* VirtualHosts, or certbot will fail to renew things correctly. (found this one out the hard way)
Lines 28-29 configure Apache to look for the necessary files in the right places. The locations listed here are actually symlinks to the real files, which are kept in an archive. These links are maintained by certbot automagically.
To obtain new certs for a subdomain, copy this config to `/etc/httpd/conf/extra/`, update the config with the appropriate subdomain name, comment out lines 5-29 to disable the redirect and ssl configuration, and add an include in the main httpd.conf. Once that is all set up, you can run certbot to obtain new certs. Once certbot is finished, you can remove the comments, restart httpd, and begin testing.

13
new/Links Of Infamy.md Normal file
View File

@ -0,0 +1,13 @@
# Links of Infamy
- [How to properly run a community.](https://wiki.archlinux.org/index.php/Code_of_conduct)
- [How to properly automate yourself out of a job.](https://github.com/NARKOZ/hacker-scripts)
- [How to properly file a bug report.](https://github.com/chrislgarry/Apollo-11/issues/3)
- [How to properly troubleshoot networking equipment.](https://tools.ietf.org/html/rfc2321)
- [How to properly manage your distro's infrastructure.](http://web.archive.org/web/20150409040851/https://manjaro.github.io/expired_SSL_certificate/)
- [How to properly learn from your mistakes.](https://web.archive.org/web/20160811103932/https://manjaro.github.io/SSL-Certificate-Expired/)
- [How to properly install Gentoo](http://www.bash.org/?464385)
- [How to properly answer useless questions that get asked repeatedly.](http://stackoverflow.com/a/1732454)
- [How to properly appreciate the number five.](https://github.com/jackdcrawford/five)

13
new/On Labels.md Normal file
View File

@ -0,0 +1,13 @@
# On Labels
### A label is not a template for behavior. It is a tool used for describing your specific brand of awesome to others. You are you, pick a label that fits (or don't, whatever)
That is to say: I am secure in the label that I've chosen, not because *I* can fit within *the label*, but because *the label* fits *me.* I am the only one in the world qualified to make any judgments about my sexuality, because I am the only one in the world who lives my life, feels my emotions, and experiences my attraction The *only* reason I have chosen to use a one-word label for such a large, complicated part of my person, is because it provides a useful short-hand.
However, this absolutely doesn't mean labels have no usefulness beyond communicating complicated concepts in a succinct way. In an external sense, labels provide some sense of community in a world where people are often denied the opportunity to internalize these concepts from a young age; Finding this community provides legitimacy, validation, and support where otherwise one would be left to deal with their identity completely alone.
But, for the purposes of one's *internal* struggle: You are who you are, and whatever that ends up looking like for you, it can be explored and discovered with or without the participation of others. For some people, it helps to have some experience to consider, but there are just as many who have come to their conclusions completely on their own.
### IMO: Begin by finding the truth about yourself, and then you can figure out how to communicate that to others.
Or don't. I don't live your life :)

View File

@ -0,0 +1,26 @@
# Password Store Setup
This is a quick reference for setting up `pass` on a new filesystem.
1. Install `pass` via the most official means possible
2. Import secret key to gpg keyring
3. Initialize the password store with the key ID
```class='prettyprint'
pass init <keyid>
```
4. Initialize the git repo inside the password store
```class='prettyprint'
pass git init
```
5. Set remote origin
```class='prettyprint'
pass git remote add origin user@site.com:pass.git
```
6. Fetch origin
```class='prettyprint'
pass git fetch origin
```
7. Reset hard to origin/master (overwriting anything that existed in the password store thus far)
```class='prettyprint'
pass git reset --hard origin/master
```

76
new/Pkglists.md Normal file
View File

@ -0,0 +1,76 @@
# Pkglists
Sources:
https://git.thurstylark.com/vcsh/pkglists.git/
https://git.thurstylark.com/vcsh/systemd-user.git/
https://github.com/gs93/pakbak
These used to be actual lists created by [an admittedly terrible script](https://git.thurstylark.com/vcsh/pkglists.git/tree/.pkglists/pkglistbu.sh?id=62cc7e34c1354900cf7cc58480d9b4db2cd7309a) that was run nightly by a systemd --user timer, but now I backup `pacman`'s whole local database whenever there's a change using pakbak and `systemd.path` units.
## Pakbak
Pakbak is pretty straightforward: You configure where you want the backups stored, the ammount of backups you want to keep, and then enable `pakbak.path`. This will trigger `pacbak.service` whenever there is a change to `/var/lib/pacman/local` in the filesystem, `pakbak.path` triggers `pakbak.service`, which runs `/usr/lib/systemd/scripts/pakbak`. The pakbak script checks for pacman's lock file before continuing, then creates a tar archive of `/var/lib/pacman/local`.
If later access is needed, untar the archive, and point pacman at that dir (e.g.: to get the package lists from an unrecoverable system). The archive includes the dirs leading up to the actual database, so if simple recovery is the goal, just untar at `/`. For accessing the database in other situations, it might be prudent to add `--strip-components=3` in order to get just the `local` subdir.
### Config
```prettyprint
- Backup the database to this folder
target_folder=/home/thurstylark/.pkglists/$(hostname)/
- Define how long backups should be kept
- Can be a number of days or empty to disable
keep_days=
- Define how many backups should be kept
- If more backup are found, the oldest are deleted
- Can be a number of file or empty to disable
keep_number=1
```
This will keep only one copy of the database around, and delete all the others. Since they are being committed to a git repo, there's no need to keep several copies to have access to the history.
## Backing up
Once pakbak has created the archive, it is added, committed, and pushed to a vcsh git repo by a couple of systemd --user services. This is triggered by any change to the directory that pakbak writes its output to for that host. Activation of this process is handled by `pkglists-commit.path`:
```prettyprint
[Unit]
Description=Path activation for pkglists-commit.service
[Path]
PathChanged=%h/.pkglists/%H
MakeDirectory=true
[Install]
WantedBy=default.target
```
This unit watches `$HOME/.pkglists/$HOSTNAME` for changes, and on any activity, activates `pkglists-commit.service`:
```prettyprint
[Unit]
Description=Add, commit, and push pacman db backups
[Service]
Type=oneshot
RemainAfterExit=no
ExecStartPre=/usr/bin/bash -c 'wait $(pgrep pakbak)'
ExecStartPre=/usr/bin/vcsh pkglists pull
ExecStartPre=/usr/bin/vcsh pkglists add -A %h/.pkglists/%H/*
ExecStartPre=/usr/bin/vcsh pkglists commit -m "Auto-commiting %H pacman db"
ExecStart=/usr/bin/vcsh pkglists push
```
This service waits for pakbak to complete, pulls the pkglists repo, adds any changes to `$HOME/.pkglists/$HOSTNAME`, commits to the repo, then pushes. Thanks to `git-add`'s `-A` option, the add step also includes removal, so that git will remove the old database from the branch, which avoids the possibility of having multiple databases exist when pulling from or cloning the repo.
This is where the main magic happens that allows automatic distributed backups. For each host that has this set up, they also are housing the backups. The origin branch is _technically_ the canonical master, but since this is git, recovery is very easy to access from any machine. Also, since the trigger is literally any time pacman's local database changes (read: installation or removal of a package), the chances of all the clients having the latest revision of the repo becomes much higher.
## Caveats
- I'm not a big fan of using my own `systemd.path` unit since one is already provided by pakbak, but since A) this process deals with files in a home folder, and B) there isn't any forseeable situation where a `systemd --user` instance _won't_ be running when the database gets updated, I opted for `systemd --user` units to manage this part of the solution, and `--user` units can't depend on `--system` units. This could easily be fixed by installing a copy of pakbak's units to `/usr/lib/systemd/user/` in the `PKGBUILD` and running it from there.
- All of this could probably be replaced with my own `systemd --user` units or a pacman hook, but for the moment, I'm more concerned with getting it working.

15
new/Ramblings.md Normal file
View File

@ -0,0 +1,15 @@
= Ramblings =
Sometimes I just need to write shit down.
## LGBTQ+
- [On Labels](On Labels.md)
### On Gender
- [Am I faking being trans?](am-i-faking-gender)
### On Sexuality
- [Does experimenting make you any less straight?](experimenting-with-sexuality)
- [Should I come out while still questioning?](coming-out-while-questioning) -- Adolescence, fluidity, and communicating your truth
- [Do people actually desire physical affection?](desiring-physical-affection) -- Asexuality, relationships, and wtf is normalcy anyways?

74
new/SSH.md Normal file
View File

@ -0,0 +1,74 @@
# SSH
----
## User-Specific Client Config
Most directives that can be set in the system-wide client configuration can be set by each user in `~/.ssh/config`. This snippit contains a collection of my most used options:
```prettyprint
SendEnv LC_* * Send all LC env vars to the host
AddKeysToAgent yes * If asked to unlock a password-protected private
- key, automatically add that key to the ssh-agent
- so you no longer need to reenter the password
- again this session
- Example Host Definition
Host foo * Arbitrary String. Use this definition by running `ssh foo`
HostName foo.bar.com * Actual DNS Hostname or IP address of the server
Port 12345 * Port number to connect to
User thurstylark * Username on the server to connect as
IdentityFile ~/.ssh/id_rsa * Private key to use for authentication
ServerAliveInterval 300 * Interval in seconds before a keepalive packet is sent to the server
ServerAliveCountMax 3 * Declare the connection dead after no response to this many keepalive packets
HostKeyAlgorithms ssh-dss * Use ssh-dss for host-key algorithm checking (ssh-dss is insecure. Use something else)
KexAlgorithms +kex * Add 'kex' to the list of Key Exchange Algorithms available for use.
StrictHostKeyChecking no * Turn off Strict Host Key Checking for only this host (insecure)
UserKnownHostsFile /dev/null * Discard this hosts host key instead of storing in ~/.ssh/known_hosts (not recommended)
VisualHostKey yes * Always use randomart in place of host key sums
```
### Directive Notes
- `Host`
- Can also refer to an actual hostname. See "Host-Specific Keys" below.
- `ServerAliveInterval` and `ServerAliveCountMax`
- It's common for a firewall to cause problems keeping connections open, so tweaking these settings can help. See "Broken Pipe Remedy" below.
- `HostKeyAlgorithms`
- ssh-dss is less secure than the alternatives/defaults. Only use this if necessary.
- `KexAlgorithms`
- I use this to add `diffie-hellman-group1-sha1` to the available Key Exchange Algorithms for connecting to older hardware that doesn't accept any currently allowed kex algorithms. Diffie Hellman is quite insecure, so please use caution.
- `StrictHostKeyChecking`
- Several servers I connect to are descrete servers, but they all are accessed through a single IP Address with a randomized port number. This allows me to continue connecting to the host without stopping to delete a line from `~/.ssh/known_hosts` before connecting.
### Host-Specific Keys
User-specific ssh configs make it stupid easy to create several keys for several different uses. For instance, this allows you to have a separate key for each service that you use, and allows you less headache should one key be compromised.
For example: Github allows you to push to your remote repositories over ssh by adding a public key to your account. Ideally, you should create a keypair for this specific purpose, and name it something like 'github'. Then you can add something like this to your `~/.ssh/config`:
```prettyprint
host github.com
IdentityFile ~/.ssh/github
```
Now, when your repo's origin url is set to something like `git@github.com:username/reponame.git`, ssh will automatically use your github key instead of needing to specify it in the command, or using your username and password with HTTPS every time.
### Broken Pipe Remedy
Often times a firewall or inconsistent connection can cause an ssh connection to be closed prematurely and give a "Write Failed: broken pipe" error message. Some firewalls are configured to close connections that have sent no data after a certain interval, thus causing a broken pipe error when the connection was otherwise healthy. This can usually be solved by sending data through the connection before that interval is up, thus resetting the firewall's timer.
The `ServerAliveInterval` option sends a keepalive packet if no data has been received within the interval specified. All the keepalive packet does is request a response from the server to verify the connection is still good. By default, this option is disabled.
Additionally, the `ServerAliveCountMax` option specifies the number of keepalive packets that may be sent without a response before ssh terminates the connection. By default this is set to `3`, but if your connection is unreliable, you can set this higher to give your server a better chance at responding the next time a keepalive packet is sent.
It is important to note that messages sent by the `TTYKeepAlive` option are not sent through the encrypted channel and can be spoofed, but the "server alive" messages are sent through the encrypted channel and cannot be spoofed. Do not use `TTYKeepAlive` messages for determining the quality or security of a connection! See `ssh-config(5)` for more info.
----
## SSH Host Configuration
### Google Authenticator

View File

@ -0,0 +1,23 @@
# Stupid Crestron Quirks
Crestron can be stupid sometimes. These are the undocumented ways.
## When creating a SIMPL Windows program for a 2 Series DMPS, DO NOT select the control system at program creation
When you create a new SIMPL Windows program, you get the option to select which control system this program is being created for. Without selecting this option, you won't be able to connect any of your logic to any of the hardware, and your program won't do anything useful. You *can* create a program without a control system, but this is usually to create a SIMPL Macro, which is then completed and added to a different SIMPL program. All this to say, a SIMPL Windows program without a control system at the top of the hardware tree is not useful on its own.
So, when I create a program that's supposed to run on a 2 Series DMPS (model `DMPS-*`, not `DMPS3-*`), and I understand all the above, naturally I select the model number of the control system I'm writing a program for.
The program gets created, and I get started creating the program. I get hung up on the part of the program that deals with switching video and audio sources, so I naturally look at the help file for the device that I'm trying to control. It's probably the most unhelpful help file in the history of helping people.
Here's where it's valuable to understand a little about the hardware. Crestron has a long history of design-recycling masquerading as backwards-compatibility. Basically, whenever they create a new product, they take an existing product and its tech, modify it to do what they want to market, and throw it out there. In this case, they took a 2 Series processor and a paired-down DM chassis, shoehorned them into the same case, and rushed it to market. The result is a disjointed attempt at providing the advertized functionality. Instead of providing the programmer with the appropriate controls for input switching in the hardware tree (you know, where you control the hardware), they instead had a whole bunch of undocumented nonsense nodes in a jumble of confusing unreadable card-based slot structure, and then a macro (yes, quite literally like the macro that I alluded to earlier), which connects itself to all the right spots in the hardware tree, and provides a littany of **actually useful** controls in the logic tree.
The perceptive reader might ask how such a macro does the attaching by itself (as the attaching of signals is usually the exclusive job of the Crestron programmer/dealer). Well, the answer came to me after 45 minutes of troubleshooting on my own and with my manager, and then after an hour-long phone call with Crestron True Blue support: I created the program wrong.
See, if you select a 2 Series DMPS at program creation, this macro doesn't get automatically added and connected to the appropriate places in order to be useful. Instead you have to create the program with no control system, then add the control system in configure mode. Apparently there is some sort of script that bootstraps the module to the hardware, and if you add the control system to the project at program creation, this script doesn't get to run, and your program is SOL. And since I had put the switching problem aside and finished creating the rest of the program, the tech on the phone had to tell me that I had to create a new program from scratch, and copy/pase my code into my new project to get it to work.
Now, I'm hesitant to rag solely on Crestron's developers for this convoluted mess of what-the-fuckery, but this situation does make it obvious that there is definitely a cultural reluctance to modernize and refactor their systems for the good of the programmers that have to put these systems together for *their* customers. Further, I'm sure that the decision to base their control systems on Windows CE and .NET Compact Framework 3.5 was not made by the developers, and they are certainly making the best of the hand they're dealt (especially now that their current control systems are running on these discontinued products). I think the blame for this particular circuis goes to their exec team who didn't give enough time to make this project the right way. It's a classic case of a product being rushed to market, but here's the important part: It seems that way only from the perspective of the *programmer*.
See, if there's anything that I would commend Crestron's Dev team for, it would be stability. It takes a lot to get a big system with hundreds of finicky pieces to work together just right, but by god, once you get it right, it will do the exact same thing in the exact same way every freakin time until the hardware gives out. This is no small feat, and I recognize that for what it is. I take issue with all the other cruft and bullshittery that collects after years and years of the "Backwards Compatibility and Stability above all" doctrine. It's a doctrine that creates a focus on marketing and sales above product quality. From the end-user's perspective, the product works as desired, but this is at the cost of programming time due to the complexity of these systems and the necessity of a programmer with the appropriate experience. All part of the bill that the customer has to pay.
And this is one of the many reasons Crestron can be stupid.

16
new/Tasks.md Normal file
View File

@ -0,0 +1,16 @@
# Tasks
## General
## Wiki
### Pages
- [ ] Thurstylark-VPS
- [ ] Cgit
- [ ] Apache
### Template
- [ ] Figure out TOC
- [ ] Finish building out navbar
- [ ] Change page title to "Thurstylark Wiki -- %title%"
- [ ] Breadcrumbs?

10
new/Thurstylark-VPS.md Normal file
View File

@ -0,0 +1,10 @@
# Thurstylark-VPS
Just a little Linode VPS running Arch, but it's a powerful little sucker.
## Services
- [Cgit](Cgit.md)
- Apache
- [Weechat](Weechat.md)
- Custom Repo

142
new/Vimwiki.md Normal file
View File

@ -0,0 +1,142 @@
# Vimwiki
Source: https://git.thurstylark.com/vimwiki.git/
## Features
- All content is stored in a git repo as vimwiki content (to avoid having to sync HTML content as well)
- All content automatically converted to HTML and moved to the appropriate directory when the git repo is pushed
- [Template](https://git.thurstylark.com/vimwiki.git/tree/html-template/index.html) based on bootstrap, so theming/building the template is easy peasy
## Table tweaks
Tables without any styles are gross, so let's use the styles from Bootstrap. Problem is that Vimwiki doesn't provide a way to add a class to a table element, so we'll do it with JQuery:
```prettyprint
<head>
...
<script>
$(document).ready(function(){
$("table").addClass("table table-condensed table-hover");
});
</script>
...
</head>
```
This adds `.table`, `.table-condensed`, and `.table-hover` classes to every table element in the whole document. Don't see why it should be any other way for the moment.
### References
- http://stackoverflow.com/a/39897883
- http://www.w3schools.com/jquery/jquery_syntax.asp
## HTML Checkboxes
By default, there is no difference between how a non-checkbox list item, unchecked list item, and a checked list item are displayed when exported to HTML.
There are 5 states of a checkbox, 0-4, and they each represent a different level of completeness. This is mainly for checklist items with children.
Checkbox states:
| State * | % Complete | li class | Unicode character | Escape sequence | HTML code |
|---------|------------|----------|-------------------|-----------------|------------|
| 0 | 0% | `done0` | ◯ | `\u25EF` | `&#9711;` |
| 1 | 1-33% | `done1` | ◔ | `\u25D4` | `&#9684;` |
| 2 | 34-66% | `done2` | ◑ | `\u25D1` | `&#9681;` |
| 3 | 67-99% | `done3` | ◕ | `\u25D5` | `&#9685;` |
| 4 | 100% | `done4` | ✔ | `\u2714` | `&#10004;` |
Now, in order to use these in our HTML, we just have to write a style for `ul li.doneX:before` in our header like so:
```prettyprint linenums >
<style>
ul li.done0:before {content: '\25EF';}
ul li.done1:before {content: '\25D4';}
ul li.done2:before {content: '\25D1';}
ul li.done3:before {content: '\25D5';}
ul li.done4:before {content: '\2714';}
</style>
```
Now here's a few test lists:
- [ ] Unfinished item
- [X] Finished item
- [ ] Parent item 1
- [X] Child item 1
- [ ] Child item 2
- [ ] Child item 3
- [ ] Child item 4
- [ ] Parent item 2
- [X] Child item 1
- [X] Child item 2
- [ ] Child item 3
- [ ] Child item 4
- [ ] Parent item 3
- [X] Child item 1
- [X] Child item 2
- [X] Child item 3
- [ ] Child item 4
- [X] Parent item 4
- [X] Child item 1
- [X] Child item 2
- [X] Child item 3
- [X] Child item 4
- [ ] Parent item 5
- [ ] Child item 1
- [ ] Child item 2
- [ ] Child item 3
- [ ] Child item 4
## Push to Deploy
The easiest way to manage this wiki, and also allow it to be hosted, is to commit all the wiki documents to a repo, and script the deployment to the wiki's webroot using git's post-receive hook. The origin remote repo also hosts the http server, so it makes things simple. Less simple because it requires a vim plugin to compile the HTML files, but it's still doable.
First part of this solution is the vimrc for the remote machine. This sets the destination for the final html files, the origin wiki files, and the html template page.
```prettyprint linenums
set nocompatible
filetype plugin on
syntax on
let g:vimwiki_list = [{
\ 'path': '/tmp/vimwiki/',
\ 'path_html': '/srv/wiki/',
\ 'template_path': '/tmp/vimwiki/html-template',
\ 'template_default': 'index',
\ 'template_ext': '.html'}]
```
Note: lines 1-3 are required for vimwiki to work correctly with the post-receive hook. The rest of the config are options for vimwiki directly.
The post-receive hook is a fairly simple bash script. This script is located at `~/git/vimwiki.git/hooks/post-receive`, and is run every time the repo receives a push from downstream.
```prettyprint linenums
#!/bin/bash
mkdir /tmp/vimwiki
export GIT_WORK_TREE=/tmp/vimwiki
export GIT_DIR=/home/thurstylark/git/vimwiki.git
git checkout -f
vim -u /tmp/vimwiki/html-template/srv-vimrc -c VimwikiAll2HTML -c q /tmp/vimwiki/index.wiki
cp /tmp/vimwiki/html-template/slate.bootstrap.css /srv/wiki/
rm -rf /tmp/vimwiki
```
It first makes a directory under /tmp for the contents of the repo, sets `$GIT_WORK_TREE` and `$GIT_DIR`, and does a `git checkout` for all the files in the repo.
Line 9 is where the magic happens. This line runs vim with the vimrc from above, and runs the `:VimwikiAll2HTML` command.
Next, the script copies over the one CSS file that I need to host myself, and lastly, it cleans up the temp dir.
## TODO
- [X] Commit to a repository
- [X] Setup remote to host
- [X] Setup remote to automatically `:VimwikiAll2HTML` after it's been pushed to
- [X] Document push to deploy

206
new/Weechat.md Normal file
View File

@ -0,0 +1,206 @@
# Weechat
Current configuration can always be found at https://git.thurstylark.com/vcsh/weechat.git
Requirements:
- Not dependent on graphical session (terminal-based client)
- Use only one nick during normal operation
- Use multiple computers interchangeably at random
- Do not require a close/quit process to move between workstations
- Reduce the ammount of join/part messages caused by me
- Be reachable through IRC as much as possible (stay online)
- Have the ability to use a mobile app at will
The best option so far is weechat run in a multiplexer like tmux.
----
## Starting Weechat
Easiest way to get this done is to start weechat at boot with a systemd system service:
```prettyprint linenums
[Unit]
Description=Start Weechat as relay and client
[Service]
Type=forking
User=thurstylark
Group=thurstylark
ExecStart=/usr/bin/tmux -f /home/thurstylark/.config/srv-tmux.conf new-session -ds weechat weechat
[Install]
WantedBy=multi-user.target
```
### Notes
- When starting tmux with `new-session -d` as its command, tmux forks to the background, thus requiring `Type=forking` in order to let systemd keep track of the process.
- I run this service as my user and group, because I use the default locations for weechat config: `~/.weechat/`. This greatly simplifies weechat configuration.
- tmux configuration needs to be passed to tmux by using `-t /path/to/config`. Full path is used just to be thorough.
----
## Configuring tmux
tmux needs a configuration to disable the status bar, visual bell, and other things that won't be useful in this setup.
```prettyprint linenums
set -g default-terminal "screen-256color"
set-option -g assume-paste-time 1
set-option -g base-index 1
set-option -g pane-base-index 1
set-option -g default-command ""
set-option -g default-shell "/bin/bash"
set-option -g destroy-unattached off
set-option -g detach-on-destroy on
set-option -g display-panes-active-colour red
set-option -g display-panes-colour blue
set-option -g display-panes-time 1000
set-option -g display-time 750
set-option -g history-limit 10000
set-option -g word-separators " -_@"
set-option -g renumber-windows off
set-option -g repeat-time 500
set-option -g set-remain-on-exit off
set-option -g set-titles off
set-option -g set-titles-string "#S:#I:#W - "#T" #{session_alerts}"
set-option -g status off
- Change prefix to C-a
set-option -g prefix C-a
set-option -g status-style fg=black,bg=cyan
set-option -g message-command-style fg=green,bg=black
set-option -g message-style fg=white,bg=red
set-option -g update-environment "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY"
- Set audible bell on, and visual bell off because it is slooooowwwww
set-option -g bell-action any
set-option -g bell-on-alert on
set-option -g visual-bell off
set-option -g visual-silence off
set-option -g visual-activity off
- Pane active colors
set-option -g pane-active-border-style fg=cyan,bright
- Pane inactive colors
set-option -g pane-border-style fg=colour8
- Use C-a,Shift-R to reload configuration
bind R source-file ~/.tmux.conf \; display-message "Config reloaded..."
- Use C-a,a to send prefix to nested session
bind-key a send-prefix
- Use Alt-arrow keys without prefix key to switch panes
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D
- Do the same for HJKL
bind -n M-h select-pane -L
bind -n M-l select-pane -R
bind -n M-k select-pane -U
bind -n M-j select-pane -D
- No delay for escape key press
set -sg escape-time 0
- Various copy mode tweaks
bind-key -t vi-copy Home start-of-line
bind-key -t vi-copy End end-of-line
- Sync copy mode and PRIMARY selection
bind-key -t vi-copy MouseDragEnd1Pane copy-pipe "xsel -i -p -b"
bind-key -t vi-copy Enter copy-pipe "xsel -i -p -b"
bind-key -t vi-copy y copy-pipe "xsel -i -p -b"
```
### Usage
I will usually use this within yet another tmux session, so I end up needing to set up some key bindings to control the differrent sessions
- `C-a a`: Send prefix to the terminal
- `C-a a d`: Disconnect the nested session from this client.
- `C-a a :`: Get command prompt on nested session
----
## Weechat Relay
Here are all the options related to weechat relay:
```prettyprint linenums
[cmd] (alias.conf)
alias.cmd.norelay = "/buffer set localvar_set_relay hard-hide"
[look] (relay.conf)
relay.look.auto_open_buffer = off (default: on)
relay.look.raw_messages = 256
[color] (relay.conf)
relay.color.client = cyan
relay.color.status_active = lightblue
relay.color.status_auth_failed = lightred
relay.color.status_connecting = yellow
relay.color.status_disconnected = lightred
relay.color.status_waiting_auth = brown
relay.color.text = default
relay.color.text_bg = default
relay.color.text_selected = white
[network] (relay.conf)
relay.network.allow_empty_password = off
relay.network.allowed_ips = ""
relay.network.bind_address = "127.0.0.1" (default: "")
relay.network.clients_purge_delay = 0
relay.network.compression_level = 6
relay.network.ipv6 = off (default: on)
relay.network.max_clients = 5
relay.network.password = "letmein" (default: "")
relay.network.ssl_cert_key = "%h/ssl/relay.pem"
relay.network.ssl_priorities = "NORMAL:-VERS-SSL3.0"
relay.network.websocket_allowed_origins = ""
[irc] (relay.conf)
relay.irc.backlog_max_minutes = 1440
relay.irc.backlog_max_number = 256
relay.irc.backlog_since_last_disconnect = on
relay.irc.backlog_since_last_message = off
relay.irc.backlog_tags = "irc_privmsg"
relay.irc.backlog_time_format = "[%H:%M] "
[port] (relay.conf)
relay.port.weechat = 9001 (default: 0)
```
### Notes
- `alias.cmd.norelay = "/buffer set localvar_set_relay hard-hide`
- Creates the `/norelay` command which is used to hide a buffer from being relayed to any relay client. This is mainly for stopping a buffer from alerting me on mobile.
- `relay.look.auto_open_buffer = off`
- Keeps weechat from opening a buffer with superfluous information every time a client connects or disconnects
- `relay.network.bind_address = "127.0.0.1"`
- Weechat will only accept relay connections from localhost. This means any relay client that wishes to connect will need to tunnel over ssh first, then connect to the relay. Luckily for me, weechat-android does this natively.
- `relay.port.weechat = 9001`
- The relay client will want to know this.
### Reference
- https://weechat.org/files/doc/stable/weechat_user.en.html#relay_plugin
----
## Workstation Client
By far, the most use of weechat will be from a workstation. With this setup, the only requirements of the client is ssh or mosh. I prefer mosh in this case because of it's reconnect capabilities, making it much less painful to keep a session running on a mobile workstation.
Also, the easiest way to launch this connection is to run literally `weechat`, so I set up a couple aliases for this in my `~/.bashrc` (found [here](https://git.thurstylark.com/vcsh/bashrc.git/tree/.bashrc)):
```prettyprint
- If you don't have weechat installed, connect to the existing tmux session through mosh
[ ! -s /usr/bin/weechat ]( ! -s /usr/bin/weechat .md) && alias weechat='mosh vps -- tmux attach -dt weechat'
- If you are thurstylark-vps, connect to the existing tmux session locally
[ "$HOSTNAME" = "thurstylark-vps" ]( "$HOSTNAME" = "thurstylark-vps" .md) && alias weechat='tmux attach -dt weechat'
```
This gets run when bash starts, so this allows me to use the same `~/.bashrc` on the client and the server. More details on the Bash page.
The only thing not noted is that if the client has weechat installed (to /usr/bin/weechat) and `$HOSTNAME` is not "thurstylark-vps", an alias for 'weechat' will not be created, and weechat will launch normally.
[Configuration](Configuration.md) that allows one to use an arbitrary string as a hostname for ssh/mosh can be found on the ssh config page.

124
new/Xinitrc.md Normal file
View File

@ -0,0 +1,124 @@
# Xinitrc
Source: https://git.thurstylark.com/vcsh/xinitrc.git
----
## Preamble
The first few lines of my Xinitrc are from `/etc/X11/xinit/xinitrc`. They pull in different X configuration, and also run any scripts from `/etc/X11/xinit/xinitrc.d/`.
----
## Screen Locker
-WARNING*: [(in fact, you might want to consider even using X11 in the first place...)](http://blog.martin-graesslin.com/blog/2015/01/why-screen-lockers-on-x11-cannot-be-secure/|Screen lockers on X11 are absolutely not secure]]!! Do not use a screen locker if you require high security!! [[http://theinvisiblethings.blogspot.com/2011/04/linux-security-circus-on-gui-isolation.html)
I lock my desktop using a combination of `i3lock(1)` and `xautolock(1)` with some help from `xset(1)` to change dpms timeout before and after locking:
```prettyprint
screen_locker="xset dpms 0 0 10 dpms force off; i3lock --nofork -befc 000000; xset dpms 0 0 0"
locktime=30 * Default screen lock timeout in minutes
...
- Automatically lock after $locktime minutes using i3lock
xautolock -time $locktime -locker "$screen_locker" -detectsleep &
```
The locker is defined in `$screen_locker`, then used later along with `$locktime` to start `xautolock(1)`. When `$screen_locker` is run, the following happens:
1. DPMS timeout is set to 10 seconds
2. DPMS forces the display off now
3. i3lock is run with these options:
- `--nofork`: Don't fork to the background
- `-b`: Beep on incorrect password attempt
- `-e`: Ignore empty password
- `-f`: Show number of failed attempts, if any
- `-c 000000`: Background color should be `#000000`
4. When i3lock exits, DPMS timeout is set to 0 for never
Whenever I wish to lock the screen, I need only run `xautolock -locknow` making sure that `$DISPLAY` is set correctly. For example, my [i3](i3.md) config is set up to run that command for `Ctrl+Alt+l`.
Also note that the definition of `$screen_locker` and `$locktime` are separated from the invocation of `xautolock(1)` by all the host-specific configuration. This is to allow setting `$locktime` on a host-by-host basis. Given the first step of the locker is to use DPMS to turn the display off, this effectively sets the display sleep timeout to `$locktime`.
As far as power saving options go, `$screen_locker` _could_ be a little more general by using a variable for the last invocation of `xset(1)`, but I don't have a need for it.
----
## Srandrd
All display output configuration, touchscreen configuration, or any other configuration that should change based on display connectivity takes place in the `srandrd(1)` configuration. In fact, `~/.xinitrc` will completely abort if srandrd isn't installed. This makes display layouts and touchscreen easier to maintain in the long run.
The "configuration" can be any executable file which will be run with the environment variable `$SRANDRD_ACTION` set to a string formatted as `<output> <connected|disconnected|unknown>`, where `<output>` is the name of the output according to `xrandr(1)`. I use a bash script for this purpose.
### Script Summary
This script is set up to be one monolithic "configuration" for multiple hosts by using a case statement that tests against `$(hostname)` before attempting to handle `$SRANDRD_ACTION`. If multiple configuration files become necessary at some point, it would be trivial to break out each host's configurations into their own files and do something similar to `source ~/.config/srandrd/$(hostname).conf`, but it's not necessary for the time being.
Once the hostname is determined, I begin by setting a few variables with host-specific information. Setting these variables before handling `$SRANDRD_ACTION` is beneficial for situations where a software or hardware change might change any one of these values, in which case, the information will only need to be updated in one place instead of several places throughout the script.
Finally, `$SRANDRD_ACTION` is handled with a case statement. This section of the script can be arbitrarily complicated, but for my simple usage, every output that needs to be handled needs both a connected and disconnected case defined. In the most complicated case, I do 3 things: Run `xrandr(1)` to configure outputs, configure the touchscreen with `xinput(1)`, and set PulseAudio's default sink with `pacmd(1)`.
### Touchscreen Configuration
When using a touchscreen with multiple monitors, it is possible that the touchscreen will be mapped to cover the entire canvas instead of only the display to which it is attached. This results in situations where touch events on one side of the display will be close to accurate, but touch events on the other side of the display begin to manipulate the cursor on the 2nd display.
This is fairly easy to rectify using `xinput --map-to-output <device id> <output name>` where `<device id>` is the id number of the touchscreen as reported by `xinput list`, and `<output name>` is the xrandr name of the output you wish to map the touchscreen to.
This may seem easy enough to script by finding the device id once, then adding an appropriate line in `~/.xinitrc`, but the device id is not static, and may change between boots.
For this reason, it is more appropriate to match against an attribute of the device that will not change. In the case of `xinput(1)`, the best option for this situation is the device name. The device id can easily be found by running `xinput list --id-only <device name>`. This can easily be strung together with a subshell to do everything on one line. For instance, if you wish to map a device named `ELAN Touchscreen` to an output named `eDP-1`, the resulting line might look like the following:
```prettyprint
xinput --map-to-output $(xinput list --id-only "ELAN Touchscreen") eDP-1
```
This command must be run after every time the display configuration changes, so it is possible that the command will need to exist several times in the `srandrd(1)` configuration. Since the only unique pieces of information between hosts will be the device name and the output name, it is easier to use a function instead of duplicating the same line over and over:
```prettyprint
maptouchscreen() {
- maptouchscreen <name> <output>
local name="$1" * <name> should be a full name from the output of `xinput list`
local output="$2" * <output> should be an xrandr output name
xinput --map-to-output $(xinput list --id-only "$name") "$output"
}
```
This allows you to replace any instance of the full `xinput(1)` command with `maptouchscreen <device name> <output>`.
-Note:* If there are spaces in the device name, bash will glob the crap out of it, so be sure to double quote the device name when calling `maptouchscreen()`.
### PulseAudio Default Sink
I want the default PulseAudio sink to change to HDMI when HDMI is plugged in, and back to analog when disconnected.
Changing the default sink in pulse is as easy as running `pacmd set-default-sink <sink id>` where `<sink id>` is the id of the desired sink. Unfortunately, this is another situation where the id might change unexpectedly. We also don't have an easy interface to determine the id number from a name like we did with `xinput(1)`, so we're forced to parse the output of `pactl list sinks short` like so:
```prettyprint
pacmd set-default-sink $(pactl list sinks short | grep "hdmi" | grep -o "^\S\+")
```
This command lists all sinks in short form, then greps for a line containing "hdmi", uses grep to only print the first character (the sink id), then sets the default sink with `pacmd(1)`. Since this will also need to be run any time the display configuration changes, a function is, again, appropriate:
```prettyprint
setpasink() {
- setpasink <name>
- Find a unique string in the output of `pacmd list short` to use for <name>
pacmd set-default-sink $(pactl list sinks short | grep "$1" | grep -o "^\S\+")
}
```
This allows you to change the default PulseAudio sink with `setpasink <name>` where `<name>` is any arbitrary string that is unique to the line that corresponds to the desired sink in the output of `pactl list sinks short`.
----
## NumLock
----
## ssh-agent
----

39
new/am-i-faking-gender.md Normal file
View File

@ -0,0 +1,39 @@
# Am I Faking Being Trans?
This began life as a reply to someone on /r/questioning, but I later came to realize that I was actually writing to myself.
## Prompt
(paraphrasing to anonymize)
OP expressed that they had recently begun feeling like he/him didn't quite fit, and had started talking to their non-binary friends about their feelings. Unfortunately, OP received some pushback from those friends because, they had felt NB all their life, and the process of discovery for them was mainly focussed on finding the language to express as much, so these friends began assuming that OP was faking it.
OP's main question was: Is it possible that I'm just faking how I feel? That they're right and I'm just making it up in my mind to fit in with my friends?
## Response
Labels aren't a template for behavior. They're a tool used to communicate your particular flavor of awesome to others. You are you, pick a label that fits (or don't, whatever).
There are 7 billion unique people on this earth, and we haven't developed mind-reading tech yet, so that leaves *you* as the only person who is physically capable of living your life, feeling your emotions, and experiencing your gender. Nobody else knows exactly what's going on in your head, and the only way we can learn is if you tell us.
That doesn't always happen perfectly, though. Sometimes the right words don't exist, sometimes the words come out wrong, sometimes both of those go exactly right, and the other party ends up misinterpreting what was said... This can affect what others understand about what you're trying to communicate, but none of that changes this one simple fact:
### *You* are the ultimate source of information about *yourself*
So, are you cis? How the fuck should I know? I don't live your life. You're cis if you say so. You're bi if you say so. You are who you say you are, because nobody else has a better source of information about you than you do.
Put another way: What if you're faking being *cis?* What if you were never cis from the get-go, but you've been "faking it" as your assigned gender for your whole life because that's all that you've been allowed to think until now? What if this means that, since you have no experience with a label that accurately reflects your gender identity (internal), you therefore don't know what it's like to *not* fake your gender expression (external)? What if it feels like or sounds like "faking it" because you've been faking an *incorrect* gender this whole time, and simply don't know what it feels like to truly identify with your label because it was given to you at birth based on your genitals instead of you choosing your label based on how accurately it reflects your reality?
### Change is life
Additionally: Human nature is to change, and neither sexuality or gender are exempt from that by any means. Knowing for certain that one label fits you for any amount of time does not mean that you're stuck with it until you die. Changing your label is just as valid as changing your haircut or your clothes. Both of these are also external expressions of internal taste in style, why would the rules for your taste in romance or sex be any different?
If your gender changes, and you decide to change your labels to match, that's it. Any resistance you receive for communicating this information to others is laughably pointless. What are they gonna do, try to *persuade* your experience into compliance??
### Communicating your truth
Remember, You aren't responsible for how others react to information that you provide. You are simply putting it out there, and any reaction to that news is ultimately a reflection of *their* thoughts and emotions through the lens of *their* experience and bias. Your life and experience isn't affected by whether they choose to respect you by accepting information from the primary source (you) as truth, or if they choose to live in their own reality by denying it. You continue to be you, they continue to be them, and the planet continues to spin.
I realize that you may not be in a place to directly confront your friends about how they discuss sexuality and gender, but I would encourage you to push back on the idea that you're "faking" something. You are welcome to accept others' perspective, but *they* are as much of an authority on *your* gender as *you* are on *theirs.* Just because they know what it's like to experience *their* gender doesn't mean that they know what it's like to experience *your* gender.
The short version of this story is this: Your friends have shared information about their experience that they expect *you* to respect, but they did not to afford *you* the same respect when you decided to express similar information. That's rude and inconsiderate, and it's perfectly appropriate for you to ~~ask~~ ~~expect~~ *demand* them to respect your gender expression (however fluid or unresolved it might be), just the same as *they* have asked of *you*.

View File

@ -0,0 +1,65 @@
# Should I Come Out While Still Questioning?
This began life as a reply to someone on /r/questioning, but decided to archive it for myself.
## Prompt
(Paraphrasing to anonymize)
OP is female, and 17 at the time of writing. She had been questioning her sexuality for a while, has privately used a few different labels along the way,but still remained kind of confused about her identity. She had planned on coming out to her family once sure of her labels, but she's slowly coming to the realization that this might take some many years to fully flesh out. She wants to be open about her sexuality to friends and family, but even though they are generally supportive of the LGBTQ+ community, she feels it may still be complicated to explain certain concepts to some individuals.
OP's main question: "Is it a possibility to come out although I'm not sure of my labels yet? At the moment, I would most likely come out as simply "not heterosexual" and questioning. Also, since I'm fairly nervous about this, would it be ok to do this in writing, or should I only do this face-to-face? Should I wait until I've stopped questioning?"
## Response
IMO, identifying as questioning is such a power move.
"Good luck trying to shove me in one of your stupid boxes while even *I* don't know what the hell is going on in here!"
Labels can be tricky when the landscape seems to keep shifting like this, but I have two main ideas on this front:
### 1. On Adolescence
Teen years suck in countless ways, but they also come with a neat perk: ***Nobody expects you to have your shit together yet.*** Those younger than you will look up to you by default, those older than you have been through it and understand, and your peers are busy dealing with their own shit. You have the benefit of a few years of life with bumpers where you're ~~allowed~~ *expected* to figure out who you are, often via trial-and-error.
Salty adults can complain all they want about a teenager going through a "phase," but we only call it that because when we try to remember our *own* teenage years, it reminds us of all the ways that our teenage selves needed improvement in order to become who we are today. It's human nature to change and adapt, and teen/early adult years are often one's first and most substantial opportunity to make those changes based on *internal* motivation as opposed to *external* motivation like a parent, guardian, teacher, etc.
Guess what: When a human with little life experience and a newly-discovered personal agency is given the opportunity to make changes to themselves, they make uninformed decisions. Every single adult on this planet has made a bad decision in their teenage years, and learned from it. C'est la vie. The important part of this process is that when we make a misstep like this, we come out of it with lessons about what not to do next time. This is how adults are forged from the pressure-cooker of puberty, and we all go through it, whether we want to acknowledge that reality or not.
The only reason that adults label this as a "phase" is because when adults cast their mind back to their own lessons, they come to the incorrect conclusion that they *shouldn't have made that decision in the first place.* This makes a little sense when considering that this conclusion *is* the lesson they took from the experience, but how else were they to learn that lesson if not for experience? Life doesn't come with a manual or textbook to learn from, so how else are teenagers supposed to figure out how they want to dress or who they want to hang out with, or what they want to do with their life??
We *all* learn via experience during puberty, and your parents are no exception.
=== 2. On Labels and Questioning ===
-A label is not a template for behavior. It's a tool used to communicate you particular brand of awesome to others.* You are you, pick a label that fits. (or don't, whatever)
This isn't to say that labels are unimportant, though. At the very least labels provide a useful shorthand for things that are complicated or abstract (see: bisexuality vs pansexuality), so there's definitely an argument for their practicality. The point is that *your you-ness* should inform your label choice, and not the other way around.
This is why I think identifying as questioning is so cool. You can't get any more honest than openly admitting that you don't know shit and are still figuring it out :D
Alright, out of my soliloquy, and back to your thing :P
### Communicating Your Truth
Is it a possibility to come out although I am not sure of my labels yet?
As each person on earth is wholely unique, I would argue that there's currently around 7 billion different possible sexualities out there. Who you are, who you like, and the reasoning/motivation for any of these things are fully unique to you alone, which means that you happen to be *literally the only human on the face of the planet* with enough information to determine what label fits you best.
This goes both ways, too. You are the only one who can determine which labels *do* fit, but the same goes for labels that *don't* fit. If heterosexuality no longer fits you, that conclusion is equally entirely valid.
On that same coin, choosing to use no labels is just as valid, and so is picking a label but choosing to keep it private.
should I wait until I stopped questioning?
No. All humans change, and sexuality is not exempt. If you're feeling strongly about letting people know your labels, then that's a good enough reason in itself. If your attraction happens to change later on, that change is also valid, as is your choice of new labels
do you think that I should use a letter to come out?
IMO, whether you end up using it or not, write the letter anyways. When I have tangled, shifting, or abstract thoughts that don't lend themselves to easy explanation, I find that the process of taking hold of them and translating them into words helps *my own* understanding. Even if nobody reads what I write, I come away with a better idea of what I'm feeling, which parts are the most important to communicate, and how they can be worded.
If you end up with a letter you're happy with, I think it's a great way to deal with the nerves involved with face-to-face convos. A letter involves a great deal more time and effort than just words on a page, and I think your parents will definitely understand that :)
Above all else, remember that the way others respond to this information is ultimately filtered through *their* emotions, and is more of a reflection of *their* perspective. Whether the result is positive or negative, you are simply putting the information out there (as is your prerogative), and it is *their* responsibility to deal with it. There can be wider practical concerns (cases where parental withdrawal is likely, for instance), but on the general social front: you are not responsible for how other people handle the information you provide.
However you choose to come out, I wish you all the best :)

7
new/contact.md Normal file
View File

@ -0,0 +1,7 @@
# Contact Info
| Service | |
|----------------|-----------------------|
| Email | thurstylark@gmail.com |
| IRC (Freenode) | thurstylark |
| Twitter | @thurstylark |

View File

@ -0,0 +1,50 @@
# Do People Actually Desire Physical Affection?
This began life as a reply to someone on /r/questioning, but decided to archive it for myself.
## Prompt
(paraphrasing to anonymize)
OP has just started their first romantic relationship with someone they have quite a bit in common with. OP enjoys spending time with their partner, but didn't feel anything special during their first kiss. OP would be fine with kissing them again if requested, but it's not something they felt that they would specifically desire or seek out.
OP recognizes that they generally don't quite understand romance or attraction, so being in a relationship is somewhat difficult already, but in an effort to understand their partner better, they wanted other perspectives.
OP's main question: "Do 'regular' people actually desire physical affection? Like, do they look at their partner and feel a physical urge to touch/kiss them, or does it originate in some concious 'I want to touch/kiss them' thought that then begets an action?"
## Response
Do people actually desire physical affection?
For me, 'yes' isn't strong enough.
I don't just desire physical affection, I *need it*. In fact, I sometimes don't feel as if my feelings are properly expressed *without* employing physical affection. Past that, I can get irritable, depressed, and lonely during prolonged periods without it. It affects my mood on a deep level, and it's something I need in order to function properly. I don't think I could stay in a monogamous relationship that lacked physical affection.
### "Regular" people
BUT, if that's something you don't desire or need, then that isn't weird, it's just a part of your particular flavor of awesome. "Normal" or "regular" people aren't a thing, and I discourage anyone from trying to compare themselves to a baseline human configuration of wants and needs. Evolution-based life doesn't operate like that. Evolution is dependent on randomness, uniqueness, and mutations, then it keeps the useful ones around over time.
To this end, I encourage you to ask yourself: Where your idea of "normal" comes from? From your parents? Peers? Media? A combination?
Also, what is to be gained by people who reinforce this notion of "normal"? Do they earn money from it? Do they feel accepted or powerful by being (or claiming to be) a part of the "normal" group? Do they use it to otherize those who don't fit in the "normalcy" they so enjoy?
There's deep introspection down that path, so here's a lighter take: I don't have to understand you to respect you, but more importantly, *I don't have to understand you for you to deserve my respect.* You don't deserve respect because you fit in my definition of "respectable person", you deserve my respect because you are a human.
For example: I don't understand what it is to live in an existence where physical affection does nothing for me, but that's ok. My inability to empathize fully with your situation is not a failing on my part, and especially not on yours. I have to accept that yours is a perspective that I will never fully grasp, but also that ***you are still valid***. If someone is unable to *respect* you, that's a them thing, not a you thing.
### The nature of relationships
Above all, don't feel like you have to push yourself to do things that you're not comfortable with. In our current society, there is definitely a tendency to push for obtaining romantic relationships and putting them on an ever-escalating path towards monogamous marriage (most commonly referred to as the [Relationship Escalator](https://medium.com/@agahran/why-step-off-the-relationship-escalator-d5b033b1ccb2)).
There's a societal expectation that you date to marry forever and that's the best path for everyone, but it doesn't have to be that way. You are a unique person, your partner is a unique person, but also, the relationship between you and your partner is a unique entity of its own. Just as you don't have any responsibility to look or act or be a certain way, your relationships with others don't have to look a certain way.
All that to say: If physical affection is something that you don't want or need to be included in your relationship with another person, then by all means, you shouldn't feel obligated to shoehorn it in. Human relationships are best when they're mutually beneficial, and beneficial relationships tend to be stifled when one forces themselves to be someone they're not for the sake of the relationship.
That is my perspective, but don't take my word for everything. Try things out, figure out what works best for *you*. I greatly appreciate that you specifically expressed your desire for other perspectives. That is a valuable and [seemingly] rare trait, and you should be proud of that. Keep following that curiosity and openness.
If you would like more perspective, I would take a look at /r/asexuality, /r/demisexuality, and any other subs that may interest you from their sidebars and wikis. Follow your nose, ask questions, and read about the experience of others.
### Learning from the Polyamorous community
Also, while I am not directly recommending polyamory for your situation, a lot of understanding can be gained from that community about the nature of relationships. It was certainly a catalyst for shifting my own perspectives when it came to relationships. /r/polyamory, and the resources documented there is a good place to start. Decide whether it's for you or not, but I would recommend checking it out, if only in the interest of gaining new outside perspectives.

View File

@ -0,0 +1,13 @@
# Does Experimenting Make You Any Less Straight?
## No.
End of story. Full stop. Thanks for playing!
### Wait, Really?
Yes, really.
-You* are the only one who can define your sexuality. Sometimes people just know, sometimes they have to try things out before they are sure. Both are valid methods, and their results are genuine. Just because you experimented doesn't make the results any less valid. It doesn't matter if you kissed someone, or slept with someone and enjoyed it. If you say you're straight, then you're straight.
Labels aren't a template for behavior. Labels are a tool used to communicate your specific flavor of awesome to others. Likewise, behavior doesn't define your labels either. You do.

142
new/i3.md Normal file
View File

@ -0,0 +1,142 @@
# i3 Configuration
Source: https://git.thurstylark.com/vcsh/i3.git
## j4-make-config
The final config that actually is read by i3 is created using j4-make-config. This is done in the [Xinitrc](Xinitrc.md).
Simple usage:
```prettyprint
j4-make-config -a $(hostname).config archlinux
```
This creates `~/.config/i3/config` by merging `~/.config/i3/config.base` and `~/.config/i3/$HOSTNAME.config`, and adds the 'archlinux' theme (included with j4-make-config). Optionally, you can add `-r` to tell i3 to reload the config after `j4-make-config` has completed.
Since using `j4-make-config`, the command for reloading the config has been changed to the following:
```prettyprint
- rebuild and reload the configuration file
bindsym $mod+Shift+c exec "j4-make-config -r -a $HOSTNAME.config archlinux"
```
### Reference
https://github.com/okraits/j4-make-config
----
## Media Keys
### Volume
This differs depending on if you're using ALSA or Pulseaudio. Thus, I include these instructions in the host-specific configs instead of the base config
ALSA:
```prettyprint
- Alsa Volume controls
bindsym XF86AudioRaiseVolume exec --no-startup-id amixer set Master 5%+ #increase sound volume
bindsym XF86AudioLowerVolume exec --no-startup-id amixer set Master 5%- #decrease sound volume
bindsym XF86AudioMute exec --no-startup-id amixer set Master toggle * mute sound
```
PulseAudio:
```prettyprint
- PulseAudio Volume controls
bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +5% #increase sound volume
bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -5% #decrease sound volume
bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle * mute sound
```
### Brightness
Brightness can be universal unless the utility for changing brightness differs between machines, so this snippit lives in the base config.
```prettyprint
- Sreen brightness controls (requires light(1) from the AUR)
bindsym XF86MonBrightnessUp exec light -A 10 * increase screen brightness
bindsym XF86MonBrightnessDown exec light -U 10 * decrease screen brightness
```
### Playhead Control
This also is universal if the same tool is being used across hosts. I use `playerctl` mainly for its compatibility with Spotify's Linux client.
```prettyprint
- Music Player controls
bindsym XF86AudioPlay exec --no-startup-id playerctl play-pause
bindsym XF86AudioNext exec --no-startup-id playerctl next
bindsym XF86AudioPrev exec --no-startup-id playerctl previous
```
### References
https://wiki.archlinux.org/index.php/Extra_keyboard_keys
https://wiki.archlinux.org/index.php/Advanced_Linux_Sound_Architecture#Keyboard_volume_control
https://wiki.archlinux.org/index.php/PulseAudio#Keyboard_volume_control
https://wiki.archlinux.org/index.php/Backlight
https://wiki.archlinux.org/index.php/Spotify#Global_media_hotkeys
----
## Screen Locker
The screen locker is already set up in [Xinitrc](Xinitrc.md), so all that is necessary in the i3 config is to set the key combination that should spawn `xautolock -locknow`.
```prettyprint
- Ctrl+Alt+L to lock the screen
- Locker is set in ~/.xinitrc
bindsym Mod1+Control+l exec "xautolock -locknow"
```
----
## i3Bar
This is another host-specific configuration, since `bar {}` has host-specific options apart from just the i3status config. It also includes the `j4-make-config` theme placeholder, since the theme definitions for the bar are separate from the main config.
I'll only demonstrate the most complicated of my current i3bar configuration. The rest can be viewed on the git repo.
```prettyprint
bar {
status_command i3status -c ~/.config/i3/status/$HOSTNAME.config
tray_output primary
output eDP1 * Which display should i3bar be bound to?
- $i3-theme-bar
}
```
----
## i3Status
Most of the i3Status configuration is pretty standard, and is well documented by [the upstream docs](https://i3wm.org/i3status/manpage.html), so I'll only document the specific directives I crafted/modified myself
### Volume
This directive chooses ALSA by default, PulseAudio can be specified by adding `device = "pulse"` to the end of this directive.
```prettyprint
volume master {
format = "🔈%volume" * U+1F508
format_muted = "🔇" * U+1F507
}
```
### SPVPN
This is a simple pidfile watcher used with one of my [VPN](VPN.md) configurations that gets started with systemd.
```prettyprint
run_watch SPVPN {
pidfile = "/var/run/spvpn@*.pid"
}
```
----
## Nagbar
The nagbar is intensely annoying to encounter mainly because you can only use the mouse for interacting with it. It has been removed from my config altogether, and I plan on replacing it with dmenu in the future.

32
new/index.md Normal file
View File

@ -0,0 +1,32 @@
# Thurstylark's Knowledge Base
Half brain dump, half documentation practice.
### Projects
- [Vimwiki](Vimwiki.md) -- This very wiki, and how it's hosted
- [Cgit](Cgit.md) -- Configuration and hosting of https://git.thurstylark.com/
### Configuration/Dotfiles
- [Bashrc](Bashrc.md)
- [SSH](SSH.md)
- [Chrome Search Shortcuts](Chrome Search Shortcuts.md)
### Reference
- [Thurstylark-VPS](Thurstylark-VPS.md) -- All the services and little tweaks unique to my VPS
- [LetsEncrypt](LetsEncrypt.md) -- Usage of certbot, and relevant info for Apache configuration
- [Keyboard Mapping](Keyboard Mapping.md) -- Changing keyboard mapping at the hwdb level
- [Password-Store setup](Password-Store setup.md)
- [Formatting Cheat Sheet](Formatting Cheat Sheet.md)
### Misc.
- [Links Of Infamy](Links Of Infamy.md) -- A link dump of things I find truly amazing
- [Stupid Crestron Quirks](Stupid Crestron Quirks.md) -- Crestron can be stupid. Here are some examples
- [Ramblings](Ramblings.md) -- Non-technical musings, rants, or other such tomfoolery
- [Archive](Archive.md) -- Pages that aren't of much active use, but worth keeping around
### [Contact Info](contact)

48
new/vagst-testing.md Normal file
View File

@ -0,0 +1,48 @@
# VA GST Testing
## TODO
- [ ] Finish info gathering script
- [ ] Add test cases for 30FPS for existing cases
- [ ] Implement special groups
- [ ] Create parse script
- [ ] pyparsing
- [ ] general info
- [ ] data
- [ ] matplotlib
- [ ] Package va264enc for independent install
- [ ] Debian
- [ ] Arch
- [ ] Create netboot image
- [ ] Debian
- [ ] Arch
## Situations
- 1280x720 @30-@60 x1-x10
- 640x360 @30-@60 x1-x10
- Group 1
- 1280x720 @30 x1
- 1280x720 @30 x6
- Group 2
- 1280x720 @60 x1
- 1280x720 @60 x6
## Parser Output
- General info
- OS
- Kernel Version
- CPU generation
- Memory
- LibVA version
- VA-API version
- Gfx Driver version
- Render time per frame
- mean
- median
- mode
- max