2024-11-16 21:35:48 +01:00
|
|
|
#!/bin/bash
|
|
|
|
|
2025-01-12 12:38:58 +01:00
|
|
|
###
|
|
|
|
# Paste to a Pinnwand pastebin service
|
|
|
|
#
|
|
|
|
# This script uploads text content from files or stdin to a Pinnwand
|
|
|
|
# pastebin instance. It supports specifying expiry times, lexers for
|
|
|
|
# syntax highlighting.
|
|
|
|
#
|
|
|
|
# Features:
|
|
|
|
# - Upload content from files or stdin
|
|
|
|
# - Specify expiry times and lexers for syntax highlighting
|
|
|
|
# - Supports autodetection (if enabled by the server) or explicit
|
|
|
|
# lexer selection
|
|
|
|
#
|
|
|
|
# Dependencies:
|
|
|
|
# - curl: For sending HTTP requests to the Pinnwand API
|
|
|
|
# - jq: For parsing JSON responses and encoding input
|
|
|
|
# - file: For binary file detection
|
|
|
|
#
|
|
|
|
# SPDX-License-Identifier: CC0-1.0
|
|
|
|
###
|
2024-11-17 00:12:42 +01:00
|
|
|
|
2024-11-16 21:35:48 +01:00
|
|
|
# Base URL of the Pinnwand instance
|
2025-01-12 12:38:58 +01:00
|
|
|
PINNWAND_BASE_URL="${PINNWAND_BASE_URL:-https://gist.tnonline.net/api/v1}"
|
|
|
|
|
2024-11-16 21:35:48 +01:00
|
|
|
PASTE_URL="${PINNWAND_BASE_URL}/paste"
|
|
|
|
LEXER_URL="${PINNWAND_BASE_URL}/lexer"
|
|
|
|
|
|
|
|
# Default options
|
|
|
|
expiry="1day"
|
2025-01-12 12:38:58 +01:00
|
|
|
lexer="autodetect"
|
2024-11-16 21:35:48 +01:00
|
|
|
|
|
|
|
# Function to show help information
|
|
|
|
show_help() {
|
|
|
|
local s
|
|
|
|
s=$(basename "$0")
|
|
|
|
cat <<END
|
|
|
|
Usage: $s [options] [file1 file2 ...]
|
|
|
|
|
|
|
|
Options:
|
2025-01-12 12:38:58 +01:00
|
|
|
-e, --expiry <expiry> Set the expiry time for the paste (e.g., 1day,
|
|
|
|
1hour). Default is '1day' if not specified.
|
|
|
|
--expiries List valid expiry periods.
|
2024-11-16 21:35:48 +01:00
|
|
|
-l, --lexer <lexer> Specify the lexer to use for syntax highlighting.
|
2025-01-12 12:38:58 +01:00
|
|
|
Default is 'autodetect' if not specified.
|
|
|
|
--lexers List all available lexers in 'name : description'
|
|
|
|
format.
|
2024-11-16 21:35:48 +01:00
|
|
|
-h, --help Show this help message and exit.
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
$s -e 1hour -l python file1 file2
|
|
|
|
$s --lexers
|
|
|
|
dmesg | $s -l kmsg
|
|
|
|
END
|
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
2025-01-12 12:38:58 +01:00
|
|
|
|
2024-11-16 21:35:48 +01:00
|
|
|
# Function to check if a file or input is binary
|
|
|
|
is_binary() {
|
|
|
|
local input="$1"
|
|
|
|
|
2025-01-12 12:38:58 +01:00
|
|
|
# Use the `file` command to check if the input is binary
|
|
|
|
[[ "$(file --mime-encoding -b -L "$input")" == "binary" ]]
|
2024-11-16 21:35:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Function to post content to Pinnwand
|
|
|
|
post_to_pinnwand() {
|
|
|
|
local expiry="$1"
|
|
|
|
local lexer="$2"
|
|
|
|
shift 2
|
|
|
|
local files=("$@")
|
2025-01-12 12:38:58 +01:00
|
|
|
|
|
|
|
# Create temporary files for payload and response
|
|
|
|
tmp_payload=$(mktemp 2>/dev/null) || { echo "Error: Failed to create a temporary file for payload"; exit 1; }
|
|
|
|
tmp_response=$(mktemp 2>/dev/null) || { echo "Error: Failed to create a temporary file for response"; rm -f "$tmp_payload"; exit 1; }
|
|
|
|
tmp_status=$(mktemp 2>/dev/null) || { echo "Error: Failed to create a temporary file for status code"; rm -f "$tmp_payload" "$tmp_response"; exit 1; }
|
|
|
|
tmp_stdin=$(mktemp 2>/dev/null) || { echo "Error: Failed to create a temporary file for stdin"; rm -f "$tmp_payload" "$tmp_response" "$tmp_status"; exit 1; }
|
|
|
|
trap 'rm -f "$tmp_payload" "$tmp_response" "$tmp_status" "$tmp_stdin"' EXIT
|
|
|
|
|
2024-11-16 21:35:48 +01:00
|
|
|
# Prepare files array for JSON
|
|
|
|
files_json="["
|
|
|
|
|
|
|
|
if [[ "${#files[@]}" -gt 0 ]]; then
|
|
|
|
# Add each file to the JSON array
|
|
|
|
for file in "${files[@]}"; do
|
|
|
|
if [[ -f "$file" ]]; then
|
|
|
|
# Check if the file is binary
|
|
|
|
if is_binary "$file"; then
|
|
|
|
echo "Error: $file is a binary file. Only text files are allowed."
|
|
|
|
exit 1
|
|
|
|
fi
|
2025-01-12 12:38:58 +01:00
|
|
|
|
2024-11-16 21:35:48 +01:00
|
|
|
content=$(<"$file" jq -Rs .) # Read and JSON-encode file content
|
|
|
|
files_json+="{\"name\":\"$(basename "$file")\",\"lexer\":\"$lexer\",\"content\":$content},"
|
|
|
|
else
|
|
|
|
echo "File not found: $file"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
else
|
2025-01-12 12:38:58 +01:00
|
|
|
# Write stdin to a temp file
|
|
|
|
cat > "$tmp_stdin"
|
|
|
|
|
2024-11-16 21:35:48 +01:00
|
|
|
# Check if stdin content is binary
|
2025-01-12 12:38:58 +01:00
|
|
|
if is_binary "$tmp_stdin"; then
|
2024-11-16 21:35:48 +01:00
|
|
|
echo "Error: Input from stdin is binary. Only text content is allowed."
|
|
|
|
exit 1
|
|
|
|
fi
|
2025-01-12 12:38:58 +01:00
|
|
|
|
|
|
|
# Read and JSON-encode stdin content
|
|
|
|
stdin_content=$(<"$tmp_stdin" jq -Rs .)
|
2024-11-16 21:35:48 +01:00
|
|
|
files_json+="{\"name\":\"stdin\",\"lexer\":\"$lexer\",\"content\":$stdin_content},"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Remove trailing comma and close array
|
|
|
|
files_json="${files_json%,}]"
|
|
|
|
|
2025-01-12 12:38:58 +01:00
|
|
|
echo '{"expiry":"'"$expiry"'","files":'"$files_json"'}' > "$tmp_payload"
|
|
|
|
|
|
|
|
# Send the payload using curl and save the response and HTTP status separately
|
|
|
|
curl -s -o "$tmp_response" -w "%{http_code}" -X POST "$PASTE_URL" \
|
|
|
|
-H "Content-Type: application/json" --data @"$tmp_payload" > "$tmp_status"
|
2024-11-16 21:35:48 +01:00
|
|
|
|
2025-01-12 12:38:58 +01:00
|
|
|
# Extract HTTP status code and response body
|
|
|
|
http_code=$(<"$tmp_status")
|
|
|
|
response_body=$(<"$tmp_response")
|
|
|
|
|
|
|
|
# Ensure http_code is a valid number
|
|
|
|
if ! [[ "$http_code" =~ ^[0-9]{3}$ ]]; then
|
|
|
|
echo "Error: Failed to parse HTTP status code. Raw response:"
|
|
|
|
cat "$tmp_response"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Check if the HTTP status code indicates success
|
|
|
|
if [[ "$http_code" -ne 200 ]]; then
|
|
|
|
echo "Error: Failed to create paste (HTTP $http_code). Response body:"
|
|
|
|
echo "$response_body"
|
|
|
|
exit 1
|
|
|
|
fi
|
2024-11-16 21:35:48 +01:00
|
|
|
|
2025-01-12 12:38:58 +01:00
|
|
|
# Extract link and removal URLs from the response body
|
|
|
|
link=$(echo "$response_body" | jq -r '.link')
|
|
|
|
removal=$(echo "$response_body" | jq -r '.removal')
|
2024-11-16 21:35:48 +01:00
|
|
|
|
2025-01-12 12:38:58 +01:00
|
|
|
# Check if the response contains valid URLs
|
|
|
|
if [[ -z "$link" || "$link" == "null" ]]; then
|
|
|
|
echo "Error: Could not create paste. API response:"
|
|
|
|
echo "$response_body"
|
2024-11-16 21:35:48 +01:00
|
|
|
exit 1
|
|
|
|
else
|
|
|
|
echo "Paste URL: $link"
|
|
|
|
echo "Removal URL: $removal"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2025-01-12 12:38:58 +01:00
|
|
|
# Function to fetch and list available expiry times
|
|
|
|
list_expiries() {
|
|
|
|
local expiries
|
|
|
|
|
|
|
|
# Fetch expiry options from the API
|
|
|
|
expiries=$(curl -s "$PINNWAND_BASE_URL/expiry" | jq -r 'keys_unsorted | join(" ")' 2>/dev/null)
|
|
|
|
|
|
|
|
if [[ -z "$expiries" ]]; then
|
|
|
|
echo "Error: Unable to fetch valid expiry options from the server."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "Valid expiry times: $expiries"
|
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
2024-11-16 21:35:48 +01:00
|
|
|
# Function to list available lexers
|
|
|
|
list_lexers() {
|
|
|
|
curl -s "$LEXER_URL" | jq -r '.'
|
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
|
|
|
# Parse command line options
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
|
|
case $1 in
|
|
|
|
-e|--expiry)
|
2025-01-12 12:38:58 +01:00
|
|
|
if [[ -z "$2" || "$2" == -* ]]; then
|
|
|
|
echo "Error: The --expiry option requires a value."
|
|
|
|
exit 1
|
|
|
|
fi
|
2024-11-16 21:35:48 +01:00
|
|
|
expiry="$2"
|
|
|
|
shift 2
|
|
|
|
;;
|
|
|
|
-l|--lexer)
|
2025-01-12 12:38:58 +01:00
|
|
|
if [[ -z "$2" || "$2" == -* ]]; then
|
|
|
|
echo "Error: The --lexer option requires a value."
|
|
|
|
exit 1
|
|
|
|
fi
|
2024-11-16 21:35:48 +01:00
|
|
|
lexer="$2"
|
|
|
|
shift 2
|
|
|
|
;;
|
|
|
|
--lexers)
|
|
|
|
list_lexers
|
|
|
|
;;
|
2025-01-12 12:38:58 +01:00
|
|
|
--expiries)
|
|
|
|
list_expiries
|
|
|
|
;;
|
2024-11-16 21:35:48 +01:00
|
|
|
-h|--help)
|
|
|
|
show_help
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
# Remaining arguments are assumed to be files
|
|
|
|
files=("$@")
|
|
|
|
|
|
|
|
# Post content from provided files or stdin
|
|
|
|
post_to_pinnwand "$expiry" "$lexer" "${files[@]}"
|
2025-01-12 12:38:58 +01:00
|
|
|
|