Compare commits
22 Commits
1bc335aed0
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89ed2acf2b | ||
|
|
fc11a2202d | ||
|
|
f3be14b0ed | ||
|
|
ea7f187c8b | ||
|
|
5be67afa54 | ||
|
|
3970f9bca7 | ||
|
|
f46000649c | ||
| 9c819d6325 | |||
| a23e71ab5a | |||
| ce836a568c | |||
| 23d7c0d52f | |||
| 129f8ab159 | |||
| 4471fe0bb9 | |||
| 8d699bccd6 | |||
| a99ca6431e | |||
| d5fd5b8c38 | |||
| 979d769bfb | |||
| 08ece46452 | |||
| 4c78b77e60 | |||
| d3b21fb2f1 | |||
| ce12e90225 | |||
| 5c8ad98bb5 |
14
.FreeCAD/toolbits/Bit/125_Drill.fctb
Normal file
14
.FreeCAD/toolbits/Bit/125_Drill.fctb
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "1/8th Drill Bit",
|
||||
"shape": "drill.fcstd",
|
||||
"parameter": {
|
||||
"Chipload": "0.000 in",
|
||||
"Diameter": "0.125 in",
|
||||
"Flutes": "0",
|
||||
"Length": "0.750 in",
|
||||
"Material": "HSS",
|
||||
"TipAngle": "135.000 \u00b0"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
16
.FreeCAD/toolbits/Bit/316_Endmill.fctb
Normal file
16
.FreeCAD/toolbits/Bit/316_Endmill.fctb
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "3/16 Endmill",
|
||||
"shape": "endmill.fcstd",
|
||||
"parameter": {
|
||||
"Chipload": "0.000 in",
|
||||
"CuttingEdgeHeight": "0.600 \"",
|
||||
"Diameter": "0.187 \"",
|
||||
"Flutes": "0",
|
||||
"Length": "1.500 \"",
|
||||
"Material": "HSS",
|
||||
"ShankDiameter": "0.315 \"",
|
||||
"SpindleDirection": "Forward"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
14
.FreeCAD/toolbits/Bit/45degree_chamfer.fctb
Normal file
14
.FreeCAD/toolbits/Bit/45degree_chamfer.fctb
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "45 Deg. Chamfer",
|
||||
"shape": "chamfer.fcstd",
|
||||
"parameter": {
|
||||
"CuttingEdgeAngle": "45.0000 \u00b0",
|
||||
"CuttingEdgeHeight": "6.3500 mm",
|
||||
"Diameter": "12.3323 mm",
|
||||
"Length": "30.0000 mm",
|
||||
"ShankDiameter": "6.3500 mm",
|
||||
"TipDiameter": "5.0000 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
14
.FreeCAD/toolbits/Bit/5mm-thread-cutter.fctb
Normal file
14
.FreeCAD/toolbits/Bit/5mm-thread-cutter.fctb
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "5mm-thread-cutter",
|
||||
"shape": "thread-mill.fcstd",
|
||||
"parameter": {
|
||||
"Crest": "0.10 mm",
|
||||
"Diameter": "5.00 mm",
|
||||
"Length": "50.00 mm",
|
||||
"NeckDiameter": "3.00 mm",
|
||||
"NeckLength": "20.00 mm",
|
||||
"ShankDiameter": "5.00 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
11
.FreeCAD/toolbits/Bit/5mm_Drill.fctb
Normal file
11
.FreeCAD/toolbits/Bit/5mm_Drill.fctb
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "5mm Drill",
|
||||
"shape": "drill.fcstd",
|
||||
"parameter": {
|
||||
"Diameter": "5.0000 mm",
|
||||
"Length": "50.0000 mm",
|
||||
"TipAngle": "119.0000 \u00b0"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
12
.FreeCAD/toolbits/Bit/5mm_Endmill.fctb
Normal file
12
.FreeCAD/toolbits/Bit/5mm_Endmill.fctb
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "5mm Endmill",
|
||||
"shape": "endmill.fcstd",
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "30.0000 mm",
|
||||
"Diameter": "5.0000 mm",
|
||||
"Length": "50.0000 mm",
|
||||
"ShankDiameter": "3.0000 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
14
.FreeCAD/toolbits/Bit/60degree_Vbit.fctb
Normal file
14
.FreeCAD/toolbits/Bit/60degree_Vbit.fctb
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "60 Deg. V-Bit",
|
||||
"shape": "v-bit.fcstd",
|
||||
"parameter": {
|
||||
"CuttingEdgeAngle": "60.0000 \u00b0",
|
||||
"Diameter": "10.0000 mm",
|
||||
"CuttingEdgeHeight": "1.0000 mm",
|
||||
"TipDiameter": "1.0000 mm",
|
||||
"Length": "20.0000 mm",
|
||||
"ShankDiameter": "5.0000 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
12
.FreeCAD/toolbits/Bit/6mm_Ball_End.fctb
Normal file
12
.FreeCAD/toolbits/Bit/6mm_Ball_End.fctb
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "6mm Ball End",
|
||||
"shape": "ballend.fcstd",
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "40.0000 mm",
|
||||
"Diameter": "6.0000 mm",
|
||||
"Length": "50.0000 mm",
|
||||
"ShankDiameter": "3.0000 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
13
.FreeCAD/toolbits/Bit/6mm_Bullnose.fctb
Normal file
13
.FreeCAD/toolbits/Bit/6mm_Bullnose.fctb
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "6 mm Bull Nose",
|
||||
"shape": "bullnose.fcstd",
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "40.0000 mm",
|
||||
"Diameter": "6.0000 mm",
|
||||
"FlatRadius": "1.5000 mm",
|
||||
"Length": "50.0000 mm",
|
||||
"ShankDiameter": "3.0000 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
11
.FreeCAD/toolbits/Bit/probe.fctb
Normal file
11
.FreeCAD/toolbits/Bit/probe.fctb
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "Probe",
|
||||
"shape": "probe.fcstd",
|
||||
"parameter": {
|
||||
"Diameter": "6.0000 mm",
|
||||
"Length": "50.0000 mm",
|
||||
"ShaftDiameter": "4.0000 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
16
.FreeCAD/toolbits/Bit/singleFlute8th_Endmill.fctb
Normal file
16
.FreeCAD/toolbits/Bit/singleFlute8th_Endmill.fctb
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "Single Flute 1/8th inch endmill",
|
||||
"shape": "endmill.fcstd",
|
||||
"parameter": {
|
||||
"Chipload": "0.000 in",
|
||||
"CuttingEdgeHeight": "0.600 \"",
|
||||
"Diameter": "0.125 \"",
|
||||
"Flutes": "0",
|
||||
"Length": "1.000 \"",
|
||||
"Material": "HSS",
|
||||
"ShankDiameter": "0.315 \"",
|
||||
"SpindleDirection": "Forward"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
14
.FreeCAD/toolbits/Bit/slittingsaw.fctb
Normal file
14
.FreeCAD/toolbits/Bit/slittingsaw.fctb
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "Slitting Saw",
|
||||
"shape": "slittingsaw.fcstd",
|
||||
"parameter": {
|
||||
"BladeThickness": "3.0000 mm",
|
||||
"CapHeight": "3.0000 mm",
|
||||
"CapDiameter": "8.0000 mm",
|
||||
"Diameter": "76.2000 mm",
|
||||
"Length": "50.0000 mm",
|
||||
"ShankDiameter": "19.0500 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
41
.FreeCAD/toolbits/Library/Default.fctl
Normal file
41
.FreeCAD/toolbits/Library/Default.fctl
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"tools": [
|
||||
{
|
||||
"nr": 1,
|
||||
"path": "5mm_Endmill.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 2,
|
||||
"path": "5mm_Drill.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 3,
|
||||
"path": "6mm_Ball_End.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 4,
|
||||
"path": "6mm_Bullnose.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 5,
|
||||
"path": "60degree_Vbit.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 6,
|
||||
"path": "45degree_chamfer.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 7,
|
||||
"path": "slittingsaw.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 8,
|
||||
"path": "probe.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 9,
|
||||
"path": "5mm-thread-cutter.fctb"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
13
.FreeCAD/toolbits/Library/Tidal Force.fctl
Normal file
13
.FreeCAD/toolbits/Library/Tidal Force.fctl
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"tools": [
|
||||
{
|
||||
"nr": 1,
|
||||
"path": "125_Drill.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 2,
|
||||
"path": "singleFlute8th_Endmill.fctb"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
88
.FreeCAD/toolbits/README.md
Normal file
88
.FreeCAD/toolbits/README.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Tools
|
||||
|
||||
Each tool is stored as a JSON file which has the shape's path and values for all attributes of the shape.
|
||||
It also includes all additional parameters and their values.
|
||||
|
||||
Storing a tool as a JSON file sounds great but eliminates the option of an accurate thumbnail. On the other hand,
|
||||
storing each tool as a `*.fcstd` file requires more space and does not allow for generating tools. If one has an
|
||||
extensive tool aresenal they might want to script the generation of tools which is easily done for a `*.json` file but
|
||||
practically impossible for `*.fcstd` files.
|
||||
|
||||
When a tool is instantiated in a job the PDN body is created from the shape and the attributes and constraints are set
|
||||
according to the values from the JSON file. All additional parameters are created as properties on the object. This
|
||||
provides the correct shape and dimensions which can be used to generate a point cloud or mesh for advanced
|
||||
algorithms (and potentially simulation).
|
||||
|
||||
# Tool Libraries
|
||||
|
||||
Due to each tool being stored in its own file and the storage/organization of those files being quite flexible the
|
||||
importance of a tool library for organisational purposes is quite diminished. The user is free to organise their tools
|
||||
in whichever directory hierarchy they see fit and can also name them as best fits their use and organisation. A
|
||||
_tool library_ is nevertheless a great representation for a physical grouping of tools, such as in an automatic tool
|
||||
changer.
|
||||
|
||||
A tool library is a (JSON) file with a mapping of tool id to the path of the tool file. As a consequence each tool
|
||||
can be in multiple libraries and doesn't have an `id` of it's own. The `id` is a property of the library.
|
||||
|
||||
If a tool from a tool library (or an entire tool library) is added to a job it retains its `id` from the library as a
|
||||
property. Adding a tool bit directly rsults in the tool getting the next free id assigned.
|
||||
|
||||
# Tool Controllers
|
||||
|
||||
They largely stay the same as they are today. As an additional feature it should be possible to _copy_ a TC, which
|
||||
allows for easy feed/speed changes for the same tool.
|
||||
|
||||
Above requirement highlights one change though, that the `id` should be a property of the Bit, and not of the TC.
|
||||
There are two requirements that are currently mapped to a single `id`. There needs to be an identification of which
|
||||
TC is being used by a certain op, and which tool number to use for a `M6` command.
|
||||
|
||||
# Paths and Extensibility
|
||||
|
||||
The following directory structure is used for supplied (shipped with FreeCAD) tools:
|
||||
```
|
||||
Tools
|
||||
+ Bit
|
||||
+ Library
|
||||
+ Shape
|
||||
```
|
||||
|
||||
Strictly speaking a user is free to store their tools wherever they want and however they want. By default the file
|
||||
dialog will open the corresponding directory (depending on context), or whichever directory the user opened last.
|
||||
|
||||
Above directory structure with the most common default tools shipped with FreeCAD should be installed analogous to
|
||||
TechDraw's templates.
|
||||
|
||||
## How to create a new tool
|
||||
|
||||
1. Set the tool's Label, this will show up in the object tree
|
||||
1. Select a tool shape from the existing shape files. If your tool doesn't exist, you'll have to create a new shape,
|
||||
see below for details.
|
||||
1. Each tool bit shape has its own set of parameters, fill them with the tool's values.
|
||||
1. Select additional parameters
|
||||
1. Save the tool under path/file that makes sense to you
|
||||
|
||||
|
||||
## How to create a new tool bit Shape
|
||||
|
||||
The shape file for a tool bit is expected to contain a PD body which represents the tool as a 3d solid. The PD body
|
||||
should be parametric based on a PropertyBag object so that, when the properties of the PropertyBag are changed the
|
||||
solid is updated to the correct representation.
|
||||
|
||||
1. Create a new FreeCAD document
|
||||
1. Open the `PartDesign` workbench, create a body and give the body a label you want to show up in the bit selection.
|
||||
1. Open the Path workbench and (with the PD body selected) create a PropertyBag,
|
||||
menu 'Path' -> 'Utils' -> 'Property Bag'
|
||||
* this creates a PropertyBag object inside the Body (assuming it was selected)
|
||||
* add properties to which define the tool bit's shape and put those into the group 'Shape'
|
||||
* add any other properties to the bag which might be useful for the tool bit
|
||||
1. Construct the body of the tool bit and assign expressions referencing properties from the PropertyBag (in the
|
||||
`Shape` Group) for all constraints.
|
||||
* Position the tip of the tool bit on the origin (0,0)
|
||||
1. Save the document as a new file in the Shape directory
|
||||
* Before saving the document make sure you have _Save Thumbnail_ selected, and _Add program logo_ deselected in
|
||||
FreeCAD's preferences.
|
||||
* Also make sure to switch to _Front View_ and _Fit content to screen_
|
||||
* Whatever you see when saving the document will end up being the visual representation of tool bits with this shape
|
||||
|
||||
Not that 'Shape' is the only property group which has special meaning for tool bits. All other property groups are
|
||||
copied verbatim to the ToolBit object when one is created.
|
||||
28
.config/nvim/init.vim
Normal file
28
.config/nvim/init.vim
Normal file
@@ -0,0 +1,28 @@
|
||||
set number
|
||||
syntax on
|
||||
set expandtab shiftwidth=4 tabstop=4
|
||||
set autoindent
|
||||
set clipboard=unnamedplus
|
||||
|
||||
" I want nvim using a venv for plugins and stuff
|
||||
let g:python3_host_prog = expand('~/.venvs/nvim/bin/python')
|
||||
|
||||
" Plugins with vim-plug
|
||||
call plug#begin('~/.vim/plugged')
|
||||
|
||||
Plug 'psf/black', { 'do': ':!pip install black' }
|
||||
Plug 'dense-analysis/ale' " For linting and format-on-save
|
||||
Plug 'vim-python/python-syntax' " Improved Python syntax highlighting
|
||||
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } " Fuzzy finder
|
||||
Plug 'junegunn/fzf.vim'
|
||||
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'} " Better syntax
|
||||
|
||||
call plug#end()
|
||||
|
||||
" Enable ALE for linting and formatting
|
||||
let g:ale_fix_on_save = 1
|
||||
let g:ale_linters = { 'python': ['flake8'] }
|
||||
let g:ale_fixers = { 'python': ['black'] }
|
||||
|
||||
" Keybindings
|
||||
nnoremap <leader>f :Files<CR> " Fuzzy file search
|
||||
2
.config/plasma-workspace/latex.sh
Executable file
2
.config/plasma-workspace/latex.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
# LaTeX Import path
|
||||
export TEXINPUTS=/home/joe/College/SNHU/LaTeX:$(kpsepath tex | tr ':' '\n' | head -n 1):
|
||||
@@ -1,24 +0,0 @@
|
||||
[/home/joe/.local/share/plasma-vault/Blackmail.enc]
|
||||
activities=
|
||||
backend=cryfs
|
||||
lastError=Unknown device (code: 1)
|
||||
lastStatus=2
|
||||
mountPoint=/home/joe/Vaults/Blackmail
|
||||
name=Blackmail
|
||||
offlineOnly=false
|
||||
|
||||
[/home/joe/.local/share/plasma-vault/NSFW.enc]
|
||||
activities=
|
||||
backend=cryfs
|
||||
lastError=Cannot create the mount point (code: 0)
|
||||
lastStatus=1
|
||||
mountPoint=/home/joe/Vaults/NSFW
|
||||
name=NSFW
|
||||
offlineOnly=false
|
||||
|
||||
[EncryptedDevices]
|
||||
/home/joe/.local/share/plasma-vault/Blackmail.enc=true
|
||||
/home/joe/.local/share/plasma-vault/NSFW.enc=true
|
||||
|
||||
[UI-notice]
|
||||
SkipNotice-cryfs-message=false
|
||||
14
.gitconfig
14
.gitconfig
@@ -1,5 +1,5 @@
|
||||
[user]
|
||||
email = kenwood364@gmail.com
|
||||
email = joe@kitsunehosting.net
|
||||
name = KenwoodFox
|
||||
signingkey = DD5E787D6C678F3F64
|
||||
[alias]
|
||||
@@ -14,6 +14,7 @@
|
||||
[global]
|
||||
[push]
|
||||
default = current
|
||||
autoSetupRemote = true
|
||||
[init]
|
||||
defaultBranch = main
|
||||
[pull]
|
||||
@@ -22,3 +23,14 @@
|
||||
autosetuprebase = always
|
||||
[safe]
|
||||
directory = /opt/flutter
|
||||
[protocol "file"]
|
||||
allow = always
|
||||
[filter "lfs"]
|
||||
required = true
|
||||
clean = git-lfs clean -- %f
|
||||
smudge = git-lfs smudge -- %f
|
||||
process = git-lfs filter-process
|
||||
[diff "fcinfo"]
|
||||
textconv = ~/.local/bin/fcinfo
|
||||
[core]
|
||||
hooksPath = /home/joe/.githooks
|
||||
|
||||
44
.githooks/pre-commit
Executable file
44
.githooks/pre-commit
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/bin/sh
|
||||
# Global pre-commit hook: print effective identity and ask to continue.
|
||||
# Set BYPASS_COMMIT_IDENTITY_CHECK=1 to skip (e.g., in CI).
|
||||
|
||||
[ -n "$BYPASS_COMMIT_IDENTITY_CHECK" ] && exit 0
|
||||
|
||||
# Resolve effective identity (prefer repo-local config, fall back to global)
|
||||
name="$(git config --get user.name)"
|
||||
[ -z "$name" ] && name="$(git config --global --get user.name)"
|
||||
email="$(git config --get user.email)"
|
||||
[ -z "$email" ] && email="$(git config --global --get user.email)"
|
||||
|
||||
branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo '?')"
|
||||
remote="$(git remote -v | awk '/\(push\)/{print $2; exit}' | sed 's#^https\?://##; s#git@##' )"
|
||||
|
||||
# Optional: block specific identities unless overridden
|
||||
# Add your alt(s) here, comma-separated (exact match on email or name).
|
||||
BLOCKED_EMAILS="${BLOCKED_EMAILS:-alt@example.com}"
|
||||
BLOCKED_NAMES="${BLOCKED_NAMES:-Alt Name}"
|
||||
|
||||
is_blocked() {
|
||||
needle="$1" haystack="$2"
|
||||
printf '%s' "$haystack" | tr ',' '\n' | grep -Fxq "$needle"
|
||||
}
|
||||
|
||||
printf '\n\033[1;33m⚠ Committing as:\033[0m \033[1m%s\033[0m <\033[1m%s\033[0m>\n' "$name" "$email"
|
||||
[ -n "$branch" ] && printf ' Branch: %s\n' "$branch"
|
||||
[ -n "$remote" ] && printf ' Remote: %s\n' "$remote"
|
||||
printf ' Double-check this is the right account.\n\n'
|
||||
|
||||
if is_blocked "$email" "$BLOCKED_EMAILS" || is_blocked "$name" "$BLOCKED_NAMES"; then
|
||||
printf '\033[1;31mBlocked identity detected.\033[0m Set BYPASS_COMMIT_IDENTITY_CHECK=1 to override just this commit.\n'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Interactive confirm (skip if no TTY, e.g., merge drivers)
|
||||
if [ -t 0 ]; then
|
||||
printf 'Continue with commit? [y/N] '
|
||||
read ans
|
||||
case "$ans" in
|
||||
y|Y) ;;
|
||||
*) echo "Commit aborted."; exit 1 ;;
|
||||
esac
|
||||
fi
|
||||
187
.local/bin/computer
Executable file
187
.local/bin/computer
Executable file
@@ -0,0 +1,187 @@
|
||||
#!/usr/bin/env python3
|
||||
# Joe wrote this :P
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
try:
|
||||
from rich.console import Console
|
||||
from rich.markdown import Markdown
|
||||
|
||||
RICH = True
|
||||
except ImportError:
|
||||
RICH = False
|
||||
|
||||
FAST_MODEL = "gemma3:4b"
|
||||
THINK_MODEL = "qwen3:4b"
|
||||
|
||||
ANSI_ESCAPE = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
|
||||
|
||||
SYSTEM_PROMPT = """
|
||||
You are Computer.
|
||||
|
||||
Rules:
|
||||
- Respond in under 100 words unless asked for detail.
|
||||
- Prefer direct answers.
|
||||
- Use technical language.
|
||||
- Do not apologize.
|
||||
- For Linux questions assume Arch Linux.
|
||||
- For electronics questions assume the user is an engineer.
|
||||
- If providing a command, put the command first.
|
||||
- Do not explain your reasoning unless explicitly asked.
|
||||
- Do not show chain-of-thought.
|
||||
- Give final answers only.
|
||||
""".strip()
|
||||
|
||||
|
||||
def ollama_base_url():
|
||||
host = os.environ.get("OLLAMA_HOST", "127.0.0.1:11434").strip()
|
||||
if host.startswith(("http://", "https://")):
|
||||
return host.rstrip("/")
|
||||
return f"http://{host}".rstrip("/")
|
||||
|
||||
|
||||
def strip_ansi(text):
|
||||
return ANSI_ESCAPE.sub("", text)
|
||||
|
||||
|
||||
def copy_to_clipboard(text):
|
||||
commands = [
|
||||
["wl-copy"],
|
||||
["xclip", "-selection", "clipboard"],
|
||||
["xsel", "--clipboard", "--input"],
|
||||
]
|
||||
|
||||
for cmd in commands:
|
||||
try:
|
||||
subprocess.run(
|
||||
cmd,
|
||||
input=text,
|
||||
text=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
check=True,
|
||||
)
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def run_ollama_api(model, prompt):
|
||||
url = f"{ollama_base_url()}/api/generate"
|
||||
payload = json.dumps(
|
||||
{
|
||||
"model": model,
|
||||
"prompt": prompt,
|
||||
"stream": False,
|
||||
}
|
||||
).encode()
|
||||
|
||||
req = urllib.request.Request(
|
||||
url,
|
||||
data=payload,
|
||||
headers={"Content-Type": "application/json"},
|
||||
method="POST",
|
||||
)
|
||||
|
||||
with urllib.request.urlopen(req, timeout=600) as resp:
|
||||
data = json.load(resp)
|
||||
|
||||
return strip_ansi(data.get("response", "")).strip()
|
||||
|
||||
|
||||
def run_ollama_cli(model, prompt):
|
||||
result = subprocess.run(
|
||||
["ollama", "run", model, prompt],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
err = (result.stderr or result.stdout or "ollama run failed").strip()
|
||||
raise RuntimeError(err)
|
||||
return strip_ansi(result.stdout).strip()
|
||||
|
||||
|
||||
def run_ollama(model, prompt):
|
||||
try:
|
||||
return run_ollama_api(model, prompt)
|
||||
except (urllib.error.URLError, TimeoutError, json.JSONDecodeError) as exc:
|
||||
print(f"computer: API unavailable ({exc}), using CLI", file=sys.stderr)
|
||||
return run_ollama_cli(model, prompt)
|
||||
|
||||
|
||||
def print_response(response, raw):
|
||||
if RICH and not raw:
|
||||
console = Console()
|
||||
console.print(Markdown(response))
|
||||
else:
|
||||
print(response)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="computer",
|
||||
description="Tiny local terminal AI",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--think",
|
||||
action="store_true",
|
||||
help="Use the larger reasoning model",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--copy",
|
||||
action="store_true",
|
||||
help="Copy response to clipboard",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--raw",
|
||||
action="store_true",
|
||||
help="Disable rich formatting",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"prompt",
|
||||
nargs="*",
|
||||
help="Prompt text",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
model = THINK_MODEL if args.think else FAST_MODEL
|
||||
|
||||
user_prompt = " ".join(args.prompt)
|
||||
|
||||
stdin_text = ""
|
||||
if not sys.stdin.isatty():
|
||||
stdin_text = sys.stdin.read()
|
||||
|
||||
prompt = f"{SYSTEM_PROMPT}\n\nUser:\n{user_prompt}"
|
||||
|
||||
if stdin_text.strip():
|
||||
prompt += f"\n\nInput:\n{stdin_text}"
|
||||
|
||||
try:
|
||||
response = run_ollama(model, prompt)
|
||||
except RuntimeError as exc:
|
||||
print(f"computer: {exc}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if args.copy:
|
||||
copy_to_clipboard(response)
|
||||
|
||||
print_response(response, args.raw)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
82
.local/bin/discompress
Executable file
82
.local/bin/discompress
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Re-encode a video to a target size in MB.
|
||||
# Example:
|
||||
# ./this_script.sh video.mp4 15
|
||||
|
||||
T_SIZE="$2" # target size in MB
|
||||
T_FILE="${1%.*}-$2MB.mp4" # filename out
|
||||
|
||||
# Original duration in seconds
|
||||
O_DUR=$(\
|
||||
ffprobe \
|
||||
-v error \
|
||||
-show_entries format=duration \
|
||||
-of csv=p=0 "$1")
|
||||
|
||||
# Original audio rate
|
||||
O_ARATE=$(\
|
||||
ffprobe \
|
||||
-v error \
|
||||
-select_streams a:0 \
|
||||
-show_entries stream=bit_rate \
|
||||
-of csv=p=0 "$1")
|
||||
|
||||
# Original audio rate in KiB/s
|
||||
O_ARATE=$(\
|
||||
awk \
|
||||
-v arate="$O_ARATE" \
|
||||
'BEGIN { printf "%.0f", (arate / 1024) }')
|
||||
|
||||
# Target size is required to be less than the size of the original audio stream
|
||||
T_MINSIZE=$(\
|
||||
awk \
|
||||
-v arate="$O_ARATE" \
|
||||
-v duration="$O_DUR" \
|
||||
'BEGIN { printf "%.2f", ( (arate * duration) / 8192 ) }')
|
||||
|
||||
# Equals 1 if target size is ok, 0 otherwise
|
||||
IS_MINSIZE=$(\
|
||||
awk \
|
||||
-v size="$T_SIZE" \
|
||||
-v minsize="$T_MINSIZE" \
|
||||
'BEGIN { print (minsize < size) }')
|
||||
|
||||
# Give useful information if size is too small
|
||||
if [[ $IS_MINSIZE -eq 0 ]]; then
|
||||
printf "%s\n" "Target size ${T_SIZE}MB is too small!" >&2
|
||||
printf "%s %s\n" "Try values larger than" "${T_MINSIZE}MB" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set target audio bitrate
|
||||
T_ARATE=$O_ARATE
|
||||
|
||||
|
||||
# Calculate target video rate - MB -> KiB/s
|
||||
T_VRATE=$(\
|
||||
awk \
|
||||
-v size="$T_SIZE" \
|
||||
-v duration="$O_DUR" \
|
||||
-v audio_rate="$O_ARATE" \
|
||||
'BEGIN { print ( ( size * 8192.0 ) / ( 1.048576 * duration ) - audio_rate) }')
|
||||
|
||||
# Perform the conversion
|
||||
ffmpeg \
|
||||
-y \
|
||||
-i "$1" \
|
||||
-c:v libx264 \
|
||||
-b:v "$T_VRATE"k \
|
||||
-pass 1 \
|
||||
-an \
|
||||
-f mp4 \
|
||||
/dev/null \
|
||||
&& \
|
||||
ffmpeg \
|
||||
-i "$1" \
|
||||
-c:v libx264 \
|
||||
-b:v "$T_VRATE"k \
|
||||
-pass 2 \
|
||||
-c:a aac \
|
||||
-b:a "$T_ARATE"k \
|
||||
$T_FILE
|
||||
293
.local/bin/fcinfo
Executable file
293
.local/bin/fcinfo
Executable file
@@ -0,0 +1,293 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# -*- coding: utf8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2015 Yorik van Havre <yorik@uncreated.net> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * 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 Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
__title__ = "FreeCAD File info utility"
|
||||
__author__ = "Yorik van Havre"
|
||||
__url__ = ["http://www.freecad.org"]
|
||||
__doc__ = """
|
||||
This utility prints information about a given FreeCAD file (*.FCStd)
|
||||
on screen, including document properties, number of included objects,
|
||||
object sizes and properties and values. Its main use is to compare
|
||||
two files and be able to see the differences in a text-based form.
|
||||
|
||||
If no option is used, fcinfo prints the document properties and a list
|
||||
of properties of each object found in the given file.
|
||||
|
||||
Usage:
|
||||
|
||||
fcinfo [options] myfile.FCStd
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help: Prints this help text
|
||||
-s, --short: Do not print object properties. Only one line
|
||||
per object is printed, including its size and SHA1.
|
||||
This is sufficient to see that an object has
|
||||
changed, but not what exactly has changed.
|
||||
-vs --veryshort: Only prints the document info, not objects info.
|
||||
This is sufficient to see if a file has changed, as
|
||||
its SHA1 code and timestamp will show it. But won't
|
||||
show details of what has changed.
|
||||
-g --gui: Adds visual properties too (if not using -s or -vs)
|
||||
|
||||
Git usage:
|
||||
|
||||
This script can be used as a textconv tool for git diff by
|
||||
configuring your git folder as follows:
|
||||
|
||||
1) add to .gitattributes (or ~/.gitattributes for user-wide):
|
||||
|
||||
*.fcstd diff=fcinfo
|
||||
|
||||
2) add to .git/config (or ~/.gitconfig for user-wide):
|
||||
|
||||
[diff "fcinfo"]
|
||||
textconv = /path/to/fcinfo
|
||||
|
||||
With this, when committing a .FCStd file with Git,
|
||||
'git diff' will show you the difference between the two
|
||||
texts obtained by fcinfo
|
||||
"""
|
||||
|
||||
|
||||
import sys
|
||||
import zipfile
|
||||
import xml.sax
|
||||
import os
|
||||
import hashlib
|
||||
import re
|
||||
|
||||
|
||||
class FreeCADFileHandler(xml.sax.ContentHandler):
|
||||
def __init__(self, zfile, short=0): # short: 0=normal, 1=short, 2=veryshort
|
||||
|
||||
xml.sax.ContentHandler.__init__(self)
|
||||
self.zfile = zfile
|
||||
self.obj = None
|
||||
self.prop = None
|
||||
self.count = "0"
|
||||
self.contents = {}
|
||||
self.short = short
|
||||
|
||||
def startElement(self, tag, attributes):
|
||||
|
||||
if tag == "Document":
|
||||
self.obj = tag
|
||||
self.contents = {}
|
||||
self.contents["ProgramVersion"] = attributes["ProgramVersion"]
|
||||
self.contents["FileVersion"] = attributes["FileVersion"]
|
||||
|
||||
elif tag == "Object":
|
||||
if "name" in attributes:
|
||||
name = self.clean(attributes["name"])
|
||||
self.obj = name
|
||||
if "type" in attributes:
|
||||
self.contents[name] = attributes["type"]
|
||||
|
||||
elif tag == "ViewProvider":
|
||||
if "name" in attributes:
|
||||
self.obj = self.clean(attributes["name"])
|
||||
|
||||
elif tag == "Part":
|
||||
if self.obj:
|
||||
r = self.zfile.read(attributes["file"])
|
||||
s = r.__sizeof__()
|
||||
if s < 1024:
|
||||
s = str(s) + "B"
|
||||
elif s > 1048576:
|
||||
s = str(s / 1048576) + "M"
|
||||
else:
|
||||
s = str(s / 1024) + "K"
|
||||
s += " " + str(hashlib.sha1(r).hexdigest()[:12])
|
||||
self.contents[self.obj] += " (" + s + ")"
|
||||
|
||||
elif tag == "Property":
|
||||
self.prop = None
|
||||
# skip "internal" properties, useless for a diff
|
||||
if attributes["name"] not in [
|
||||
"Symbol",
|
||||
"AttacherType",
|
||||
"MapMode",
|
||||
"MapPathParameter",
|
||||
"MapReversed",
|
||||
"AttachmentOffset",
|
||||
"SelectionStyle",
|
||||
"TightGrid",
|
||||
"GridSize",
|
||||
"GridSnap",
|
||||
"GridStyle",
|
||||
"Lighting",
|
||||
"Deviation",
|
||||
"AngularDeflection",
|
||||
"BoundingBox",
|
||||
"Selectable",
|
||||
"ShowGrid",
|
||||
]:
|
||||
self.prop = attributes["name"]
|
||||
|
||||
elif tag in ["String", "Uuid", "Float", "Integer", "Bool", "Link"]:
|
||||
if self.prop and ("value" in attributes):
|
||||
if self.obj == "Document":
|
||||
self.contents[self.prop] = attributes["value"]
|
||||
elif self.short == 0:
|
||||
if tag == "Float":
|
||||
self.contents[self.obj + "00000000::" + self.prop] = str(
|
||||
float(attributes["value"])
|
||||
)
|
||||
else:
|
||||
self.contents[self.obj + "00000000::" + self.prop] = attributes["value"]
|
||||
|
||||
elif tag in ["PropertyVector"]:
|
||||
if self.prop and self.obj and (self.short == 0):
|
||||
val = (
|
||||
"("
|
||||
+ str(float(attributes["valueX"]))
|
||||
+ ","
|
||||
+ str(float(attributes["valueY"]))
|
||||
+ ","
|
||||
+ str(float(attributes["valueZ"]))
|
||||
+ ")"
|
||||
)
|
||||
self.contents[self.obj + "00000000::" + self.prop] = val
|
||||
|
||||
elif tag in ["PropertyPlacement"]:
|
||||
if self.prop and self.obj and (self.short == 0):
|
||||
val = (
|
||||
"("
|
||||
+ str(float(attributes["Px"]))
|
||||
+ ","
|
||||
+ str(float(attributes["Py"]))
|
||||
+ ","
|
||||
+ str(float(attributes["Pz"]))
|
||||
+ ")"
|
||||
)
|
||||
val += (
|
||||
" ("
|
||||
+ str(round(float(attributes["Q0"]), 4))
|
||||
+ ","
|
||||
+ str(round(float(attributes["Q1"]), 4))
|
||||
+ ","
|
||||
)
|
||||
val += (
|
||||
str(round(float(attributes["Q2"]), 4))
|
||||
+ ","
|
||||
+ str(round(float(attributes["Q3"]), 4))
|
||||
+ ")"
|
||||
)
|
||||
self.contents[self.obj + "00000000::" + self.prop] = val
|
||||
|
||||
elif tag in ["PropertyColor"]:
|
||||
if self.prop and self.obj and (self.short == 0):
|
||||
c = int(attributes["value"])
|
||||
r = float((c >> 24) & 0xFF) / 255.0
|
||||
g = float((c >> 16) & 0xFF) / 255.0
|
||||
b = float((c >> 8) & 0xFF) / 255.0
|
||||
val = str((r, g, b))
|
||||
self.contents[self.obj + "00000000::" + self.prop] = val
|
||||
|
||||
elif tag == "Objects":
|
||||
self.count = attributes["Count"]
|
||||
self.obj = None
|
||||
|
||||
# Print all the contents of the document properties
|
||||
items = self.contents.items()
|
||||
items = sorted(items)
|
||||
for key, value in items:
|
||||
key = self.clean(key)
|
||||
value = self.clean(value)
|
||||
print(" " + key + " : " + value)
|
||||
print(" Objects: (" + self.count + ")")
|
||||
self.contents = {}
|
||||
|
||||
def endElement(self, tag):
|
||||
|
||||
if (tag == "Document") and (self.short != 2):
|
||||
items = self.contents.items()
|
||||
items = sorted(items)
|
||||
for key, value in items:
|
||||
key = self.clean(key)
|
||||
if "00000000::" in key:
|
||||
key = " " + key.split("00000000::")[1]
|
||||
value = self.clean(value)
|
||||
if value:
|
||||
print(" " + key + " : " + value)
|
||||
|
||||
def clean(self, value):
|
||||
|
||||
value = value.strip()
|
||||
return value
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print(__doc__)
|
||||
sys.exit()
|
||||
|
||||
if ("-h" in sys.argv[1:]) or ("--help" in sys.argv[1:]):
|
||||
print(__doc__)
|
||||
sys.exit()
|
||||
|
||||
ext = sys.argv[-1].rsplit(".")[-1].lower()
|
||||
if not ext.startswith("fcstd") and not ext.startswith("fcbak"):
|
||||
print(__doc__)
|
||||
sys.exit()
|
||||
|
||||
if ("-vs" in sys.argv[1:]) or ("--veryshort" in sys.argv[1:]):
|
||||
short = 2
|
||||
elif ("-s" in sys.argv[1:]) or ("--short" in sys.argv[1:]):
|
||||
short = 1
|
||||
else:
|
||||
short = 0
|
||||
|
||||
if ("-g" in sys.argv[1:]) or ("--gui" in sys.argv[1:]):
|
||||
gui = True
|
||||
else:
|
||||
gui = False
|
||||
|
||||
zfile = zipfile.ZipFile(sys.argv[-1])
|
||||
|
||||
if not "Document.xml" in zfile.namelist():
|
||||
sys.exit(1)
|
||||
doc = zfile.read("Document.xml")
|
||||
if gui and "GuiDocument.xml" in zfile.namelist():
|
||||
guidoc = zfile.read("GuiDocument.xml")
|
||||
guidoc = re.sub(b"<\?xml.*?-->", b" ", guidoc, flags=re.MULTILINE | re.DOTALL)
|
||||
# a valid xml doc can have only one root element. So we need to insert
|
||||
# all the contents of the GUiDocument <document> tag into the main one
|
||||
doc = re.sub(b"<\/Document>", b"", doc, flags=re.MULTILINE | re.DOTALL)
|
||||
guidoc = re.sub(b"<Document.*?>", b" ", guidoc, flags=re.MULTILINE | re.DOTALL)
|
||||
doc += guidoc
|
||||
s = os.path.getsize(sys.argv[-1])
|
||||
if s < 1024:
|
||||
s = str(s) + "B"
|
||||
elif s > 1048576:
|
||||
s = str(s / 1048576) + "M"
|
||||
else:
|
||||
s = str(s / 1024) + "K"
|
||||
print("Document: " + sys.argv[-1] + " (" + s + ")")
|
||||
print(" SHA1: " + str(hashlib.sha1(open(sys.argv[-1], "rb").read()).hexdigest()))
|
||||
xml.sax.parseString(doc, FreeCADFileHandler(zfile, short))
|
||||
100
.local/bin/qalctex
Executable file
100
.local/bin/qalctex
Executable file
@@ -0,0 +1,100 @@
|
||||
#!/bin/python
|
||||
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
# Dictionary for symbol conversion to LaTeX format
|
||||
latex_symbols = {
|
||||
"Ω": r"\Omega",
|
||||
"ohm": r"\Omega",
|
||||
"A": r"\text{A}",
|
||||
"V": r"\text{V}",
|
||||
"milliamperes": r"\text{mA}",
|
||||
"*": r"\cdot",
|
||||
"N*m": r"\text{N} \cdot \text{m}",
|
||||
"in*lb": r"\text{in} \cdot \text{lb}",
|
||||
"||": r"\|",
|
||||
"−": r"-",
|
||||
"μ": r"\mu",
|
||||
"−": r"-",
|
||||
}
|
||||
|
||||
|
||||
def run_qalc(expression):
|
||||
# Run qalc with the provided expression
|
||||
result = subprocess.run(["qalc", expression], stdout=subprocess.PIPE, text=True)
|
||||
output = result.stdout
|
||||
return output
|
||||
|
||||
|
||||
def format_expression_for_latex(expression):
|
||||
# Replace the units and special characters in the input expression using the dictionary
|
||||
for symbol, latex_symbol in latex_symbols.items():
|
||||
expression = expression.replace(symbol, latex_symbol)
|
||||
|
||||
return expression
|
||||
|
||||
|
||||
def format_result_for_latex(output):
|
||||
# Get the last line of qalc output (the answer)
|
||||
output = output.strip().split("\n")[-1]
|
||||
|
||||
# Check if the result is approximate (contains "≈")
|
||||
approx_match = "≈" in output
|
||||
|
||||
# Extract the value and unit from the result
|
||||
match = re.search(r"(≈|=)\s*([-\d\.]+)\s*(.*)", output)
|
||||
if match:
|
||||
_, value, unit = match.groups()
|
||||
# Replace the units and special characters using the dictionary
|
||||
unit = unit.strip()
|
||||
for symbol, latex_symbol in latex_symbols.items():
|
||||
unit = unit.replace(symbol, latex_symbol)
|
||||
|
||||
# Use = or \approx in LaTeX based on whether the result is approximate
|
||||
equal_symbol = r"\approx" if approx_match else "="
|
||||
|
||||
# Only add \, if there's a unit
|
||||
if unit:
|
||||
latex_result = f"{equal_symbol} {value.strip()} \\, {unit}"
|
||||
else:
|
||||
latex_result = f"{equal_symbol} {value.strip()}"
|
||||
|
||||
return latex_result
|
||||
return output # Fallback to returning the raw qalc output if no match
|
||||
|
||||
|
||||
def copy_to_clipboard(text):
|
||||
# Use wl-copy to send the text to the clipboard
|
||||
subprocess.run(["wl-copy"], input=text, text=True)
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
while True:
|
||||
# Input the qalc expression
|
||||
expression = input("\nEnter qalc expression (Ctrl+C to exit): ")
|
||||
|
||||
# Run qalc and get the result
|
||||
qalc_output = run_qalc(expression)
|
||||
|
||||
# Format the input expression for LaTeX
|
||||
latex_expression = format_expression_for_latex(expression)
|
||||
|
||||
# Format the output result for LaTeX
|
||||
latex_result = format_result_for_latex(qalc_output)
|
||||
|
||||
# Combine both input expression and result for final LaTeX output
|
||||
final_latex_output = f"{latex_expression} {latex_result}"
|
||||
|
||||
# Print and copy to clipboard
|
||||
print(f"Final LaTeX output:\n{final_latex_output}")
|
||||
copy_to_clipboard(final_latex_output)
|
||||
print("LaTeX result copied to clipboard!")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nExiting...")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
150
.ssh/config
150
.ssh/config
@@ -8,53 +8,107 @@ Host crawler.kitsunehosting.net
|
||||
HostName crawler.kitsunehosting.net
|
||||
User joe
|
||||
|
||||
Host 10.12.33.234
|
||||
HostName 10.12.33.234
|
||||
User will
|
||||
host edge
|
||||
HostName 10.85.5.52
|
||||
User joe
|
||||
|
||||
Host 10.85.3.39
|
||||
HostName 10.85.3.39
|
||||
host lakemesh
|
||||
HostName 172.25.72.74
|
||||
User joe
|
||||
|
||||
host portainer
|
||||
HostName 10.85.3.60
|
||||
User joe
|
||||
|
||||
host bitwarden
|
||||
HostName 10.85.3.83
|
||||
User joe
|
||||
|
||||
host frigate
|
||||
IdentityFile ~/.ssh/hydroxonium
|
||||
HostName 10.85.5.20
|
||||
User joe
|
||||
|
||||
host portainer
|
||||
IdentityFile ~/.ssh/hydroxonium
|
||||
HostName 10.85.3.60
|
||||
User joe
|
||||
|
||||
host lithium
|
||||
IdentityFile ~/.ssh/gallium
|
||||
HostName 10.85.3.112
|
||||
IPQoS cs0 cs0
|
||||
User joe
|
||||
|
||||
host matrix
|
||||
IdentityFile ~/.ssh/gallium
|
||||
HostName 10.85.3.38
|
||||
user joe
|
||||
|
||||
host crackheadbot
|
||||
HostName 10.85.3.182
|
||||
User joe
|
||||
|
||||
host dockerhost
|
||||
HostName 10.85.3.75
|
||||
User joe
|
||||
|
||||
Host cobalt
|
||||
HostName 10.85.3.6
|
||||
User root
|
||||
|
||||
Host ssh.kitsunehosting.net
|
||||
port 2222
|
||||
IdentityFile ~/.ssh/gitea
|
||||
|
||||
# Supermicro machine in the server rack
|
||||
Host manganese
|
||||
HostName 10.85.3.5
|
||||
User root
|
||||
|
||||
# R710
|
||||
Host magnesium
|
||||
Host nickel
|
||||
HostName 10.85.3.4
|
||||
User root
|
||||
|
||||
# The small romi robot for 1721
|
||||
Host romi
|
||||
HostName 10.17.21.55
|
||||
User joe
|
||||
|
||||
# My main NAS
|
||||
Host zinc
|
||||
IdentityFile ~/.ssh/hydroxonium
|
||||
HostName 10.85.3.120
|
||||
User joe
|
||||
|
||||
# APRS
|
||||
Host houston
|
||||
IdentityFile ~/.ssh/hydroxonium
|
||||
HostName 10.85.3.39
|
||||
User joe
|
||||
|
||||
# Steamcache
|
||||
Host steamcache
|
||||
HostName 10.85.3.60
|
||||
User joe
|
||||
Host deck
|
||||
HostName 10.85.3.221
|
||||
User deck
|
||||
|
||||
# booru Image Server
|
||||
Host booru
|
||||
IdentityFile ~/.ssh/hydroxonium
|
||||
HostName 10.85.3.71
|
||||
User joe
|
||||
|
||||
# Caddy
|
||||
Host caddy
|
||||
IdentityFile ~/.ssh/hydroxonium
|
||||
HostName 10.85.3.9
|
||||
User joe
|
||||
|
||||
# Robotics
|
||||
# 1721's main NAS
|
||||
Host flattoaster
|
||||
HostName 10.17.21.10
|
||||
PreferredAuthentications password
|
||||
IdentityFile none
|
||||
User root
|
||||
|
||||
Host robotics-vps
|
||||
HostName 50.116.52.250
|
||||
User root
|
||||
|
||||
Host lapis
|
||||
@@ -74,14 +128,29 @@ Host aur.archlinux.org
|
||||
User aur
|
||||
|
||||
# Personal Git Server
|
||||
Host kitsunehosting.net
|
||||
Host ssh.kitsunehosting.net
|
||||
Port 2222
|
||||
IdentityFile ~/.ssh/gitea
|
||||
|
||||
# Github
|
||||
Host github.com
|
||||
Hostname ssh.github.com
|
||||
Port 443
|
||||
User git
|
||||
IdentityFile ~/.ssh/github
|
||||
|
||||
Host snowsunehost
|
||||
Hostname 10.85.3.65
|
||||
User joe
|
||||
|
||||
# Also github but, for snowsune
|
||||
Host github_snowsune
|
||||
HostName ssh.github.com
|
||||
User git
|
||||
Port 443
|
||||
IdentityFile ~/.ssh/github_snowsune
|
||||
IdentitiesOnly yes
|
||||
|
||||
# Bitbucket
|
||||
Host bitbucket.org
|
||||
IdentityFile ~/.ssh/bitbucket
|
||||
@@ -91,13 +160,56 @@ Host devserver
|
||||
HostName 10.12.32.35
|
||||
User joe
|
||||
|
||||
Host bosch
|
||||
HostName 192.168.0.41
|
||||
#IdentityFile ~/.ssh/silvertech/ssh_host_dsa_key
|
||||
#UpdateHostKeys no
|
||||
|
||||
Host retropie
|
||||
HostName 10.19.80.2
|
||||
User pi
|
||||
IdentityFile ~/.ssh/silvertech/silvertech
|
||||
IdentitiesOnly yes
|
||||
|
||||
# The little docker host in the closet
|
||||
# Runs the vestabot image
|
||||
Host stdocker1
|
||||
HostName 10.20.30.225
|
||||
IdentityFile ~/.ssh/stdocker
|
||||
HostName 10.10.20.27
|
||||
IdentityFile ~/.ssh/silvertech-iot
|
||||
|
||||
# Platformio remote
|
||||
Host pio-remote
|
||||
HostName 10.144.0.15
|
||||
IdentityFile ~/.ssh/silvertech-iot
|
||||
|
||||
# Little mini-pc in the IOT room
|
||||
Host pioremote
|
||||
# This is actually a zerotier ip
|
||||
HostName 10.144.0.15
|
||||
IdentityFile ~/.ssh/silvertech/silvertech
|
||||
IdentitiesOnly yes
|
||||
|
||||
# Work laptop
|
||||
Host workLaptop
|
||||
HostName 10.144.236.234
|
||||
IdentityFile ~/.ssh/hydroxonium
|
||||
|
||||
# Argen pi
|
||||
Host argen
|
||||
HostName 10.20.30.224
|
||||
HostName 10.10.20.11
|
||||
User joe
|
||||
IdentityFile ~/.ssh/gitlab
|
||||
|
||||
# Millyard labs
|
||||
Host git.millyardlabs.com
|
||||
IdentityFile ~/.ssh/millyard
|
||||
|
||||
Host asterisk
|
||||
HostName 10.85.3.155
|
||||
IdentityFile ~/.ssh/hydroxonium
|
||||
|
||||
# Pterodactyal stuff
|
||||
Host wing1.kitsunehosting.net
|
||||
HostName wing1.kitsunehosting.net
|
||||
PreferredAuthentications password
|
||||
IdentityFile none
|
||||
|
||||
40
.zshrc
40
.zshrc
@@ -1,12 +1,23 @@
|
||||
# Joe added this:
|
||||
uwufetch
|
||||
echo ""
|
||||
fortune
|
||||
fortune -a
|
||||
|
||||
# This is for platformio on work machine
|
||||
path+=("$HOME/.platformio/penv/bin")
|
||||
|
||||
# Add my bins to path
|
||||
path+=("$HOME/.local/bin")
|
||||
path+=("$HOME/Pictures/Furry/Scripts")
|
||||
path+=("/opt/balena-cli/")
|
||||
export PATH
|
||||
|
||||
# LaTeX Import path
|
||||
export TEXINPUTS=/home/joe/College/SNHU/LaTeX:$(kpsepath tex | tr ':' '\n' | head -n 1):
|
||||
|
||||
# Not sure why but, needed to path these manually for ruby bin
|
||||
path+=("/home/joe/.local/share/gem/ruby/3.3.0/bin")
|
||||
|
||||
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
|
||||
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
|
||||
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
|
||||
@@ -123,6 +134,13 @@ fi
|
||||
# alias zshconfig="mate ~/.zshrc"
|
||||
# alias ohmyzsh="mate ~/.oh-my-zsh"
|
||||
|
||||
# https://www.reddit.com/r/archlinux/comments/p0y2hs/flatpak/
|
||||
alias update="paru -Syu --skipreview; flatpak update; sudo snap refresh"
|
||||
|
||||
# Power
|
||||
alias upshift="powerprofilesctl set performance"
|
||||
alias downshift="powerprofilesctl set power-saver"
|
||||
|
||||
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
|
||||
|
||||
export FZF_DEFAULT_COMMAND='fdfind --type f'
|
||||
@@ -130,3 +148,23 @@ export FZF_DEFAULT_OPTS="--layout=reverse --inline-info --height=80%"
|
||||
|
||||
# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
|
||||
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
|
||||
|
||||
|
||||
# This is fo cumtanks lol
|
||||
cumtanks() {
|
||||
cd /home/joe/git/Snowsune/cumtanks || return 1
|
||||
EPOCH=$(date +%s)
|
||||
DATA_JSON="www/data.json"
|
||||
tmpfile=$(mktemp)
|
||||
awk -v epoch="$EPOCH" '
|
||||
BEGIN { added=0 }
|
||||
/"logs"[ \t]*:[ \t]*\[/ { inlogs=1 }
|
||||
inlogs && /\]/ && !added {
|
||||
sub(/\]/, " ,{ \"date\": " epoch ", \"text\": \"\" }\n ]")
|
||||
added=1
|
||||
}
|
||||
{ print }
|
||||
' "$DATA_JSON" > "$tmpfile" && mv "$tmpfile" "$DATA_JSON"
|
||||
sed -i 's/,\n ]/\n ]/' "$DATA_JSON"
|
||||
code -g "$DATA_JSON":$(grep -n '"logs"' "$DATA_JSON" | cut -d: -f1)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user