Compare commits
18 Commits
b3de100aed
...
25777321e0
Author | SHA1 | Date | |
---|---|---|---|
25777321e0 | |||
a3b6837849 | |||
f86cebad72 | |||
929578cfd2 | |||
5aec8f04a1 | |||
bf786dfc8f | |||
e8d861b8e5 | |||
c3e4ba4cfb | |||
b76608d53d | |||
2615557e43 | |||
4a02110b2e | |||
![]() |
669f5f92f3 | ||
![]() |
7a776bcf7f | ||
![]() |
a114e18fdf | ||
![]() |
e4602aeeec | ||
![]() |
e8e8080e08 | ||
a796d694b2 | |||
c9596e0a28 |
130
README.md
130
README.md
@ -1,3 +1,129 @@
|
|||||||
# imgbb-uploader
|
# ImgBB Upload Script (`imgbb`)
|
||||||
|
|
||||||
Small script to upload an image from clipboard or file to imgbb.com. URL is then inserted directly into clipboard ready to be pasted to IRC or.. wherever.
|
[](https://www.gnu.org/licenses/gpl-3.0) A simple Bash script to quickly upload images from the system clipboard (X11) or a specified file directly to [ImgBB](https://imgbb.com/) using their v1 API. It retrieves the direct image URL, prints it to STDOUT, and copies it to the X11 clipboard.
|
||||||
|
|
||||||
|
Ideal for quickly sharing screenshots or images in environments like IRC without needing to manually use the website interface.
|
||||||
|
|
||||||
|
**Author:** Ritchie Cunningham <ritchie@ritchiecunningham.co.uk>
|
||||||
|
|
||||||
|
**Contributors:** dacav <dacav@fastmail.com>
|
||||||
|
|
||||||
|
**Version:** 2.0 (as of 25/04/2025)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
* Upload images directly from the clipboard (PNG or JPEG).
|
||||||
|
* Upload images directly from a file path.
|
||||||
|
* Set an optional auto-deletion expiration time (e.g., `5m`, `2h`, `7d`, `0` for none).
|
||||||
|
* Specify a custom filename for the uploaded image on ImgBB.
|
||||||
|
* Optionally output and copy the URL in Markdown format.
|
||||||
|
* Optionally output and copy the URL in orgmode format.
|
||||||
|
* Takes screenshot of selected region.
|
||||||
|
* Takes screenshot of selected display.
|
||||||
|
* Copies the resulting URL to the X11 clipboard.
|
||||||
|
* Provides desktop notifications for progress and success/failure (optional).
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
Make sure you have the following command-line tools installed:
|
||||||
|
|
||||||
|
* **curl:** Used for making the HTTP API request.
|
||||||
|
```bash
|
||||||
|
sudo apt install curl # Debian.
|
||||||
|
```
|
||||||
|
* **jq:** Used for parsing the JSON API response.
|
||||||
|
```bash
|
||||||
|
sudo apt install jq # Debian.
|
||||||
|
```
|
||||||
|
* **xclip:** Used for accessing the X11 clipboard. **This is for X11. Wayland users, see below..**
|
||||||
|
```bash
|
||||||
|
sudo apt install xclip # Debian.
|
||||||
|
```
|
||||||
|
* **wl-clipboard** Used for accessing the Wayland clipboard. **This is for Wayland. X11 users, see above.**
|
||||||
|
* **notify-send (Optional):** Used for desktop notifications. The script works without it but won't show popups.
|
||||||
|
```bash
|
||||||
|
sudo apt install notify-send # Debian (often in libnotify-bin).
|
||||||
|
```
|
||||||
|
* **scrot (Optional)**: Used for taking screenshots.
|
||||||
|
``` bash
|
||||||
|
sudo apt install scrot # Debian.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. **Clone the repository:**
|
||||||
|
```bash
|
||||||
|
git clone git@git.ritchiecunningham.co.uk:Rtch/imgbb-uploader.git
|
||||||
|
cd imgbb-uploader
|
||||||
|
```
|
||||||
|
2. **Make the script executable:**
|
||||||
|
```bash
|
||||||
|
chmod +x imgbb
|
||||||
|
```
|
||||||
|
3. **Place in your PATH (Recommended):** Create a symbolic link to the script from a directory in your `$PATH` for easy execution (e.g., `~/.local/bin`, ensure this is in your `$PATH`).
|
||||||
|
```bash
|
||||||
|
mkdir -p ~/.local/bin
|
||||||
|
ln -s "$(pwd)/imgbb" ~/.local/bin/imgbb
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
This script requires a **free API key** from ImgBB:
|
||||||
|
|
||||||
|
1. Go to [https://api.imgbb.com/](https://api.imgbb.com/) and register or log in to get your key.
|
||||||
|
2. Set the API key using *one* of these methods (script checks in this order):
|
||||||
|
* Store the key in `.config/imgbb/uploader/api_key`.
|
||||||
|
* **File** Move the `imgbb_uploader.conf` from the root directory of this project into `~/.config`.
|
||||||
|
* Edit the file to include your API key, and optionally set up your own personal defaults.
|
||||||
|
```bash
|
||||||
|
# Set permissions so only you can read it:
|
||||||
|
chmod 600 ~/.config/imgbb_uploader.conf
|
||||||
|
```
|
||||||
|
* **Environment Variable:** Set the `IMGBB_API_KEY` variable in your environment
|
||||||
|
```bash
|
||||||
|
export IMGBB_API_KEY="YOUR KEY HERE"
|
||||||
|
```
|
||||||
|
Now you can just run `imgbb` from your terminal.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
**Options:**
|
||||||
|
|
||||||
|
* `[filepath]` : Optional path to an image file to upload. If omitted, uses the clipboard content.
|
||||||
|
* `-e, --expire DURATION`: Set auto-deletion timeout. DURATION is a number followed by `s`(econds), `m`(inutes), `h`(ours), or `d`(ays) (e.g., `5m`, `2h`, `7d`, `300s`). Range: 60s-180d. Use `0`, `none`, or `never` for no expiration (overrides the default). Default expiration is 2 hours (7200s) if this option is not used.
|
||||||
|
* `-n, --name NAME`: Set a custom filename for the uploaded image on ImgBB.
|
||||||
|
* `--markdown`: Output and copy the URL in Markdown image format: ``
|
||||||
|
* `--org`: Output and copy the URL in Orgmode image format: `[[url][alt text]]`
|
||||||
|
* `-s, --select`: Take screenshot of selected area for upload.
|
||||||
|
* `-M, --monitor NUM`: Take screenshot of monitor NUM (e.g., 0, 1) for upload.
|
||||||
|
* `-h, --help`: Show the help message and exit.
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Upload image from clipboard, expire in 2 hours (default)
|
||||||
|
imgbb
|
||||||
|
|
||||||
|
# Upload specific image file, expire in 2 hours
|
||||||
|
imgbb screenshot.png
|
||||||
|
|
||||||
|
# Upload from clipboard, expire in 10 minutes
|
||||||
|
imgbb -e 10m
|
||||||
|
|
||||||
|
# Upload from clipboard, never expire
|
||||||
|
imgbb -e 0
|
||||||
|
|
||||||
|
# Upload file, give it a name on ImgBB, get Markdown output/copy
|
||||||
|
imgbb -n "Cool Diagram" --markdown diagram.jpg
|
||||||
|
|
||||||
|
# Take screenshot of selected region and upload
|
||||||
|
imgbb -s
|
||||||
|
|
||||||
|
# Take screenshot of display #2 and upload
|
||||||
|
imgbb -M 2
|
||||||
|
|
||||||
|
# Show help
|
||||||
|
imgbb -h
|
||||||
|
|
||||||
|
# Notes
|
||||||
|
|
||||||
|
- Supports both X11 (using xclip) and Wayland (using wl-clipboard) sessions. It detects the session type using $XDG_SESSION_TYPE.
|
||||||
|
478
imgbb
Executable file
478
imgbb
Executable file
@ -0,0 +1,478 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Script Name: imgbb
|
||||||
|
# Description: Uploads an image from the system clipboard or a specified file
|
||||||
|
# to ImgBB (imgbb.com) using their V1 API. Retrieves the direct
|
||||||
|
# image URL, prints it to stdout, and copies it to the X11 clipboard.
|
||||||
|
# Author: Ritchie Cunningham <ritchie@ritchiecunningham.co.uk>
|
||||||
|
# Contributors: dacav <dacav@fastmail.com>
|
||||||
|
# License: GPL 3.0 License
|
||||||
|
# Version: 2.0
|
||||||
|
# Date: 22/04/2025
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# === Default Configuration & Argument Parsing. ===
|
||||||
|
|
||||||
|
config_file="$HOME/.config/imgbb_uploader.conf"
|
||||||
|
imgbb_api_url="https://api.imgbb.com/1/upload"
|
||||||
|
# imgbb first reads defaults from ~/.config/imgbb_uploader.conf.
|
||||||
|
# If defaults not found in the config file, it reads them from the values
|
||||||
|
# assigned below.
|
||||||
|
# Optional flags override both config and values below.
|
||||||
|
api_key=""
|
||||||
|
filepath=""
|
||||||
|
expire_seconds=""
|
||||||
|
custom_name=""
|
||||||
|
markdown_mode="false"
|
||||||
|
org_mode="false"
|
||||||
|
select_mode="false"
|
||||||
|
monitor_num=""
|
||||||
|
screenshot_tool=""
|
||||||
|
clipboard="$XDG_SESSION_TYPE"
|
||||||
|
|
||||||
|
[ ! -e "$config_file" ] || . "$config_file"
|
||||||
|
|
||||||
|
print_usage() {
|
||||||
|
echo "Usage: $(basename "$0") [options] [filepath]"
|
||||||
|
echo "Uploads image from clipboard (default) or filepath to ImgBB."
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " [filepath] Optional path to an image file to upload."
|
||||||
|
echo " -e, --expire DURATION Set auto-deletion timeout. DURATION is a number"
|
||||||
|
echo " followed by s(econds), m(inutes), h(ours), or d(ays)."
|
||||||
|
echo " Default unit is minutes if unspecified."
|
||||||
|
echo " '0', 'none', 'never' to override default expiry."
|
||||||
|
echo " -n, --name NAME Set a custom filename for the uploaded image."
|
||||||
|
echo " --markdown Output/copy the URL in Markdown image format."
|
||||||
|
echo " --org Output/copy the URL in Orgmode image format."
|
||||||
|
echo " -s, --select Take screenshot of selected area for upload."
|
||||||
|
echo " -M, --monitor NUM Take screenshot of monitor NUM (e.g., 0, 1) for upload"
|
||||||
|
echo " -h, --help Show this help message."
|
||||||
|
}
|
||||||
|
|
||||||
|
die() {
|
||||||
|
declare msg
|
||||||
|
|
||||||
|
msg="$*"
|
||||||
|
notify_cmd -u critical "ImgBB Upload Error" "$msg" &>/dev/null
|
||||||
|
echo "$msg" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse command-line options.
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
key="$1"
|
||||||
|
case $key in
|
||||||
|
-e|--expire)
|
||||||
|
expire_input="$2" # Usr input.
|
||||||
|
# Check for 'no expiry value'.
|
||||||
|
if [[ "$expire_input" == "0" || "$expire_input" == "never" || "$expire_input" == 'none' ]]; then
|
||||||
|
expire_seconds="" # Unset for no expiration.
|
||||||
|
echo "Setting NO expiration."
|
||||||
|
else
|
||||||
|
# Proceed with parsing regular.
|
||||||
|
value="" unit="" seconds=""
|
||||||
|
|
||||||
|
# Regex to capture the number part and optional unit part (s,m,h,d)
|
||||||
|
if [[ "$expire_input" =~ ^([0-9]+)([smhd]?)$ ]]; then
|
||||||
|
value="${BASH_REMATCH[1]}" # The numeric part.
|
||||||
|
unit="${BASH_REMATCH[2]}" # The unit part.
|
||||||
|
|
||||||
|
# Default to minutes if no unit was provided.
|
||||||
|
if [ -z "$unit" ]; then unit="m"; fi
|
||||||
|
|
||||||
|
# Calculate total seconds based on the unit.
|
||||||
|
case "$unit" in
|
||||||
|
s) seconds=$((value)) ;;
|
||||||
|
m) seconds=$((value * 60)) ;;
|
||||||
|
h) seconds=$((value * 3600)) ;; # 60*60.
|
||||||
|
d) seconds=$((value * 86400)) ;; # 60*60*24.
|
||||||
|
*) # Not really requried given the regex, but hey-ho.
|
||||||
|
echo "Error: Internal error parsing unit '$unit' from '$expire_input'."
|
||||||
|
exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Validate against ImgBB limits (60 seconds to 15552000 seconds / 180 days).
|
||||||
|
if (( seconds < 60 )) || (( seconds > 15552000 )); then
|
||||||
|
echo "Error: Calculated expiration ($seconds seconds) is outside of ImgBB's allowed range (60s - 15552000s)." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Store the final result.
|
||||||
|
expire_seconds="$seconds"
|
||||||
|
echo "Expiration set to $expire_seconds seconds ($expire_input)"
|
||||||
|
else
|
||||||
|
# Someone did funky input. Tell them to stop that!
|
||||||
|
echo "Error: Invalid expiration format '$expire_input'." >&2
|
||||||
|
echo "Use a number optionally followed by s, m, h or d OR use 0/none/never (e.g., 300, 5m, 2h, 7d)." >&2
|
||||||
|
print_usage # Maybe they need help.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-n|--name)
|
||||||
|
custom_name="$2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--markdown)
|
||||||
|
markdown_mode="true"
|
||||||
|
org_mode="false" # Sorry org, only one at a time.
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--org)
|
||||||
|
org_mode="true"
|
||||||
|
markdown_mode="false"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-s|--select)
|
||||||
|
select_mode="true"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-M|--monitor)
|
||||||
|
monitor_num="$2"
|
||||||
|
# Check if it's a non-negative integer.
|
||||||
|
if ! [[ "$monitor_num" =~ ^[0-9]+$ ]]; then
|
||||||
|
die "Error: Monitor number '$monitor_num' is not a valid non-negative integer."
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
print_usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
# Unknown option.
|
||||||
|
echo "Error: Unknown option '$1'" >&2
|
||||||
|
print_usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Assume it's the filepath (only one allowed).
|
||||||
|
if [ -n "$filepath" ]; then
|
||||||
|
echo "Error: Multiple filepaths provided ($filepath, $1). Only one allowed." >&2
|
||||||
|
print_usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
filepath="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Validate mutually exclusive input modes.
|
||||||
|
if [ "$select_mode" = "true" ] && [ -n "$filepath" ]; then
|
||||||
|
die "Error: Cannot use --select (-s) flag and provided filepath simultaneously."
|
||||||
|
fi
|
||||||
|
if [ -n "$monitor_num" ] && [ -n "$filepath" ]; then
|
||||||
|
die "Error: Cannot use --monitor (-M) flag and provided filepath simultaneously."
|
||||||
|
fi
|
||||||
|
if [ "$select_mode" = "true" ] && [ -n "$monitor_num" ]; then
|
||||||
|
die "Error: Cannot use --select (-s) and --monitor (-M) flags simultaneously."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if filepath exists and is readable if provided.
|
||||||
|
if [ -n "$filepath" ] && [ ! -r "$filepath" ]; then
|
||||||
|
echo "Error: Cannot read file '$filepath'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# === Read API Key. ===
|
||||||
|
if [[ -n "$IMGBB_API_KEY" ]]; then
|
||||||
|
api_key="$IMGBB_API_KEY"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if API key is actually set.
|
||||||
|
if [ -z "$api_key" ]; then
|
||||||
|
# Use function defined below if notify-send exists.
|
||||||
|
notify_cmd -u critical "ImgBB Upload Error" "API Key not found." &>/dev/null
|
||||||
|
echo "Error: API Key not found." >&2
|
||||||
|
echo "Please store your key in '$config_file' or set the IMGBB_API_KEY environment variable." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# === Check Dependencies. ===
|
||||||
|
check_command() {
|
||||||
|
if ! command -v "$1" &> /dev/null; then
|
||||||
|
notify_cmd -u critical "ImgBB Upload Error" "'$1' command not found. Please install it." &>/dev/null
|
||||||
|
echo "Error: '$1' command not found. Please install it (e.g., sudo apt install $1)." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
# Define notify_cmd first based on whether notify-send exists.
|
||||||
|
notify_cmd() { :; } # Default to no-up.
|
||||||
|
if ! command -v notify-send &> /dev/null; then
|
||||||
|
notify_cmd() { :; } # No-op if not found.
|
||||||
|
echo "Warning: notify-send not found. Desktop notifications disabled." >&2
|
||||||
|
else
|
||||||
|
notify_cmd() { notify-send "$@"; } # Actual command if found.
|
||||||
|
fi
|
||||||
|
# Now check other dependencies.
|
||||||
|
check_command curl
|
||||||
|
check_command jq
|
||||||
|
# Check screenshot tool if needed.
|
||||||
|
# Monitor mode currently hardcodes scrot, ensure it's checked if -M is used.
|
||||||
|
if [ -n "$monitor_num" ]; then check_command "scrot"; fi
|
||||||
|
if [ "$select_mode" = "true" ]; then
|
||||||
|
check_command "$screenshot_tool"
|
||||||
|
elif [ -z "$filepath" ]; then
|
||||||
|
# Check clipboard tool only if using clipboard mode (and not select mode).
|
||||||
|
case "$clipboard" in
|
||||||
|
x11)
|
||||||
|
check_command xclip
|
||||||
|
;;
|
||||||
|
wayland)
|
||||||
|
check_command wl-paste
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
die "Unsupported clipboard: $clipboard"
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# === Main Logic. ===
|
||||||
|
paste_x11() {
|
||||||
|
declare tmp
|
||||||
|
|
||||||
|
tmp_img="$(mktemp)" || die "Could not create temp file."
|
||||||
|
|
||||||
|
xclip -selection clipboard -t image/png -o >"$tmp_img" 2>/dev/null
|
||||||
|
if [ -s "$tmp_img" ]; then
|
||||||
|
mv "$tmp_img" "$tmp_img.png"
|
||||||
|
printf "%s\n" "$tmp_img.png"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
xclip -selection clipboard -t image/jpeg -o >"$tmp_img" 2>/dev/null
|
||||||
|
if [ -s "$tmp_img" ]; then
|
||||||
|
mv "$tmp_img" "$tmp_img.jpeg"
|
||||||
|
printf "%s\n" "$tmp_img.jpeg"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$tmp_img"
|
||||||
|
die "Could not get PNG or JPEG image data from clipboard."
|
||||||
|
}
|
||||||
|
|
||||||
|
paste_wl() {
|
||||||
|
declare tmp_img
|
||||||
|
declare format
|
||||||
|
|
||||||
|
format="$(wl-paste -l | grep -m1 -F -e image/png -e image/jpeg)" ||
|
||||||
|
die "Invalid file type in clipboard."
|
||||||
|
|
||||||
|
tmp_img="$(mktemp)" || die "Could not create temp file."
|
||||||
|
|
||||||
|
if wl-paste -t "$format" >"$tmp_img" 2>/dev/null; then
|
||||||
|
mv "$tmp_img" "$tmp_img.${format##image/}"
|
||||||
|
printf "%s\n" "$tmp_img.${format##image/}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$tmp_img"
|
||||||
|
die "Could not get PNG or JPEG image data from clipboard."
|
||||||
|
}
|
||||||
|
|
||||||
|
yank_x11() {
|
||||||
|
xclip -selection clipboard
|
||||||
|
}
|
||||||
|
|
||||||
|
yank_wl() {
|
||||||
|
wl-copy
|
||||||
|
}
|
||||||
|
|
||||||
|
TMP_IMG="" # Path to the image file to upload.
|
||||||
|
response="" # API response.
|
||||||
|
image_source_description=""
|
||||||
|
temp_file_to_clean="" # Track temp file for cleanup if created.
|
||||||
|
|
||||||
|
# === Determine Input and Upload ===
|
||||||
|
|
||||||
|
# --- Define base curl options ---
|
||||||
|
curl_opts_base=(-s -S -f -L -X POST --form "key=$api_key")
|
||||||
|
|
||||||
|
# --- Set default trap (will be cleared or modified below) ---
|
||||||
|
trap 'rm -f "$temp_file_to_clean"' EXIT
|
||||||
|
|
||||||
|
if [ "$select_mode" = "true" ]; then
|
||||||
|
# === Screenshot Mode ===
|
||||||
|
image_source_description="Screenshot selection"
|
||||||
|
notify_cmd "ImgBB Uploader" "Select area for screenshot using $screenshot_tool..."
|
||||||
|
|
||||||
|
screenshot_cmd=""
|
||||||
|
case "$screenshot_tool" in
|
||||||
|
maim) screenshot_cmd="maim -s -f png /dev/stdout";;
|
||||||
|
scrot) screenshot_cmd="scrot -s -o /dev/stdout";;
|
||||||
|
flameshot) screenshot_cmd="flameshot gui -r";;
|
||||||
|
*) die "Unsupported screenshot tool configured: '$screenshot_tool'";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Build full options for this mode, starting with base.
|
||||||
|
curl_opts=("${curl_opts_base[@]}")
|
||||||
|
if [ -n "$expire_seconds" ]; then curl_opts_base+=(--form "expiration=$expire_seconds"); fi
|
||||||
|
if [ -n "$custom_name" ]; then curl_opts_base+=(--form "name=$custom_name"); fi
|
||||||
|
# Add mode-specific image source (stdin) and the API URL.
|
||||||
|
curl_opts+=(--form "image=@-;filename=screenshot.png")
|
||||||
|
curl_opts+=("$imgbb_api_url")
|
||||||
|
|
||||||
|
notify_cmd "ImgBB Uploader" "Uploading $image_source_description..."
|
||||||
|
# Capture the response and potential curl errors.
|
||||||
|
temp_stderr=$(mktemp)
|
||||||
|
response=$(eval "$screenshot_cmd" | curl "${curl_opts[@]}" 2>"$temp_stderr")
|
||||||
|
|
||||||
|
# Check the status of both commands in the pipeline.
|
||||||
|
pipeline_status=("${PIPESTATUS[@]}")
|
||||||
|
screenshot_status=${pipeline_status[0]}
|
||||||
|
upload_status=${pipeline_status[1]}
|
||||||
|
curl_stderr=$(cat "$temp_stderr")
|
||||||
|
rm -rf "$temp_stderr"
|
||||||
|
|
||||||
|
# Check for errors in the pipeline.
|
||||||
|
if [ "$screenshot_status" -ne 0 ]; then
|
||||||
|
die "Screenshot command ($screenshot_tool) failed (status $screenshot_status).";
|
||||||
|
fi
|
||||||
|
if (( upload_status != 0 )); then
|
||||||
|
die "curl command failed during upload (status $upload_status). Check network? Curl stderr: $curl_stderr";
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clear the trap, no temp file used in this mode.
|
||||||
|
trap '' EXIT
|
||||||
|
elif [ -n "$monitor_num" ]; then
|
||||||
|
# === Screenshot Monitor Mode ===
|
||||||
|
image_source_description="Monitor $monitor_num screenshot"
|
||||||
|
screenshot_tool="scrot" # Requires scrot for --monitor flag.
|
||||||
|
notify_cmd "ImgBB Uploader" "Capturing monitor $monitor_num using $screenshot_tool..."
|
||||||
|
|
||||||
|
# Build full options array starting with common.
|
||||||
|
curl_opts=("${curl_opts_base[@]}")
|
||||||
|
if [ -n "$expire_seconds" ]; then
|
||||||
|
curl_opts+=(--form "expiration=$expire_seconds");
|
||||||
|
fi
|
||||||
|
if [ -n "$custom_name" ]; then curl_opts+=(--form "name=$custom_name"); fi
|
||||||
|
|
||||||
|
# --- Create temp file for scrot output ---
|
||||||
|
TMP_IMG=$(mktemp --suffix=.png) || die "Could not create temp file for screenshot."
|
||||||
|
temp_file_to_clean="$TMP_IMG" # Ensure trap cleans up.
|
||||||
|
trap 'rm -f "$temp_file_to_clean"' EXIT
|
||||||
|
|
||||||
|
rm -f "$TMP_IMG"
|
||||||
|
# --- Take screenshot saving to temp file ---
|
||||||
|
if ! scrot --monitor "$monitor_num" "$TMP_IMG"; then
|
||||||
|
#rm -f "$TMP_IMG" # Clean up failed/empty file.
|
||||||
|
die "Screenshot command ($screenshot_tool --monitor $monitor_num) failed (status $?). Check monitor index."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add temp file path to curl options
|
||||||
|
curl_opts+=(--form "image=@$TMP_IMG")
|
||||||
|
curl_opts+=("$imgbb_api_url")
|
||||||
|
|
||||||
|
notify_cmd "ImgBB Uploader" "Uploading $image_source_description..."
|
||||||
|
temp_stderr=$(mktemp)
|
||||||
|
response=$(eval "$screenshot_cmd" | curl "${curl_opts[@]}" 2>"$temp_stderr")
|
||||||
|
pipeline_status=("${PIPESTATUS[@]}")
|
||||||
|
screenshot_status=${pipeline_status[0]}
|
||||||
|
upload_status=${pipeline_status[1]}
|
||||||
|
curl_stderr=$(cat "$temp_stderr")
|
||||||
|
rm -f "$temp_stderr"
|
||||||
|
if [ "$screenshot_status" -ne 0 ]; then
|
||||||
|
die "Screenshot command ($screenshot_tool --monitor $monitor_num) failed (status $screenshot_status).";
|
||||||
|
fi
|
||||||
|
if (( upload_status != 0 )); then
|
||||||
|
die "curl command failed during upload (status $upload_status). Check network? Curl stderr: $curl_stderr";
|
||||||
|
fi
|
||||||
|
trap '' EXIT # Clear trap.
|
||||||
|
elif [ -n "$filepath" ]; then
|
||||||
|
# === File Input Mode. ===
|
||||||
|
image_source_description="file '$filepath'"
|
||||||
|
TMP_IMG="$filepath" # Use the provided filepath directly.
|
||||||
|
echo "Using image from file: $filepath."
|
||||||
|
trap '' EXIT # Clear trap if we are not using temp files.
|
||||||
|
|
||||||
|
# Build full options for this mode, starting with base.
|
||||||
|
curl_opts=("${curl_opts_base[@]}")
|
||||||
|
curl_opts+=(--form "image=@$TMP_IMG") # Use @filepath
|
||||||
|
if [ -n "$expire_seconds" ]; then curl_opts+=(--form "expiration=$expire_seconds"); fi
|
||||||
|
if [ -n "$custom_name" ]; then curl_opts+=(--form "name=$custom_name"); fi
|
||||||
|
curl_opts+=("$imgbb_api_url")
|
||||||
|
|
||||||
|
# Upload the image using curl.
|
||||||
|
notify_cmd "ImgBB Uploader" "Uploading $image_source_description..."
|
||||||
|
response=$(curl "${curl_opts[@]}")
|
||||||
|
#Check curl exit status.
|
||||||
|
if [ $? -ne 0 ]; then die "curl command failed during upload. Check network?"; fi
|
||||||
|
else
|
||||||
|
# === Clipboard Input Mode ===
|
||||||
|
image_source_description="clipboard"
|
||||||
|
# Use helper functions to get image data into temp file $TMP_IMG.
|
||||||
|
TMP_IMG=""; # Reset it just in case.
|
||||||
|
case "$clipboard" in
|
||||||
|
x11) TMP_IMG=$(paste_x11);;
|
||||||
|
wayland) TMP_IMG=$(paste_wl);;
|
||||||
|
esac || exit 1 # Exit if paste function failed.
|
||||||
|
temp_file_to_clean="$TMP_IMG" # Mark temp file for cleanup by trap.
|
||||||
|
# Ensure trap is set correctly.
|
||||||
|
trap 'rm -f "$temp_file_to_clean"' EXIT
|
||||||
|
|
||||||
|
# Build full options for this mode, starting with base.
|
||||||
|
curl_opts=("${curl_opts_base[@]}")
|
||||||
|
curl_opts+=(--form "image=@$TMP_IMG") # Upload from temp file path.
|
||||||
|
if [ -n "$expire_seconds" ]; then curl_opts+=(--form "expiration=$expire_seconds"); fi
|
||||||
|
if [ -n "$custom_name" ]; then curl_opts+=(--form "name=$custom_name"); fi
|
||||||
|
curl_opts+=("$imgbb_api_url")
|
||||||
|
|
||||||
|
# Upload the image using curl.
|
||||||
|
notify_cmd "ImgBB Uploader" "Uploading $image_source_description..."
|
||||||
|
response=$(curl "${curl_opts[@]}")
|
||||||
|
# Check curl exit status.
|
||||||
|
if [ $? -ne 0 ]; then die "curl command failed during upload. Check network?"; fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# === Process Response (This is common to all modes) ===
|
||||||
|
success=$(echo "$response" | jq -r '.success')
|
||||||
|
|
||||||
|
if [ "$success" != "true" ]; then
|
||||||
|
error_msg=$(echo "$response" | jq -r '.error.message // "Unknown API error"')
|
||||||
|
notify_cmd -u critical "ImgBB Upload Error" "API Error: $error_msg"
|
||||||
|
echo "Error: ImgBB API returned an error - $error_msg" >&2
|
||||||
|
echo "Full response: $response" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract the direct image URL.
|
||||||
|
image_url=$(echo "$response" | jq -r '.data.url')
|
||||||
|
|
||||||
|
# Check if URL was successfully extracted.
|
||||||
|
if [ -z "$image_url" ] || [ "$image_url" == "null" ]; then
|
||||||
|
notify_cmd -u critical "ImgBB Upload Error" "Could not parse image URL from API response."
|
||||||
|
echo "Error: Could not parse image URL from API response." >&2
|
||||||
|
echo "Full response: $response" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Format output based on markdown flag.
|
||||||
|
output_url="$image_url"
|
||||||
|
if [ "$markdown_mode" = "true" ]; then
|
||||||
|
# Basic markdown image syntax - assumes filename is not needed for alt text here.
|
||||||
|
output_url=""
|
||||||
|
echo "Formatting as Markdown."
|
||||||
|
elif [ "$org_mode" = "true" ]; then
|
||||||
|
output_url="[[${image_url}][]]"
|
||||||
|
echo "Formatting as orgmode."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Output the URL to terminal and copy to clipboard.
|
||||||
|
echo "Image URL:"
|
||||||
|
echo "$output_url"
|
||||||
|
# Copy URL only if we determined we are not uploading from file (i.e., we used clipboard input)
|
||||||
|
# Or always copy? Let's always copy for now.
|
||||||
|
|
||||||
|
case "$clipboard" in
|
||||||
|
x11) printf "%s\n" "$output_url" | yank_x11;;
|
||||||
|
wayland) printf "%s\n" "$output_url" | yank_wl;;
|
||||||
|
esac
|
||||||
|
notify_cmd "ImgBB Uploader" "Success! URL copied: $output_url"
|
||||||
|
|
||||||
|
# Temporary file (if used) is removed automatically by the 'trap' command on exit.
|
||||||
|
exit 0
|
26
imgbb_uploader.conf
Normal file
26
imgbb_uploader.conf
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Template Configuration File. Place this under ~/.config/
|
||||||
|
|
||||||
|
# (REQUIRED) Replace this with your actual key.
|
||||||
|
api_key="YOUR_API_KEY_FROM_IMG_BB_WEBSITE"
|
||||||
|
|
||||||
|
# Set default expiration time in seconds.
|
||||||
|
# expire_seconds="3600" # Default to 1 hour.
|
||||||
|
# expire_seconds="86400" # Default to 1 day.
|
||||||
|
expire_seconds="" # Default to NO expiration.
|
||||||
|
|
||||||
|
# Set default output format (only set one! Or none for raw URL which is the default).
|
||||||
|
#markdown_mode="true"
|
||||||
|
#org_mode="true"
|
||||||
|
|
||||||
|
|
||||||
|
# Default custom name (I think this isn't ideal to set as a default).
|
||||||
|
# custom_name="MyDefaultUploadName"
|
||||||
|
|
||||||
|
# Default screenshot tool when using option -s. Defaults to scrot but also supports
|
||||||
|
# maim and flameshot. You can add your own in the script by adding to the definition of
|
||||||
|
# screenshot_cmd
|
||||||
|
screenshot_tool="scrot"
|
||||||
|
|
||||||
|
# Default monitor number to screenshot and send to ImgBB. Currently only supported with scrot.
|
||||||
|
# NOTE: setting this will override default 'imgbb' command to upload clipboard image.
|
||||||
|
#monitor_num="0"
|
Loading…
Reference in New Issue
Block a user