#!/bin/bash API_URL="https://paste.priet.us" TOKEN_FILE="$HOME/.pastebin_token" load_token() { [[ -f "$TOKEN_FILE" ]] && TOKEN=$(cat "$TOKEN_FILE") || TOKEN="" } save_token() { echo "$TOKEN" > "$TOKEN_FILE" } authenticate() { local username="$1" password="$2" response=$(curl -s -X POST "$API_URL/api/token" \ -H "Content-Type: application/json" \ -d '{"username": "'$username'", "password": "'$password'"}') if echo "$response" | grep -q 'token'; then TOKEN=$(echo "$response" | jq -r '.token') save_token echo "Authentication successful. Token saved." else echo "Authentication failed: $(echo "$response" | jq -r '.error')" exit 1 fi } list_users() { load_token if [[ -z "$TOKEN" ]]; then echo "Error: No token found. Please authenticate first." return 1 fi response=$(curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/api/users") error_msg=$(echo "$response" | jq -r '.error // empty') if [[ -n "$error_msg" ]]; then echo "Error: $error_msg" return 1 fi usernames=$(echo "$response" | jq -r '.users[]') echo "$usernames" } remove_gps_metadata() { local paste_id="$1" load_token if [[ -z "$TOKEN" ]]; then echo "Error: No token found. Please authenticate first." return 1 fi if [[ -z "$paste_id" ]]; then echo "Usage: $0 remove_gps " return 1 fi response=$(curl -s -X POST "$API_URL/api/removegps" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d "{\"paste_id\": $paste_id}") success=$(echo "$response" | jq -r '.success // empty') if [[ "$success" == "true" ]]; then echo "✅ GPS metadata successfully removed from paste ID $paste_id" else error_msg=$(echo "$response" | jq -r '.error // empty') echo "❌ Error: $error_msg" fi } edit_paste() { local paste_id="$1" load_token # Chequear token if [[ -z "$TOKEN" ]]; then echo "Error: No token found. Please authenticate first." return 1 fi if [[ -z "$paste_id" ]]; then echo "Usage: $0 edit " return 1 fi # 1. Descargar contenido JSON del paste echo "Fetching current content of paste $paste_id..." response=$(curl -s -H "Authorization: Bearer $TOKEN" \ "$API_URL/paste/$paste_id/json") # Checar error error_msg=$(echo "$response" | jq -r '.error // empty') if [[ -n "$error_msg" ]]; then echo "Error: $error_msg" return 1 fi # 2. Extraer el contenido, filename, etc. current_content=$(echo "$response" | jq -r '.content // empty') paste_filename=$(echo "$response" | jq -r '.filename // empty') paste_language=$(echo "$response" | jq -r '.language // empty') # 3. Decidir la extensión local: # a) tratar de inferirla de paste_filename # b) si no hay, usar language # c) fallback a "txt" # Extraer extensión del filename, si existe extension="txt" if [[ -n "$paste_filename" ]]; then # e.g. "myscript.py" -> ".py" ext_from_name="${paste_filename##*.}" # todo lo que viene después de la última. if [[ "$ext_from_name" != "$paste_filename" ]]; then extension="$ext_from_name" fi elif [[ -n "$paste_language" ]]; then # Una pequeña tabla de mapeo básico case "$paste_language" in python) extension="py" ;; javascript|js) extension="js" ;; typescript|ts) extension="ts" ;; java) extension="java" ;; c) extension="c" ;; cpp|c++) extension="cpp" ;; bash|shell) extension="sh" ;; html) extension="html" ;; css) extension="css" ;; json) extension="json" ;; sql) extension="sql" ;; *) extension="txt" ;; esac fi # 4. Crear archivo temporal con esa extensión temp_file=$(mktemp "/tmp/paste_${paste_id}_XXXXXX.${extension}") # 5. Guardar el contenido en el archivo y abrir editor echo "$current_content" > "$temp_file" "${EDITOR:-nano}" "$temp_file" # 6. Leer el contenido editado new_content=$(cat "$temp_file") if [[ -z "$new_content" ]]; then echo "No content provided. Aborting." rm -f "$temp_file" return 1 fi # 7. Convertir a JSON con jq -Rs '.' new_content_json=$(echo "$new_content" | jq -Rs '.') # 8. Enviar PUT /api/paste/ con el nuevo contenido update_response=$(curl -s -X PUT "$API_URL/api/paste/$paste_id" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"content":'"$new_content_json"'}') # 9. Mostrar resultado msg=$(echo "$update_response" | jq -r '.message // .error // empty') if [[ -n "$msg" ]]; then echo "$msg" else echo "$update_response" fi # 10. Limpieza rm -f "$temp_file" } unshare_paste() { local paste_id="$1" username="$2" load_token if [[ -z "$TOKEN" ]]; then echo "Error: No token found. Please authenticate first." return 1 fi if [[ -z "$paste_id" || -z "$username" ]]; then echo "Error: Paste ID and username are required." return 1 fi response=$(curl -s -X POST "$API_URL/api/paste/$paste_id/unshare" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"username": "'$username'"}') if echo "$response" | grep -q '"message"'; then echo "$response" | jq -r '.message' else echo "Error: $(echo "$response" | jq -r '.error')" fi } share_paste() { local paste_id="$1" local username="$2" local can_edit_input="${3:-false}" # Por defecto, no se permite editar load_token if [[ -z "$TOKEN" ]]; then echo "Error: No token found. Please authenticate first." return 1 fi # Validación de argumentos if [[ -z "$paste_id" || -z "$username" ]]; then echo "Usage: share_paste [can_edit (true|false)]" return 1 fi # Validar que can_edit sea 'true' o 'false' if [[ "$can_edit_input" != "true" && "$can_edit_input" != "false" ]]; then echo "Error: can_edit must be 'true' or 'false'." return 1 fi # Convertir la entrada can_edit a booleano JSON if [[ "$can_edit_input" == "true" ]]; then can_edit_json=true else can_edit_json=false fi # Construir el JSON de manera segura usando jq json_data=$(jq -n --arg username "$username" --argjson can_edit "$can_edit_json" \ '{username: $username, can_edit: $can_edit}') # Verificar que json_data es válido if [[ -z "$json_data" ]]; then echo "Error: Failed to construct JSON data." return 1 fi # Realizar la solicitud POST al endpoint y capturar la respuesta y el código HTTP response=$(curl -s -w "\n%{http_code}" -X POST "$API_URL/api/paste/$paste_id/share" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d "$json_data") # Separar el cuerpo de la respuesta y el código de estado http_body=$(echo "$response" | sed '$d') http_code=$(echo "$response" | tail -n1) # Manejar la respuesta según el código de estado if [[ "$http_code" == "200" ]]; then echo "$http_body" | jq elif [[ "$http_code" == "400" || "$http_code" == "403" || "$http_code" == "404" || "$http_code" == "500" ]]; then echo "$http_body" | jq -r '.error // .message' else echo "Unexpected HTTP code: $http_code" echo "$http_body" fi } list_shared_with_others() { load_token if [[ -z "$TOKEN" ]]; then echo "Error: No token found. Please authenticate first." return 1 fi response=$(curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/api/shared_with_others") echo "$response" | jq } list_shared_with_me() { load_token if [[ -z "$TOKEN" ]]; then echo "Error: No token found. Please authenticate first." return 1 fi response=$(curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/api/shared_with_me") echo "$response" | jq } list_favorites() { load_token if [[ -z "$TOKEN" ]]; then echo "Error: No token found. Please authenticate first." return 1 fi response=$(curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/api/favorites") echo "$response" | jq } download() { local paste_id="$1" load_token if [[ -z "$TOKEN" ]]; then echo "Error: No token found. Please authenticate first." return 1 fi # Solicitar el archivo y guardar las cabeceras en un archivo temporal response=$(curl -s -w "%{http_code}" -D headers.tmp -o "paste_${paste_id}.tmp" \ -H "Authorization: Bearer $TOKEN" "$API_URL/api/paste/$paste_id/download") # Extraer el código HTTP del final de la respuesta http_code=$(echo "$response" | tail -n1) if [[ "$http_code" -eq 200 ]]; then # Extraer el nombre del archivo del encabezado "Content-Disposition" filename=$(grep -i "Content-Disposition" headers.tmp | grep -o 'filename="[^"]*"' | sed 's/filename=//' | tr -d '"') if [[ -z "$filename" ]]; then # Si no se encuentra el encabezado, usar un nombre genérico file_extension=$(file --mime-type -b "paste_${paste_id}.tmp" | awk -F'/' '{print $2}') filename="paste_${paste_id}.${file_extension}" fi mv "paste_${paste_id}.tmp" "$filename" echo "Paste $paste_id downloaded to $filename" elif [[ "$http_code" -eq 403 ]]; then echo "Error: You do not have permission to download paste $paste_id." rm -f "paste_${paste_id}.tmp" elif [[ "$http_code" -eq 404 ]]; then echo "Error: Paste $paste_id not found." rm -f "paste_${paste_id}.tmp" else echo "Failed to download paste $paste_id (HTTP code: $http_code)" rm -f "paste_${paste_id}.tmp" fi # Limpieza rm -f headers.tmp } download_favorites() { load_token if [[ -z "$TOKEN" ]]; then echo "Error: No token found. Please authenticate first." return 1 fi response=$(curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/api/favorites") echo "$response" | jq -r '.[] | @base64' | while read paste; do paste_id=$(echo "$paste" | base64 --decode | jq -r '.id') download "$paste_id" done } create_paste() { # local lang="$1" local expire="${1:-yes}" local private="${2:-no}" # ✅ Nuevo parámetro opcional, por defecto "no" echo "Enter the content for the paste (Ctrl+D to finish):" content=$(cat) [[ -z "$content" ]] && { echo "Error: Paste content cannot be empty."; exit 1; } response=$(echo "$content" | curl -s -X POST "$API_URL/paste" \ -H "Authorization: Bearer $TOKEN" \ -F "c=@-" \ -F "expire=$expire" \ $( [[ "$private" == "yes" ]] && echo "-F private=true" ) ) # ✅ Se envía "private=true" solo si es necesario echo "$response" | jq -r '.url // .error' } upload_file() { local file="$1" local expire="${2:-yes}" local private="${3:-no}" [[ ! -f "$file" ]] && { echo "Error: File not found."; exit 1; } response=$(curl -s -X POST "$API_URL/paste" \ -H "Authorization: Bearer $TOKEN" \ -F "c=@$file" \ -F "expire=$expire" \ $( [[ "$private" == "yes" ]] && echo "-F private=true" ) ) # ✅ Se envía "private=true" solo si es necesario echo "$response" | jq -r '.url // .error' } view_paste() { local paste_id="$1" response=$(curl -s "$API_URL/paste/$paste_id/json" \ -H "Authorization: Bearer $TOKEN") echo "$response" | jq -r '.content // .error' } list_pastes() { response=$(curl -s "$API_URL/pastes" -H "Authorization: Bearer $TOKEN") echo "$response" | jq } delete_paste() { local paste_id="$1" response=$(curl -s -X DELETE "$API_URL/paste/$paste_id" \ -H "Authorization: Bearer $TOKEN") echo "$response" } view_raw() { local paste_id="$1" response=$(curl -s "$API_URL/paste/$paste_id/raw" \ -H "Authorization: Bearer $TOKEN") echo "$response" } register_user() { local username="$1" password="$2" response=$(curl -s -X POST "$API_URL/register" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{"username": "'$username'", "password": "'$password'"}') echo "$response" } details() { response=$(curl -s -X GET "$API_URL/user/details" \ -H "Authorization: Bearer $TOKEN") echo "$response" | jq } search_pastes() { local query="$1" response=$(curl -s -X GET "$API_URL/pastes/search?q=$query" \ -H "Authorization: Bearer $TOKEN") echo "$response" | jq } add_to_favorites() { local paste_id="$1" load_token if [[ -z "$TOKEN" ]]; then echo "Error: No token found. Please authenticate first." return 1 fi response=$(curl -s -X POST "$API_URL/api/paste/$paste_id/favorite" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json") echo "$response" } remove_from_favorites() { local paste_id="$1" load_token if [[ -z "$TOKEN" ]]; then echo "Error: No token found. Please authenticate first." return 1 fi response=$(curl -s -X POST "$API_URL/api/paste/$paste_id/unfavorite" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json") echo "$response" } load_token case "$1" in login) authenticate "$2" "$3" ;; edit) edit_paste "$2" ;; shared_with_others) list_shared_with_others ;; shared_with_me) list_shared_with_me ;; download) download "$2" ;; list_favorites) list_favorites ;; remove_gps) remove_gps_metadata "$2" ;; favorite) add_to_favorites "$2" ;; unfavorite) remove_from_favorites "$2" ;; create) create_paste "$2" "$3" ;; upload) upload_file "$2" "$3" "$4" ;; view) view_paste "$2" ;; share) share_paste "$2" "$3" "$4" ;; unshare) unshare_paste "$2" "$3" ;; list) list_pastes ;; delete) delete_paste "$2" ;; view_raw) view_raw "$2" ;; register) register_user "$2" "$3" ;; details) details ;; search) search_pastes "$2" ;; *) echo "Usage: $0 {login|create|upload|view|list|delete|view_raw|register|details|search|favorite|unfavorite|shared_with_others|shared_with_me|share|unshare|remove_gps}" ;; esac