Initial commit

This commit is contained in:
snow flurry 2022-08-05 22:16:17 -07:00
commit 4a7b2899b5
20 changed files with 2334 additions and 0 deletions

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
#pattern filter=crypt diff=crypt merge=crypt
base/.ssh/* filter=crypt diff=crypt merge=crypt

23
base/.config/mpv/mpv.conf Normal file
View file

@ -0,0 +1,23 @@
[default]
# autofit=100%x100%
# autofit-larger=90%x90%
[floaty]
# Attempt to use yt-dlp on older mpv (coughdebiancough)
config=no
focus=no
# For picom/fvwm to latch onto
x11-name="mpv-floaty"
alpha=yes
input-ipc-server="~/.tmp/floaty-mpv.sock"
ytdl-format=bestvideo[height<=?720][fps<=?30][vcodec!=?vp9]+bestaudio/best
script-opts="qs_scale=0.20"
# autofit=25%x25%
# autofit-larger=25%x25%
ontop=yes
geometry=-10-10
autosync=30
sub-back-color=0.0/0.0/0.0
cache=yes
demuxer-max-bytes=204800KiB
demuxer-readahead-secs=10

View file

@ -0,0 +1,119 @@
local mpopt = require('mp.options')
local initial_config = {}
local default_profile_filename = 'subs2srs'
local profiles_filename = 'subs2srs_profiles'
local config, profiles
local function is_empty(var)
return var == nil or var == '' or (type(var) == 'table' and next(var) == nil)
end
local function set_audio_format()
if config.audio_format == 'opus' then
config.audio_codec = 'libopus'
config.audio_extension = '.ogg'
else
config.audio_codec = 'libmp3lame'
config.audio_extension = '.mp3'
end
end
local function set_video_format()
if config.snapshot_format == 'webp' then
config.snapshot_extension = '.webp'
config.snapshot_codec = 'libwebp'
else
config.snapshot_extension = '.jpg'
config.snapshot_codec = 'mjpeg'
end
end
local function ensure_in_range(dimension)
config[dimension] = config[dimension] < 42 and -2 or config[dimension]
config[dimension] = config[dimension] > 640 and 640 or config[dimension]
end
local function conditionally_set_defaults(width, height, quality)
if config[width] < 1 and config[height] < 1 then
config[width] = -2
config[height] = 200
end
if config[quality] < 0 or config[quality] > 100 then
config[quality] = 15
end
end
local function check_image_settings()
ensure_in_range('snapshot_width')
ensure_in_range('snapshot_height')
conditionally_set_defaults('snapshot_width', 'snapshot_height', 'snapshot_quality')
end
local function validate_config()
set_audio_format()
set_video_format()
check_image_settings()
end
local function load_profile(profile_name)
if is_empty(profile_name) then
profile_name = profiles.active
if is_empty(profile_name) then
profile_name = default_profile_filename
end
end
mpopt.read_options(config, profile_name)
end
local function save_initial_config()
for key, value in pairs(config) do
initial_config[key] = value
end
end
local function restore_initial_config()
for key, value in pairs(initial_config) do
config[key] = value
end
end
local function next_profile()
local first, next, new
for profile in string.gmatch(profiles.profiles, '[^,]+') do
if not first then
first = profile
end
if profile == profiles.active then
next = true
elseif next then
next = false
new = profile
end
end
if next == true or not new then
new = first
end
profiles.active = new
restore_initial_config()
load_profile(profiles.active)
validate_config()
end
local function init(config_table, profiles_table)
config, profiles = config_table, profiles_table
-- 'subs2srs' is the main profile, it is always loaded.
-- 'active profile' overrides it afterwards.
mpopt.read_options(profiles, profiles_filename)
load_profile(default_profile_filename)
save_initial_config(config)
if profiles.active ~= default_profile_filename then
load_profile(profiles.active)
end
validate_config()
end
return {
init = init,
next_profile = next_profile,
}

View file

@ -0,0 +1,194 @@
local mp = require('mp')
local utils = require('mp.utils')
local _config, _store_fn, _os_temp_dir, _subprocess
local encoder
------------------------------------------------------------
-- utility functions
local pad_timings = function(padding, start_time, end_time)
local video_duration = mp.get_property_number('duration')
start_time = start_time - padding
end_time = end_time + padding
if start_time < 0 then
start_time = 0
end
if end_time > video_duration then
end_time = video_duration
end
return start_time, end_time
end
local get_active_track = function(track_type)
local track_list = mp.get_property_native('track-list')
for _, track in pairs(track_list) do
if track.type == track_type and track.selected == true then
return track
end
end
return nil
end
------------------------------------------------------------
-- ffmpeg encoder
local ffmpeg = {}
ffmpeg.prefix = { "ffmpeg", "-hide_banner", "-nostdin", "-y", "-loglevel", "quiet", "-sn", }
ffmpeg.prepend = function(args)
if next(args) ~= nil then
for i, value in ipairs(ffmpeg.prefix) do
table.insert(args, i, value)
end
end
return args
end
ffmpeg.make_snapshot_args = function(source_path, output_path, timestamp)
return ffmpeg.prepend {
'-an',
'-ss', tostring(timestamp),
'-i', source_path,
'-map_metadata', '-1',
'-vcodec', _config.snapshot_codec,
'-lossless', '0',
'-compression_level', '6',
'-qscale:v', tostring(_config.snapshot_quality),
'-vf', string.format('scale=%d:%d', _config.snapshot_width, _config.snapshot_height),
'-vframes', '1',
output_path
}
end
ffmpeg.make_audio_args = function(source_path, output_path, start_timestamp, end_timestamp)
local audio_track = get_active_track('audio')
local audio_track_id = audio_track['ff-index']
if audio_track and audio_track.external == true then
source_path = audio_track['external-filename']
audio_track_id = 'a'
end
return ffmpeg.prepend {
'-vn',
'-ss', tostring(start_timestamp),
'-to', tostring(end_timestamp),
'-i', source_path,
'-map_metadata', '-1',
'-map', string.format("0:%d", audio_track_id),
'-ac', '1',
'-codec:a', _config.audio_codec,
'-vbr', 'on',
'-compression_level', '10',
'-application', 'voip',
'-b:a', tostring(_config.audio_bitrate),
'-filter:a', string.format("volume=%.1f", _config.tie_volumes and mp.get_property_native('volume') / 100 or 1),
output_path
}
end
------------------------------------------------------------
-- mpv encoder
local mpv = {}
mpv.make_snapshot_args = function(source_path, output_path, timestamp)
return {
'mpv',
source_path,
'--loop-file=no',
'--audio=no',
'--no-ocopy-metadata',
'--no-sub',
'--frames=1',
'--ovcopts-add=lossless=0',
'--ovcopts-add=compression_level=6',
table.concat { '--ovc=', _config.snapshot_codec },
table.concat { '-start=', timestamp },
table.concat { '--ovcopts-add=quality=', tostring(_config.snapshot_quality) },
table.concat { '--vf-add=scale=', _config.snapshot_width, ':', _config.snapshot_height },
table.concat { '-o=', output_path }
}
end
mpv.make_audio_args = function(source_path, output_path, start_timestamp, end_timestamp)
local audio_track = get_active_track('audio')
local audio_track_id = mp.get_property("aid")
if audio_track and audio_track.external == true then
source_path = audio_track['external-filename']
audio_track_id = 'auto'
end
return {
'mpv',
source_path,
'--loop-file=no',
'--video=no',
'--no-ocopy-metadata',
'--no-sub',
'--audio-channels=mono',
'--oacopts-add=vbr=on',
'--oacopts-add=application=voip',
'--oacopts-add=compression_level=10',
table.concat { '--oac=', _config.audio_codec },
table.concat { '--start=', start_timestamp },
table.concat { '--end=', end_timestamp },
table.concat { '--aid=', audio_track_id },
table.concat { '--volume=', _config.tie_volumes and mp.get_property('volume') or '100' },
table.concat { '--oacopts-add=b=', _config.audio_bitrate },
table.concat { '-o=', output_path }
}
end
------------------------------------------------------------
-- main interface
local create_snapshot = function(timestamp, filename)
local source_path = mp.get_property("path")
local output_path = utils.join_path(_os_temp_dir(), filename)
local args = encoder.make_snapshot_args(source_path, output_path, timestamp)
local on_finish = function()
_store_fn(filename, output_path)
os.remove(output_path)
end
_subprocess(args, on_finish)
end
local create_audio = function(start_timestamp, end_timestamp, filename, padding)
local source_path = mp.get_property("path")
local output_path = utils.join_path(_os_temp_dir(), filename)
if padding > 0 then
start_timestamp, end_timestamp = pad_timings(padding, start_timestamp, end_timestamp)
end
local args = encoder.make_audio_args(source_path, output_path, start_timestamp, end_timestamp)
for arg in string.gmatch(_config.use_ffmpeg and _config.ffmpeg_audio_args or _config.mpv_audio_args, "%S+") do
-- Prepend before output path
table.insert(args, #args, arg)
end
local on_finish = function()
_store_fn(filename, output_path)
os.remove(output_path)
end
_subprocess(args, on_finish)
end
local init = function(config, store_fn, os_temp_dir, subprocess)
_config = config
_store_fn = store_fn
_os_temp_dir = os_temp_dir
_subprocess = subprocess
encoder = config.use_ffmpeg and ffmpeg or mpv
end
return {
init = init,
create_snapshot = create_snapshot,
create_audio = create_audio,
}

View file

@ -0,0 +1,85 @@
--[[
A helper class for styling OSD messages
http://docs.aegisub.org/3.2/ASS_Tags/
Copyright (C) 2021 Ren Tatsumoto
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
]]
local OSD = {}
OSD.__index = OSD
function OSD:new()
return setmetatable({ messages = {} }, self)
end
function OSD:append(s)
table.insert(self.messages, s)
return self
end
function OSD:newline()
return self:append([[\N]])
end
function OSD:tab()
return self:append([[\h\h\h\h]])
end
function OSD:size(size)
return self:append('{\\fs'):append(size):append('}')
end
function OSD:align(number)
return self:append('{\\an'):append(number):append('}')
end
function OSD:get_text()
return table.concat(self.messages)
end
function OSD:color(code)
return self:append('{\\1c&H')
:append(code:sub(5, 6))
:append(code:sub(3, 4))
:append(code:sub(1, 2))
:append('&}')
end
function OSD:text(text)
return self:append(text)
end
function OSD:bold(s)
return self:append('{\\b1}'):append(s):append('{\\b0}')
end
function OSD:italics(s)
return self:append('{\\i1}'):append(s):append('{\\i0}')
end
function OSD:submenu(text)
return self:color('ffe1d0'):bold(text):color('ffffff')
end
function OSD:item(text)
return self:color('fef6dd'):bold(text):color('ffffff')
end
function OSD:red(text)
return self:color('ff0000'):bold(text):color('ffffff')
end
return OSD

View file

@ -0,0 +1,111 @@
-- -----------------------------------------------------------
--
-- QUICK-SCALE.LUA
-- Version: 1.1
-- Author: VideoPlayerCode
-- URL: https://github.com/VideoPlayerCode/mpv-tools
--
-- Description:
--
-- Quickly scale the video player to a target size,
-- with full control over target scale and max scale.
-- Helps you effortlessly resize a video to fit on your
-- desktop, or any other video dimensions you need!
--
-- History:
--
-- 1.0: Initial release.
-- 1.1: Do nothing if mpv is in fullscreen mode.
--
-- -----------------------------------------------------------
--
-- Parameters:
-- targetwidth = How wide you want the target area to be.
-- targetheight = How tall you want the target area to be.
-- targetscale = If this is 1, we use your target width/height
-- as-is, but if it's another value then we scale your provided
-- target size by that amount. This parameter is great if you want
-- a video to be a certain percentage of your desktop resolution.
-- In that case, just set targetwidth/targetheight to your
-- desktop resolution, and set this targetscale to the percentage
-- of your desktop that you want to use for the video, such as
-- "0.25" to resize the video to 25% of your desktop resolution.
-- maxvideoscale = If this is a positive number (anything above 0),
-- then the final video scale cannot exceed this number.
-- This is useful if you for example set the target to 25%
-- of your desktop resolution. If the video is smaller than that,
-- then it would be scaled up (enlarged) to the size of the target.
-- To control that behavior, simply set this parameter.
-- Here are some examples:
-- -1, 0, or any other non-positive number: We'll enlarge
-- too-small videos and shrink too-large videos. Small videos
-- will be enlarged as much as needed to match target size.
-- 1: Video will only be allowed to enlarge to 100% of its natural size.
-- This means that small videos won't become big and blurry.
-- 1.5: Video will only be allowed to enlarge to 150% of its natural size.
local options = require 'mp.options'
function quick_scale(targetwidth, targetheight, targetscale, maxvideoscale)
-- Don't attempt to scale the fullscreen window.
if (mp.get_property_bool("fullscreen", false)) then
return nil -- abort
end
-- Check parameter existence.
if (targetwidth == nil or targetheight == nil
or targetscale == nil or maxvideoscale == nil)
then
mp.osd_message("Quick_Scale: Missing parameters")
return nil -- abort
end
-- Ensure that the incoming strings are valid numbers.
targetwidth = tonumber(targetwidth)
targetheight = tonumber(targetheight)
targetscale = tonumber(targetscale)
maxvideoscale = tonumber(maxvideoscale)
if (targetwidth == nil or targetheight == nil
or targetscale == nil or maxvideoscale == nil)
then
mp.osd_message("Quick_Scale: Non-numeric parameters")
return nil -- abort
end
-- If the target scale isn't 1 (100%), we'll re-calculate target size.
if (targetscale ~= 1) then
targetwidth = targetwidth * targetscale
targetheight = targetheight * targetscale
end
-- Find smallest video scale that fits target size in both width and height.
-- This only looks at video and doesn't take window borders into account!
widthscale = targetwidth / mp.get_property("width")
heightscale = targetheight / mp.get_property("height")
local scale = (widthscale < heightscale and widthscale or heightscale)
-- If we arrived at a target width/height that is larger than the video's
-- natural "100%" scale, then we may want to limit it to a maximum amount.
if (maxvideoscale > 0 and scale > maxvideoscale) then
scale = maxvideoscale
end
-- Apply the new video scale.
mp.set_property_number("window-scale", scale)
end
-- Bind this via input.conf. Examples:
-- To fit a video to 100% of a 1680x1050 desktop size, with unlimited video enlarging:
-- Alt+9 script-message Quick_Scale "1680" "1050" "1" "-1"
-- To fit a video to 80% of a 1680x1050 desktop size, but disallowing the
-- video from becoming larger than 150% of its natural size:
-- Alt+9 script-message Quick_Scale "1680" "1050" "0.8" "1.5"
-- To fit a video to a 200x200 box, with unlimited video enlarging:
-- Alt+9 script-message Quick_Scale "200" "200" "1" "-1"
mp.register_script_message("Quick_Scale", quick_scale)
mp.register_event("file-loaded", function()
local scale = mp.get_opt("qs_scale")
if not (scale == nil) then
quick_scale("1920", "1080", scale, "1")
end
end)

File diff suppressed because it is too large Load diff

8
base/.config/picom.conf Normal file
View file

@ -0,0 +1,8 @@
backend = "glx";
dbus = false;
vsync = true;
daemon = true;
opacity-rule = [
"90:class_i = 'mpv-floaty' && !focused"
];

5
base/.gitconfig Normal file
View file

@ -0,0 +1,5 @@
[user]
name = snow flurry
email = snow@datagirl.xyz
[init]
defaultBranch = trunk

121
base/.mkshrc Normal file
View file

@ -0,0 +1,121 @@
# (mk)shrc
if [ -f /etc/shrc ]; then
. /etc/shrc
fi
export EDITOR=vim
# Force 256color term for screen
if [ "$TERM" = "screen" ] ; then
TERM="screen-256color"
export TERM
fi
export LANG=
export LC_ALL=en_US.UTF-8
## Ripped from a custom /etc/shrc, not very useful here
UID="$(id -u)"
if [ "$UID" -eq "0" ] ; then
PROMPT="#"
USER_COLOR=''
else
PROMPT="$"
USER_COLOR=''
fi
get_ps1() {
rv=$?
if [ "$rv" -ne "0" -a "$rv" -ne "130" ] ; then
print -n "$rv | "
fi
if [ -n "$SSH_TTY" ] ; then
print -n "[SSH] "
fi
print -n "${USER_COLOR}${HOST%%.*}:";
if [[ "${PWD#$HOME}" != "$PWD" ]] ; then
print -n "~${PWD#$HOME}"
else
print -n "$PWD"
fi
print -n "${USER_COLOR} ${PROMPT} "
}
case "$-" in *i*)
# interactive mode settings go here
if /bin/test -z "${HOST}"; then
HOST="$(hostname)"
fi
PS1='$(get_ps1)'
set -o emacs
# This file is used by shells that might not support
# set -o tabcomplete, so check before trying to use it.
( set -o tabcomplete 2>/dev/null ) && set -o tabcomplete
alias gpg='gpg2'
alias ctop='xclip -selection clipboard -out | xclip -selection primary -in'
alias ptoc='xclip -selection primary -out | xclip -selection primary -in'
alias mutt='neomutt'
alias define='dict'
# Hack to bubble up profile, see bin/tmux-shim
alias tmux="$HOME/bin/tmux-shim"
if [ "${KSH_VERSION:-notksh}" != "notksh" ] ; then
[[ "${KSH_VERSION}" == *"MIRBSD KSH"* ]] && bind '^L=clear-screen'
else
hn="$(hostname)"
PS1='${hn}:${PWD} \$ '
fi
calc()
{
echo "$@" | bc
}
nconv()
{
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
echo "usage: nconv [from-base] [to-base] [num]" >&2
return 1
fi
echo "obase=$2; ibase=$1; $3" | bc
}
;;
esac
if [ -f "$HOME/.cargo/env" ] ; then
. $HOME/.cargo/env
fi
# Python packages go here
if [ -d "$HOME/.local/bin" ] ; then
PATH="$HOME/.local/bin:$PATH"
fi
# Homebrew (macOS)
if [ -d "/opt/homebrew" ] ; then
PATH="/opt/homebrew/bin:/opt/homebrew/sbin:/sbin:/usr/sbin:$PATH"
HOMEBREW_CASK_OPTS="--appdir=~/Applications"
export HOMEBREW_CASK_OPTS
# x86 brew hack
if [ -d "$HOME/.x86_64/homebrew" ] ; then
brew86() {
PATH="$HOME/.x86_64/homebrew/bin:$PATH" arch -x86_64 $HOME/.x86_64/homebrew/bin/brew "$@"
}
fi
fi
# Flutter
if [ -d "$HOME/.opt/flutter" ] ; then
PATH="$HOME/.opt/flutter/bin:$PATH"
fi
# Android SDK (for VMs)
if [ -d "$HOME/Library/Android/sdk" ] ; then
export ANDROID_SDK_ROOT=$HOME/Library/Android/sdk
PATH="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/emulator:$ANDROID_SDK_ROOT/platform-tools:$PATH"
fi
export PATH

36
base/.ssh/config Normal file
View file

@ -0,0 +1,36 @@
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
PQAYUQlBz14wpRwuqgA6Ng==

6
base/.tmux.conf Normal file
View file

@ -0,0 +1,6 @@
new-session -n $HOST
source '.tmux/source.conf'
# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run -b '~/.tmux/plugins/tpm/tpm'

76
base/.tmux/source.conf Normal file
View file

@ -0,0 +1,76 @@
# Used for reloading config
set -g default-terminal screen-256color
unbind C-b
set-option -g prefix C-a
### Keybinds
# prefix
bind-key C-a send-prefix
# pane splitting
bind | split-window -h
bind - split-window -v
unbind '"'
unbind %
# reload tmux.conf
bind r source-file ~/.tmux/source.conf
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
bind R move-window -r
set -g mouse off
set-option -g allow-rename off
set-window-option -g mode-keys vi
bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "xclip -selection clipboard -i"
### Theming
set-option -g visual-activity off
set-option -g visual-bell both
set-option -g visual-silence off
set-window-option -g monitor-activity off
set-option -g bell-action any
setw -g clock-mode-colour colour5
setw -g mode-style bold,fg=colour1,bg=colour18
# panes
set -g pane-border-style bg=colour0,fg=colour54
set -g pane-active-border-style bg=colour0,fg=colour54
# statusbar
set -g status-position top
set -g status-justify left
set -g status-style bg=colour234,fg=colour248,dim
set -g status-left '#[fg=colour5,nodim]#h#[fg=colour248,dim] :: '
set -g status-right '#[fg=colour233,bg=colour242,bold] %d/%m #[fg=colour233,bg=colour246,bold] %H:%M:%S '
set -g status-right-length 50
set -g status-left-length 20
setw -g window-status-current-style fg=colour239,bg=colour243,bold
setw -g window-status-current-format ' #I:#[fg=colour255]#W#[fg=colour237]#F '
setw -g window-status-style fg=colour248,bg=colour236,none
setw -g window-status-format ' #I#[fg=colour242]:#[fg=colour250]#W#[fg=colour243]#F '
setw -g window-status-bell-style bold,fg=colour255,bg=colour1
setw -g window-style fg=colour8
setw -g window-active-style fg=colour7
# messages
set -g message-style bold,fg=colour242,bg=colour16
# vim compat
set -sg escape-time 10
# plugins
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'

45
base/bin/clipify Executable file
View file

@ -0,0 +1,45 @@
#!/usr/bin/env mksh
# Make a video clip from a larger video
usage() {
if [ -n "$1" ] ; then
echo "$1" >&2
fi
echo "usage: $0 to-clip start-time end-time clipname" >&2
echo "example:" >&2
echo " $0 ToClip.mkv 00:15:00.0 00:15:30.0 sickflips" >&2
exit 1
}
die() {
echo "err: $1" >&2
exit 1
}
origfile=$1
starttime=$2
endtime=$3
clipname=$4
if [ -z "$origfile" ] || [ -z "$starttime" ] || [ -z "$endtime" ] || [ -z "$clipname" ]
then
usage
fi
if ! [ -f "$origfile" ] ; then
usage "$origfile doesn't exist!"
fi
duration=$(( $(gdate -d "$endtime" "+%s") - $(gdate -d "$starttime" "+%s") )) || usage "Couldn't get clip duration"
[ "$duration" -gt 0 ] || usage "end-time should be after start-time"
strduration="$(gdate -ud "@${duration}" "+%H:%M:%S.%N" | cut -c-10)"
if [ -n "$SUBSFILE" ] ; then
ffmpeg -ss "$starttime" -copyts -i "$origfile" -ss "$starttime" -t "$strduration" -c:v libx264 -c:a mp3 -ac 2 -vf subtitles="$SUBSFILE" "$clipname.mp4"
else
ffmpeg -ss "$starttime" -i "$origfile" -t "$strduration" \
-c:v libx264 -c:a mp3 $FFMPEG_PARAM -ac 2 \
"$clipname.mp4"
fi

31
base/bin/ff2mpv Executable file
View file

@ -0,0 +1,31 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
# Modified from original ff2mpv to use floaty-mpv instead of
# standard mpv.
require "json"
len = $stdin.read(4).unpack1("L")
data = JSON.parse($stdin.read(len))
url = data["url"]
args = %w[--no-terminal]
# HACK(ww): On macOS, graphical applications inherit their path from `launchd`
# rather than the default path list in `/etc/paths`. `launchd` doesn't include
# `/usr/local/bin` in its default list, which means that any installations
# of MPV and/or youtube-dl under that prefix aren't visible when spawning
# from, say, Firefox. The real fix is to modify `launchd.conf`, but that's
# invasive and maybe not what users want in the general case.
# Hence this nasty hack.
# ENV["PATH"] = "/usr/local/bin:#{ENV['PATH']}" if RUBY_PLATFORM =~ /darwin/
pid = nil
if (/darwin/ =~ RUBY_PLATFORM) != nil then
pid = spawn "/Users/flurry/bin/iinado", url, in: :close, out: :close, err: :close
else
pid = spawn "/home/flurry/bin/floaty-mpv", url, in: :close, out: "/dev/null", err: "/home/flurry/.tmp/fmpv.log"
end
Process.detach pid

9
base/bin/genpw Executable file
View file

@ -0,0 +1,9 @@
#!/bin/sh
if [ -z "$1" ] ; then
echo "usage: $0 [length]" >&2
exit 1
fi
LC_ALL=C tr -dc '[:alnum:]' </dev/urandom | \
fold -w$1 | head -n1

4
base/bin/pkg_find Executable file
View file

@ -0,0 +1,4 @@
#!/bin/sh
# Find a package in pkgsrc
find /usr/pkgsrc -mindepth 2 -maxdepth 2 -type d -name "*$1*" | sed 's,^/usr/pkgsrc/,,'

28
base/bin/tmux-shim Executable file
View file

@ -0,0 +1,28 @@
#!/bin/ksh
# Workaround for some tmux silliness
# TODO: way too hacky
REAL_TMUX=${REAL_TMUX:-/usr/pkg/bin/tmux}
if [ ! -x "$REAL_TMUX" ] ; then
REAL_TMUX="$(which tmux)"
fi
if [ -n "$1" ] ; then
$REAL_TMUX "$@"
exit
fi
myhost="$(hostname)"
SESSION_NAME="${myhost%%.*}"
if $REAL_TMUX ls -F "#{session_name}" | grep -q "^${SESSION_NAME}\$" ; then
# set necessary session variables
for envvar in DBUS_SESSION_BUS_ADDRESS XDG_RUNTIME_DIR XDG_SEAT XDG_SESSION_CLASS XDG_SESSION_COOKIE XDG_SESSION_ID XDG_SESSION_TYPE XDG_VTNR ; do
nameref val=$envvar
[ -n "$val" ] && $REAL_TMUX setenv -t $SESSION_NAME $envvar "$val"
done
$REAL_TMUX attach -t $SESSION_NAME
else
$REAL_TMUX new -s $SESSION_NAME
fi

13
base/bin/ttc2ttf Executable file
View file

@ -0,0 +1,13 @@
#!/usr/bin/env fontforge
Print("Opening " + $1);
Print(FontsInFile($1));
nfiles = SizeOf(FontsInFile($1));
i = 0;
while (i < nfiles)
Open($1 + "(" + i + ")", 4);
Print("Saving " + $1:r + "-" + i + ".ttf");
Generate($1:r + "-" + i + ".ttf");
++i;
endloop
Quit(0);

62
base/bin/upfile Executable file
View file

@ -0,0 +1,62 @@
#!/bin/ksh
usage() {
echo "usage: $0 <file to upload>" >&2
}
if [ "$1" = "-x" ] ; then
with_message=1
shift
fi
CURL="curl"
if [ "$1" = "-q" ] ; then
with_interop=1
CURL="$CURL -sS"
shift
fi
CREDFILE="$HOME/.config/upfile/credentials"
if [ ! -r "$CREDFILE" ] ; then
echo "err: can't find credentials file. must be at $CREDFILE" >&2
exit 1
fi
upload_file() {
up_file="$1"
if [ -z "$up_file" ] ; then
usage
return 2
fi
if [ ! -f "$up_file" ] ; then
echo "err: file $up_file doesn't exist?" >&2
return 1
fi
res=$($CURL -f -X POST -F "sendfile=@\"$up_file\"" \
-u "$(cat "$CREDFILE")" \
https://f.2ki.xyz/cgi-bin/aperture.cgi)
if [ $? -ne 0 ] ; then
echo "Upload failed: $res" >&2
return 1
fi
CLIP_URL="$res"
}
upload_file "$1" || exit $?
echo -n "$CLIP_URL" | xclip -selection primary
echo -n "$CLIP_URL" | xclip -selection clipboard
if [ -n "$with_interop" ] ; then
echo "$CLIP_URL"
elif [ -n "$with_message" ]; then
notify-send "File uploaded" "Uploaded to $CLIP_URL. URL copied to clipboard."
else
echo "Uploaded to $CLIP_URL. Copied to clipboard."
fi