Skip to content

Instantly share code, notes, and snippets.

@Staninna
Last active November 13, 2024 10:04
Show Gist options
  • Save Staninna/a1186880759df955f05ada8140365952 to your computer and use it in GitHub Desktop.
Save Staninna/a1186880759df955f05ada8140365952 to your computer and use it in GitHub Desktop.
bash scripts
#!/bin/bash
JINA_CONFIG_DIR="$HOME/.config/jina"
JINA_STATS_FILE="$JINA_CONFIG_DIR/stats.json"
JINA_CACHE_FILE="$JINA_CONFIG_DIR/cache.json"
CACHE_TTL=3600 # Cache validity in seconds (1 hour)
declare -A JINA_KEY_USAGE
setup_directories() {
mkdir -p "$JINA_CONFIG_DIR"
if [ ! -f "$JINA_STATS_FILE" ]; then
echo '{"current_key":1,"usage":{}}' > "$JINA_STATS_FILE"
fi
if [ ! -f "$JINA_CACHE_FILE" ]; then
echo '{"last_update":"","balances":{}}' > "$JINA_CACHE_FILE"
fi
}
check_dependencies() {
local missing_deps=()
if ! command -v jq >/dev/null 2>&1; then
missing_deps+=("jq")
fi
if ! command -v xclip >/dev/null 2>&1; then
missing_deps+=("xclip")
fi
if [ ${#missing_deps[@]} -ne 0 ]; then
echo "Error: Missing dependencies: ${missing_deps[*]}"
echo "Please install them with: sudo apt install ${missing_deps[*]}"
return 1
fi
return 0
}
count_api_keys() {
local count=1
while true; do
local key_var="JINA_API_KEY_${count}"
[ -z "${!key_var}" ] && break
((count++))
done
echo $((count - 1))
}
get_api_key() {
local key_num=$1
local key_var="JINA_API_KEY_${key_num}"
echo "${!key_var}"
}
fetch_token_balance() {
local api_key=$1
local response
response=$(curl -s "https://embeddings-dashboard-api.jina.ai/api/v1/api_key/user?api_key=${api_key}" \
-H 'accept: */*' \
-H 'origin: https://jina.ai' \
-H 'referer: https://jina.ai/')
echo "$response" | jq -r '.wallet.total_balance // 0'
}
update_token_cache() {
local current_time=$(date +%s)
local last_update=$(jq -r '.last_update' "$JINA_CACHE_FILE")
local force_update=${1:-false}
if [ "$force_update" = true ] || [ -z "$last_update" ] || [ $((current_time - last_update)) -gt $CACHE_TTL ]; then
local balances="{}"
local key_count=$(count_api_keys)
for ((i=1; i<=key_count; i++)); do
local api_key=$(get_api_key $i)
if [ -n "$api_key" ]; then
local balance=$(fetch_token_balance "$api_key")
balances=$(echo $balances | jq --arg key "$i" --arg balance "$balance" '. + {($key): ($balance)}')
fi
done
echo "{\"last_update\":$current_time,\"balances\":$balances}" > "$JINA_CACHE_FILE"
fi
}
get_sorted_keys() {
update_token_cache
jq -r '.balances | to_entries | map({key: .key, value: (.value | tonumber)}) | sort_by(-.value) | map(.key)[]' "$JINA_CACHE_FILE"
}
load_usage_stats() {
if [ -f "$JINA_STATS_FILE" ]; then
while IFS="=" read -r key value; do
JINA_KEY_USAGE[$key]=$value
done < <(jq -r '.usage | to_entries | .[] | "\(.key)=\(.value)"' "$JINA_STATS_FILE")
fi
}
save_usage_stats() {
local key=$1
JINA_KEY_USAGE[$key]=$((${JINA_KEY_USAGE[$key]:-0} + 1))
local usage_json="{"
for k in "${!JINA_KEY_USAGE[@]}"; do
usage_json+="\"$k\":${JINA_KEY_USAGE[$k]},"
done
usage_json="${usage_json%,}}"
echo "{\"current_key\":$key,\"usage\":$usage_json}" > "$JINA_STATS_FILE"
}
reset_usage_stats() {
declare -A JINA_KEY_USAGE
echo '{"current_key":1,"usage":{}}' > "$JINA_STATS_FILE"
}
handle_status() {
update_token_cache
local key_count=$(count_api_keys)
echo "Available API Keys: ${key_count}"
echo "Usage Statistics and Balances:"
while IFS= read -r key; do
local usage=${JINA_KEY_USAGE[$key]:-0}
local balance=$(jq -r ".balances.\"$key\"" "$JINA_CACHE_FILE")
echo " Key #$key: $usage calls, $balance tokens available"
done < <(get_sorted_keys)
}
handle_reset() {
reset_usage_stats
echo "Usage statistics reset"
}
handle_update() {
update_token_cache true
echo "Token balance cache updated"
}
handle_request() {
local url=$1
local key_num=$(get_sorted_keys | head -n1)
local api_key=$(get_api_key $key_num)
if [ -z "$api_key" ]; then
echo "Error: No valid API key found"
return 1
fi
curl "https://r.jina.ai/$url" \
-H "Authorization: Bearer ${api_key}" \
-s | xclip -selection clipboard
save_usage_stats $key_num
echo "Result copied to clipboard (used key #${key_num})"
}
jina() {
setup_directories
check_dependencies || return 1
load_usage_stats
if [ -z "$1" ]; then
echo "Usage: jina <url>"
echo "Commands:"
echo " jina status - Show key usage statistics"
echo " jina reset - Reset usage statistics"
echo " jina update - Force update token balance cache"
return 1
fi
case "$1" in
status)
handle_status
;;
reset)
handle_reset
;;
update)
handle_update
;;
*)
handle_request "$1"
;;
esac
}
#!/bin/bash
readonly LLM_DIR_MAX_FILE_SIZE=1048576 # 1MB in bytes
readonly LLM_DIR_IGNORE_FILE=".llm-dir-ignore"
readonly LLM_DIR_TEMP_DIR="/tmp/llm-dir-$$"
set -euo pipefail
trap cleanup EXIT
cleanup() {
[ -d "$LLM_DIR_TEMP_DIR" ] && rm -rf "$LLM_DIR_TEMP_DIR"
}
log_info() {
echo "[INFO] $1" >&2
}
log_error() {
echo "[ERROR] $1" >&2
return 1
}
load_ignore_patterns() {
local ignore_patterns=()
if [ -f "$LLM_DIR_IGNORE_FILE" ]; then
while IFS= read -r pattern || [ -n "$pattern" ]; do
[[ -z "$pattern" || "$pattern" =~ ^[[:space:]]*# ]] && continue
ignore_patterns+=("$pattern")
done < "$LLM_DIR_IGNORE_FILE"
log_info "Loaded ${#ignore_patterns[@]} ignore patterns from $LLM_DIR_IGNORE_FILE"
fi
printf "%s\n" "${ignore_patterns[@]}"
}
should_ignore_path() {
local path="$1"
local pattern
while IFS= read -r pattern; do
[[ -z "$pattern" ]] && continue
# Add wildcards around the pattern for more flexible matching
if [[ "$path" =~ ^.*${pattern}.*$ ]]; then
return 0 # true, should ignore
fi
done
return 1 # false, should not ignore
}
print_directory_tree() {
local patterns=()
local pattern
while IFS= read -r pattern; do
[[ -z "$pattern" ]] && continue
patterns+=("$pattern")
done
if [ "${#patterns[@]}" -gt 0 ]; then
# Join patterns with | for tree's -I option
local pattern_string
pattern_string=$(IFS="|"; echo "${patterns[*]}")
tree -I "$pattern_string" --dirsfirst
else
tree --dirsfirst
fi
}
process_file() {
local filename="$1"
local filesize
filesize=$(stat -c%s "$filename")
echo -e "\n==== $filename ===="
echo "Size: $(numfmt --to=iec-i --suffix=B "$filesize")"
echo "Last modified: $(stat -c%y "$filename")"
echo -e "====\n"
if [ "$filesize" -gt "$LLM_DIR_MAX_FILE_SIZE" ]; then
echo "[File larger than $LLM_DIR_MAX_FILE_SIZE bytes]"
file "$filename"
return
fi
if file "$filename" | grep -q 'text'; then
echo "Content:"
echo "\`\`\`"
nl -ba "$filename"
echo "\`\`\`"
else
echo "[Non-text file, content skipped]"
file "$filename"
fi
}
dir_to_llm() {
local ignore_patterns
ignore_patterns=$(load_ignore_patterns)
echo "Directory Analysis for LLM Processing"
echo "Generated on: $(date)"
echo "Working directory: $(pwd)"
echo "Ignore patterns:"
echo "\`\`\`"
echo "${ignore_patterns[@]}"
echo "\`\`\`"
echo -e "\nDirectory Structure:"
echo "===================="
echo "$ignore_patterns" | print_directory_tree
echo -e "\nFile Contents:"
echo "=============="
while IFS= read -r -d '' file; do
file="${file#./}"
[[ "$file" == .* ]] && continue # dont wanna post env files and such online hahahaha
[[ -z "$file" ]] && continue # skip empty lines
[[ "$file" == target/* ]] && continue # rust speedy hack ;-;
if echo "$ignore_patterns" | should_ignore_path "$file"; then
continue
fi
process_file "$file"
done < <(find . -type f -print0)
}
copy_to_clipboard() {
if command -v xclip >/dev/null 2>&1; then
xclip -selection clipboard
elif command -v pbcopy >/dev/null 2>&1; then
pbcopy
elif command -v clip.exe >/dev/null 2>&1; then
clip.exe
else
mkdir -p "$LLM_DIR_TEMP_DIR"
log_error "No clipboard command found (xclip, pbcopy, or clip.exe required)"
cat > "$LLM_DIR_TEMP_DIR/output.txt"
echo "Output saved to $LLM_DIR_TEMP_DIR/output.txt (no clipboard command available)"
exit 1
fi
}
alias llm-dir='dir_to_llm | copy_to_clipboard'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment