Auto-update: Tue Jul 30 19:30:24 PDT 2024
This commit is contained in:
parent
6c3143513e
commit
2f4467362d
51 changed files with 1443 additions and 20 deletions
12
15
Executable file
12
15
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
|
||||
tailscale="/Applications/Tailscale.app/Contents/MacOS/Tailscale"
|
||||
|
||||
if $tailscale status | grep -q "100."; then
|
||||
echo "Connected to Tailscale, SSH'ing to 100.64.64.30..."
|
||||
ssh sangye@100.64.64.30
|
||||
else
|
||||
echo "Not connected to Tailscale, SSH'ing to 10.13.37.30..."
|
||||
ssh sangye@10.13.37.30
|
||||
fi
|
||||
|
2
2fa
Executable file
2
2fa
Executable file
|
@ -0,0 +1,2 @@
|
|||
source ~/.zshrc
|
||||
python ~/.2fa.py
|
36
Summarizer
Executable file
36
Summarizer
Executable file
|
@ -0,0 +1,36 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Endpoint URL
|
||||
endpoint="http://localhost:3456/summarize"
|
||||
|
||||
# Function to check if port 3456 is open
|
||||
is_port_open() {
|
||||
nc -z localhost 3456
|
||||
return $?
|
||||
}
|
||||
|
||||
# Check if the FastAPI server is running (port 3456)
|
||||
if ! is_port_open; then
|
||||
echo "Starting BananaPhone.py..."
|
||||
# Start the FastAPI server
|
||||
/Users/sij/AI/banana-phone/BananaPhone.sh &
|
||||
|
||||
# Wait for the server to start
|
||||
echo "Waiting for server to start..."
|
||||
until is_port_open; do
|
||||
sleep 1
|
||||
done
|
||||
echo "Server started."
|
||||
fi
|
||||
|
||||
# Loop through each file dropped onto the droplet
|
||||
for f in "$@"
|
||||
do
|
||||
# POST request using curl
|
||||
curl -X POST -H "Content-Type: multipart/form-data" \
|
||||
-H "Authorization: Bearer sk-NhrtQwCHNdK5sRZC" \
|
||||
-F "file=@$f" \
|
||||
-F "podcast=true" \
|
||||
-F "speed=1.2" \
|
||||
"$endpoint"
|
||||
done
|
2
VBoxAudioTest
Executable file
2
VBoxAudioTest
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
exec /Applications/VirtualBox.app/Contents/MacOS/VBoxAudioTest "$@"
|
2
VBoxAutostart
Executable file
2
VBoxAutostart
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
exec /Applications/VirtualBox.app/Contents/MacOS/VBoxAutostart "$@"
|
2
VBoxBalloonCtrl
Executable file
2
VBoxBalloonCtrl
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
exec /Applications/VirtualBox.app/Contents/MacOS/VBoxBalloonCtrl "$@"
|
2
VBoxBugReport
Executable file
2
VBoxBugReport
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
exec /Applications/VirtualBox.app/Contents/MacOS/VBoxBugReport "$@"
|
2
VBoxHeadless
Executable file
2
VBoxHeadless
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
exec /Applications/VirtualBox.app/Contents/MacOS/VBoxHeadless "$@"
|
2
VBoxManage
Executable file
2
VBoxManage
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
exec /Applications/VirtualBox.app/Contents/MacOS/VBoxManage "$@"
|
2
VBoxVRDP
Executable file
2
VBoxVRDP
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
exec /Applications/VirtualBox.app/Contents/MacOS/VBoxHeadless "$@"
|
29
all
Executable file
29
all
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Create a new tmux session
|
||||
tmux new-session -d -s servers -n 'ssh'
|
||||
|
||||
# Split the first window horizontally
|
||||
tmux split-window -h
|
||||
|
||||
# Split the first and second panes vertically
|
||||
tmux select-pane -t 0
|
||||
tmux split-window -v
|
||||
|
||||
tmux select-pane -t 2
|
||||
tmux split-window -v
|
||||
|
||||
# Function to connect to servers with retry
|
||||
connect_to_server_with_retry() {
|
||||
tmux send-keys -t "$1" "while true; do ssh $2; sleep 30; done" C-m
|
||||
}
|
||||
|
||||
# Connect to servers with retry
|
||||
connect_to_server_with_retry 0 "100.64.64.11"
|
||||
connect_to_server_with_retry 1 "100.64.64.30"
|
||||
connect_to_server_with_retry 2 "100.64.64.15"
|
||||
connect_to_server_with_retry 3 "root@10.13.37.10"
|
||||
|
||||
# Attach to the tmux session
|
||||
tmux attach -t servers
|
||||
|
37
asf
Executable file
37
asf
Executable file
|
@ -0,0 +1,37 @@
|
|||
-- Mail Rule - Add messages to DEVONthink
|
||||
-- Created by Christian Grunenberg on Mon Apr 19 2004.
|
||||
-- Copyright (c) 2004-2020. All rights reserved.
|
||||
|
||||
-- this string is used when the message subject is empty
|
||||
property pNoSubjectString : "(no subject)"
|
||||
|
||||
using terms from application "Mail"
|
||||
on perform mail action with messages theMessages for rule theRule
|
||||
tell application "Mail"
|
||||
repeat with theMessage in theMessages
|
||||
try
|
||||
tell theMessage
|
||||
set {theDateReceived, theDateSent, theSender, theSubject, theSource, theReadFlag} to {the date received, the date sent, the sender, subject, the source, the read status}
|
||||
set theMessageURL to "message://%3c" & theMessage's message id & "%3e"
|
||||
end tell
|
||||
if theSubject is equal to "" then set theSubject to pNoSubjectString
|
||||
tell application id "DNtp"
|
||||
set username to do shell script "id -un" -- this will get the current username dynamically
|
||||
set theDatabase to open database ("/Users/" & username & "/Databases/Professional.dtbase2")
|
||||
set theYear to year of theDateReceived
|
||||
set theMonth to texts -2 thru -1 of ("0" & (month of theDateReceived as integer))
|
||||
set theMonthName to month of theDateReceived as string
|
||||
set theDay to texts -2 thru -1 of ("0" & (day of theDateReceived))
|
||||
set theWeekday to weekday of theDateReceived
|
||||
set theGroup to create location ("/Notes/Journal/" & theYear & "/" & theYear & "-" & theMonth & " " & theMonthName & "/" & theYear & "-" & theMonth & "-" & theDay & " " & theWeekday & "/" & "Emails") in theDatabase
|
||||
set theRecord to create record with {name:theSubject & ".eml", type:unknown, creation date:theDateSent, modification date:theDateReceived, URL:theSender, source:(theSource as string), unread:(not theReadFlag)} in theGroup
|
||||
set theConvertedRecord to convert record theRecord to markdown
|
||||
delete record theRecord
|
||||
set URL of theConvertedRecord to theMessageURL
|
||||
perform smart rule trigger import event record theConvertedRecord
|
||||
end tell
|
||||
end try
|
||||
end repeat
|
||||
end tell
|
||||
end perform mail action with messages
|
||||
end using terms from
|
22
asr copy
Executable file
22
asr copy
Executable file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Check if a filename is provided
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 filename"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Assign the first argument to FILENAME
|
||||
FILENAME="$1"
|
||||
|
||||
# Check if the file exists
|
||||
if [ ! -f "$FILENAME" ]; then
|
||||
echo "Error: File not found - $FILENAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Perform the curl POST request with the file
|
||||
curl -X POST http://127.0.0.1:3456/v1/asr \
|
||||
-H 'Authorization: bearer sk-NhrtQwCHNdK5sRZC' \
|
||||
-F "file=@$FILENAME"
|
||||
|
3
ccd
Executable file
3
ccd
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
cd $1
|
||||
ls -lsa
|
1
chat
Executable file
1
chat
Executable file
|
@ -0,0 +1 @@
|
|||
python /usr/local/bin/chat.py
|
55
checknode
Executable file
55
checknode
Executable file
|
@ -0,0 +1,55 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "Checking for remnants of Node.js, npm, and nvm..."
|
||||
|
||||
# Check PATH
|
||||
echo "Checking PATH..."
|
||||
echo $PATH | grep -q 'node\|npm' && echo "Found Node.js or npm in PATH"
|
||||
|
||||
# Check Homebrew
|
||||
echo "Checking Homebrew..."
|
||||
brew list | grep -q 'node\|npm' && echo "Found Node.js or npm installed with Homebrew"
|
||||
|
||||
# Check Yarn
|
||||
echo "Checking Yarn..."
|
||||
command -v yarn >/dev/null 2>&1 && echo "Found Yarn"
|
||||
|
||||
# Check Node.js and npm directories
|
||||
echo "Checking Node.js and npm directories..."
|
||||
ls ~/.npm >/dev/null 2>&1 && echo "Found ~/.npm directory"
|
||||
ls ~/.node-gyp >/dev/null 2>&1 && echo "Found ~/.node-gyp directory"
|
||||
|
||||
# Check open files and sockets
|
||||
echo "Checking open files and sockets..."
|
||||
lsof | grep -q 'node' && echo "Found open files or sockets related to Node.js"
|
||||
|
||||
# Check other version managers
|
||||
echo "Checking other version managers..."
|
||||
command -v n >/dev/null 2>&1 && echo "Found 'n' version manager"
|
||||
|
||||
# Check temporary directories
|
||||
echo "Checking temporary directories..."
|
||||
ls /tmp | grep -q 'node\|npm' && echo "Found Node.js or npm related files in /tmp"
|
||||
|
||||
# Check Browserify and Webpack cache
|
||||
echo "Checking Browserify and Webpack cache..."
|
||||
ls ~/.config/browserify >/dev/null 2>&1 && echo "Found Browserify cache"
|
||||
ls ~/.config/webpack >/dev/null 2>&1 && echo "Found Webpack cache"
|
||||
|
||||
# Check Electron cache
|
||||
echo "Checking Electron cache..."
|
||||
ls ~/.electron >/dev/null 2>&1 && echo "Found Electron cache"
|
||||
|
||||
# Check logs
|
||||
echo "Checking logs..."
|
||||
ls ~/.npm/_logs >/dev/null 2>&1 && echo "Found npm logs"
|
||||
ls ~/.node-gyp/*.log >/dev/null 2>&1 && echo "Found Node.js logs"
|
||||
|
||||
# Check miscellaneous directories
|
||||
echo "Checking miscellaneous directories..."
|
||||
ls ~/.node_repl_history >/dev/null 2>&1 && echo "Found ~/.node_repl_history"
|
||||
ls ~/.v8flags* >/dev/null 2>&1 && echo "Found ~/.v8flags*"
|
||||
ls ~/.npm-global >/dev/null 2>&1 && echo "Found ~/.npm-global"
|
||||
ls ~/.nvm-global >/dev/null 2>&1 && echo "Found ~/.nvm-global"
|
||||
|
||||
echo "Check completed."
|
26
comfy
Executable file
26
comfy
Executable file
|
@ -0,0 +1,26 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Create a new tmux session named "comfy" detached (-d) and start the first command in the left pane
|
||||
tmux new-session -d -s comfy -n comfypane
|
||||
|
||||
# Split the window into two panes. By default, this creates a vertical split.
|
||||
tmux split-window -h -t comfy
|
||||
|
||||
# Select the first pane to setup comfy environment
|
||||
tmux select-pane -t 0
|
||||
COMFY_MAMBA=$(mamba env list | grep "^comfy" | awk '{print $2}')
|
||||
tmux send-keys -t 0 "cd ~/workshop/sd/ComfyUI" C-m
|
||||
tmux send-keys -t 0 "export PATH=\"$COMFY_MAMBA/bin:\$PATH\"" C-m
|
||||
tmux send-keys -t 0 "source ~/.zshrc" C-m
|
||||
tmux send-keys -t 0 "mamba activate comfy; sleep 1; while true; do PYTORCH_MPS_HIGH_WATERMARK_RATIO=0.0 PYTORCH_ENABLE_MPS_FALLBACK=1 python main.py --preview-method auto --force-fp16 --enable-cors-header; exit_status=\$?; if [ \$exit_status -ne 0 ]; then osascript -e 'display notification \"ComfyUI script exited unexpectedly\" with title \"Error in ComfyUI\"'; fi; sleep 1; done" C-m
|
||||
|
||||
# Select the second pane to setup extracomfy environment
|
||||
tmux select-pane -t 1
|
||||
IG_MAMBA=$(mamba env list | grep "^insta" | awk '{print $2}')
|
||||
tmux send-keys -t 1 "export PATH=\"$IG_MAMBA/bin:\$PATH\"" C-m
|
||||
tmux send-keys -t 1 "source ~/.zshrc" C-m
|
||||
tmux send-keys -t 1 "mamba activate instabot; cd workshop/igbot" C-m
|
||||
|
||||
# Attach to the tmux session
|
||||
# tmux attach -t comfy
|
||||
|
14
emoji-flag
Executable file
14
emoji-flag
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env python3
|
||||
import sys
|
||||
|
||||
def flag_emoji(country_code):
|
||||
offset = 127397
|
||||
flag = ''.join(chr(ord(char) + offset) for char in country_code.upper())
|
||||
return flag
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) > 1:
|
||||
country_code = sys.argv[1]
|
||||
print(flag_emoji(country_code))
|
||||
else:
|
||||
print("No country code provided")
|
47
fixname
Executable file
47
fixname
Executable file
|
@ -0,0 +1,47 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Check if enough arguments are passed
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <file_path>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to truncate filename to a maximum length, preserving the extension
|
||||
truncate_filename() {
|
||||
local filename="$1"
|
||||
local max_length="$2"
|
||||
local extension="${filename##*.}"
|
||||
local base_name="${filename%.*}"
|
||||
|
||||
if [ ${#filename} -gt $max_length ]; then
|
||||
local truncated_base="${base_name:0:($max_length - ${#extension} - 1)}"
|
||||
echo "${truncated_base}.${extension}"
|
||||
else
|
||||
echo "$filename"
|
||||
fi
|
||||
}
|
||||
|
||||
# Read the file paths from the input file
|
||||
while IFS= read -r file_path; do
|
||||
# Extract the directory and filename
|
||||
dir_path=$(dirname "$file_path")
|
||||
file_name=$(basename "$file_path")
|
||||
|
||||
# Define the new filename by replacing or removing illegal characters
|
||||
new_file_name=$(echo "$file_name" | tr -d '<>:"/\\|?*' | tr '[:cntrl:]' '_' | sed 's/[—·]/-/g' | sed 's/"/_/g' | sed "s/'/_/g")
|
||||
|
||||
# Ensure filename does not end with an underscore
|
||||
new_file_name=$(echo "$new_file_name" | sed 's/_$//')
|
||||
|
||||
# Truncate the filename if it is longer than 200 characters, preserving the extension
|
||||
new_file_name=$(truncate_filename "$new_file_name" 200)
|
||||
|
||||
# Construct the new path
|
||||
new_path="$dir_path/$new_file_name"
|
||||
|
||||
# Rename the file if necessary
|
||||
if [ "$new_file_name" != "$file_name" ]; then
|
||||
echo "Renaming '$file_path' to '$new_path'"
|
||||
mv "$file_path" "$new_path"
|
||||
fi
|
||||
done <"$1"
|
27
fuzzy_match
Executable file
27
fuzzy_match
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
|
||||
#
|
||||
# This file was generated by RubyGems.
|
||||
#
|
||||
# The application 'fuzzy_match' is installed as part of a gem, and
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
require 'rubygems'
|
||||
|
||||
version = ">= 0.a"
|
||||
|
||||
str = ARGV.first
|
||||
if str
|
||||
str = str.b[/\A_(.*)_\z/, 1]
|
||||
if str and Gem::Version.correct?(str)
|
||||
version = str
|
||||
ARGV.shift
|
||||
end
|
||||
end
|
||||
|
||||
if Gem.respond_to?(:activate_bin_path)
|
||||
load Gem.activate_bin_path('fuzzy_match', 'fuzzy_match', version)
|
||||
else
|
||||
gem "fuzzy_match", version
|
||||
load Gem.bin_path("fuzzy_match", "fuzzy_match", version)
|
||||
end
|
37
getreq
Executable file
37
getreq
Executable file
|
@ -0,0 +1,37 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Script to find Python imports and install them if necessary
|
||||
|
||||
# Check for input argument
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <path-to-python-file>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PYTHON_FILE="$1"
|
||||
|
||||
# Extract import statements
|
||||
IMPORTS=$(grep -E "^import |^from " "$PYTHON_FILE" | \
|
||||
awk '{print $2}' | cut -d. -f1 | sort | uniq)
|
||||
|
||||
# Function to check and install packages
|
||||
check_and_install() {
|
||||
PACKAGE=$1
|
||||
# Check if the package is installed via pip
|
||||
if pip list | grep -q "^$PACKAGE "; then
|
||||
echo "$PACKAGE is already installed via pip."
|
||||
# Check if the package is installed via conda
|
||||
elif conda list | grep -q "^$PACKAGE "; then
|
||||
echo "$PACKAGE is already installed via conda."
|
||||
else
|
||||
# Install the package using kip
|
||||
echo "Installing $PACKAGE using kip..."
|
||||
kip install "$PACKAGE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Iterate over imports and check/install them
|
||||
for pkg in $IMPORTS; do
|
||||
check_and_install $pkg
|
||||
done
|
||||
|
27
httpclient
Executable file
27
httpclient
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
|
||||
#
|
||||
# This file was generated by RubyGems.
|
||||
#
|
||||
# The application 'httpclient' is installed as part of a gem, and
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
require 'rubygems'
|
||||
|
||||
version = ">= 0.a"
|
||||
|
||||
str = ARGV.first
|
||||
if str
|
||||
str = str.b[/\A_(.*)_\z/, 1]
|
||||
if str and Gem::Version.correct?(str)
|
||||
version = str
|
||||
ARGV.shift
|
||||
end
|
||||
end
|
||||
|
||||
if Gem.respond_to?(:activate_bin_path)
|
||||
load Gem.activate_bin_path('httpclient', 'httpclient', version)
|
||||
else
|
||||
gem "httpclient", version
|
||||
load Gem.bin_path("httpclient", "httpclient", version)
|
||||
end
|
46
i
Executable file
46
i
Executable file
|
@ -0,0 +1,46 @@
|
|||
#!/Users/sij/miniforge3/envs/minicpm/bin/python
|
||||
import os
|
||||
import torch
|
||||
from transformers import AutoModel, AutoTokenizer
|
||||
from PIL import Image
|
||||
import argparse
|
||||
|
||||
# Set environment variable to enable CPU fallback
|
||||
os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
|
||||
|
||||
# Parse command line arguments
|
||||
parser = argparse.ArgumentParser(description='Process image for model.')
|
||||
parser.add_argument('image_path', type=str, help='Path to the image file')
|
||||
args = parser.parse_args()
|
||||
|
||||
# Check if MPS is available
|
||||
if torch.backends.mps.is_available():
|
||||
device = torch.device("mps")
|
||||
else:
|
||||
device = torch.device("cpu")
|
||||
|
||||
# Load the model with appropriate torch dtype
|
||||
model = AutoModel.from_pretrained('openbmb/MiniCPM-Llama3-V-2_5', trust_remote_code=True, torch_dtype=torch.float32 if device == torch.device("cpu") else torch.float16)
|
||||
model = model.to(device)
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained('openbmb/MiniCPM-Llama3-V-2_5', trust_remote_code=True)
|
||||
model.eval()
|
||||
|
||||
# Load and prepare the image
|
||||
image_path = "/Users/sij/adorablenakedskinny.jpeg" # args.image_path
|
||||
image = Image.open(image_path).convert('RGB')
|
||||
question = 'Using modern English and adult slang words like cock, cum, pussy, fuck, etc., describe the scene pictured in the image.'
|
||||
msgs = [{'role': 'user', 'content': question}]
|
||||
|
||||
# Perform inference
|
||||
with torch.no_grad():
|
||||
res = model.chat(
|
||||
image=image,
|
||||
msgs=msgs,
|
||||
tokenizer=tokenizer,
|
||||
sampling=True,
|
||||
temperature=0.7
|
||||
)
|
||||
|
||||
print(res)
|
||||
|
144
import-finder
Executable file
144
import-finder
Executable file
|
@ -0,0 +1,144 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
import time
|
||||
import pkg_resources
|
||||
|
||||
# List of Python built-in modules
|
||||
BUILTIN_MODULES = {
|
||||
'abc', 'aifc', 'argparse', 'array', 'ast', 'asynchat', 'asyncio', 'asyncore', 'atexit',
|
||||
'audioop', 'base64', 'bdb', 'binascii', 'binhex', 'bisect', 'builtins', 'bz2', 'calendar',
|
||||
'cgi', 'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop', 'collections', 'colorsys',
|
||||
'compileall', 'concurrent', 'configparser', 'contextlib', 'copy', 'copyreg', 'crypt', 'csv',
|
||||
'ctypes', 'curses', 'dataclasses', 'datetime', 'dbm', 'decimal', 'difflib', 'dis', 'distutils',
|
||||
'doctest', 'dummy_threading', 'email', 'encodings', 'ensurepip', 'enum', 'errno', 'faulthandler',
|
||||
'fcntl', 'filecmp', 'fileinput', 'fnmatch', 'formatter', 'fractions', 'ftplib', 'functools',
|
||||
'gc', 'getopt', 'getpass', 'gettext', 'glob', 'gzip', 'hashlib', 'heapq', 'hmac', 'html', 'http',
|
||||
'imaplib', 'imghdr', 'imp', 'importlib', 'inspect', 'io', 'ipaddress', 'itertools', 'json',
|
||||
'keyword', 'lib2to3', 'linecache', 'locale', 'logging', 'lzma', 'mailbox', 'mailcap', 'marshal',
|
||||
'math', 'mimetypes', 'modulefinder', 'multiprocessing', 'netrc', 'nntplib', 'numbers', 'operator',
|
||||
'optparse', 'os', 'ossaudiodev', 'parser', 'pathlib', 'pdb', 'pickle', 'pickletools', 'pipes',
|
||||
'pkgutil', 'platform', 'plistlib', 'poplib', 'posix', 'pprint', 'profile', 'pstats', 'pty',
|
||||
'pwd', 'py_compile', 'pyclbr', 'pydoc', 'queue', 'quopri', 'random', 're', 'readline',
|
||||
'reprlib', 'resource', 'rlcompleter', 'runpy', 'sched', 'secrets', 'select', 'selectors', 'shelve',
|
||||
'shlex', 'shutil', 'signal', 'site', 'smtpd', 'smtplib', 'sndhdr', 'socket', 'socketserver',
|
||||
'spwd', 'sqlite3', 'ssl', 'stat', 'statistics', 'string', 'stringprep', 'struct', 'subprocess',
|
||||
'sunau', 'symtable', 'sys', 'sysconfig', 'syslog', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile',
|
||||
'termios', 'test', 'textwrap', 'threading', 'time', 'timeit', 'token', 'tokenize', 'trace',
|
||||
'traceback', 'tracemalloc', 'tty', 'turtle', 'types', 'typing', 'unicodedata', 'unittest',
|
||||
'urllib', 'uu', 'uuid', 'venv', 'warnings', 'wave', 'weakref', 'webbrowser', 'xdrlib', 'xml',
|
||||
'xmlrpc', 'zipapp', 'zipfile', 'zipimport', 'zlib'
|
||||
}
|
||||
|
||||
# Known corrections for PyPI package names
|
||||
KNOWN_CORRECTIONS = {
|
||||
'dateutil': 'python-dateutil',
|
||||
'dotenv': 'python-dotenv',
|
||||
'docx': 'python-docx',
|
||||
'tesseract': 'pytesseract',
|
||||
'magic': 'python-magic',
|
||||
'multipart': 'python-multipart',
|
||||
'newspaper': 'newspaper3k',
|
||||
'srtm': 'elevation',
|
||||
'yaml': 'pyyaml',
|
||||
'zoneinfo': 'backports.zoneinfo'
|
||||
}
|
||||
|
||||
# List of generic names to exclude
|
||||
EXCLUDED_NAMES = {'models', 'data', 'convert', 'example', 'tests'}
|
||||
|
||||
def find_imports(root_dir):
|
||||
imports_by_file = {}
|
||||
for dirpath, _, filenames in os.walk(root_dir):
|
||||
for filename in filenames:
|
||||
if filename.endswith('.py'):
|
||||
filepath = os.path.join(dirpath, filename)
|
||||
with open(filepath, 'r') as file:
|
||||
import_lines = []
|
||||
for line in file:
|
||||
line = line.strip()
|
||||
if line.startswith(('import ', 'from ')) and not line.startswith('#'):
|
||||
import_lines.append(line)
|
||||
imports_by_file[filepath] = import_lines
|
||||
return imports_by_file
|
||||
|
||||
def process_import_lines(import_lines):
|
||||
processed_lines = set() # Use a set to remove duplicates
|
||||
for line in import_lines:
|
||||
# Handle 'import xyz' and 'import abc, def, geh'
|
||||
if line.startswith('import '):
|
||||
modules = line.replace('import ', '').split(',')
|
||||
for mod in modules:
|
||||
mod = re.sub(r'\s+as\s+\w+', '', mod).split('.')[0].strip()
|
||||
if mod and not mod.isupper() and mod not in EXCLUDED_NAMES:
|
||||
processed_lines.add(mod)
|
||||
# Handle 'from abc import def, geh'
|
||||
elif line.startswith('from '):
|
||||
mod = line.split(' ')[1].split('.')[0].strip()
|
||||
if mod and not mod.isupper() and mod not in EXCLUDED_NAMES:
|
||||
processed_lines.add(mod)
|
||||
return processed_lines
|
||||
|
||||
def check_pypi_availability(libraries):
|
||||
available = set()
|
||||
unavailable = set()
|
||||
for lib in libraries:
|
||||
if lib in BUILTIN_MODULES: # Skip built-in modules
|
||||
continue
|
||||
corrected_lib = KNOWN_CORRECTIONS.get(lib, lib)
|
||||
try:
|
||||
if check_library_on_pypi(corrected_lib):
|
||||
available.add(corrected_lib)
|
||||
else:
|
||||
unavailable.add(corrected_lib)
|
||||
except requests.exceptions.RequestException:
|
||||
print(f"Warning: Unable to check {corrected_lib} on PyPI due to network error.")
|
||||
unavailable.add(corrected_lib)
|
||||
return available, unavailable
|
||||
|
||||
def check_library_on_pypi(library):
|
||||
max_retries = 3
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
response = requests.get(f"https://pypi.org/pypi/{library}/json", timeout=5)
|
||||
return response.status_code == 200
|
||||
except requests.exceptions.RequestException:
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(1) # Wait for 1 second before retrying
|
||||
else:
|
||||
raise
|
||||
|
||||
def save_to_requirements_file(available, output_file='requirements.txt'):
|
||||
existing_requirements = set()
|
||||
if os.path.isfile(output_file):
|
||||
with open(output_file, 'r') as file:
|
||||
existing_requirements = set(line.strip() for line in file)
|
||||
with open(output_file, 'a') as file:
|
||||
for pkg in sorted(available - existing_requirements):
|
||||
print(f"Adding to requirements.txt: {pkg}")
|
||||
file.write(pkg + '\n')
|
||||
|
||||
def save_to_missing_file(unavailable, output_file='missing-packages.txt'):
|
||||
existing_missing = set()
|
||||
if os.path.isfile(output_file):
|
||||
with open(output_file, 'r') as file:
|
||||
existing_missing = set(line.strip() for line in file)
|
||||
with open(output_file, 'a') as file:
|
||||
for pkg in sorted(unavailable - existing_missing):
|
||||
print(f"Adding to missing-packages.txt: {pkg}")
|
||||
file.write(pkg + '\n')
|
||||
|
||||
if __name__ == "__main__":
|
||||
root_dir = os.getcwd() # Get the current working directory
|
||||
|
||||
imports_by_file = find_imports(root_dir)
|
||||
for filepath, import_lines in imports_by_file.items():
|
||||
print(f"# Processing {filepath}")
|
||||
processed_lines = process_import_lines(import_lines)
|
||||
available, unavailable = check_pypi_availability(processed_lines)
|
||||
save_to_requirements_file(available)
|
||||
save_to_missing_file(unavailable)
|
||||
|
||||
print(f"Processed import statements have been saved to requirements.txt and missing-packages.txt")
|
29
ison
Executable file
29
ison
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/Users/sij/miniforge3/envs/sijapi/bin/python
|
||||
|
||||
import requests
|
||||
|
||||
def check_health(url):
|
||||
try:
|
||||
response = requests.get(url)
|
||||
if response.status_code == 200:
|
||||
return f"{url} is up"
|
||||
else:
|
||||
return f"{url} returned status code {response.status_code}"
|
||||
except requests.exceptions.RequestException:
|
||||
return f"{url} is down"
|
||||
|
||||
def main():
|
||||
addresses = [
|
||||
"http://localhost:4444/health",
|
||||
"http://100.64.64.20:4444/health",
|
||||
"http://100.64.64.30:4444/health",
|
||||
"http://100.64.64.11:4444/health",
|
||||
"http://100.64.64.15:4444/health"
|
||||
]
|
||||
|
||||
for address in addresses:
|
||||
print(check_health(address))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
12
llm
Executable file
12
llm
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
murder ollama
|
||||
tmux new-session -d -s ollama -n ollamapane
|
||||
|
||||
tmux split-window -h -t ollama
|
||||
tmux select-pane -t 0
|
||||
tmux send-keys -t 0 "source ~/.zshrc" C-m
|
||||
tmux send-keys -t 0 "ollama serve; sleep 1" C-m
|
||||
|
||||
tmux select-pane -t 1
|
||||
tmux send-keys -t 1 "source ~/.zshrc" C-m
|
||||
|
19
lsd
Executable file
19
lsd
Executable file
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Default options for lsd
|
||||
default_options="--color=always -F --long --size=short --permission=octal --group-dirs=first -X"
|
||||
|
||||
# Check if the first argument is a directory or an option
|
||||
if [[ $# -gt 0 && ! $1 =~ ^- ]]; then
|
||||
# First argument is a directory, store it and remove from arguments list
|
||||
directory=$1
|
||||
shift
|
||||
else
|
||||
# No directory specified, default to the current directory
|
||||
directory="."
|
||||
fi
|
||||
|
||||
# Execute lsd with the default options, directory, and any additional arguments provided
|
||||
/opt/homebrew/bin/lsd $default_options "$directory" "$@"
|
||||
|
||||
|
15
mamba-exporter
Executable file
15
mamba-exporter
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
# List all conda environments and cut the output to get just the names
|
||||
envs=$(mamba env list | awk '{print $1}' | grep -v '^#' | grep -v 'base')
|
||||
|
||||
# Loop through each environment name
|
||||
for env in $envs; do
|
||||
# Use conda (or mamba, but conda is preferred for compatibility reasons) to export the environment to a YAML file
|
||||
# No need to activate the environment; conda can export directly by specifying the name
|
||||
echo "Exporting $env..."
|
||||
mamba env export --name $env > "${env}.yml"
|
||||
done
|
||||
|
||||
echo "All environments have been exported."
|
||||
|
26
mamba-importer
Executable file
26
mamba-importer
Executable file
|
@ -0,0 +1,26 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Function to process a single .yml file
|
||||
process_file() {
|
||||
file="$1"
|
||||
if [[ -f "$file" ]]; then
|
||||
env_name=$(echo "$file" | sed 's/.yml$//')
|
||||
echo "Creating environment from $file..."
|
||||
conda env create -f "$file" || echo "Failed to create environment from $file"
|
||||
else
|
||||
echo "File $file does not exist."
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if a .yml file was provided as an argument
|
||||
if [[ $# -eq 1 && $1 == *.yml ]]; then
|
||||
# Process the provided .yml file
|
||||
process_file "$1"
|
||||
else
|
||||
# No argument provided, process all .yml files in the current directory
|
||||
for file in *.yml; do
|
||||
process_file "$file"
|
||||
done
|
||||
echo "Environment creation process completed."
|
||||
fi
|
||||
|
3
master
Executable file
3
master
Executable file
|
@ -0,0 +1,3 @@
|
|||
st
|
||||
api
|
||||
comfy
|
24
murder
Executable file
24
murder
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Check if an argument is given
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: murder [process name or port]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the input parameter
|
||||
ARGUMENT=$1
|
||||
|
||||
# Check if the argument is numeric
|
||||
if [[ $ARGUMENT =~ ^[0-9]+$ ]]; then
|
||||
echo "Killing processes listening on port $ARGUMENT"
|
||||
lsof -t -i:$ARGUMENT | xargs kill
|
||||
else
|
||||
# Process name was given instead of a port number
|
||||
echo "Killing processes with name $ARGUMENT"
|
||||
for PID in $(ps aux | grep $ARGUMENT | grep -v grep | awk '{print $2}'); do
|
||||
echo "Killing process $PID"
|
||||
sudo kill -9 $PID
|
||||
done
|
||||
fi
|
||||
|
68
nukenode
Executable file
68
nukenode
Executable file
|
@ -0,0 +1,68 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Uninstall global npm packages
|
||||
npm ls -gp --depth=0 | awk -F/ '/node_modules/ && !/\/npm$/ {print $NF}' | xargs npm -g rm
|
||||
|
||||
# Uninstall Node.js and npm
|
||||
brew uninstall node
|
||||
brew uninstall npm
|
||||
|
||||
# Remove npm, Node.js, and nvm directories
|
||||
sudo rm -rf /usr/local/lib/node_modules
|
||||
sudo rm -rf ~/.npm
|
||||
sudo rm -rf /usr/local/bin/npm
|
||||
sudo rm -rf /usr/local/share/man/man1/node*
|
||||
sudo rm -rf /usr/local/bin/node
|
||||
sudo rm -rf /usr/local/lib/node_modules/
|
||||
sudo rm -rf /usr/local/include/node/
|
||||
rm -rf ~/.nvm
|
||||
|
||||
# Clean up Node.js and npm related files
|
||||
sudo rm -rf ~/.node*
|
||||
sudo rm -rf ~/.npm*
|
||||
|
||||
# Remove Yarn
|
||||
brew uninstall yarn
|
||||
rm -rf ~/.yarn
|
||||
|
||||
# Clean up Homebrew
|
||||
brew cleanup
|
||||
|
||||
# Remove package manager cache
|
||||
rm -rf ~/.yarn-cache
|
||||
rm -rf ~/.pnpm-store
|
||||
|
||||
# Remove other version managers
|
||||
brew uninstall n
|
||||
rm -rf /usr/local/n
|
||||
rm -rf /usr/local/bin/n
|
||||
|
||||
# Remove temporary directories
|
||||
rm -rf /tmp/npm-*
|
||||
rm -rf /tmp/node-*
|
||||
rm -rf ~/Library/Caches/com.apple.DiagnosticReporting.nettopologyd/node_modules/
|
||||
|
||||
# Remove Browserify and Webpack cache
|
||||
rm -rf ~/.config/browserify
|
||||
rm -rf ~/.config/webpack
|
||||
rm -rf ~/.cache/webpack
|
||||
|
||||
# Remove Electron cache
|
||||
rm -rf ~/.electron
|
||||
|
||||
# Remove npm and Node.js logs
|
||||
rm -rf ~/.npm/_logs
|
||||
rm -rf ~/.node-gyp/*.log
|
||||
|
||||
# Remove miscellaneous directories
|
||||
rm -rf ~/.node_repl_history
|
||||
rm -rf ~/.v8flags*
|
||||
rm -rf ~/.npm-global
|
||||
rm -rf ~/.nvm-global
|
||||
|
||||
# Remove any references to Node.js or npm from shell profile files
|
||||
sed -i '' '/# Node.js/d' ~/.bashrc ~/.bash_profile ~/.zshrc
|
||||
sed -i '' '/export PATH=.*node.*/d' ~/.bashrc ~/.bash_profile ~/.zshrc
|
||||
sed -i '' '/export PATH=.*npm.*/d' ~/.bashrc ~/.bash_profile ~/.zshrc
|
||||
|
||||
echo "Node.js, npm, and nvm have been removed."
|
7
nv_mount
Executable file
7
nv_mount
Executable file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
SESSION_NAME="$1"
|
||||
# Attach to tmux session and activate Conda environment
|
||||
tmux send-keys -t "$SESSION_NAME" "conda activate $SESSION_NAME" C-m
|
||||
tmux attach -t "$SESSION_NAME"
|
||||
|
8
o
Executable file
8
o
Executable file
|
@ -0,0 +1,8 @@
|
|||
#! /bin/bash
|
||||
|
||||
if [[ -z $(pidof ollama) ]]; then
|
||||
ollama serve &>/dev/null &
|
||||
disown
|
||||
fi
|
||||
|
||||
/usr/bin/env python3 /Users/sij/AI/osh/osh.py $@
|
79
scrape
Executable file
79
scrape
Executable file
|
@ -0,0 +1,79 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Network share URL
|
||||
NETWORK_SHARE="smb://10.13.37.10/Media"
|
||||
|
||||
# Attempt to open the network share using Finder
|
||||
# echo "Attempting to mount the network share..."
|
||||
# open "${NETWORK_SHARE}" || { echo "Failed to access network share."; exit 1; }
|
||||
|
||||
# Optionally, add a sleep command to allow some time for the share to mount before proceeding.
|
||||
# sleep 5
|
||||
|
||||
# First input argument, could be a URL or a variant
|
||||
FIRST_ARG="$1"
|
||||
|
||||
# Function to detect if the input is a URL
|
||||
is_url() {
|
||||
if [[ "$1" =~ ^https?:// ]]; then
|
||||
echo "true"
|
||||
else
|
||||
echo "false"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to determine the variant based on the URL's domain
|
||||
detect_variant_from_url() {
|
||||
local domain=$(echo "$FIRST_ARG" | awk -F/ '{print $3}' | sed -e 's/^www\.//')
|
||||
|
||||
case "$domain" in
|
||||
*incestflix.com)
|
||||
echo "if"
|
||||
;;
|
||||
*xvideos.com)
|
||||
echo "xv"
|
||||
;;
|
||||
*familyporn.tv)
|
||||
echo "fptv"
|
||||
;;
|
||||
*pornhub.com)
|
||||
echo "ph"
|
||||
;;
|
||||
*motherless.com)
|
||||
echo "ml"
|
||||
;;
|
||||
*xnxx.com)
|
||||
echo "xnxx"
|
||||
;;
|
||||
*9vids.com)
|
||||
echo "9v"
|
||||
;;
|
||||
*)
|
||||
echo "unrecognized"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Determine if the first argument is a URL
|
||||
if [[ $(is_url "$FIRST_ARG") == "true" ]]; then
|
||||
VARIANT=$(detect_variant_from_url)
|
||||
if [ "$VARIANT" = "unrecognized" ]; then
|
||||
echo "Domain not recognized. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
# For URLs, pass the entire set of arguments to the scraper script
|
||||
ARGS="$@"
|
||||
else
|
||||
# For direct variant inputs, the variant is the first argument, and the rest are additional parameters
|
||||
VARIANT="$1"
|
||||
# Shift the first argument off, leaving the rest as $@
|
||||
shift
|
||||
ARGS="$@"
|
||||
fi
|
||||
|
||||
# Activate the Conda environment
|
||||
source /home/sij/miniforge3/bin/activate scrape
|
||||
|
||||
# Run the Python script, adjusting for either URL or direct variant input
|
||||
/home/sij/miniforge3/envs/scrape/bin/python "/home/sij/workshop/.private/videoscraper/videoscraper-$VARIANT.py" $ARGS
|
||||
|
40
sij
Executable file
40
sij
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/bin/zsh
|
||||
# #!/bin/bash
|
||||
source /Users/sij/.zshrc
|
||||
|
||||
# Kill the existing tmux server
|
||||
tmux kill-server
|
||||
sleep 2
|
||||
|
||||
# Create the main session and windows
|
||||
tmux new-session -d -s sijapi -n 'Main'
|
||||
|
||||
# Split the main window into three vertical panes
|
||||
tmux split-window -v -t sijapi:Main
|
||||
#tmux split-window -v -t sijapi:Main
|
||||
tmux select-layout even-vertical
|
||||
|
||||
# Configure API pane (top pane)
|
||||
tmux select-pane -t 0
|
||||
tmux send-keys "cd ~/workshop" C-m
|
||||
tmux send-keys "source ~/.zshrc; sleep 1" C-m
|
||||
tmux send-keys "mamba activate sijapi; while true; do python -m sijapi; sleep 1; done" C-m
|
||||
|
||||
# Configure Khoj (middle pane)
|
||||
tmux select-pane -t 1
|
||||
tmux send-keys "source ~/.zshrc" C-m
|
||||
tmux send-keys "mamba activate khoj; export KHOJ_DOMAIN=ai.sij.ai && export KHOJ_ADMIN_EMAIL=sij@env.esq && export KHOJ_ADMIN_PASSWORD='Synchr0!-K' && export KHOJ_DEBUG=True && export DEBUG=true && while true; do khoj --anonymous-mode; sleep 1; done" C-m
|
||||
|
||||
# Configure Ollama (bottom pane)
|
||||
tmux select-pane -t 1
|
||||
tmux send-keys "cd ~/sync/sijapi/api" C-m
|
||||
tmux send-keys "source ~/.zshrc; sleep 1" C-m
|
||||
tmux send-keys "while true; do export OLLAMA_HOST='0.0.0.0:11434' && export OLLAMA_ORIGINS='*' && ollama serve; sleep 1; done" C-m
|
||||
|
||||
# Create separate session for Syncthing
|
||||
# tmux new-session -d -s syncthing -n 'Syncthing'
|
||||
# tmux send-keys "source ~/.zshrc" C-m
|
||||
# tmux send-keys "while true; do /opt/homebrew/bin/syncthing; done" C-m
|
||||
|
||||
# Attach to the main tmux session
|
||||
tmux attach-session -t sijapi
|
23
ssh-scrape
Executable file
23
ssh-scrape
Executable file
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ "$#" -lt 2 ]; then
|
||||
echo "Error: No command provided."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
variant=$1
|
||||
shift # Remove the first argument, which is now stored in 'variant'
|
||||
additional_params="$@" # Remaining arguments
|
||||
|
||||
quoted_params=""
|
||||
for param in "$@"; do
|
||||
quoted_params+="\"$param\" "
|
||||
done
|
||||
|
||||
session_name="scrape-$(date +%Y%m%d%H%M%S)"
|
||||
tailscale up
|
||||
tmux new-session -d -s "$session_name"
|
||||
ssh_command="ssh -t sij@vm 'tmux new-session -d -s \"$session_name\" \"/usr/local/bin/scrape ${variant} ${quoted_params}\"; tmux attach-session -t \"$session_name\"'"
|
||||
tmux send-keys -t "$session_name" "$ssh_command" C-m
|
||||
tmux attach-session -t "$session_name"
|
||||
|
5
st
Executable file
5
st
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
tmux new-session -d -s syncthing -n syncthingpane
|
||||
tmux select-pane -t 0
|
||||
tmux send-keys -t 0 "/opt/homebrew/bin/syncthing" C-m
|
39
summarize
Executable file
39
summarize
Executable file
|
@ -0,0 +1,39 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Check if a filename has been provided
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <filename>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
filename="$1"
|
||||
|
||||
# Check if the file exists
|
||||
if [ ! -f "$filename" ]; then
|
||||
echo "Error: File does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Assuming GLOBAL_API_KEY is exported in your environment
|
||||
if [ -z "$GLOBAL_API_KEY" ]; then
|
||||
echo "Error: GLOBAL_API_KEY is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Endpoint
|
||||
endpoint="https://api.sij.ai/speaksummary"
|
||||
|
||||
# Make the request
|
||||
curl -X POST "$endpoint" \
|
||||
-H "Authorization: Bearer $GLOBAL_API_KEY" \
|
||||
-H "Content-Type: multipart/form-data" \
|
||||
-F "file=@$filename" \
|
||||
-o "response.wav"
|
||||
|
||||
# Check if the output was saved successfully
|
||||
if [ -f "response.wav" ]; then
|
||||
echo "The summary has been processed and saved as 'response.wav'"
|
||||
else
|
||||
echo "Failed to save the summary."
|
||||
fi
|
||||
|
33
temp.txt
Normal file
33
temp.txt
Normal file
|
@ -0,0 +1,33 @@
|
|||
List of files in /Users/sij/Nextcloud/notes with nonconforming names:
|
||||
|
||||
/Users/sij/Nextcloud/notes/clippings/Personal — Mac (Metal) support- · Issue #114 · yl4579-StyleTTS2-58274.md
|
||||
/Users/sij/Nextcloud/notes/clippings/Dependencies missing for Insightface · Issue #162 · cubiq-ComfyUI_IPAdapter_plus · GitHub-12313.md
|
||||
/Users/sij/Nextcloud/notes/clippings/Personal — Enable opening from Finder · Issue #102 · warpdotdev-Warp-50868.md
|
||||
/Users/sij/Nextcloud/notes/clippings/Personal — TTS example on colab not working · Issue #113 · mozilla-TTS-32446.md
|
||||
/Users/sij/Nextcloud/notes/unsorted/<% tp.date.now("YYYY-MM-DD dddd", 1, tp.file.title, "YYYY-MM-DD dddd") %>.md
|
||||
/Users/sij/Nextcloud/notes/unsorted/Awareness > Thought.md
|
||||
/Users/sij/Nextcloud/notes/unsorted/Debate on DGR about "colonial veganism".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/Nov 22, 2022 at 11-51 AM— "Transcription Editing Instructions".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/Happy Mother’s Day, .md
|
||||
/Users/sij/Nextcloud/notes/unsorted/May 19, 2023 at 7-05 PM— "The Best Text-to-Speech Tools".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/2023-05-24 — "Job Change Check-in with Sanjay".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/Sangye & Casetext | Zoom Meeting - [[2023-05-31-Wednesday]].md
|
||||
/Users/sij/Nextcloud/notes/unsorted/2023-05-24 — "Bureau authorizes timber sales impacting owls".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/Jan 30, 2023 at 2-46 PM— "Transcribed Raw Voice Recording".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/What can be appealed?.md
|
||||
/Users/sij/Nextcloud/notes/unsorted/I’ve discovered awe... but what was my name?.md
|
||||
/Users/sij/Nextcloud/notes/unsorted/May 25, 2023 at 12-09— "Exciting Buyout News from Michigan".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/Nov 9, 2022 at 3-10 PM— Title suggestion- "North Project Threatens Spotted Owl".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/Call with .md
|
||||
/Users/sij/Nextcloud/notes/unsorted/Nov 9, 2022 at 15-31— Title- "Habitat loss and endangered owls".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/“Hear Me" Trilogy.md
|
||||
/Users/sij/Nextcloud/notes/unsorted/May 27, 2023 at 14-02— "Transcription Editing Tips".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/May 24, 2023 at 08-06— "Consider Avoiding Grocery Stores".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/Human Rights Watch | Defending Human Rights Worldwide.md
|
||||
/Users/sij/Nextcloud/notes/unsorted/Sep 1, 2021 - Clinic Meeting #2.md
|
||||
/Users/sij/Nextcloud/notes/unsorted/May 25, 2023 at 12-08— "Raw Voice Recording Transcript- Technical Issues".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/May 25, 2023 at 19-32— "Taystex Follow-Up on Co-Counsel Request".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/May 27, 2023 at 14-35— "Voice Recording Test with AI".md
|
||||
/Users/sij/Nextcloud/notes/unsorted/May 27, 2023 at 15-11— "Transcript Editing Suggestions".md
|
||||
/Users/sij/Nextcloud/notes/W\&W breakout.md
|
||||
/Users/sij/Nextcloud/notes/obsidian/resources/awesome-selfhosted#note-taking--editors.webarchive
|
19
ts-info
Executable file
19
ts-info
Executable file
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Function to get exit node details
|
||||
# get_exit_node_details() {
|
||||
# echo $(/Applications/Tailscale.app/Contents/MacOS/Tailscale exit-node list | awk '/'"$1"'/ {print $4", "$3" ("$2")"}')
|
||||
# }
|
||||
|
||||
# Get the current exit node details and public IP
|
||||
# CURRENT_NODE=$(get_exit_node_details 'selected')
|
||||
# CURRENT_IP=$(curl -s ifconfig.me)
|
||||
# DNS_SERVER=$(python3 ~/.dns-info.py)
|
||||
|
||||
# echo "IP address: $CURRENT_IP"
|
||||
# echo "DNS server: $DNS_SERVER"
|
||||
# echo "Exit node: ${CURRENT_NODE:-None}"
|
||||
# echo ""
|
||||
|
||||
READOUT=$(python3 /Users/sij/Scripts/Raycast\ Scripts/vpn-dns-info.py)
|
||||
echo "$READOUT"
|
24
ts-new-node-minimalist
Executable file
24
ts-new-node-minimalist
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Define the path to your Tailscale binary
|
||||
tailscale="/Applications/Tailscale.app/Contents/MacOS/Tailscale"
|
||||
|
||||
# Check if Tailscale is running
|
||||
if ! pgrep "Tailscale" > /dev/null; then
|
||||
echo "Tailscale is not running. Starting Tailscale..."
|
||||
open -a "/Applications/Tailscale.app"
|
||||
# Wait for Tailscale to initialize
|
||||
sleep 5
|
||||
$tailscale up
|
||||
fi
|
||||
|
||||
# Select a new exit node from the whitelist and set it
|
||||
selected_exit_node=$($tailscale exit-node list | grep -f ~/.vpnwhitelist | awk '{print $2}' | shuf -n 1)
|
||||
if [ -n "$selected_exit_node" ]; then
|
||||
# Set the new exit node
|
||||
$tailscale set --exit-node=$selected_exit_node
|
||||
else
|
||||
echo "No valid exit node found."
|
||||
exit 1
|
||||
fi
|
||||
|
85
tts copy
Executable file
85
tts copy
Executable file
|
@ -0,0 +1,85 @@
|
|||
#!/Users/sij/miniforge3/bin/python
|
||||
|
||||
import sys
|
||||
import os
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
import uuid
|
||||
import hashlib
|
||||
from pydub import AudioSegment
|
||||
import torch
|
||||
from TTS.api import TTS # Adjust with actual import
|
||||
from playsound import playsound
|
||||
|
||||
from TTS.api import TTS
|
||||
|
||||
device = torch.device('cpu') # keep trying 'mps' it will eventually be implemented
|
||||
model_name = "tts_models/multilingual/multi-dataset/xtts_v2"
|
||||
tts = TTS(model_name=model_name).to(device)
|
||||
DEFAULT_VOICE = "kiel"
|
||||
|
||||
def select_voice(voice_name: str) -> str:
|
||||
voice_dir = Path('/Users/sij/AI/banana-phone/voices')
|
||||
voice_file = voice_dir / f"{voice_name}.wav"
|
||||
if voice_file.is_file():
|
||||
return str(voice_file)
|
||||
else:
|
||||
print(f"Voice file not found for {voice_name}, using default")
|
||||
return str(voice_dir / f"{DEFAULT_VOICE}.wav")
|
||||
|
||||
def generate_speech(text, speed, voice_file):
|
||||
output_dir = Path(tempfile.gettempdir())
|
||||
output_dir.mkdir(exist_ok=True)
|
||||
|
||||
short_uuid = str(uuid.uuid4())[:8]
|
||||
output_file_name = f"{Path(voice_file).stem}-{short_uuid}.wav"
|
||||
output_file = output_dir / output_file_name
|
||||
|
||||
tts.tts_to_file(
|
||||
text=text,
|
||||
speed=speed,
|
||||
file_path=output_file,
|
||||
speaker_wav=[voice_file],
|
||||
language="en"
|
||||
)
|
||||
|
||||
return output_file
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python script.py <text/file> [voice] [speed]")
|
||||
sys.exit(1)
|
||||
|
||||
text_input = sys.argv[1]
|
||||
if len(text_input) < 255 and os.path.isfile(text_input):
|
||||
with open(text_input, 'r') as file:
|
||||
text = file.read()
|
||||
else:
|
||||
text = text_input
|
||||
|
||||
voice = sys.argv[2] if len(sys.argv) > 2 else DEFAULT_VOICE
|
||||
speed = float(sys.argv[3]) if len(sys.argv) > 3 else 1.1
|
||||
|
||||
voice_file_path = select_voice(voice)
|
||||
|
||||
print(f"Using voice file at {voice_file_path}")
|
||||
|
||||
combined_audio = AudioSegment.silent(duration=0)
|
||||
output_file = generate_speech(text, speed, voice_file_path)
|
||||
combined_audio += AudioSegment.from_wav(str(output_file))
|
||||
|
||||
# Exporting combined audio
|
||||
final_output_path = Path(tempfile.gettempdir()) / "output.wav"
|
||||
combined_audio.export(str(final_output_path), format="wav")
|
||||
|
||||
# Now playing the generated speech file
|
||||
print(f"Playing generated speech from {final_output_path}")
|
||||
playsound(str(final_output_path))
|
||||
|
||||
# Cleanup
|
||||
os.remove(output_file)
|
||||
os.remove(final_output_path)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
16
txtsort
Executable file
16
txtsort
Executable file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Checking if the user provided a file name
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: $0 filename"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Checking if the given file is readable
|
||||
if ! [ -r "$1" ]; then
|
||||
echo "The file '$1' is not readable or does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sort $1
|
||||
|
86
update_calendar
Executable file
86
update_calendar
Executable file
|
@ -0,0 +1,86 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Check if a date parameter is passed
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 <YYYY-MM-DD>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DATE=$1
|
||||
|
||||
# Convert the date to a format that AppleScript expects (MM/DD/YYYY)
|
||||
formatted_date=$(date -j -f "%Y-%m-%d" "$DATE" +"%A, %B %e, %Y at 00:00:00")
|
||||
|
||||
osascript <<EOF
|
||||
set targetDate to date "$formatted_date"
|
||||
set endOfTargetDate to targetDate + (1 * days)
|
||||
|
||||
tell application "Calendar"
|
||||
set exportFolder to (POSIX path of (path to home folder)) & "workshop/sijapi/data/" -- Ensure this path is correct
|
||||
set calendarName to "Calendar" -- Replace with the name of your calendar
|
||||
|
||||
if not (exists calendar calendarName) then
|
||||
return
|
||||
end if
|
||||
|
||||
-- Create a temporary calendar
|
||||
set tempCalendar to make new calendar with properties {name:"TempExportCalendar"}
|
||||
|
||||
-- Copy events from the target calendar to the temporary calendar
|
||||
set cal to calendar calendarName
|
||||
set eventsList to (every event of cal whose start date ≥ targetDate and start date < endOfTargetDate) & (every event of cal whose end date ≥ targetDate and end date < endOfTargetDate)
|
||||
|
||||
repeat with eventItem in eventsList
|
||||
-- Create a new event
|
||||
tell tempCalendar
|
||||
set newEvent to make new event with properties {start date:start date of eventItem, end date:end date of eventItem, summary:(summary of eventItem)}
|
||||
end tell
|
||||
|
||||
-- Add optional properties if they exist
|
||||
try
|
||||
set eventLocation to location of eventItem
|
||||
if eventLocation is not missing value then
|
||||
set location of newEvent to eventLocation
|
||||
end if
|
||||
end try
|
||||
|
||||
try
|
||||
set eventDescription to description of eventItem
|
||||
if eventDescription is not missing value then
|
||||
set description of newEvent to eventDescription
|
||||
end if
|
||||
end try
|
||||
|
||||
try
|
||||
set eventSummary to summary of eventItem
|
||||
if eventSummary is not missing value then
|
||||
set summary of newEvent to eventSummary
|
||||
end if
|
||||
end try
|
||||
|
||||
try
|
||||
set eventAttendees to attendees of eventItem
|
||||
if eventAttendees is not missing value then
|
||||
set attendees of newEvent to eventAttendees
|
||||
end if
|
||||
end try
|
||||
|
||||
try
|
||||
set eventURL to url of eventItem
|
||||
if eventURL is not missing value then
|
||||
set url of newEvent to eventURL
|
||||
end if
|
||||
end try
|
||||
end repeat
|
||||
|
||||
-- Export the temporary calendar
|
||||
set exportFile to (exportFolder & "calendar.ics")
|
||||
set exportPath to POSIX path of exportFile
|
||||
do shell script "mkdir -p " & quoted form of exportFolder -- Ensure the folder exists
|
||||
tell tempCalendar to save in exportPath
|
||||
|
||||
-- Delete the temporary calendar
|
||||
delete calendar "TempExportCalendar"
|
||||
end tell
|
||||
EOF
|
||||
|
2
vbox-img
Executable file
2
vbox-img
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
exec /Applications/VirtualBox.app/Contents/MacOS/vbox-img "$@"
|
2
vboximg-mount
Executable file
2
vboximg-mount
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
exec /Applications/VirtualBox.app/Contents/MacOS/vboximg-mount "$@"
|
13
vm
Executable file
13
vm
Executable file
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
|
||||
tailscale="/Applications/Tailscale.app/Contents/MacOS/Tailscale"
|
||||
# Check if Tailscale is up by looking for a specific output in the tailscale status command.
|
||||
# Adjust the grep search pattern if needed based on your Tailscale setup.
|
||||
if $tailscale status | grep -q "100."; then
|
||||
echo "Connected to Tailscale, SSH'ing to 100.64.64.11..."
|
||||
ssh sij@100.64.64.11
|
||||
else
|
||||
echo "Not connected to Tailscale, SSH'ing to 10.13.37.11..."
|
||||
ssh sij@10.13.37.11
|
||||
fi
|
||||
|
126
vpn
126
vpn
|
@ -1,29 +1,115 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Get the suggested exit node
|
||||
exit_node=$(tailscale exit-node suggest | awk -F': ' '/Suggested exit node/ {print substr($2, 1, length($2)-1)}')
|
||||
import subprocess
|
||||
import requests
|
||||
import argparse
|
||||
import json
|
||||
import random
|
||||
|
||||
# Print the exit node
|
||||
echo "Suggested exit node: $exit_node"
|
||||
PRIVACY_FRIENDLY_COUNTRIES = ['Sweden', 'Switzerland', 'Germany', 'Finland', 'Netherlands', 'Norway']
|
||||
|
||||
# Set the exit node
|
||||
tailscale set --exit-node=$exit_node
|
||||
def get_current_exit_node():
|
||||
result = subprocess.run(['tailscale', 'status', '--json'], capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to get Tailscale status")
|
||||
|
||||
# Verify the exit node
|
||||
exit_node_info=$(curl -s https://am.i.mullvad.net/json)
|
||||
status = json.loads(result.stdout)
|
||||
current_exit_node = status.get('Peer', {}).get('Tailnet', {}).get('ExitNode', {}).get('Name')
|
||||
return current_exit_node
|
||||
|
||||
# Parse the JSON response to get the hostname
|
||||
exit_node_hostname=$(echo $exit_node_info | jq -r '.mullvad_exit_ip_hostname')
|
||||
def set_exit_node():
|
||||
# Get the suggested exit node
|
||||
result = subprocess.run(['tailscale', 'exit-node', 'suggest'], capture_output=True, text=True)
|
||||
exit_node = ''
|
||||
for line in result.stdout.splitlines():
|
||||
if 'Suggested exit node' in line:
|
||||
exit_node = line.split(': ')[1].strip()
|
||||
break
|
||||
|
||||
echo "Current exit node hostname: $exit_node_hostname"
|
||||
print(f"Suggested exit node: {exit_node}")
|
||||
|
||||
# Get the part before the first '.' in the exit_node
|
||||
exit_node_short=$(echo $exit_node | cut -d'.' -f1)
|
||||
# Set the exit node
|
||||
subprocess.run(['tailscale', 'set', f'--exit-node={exit_node}'], check=True)
|
||||
|
||||
# Verify that the exit_node_short and exit_node_hostname are equal
|
||||
if [ "$exit_node_short" == "$exit_node_hostname" ]; then
|
||||
echo "Exit node set successfully!"
|
||||
else
|
||||
echo "Failed to set exit node!"
|
||||
fi
|
||||
# Verify the exit node
|
||||
response = requests.get('https://am.i.mullvad.net/json')
|
||||
exit_node_info = response.json()
|
||||
exit_node_hostname = exit_node_info.get('mullvad_exit_ip_hostname')
|
||||
|
||||
print(f"Current exit node hostname: {exit_node_hostname}")
|
||||
|
||||
# Get the part before the first '.' in the exit_node
|
||||
exit_node_short = exit_node.split('.')[0]
|
||||
|
||||
# Verify that the exit_node_short and exit_node_hostname are equal
|
||||
if exit_node_short == exit_node_hostname:
|
||||
print("Exit node set successfully!")
|
||||
else:
|
||||
print("Failed to set exit node!")
|
||||
|
||||
def unset_exit_node():
|
||||
# Unset the exit node
|
||||
subprocess.run(['tailscale', 'set', '--exit-node='], check=True)
|
||||
print("Exit node unset successfully!")
|
||||
|
||||
def start_exit_node():
|
||||
current_exit_node = get_current_exit_node()
|
||||
if current_exit_node:
|
||||
print(f"Already connected to exit node: {current_exit_node}")
|
||||
else:
|
||||
set_exit_node()
|
||||
|
||||
def get_random_privacy_friendly_exit_node():
|
||||
result = subprocess.run(['tailscale', 'exit-node', 'list'], capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to list Tailscale exit nodes")
|
||||
|
||||
exit_nodes = []
|
||||
for line in result.stdout.splitlines():
|
||||
parts = line.split()
|
||||
if len(parts) > 3 and parts[2] in PRIVACY_FRIENDLY_COUNTRIES:
|
||||
exit_nodes.append(parts[1])
|
||||
|
||||
if not exit_nodes:
|
||||
raise Exception("No privacy-friendly exit nodes available")
|
||||
|
||||
return random.choice(exit_nodes)
|
||||
|
||||
def set_random_privacy_friendly_exit_node():
|
||||
exit_node = get_random_privacy_friendly_exit_node()
|
||||
print(f"Selected random privacy-friendly exit node: {exit_node}")
|
||||
|
||||
# Set the exit node
|
||||
subprocess.run(['tailscale', 'set', f'--exit-node={exit_node}'], check=True)
|
||||
|
||||
# Verify the exit node
|
||||
response = requests.get('https://am.i.mullvad.net/json')
|
||||
exit_node_info = response.json()
|
||||
exit_node_hostname = exit_node_info.get('mullvad_exit_ip_hostname')
|
||||
|
||||
print(f"Current exit node hostname: {exit_node_hostname}")
|
||||
|
||||
# Get the part before the first '.' in the exit_node
|
||||
exit_node_short = exit_node.split('.')[0]
|
||||
|
||||
# Verify that the exit_node_short and exit_node_hostname are equal
|
||||
if exit_node_short == exit_node_hostname:
|
||||
print("Exit node set successfully!")
|
||||
else:
|
||||
print("Failed to set exit node!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='Manage VPN exit nodes.')
|
||||
parser.add_argument('action', choices=['start', 'stop', 'new', 'shh'], help='Action to perform: start, stop, new, or shh')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.action == 'start':
|
||||
start_exit_node()
|
||||
elif args.action == 'stop':
|
||||
unset_exit_node()
|
||||
elif args.action == 'new':
|
||||
set_exit_node()
|
||||
elif args.action == 'shh':
|
||||
set_random_privacy_friendly_exit_node()
|
||||
|
||||
|
|
78
xtts
Executable file
78
xtts
Executable file
|
@ -0,0 +1,78 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Default voice
|
||||
VOICE="m_50_news"
|
||||
|
||||
SERVER="https://api.sij.ai"
|
||||
|
||||
# Initialize ARGUMENT as an empty string
|
||||
ARGUMENT=""
|
||||
|
||||
# Process arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
key="$1"
|
||||
case $key in
|
||||
--voice)
|
||||
VOICE="$2"
|
||||
shift # past argument
|
||||
shift # past value
|
||||
;;
|
||||
--voice=*)
|
||||
VOICE="${key#*=}" # Extracting value after '='
|
||||
shift # past argument
|
||||
;;
|
||||
*)
|
||||
if [ -z "$ARGUMENT" ]; then
|
||||
ARGUMENT="$1"
|
||||
else
|
||||
ARGUMENT="$ARGUMENT $1"
|
||||
fi
|
||||
shift # past argument
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check if text or file argument is provided
|
||||
if [ -z "$ARGUMENT" ]; then
|
||||
echo "Usage: $0 <file or text> [--voice='voice_name']"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TIMESTAMP=$(date +"%Y%m%d%H%M%S")
|
||||
OUTPUT_FILE="/Users/sij/AI/TTS/${TIMESTAMP}_output.wav"
|
||||
|
||||
# Determine if the argument is a file or a string
|
||||
if [[ "$ARGUMENT" == *".txt" ]]; then
|
||||
# It's a file, use the text_file parameter
|
||||
curl -s -X 'POST' \
|
||||
"$SERVER/tts/speak" \
|
||||
-H 'Authorization: Bearer sk-NhrtQwCHNdK5sRZC' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'Content-Type: multipart/form-data' \
|
||||
-F "file=@$ARGUMENT" \
|
||||
-F "voice=$VOICE" \
|
||||
-F 'speed=0.9' > "$OUTPUT_FILE"
|
||||
else
|
||||
# It's a string, process and use the text parameter
|
||||
SIMPLE_TEXT=$(echo "$ARGUMENT" | tr -d '\n' | tr -d '\r' | sed 's/[^a-zA-Z0-9 .,?!-]//g' | sed 's/ */ /g')
|
||||
|
||||
curl -s -X 'POST' \
|
||||
"$SERVER/tts/speak" \
|
||||
-H 'Authorization: Bearer sk-NhrtQwCHNdK5sRZC' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'Content-Type: multipart/form-data' \
|
||||
-F "text=$SIMPLE_TEXT" \
|
||||
-F "voice=$VOICE" \
|
||||
-F 'speed=0.9' > "$OUTPUT_FILE"
|
||||
fi
|
||||
|
||||
# Check if the output file was created
|
||||
if [ ! -f "$OUTPUT_FILE" ]; then
|
||||
echo "Failed to create audio file."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Output the path and play the file
|
||||
echo "Audio file saved: $OUTPUT_FILE"
|
||||
afplay "$OUTPUT_FILE"
|
||||
|
3
z
Executable file
3
z
Executable file
|
@ -0,0 +1,3 @@
|
|||
source ~/.zprofile
|
||||
source ~/.zshrc
|
||||
source ~/.zshenv
|
Loading…
Reference in a new issue