From aeb143ecb77599028e61887b4e8af863beb86123 Mon Sep 17 00:00:00 2001 From: sanj <67624670+iodrift@users.noreply.github.com> Date: Sun, 23 Jun 2024 13:47:43 -0700 Subject: [PATCH] first commit --- kip | 52 +++++++++++++++++++++++ noon | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++ nv | 40 ++++++++++++++++++ serv | 46 +++++++++++++++++++++ tmux-merge | 41 +++++++++++++++++++ ts-new-node | 59 ++++++++++++++++++++++++++ ts-start | 3 ++ ts-tmux | 3 ++ uninstall | 75 +++++++++++++++++++++++++++++++++ up | 23 +++++++++++ vitals | 77 ++++++++++++++++++++++++++++++++++ 11 files changed, 535 insertions(+) create mode 100755 kip create mode 100755 noon create mode 100755 nv create mode 100755 serv create mode 100755 tmux-merge create mode 100755 ts-new-node create mode 100755 ts-start create mode 100755 ts-tmux create mode 100755 uninstall create mode 100755 up create mode 100755 vitals diff --git a/kip b/kip new file mode 100755 index 0000000..321ce4c --- /dev/null +++ b/kip @@ -0,0 +1,52 @@ +#!/bin/bash + +# Function to install a package +install_package() { + package=$1 + + if mamba list | grep -q "^$package\s"; then + echo "Package '$package' already installed by mamba." + elif pip list | grep -q "^$package\s"; then + echo "Package '$package' already installed by pip." + else + echo "Installing package '$package'." + mamba install -y -c conda-forge "$package" || pip install "$package" + fi +} + +# Function to process Python file for import statements +process_python_file() { + file_path=$1 + # Extracting module names from import statements, handling both 'import' and 'from ... import ...' + IMPORTS=$(grep -E "^import |^from " "$file_path" | \ + awk '{if($1=="from") print $2; else print $2}' | \ + cut -d. -f1 | sort | uniq) + + for package in $IMPORTS; do + echo "Processing $package from $file_path" + install_package $package + done +} + +# Check if any arguments were passed +if [ "$#" -lt 1 ]; then + echo "Usage: kip [ ...] or kip " + exit 1 +fi + +MAMBA_BASE=$(mamba info --base) +export PYTHONPATH="${PYTHONPATH}:${MAMBA_BASE}/${CONDA_DEFAULT_ENV}/lib/python" + +for arg in "$@"; do + # Check if the argument is a Python file + if [[ "$arg" == *.py ]]; then + if [ -f "$arg" ]; then + process_python_file "$arg" + else + echo "File $arg not found." + fi + else + install_package "$arg" + fi +done + diff --git a/noon b/noon new file mode 100755 index 0000000..1c2bb0c --- /dev/null +++ b/noon @@ -0,0 +1,116 @@ +#!/Users/sij/miniforge3/bin/python + +import os +import sys +import argparse + +def ask_for_confirmation(message): + while True: + user_input = input(message + " (y/n): ").strip().lower() + if user_input in ('y', 'n'): + return user_input == 'y' + else: + print("Invalid input. Please enter 'y' or 'n'.") + +def rename_files_orig(root_dir, manual): + for dirpath, _, filenames in os.walk(root_dir, followlinks=False): + for filename in filenames: + if '(orig)' in filename: + orig_filepath = os.path.join(dirpath, filename) + base_filename, ext = os.path.splitext(filename) + new_filename = base_filename.replace('(orig)', '') + new_filepath = os.path.join(dirpath, new_filename + ext) + + if os.path.exists(new_filepath): + new_file_new_name = new_filename + '(new)' + ext + new_file_new_path = os.path.join(dirpath, new_file_new_name) + + if manual: + if not ask_for_confirmation(f"Do you want to rename {new_filepath} to {new_file_new_path}?"): + continue + + if os.path.exists(new_file_new_path): + print(f"Error: Cannot rename {new_filepath} to {new_file_new_path} because the target file already exists.") + continue + + os.rename(new_filepath, new_file_new_path) + print(f'Renamed: {new_filepath} -> {new_file_new_name}') + else: + print(f"No associated file found for: {orig_filepath}") + + orig_file_new_name = new_filename + ext + orig_file_new_path = os.path.join(dirpath, orig_file_new_name) + + if manual: + if not ask_for_confirmation(f"Do you want to rename {orig_filepath} to {orig_file_new_path}?"): + continue + + if os.path.exists(orig_file_new_path): + print(f"Error: Cannot rename {orig_filepath} to {orig_file_new_path} because the target file already exists.") + continue + + os.rename(orig_filepath, orig_file_new_path) + print(f'Renamed: {orig_filepath} -> {orig_file_new_name}') + +def rename_files_new(root_dir, manual): + for dirpath, _, filenames in os.walk(root_dir, followlinks=False): + for filename in filenames: + if '(new)' in filename: + new_filepath = os.path.join(dirpath, filename) + base_filename, ext = os.path.splitext(filename) + orig_filename = base_filename.replace('(new)', '') + orig_filepath = os.path.join(dirpath, orig_filename + ext) + + if os.path.exists(orig_filepath): + orig_file_orig_name = orig_filename + '(orig)' + ext + orig_file_orig_path = os.path.join(dirpath, orig_file_orig_name) + + if manual: + if not ask_for_confirmation(f"Do you want to rename {orig_filepath} to {orig_file_orig_path}?"): + continue + + if os.path.exists(orig_file_orig_path): + print(f"Error: Cannot rename {orig_filepath} to {orig_file_orig_path} because the target file already exists.") + continue + + os.rename(orig_filepath, orig_file_orig_path) + print(f'Renamed: {orig_filepath} -> {orig_file_orig_name}') + else: + print(f"No associated file found for: {new_filepath}") + + new_file_new_name = orig_filename + ext + new_file_new_path = os.path.join(dirpath, new_file_new_name) + + if manual: + if not ask_for_confirmation(f"Do you want to rename {new_filepath} to {new_file_new_path}?"): + continue + + if os.path.exists(new_file_new_path): + print(f"Error: Cannot rename {new_filepath} to {new_file_new_path} because the target file already exists.") + continue + + os.rename(new_filepath, new_file_new_path) + print(f'Renamed: {new_filepath} -> {new_file_new_name}') + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Rename files based on given criteria.') + parser.add_argument('-o', '--orig', action='store_true', help='Rename files ending with (orig)') + parser.add_argument('-n', '--new', action='store_true', help='Rename files ending with (new)') + parser.add_argument('-m', '--manual', action='store_true', help='Manual mode: ask for confirmation before each renaming') + parser.add_argument('directory', nargs='?', default=os.getcwd(), help='Directory to start the search (default: current directory)') + args = parser.parse_args() + + if args.orig and args.new: + print("Error: Please specify either -o or -n, not both.") + sys.exit(1) + + if args.orig: + print("Running in ORIG mode") + rename_files_orig(args.directory, args.manual) + elif args.new: + print("Running in NEW mode") + rename_files_new(args.directory, args.manual) + else: + print("Error: Please specify either -o or -n.") + sys.exit(1) + diff --git a/nv b/nv new file mode 100755 index 0000000..f0775e9 --- /dev/null +++ b/nv @@ -0,0 +1,40 @@ +#!/bin/bash + +SESSION_NAME="$1" +PYTHON_VERSION_INPUT="${2:-3.10}" # Default to 3.8 if not specified + +# Normalize the Python version input +if [[ "$PYTHON_VERSION_INPUT" =~ ^python[0-9.]+$ ]]; then + PYTHON_VERSION="${PYTHON_VERSION_INPUT//python/}" +elif [[ "$PYTHON_VERSION_INPUT" =~ ^py[0-9.]+$ ]]; then + PYTHON_VERSION="${PYTHON_VERSION_INPUT//py/}" +else + PYTHON_VERSION="$PYTHON_VERSION_INPUT" +fi + +# Format for Conda +MAMBA_PYTHON_VERSION="python=$PYTHON_VERSION" + +# Check if Conda environment exists +if ! mamba env list | grep -q "^$SESSION_NAME\s"; then + echo "Creating new Mamba environment: $SESSION_NAME with $MAMBA_PYTHON_VERSION" + mamba create --name "$SESSION_NAME" "$MAMBA_PYTHON_VERSION" --yes +fi + +# Find Conda env directory +CONDA_ENV_DIR=$(mamba env list | grep "^$SESSION_NAME" | awk '{print $2}') + +# Handle tmux session +if ! tmux has-session -t "$SESSION_NAME" 2>/dev/null; then + echo "Creating new tmux session: $SESSION_NAME" + tmux new-session -d -s "$SESSION_NAME" + sleep 2 +fi + +# Attach to tmux session and update PATH before activating Conda environment +sleep 1 +tmux send-keys -t "$SESSION_NAME" "export PATH=\"$MAMBA_ENV_DIR/bin:\$PATH\"" C-m +tmux send-keys -t "$SESSION_NAME" "source ~/.zshrc" C-m +tmux send-keys -t "$SESSION_NAME" "mamba activate $SESSION_NAME" C-m +tmux attach -t "$SESSION_NAME" + diff --git a/serv b/serv new file mode 100755 index 0000000..d17d54c --- /dev/null +++ b/serv @@ -0,0 +1,46 @@ +#!/bin/bash + +# Check if an executable is provided as an argument +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +# Find the executable path using 'which' +EXEC_PATH=$(which "$1") + +# Check if the executable exists +if [ -z "$EXEC_PATH" ]; then + echo "Error: Executable '$1' not found." + exit 1 +fi + +# Get the executable name +EXEC_NAME=$(basename "$EXEC_PATH") + +# Create the launchd plist file content +PLIST_FILE_CONTENT=" + + + + Label + $EXEC_NAME + ProgramArguments + + $EXEC_PATH + + KeepAlive + + RunAtLoad + + +" + +# Create the launchd plist file +PLIST_FILE="$HOME/Library/LaunchAgents/$EXEC_NAME.plist" +echo "$PLIST_FILE_CONTENT" > "$PLIST_FILE" + +# Load the launchd service +launchctl load "$PLIST_FILE" + +echo "Service '$EXEC_NAME' has been created and loaded." diff --git a/tmux-merge b/tmux-merge new file mode 100755 index 0000000..50ec168 --- /dev/null +++ b/tmux-merge @@ -0,0 +1,41 @@ +#!/bin/bash + +# Get the first session as the target for all panes +target_session=$(tmux list-sessions -F '#{session_name}' | head -n 1) +target_window="${target_session}:0" # assuming the first window is index 0 +target_pane="${target_window}.0" # assuming the first pane is index 0 + +# Loop through each session +tmux list-sessions -F '#{session_name}' | while read session; do + # Skip the target session + if [[ "$session" == "$target_session" ]]; then + continue + fi + + # Loop through each window in the session + tmux list-windows -t "$session" -F '#{window_index}' | while read window; do + # Loop through each pane in the window + tmux list-panes -t "${session}:${window}" -F '#{pane_index}' | while read pane; do + source="${session}:${window}.${pane}" + # Check if the source is not the same as the target + if [[ "$source" != "$target_pane" ]]; then + # Join the pane to the target pane + tmux join-pane -s "$source" -t "$target_pane" + fi + done + done + + # After moving all panes from a session, kill the now-empty session + # Check if the session to be killed is not the target session + if [[ "$session" != "$target_session" ]]; then + tmux kill-session -t "$session" + fi +done + +# After moving all panes, you may want to manually adjust the layout. +# For a simple automatic layout adjustment, you can use: +tmux select-layout -t "$target_window" tiled + +# Attach to the master session after everything is merged +tmux attach-session -t "$target_session" + diff --git a/ts-new-node b/ts-new-node new file mode 100755 index 0000000..779582a --- /dev/null +++ b/ts-new-node @@ -0,0 +1,59 @@ +#!/bin/bash + +# TSBINARY=$(which tailscale || echo "tailscale") +TSBINARY='/Applications/Tailscale.app/Contents/MacOS/Tailscale' +VERBOSE=0 + +# Check for -v argument +while getopts "v" option; do + case $option in + v) + VERBOSE=1 + ;; + esac +done + +# Function to get exit node details +get_exit_node_details() { + if [[ $VERBOSE -eq 1 ]]; then + echo "$($TSBINARY exit-node list | awk '/'"$1"'/ {print $4", "$3" ("$2")"}')" + fi +} + +if [[ $VERBOSE -eq 1 ]]; then + # 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) + + # Print the current node and IP + echo "IP address: $CURRENT_IP" + echo "DNS server: $DNS_SERVER" + echo "Exit node: ${CURRENT_NODE:-None}" + echo "" +fi + +# Select a new exit node +SELECTED_NODE=$($TSBINARY exit-node list | grep -v -f ~/.vpnblacklist | awk 'BEGIN {srand()} {print rand() " " $0}' | sort -k1,1n | cut -d ' ' -f2- | awk '{print $2}' | head -n 1) + +# Set the selected node as the exit node +$TSBINARY set --exit-node="$SELECTED_NODE" + +if [[ $VERBOSE -eq 1 ]]; then + # Wait for the network to update + sleep 1 + + # Get the new public IP + NEW_IP=$(curl -s ifconfig.me) + + # Get the new exit node details + NEW_NODE=$(get_exit_node_details "$SELECTED_NODE") + + NEW_DNS=$(python3 ~/.dns-info.py) + + # Print the new node and IP + echo "New Public IP address: $NEW_IP" + echo "New DNS server: $NEW_DNS" + echo "Exit node: ${NEW_NODE:-None}" + echo "" +fi diff --git a/ts-start b/ts-start new file mode 100755 index 0000000..248f21f --- /dev/null +++ b/ts-start @@ -0,0 +1,3 @@ +#!/bin/bash +export PATH=/opt/local/bin:/opt/local/sbin:/Users/sangye/.pyenv/shims:/Library/Frameworks/Python.framework/Versions/3.11/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/ +sudo /opt/homebrew/bin/tailscaled --state=/var/lib/tailscale/tailscaled.state diff --git a/ts-tmux b/ts-tmux new file mode 100755 index 0000000..ccefe2a --- /dev/null +++ b/ts-tmux @@ -0,0 +1,3 @@ +#!/bin/bash +export PATH=/opt/local/bin:/opt/local/sbin:/Users/sangye/.pyenv/shims:/Library/Frameworks/Python.framework/Versions/3.11/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin:/Users/sangye/.local/bin +sudo tmux new-session -d -s tailscale 'ts-start' diff --git a/uninstall b/uninstall new file mode 100755 index 0000000..c284763 --- /dev/null +++ b/uninstall @@ -0,0 +1,75 @@ + +#!/bin/bash + +# Required parameters: +# @raycast.schemaVersion 1 +# @raycast.title Uninstall App +# @raycast.mode fullOutput + +# Optional parameters: +# @raycast.icon 🗑️ +# @raycast.argument1 { "type": "text", "placeholder": "App name" } + +# Documentation: +# @raycast.description Move an application and its related files to the Trash + +app_name="$1" + +move_to_trash() { + local file_path="$1" + osascript -e "tell application \"Finder\" to delete POSIX file \"$file_path\"" > /dev/null 2>&1 +} + +uninstall_app() { + local app_name="$1" + + if [[ ! "$app_name" =~ \.app$ ]]; then + app_name="${app_name}.app" + fi + + local app_paths=$(mdfind "kMDItemKind == 'Application' && kMDItemDisplayName == '${app_name%.*}'") + + if [ -z "$app_paths" ]; then + echo "Application not found. Please check the name and try again." + return 1 + fi + + if [ $(echo "$app_paths" | wc -l) -gt 1 ]; then + echo "Multiple applications found:" + select app_path in $app_paths; do + if [ -n "$app_path" ]; then + break + fi + done + else + app_path=$app_paths + fi + + echo "Are you sure you want to move $app_path to the Trash?" + echo "Type 'yes' to confirm:" + read confirmation + if [ "$confirmation" != "yes" ]; then + echo "Uninstallation cancelled." + return 1 + fi + + echo "Moving $app_path to Trash" + move_to_trash "$app_path" + + echo "Moving related files to Trash..." + local app_identifier=$(mdls -name kMDItemCFBundleIdentifier -r "$app_path") + if [ -n "$app_identifier" ]; then + find /Library/Application\ Support /Library/Caches /Library/Preferences ~/Library/Application\ Support ~/Library/Caches ~/Library/Preferences -name "*$app_identifier*" -maxdepth 1 -print0 | while IFS= read -r -d '' file; do + move_to_trash "$file" + done + else + echo "Couldn't find bundle identifier. Attempting to move files based on app name..." + find /Library/Application\ Support /Library/Caches /Library/Preferences ~/Library/Application\ Support ~/Library/Caches ~/Library/Preferences -name "*${app_name%.*}*" -maxdepth 1 -print0 | while IFS= read -r -d '' file; do + move_to_trash "$file" + done + fi + + echo "Uninstallation complete. Files have been moved to the Trash." +} + +uninstall_app "$app_name" diff --git a/up b/up new file mode 100755 index 0000000..8825538 --- /dev/null +++ b/up @@ -0,0 +1,23 @@ +#!/bin/bash + +# Navigate to your project directory +cd ~/workshop/sijapi + +# Pull the latest changes from the repository +echo "Pulling from main branch..." +git pull origin main + +# Add changes to the Git index (staging area) +echo "Adding all changes..." +git add . + +# Commit changes +echo "Committing changes..." +git commit -m "Auto-update: $(date)" + +# Push changes to the remote repository +echo "Pushing all changes..." +git push origin main + +echo "Update complete!" + diff --git a/vitals b/vitals new file mode 100755 index 0000000..f294bb0 --- /dev/null +++ b/vitals @@ -0,0 +1,77 @@ +#!/bin/bash + +tailscale='/Applications/Tailscale.app/Contents/MacOS/Tailscale' + +# Get local IP +local_ip=$(hostname -I | awk '{print $1}') +wan_info=$(curl -s --max-time 10 https://am.i.mullvad.net/json) +wan_connected=false +if [ ! -z "$wan_info" ]; then + wan_connected=true + wan_ip=$(echo "$wan_info" | jq -r '.ip') + mullvad_exit_ip=$(echo "$wan_info" | jq '.mullvad_exit_ip') + blacklisted=$(echo "$wan_info" | jq '.blacklisted.blacklisted') +else + wan_ip="Unavailable" +fi + +# Check if Tailscale is installed and get IP +if command -v $tailscale &> /dev/null; then + has_tailscale=true + tailscale_ip=$($tailscale ip -4) + # Get Tailscale exit-node information + ts_exitnode_output=$($tailscale exit-node list) + # Parse exit node hostname + if echo "$ts_exitnode_output" | grep -q 'selected'; then + mullvad_exitnode=true + # Extract the hostname of the selected exit node + mullvad_hostname=$(echo "$ts_exitnode_output" | grep 'selected' | awk '{print $2}') + else + mullvad_exitnode=false + mullvad_hostname="" + fi +else + has_tailscale=false + tailscale_ip="Not installed" + mullvad_exitnode=false + mullvad_hostname="" +fi + +nextdns_info=$(curl -sL --max-time 10 https://test.nextdns.io) +if [ -z "$nextdns_info" ]; then + echo "Failed to fetch NextDNS status or no internet connection." +else + nextdns_status=$(echo "$nextdns_info" | jq -r '.status') + if [ "$nextdns_status" = "unconfigured" ]; then + echo "You are not using NextDNS." + nextdns_connected=false + nextdns_protocol="" + nextdns_client="" + else + nextdns_connected=true + nextdns_protocol=$(echo "$nextdns_info" | jq -r '.protocol') + nextdns_client=$(echo "$nextdns_info" | jq -r '.clientName') + echo "Connected to NextDNS via $nextdns_protocol. Client: $nextdns_client." + fi +fi + +# read uptime_seconds _ < /proc/uptime +# uptime_days=$(echo "$uptime_seconds / 86400" | bc -l) +# uptime_rounded=$(printf "%.2f" $uptime_days) + +cat <