490 lines
13 KiB
Bash
Executable File
490 lines
13 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
API_URL="http://localhost:5000"
|
|
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 <paste_id>"
|
|
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 <paste_id>"
|
|
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/<paste_id> 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 <paste_id> <username> [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
|
|
|