120 lines
3.2 KiB
Bash
Executable File
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 |