You are not logged in.
@Doobie03 That's ultra minimal and looks so cool. I'll never learn the skills to do something like that.
'The Universe is under no obligation to make sense to you'
Offline
Thanks. You are already on the right path, I'm sure you will get there.
"All we are is dust in the wind, dude"
- Theodore "Ted" Logan
"Led Zeppelin didn't write tunes that everybody liked, they left that to the Bee Gees."
- Wayne Campbell
Offline
Offline
...a wayland hack of
bl-imgur-upload
.
I've been thinking about what will happen to our scripts - came to the conclusion that tweaking them to be wayland-compliant might not be too hard. Will your version also work on X11 as-is?
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
I've been thinking about what will happen to our scripts - came to the conclusion that tweaking them to be wayland-compliant might not be too hard. Will your version also work on X11 as-is?
Not verbatim, but I suppose with a few (quite a few) if and/or case statements it will be doable.
#!/bin/sh
echo '#include <stdio.h>\nvoid main() { printf("Hi, bunsenlabs\\n"); return; }' > bunsen.c
gcc bunsen.c -o bunsen
./bunsen
Offline
^I didn't write the bl-imgur-upload script, and it's quite long...
Could I have a look at your rewrite of it?
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
Still very WIP and definitely not ready for production so I will post it here but anyone watching, please do not use.
Helper script wshot
(extremely WIP) (actually specific to my system)
#!/bin/sh
sleep 1
case $1 in
-r)slurp | grim -g - "$2"
;;
-m)if [ -n "$5" ]; then
sleep $5
grim "$2" "$3" "$6"
else
grim "$2" "$3" "$4"
fi
;;
'')
grim "$1"
;;
esac
bl-w-imgur-upload
#!/bin/bash
#
# bl-w-imgur-upload: script to take screenshots and upload them to Imgur; this
# can be to an existing account, or anonymously.
#
# Credentials and an access token for an account can be set up.
#
# Settings (imgur.conf) and credentials (credentials.conf}) files are created in
# ${HOME}/.config/image-upload/imgur/
#
# The script returns BB-Code for the direct image link, and a linked thumbnail.
# YAD dialogs are used for user interaction.
#
# There is an option to upload a file directly from the file manager, and the
# BBCode placed on the clipboard.
#
# Kudos to the writer of the script at https://github.com/jomo/imgur-screenshot,
# which has provided most of the OAuth2 and Imgur API functions adapted here.
# ("imgur-screenshot" is featured in https://imgur.com/tools.)
# Modified for wayland 2024-06-23
#
########################################################################
#
# Copyright (C) 2020 damo <damo@bunsenlabs.org>
# Copyright (C) 2024 micko01 <01micko@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
########################################################################
BL_COMMON_LIBDIR='/usr/lib/bunsen/common'
USR_CFG_DIR="$HOME/.config/image-upload/imgur"
CREDENTIALS_FILE="${USR_CFG_DIR}/credentials.conf"
SETTINGS_FILE="${USR_CFG_DIR}/imgur.conf"
SCRIPT=$(basename "$0")
IMG_VIEWER=bl-image-viewer
USAGE="bl-imgur-upload is a script to take screenshots and upload them to Imgur
this can be to an existing account, or anonymously.
Usage: bl-imgur-upload [option]... [file]...
With no script args, ${SCRIPT} will upload a screenshot of
the full desktop, as anonymous user.
Arguments:
-h, --help Show this help, exit
-l, --login Upload to Imgur account
-c, --connect Show connected Imgur account, exit
-r, --register Register for Imgur account
-s, --select Take screenshot in select mode
-f, --full Take screenshot in full desktop mode
-d, --delay <seconds> Delay in integer seconds, before taking screenshot
-a, --album <album_title> Upload to specified album
-t, --title <image title> Label uploaded image
--file <filepath/filename> Upload specified image. Overrides scrot options
--auto-upload Upload image from filemanager, put BBCode on clipboard
--test-account For use by external command, to see if user
has an Imgur account already
The final dialog displays forum BB-Code for both the direct image link and
the linked image thumbnail. These can be copy/pasted as desired.
If more than one of '-f','-w', or '-s' are passed to the script, the LAST
one will be used.
There is an option to delete uploaded and/or local screenshot images
before exiting the script. This doesn't apply if using '--auto-upload'.
'imgur.conf' settings, such as filepaths and image format, can be changed
by editing the file directly.
"
# if help option anywhere in args, output $USAGE and exit immediately
for i in "$@"
do
case "$i" in
-h|--help)
echo "$USAGE"
exit 0
;;
esac
done
### required commands ###
declare -a APPS
APPS=( "yad" "grim" "slurp" "wget" "curl" "pngtopam" "pamscale" "pamtopng" "jq" )
### Get script args ####################################################
function getargs(){
if (( $# == 0 ));then # no args, so run with anonymous, full desktop scrot
echo -e "\n\tAnonymous upload\n"
AUTH_MODE="A"
SCROT="${SCREENSHOT_FULL_COMMAND}"
fi
while [[ ${#} != 0 ]]; do
case "$1" in
-h | --help) echo -e "${USAGE}"
exit 0
;;
-l | --login) ID="${CLIENT_ID}" # run as auth user; username set in imgur.conf
AUTH="Authorization: Bearer ${ACCESS_TOKEN}" # in curl command
AUTH_MODE="L"
;;
-c | --connect) ID="${CLIENT_ID}"
AUTH_MODE="L"
load_access_token "${ID}"
fetch_account_info
exit 0
;;
-r | --register)REGISTER=1 # Register for an Imgur account
;;
-s | --select) REGION=""
SCROT="${SCREENSHOT_SELECT_COMMAND}"
;;
-f | --full) SCROT="${SCREENSHOT_FULL_COMMAND}"
;;
-d | --delay) if [[ $2 != ?(-)+([0-9]) ]];then
MSG="\n\tDelay value must be an integer\n\tExiting script...\n"
echo -e "${MSG}"
yad_error "${MSG}"
exit 1
else
DELAY="$2"
fi
shift
;;
-a | --album) ALBUM_TITLE="$2" # override imgur.conf
shift
;;
-t | --title) IMG_TITLE="$2"
shift
;;
--file) FNAME="$2"
if ! [[ -f "${FNAME}" ]]; then
MSG="\n\tFile\"'${FNAME}\" doesn't exist!\n\n\tExiting script...\n"
echo -e "${MSG}"
yad_error "${MSG}"
exit 1
fi
F_FLAG=1
shift
;;
--auto-upload) THUNAR=1
;;
--test-account) TEST=1 # to test if user has Imgur account
;;
*) MSG="\n\tFailed to parse options\n\tExiting script...\n"
echo -e "${MSG}" >&2
yad_error "${MSG}"
exit 1
;;
esac || { echo "Failed to parse options" >&2 && exit 1; }
shift
done
}
### Initialize imgur.conf config ###################################
function settings_conf(){
! [[ -d "$USR_CFG_DIR" ]] && mkdir -p "$USR_CFG_DIR" 2>/dev/null
if ! [[ -f "${SETTINGS_FILE}" ]] 2>/dev/null;then
touch "${SETTINGS_FILE}" && chmod 600 "${SETTINGS_FILE}"
cat <<EOF > "${SETTINGS_FILE}"
### IMGUR SCREENSHOT DEFAULT CONFIG ####
### Read by ${SCRIPT} ###################
# Most of these settings can be overridden with script args
# Imgur settings
ANON_ID="ea6c0ef2987808e"
CLIENT_ID=""
CLIENT_SECRET=""
USER_NAME=""
ALBUM_TITLE=""
IMGUR_ICON_PATH=""
# Local file settings
# User directory to save image:
FILE_DIR="$(xdg-user-dir PICTURES)/screenshots"
FILE_NAME="imgur-%Y_%m_%d-%H:%M:%S"
# possible formats are png | jpg | tiff | gif
FILE_FORMAT="png"
# Use this app to view images locally
IMG_VIEWER=bl-image-viewer
# Screenshot scrot commands
OUTPUT=HDMI-A-1
SCREENSHOT_SELECT_COMMAND="slurp | grim -g - "
SCREENSHOT_FULL_COMMAND="grim -o \$OUTPUT "
EOF
fi
source "${SETTINGS_FILE}"
}
# Check for availability of commands used in script.
function declareDependencies(){ # adapted from bl-includes
# Usage: declareDependencies command [command...]
local missing_commands=()
i=
for i in "$@"
do
hash "$i" 2>/dev/null || missing_commands+=(" $i")
done
if [[ ${missing_commands[0]} ]];then
ERR_MSG="
This script requires the following commands:
${missing_commands[*]}
Please install the packages containing the missing commands
and rerun the script.
"
yad_error "${ERR_MSG}"
exit
fi
}
### File and Image functions #####################################################
# takes file as argument
function getimage(){
if (( THUNAR == 1 ));then # --auto-upload requested
if (( F_FLAG == 1 ));then # a file is being uploaded
if [[ -f "${CREDENTIALS_FILE}" ]];then
TEXT="
This action will upload \"${FNAME}\",
and return the BBCode to the clipboard.
Do you want to upload to your Imgur account
or upload Anonymously?
"
DLG=$(${DIALOG} "${TITLE}" \
"${T}${TEXT}" --text-align=left \
--button="To Account:0" --button="Anonymous upload:2" "${CANCEL}" \
)
RET=$?
if (( RET == 0 ));then # upload to account
load_access_token "${CLIENT_ID}"
AUTH="Authorization: Bearer ${ACCESS_TOKEN}"
elif (( RET == 2 ));then # upload as anonymous user
AUTH_MODE="A"
else
exit 0
fi
fi
else
MSG="\n\tNo file specified for upload!\n\n\tExiting script...\n"
echo -e "${MSG}"
yad_error "${MSG}"
exit 1
fi
fi
# Only show dialogs if account upload was requested
if ! [[ -z ${DELAY} ]] 2>/dev/null && ! [[ ${SCROT} == "${SCREENSHOT_SELECT_COMMAND}" ]] 2>/dev/null;then
SCROT="${SCROT} -d ${DELAY}"
MSG="\n\tProceed with Imgur account screenshot?\n\n\t \
There will be a pause of ${DELAY}s, to select windows etc\n"
else
if [[ ${SCROT} == "${SCREENSHOT_SELECT_COMMAND}" ]] 2>/dev/null;then
MSG="\n\tSelected Area screenshot...\n\n\tProceed with Imgur account screenshot?\n"
else
MSG="\n\tFull desktop screenshot...\n\n\tProceed with Imgur account screenshot?\n"
SCROT="${SCROT} " # need a pause so YAD dialog can leave the scene
fi
fi
if [[ -z "$1" ]] 2>/dev/null; then
if [[ ${AUTH_MODE} = "L" ]];then
yad_question "--image=dialog-question" "${MSG}"
RET="$?"
(( RET == 1 )) && exit 0
fi
# new filename with date
IMG_FILE="$(date +"${FILE_NAME}.${FILE_FORMAT}")"
IMG_FILE="${FILE_DIR}/${IMG_FILE}"
thumbnail="${IMG_FILE%.*}-thumb.${FILE_FORMAT}"
take_screenshot "${IMG_FILE}" "$thumbnail"
MSG="
This action will upload this screenshot of your desktop,
and return the BBCode to the clipboard.
Do you want to upload anonymously to Imgur?
"
while true; do
${DIALOG} --image="${thumbnail}" --title="Confirm Screenshot Upload" \
${CANCEL} ${OK} --button="Show Fullsize":2 --button="Imgur T.O.S":3 --width=680 --text="${MSG}" --text-align=left
RET=$?
case "$RET" in
0)
break;;
1|70|252)
exit 0;;
2)
"$IMG_VIEWER" "${IMG_FILE}";;
3)
x-www-browser "https://imgur.com/tos";;
esac
done
rm -f "${thumbnail}"
else
# upload file instead of screenshot
IMG_FILE="$1"
fi
# check if file exists
if ! [[ -f "${IMG_FILE}" ]] 2>/dev/null; then
MSG="\n\tfile\"'${IMG_FILE}\" doesn't exist!\n\n\tExiting script...\n"
echo -e "${MSG}"
yad_error "${MSG}"
exit 1
fi
}
function delete_images(){ # set up dialogs to delete hosted and/or local images
local IMG="$1"
if (( F_FLAG == 0 ));then # screenshot was uploaded
CHOICE=$(${DIALOG} --image-on-top ${TITLE} \
--form --height=300 --width=300 \
--image="${TEMP_THUMB}" \
--image-on-top \
--text="Choose the images to delete...\n\n$(basename ${IMG_FILE})" \
--field=" Uploaded screenshot:CHK" \
--field=" Local screenshot:CHK" \
$DELETE $CANCEL \
)
ret=$?
choices=($(awk -F '|' '{print $1,$2}' <<< "${CHOICE}"))
if (( ret == 2 ));then
if [[ ${choices[0]} = "TRUE" ]];then
echo -e "\ndeleting upload.."
delete_img "${IMG}"
fi
if [[ ${choices[1]} = "TRUE" ]];then
echo -e "\ndeleting local..."
delete_local
else
MSG="File was saved locally as:\n\n\"${IMG_FILE}\"\n"
notify_msg "${MSG}"
fi
else
MSG="BBCode for linked thumbnail\n \
${IMG_FILE}\n \
is on the clipboard.\n\n \
File was saved as:\n \
${IMG_FILE}\n"
notify_msg "${MSG}"
fi
else
## for file upload, just do it
echo -e "\ndeleting upload.."
delete_img "${IMG}"
fi
}
function delete_img() { # delete uploaded screenshot from Imgur
local IMG="$1"
if [[ ${AUTH_MODE} == "L" ]];then
CMD="curl -s --location --request DELETE \"https://api.imgur.com/3/image/${IMG}\" \
--header \"Authorization: Bearer ${ACCESS_TOKEN}\""
else
CMD="curl -s --location --request DELETE \"https://api.imgur.com/3/image/${IMG}\" \
--header \"${AUTH}\""
fi
api_call "${CMD}" " Deleting file ${IMG_LINK} "
if [[ $(jq -r .success <<< ${RESPONSE}) == "true" ]]; then
MSG="\nUploaded image successfully deleted.\n\ndelete hash: $1\n"
KEEP_BB=0 # Flag for notification text and to
notify_msg "${MSG}" # clear clipboard.
elif (( PIPE[0] != 0 ));then
MSG="\nThe upload was interrupted.\n"
yad_error "${MSG}"
else
MSG="\nThe image could not be deleted.\n"
yad_error "${MSG}"
fi
echo -e "${MSG}"
}
function delete_local(){ # delete local screenshot or image file
if (( F_FLAG == 1));then # local file was uploaded
MSG="\n\tConfirm moving local uploaded file to 'Trash'?\n\n\t${IMG_FILE}\n"
yad_question "--image=dialog-question" "${MSG}"
RET="$?"
if (( RET == 0 )); then
if type "/usr/bin/gio" > /dev/null;then # send to 'Wastebasket'
gio trash "${IMG_FILE}"
else
rm -f "${IMG_FILE}"
fi
fi
else
if type "/usr/bin/gio" > /dev/null;then # send to 'Wastebasket'
gio trash "${IMG_FILE}"
else
rm -f "${IMG_FILE}"
fi
MSG="\nLocal screenshot image was deleted\n"
notify_msg "${MSG}"
fi
}
function take_screenshot() {
set -x
CMD_SCROT="${SCROT} ${1}" # also take thumbnail for dialogue
#echo $CMD_SCROT ##########debug
SHOT_ERR="$(${CMD_SCROT})" #takes a screenshot
#${CMD_SCROT}
if (( $? != 0 )); then
MSG="\n\tFailed to take screenshot of\n\t\"$1\":\n\tError: \"${SHOT_ERR}\"\n"
echo -e "${MSG}"
yad_error "${MSG}"
exit 1
fi
if [[ ! -s "${1}" ]]; then
MSG="\n\tFailed to take screenshot of\n\t\"$1\":\n\tError: empty file\n"
echo -e "${MSG}"
yad_error "${MSG}"
exit 1
fi
# scale the image
pngtopam ${1} | pamscale -xscale .13 -yscale .13 | pamtopng > ${2} || \
{
MSG="\n\tFailed to scale image of\n\t\"$1\":\n\tError\n"
echo -e "${MSG}"
yad_error "${MSG}"
exit 1
}
}
function notify_msg(){ # for displaying notifications; add to or clear clipboard
local MSG="$1"
if (( KEEP_BB == 0 ));then # uploaded file was deleted, clear clipboard
echo ''
if ! grep -i "local" <<< "$MSG" &>/dev/null;then # for 'delete_img' text
MSG="${MSG}\n\nClipboard cleared of BBCode\n" # for 'delete_local' text
fi
else
echo "${BB_THUMB_LINKED}"
fi
notify-send "$(echo -e ${MSG})"
}
function api_call(){
TEMP_FILE=$(mktemp --tmpdir response.XXX) # stores curl output for use by $RESPONSE
CURL_CMD="$1"
local MSG="$2"
# Run curl command passed as first arg; write output to tempfile; pipe to yad --progress
eval "${CURL_CMD}" 2>&1 > "${TEMP_FILE}" | yad --progress --pulsate --auto-close \
--progress-text="$MSG" \
--undecorated --on-top --sticky --center \
--borders=20 --button='Cancel':'/bin/bash -c "killall curl"' 2>/dev/null
# use bash builtin 'PIPESTATUS' to get curl exit code
PIPE=( "${PIPESTATUS[@]}" ) # get pipe array values (curl was stopped?)
RESPONSE=$(cat "${TEMP_FILE}") # used by calling function
IMG_ID="$(jq -r '.data.id' <<< ${RESPONSE})" # used by check_image()
rm -f "${TEMP_FILE}"
}
####### END Image Functions ############################################
### OAuth Credentials Functions ########################################
### Adapted from https://github.com/jomo/imgur-screenshot ##############
function check_oauth2_client_secrets() {
if [[ -z "${CLIENT_ID}" ]] || [[ -z "${CLIENT_SECRET}" ]]; then
MSG='
Your CLIENT_ID and CLIENT_SECRET are not set.
You need to register an imgur application at:
https://api.imgur.com/oauth2/addclient
'
DLG=$(${DIALOG} "${TITLE}" ${T}"${MSG}" --button="Get Credentials:0" ${CLOSE})
RET=$?
(( RET == 0 )) && get_oauth2_client_secrets || exit 1
fi
}
function get_oauth2_client_secrets(){
#URL = "https://api.imgur.com/oauth2/addclient"
MSG='
Your CLIENT_ID and CLIENT_SECRET are not set.
To register an imgur application:
1: "Run browser"
2: Select "OAuth 2 authorization without a callback URL" and fill out the form.
3: Then, set the CLIENT_ID and CLIENT_SECRET in your imgur.conf,
or paste them in the fields below, and click "OK"
'
DLG=$($DIALOG --form --image=dialog-question --image-on-top \
--title="Get Imgur authorization" --text="${MSG}" \
--fixed --center --borders=20 \
--sticky --on-top \
--width=650 \
--field="Client ID:" --field="Client Secret:" "" "" \
--button="Run browser":"/bin/bash -c 'run_browser addclient'" \
${OK} ${CANCEL}
)
ANS="$?"
[[ ${ANS} == 1 ]] && exit 0
C_ID="$(echo ${DLG} | awk -F '|' '{print $1}')" # 'pipe' separators
C_SECRET="$(echo ${DLG} | awk -F '|' '{print $2}')"
# check returned values
if [[ -z "${C_ID}" ]] || (( ${#C_ID} != 15 )) || ! [[ ${C_ID} =~ ^[a-fA-F0-9]+$ ]];then
ERR_MSG_1="Client ID is wrong!"
fi
if [[ -z "${C_ID}" ]] || (( ${#C_SECRET} != 40 )) || ! [[ ${C_SECRET} =~ ^[a-fA-F0-9]+$ ]];then
ERR_MSG_2="Client Secret is wrong!"
fi
if [[ ${ERR_MSG_1} ]] || [[ ${ERR_MSG_2} ]]; then
DLG_MSG="
${ERR_MSG_1}
${ERR_MSG_2}
Try again or Exit script?
"
ERR_DLG=$(${DIALOG} --text="${DLG_MSG}" --undecorated \
--image="dialog-question" --button="Exit:1" ${OK})
ANS=$?
if (( ANS == 0 )); then
get_oauth2_client_secrets
else
exit
fi
fi
# write credentials to imgur.conf
# sed: change line containing <string> to <stringvar>
C_ID_LINE="CLIENT_ID="\""${C_ID}\""
C_SECRET_LINE="CLIENT_SECRET="\""${C_SECRET}\""
sed -i "s/^CLIENT_ID.*/${C_ID_LINE}/" "${SETTINGS_FILE}"
sed -i "s/^CLIENT_SECRET.*/${C_SECRET_LINE}/" "${SETTINGS_FILE}"
source "${SETTINGS_FILE}"
}
function load_access_token() {
local CURRENT_TIME PREEMPTIVE_REFRESH_TIME EXPIRED
TOKEN_EXPIRE_TIME=0
ID="$1" # CLIENT_ID
if [[ ${ID} == "${ANON_ID}" ]];then # user has used '-l' or '-c' args, without credentials
MSG="
You need to Register an Imgur account
before being able to log in!
"
echo -e "${MSG}"
yad_error "${MSG}"
get_oauth2_client_secrets
else
AUTH_MODE="L"
fi
# check for saved ACCESS_TOKEN and its expiration date
if [[ -f "${CREDENTIALS_FILE}" ]] 2>/dev/null; then
source "${CREDENTIALS_FILE}"
else
acquire_access_token "${CLIENT_ID}"
save_access_token
fi
if [[ ! -z "${REFRESH_TOKEN}" ]] 2>/dev/null; then # token already set
CURRENT_TIME="$(date +%s)"
PREEMPTIVE_REFRESH_TIME="600" # 10 minutes
EXPIRED=$((CURRENT_TIME > (TOKEN_EXPIRE_TIME - PREEMPTIVE_REFRESH_TIME)))
if [[ ${EXPIRED} == "1" ]]; then # token expired
refresh_access_token
fi
else
acquire_access_token "${CLIENT_ID}"
save_access_token
fi
}
function acquire_access_token() {
local URL PARAMS PARAM_NAME PARAM_VALUE MSG
local ID="$1"
MSG="
You need to authorize ${SCRIPT} to upload images.
To grant access to this application visit the link below, by clicking 'Run browser'.
\"https://api.imgur.com/oauth2/authorize?client_id=${ID}&response_type=token\"
Then copy and paste the URL from your browser.
It should look like 'https://imgur.com/#access_token=...'
Make sure the WHOLE of the URL is selected: it is a long string!
[ You may need to close the browser before the script continues ]
"
# need to expand variable in dialog
CMD="$(printf '/bin/bash -c "run_browser token %s"' "${ID}")"
RET=$($DIALOG --form --image=dialog-information --image-on-top \
--title="Get Imgur authorization" --text="${MSG}" \
--fixed --sticky --on-top --center --borders=20 \
--width=650 \
--field="Paste here: " "" \
--button="Run browser":"${CMD}" \
--button="Save token:0" ${CANCEL}
)
ANS="$?"
[[ ${ANS} == 1 ]] && exit 0
URL="${RET:0:-1}" # cut 'pipe' char from end of string
if ! [[ ${URL} =~ "access_token=" ]] 2>/dev/null; then
MSG="\n\tERROR: That URL doesn't look right, please start script again\n"
yad_error "${MSG}"
exit 1
fi
URL="$(echo "${URL}" | cut -d "#" -f 2-)" # remove leading 'https://imgur.com/#'
PARAMS=(${URL//&/ }) # add remaining sections to array
for param in "${PARAMS[@]}"; do
PARAM_NAME="$(echo "${param}" | cut -d "=" -f 1)"
PARAM_VALUE="$(echo "${param}" | cut -d "=" -f 2-)"
case "${PARAM_NAME}" in
access_token) ACCESS_TOKEN="${PARAM_VALUE}"
;;
refresh_token) REFRESH_TOKEN="${PARAM_VALUE}"
;;
expires_in) TOKEN_EXPIRE_TIME=$(( $(date +%s) + PARAM_VALUE ))
;;
esac
done
if [[ -z "${ACCESS_TOKEN}" ]] || [[ -z "${REFRESH_TOKEN}" ]] || [[ -z "${TOKEN_EXPIRE_TIME}" ]]; then
MSG="\n\tERROR: Failed parsing the URL.\n\n\tDid you copy the full URL?\n"
yad_error "${MSG}"
exit 1
fi
save_access_token
AUTH="Authorization: Bearer ${ACCESS_TOKEN}"
}
function save_access_token() {
# create dir if not existing
mkdir -p "$(dirname "${CREDENTIALS_FILE}")" 2>/dev/null
touch "${CREDENTIALS_FILE}" && chmod 600 "${CREDENTIALS_FILE}"
cat <<EOF > "${CREDENTIALS_FILE}"
# This file is generated by ${SCRIPT}
# Do not modify it here - it will be overwritten
ACCESS_TOKEN="${ACCESS_TOKEN}"
REFRESH_TOKEN="${REFRESH_TOKEN}"
TOKEN_EXPIRE_TIME="${TOKEN_EXPIRE_TIME}"
EOF
}
function refresh_access_token() {
local TOKEN_URL RESPONSE EXPIRES_IN
echo -e "\nRefreshing access token..."
TOKEN_URL="https://api.imgur.com/oauth2/token"
# exchange the refresh token for ACCESS_TOKEN and REFRESH_TOKEN
RESPONSE="$(curl --compressed -fsSL --stderr - -F "client_id=${ID}" -F "client_secret=${CLIENT_SECRET}" -F "grant_type=refresh_token" -F "refresh_token=${REFRESH_TOKEN}" "${TOKEN_URL}")"
if (( ${?} == 0 )); then # curl failed
handle_upload_error "${RESPONSE}" "${TOKEN_URL}"
exit 1
fi
if ! jq -re .access_token >/dev/null <<<"${RESPONSE}"; then
# server did not send access_token
echo -e "\nError: Something is wrong with your credentials:"
echo "${RESPONSE}"
exit 1
fi
ACCESS_TOKEN="$(jq -r .access_token <<<"${RESPONSE}")"
REFRESH_TOKEN="$(jq -r .refresh_token <<<"${RESPONSE}")"
EXPIRES_IN="$(jq -r .expires_in <<<"${RESPONSE}")"
TOKEN_EXPIRE_TIME=$(( $(date +%s) + EXPIRES_IN ))
save_access_token
}
function check_image(){
local STATUS
local IMG_HASH="$1"
CHECK="$(curl -s --location --request GET "https://api.imgur.com/3/image/${IMG_HASH}" \
--header "${AUTH}")" && echo "$CHECK" > tmp/find.txt
STATUS="$(jq -r '.status' <<< $CHECK)"
if (( STATUS == 200 ));then
DATA="$(jq -r '.data.datetime' <<< ${CHECK})"
(( DATA > DATETIME )) && echo "newer" || echo "older"
fi
}
function get_user(){ # get user name for notifications
local RESPONSE USERNAME
RESPONSE="$(curl -sH "Authorization: Bearer ${ACCESS_TOKEN}" https://api.imgur.com/3/account/me)"
if (( $? == 0 )) && [[ $(jq -r .success <<<"${RESPONSE}") = "true" ]]; then
USERNAME="$(jq -r .data.url <<<"${RESPONSE}")"
fi
# sed: add user name to 'imgur.conf'
USR_LINE="USER_NAME=\"${USERNAME}\""
sed -i "s/USER_NAME=\"\"/${USR_LINE}/" "${SETTINGS_FILE}"
source "${SETTINGS_FILE}"
}
function fetch_account_info() {
local RESPONSE USERNAME
RESPONSE="$(curl -sH "Authorization: Bearer ${ACCESS_TOKEN}" https://api.imgur.com/3/account/me)"
if (( $? == 0 )) && [[ $(jq -r .success <<<"${RESPONSE}") = "true" ]]; then
USERNAME="$(jq -r .data.url <<<"${RESPONSE}")"
if [[ $1 == "getuser" ]];then # user name not set in imgur.conf
USER_NAME="${USERNAME,,}"
# write user name to imgur.conf
# sed: change line containing <string> to <stringvar>
USER_LINE="USER_NAME="\""${USERNAME}\""
sed -i "s/^USER_NAME.*/${USER_LINE}/" "${SETTINGS_FILE}"
source "${SETTINGS_FILE}"
echo "User name ${USERNAME} written to imgur.conf"
return
fi
MSG="\n\tLogged in as ${USERNAME}.\n\n\thttps://${USERNAME,,}.imgur.com\n"
echo -e "${MSG}"
yad_info "--image=dialog-information" "${MSG}"
else
MSG="\n\tFailed to fetch info: ${RESPONSE}\n"
echo -e "${MSG}"
yad_info "--image=dialog-information" "${MSG}"
fi
}
function run_browser(){ # run browser with API url, and switch to attention-seeking browser tab
local API_CALL="$1" # function called from button in dialog
ID_ARG="$2"
[[ ${API_CALL} = "addclient" ]] && API_URL="https://api.imgur.com/oauth2/addclient"
[[ ${API_CALL} = "token" ]] && API_URL="https://api.imgur.com/oauth2/authorize?client_id=${ID_ARG}&response_type=token"
x-www-browser "${API_URL}" 2>/dev/null
# switch_to_browser
}
#function switch_to_browser(){ # switch to new browser tab
# for id in $(wmctrl -l | awk '{ print $1 }'); do
# # filter only windows demanding attention
# xprop -id $id | grep -q "_NET_WM_STATE_DEMANDS_ATTENTION"
# if (( $? == 0 )); then
# wmctrl -i -a $id
# exit 0
# fi
# done
#}
######## End OAuth Functions ###########################################
######## YAD ###########################################################
DIALOG="yad --center --borders=20 --name=distributor-logo-bunsenlabs --fixed"
TITLE="--title=Image BBCode"
T="--text="
DELETE="--button=Delete:2"
CLOSE="--button=gtk-close:1"
CANCEL="--button=gtk-cancel:1"
OK="--button=OK:0"
######## End YAD #######################################################
######## END FUNCTIONS #################################################
### main ###############################################################
settings_conf # set up imgur.conf if necessary
# set defaults, if login not specified in script args
ID="${ANON_ID}"
AUTH="Authorization: Client-ID ${ID}" # in curl command
AUTH_MODE="A"
F_FLAG=0 # Flag for local image file upload
SCROT="${SCREENSHOT_FULL_COMMAND}"
DATETIME=$(date +%s)
REGISTER=0 # Flag for registering account
KEEP_BB=1 # Flag to keep BBCode on clipboard
TEST=0 # Flag to test if user has Imgur account
export -f run_browser # to be used as YAD button command
#export -f switch_to_browser # used by run_browser
if ! . "${BL_COMMON_LIBDIR}/yad-includes" 2> /dev/null; then
echo -e "\nError: Failed to source yad-includes in ${BL_COMMON_LIBDIR}" >&2
exit 1
elif ! . "${SETTINGS_FILE}" 2> /dev/null; then
echo -e "\nError: Failed to source ${SETTINGS_FILE} in ${USR_CFG_DIR}/" >&2
exit 1
elif ! . "${CREDENTIALS_FILE}" 2> /dev/null; then
echo -e "\nWarning: Failed to source ${CREDENTIALS_FILE} in ${USR_CFG_DIR}/" >&2
if ! [[ -z "${CLIENT_ID}" ]] && [[ ${AUTH_MODE} == "L" ]];then
load_access_token "${CLIENT_ID}"
elif ! [[ -z "${CLIENT_ID}" ]] && [[ ${AUTH_MODE} == "A" ]];then
load_access_token "${ANON_ID}"
fi
fi
getargs "${@}" # get script parameters
# Testing for an Imgur account uses none of the dependencies, and the yad error window crashes jgmenu, so do the account test first.
# See: https://forums.bunsenlabs.org/viewtopic.php?pid=128284#p128284 and following posts.
# See if user has Imgur credentials, return exit code.
if (( TEST == 1 ));then
if [[ ! -f "${CREDENTIALS_FILE}" ]];then
exit 1
else
exit 0
fi
fi
declareDependencies "${APPS[@]}" # see if system has the required commands installed
# Registering for account
if (( REGISTER == 1 )) && [[ ! -f "${CREDENTIALS_FILE}" ]];then
# no account set up yet
load_access_token "${ANON_ID}"
elif (( REGISTER == 1 )) && [[ -f "${CREDENTIALS_FILE}" ]];then
# credentials file exists, so get username
[[ -z "${USER_NAME}" ]] && get_user # if not set in 'imgur.conf'
yad_question "--image=dialog-question" "
You are already registered with Imgur as\n
\"${USER_NAME}\"\n
Continue with script?
"
ret="$?"
(( ret == 1 )) && exit 0
fi
getimage "${FNAME}" # take screenshot, or upload file from file manager
if [[ "${AUTH_MODE}" = "L" ]];then # logged in as user
check_oauth2_client_secrets
load_access_token
if ! [[ -z "${ALBUM_TITLE}" ]];then # upload to specified album
if [[ -z "${USER_NAME}" ]];then # need to get user name, and write to imgur.conf
fetch_account_info getuser
fi
## get album id
RESPONSE=$(curl -sH --location --request GET "https://api.imgur.com/3/account/${USER_NAME}/albums/ids" \
--header "${AUTH}")
declare -a ids
ids+=($(jq -r '.data[]' <<< "${RESPONSE}"))
# match album ids with chosen album title
for (( i=0;i<=${#ids[@]};i++ ));do
ID="${ids[$i]}"
RESPONSE=$(curl -sH --location --request GET "https://api.imgur.com/3/account/${USER_NAME}/album/${ID}" --header "${AUTH}")
ALBUM="$(jq -r '.data.title' <<< "${RESPONSE}")"
if [[ "${ALBUM}" = "${ALBUM_TITLE}" ]];then
ALBUM_ID="${ids[$i]}"
else
continue
fi
done
# upload to album
CMD="curl -H \"${AUTH}\" -F image=@\"${IMG_FILE}\" -F title=\"${IMG_TITLE}\" \
-F album=\"${ALBUM_ID}\" https://api.imgur.com/3/image"
api_call "${CMD}" " Uploading to ${ALBUM_TITLE} "
else # don't upload to an album
CMD="curl -H \"${AUTH}\" -F image=@\"${IMG_FILE}\" -F title=\"${IMG_TITLE}\" \
https://api.imgur.com/3/image"
api_call "${CMD}" " Uploading ${IMG_FILE}..."
fi
else # anonymous upload
CMD="curl -H \"${AUTH}\" -F image=@\"${IMG_FILE}\" -F title=\"${IMG_TITLE}\" \
https://api.imgur.com/3/image"
api_call "${CMD}" " Uploading ${IMG_FILE}..."
fi
###############
if (( PIPE[0] != 0 ));then # PIPESTATUS shows if curl command failed
#get most recent upload since script started
if [[ $AUTH_MODE == "L" ]];then
IMAGES=$(curl -s --location --request GET 'https://api.imgur.com/3/account/me/images' \
--header "Authorization: Bearer ${ACCESS_TOKEN}")
IMG_ARR+=( $(jq -r .data[].id <<< "$IMAGES") )
# newest is first in array?
RECENT_ID="${IMG_ARR[0]}"
RECENT_IMG="$(check_image ${RECENT_ID})" # check if image was uploaded
if [[ $RECENT_IMG == "newer" ]];then
echo -e "\nFile exists"
delete_img "${RECENT_ID}"
delete_local
rm -f "${TEMP_THUMB}"
exit
else
echo -e "\nImage not found"
delete_local
exit 1
fi
fi
else
###############
DEL_HASH="$(jq -r '.data.deletehash' <<< "${RESPONSE}")"
IMG_LINK="$(jq -r '.data.link' <<< "${RESPONSE}")"
IMG_F="${IMG_LINK%.*}"
IMG_EXT="${IMG_LINK##*.}"
IMG_THUMB="${IMG_F}t.${IMG_EXT}"
BB_DIRECT="[img]${IMG_LINK}[/img]"
BB_THUMB_LINKED="[url=${IMG_LINK}][img]${IMG_THUMB}[/img][/url]"
if (( THUNAR == 0 ));then # not --auto-upload (BBCode only)
# download image thumbnail, for display in YAD dialog
TEMP_THUMB="${HOME}/tmp/thumb.jpg"
wget -q -O "${TEMP_THUMB}" "${IMG_THUMB}"
### Display BB Codes for uploaded image, and tidy up
# Put BBCode on clipboard with 'notify_msg'
if (( F_FLAG == 0 ));then # screenshot was taken
MSG="\nBBCode for linked thumbnail\n\n \
${IMG_FILE}\n\n \
is on the clipboard.\n\n \
File was saved as:\n \
${IMG_FILE}\n"
else # file was uploaded
MSG="\nBBCode for linked thumbnail\n\n \
${IMG_FILE}\n\n \
is on the clipboard.\n"
fi
notify_msg "${MSG}"
# Display dialog
TEXT="
BB Code - Image thumbnail Linked
Use Ctrl-C/Ctrl-V to copy/paste the selection.
BBCode for a linked thumbnail will automatically be
put on the clipboard.
"
RET=$(${DIALOG} --image-on-top --image="${TEMP_THUMB}" "${TITLE}" \
--form \
--field="BB Code - Thumbnail linked":TXT "${BB_THUMB_LINKED}" \
--field="BB Code - Direct image link":TXT "${BB_DIRECT}" \
${DELETE} ${CLOSE} --width=680 ${T}"${TEXT}" --text-align=left)
RET="$?"
if (( RET == 2 ));then
if [[ $AUTH_MODE == "A" ]];then
delete_images "${DEL_HASH}"
else
delete_images "${IMG_ID}"
fi
fi
rm -f "${TEMP_THUMB}"
else # just the BBCode on the clipboard is wanted.
MSG="\nBBCode for linked thumbnail\n\n${IMG_FILE}\n\nis on the clipboard"
notify_msg "${MSG}"
fi
fi
exit
The easy bit bl-w-imgur-pipemenu
#!/bin/bash
# bl-w-imgur-pipemenu an Openbox/Labwc Pipe Menu for use with Imgur
# Copyright (C) 2012 Philip Newborough <corenominal@corenominal.org>
# Copyright (C) 2013 Aleks-Daniel Jakimenko
# Copyright (C) 2015-2019 John Crawley <john@bunsenlabs.org>
# Copyright (C) 2024 Mick Amadio <01micko@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
HELP=' bl-w-imgur-pipemenu an Labwc Pipe Menu for use with bl-w-imgur-upload
It should normally be called from an openbox menu.
Options (usually passed from the menu):
-h --help show this message
If bl-w-imgur-pipemenu is called with no options (the usual method),
it will output an xml openbox pipemenu
for launching bl-w-imgur-uploads with various options
'
# look for a help option somewhere
for i in "$@"
do
case "$i" in
-h|--help)
echo "$HELP"
exit 0
;;
esac
done
BL_COMMON_LIBDIR='/usr/lib/bunsen/common'
if ! . "$BL_COMMON_LIBDIR/bl-includes" 2> /dev/null; then
echo $"Error: Failed to locate bl-includes in $BL_COMMON_LIBDIR" >&2
exit 1
fi
APPS=('wshot' 'bl-w-imgur-uploads')
declare -A AppStatu
for curApp in "${APPS[@]}"; do
type "${curApp}" >/dev/null 2>&1 && AppStatus[$curApp]=installed
done
if [[ $1 ]]; then
echo "$0: no such option $*" >&2
exit 1
else
# Pipemenu
menuStart
for opt in -l -r -s -f -d; do
case $opt in
-l)menuItem "Imgur Login" "bl-w-imgur-upload -l"
;;
-r)menuItem "Imgur Register" "bl-w-imgur-upload -r"
;;
-s)menuItem "Screenshot - Region" "bl-w-imgur-upload -s"
;;
-f)menuItem "Screenshot - Fullscreen" "bl-w-imgur-upload -f"
;;
-d)menuItem "Screenshot - Delayed" "bl-w-imgur-upload -d 5"
;;
esac
done
menuEnd
fi
exit 0
EDIT to add my config
### IMGUR SCREENSHOT DEFAULT CONFIG ####
### Read by bl-w-imgur-upload ###################
# Most of these settings can be overridden with script args
# Imgur settings
ANON_ID="ea6c0ef2987808e"
CLIENT_ID=""
CLIENT_SECRET=""
USER_NAME=""
ALBUM_TITLE=""
IMGUR_ICON_PATH=""
# Local file settings
# User directory to save image:
FILE_DIR="/home/mick/Pictures/Screenshots"
FILE_NAME="imgur-%Y_%m_%d-%H:%M:%S"
# possible formats are png | jpg | tiff | gif
FILE_FORMAT="png"
# Use this app to view images locally
IMG_VIEWER=bl-image-viewer
# Screenshot scrot commands
OUTPUT=HDMI-A-1
SCREENSHOT_SELECT_COMMAND="wshot -r "
SCREENSHOT_FULL_COMMAND="wshot -m -o $OUTPUT"
Last edited by micko01 (2024-06-23 09:00:13)
#!/bin/sh
echo '#include <stdio.h>\nvoid main() { printf("Hi, bunsenlabs\\n"); return; }' > bunsen.c
gcc bunsen.c -o bunsen
./bunsen
Offline
^thanks!
I just want to diff it with the original to get an idea of what changes wayland demands for it to work.
I likely won't even run it.
PS bl-imgur-upload is so long... I feel sure that script could be simpler, but at the time had plenty of other things to think about and it seems to work OK, so left it as-is.
Last edited by johnraff (2024-06-23 09:39:35)
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
I got a script working on labwc to send volume/mute key presses to mako notification daemon...
I think I'm done with this setup, those notifications were the only piece missing for my needs.
No, he can't sleep on the floor. What do you think I'm yelling for?!!!
Offline
I got a script working on labwc to send volume/mute key presses to mako notification daemon...
https://i.imgur.com/dr1ORgVt.png
I think I'm done with this setup, those notifications were the only piece missing for my needs.
Nice.
97F playing music. It ever spike up higher? Labwc and sway can run a bit hot o this Dell. Probably just the hardware, but maybe it's Wayland.
You must unlearn what you have learned.
-- yoda
Online
^ Normal temp for this inexpensive Lenovo laptop is between 94 and 108 I'd say. The fan runs on low (very quiet) preety consistently under load, and only occasionally at idle. Basically, if it spins up to where I notice it something's wrong. On Windows it would spin up all the time, though.
I'll let you know next time I notice fan noise/temp spike. What kind of temp are you seeing, and your temp is lower using Xorg?
No, he can't sleep on the floor. What do you think I'm yelling for?!!!
Offline
^ Normal temp for this inexpensive Lenovo laptop is between 94 and 108 I'd say. The fan runs on low (very quiet) preety consistently under load, and only occasionally at idle. Basically, if it spins up to where I notice it something's wrong. On Windows it would spin up all the time, though.
I'll let you know next time I notice fan noise/temp spike. What kind of temp are you seeing, and your temp is lower using Xorg?
This laptop runs around 40C / 104F after it's warmed up; at boot it's around 32C / 90F. It will spike up to 80-90C on Wayland when I start playing music or video (mostly video) then return to about 40-45C. Does the same on Xorg, but I seem to notice it more with Wayland. Like yours it really spins up if I'm using Windows (Win 11 in this case). I put a second hard drive in and dual boot.
This laptop has always had heat issues. I replaced the fan a year ago and that helped a lot.
Back on topic -
You must unlearn what you have learned.
-- yoda
Online
Offline
I'm not completely sure about this terminal colour scheme.
Very monochromatic. Compare to...
https://images2.imgbox.com/70/2b/PKEfSy7S_o.png
I'm messing with sfwbar. BunsenLabs is going to be ready for the switch to Wayland when the time comes...
Some good stuff going on with @micko01, @johnraff and I here...
No, he can't sleep on the floor. What do you think I'm yelling for?!!!
Offline
@HHH will bl still be openbox or are you guys and girls going to use something else... Looks awesome though.
@dobbie03 Looks like it goes well to me. nice. Unnerving background, I guess that's the point.
Last edited by Zepher (2024-06-26 21:21:09)
'The Universe is under no obligation to make sense to you'
Offline
@hhh will bl still be openbox or are you guys and girls going to use something else... Looks awesome though.
Openbox won't run on Wayland. Shown is labwc, an openbox-like Wayland/wlroots compositor, a project started by BL's own @malm...
https://github.com/labwc/labwc
https://labwc.github.io/
You can read about thoughts on and suggestions for the eventual transition to Wayland in this thread...
https://forums.bunsenlabs.org/viewtopic.php?id=8843
Info about wlroots here...
No, he can't sleep on the floor. What do you think I'm yelling for?!!!
Offline
Online
I'm not completely sure about this terminal colour scheme.
Looks all good to me @Dobbie !
Top shots again fellas.
Last edited by altman (2024-06-26 22:57:00)
My Linux installs are as in my music; it s on Metal
Offline
Zepher wrote:@hhh will bl still be openbox or are you guys and girls going to use something else... Looks awesome though.
Openbox won't run on Wayland. Shown is labwc, an openbox-like Wayland/wlroots compositor, a project started by BL's own @malm...
https://github.com/labwc/labwc
https://labwc.github.io/You can read about thoughts on and suggestions for the eventual transition to Wayland in this thread...
https://forums.bunsenlabs.org/viewtopic.php?id=8843
Info about wlroots here...
Looks great, like the contrasts in there @hhh.
My Linux installs are as in my music; it s on Metal
Offline
hhh wrote:Some good stuff going on with @micko01, @johnraff and I here...
That's an understatement. You 3 are on a roll; epic progress.
Back on topic; Windows 10 this afternoon -
Oh, nice wall, remember that wall @PackRat, it was from a little
while ago ! It was in Europe if I remember well!
My Linux installs are as in my music; it s on Metal
Offline