Files
2026-05-16 18:44:34 -04:00

120 lines
3.2 KiB
Bash
Executable File

#!/bin/bash
# Required Raycast metadata parameters:
# @raycast.schemaVersion 1
# @raycast.title Push Clipboard to Paperless
# @raycast.mode silent
# @raycast.packageName Automation
# @raycast.icon 📄
# 1. Configuration
API_URL="http://paperlss.duckdns.org:8008/api/documents/post_document/"
API_TOKEN="aee0db3c33917f4f68e07045c660b156eb2da0d4"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
DISPLAY_DATE=$(date "+%Y-%m-%d %H:%M:%S")
# 2. Check if the clipboard contains an image first
HAS_IMAGE=$(osascript -e 'clipboard info' 2>/dev/null | grep -E "TIFF picture|PNG picture|JPEG picture")
if [ -n "$HAS_IMAGE" ]; then
TMP_IMG=$(mktemp).png
osascript -e "write (the clipboard as «class PNGf») to (open for access POSIX file \"$TMP_IMG\" with write permission)" >/dev/null 2>&1
if [ ! -f "$TMP_IMG" ] || [ ! -s "$TMP_IMG" ]; then
echo "❌ Image extraction failed"
rm -f "$TMP_IMG"
exit 1
fi
STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Token $API_TOKEN" \
-F "document=@${TMP_IMG};filename=clip_${TIMESTAMP}.png" \
-F "title=Clipboard Image ($DISPLAY_DATE)" \
"$API_URL")
rm -f "$TMP_IMG"
if [ "$STATUS_CODE" -eq 200 ] || [ "$STATUS_CODE" -eq 201 ]; then
echo "🖼️ Sent image to Paperless!"
exit 0
else
echo "❌ Image upload failure (HTTP $STATUS_CODE)"
exit 1
fi
fi
# 3. Fallback: Process text by rendering directly to a full-length PNG image using Pillow
CLIP_TEXT=$(pbpaste)
if [ -z "$CLIP_TEXT" ]; then
echo "❌ Clipboard is empty"
exit 1
fi
TMP_PNG=$(mktemp).png
# Generate a high-resolution, single continuous image stream from text strings
python3 - <<EOF "$CLIP_TEXT" "$TMP_PNG"
import sys
import textwrap
from PIL import Image, ImageDraw, ImageFont
text = sys.argv[1]
output_path = sys.argv[2]
raw_lines = text.splitlines()
wrapped_lines = []
# Map raw text while fully maintaining paragraph returns and empty spacers
for line in raw_lines:
if not line.strip():
wrapped_lines.append("")
else:
wrapped_lines.extend(textwrap.wrap(line, width=90))
font_size = 14
line_height = 18
padding = 40
try:
font = ImageFont.truetype("Courier", font_size)
except IOError:
font = ImageFont.load_default()
width = 850
height = (len(wrapped_lines) * line_height) + (padding * 2)
# Instantiate scalable graphic asset layout block
img = Image.new("RGB", (width, height), color="white")
draw = ImageDraw.Draw(img)
# Print lines systematically down the image frame coordinates
y = padding
for line in wrapped_lines:
draw.text((padding, y), line, fill="black", font=font)
y += line_height
img.save(output_path, "PNG")
EOF
if [ ! -f "$TMP_PNG" ] || [ ! -s "$TMP_PNG" ]; then
echo "❌ Image processing failed"
rm -f "$TMP_PNG"
exit 1
fi
# 4. Stream upload generated image straight to Paperless-ngx instance
STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Token $API_TOKEN" \
-F "document=@${TMP_PNG};filename=clip_${TIMESTAMP}.png" \
-F "title=Clipboard Snippet ($DISPLAY_DATE)" \
"$API_URL")
rm -f "$TMP_PNG"
if [ "$STATUS_CODE" -eq 200 ] || [ "$STATUS_CODE" -eq 201 ]; then
echo "📄 Sent snippet image to Paperless!"
else
echo "❌ API Failure (HTTP $STATUS_CODE)"
exit 1
fi