diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rwxr-xr-x | bot.sh | 172 | ||||
| -rw-r--r-- | commands/callback | 149 | ||||
| -rw-r--r-- | commands/clean | 7 | ||||
| -rw-r--r-- | commands/commands | 395 | ||||
| -rw-r--r-- | commands/ib_callback | 248 | ||||
| -rw-r--r-- | commands/ib_inline | 443 | ||||
| -rw-r--r-- | commands/inline | 345 | ||||
| -rw-r--r-- | functions/help | 83 | ||||
| -rw-r--r-- | functions/ib_auth | 171 | ||||
| -rw-r--r-- | functions/ib_authconfig | 57 | ||||
| -rw-r--r-- | functions/ib_config | 339 | ||||
| -rw-r--r-- | functions/ib_date | 33 | ||||
| -rw-r--r-- | functions/ib_lock | 13 | ||||
| -rw-r--r-- | functions/ib_meta | 110 | ||||
| -rw-r--r-- | functions/ib_original | 42 | ||||
| -rw-r--r-- | functions/ib_post | 92 | ||||
| -rw-r--r-- | functions/ib_size | 21 | ||||
| -rw-r--r-- | functions/ib_token | 38 |
19 files changed, 2760 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0633ad7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +cache +config @@ -0,0 +1,172 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin +# +# Run this software with `env -i` to avoid variable conflict + +set -e +umask 77 + +for required in busybox curl jq recode +do + if ! command -v ${required} > /dev/null + then + missing="${missing} ${required}" + fi +done + +if [ -n "${missing}" ] +then + echo "Missing dependencies:${missing}\n" \ + "For more information follow: https://command-not-found.com/" + exit 1 +fi + +dir="${0%/*}" +cache="${dir}/cache" +config="${dir}/config" +commands="${dir}/commands" +functions="${dir}/functions" +offset="-1" + +if [ -n "${1}" ] +then + while getopts ha:s:p: options + do + case "${options}" in + (h) + help=0 + ;; + (a) + address="${OPTARG}" + ;; + (s) + max_size=${OPTARG} + ;; + (p) + proxy="${OPTARG}" + ;; + (*) + echo "See '${0} -h'" + exit 1 + ;; + esac + done + + shift $((OPTIND - 1)) +else + help=0 +fi + +if [ -n "${help}" ] +then + echo "Sekoohaka Bot" \ + "\n\nUsage: ${0} [options] [token]" \ + "\n\nOptions:" \ + "\n -h\t\tShow help information" \ + "\n -a <addr>\tTelegram Bot API address, default: api.telegram.org" \ + "\n -s <size>\tMax file size allowed to send with URL, default: 10485760" \ + "\n -p <addr>\tProxy address for external requests" + exit 0 +fi + +if [ -z "${address}" ] +then + address="https://api.telegram.org" +fi + +if [ -n "${max_size}" ] +then + if ! test ${max_size} -gt 0 > /dev/null 2>&1 + then + echo "Illegal file size" + exit 1 + fi +else + max_size=10485760 +fi + +if [ -n "${1}" ] +then + token="${1}" + shift +else + echo "No access token specified" + exit 1 +fi + +for function in $(busybox --list) +do + if ! type ${function} | busybox grep -q "shell builtin" + then + alias ${function}="busybox ${function}" + fi +done + +alias stop="wait && exit" +alias htmlescape="sed -e 's/</\</g' -e 's/>/\>/g'" +alias urlencode="jq -Rr @uri" + +ascii_table="$(awk 'BEGIN{for(c=33;c<127;c++)printf"%c ",c}')" + +rm -fr "${cache}" +mkdir -p "${cache}" +mkdir -p "${config}" + +curl --get \ + --max-time 10 \ + --output "${cache}/getMe.json" \ + --show-error \ + --silent \ + "${address}/bot${token}/getMe" + +if ! jq -e '.' "${cache}/getMe.json" > /dev/null +then + cat "${cache}/getMe.json" + exit 1 +fi + +username="$(jq -r '.result.username' "${cache}/getMe.json")" + +if [ "${username}" = "null" ] +then + echo "Failed to authorize the bot" + exit 1 +fi + +echo "Bot: ${username}" + +while trap 'stop 0' INT TERM +do + if ! curl --data "offset=${offset}" \ + --get \ + --output "${cache}/getUpdates.json" \ + --silent \ + "${address}/bot${token}/getUpdates" + then + continue + fi + + if ! update_id="$(jq -r '.result.[0].update_id' "${cache}/getUpdates.json")" + then + continue + fi + + if [ "${update_id}" != "null" ] + then + update="${cache}/${update_id}.json" + + if ! jq '.result.[0]' "${cache}/getUpdates.json" > "${update}" + then + continue + fi + + for command in "${commands}"/* + do + . "${command}" & + done + + offset="$((update_id + 1))" + fi +done diff --git a/commands/callback b/commands/callback new file mode 100644 index 0000000..093ee26 --- /dev/null +++ b/commands/callback @@ -0,0 +1,149 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +set -- $(jq -r '.callback_query.data' "${update}") + +if [ -n "${1}" ] +then + case "${1}" in + ("short") + command_short=0 + ;; + ("reset") + command_reset=0 + ;; + ("stop") + command_stop=0 + ;; + (*) + exit 0 + ;; + esac + + shift +else + exit 0 +fi + +query_id="$(jq -r '.callback_query.id' "${update}")" + +if [ -n "${command_short}" ] +then + user_id="$(jq -r '.callback_query.from.id' "${update}")" + short_config="${config}/${user_id}/short" + + if [ -n "${1}" ] + then + short_query="${@}" + shift ${#} + else + notification_text="You must specify the query" + fi + + until mkdir "${config}/${user_id}_short.lock" > /dev/null 2>&1 + do + sleep 1 + done + + if [ -z "${notification_text}" ] && ! mkdir -p "${short_config}" + then + notification_text="Failed to create user config" + fi + + if [ -z "${notification_text}" ] + then + if short="$(grep -lrx "${short_query}" "${short_config}")" + then + rm -f "${short}" + notification_text="Removed shortcut" + else + set -- $(ls -x "${short_config}") + + if [ ${#} -le 50 ] + then + printf "%s" "${short_query}" > "${short_config}/$(date +%s)${query_id}" + notification_text="Saved shortcut" + else + notification_text="Too many shortcuts" + fi + fi + fi + + rm -fr "${config}/${user_id}_short.lock" +fi + +if [ -n "${command_reset}" ] +then + user_id="$(jq -r '.callback_query.from.id' "${update}")" + + if mkdir "${config}/${user_id}_reset.lock" > /dev/null 2>&1 + then + notification_text="Click again to confirm shortcuts removing" + fi + + if [ -z "${notification_text}" ] + then + short_config="${config}/${user_id}/short" + + until mkdir "${config}/${user_id}_short.lock" > /dev/null 2>&1 + do + sleep 1 + done + + if rm -fr "${short_config}" + then + notification_text="Removed all shortcuts" + else + notification_text="Something went wrong, try again later" + fi + + rm -fr "${config}/${user_id}_short.lock" + rm -fr "${config}/${user_id}_reset.lock" + fi +fi + +if [ -n "${command_stop}" ] +then + user_id="$(jq -r '.callback_query.from.id' "${update}")" + + if mkdir "${config}/${user_id}_stop.lock" > /dev/null 2>&1 + then + notification_text="Click again to confirm data removing" + fi + + if [ -z "${notification_text}" ] + then + locks="auth short" + + for lock in ${locks} + do + until mkdir "${config}/${user_id}_${lock}.lock" > /dev/null 2>&1 + do + sleep 1 + done + done + + if rm -fr "${config}/${user_id}" + then + notification_text="Removed all your data" + else + notification_text="Something went wrong, try again later" + fi + + for lock in ${locks} + do + rm -fr "${config}/${user_id}_${lock}.lock" + done + + rm -fr "${config}/${user_id}_stop.lock" + fi +fi + +curl --data-urlencode "callback_query_id=${query_id}" \ + --data-urlencode "text=${notification_text}" \ + --data-urlencode "cache_time=0" \ + --get \ + --silent \ + "${address}/bot${token}/answerCallbackQuery" > /dev/null diff --git a/commands/clean b/commands/clean new file mode 100644 index 0000000..83c33a9 --- /dev/null +++ b/commands/clean @@ -0,0 +1,7 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +find "${cache}" -type f -mmin +5 -delete > /dev/null 2>&1 +find "${config}" -name "*.lock" -type d -mmin +1 -delete > /dev/null 2>&1 diff --git a/commands/commands b/commands/commands new file mode 100644 index 0000000..60d8a70 --- /dev/null +++ b/commands/commands @@ -0,0 +1,395 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +set -- $(jq -r '.message.text' "${update}") + +if [ -n "${1}" ] +then + case "${1}" in + ("/start" | "/start@${username}") + command_help=0 + ;; + ("/help" | "/help@${username}") + command_help=0 + ;; + ("/authorize" | "/authorize@${username}") + command_authorize=0 + ;; + ("/original" | "/original@${username}") + command_original=0 + ;; + ("/post" | "/post@${username}") + command_post=0 + ;; + ("/short" | "/short@${username}") + command_short=0 + ;; + ("/shorts" | "/shorts@${username}") + command_shorts=0 + ;; + ("/stop" | "/stop@${username}") + command_stop=0 + ;; + ("/prpr" | "/prpr@${username}") + command_prpr=0 + ;; + (*) + exit 0 + ;; + esac + + shift +else + exit 0 +fi + +chat_id="$(jq -r '.message.chat.id' "${update}")" +message_thread_id="$(jq -r '.message.message_thread_id' "${update}")" +message_id="$(jq -r '.message.message_id' "${update}")" + +reply_parameters="$(jq --null-input --compact-output \ + --arg message_id "${message_id}" \ + '{"message_id": $message_id, "allow_sending_without_reply": true}')" + +if [ "${message_thread_id}" = "null" ] +then + unset message_thread_id +fi + +if [ -n "${command_help}" ] +then + . "${functions}/help" +fi + +if [ -n "${command_authorize}" ] +then + if [ -n "${1}" ] + then + user_id="$(jq -r '.message.from.id' "${update}")" + + ib_board="${1}" + . "${functions}/ib_authconfig" + + if [ -z "${ib_config}" ] + then + output_text="Unsupported image board" + fi + + shift + else + output_text="You must specify the image board" + fi + + if [ -z "${output_text}" ] + then + if [ -n "${1}" ] + then + ib_login="${1}" + shift + fi + + if [ -n "${1}" ] + then + ib_api_key="${1}" + shift + fi + + . "${functions}/ib_lock" + fi + + if [ -z "${output_text}" ] + then + if [ -n "${ib_noverify}" ] + then + output_text="Authorization cannot be verified, make sure you provided the correct credentials" + else + output_text="Authorized successfully" + fi + fi +fi + +if [ -n "${command_original}" ] || [ -n "${command_post}" ] +then + if [ -z "${1}" ] + then + reply_text="$(jq -r '.message.reply_to_message.text' "${update}")" + + if [ "${reply_text}" = "null" ] + then + reply_text="$(jq -r '.message.reply_to_message.caption' "${update}")" + fi + + if [ "${reply_text}" != "null" ] + then + ib_reply_name="$(printf "%s" "${reply_text}" | awk 'NR==1')" + ib_post_id="$(printf "%s" "${reply_text}" | awk '/ID:/ {print $2}')" + + for ib_board in ${ascii_table} + do + . "${functions}/ib_config" + unset output_text + + if [ "${ib_reply_name}" = "${ib_name}" ] + then + break + fi + done + + set -- ${ib_board} ${ib_post_id} + fi + fi + + if [ -n "${1}" ] + then + user_id="$(jq -r '.message.from.id' "${update}")" + + ib_board="${1}" + ib_mode="p" + . "${functions}/ib_config" + . "${functions}/ib_authconfig" + + shift + else + output_text="You must specify the image board" + fi + + if [ -n "${1}" ] + then + ib_post_id="${1}" + shift + elif [ -z "${output_text}" ] + then + output_text="You must specify the post ID" + fi + + if [ -z "${output_text}" ] && [ -n "${ib_config}" ] + then + . "${functions}/ib_token" + fi + + if [ -z "${output_text}" ] + then + if [ -n "${ib_exception_idol}" ] + then + ib_query="id_range:${ib_post_id}" + else + ib_query="id:${ib_post_id}" + fi + + ib_file="${cache}/${update_id}_data.json" + + if ! curl --data-urlencode "${ib_dfield1}" \ + --data-urlencode "${ib_dfield2}" \ + --data-urlencode "${ib_dfield3}" \ + --data-urlencode "${ib_dfield4}" \ + --data-urlencode "${ib_dfield5}" \ + --data-urlencode "${ib_dfield6}" \ + --data-urlencode "${ib_dlimit}=1" \ + --data-urlencode "${ib_dquery}=${ib_query}" \ + --get \ + --header "${ib_header}" \ + --max-time 5 \ + --output "${ib_file}" \ + --proxy "${proxy}" \ + --silent \ + --user-agent "Sekoohaka" \ + "${ib_data_url}" + then + output_text="Failed to access ${ib_name} API" + fi + + if [ -z "${output_text}" ] && ! [ -f "${ib_file}" ] + then + output_text="Failed to access ${ib_name} API" + fi + + if [ -z "${output_text}" ] && ! jq -e '.' "${ib_file}" > /dev/null 2>&1 + then + output_text="An unknown error occurred" + fi + + if [ -z "${output_text}" ] && ! jq -e ".${ib_iarray}[0]|has(\"${ib_iid}\")" "${ib_file}" > /dev/null 2>&1 + then + output_text="No results found. Try different post ID" + fi + fi + + if [ -z "${output_text}" ] + then + if [ -n "${command_original}" ] + then + . "${functions}/ib_original" + + if [ -n "${ib_file_url}" ] && [ "${ib_file_url}" != "null" ] + then + reply_markup="$(jq --null-input --compact-output \ + --arg text1 "Original file link" \ + --arg url1 "${ib_file_url}" \ + '{"inline_keyboard": [[{"text": $text1, "url": $url1}]]}')" + fi + + if [ -z "${output_text}" ] + then + curl --data-urlencode "chat_id=${chat_id}" \ + --data-urlencode "message_thread_id=${message_thread_id}" \ + --data-urlencode "action=upload_document" \ + --get \ + --silent \ + "${address}/bot${token}/sendChatAction" > /dev/null + + output_file="${cache}/${update_id}_sendDocument.json" + + curl --data-urlencode "chat_id=${chat_id}" \ + --data-urlencode "message_thread_id=${message_thread_id}" \ + --data-urlencode "document=${ib_file_url}" \ + --data-urlencode "thumbnail=${ib_preview_url}" \ + --data-urlencode "reply_parameters=${reply_parameters}" \ + --data-urlencode "reply_markup=${reply_markup}" \ + --get \ + --max-time 5 \ + --output "${output_file}" \ + --silent \ + "${address}/bot${token}/sendDocument" + + if [ -z "${output_text}" ] && ! jq -e '.' "${output_file}" > /dev/null 2>&1 + then + output_text="An unknown error occurred" + fi + + if [ -z "${output_text}" ] && [ "$(jq -r '.ok' "${output_file}")" != "true" ] + then + output_text="Failed to send the original file" + fi + + if [ -z "${output_text}" ] + then + exit 0 + fi + fi + elif [ -n "${command_post}" ] + then + . "${functions}/ib_post" + + link_preview_options="$(jq --null-input --compact-output \ + --arg url1 "${ib_sample_url}" \ + '{"url": $url1, "prefer_small_media": true, "show_above_text": true}')" + + reply_markup="$(jq --null-input --compact-output \ + --arg text1 "Post link" \ + --arg url1 "${ib_page_url}$(printf "%s" "${ib_post_id}" | urlencode)" \ + '{"inline_keyboard": [[{"text": $text1, "url": $url1}]]}')" + + if [ ${ib_tags_count} -gt 0 ] + then + reply_markup="$(printf "%s" "${reply_markup}" | jq --compact-output \ + --arg text1 "Tags (${ib_tags_count})" \ + --arg data1 "tags ${ib_board} ${ib_post_id}" \ + '.inline_keyboard.[0] += [{"text": $text1, "callback_data": $data1}]')" + fi + fi + elif [ -n "${command_post}" ] + then + reply_markup="$(jq --null-input --compact-output \ + --arg text1 "Retry" \ + --arg data1 "post ${ib_board} ${ib_post_id}" \ + '{"inline_keyboard": [[{"text": $text1, "callback_data": $data1}]]}')" + fi +fi + +if [ -n "${command_short}" ] +then + if [ -n "${1}" ] + then + short_query="${@}" + shift ${#} + else + output_text="You must specify the query" + fi + + if [ ${#short_query} -gt 1024 ] + then + output_text="Query is too long" + fi + + if [ -z "${output_text}" ] + then + output_text="<b>Shortcut:</b> <code>$(printf "%s" "${short_query}" | htmlescape)</code>" + + reply_markup="$(jq --null-input --compact-output \ + --arg text1 "Open inline" \ + --arg query1 "${short_query}" \ + '{"inline_keyboard": [[{"text": $text1, "switch_inline_query_current_chat": $query1}]]}')" + + short_query="short ${short_query}" + + if [ ${#short_query} -le 64 ] + then + reply_markup="$(printf "%s" "${reply_markup}" | jq --compact-output \ + --arg text1 "Manage" \ + --arg data1 "${short_query}" \ + '.inline_keyboard.[0] += [{"text": $text1, "callback_data": $data1}]')" + fi + fi +fi + +if [ -n "${command_shorts}" ] +then + user_id="$(jq -r '.message.from.id' "${update}")" + short_config="${config}/${user_id}/short" + + until mkdir "${config}/${user_id}_short.lock" > /dev/null 2>&1 + do + sleep 1 + done + + if [ -d "${short_config}" ] + then + shorts="$(ls -x "${short_config}")" + fi + + set -- ${shorts} + + if [ ${#} -gt 0 ] + then + output_text="You have ${#} saved shortcuts" + + reply_markup="$(jq --null-input --compact-output \ + --arg text1 "Open inline" \ + --arg query1 "shorts" \ + --arg text2 "Remove all" \ + --arg data2 "reset" \ + '{"inline_keyboard": [[{"text": $text1, "switch_inline_query_current_chat": $query1}, {"text": $text2, "callback_data": $data2}]]}')" + else + output_text="You have no saved shortcuts yet" + fi + + rm -fr "${config}/${user_id}_short.lock" +fi + +if [ -n "${command_stop}" ] +then + output_text="Remove all your data including login data and saved shortcuts" + + reply_markup="$(jq --null-input --compact-output \ + --arg text1 "Remove my data" \ + --arg data1 "stop" \ + '{"inline_keyboard": [[{"text": $text1, "callback_data": $data1}]]}')" +fi + +if [ -n "${command_prpr}" ] +then + output_text="ฅ^•ﻌ•^ฅ" +fi + +curl --data-urlencode "chat_id=${chat_id}" \ + --data-urlencode "message_thread_id=${message_thread_id}" \ + --data-urlencode "text=${output_text}" \ + --data-urlencode "parse_mode=HTML" \ + --data-urlencode "link_preview_options=${link_preview_options}" \ + --data-urlencode "reply_parameters=${reply_parameters}" \ + --data-urlencode "reply_markup=${reply_markup}" \ + --get \ + --silent \ + "${address}/bot${token}/sendMessage" > /dev/null diff --git a/commands/ib_callback b/commands/ib_callback new file mode 100644 index 0000000..e759f33 --- /dev/null +++ b/commands/ib_callback @@ -0,0 +1,248 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +set -- $(jq -r '.callback_query.data' "${update}") + +if [ -n "${1}" ] +then + case "${1}" in + ("post") + ib_post=0 + ;; + ("tags") + ib_tags=0 + ;; + (*) + exit 0 + ;; + esac + + shift +else + exit 0 +fi + +query_id="$(jq -r '.callback_query.id' "${update}")" + +if [ -n "${1}" ] +then + user_id="$(jq -r '.callback_query.from.id' "${update}")" + + ib_board="${1}" + ib_mode="p" + . "${functions}/ib_config" + . "${functions}/ib_authconfig" + + notification_text="${output_text}" + shift +else + notification_text="No image board specified" +fi + +if [ -n "${1}" ] +then + ib_post_id="${1}" + shift +elif [ -z "${notification_text}" ] +then + notification_text="No post ID specified" +fi + +if [ -z "${notification_text}" ] && [ -n "${ib_config}" ] +then + ib_lock=0 + . "${functions}/ib_token" + + if [ -n "${output_text}" ] + then + notification_text="${output_text} Try again in a few seconds" + fi +fi + +if [ -z "${notification_text}" ] +then + if [ -n "${ib_exception_idol}" ] + then + ib_query="id_range:${ib_post_id}" + else + ib_query="id:${ib_post_id}" + fi + + ib_file="${cache}/${update_id}_data.json" + + if ! curl --data-urlencode "${ib_dfield1}" \ + --data-urlencode "${ib_dfield2}" \ + --data-urlencode "${ib_dfield3}" \ + --data-urlencode "${ib_dfield4}" \ + --data-urlencode "${ib_dfield5}" \ + --data-urlencode "${ib_dfield6}" \ + --data-urlencode "${ib_dlimit}=1" \ + --data-urlencode "${ib_dquery}=${ib_query}" \ + --get \ + --header "${ib_header}" \ + --max-time 5 \ + --output "${ib_file}" \ + --proxy "${proxy}" \ + --silent \ + --user-agent "Sekoohaka" \ + "${ib_data_url}" + then + notification_text="Failed to access ${ib_name} API" + fi + + if [ -z "${notification_text}" ] && ! [ -f "${ib_file}" ] + then + notification_text="Failed to access ${ib_name} API" + fi + + if [ -z "${notification_text}" ] && ! jq -e '.' "${ib_file}" > /dev/null 2>&1 + then + notification_text="An unknown error occurred" + fi + + if [ -z "${notification_text}" ] && ! jq -e ".${ib_iarray}[0]|has(\"${ib_iid}\")" "${ib_file}" > /dev/null 2>&1 + then + notification_text="No results found" + fi +fi + +if [ -z "${notification_text}" ] +then + chat_id="$(jq -r '.callback_query.message.chat.id' "${update}")" + message_id="$(jq -r '.callback_query.message.message_id' "${update}")" + inline_message_id="$(jq -r '.callback_query.inline_message_id' "${update}")" + + if [ -n "${ib_post}" ] + then + . "${functions}/ib_post" + + link_preview_options="$(jq --null-input --compact-output \ + --arg url1 "${ib_sample_url}" \ + '{"url": $url1, "prefer_small_media": true, "show_above_text": true}')" + + reply_markup="$(jq --null-input --compact-output \ + --arg text1 "Post link" \ + --arg url1 "${ib_page_url}$(printf "%s" "${ib_post_id}" | urlencode)" \ + '{"inline_keyboard": [[{"text": $text1, "url": $url1}]]}')" + + if [ ${ib_tags_count} -gt 0 ] + then + reply_markup="$(printf "%s" "${reply_markup}" | jq --compact-output \ + --arg text1 "Tags (${ib_tags_count})" \ + --arg data1 "tags ${ib_board} ${ib_post_id}" \ + '.inline_keyboard.[0] += [{"text": $text1, "callback_data": $data1}]')" + fi + elif [ -n "${ib_tags}" ] + then + ib_created_at="$(jq -r ".${ib_iarray}[${array_count}].${ib_icreated}" "${ib_file}")" + ib_file_url="$(jq -r ".${ib_iarray}[0].${ib_ifile}" "${ib_file}")" + ib_file_size="$(jq -r ".${ib_iarray}[0].${ib_isize}" "${ib_file}")" + ib_tags="$(jq -r ".${ib_iarray}[0].${ib_itags}" "${ib_file}" | htmlescape)" + ib_tags_offset=${1:-0} + + . "${functions}/ib_size" + . "${functions}/ib_meta" + + if [ -n "${ib_tags}" ] && [ "${ib_tags}" != "null" ] + then + set -- ${ib_tags} + + if [ ${#} -ge $((ib_tags_offset + 1)) ] + then + shift ${ib_tags_offset} + else + notification_text="No tags found" + fi + else + notification_text="Failed to get tags" + fi + + if [ -z "${notification_text}" ] + then + ib_tags_count=0 + + while [ -n "${1}" ] + do + ib_tag="<code>${1}</code>" + ib_tags_length=${#output_text} + ib_tag_length=${#ib_tag} + + if [ $((ib_tags_length + ib_tag_length)) -gt 2048 ] + then + break + fi + + output_text="${output_text} ${ib_tag}" + ib_tags_count=$((ib_tags_count + 1)) + shift + done + + link_preview_options="$(jq --null-input --compact-output \ + --arg url1 "${ib_sample_url}" \ + '{"url": $url1, "prefer_small_media": true, "show_above_text": true}')" + + reply_markup="$(jq --null-input --compact-output \ + --arg text1 "Back" \ + --arg data1 "post ${ib_board} ${ib_post_id}" \ + '{"inline_keyboard": [[{"text": $text1, "callback_data": $data1}]]}')" + + if [ ${ib_tags_offset} -gt 0 ] + then + reply_markup="$(printf "%s" "${reply_markup}" | jq --compact-output \ + --arg text1 "Over" \ + --arg data1 "tags ${ib_board} ${ib_post_id}" \ + '.inline_keyboard.[0] += [{"text": $text1, "callback_data": $data1}]')" + fi + + if [ -n "${1}" ] + then + reply_markup="$(printf "%s" "${reply_markup}" | jq --compact-output \ + --arg text1 "Next" \ + --arg data1 "tags ${ib_board} ${ib_post_id} $((ib_tags_offset + ib_tags_count))" \ + '.inline_keyboard.[0] += [{"text": $text1, "callback_data": $data1}]')" + fi + fi + fi + + if [ -z "${notification_text}" ] + then + if [ "${chat_id}" = "null" ] + then + unset chat_id + unset message_id + fi + + output_file="${cache}/${update_id}_editMessageText.json" + + curl --data-urlencode "chat_id=${chat_id}" \ + --data-urlencode "message_id=${message_id}" \ + --data-urlencode "inline_message_id=${inline_message_id}" \ + --data-urlencode "text=${output_text}" \ + --data-urlencode "parse_mode=HTML" \ + --data-urlencode "link_preview_options=${link_preview_options}" \ + --data-urlencode "reply_markup=${reply_markup}" \ + --get \ + --output "${output_file}" \ + --silent \ + "${address}/bot${token}/editMessageText" + + if [ -z "${notification_text}" ] && ! jq -e '.' "${output_file}" > /dev/null 2>&1 + then + notification_text="An unknown error occurred" + fi + + if [ -z "${notification_text}" ] && [ "$(jq -r '.ok' "${output_file}")" != "true" ] + then + notification_text="Failed to update message" + fi + fi +fi + +curl --data-urlencode "callback_query_id=${query_id}" \ + --data-urlencode "text=${notification_text}" \ + --data-urlencode "cache_time=0" \ + --get \ + --silent \ + "${address}/bot${token}/answerCallbackQuery" > /dev/null diff --git a/commands/ib_inline b/commands/ib_inline new file mode 100644 index 0000000..9d75e11 --- /dev/null +++ b/commands/ib_inline @@ -0,0 +1,443 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +set -- $(jq -r '.inline_query.query' "${update}") + +if [ -n "${1}" ] +then + ib_mode="${1}" + + case "${ib_mode}" in + (l) + ib_opts="aq" + ;; + (p) + ib_opts="ampq" + ;; + (t) + ib_opts="aq" + ;; + (*) + exit 0 + ;; + esac + + shift +else + exit 0 +fi + +query_id="$(jq -r '.inline_query.id' "${update}")" + +if [ -n "${1}" ] +then + user_id="$(jq -r '.inline_query.from.id' "${update}")" + + ib_board="${1}" + . "${functions}/ib_config" + . "${functions}/ib_authconfig" + + shift +else + output_text="You must specify the image board" +fi + +if test "${1}" -gt 0 > /dev/null 2>&1 +then + ib_page="${1}" + shift +else + ib_page="1" + set -- -a ${@} +fi + +if [ -z "${output_text}" ] && [ -n "${1}" ] +then + ib_options="${@}" + + while getopts ${ib_opts} ib_getopts > /dev/null 2>&1 + do + case "${ib_getopts}" in + (a) + ib_autopaging=0 + ;; + (m) + ib_metadata=0 + ;; + (p) + ib_preview=0 + ;; + (q) + ib_quick=0 + ;; + (*) + output_text="Illegal option use" + ;; + esac + done + + shift $((OPTIND - 1)) +fi + +if [ -n "${1}" ] +then + ib_query="${@}" + shift ${#} +fi + +if [ -n "${output_text}" ] +then + output_title="An error occurred" +fi + +if [ -z "${output_text}" ] && [ -n "${ib_config}" ] +then + ib_lock=0 + . "${functions}/ib_token" + + if [ -n "${output_text}" ] + then + output_title="${output_text}" + output_text="Try again in a few seconds" + fi +fi + +if [ -z "${output_text}" ] +then + ib_offset="$(jq -r '.inline_query.offset' "${update}")" + + if [ -n "${ib_offset}" ] && [ "${ib_offset}" != "null" ] + then + ib_page="${ib_offset}" + fi + + if [ -n "${ib_query}" ] + then + if [ -n "${ib_iwildcard}" ] + then + ib_query="$(printf "%s" "${ib_query}" | sed "s/${ib_iwildcard}/\\\\${ib_iwildcard}/g" | tr '*' "${ib_iwildcard}")" + fi + + ib_query="${ib_dquery}=${ib_query}" + fi + + ib_file="${cache}/${update_id}_data.json" + + if ! curl --data-urlencode "${ib_dfield1}" \ + --data-urlencode "${ib_dfield2}" \ + --data-urlencode "${ib_dfield3}" \ + --data-urlencode "${ib_dfield4}" \ + --data-urlencode "${ib_dfield5}" \ + --data-urlencode "${ib_dfield6}" \ + --data-urlencode "${ib_dlimit}=10" \ + --data-urlencode "${ib_dpage}=$((ib_page + ib_ioffset))" \ + --data-urlencode "${ib_query}" \ + --get \ + --header "${ib_header}" \ + --max-time 5 \ + --output "${ib_file}" \ + --proxy "${proxy}" \ + --silent \ + --user-agent "Sekoohaka" \ + "${ib_data_url}" + then + output_text="Failed to access ${ib_name} API" + fi + + if [ -z "${output_text}" ] && ! [ -f "${ib_file}" ] + then + output_text="Failed to access ${ib_name} API" + fi + + if [ -n "${output_text}" ] + then + next_offset="${ib_page}" + fi + + if [ -z "${output_text}" ] && ! jq -e '.' "${ib_file}" > /dev/null 2>&1 + then + output_text="An unknown error occurred" + fi + + if [ -n "${output_text}" ] + then + output_title="An error occurred" + fi + + if [ -z "${output_text}" ] && ! jq -e ".${ib_iarray}[0]|has(\"${ib_iid}\")" "${ib_file}" > /dev/null 2>&1 + then + if [ -n "${ib_offset}" ] && [ "${ib_offset}" != "null" ] + then + output_title="End of results" + else + output_title="No results found" + fi + + case "${ib_mode}" in + (l) + output_text="Try different page or pool name" + ;; + (p) + output_text="Try different page or tags" + ;; + (t) + output_text="Try different page or tag name" + ;; + esac + fi +fi + +if [ -z "${output_text}" ] +then + results="[]" + array_count=0 + + while [ -n "${array_count}" ] + do + ib_id="$(jq -r ".${ib_iarray}[${array_count}].${ib_iid}" "${ib_file}")" + + if [ "${ib_id}" = "null" ] + then + break + fi + + case "${ib_mode}" in + (l) + ib_created_at="$(jq -r ".${ib_iarray}[${array_count}].${ib_icreated}" "${ib_file}")" + ib_pool="$(jq -r ".${ib_iarray}[${array_count}].${ib_ipool}" "${ib_file}")" + ib_count="$(jq -r ".${ib_iarray}[${array_count}].${ib_icount}" "${ib_file}")" + + unset ib_date_text + . "${functions}/ib_date" + + if [ -n "${ib_ispace}" ] + then + ib_pool="$(printf "%s" "${ib_pool}" | tr "${ib_ispace}" ' ')" + fi + + ib_result_id="${ib_page}${array_count}" + ib_text="$(printf "<b>%s</b>\n<b>ID:</b> <code>%s</code>" "${ib_name}" "${ib_id}")" + + if [ -n "${ib_date_text}" ] + then + ib_text="$(printf "%s\n<b>Date:</b> <code>%s</code>" "${ib_text}" "${ib_date_text}")" + fi + + ib_text="$(printf "%s\n<b>Name:</b> %s" "${ib_text}" "$(printf "%s" "${ib_pool}" | htmlescape)")" + ib_text="$(printf "%s\n<b>Post count:</b> %s" "${ib_text}" "${ib_count}")" + ib_button1_text="Pool link" + ib_button1_url="${ib_page_url}$(printf "%s" "${ib_id}" | urlencode)" + ib_button2_text="Resume" + ib_button2_query="l ${ib_board} ${ib_page}" + + if [ -n "${ib_options}" ] + then + ib_button2_query="${ib_button2_query} ${ib_options}" + fi + + result="$(jq --null-input --compact-output \ + --arg id "${ib_result_id}" \ + --arg title "${ib_pool:- }" \ + --arg text "${ib_text}" \ + --arg description "Click to send the pool information" \ + --arg text1 "${ib_button1_text}" \ + --arg url1 "${ib_button1_url}" \ + --arg text2 "${ib_button2_text}" \ + --arg query2 "${ib_button2_query}" \ + '{"type": "article", "id": $id, "title": $title, "input_message_content": {"message_text": $text, "parse_mode": "HTML"}, "description": $description, "reply_markup": {"inline_keyboard": [[{"text": $text1, "url": $url1}, {"text": $text2, "switch_inline_query_current_chat": $query2}]]}}')" + + if [ -n "${ib_quick}" ] + then + if [ -n "${ib_iorder}" ] + then + ib_id="${ib_id} ${ib_iorder}" + fi + + result="$(printf "%s" "${result}" | jq --compact-output \ + --arg text1 "Search posts" \ + --arg query1 "p ${ib_board} pool:${ib_id}" \ + '.reply_markup.inline_keyboard += [[{"text": $text1, "switch_inline_query_current_chat": $query1}]]')" + fi + ;; + (p) + ib_created_at="$(jq -r ".${ib_iarray}[${array_count}].${ib_icreated}" "${ib_file}")" + ib_file_url="$(jq -r ".${ib_iarray}[${array_count}].${ib_ifile}" "${ib_file}")" + ib_file_size="$(jq -r ".${ib_iarray}[${array_count}].${ib_isize}" "${ib_file}")" + + unset ib_date_text ib_resolution_text ib_type_text ib_size_text + . "${functions}/ib_date" + . "${functions}/ib_meta" + + if [ -n "${ib_preview}" ] + then + case "${ib_type}" in + (gif | video) + ib_sample_url="${ib_preview_url}" + ib_type="photo" + ;; + esac + fi + + ib_result_id="${ib_page}${array_count}" + ib_caption="$(printf "<b>%s</b>\n<b>ID:</b> <code>%s</code>" "${ib_name}" "${ib_id}")" + ib_button1_text="Post link" + ib_button1_url="${ib_page_url}$(printf "%s" "${ib_id}" | urlencode)" + ib_button2_text="Resume" + ib_button2_query="p ${ib_board} ${ib_page}" + + if [ -n "${ib_date_text}" ] + then + ib_caption="$(printf "%s\n<b>Date:</b> <code>%s</code>" "${ib_caption}" "${ib_date_text}")" + fi + + if [ -n "${ib_metadata}" ] + then + if [ -n "${ib_resolution_text}" ] + then + ib_caption="$(printf "%s\n<b>Resolution:</b> %s" "${ib_caption}" "${ib_resolution_text}")" + fi + + if [ -n "${ib_size_text}" ] + then + ib_caption="$(printf "%s\n<b>Size:</b> %s" "${ib_caption}" "${ib_size_text}")" + fi + + if [ -n "${ib_type_text}" ] + then + ib_caption="$(printf "%s\n<b>Type:</b> %s" "${ib_caption}" "${ib_type_text}")" + fi + fi + + if [ -n "${ib_options}" ] + then + ib_button2_query="${ib_button2_query} ${ib_options}" + fi + + case "${ib_type}" in + (photo) + result="$(jq --null-input --compact-output \ + --arg id "${ib_result_id}" \ + --arg photo_url "${ib_sample_url}" \ + --arg thumbnail_url "${ib_preview_url}" \ + --arg photo_width "${ib_width}" \ + --arg photo_height "${ib_height}" \ + --arg caption "${ib_caption}" \ + --arg text1 "${ib_button1_text}" \ + --arg url1 "${ib_button1_url}" \ + --arg text2 "${ib_button2_text}" \ + --arg query2 "${ib_button2_query}" \ + '{"type": "photo", "id": $id, "photo_url": $photo_url, "thumbnail_url": $thumbnail_url, "photo_width": $photo_width, "photo_height": $photo_height, "caption": $caption, "parse_mode": "HTML", "reply_markup": {"inline_keyboard": [[{"text": $text1, "url": $url1}, {"text": $text2, "switch_inline_query_current_chat": $query2}]]}}')" + ;; + (gif) + result="$(jq --null-input --compact-output \ + --arg id "${ib_result_id}" \ + --arg gif_url "${ib_file_url}" \ + --arg thumbnail_url "${ib_preview_url}" \ + --arg gif_width "${ib_width}" \ + --arg gif_height "${ib_height}" \ + --arg caption "${ib_caption}" \ + --arg text1 "${ib_button1_text}" \ + --arg url1 "${ib_button1_url}" \ + --arg text2 "${ib_button2_text}" \ + --arg query2 "${ib_button2_query}" \ + '{"type": "gif", "id": $id, "gif_url": $gif_url, "thumbnail_url": $thumbnail_url, "gif_width": $gif_width, "gif_height": $gif_height, "caption": $caption, "parse_mode": "HTML", "reply_markup": {"inline_keyboard": [[{"text": $text1, "url": $url1}, {"text": $text2, "switch_inline_query_current_chat": $query2}]]}}')" + ;; + (video) + result="$(jq --null-input --compact-output \ + --arg id "${ib_result_id}" \ + --arg mpeg4_url "${ib_file_url}" \ + --arg thumbnail_url "${ib_preview_url}" \ + --arg mpeg4_width "${ib_width}" \ + --arg mpeg4_height "${ib_height}" \ + --arg caption "${ib_caption}" \ + --arg text1 "${ib_button1_text}" \ + --arg url1 "${ib_button1_url}" \ + --arg text2 "${ib_button2_text}" \ + --arg query2 "${ib_button2_query}" \ + '{"type": "mpeg4_gif", "id": $id, "mpeg4_url": $mpeg4_url, "thumbnail_url": $thumbnail_url, "mpeg4_width": $mpeg4_width, "mpeg4_height": $mpeg4_height, "caption": $caption, "parse_mode": "HTML", "reply_markup": {"inline_keyboard": [[{"text": $text1, "url": $url1}, {"text": $text2, "switch_inline_query_current_chat": $query2}]]}}')" + ;; + esac + + if [ -n "${ib_quick}" ] + then + result="$(printf "%s" "${result}" | jq --compact-output \ + --arg text1 "Original" \ + --arg query1 "original ${ib_board} ${ib_id}" \ + --arg text2 "Post" \ + --arg query2 "post ${ib_board} ${ib_id}" \ + '.reply_markup.inline_keyboard += [[{"text": $text1, "switch_inline_query_current_chat": $query1}, {"text": $text2, "switch_inline_query_current_chat": $query2}]]')" + fi + ;; + (t) + ib_tag="$(jq -r ".${ib_iarray}[${array_count}].${ib_itag}" "${ib_file}")" + ib_count="$(jq -r ".${ib_iarray}[${array_count}].${ib_icount}" "${ib_file}")" + + if [ -n "${ib_irecode}" ] + then + if ib_tag_recode="$(printf "%s" "${ib_tag}" | recode ${ib_irecode}..ASCII 2>&1)" + then + ib_tag="${ib_tag_recode}" + fi + fi + + ib_result_id="${ib_page}${array_count}" + ib_text="$(printf "<b>%s</b>\n<b>ID:</b> <code>%s</code>" "${ib_name}" "${ib_id}")" + ib_text="$(printf "%s\n<b>Name:</b> <code>%s</code>" "${ib_text}" "$(printf "%s" "${ib_tag}" | htmlescape)")" + ib_text="$(printf "%s\n<b>Post count:</b> %s" "${ib_text}" "${ib_count}")" + ib_button1_text="Wiki link" + ib_button1_url="${ib_page_url}$(printf "%s" "${ib_tag}" | urlencode)" + ib_button2_text="Resume" + ib_button2_query="t ${ib_board} ${ib_page}" + + if [ -n "${ib_options}" ] + then + ib_button2_query="${ib_button2_query} ${ib_options}" + fi + + result="$(jq --null-input --compact-output \ + --arg id "${ib_result_id}" \ + --arg title "${ib_tag:- }" \ + --arg text "${ib_text}" \ + --arg description "Click to send the tag information" \ + --arg text1 "${ib_button1_text}" \ + --arg url1 "${ib_button1_url}" \ + --arg text2 "${ib_button2_text}" \ + --arg query2 "${ib_button2_query}" \ + '{"type": "article", "id": $id, "title": $title, "input_message_content": {"message_text": $text, "parse_mode": "HTML"}, "description": $description, "reply_markup": {"inline_keyboard": [[{"text": $text1, "url": $url1}, {"text": $text2, "switch_inline_query_current_chat": $query2}]]}}')" + + if [ -n "${ib_quick}" ] + then + result="$(printf "%s" "${result}" | jq --compact-output \ + --arg text1 "Search posts" \ + --arg query1 "p ${ib_board} ${ib_tag}" \ + '.reply_markup.inline_keyboard += [[{"text": $text1, "switch_inline_query_current_chat": $query1}]]')" + fi + ;; + esac + + results="$(printf "%s" "${results}" | jq -c ".[${array_count}] += ${result}")" + array_count=$((array_count + 1)) + done + + if [ -n "${ib_autopaging}" ] + then + next_offset="$((ib_page + 1))" + fi +else + results="$(jq --null-input --compact-output \ + --arg id "${query_id}" \ + --arg title "${output_title}" \ + --arg text "${output_text}" \ + --arg description "${output_text}" \ + '[{"type": "article", "id": $id, "title": $title, "input_message_content": {"message_text": $text}, "description": $description}]')" +fi + +curl --data-urlencode "inline_query_id=${query_id}" \ + --data-urlencode "results=${results}" \ + --data-urlencode "cache_time=0" \ + --data-urlencode "next_offset=${next_offset}" \ + --get \ + --silent \ + "${address}/bot${token}/answerInlineQuery" > /dev/null diff --git a/commands/inline b/commands/inline new file mode 100644 index 0000000..814782f --- /dev/null +++ b/commands/inline @@ -0,0 +1,345 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +set -- $(jq -r '.inline_query.query' "${update}") + +if [ -n "${1}" ] +then + case "${1}" in + ("help") + inline_help=0 + ;; + ("original") + inline_original=0 + ;; + ("post") + inline_post=0 + ;; + ("short") + inline_short=0 + ;; + ("shorts") + inline_shorts=0 + ;; + (*) + exit 0 + ;; + esac + + shift +else + user_id="$(jq -r '.inline_query.from.id' "${update}")" + short_config="${config}/${user_id}/short" + + until mkdir "${config}/${user_id}_short.lock" > /dev/null 2>&1 + do + sleep 1 + done + + if [ -d "${short_config}" ] + then + shorts="$(ls -x "${short_config}")" + fi + + if [ -n "${shorts}" ] + then + inline_shorts=0 + else + inline_help=0 + fi + + rm -fr "${config}/${user_id}_short.lock" +fi + +query_id="$(jq -r '.inline_query.id' "${update}")" + +if [ -n "${inline_help}" ] +then + . "${functions}/help" + + results="$(jq --null-input --compact-output \ + --arg id "${query_id}" \ + --arg title "Sekoohaka Bot" \ + --arg text "${output_text}" \ + --arg description "Click to send help message" \ + '[{"type": "article", "id": $id, "title": $title, "input_message_content": {"message_text": $text, "parse_mode": "HTML"}, "description": $description}]')" +fi + +if [ -n "${inline_original}" ] || [ -n "${inline_post}" ] +then + if [ -n "${1}" ] + then + user_id="$(jq -r '.inline_query.from.id' "${update}")" + + ib_board="${1}" + ib_mode="p" + . "${functions}/ib_config" + . "${functions}/ib_authconfig" + + shift + else + output_text="You must specify the image board" + fi + + if [ -n "${1}" ] + then + ib_post_id="${1}" + shift + elif [ -z "${output_text}" ] + then + output_text="You must specify the post ID" + fi + + if [ -n "${output_text}" ] + then + output_title="An error occurred" + fi + + if [ -z "${output_text}" ] && [ -n "${ib_config}" ] + then + ib_lock=0 + . "${functions}/ib_token" + + if [ -n "${output_text}" ] + then + output_title="${output_text}" + output_text="Try again in a few seconds" + fi + fi + + if [ -z "${output_text}" ] + then + if [ -n "${ib_exception_idol}" ] + then + ib_query="id_range:${ib_post_id}" + else + ib_query="id:${ib_post_id}" + fi + + ib_file="${cache}/${update_id}_data.json" + + if ! curl --data-urlencode "${ib_dfield1}" \ + --data-urlencode "${ib_dfield2}" \ + --data-urlencode "${ib_dfield3}" \ + --data-urlencode "${ib_dfield4}" \ + --data-urlencode "${ib_dfield5}" \ + --data-urlencode "${ib_dfield6}" \ + --data-urlencode "${ib_dlimit}=1" \ + --data-urlencode "${ib_dquery}=${ib_query}" \ + --get \ + --header "${ib_header}" \ + --max-time 5 \ + --output "${ib_file}" \ + --proxy "${proxy}" \ + --silent \ + --user-agent "Sekoohaka" \ + "${ib_data_url}" + then + output_text="Failed to access ${ib_name} API" + fi + + if [ -z "${output_text}" ] && ! [ -f "${ib_file}" ] + then + output_text="Failed to access ${ib_name} API" + fi + + if [ -z "${output_text}" ] && ! jq -e '.' "${ib_file}" > /dev/null 2>&1 + then + output_text="An unknown error occurred" + fi + + if [ -n "${output_text}" ] + then + output_title="An error occurred" + fi + + if [ -z "${output_text}" ] && ! jq -e ".${ib_iarray}[0]|has(\"${ib_iid}\")" "${ib_file}" > /dev/null 2>&1 + then + output_title="No results found" + output_text="Try different post ID" + fi + fi + + if [ -z "${output_text}" ] + then + if [ -n "${inline_original}" ] + then + . "${functions}/ib_original" + + if [ -n "${output_text}" ] + then + results="$(jq --null-input --compact-output \ + --arg id "${query_id}" \ + --arg title "An error occurred" \ + --arg text "${output_text}" \ + --arg description "${output_text}" \ + '[{"type": "article", "id": $id, "title": $title, "input_message_content": {"message_text": $text}, "description": $description}]')" + else + results="$(jq --null-input --compact-output \ + --arg id "${query_id}" \ + --arg title "Original file of post ${ib_post_id}" \ + --arg document_url "${ib_file_url}" \ + --arg description "Click to send the original file" \ + --arg thumbnail_url "${ib_preview_url}" \ + '[{"type": "document", "id": $id, "title": $title, "document_url": $document_url, "mime_type": "application/zip", "description": $description, "thumbnail_url", $thumbnail_url}]')" + fi + + if [ -n "${ib_file_url}" ] && [ "${ib_file_url}" != "null" ] + then + results="$(printf "%s" "${results}" | jq --compact-output \ + --arg text1 "Original file link" \ + --arg url1 "${ib_file_url}" \ + '.[0] += {"reply_markup": {"inline_keyboard": [[{"text": $text1, "url": $url1}]]}}')" + fi + elif [ -n "${inline_post}" ] + then + . "${functions}/ib_post" + + results="$(jq --null-input --compact-output \ + --arg id "${query_id}" \ + --arg title "Information of post ${ib_post_id}" \ + --arg text "${output_text}" \ + --arg url "${ib_sample_url}" \ + --arg text1 "Post link" \ + --arg url1 "${ib_page_url}$(printf "%s" "${ib_post_id}" | urlencode)" \ + --arg description "Click to send the post information" \ + --arg thumbnail_url "${ib_preview_url}" \ + '[{"type": "article", "id": $id, "title": $title, "input_message_content": {"message_text": $text, "parse_mode": "HTML", "link_preview_options": {"url": $url, "prefer_small_media": true, "show_above_text": true}}, "reply_markup": {"inline_keyboard": [[{"text": $text1, "url": $url1}]]}, "description": $description, "thumbnail_url": $thumbnail_url}]')" + + if [ ${ib_tags_count} -gt 0 ] + then + results="$(printf "%s" "${results}" | jq --compact-output \ + --arg text1 "Tags (${ib_tags_count})" \ + --arg data1 "tags ${ib_board} ${ib_post_id}" \ + '.[0].reply_markup.inline_keyboard[0] += [{"text": $text1, "callback_data": $data1}]')" + fi + fi + else + results="$(jq --null-input --compact-output \ + --arg id "${query_id}" \ + --arg title "${output_title}" \ + --arg text "${output_text}" \ + --arg description "${output_text}" \ + '[{"type": "article", "id": $id, "title": $title, "input_message_content": {"message_text": $text}, "description": $description}]')" + + if [ -n "${inline_post}" ] + then + results="$(printf "%s" "${results}" | jq --compact-output \ + --arg text1 "Retry" \ + --arg data1 "post ${ib_board} ${ib_post_id}" \ + '.[0] += {"reply_markup": {"inline_keyboard": [[{"text": $text1, "callback_data": $data1}]]}}')" + fi + fi +fi + +if [ -n "${inline_short}" ] +then + if [ -n "${1}" ] + then + short_query="${@}" + shift ${#} + else + output_title="An error occurred" + output_text="You must specify the query" + fi + + if [ ${#short_query} -gt 1024 ] + then + output_title="An error occurred" + output_text="Query is too long" + fi + + if [ -z "${output_text}" ] + then + results="$(jq --null-input --compact-output \ + --arg id "${query_id}" \ + --arg title "Shortcut" \ + --arg text "<b>Shortcut:</b> <code>$(printf "%s" "${short_query}" | htmlescape)</code>" \ + --arg text1 "Open inline" \ + --arg query1 "${short_query}" \ + --arg description "${short_query}" \ + '[{"type": "article", "id": $id, "title": $title, "input_message_content": {"message_text": $text, "parse_mode": "HTML"}, "reply_markup": {"inline_keyboard": [[{"text": $text1, "switch_inline_query_current_chat": $query1}]]}, "description": $description}]')" + + short_query="short ${short_query}" + + if [ ${#short_query} -le 64 ] + then + results="$(printf "%s" "${results}" | jq --compact-output \ + --arg text1 "Manage" \ + --arg data1 "${short_query}" \ + '.[0].reply_markup.inline_keyboard[0] += [{"text": $text1, "callback_data": $data1}]')" + fi + else + results="$(jq --null-input --compact-output \ + --arg id "${query_id}" \ + --arg title "${output_title}" \ + --arg text "${output_text}" \ + --arg description "${output_text}" \ + '[{"type": "article", "id": $id, "title": $title, "input_message_content": {"message_text": $text}, "description": $description}]')" + fi +fi + +if [ -n "${inline_shorts}" ] +then + user_id="$(jq -r '.inline_query.from.id' "${update}")" + short_config="${config}/${user_id}/short" + + until mkdir "${config}/${user_id}_short.lock" > /dev/null 2>&1 + do + sleep 1 + done + + if [ -d "${short_config}" ] + then + shorts="$(ls -xt "${short_config}")" + fi + + if [ -z "${shorts}" ] + then + output_title="An error occurred" + output_text="No shortcuts found" + fi + + if [ -z "${output_text}" ] + then + results=[] + array_count=0 + + for short in ${shorts} + do + short_query="$(cat "${short_config}/${short}")" + + result="$(jq --null-input --compact-output \ + --arg id "${array_count}" \ + --arg title "Shortcut" \ + --arg text "<b>Shortcut:</b> <code>$(printf "%s" "${short_query}" | htmlescape)</code>" \ + --arg text1 "Open inline" \ + --arg query1 "${short_query}" \ + --arg text2 "Manage" \ + --arg data2 "short ${short_query}" \ + --arg description "${short_query}" \ + '{"type": "article", "id": $id, "title": $title, "input_message_content": {"message_text": $text, "parse_mode": "HTML"}, "reply_markup": {"inline_keyboard": [[{"text": $text1, "switch_inline_query_current_chat": $query1}, {"text": $text2, "callback_data": $data2}]]}, "description": $description}')" + + results="$(printf "%s" "${results}" | jq -c ".[${array_count}] += ${result}")" + array_count=$((array_count + 1)) + done + else + results="$(jq --null-input --compact-output \ + --arg id "${query_id}" \ + --arg title "${output_title}" \ + --arg text "${output_text}" \ + --arg description "${output_text}" \ + '[{"type": "article", "id": $id, "title": $title, "input_message_content": {"message_text": $text}, "description": $description}]')" + fi + + rm -fr "${config}/${user_id}_short.lock" +fi + +curl --data-urlencode "inline_query_id=${query_id}" \ + --data-urlencode "results=${results}" \ + --data-urlencode "cache_time=0" \ + --get \ + --silent \ + "${address}/bot${token}/answerInlineQuery" > /dev/null diff --git a/functions/help b/functions/help new file mode 100644 index 0000000..5de69f7 --- /dev/null +++ b/functions/help @@ -0,0 +1,83 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +help_text="$(echo "<b>Sekoohaka Bot</b>" \ + "\n\n<b>Fields descriptions:</b>" \ + "\n[command] - Inline command" \ + "\n[b] - Image board" \ + "\n[page] - Search page number" \ + "\n[options] - Search options" \ + "\n[tags] - Search tags" \ + "\n[name] - Search pool or tag name" \ + "\n[id] - Post ID" \ + "\n[query] - Inline query" \ + "\n[login] - Image board login" \ + "\n[key] - Image board API key or password" \ + "\n\n<b>Inline commands:</b>" \ + "\nhelp - Send this message" \ + "\nl [b] [page] [options] [name] - Pool search" \ + "\np [b] [page] [options] [tags] - Post search" \ + "\nt [b] [page] [options] [name] - Tag search" \ + "\noriginal [b] [id] - Get original file of post" \ + "\npost [b] [id] - Get infromation of post" \ + "\nshort [query] - Create inline shortcut" \ + "\nshorts - List saved inline shortcuts" \ + "\n\n<b>Search options:</b>" \ + "\na - Enable autopaging (lpt)" \ + "\nm - Show more metadata (p)" \ + "\np - Show gif/video as preview only (p)" \ + "\nq - Add quick buttons (lpt)" \ + "\n\n<b>Commands:</b>" \ + "\n/help - Send this message" \ + "\n/authorize [b] [login] [key] - Authorize to image board" \ + "\n/original [b] [id] - Get original file of post" \ + "\n/post [b] [id] - Get infromation of post" \ + "\n/short [query] - Create inline shortcut" \ + "\n/shorts - Manage saved shortcuts" \ + "\n/stop - Remove all your data" \ + "\n\n<b>Inline examples:</b>" \ + "\np d -mq sakurada_shiro" \ + "\nt d *genshin*" \ + "\noriginal d 5080413" \ + "\nshort p d 1 -amq rating:g blue_archive" \ + "\n\n<b>Supported image boards:</b>")" + +for ib_board in ${ascii_table} +do + unset ib_name ib_config ib_features + . "${functions}/ib_config" + . "${functions}/ib_authconfig" + + if [ -n "${ib_name}" ] + then + help_text="$(printf "%s\n%c - %s" "${help_text}" "${ib_board}" "${ib_name}")" + + for ib_mode in ${ascii_table} + do + . "${functions}/ib_config" + + if [ -z "${output_text}" ] + then + ib_features="${ib_features}${ib_mode}" + fi + + unset output_text + done + + if [ -n "${ib_config}" ] + then + help_text="$(printf "%s (authorize)" "${help_text}")" + fi + + if [ -n "${ib_features}" ] + then + help_text="$(printf "%s (%s)" "${help_text}" "${ib_features}")" + fi + fi + + unset output_text +done + +output_text="${help_text}" diff --git a/functions/ib_auth b/functions/ib_auth new file mode 100644 index 0000000..6dfbe14 --- /dev/null +++ b/functions/ib_auth @@ -0,0 +1,171 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +if ! mkdir -p "${ib_config}" +then + output_text="Failed to create user config" + return 0 +fi + +if [ -n "${ib_login}" ] +then + printf "%s" "${ib_login}" > "${ib_config}/${ib_login_file}" +fi + +if [ -n "${ib_api_key}" ] +then + printf "%s" "${ib_api_key}" > "${ib_config}/${ib_api_key_file}" +fi + +if [ -f "${ib_config}/${ib_login_file}" ] +then + ib_login="$(cat "${ib_config}/${ib_login_file}")" +else + output_text="You must specify the ${ib_login_word}" + return 0 +fi + +if [ -f "${ib_config}/${ib_api_key_file}" ] +then + ib_api_key="$(cat "${ib_config}/${ib_api_key_file}")" +else + output_text="You must specify the ${ib_api_key_word}" + return 0 +fi + +case "${ib_board}" in + (d) + ib_file="${cache}/${update_id}_profile.json" + + if ! curl --max-time 5 \ + --output "${ib_file}" \ + --proxy "${proxy}" \ + --request GET \ + --silent \ + --user "${ib_login}:${ib_api_key}" \ + --user-agent "Sekoohaka" \ + "https://danbooru.donmai.us/profile.json" + then + output_text="Temporary error" + return 0 + fi + + if ! [ -f "${ib_file}" ] + then + output_text="Failed to process request" + return 0 + fi + + if ! jq -e '.' "${ib_file}" > /dev/null 2>&1 + then + output_text="An unknown error occurred" + return 0 + fi + + if [ "$(jq -r '.success' "${ib_file}")" = "false" ] + then + output_text="Error: <code>$(jq -r '.message' "${ib_file}" | htmlescape)</code>" + return 0 + fi + + if [ "$(jq -r '.name' "${ib_file}")" != "${ib_login}" ] + then + output_text="An unexpected error occurred" + return 0 + fi + + printf "%s" "${ib_login}:${ib_api_key}" | base64 > "${ib_config}/token" + ;; + (g) + printf '%s="%s"\n%s="%s"' \ + "ib_dfield5" "user_id=${ib_login}" \ + "ib_dfield6" "api_key=${ib_api_key}" > "${ib_config}/legacy" + ;; + (i) + ib_login_lower="$(printf "%s" "${ib_login}" | tr '[:upper:]' '[:lower:]')" + ib_password_hash="$(printf "choujin-steiner--%s--" "${ib_api_key}" | sha1sum | awk '{print $1}')" + ib_appkey="$(printf "sankakuapp_%s_Z5NE9YASej" "${ib_login_lower}" | sha1sum | awk '{print $1}')" + + printf '%s="%s"\n%s="%s"\n%s="%s"' \ + "ib_dfield4" "login=${ib_login}" \ + "ib_dfield5" "password_hash=${ib_password_hash}" \ + "ib_dfield6" "appkey=${ib_appkey}" > "${ib_config}/legacy" + ;; + (s) + ib_login_data="$(jq --null-input --compact-output \ + --arg login "${ib_login}" \ + --arg password "${ib_api_key}" \ + '{"login": $login, "password": $password}')" + + ib_file="${cache}/${update_id}_token.json" + + if ! curl --data "${ib_login_data}" \ + --header "Content-Type: application/json" \ + --max-time 5 \ + --output "${ib_file}" \ + --proxy "${proxy}" \ + --request POST \ + --silent \ + --user-agent "Sekoohaka" \ + "https://capi-v2.sankakucomplex.com/auth/token" + then + output_text="Temporary error" + return 0 + fi + + if ! [ -f "${ib_file}" ] + then + output_text="Failed to process request" + return 0 + fi + + if ! jq -e '.' "${ib_file}" > /dev/null 2>&1 + then + output_text="An unknown error occurred" + return 0 + fi + + if [ "$(jq -r '.success' "${ib_file}")" != "true" ] + then + output_text="Error: <code>$(jq -r '.error' "${ib_file}" | htmlescape)</code>" + return 0 + fi + + jq -r '.access_token' "${ib_file}" > "${ib_config}/token" + date +%s > "${ib_config}/time" + ;; + (k | y) + ib_file="${cache}/${update_id}_user.json" + + if ! curl --data-urlencode "username=${ib_login}" \ + --data-urlencode "api_key=${ib_api_key}" \ + --max-time 5 \ + --output "${ib_file}" \ + --proxy "${proxy}" \ + --silent \ + --user-agent "Sekoohaka" \ + "${ib_api}/user.json" + then + output_text="Temporary error" + return 0 + fi + + if ! [ -f "${ib_file}" ] + then + output_text="Failed to process request" + return 0 + fi + + if ! jq -e '.' "${ib_file}" > /dev/null 2>&1 + then + output_text="Invalid username or API key" + return 0 + fi + + printf '%s="%s"\n%s="%s"' \ + "ib_dfield5" "username=${ib_login}" \ + "ib_dfield6" "api_key=${ib_api_key}" > "${ib_config}/legacy" + ;; +esac diff --git a/functions/ib_authconfig b/functions/ib_authconfig new file mode 100644 index 0000000..200583d --- /dev/null +++ b/functions/ib_authconfig @@ -0,0 +1,57 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +case "${ib_board}" in + (d) + ib_config="${config}/${user_id}/danbooru" + ib_authorization="Authorization: Baisc" + ib_login_file="login" + ib_api_key_file="api_key" + ib_login_word="login" + ib_api_key_word="API key" + ;; + (g) + ib_config="${config}/${user_id}/gelbooru" + ib_noverify=0 + ib_login_file="user_id" + ib_api_key_file="api_key" + ib_login_word="user ID" + ib_api_key_word="API key" + ;; + (i) + ib_config="${config}/${user_id}/idol" + ib_noverify=0 + ib_login_file="login" + ib_api_key_file="password" + ib_login_word="login" + ib_api_key_word="password" + ;; + (s) + ib_config="${config}/${user_id}/sankaku" + ib_authorization="Authorization: Bearer" + ib_time=36000 + ib_login_file="login" + ib_api_key_file="password" + ib_login_word="login" + ib_api_key_word="password" + ;; + (k | y) + case "${ib_board}" in + (k) + ib_api="https://konachan.com" + ib_config="${config}/${user_id}/konachan" + ;; + (y) + ib_api="https://yande.re" + ib_config="${config}/${user_id}/yandere" + ;; + esac + + ib_login_file="username" + ib_api_key_file="api_key" + ib_login_word="username" + ib_api_key_word="API key" + ;; +esac diff --git a/functions/ib_config b/functions/ib_config new file mode 100644 index 0000000..7c640a2 --- /dev/null +++ b/functions/ib_config @@ -0,0 +1,339 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +ib_error_url="https://cdn.donmai.us/original/fb/b6/fbb6c45cac3194754dd1feb997cb8ad6.jpg" +ib_error_width=536 +ib_error_height=516 + +case "${ib_board}" in + (d) + ib_name="Danbooru" + ib_api="https://danbooru.donmai.us" + + ib_ratings=" + g general + s sensitive + q questionable + e explicit" + + case "${ib_mode}" in + (l) + ib_data_url="${ib_api}/pools.json" + ib_dlimit="limit" + ib_dpage="page" + ib_dquery="search[name_matches]" + ib_iid="id" + ib_icreated="created_at" + ib_ipool="name" + ib_icount="post_count" + ib_idate="%Y-%m-%dT%X" + ib_ispace="_" + ib_iorder="order:created_at_asc" + ib_page_url="${ib_api}/pools/" + ;; + (p) + ib_data_url="${ib_api}/posts.json" + ib_dlimit="limit" + ib_dpage="page" + ib_dquery="tags" + ib_iid="id" + ib_icreated="created_at" + ib_ifile="file_url" + ib_isize="file_size" + ib_isample="large_file_url" + ib_ipreview="preview_file_url" + ib_iwidth="image_width" + ib_iheight="image_height" + ib_irating="rating" + ib_iparent="parent_id" + ib_ichildren="has_children" + ib_imd5="md5" + ib_isource="source" + ib_itags="tag_string" + ib_idate="%Y-%m-%dT%X" + ib_ifilename="cut -d '/' -f 7" + ib_page_url="${ib_api}/posts/" + ;; + (t) + ib_data_url="${ib_api}/tags.json" + ib_dlimit="limit" + ib_dpage="page" + ib_dquery="search[name_matches]" + ib_iid="id" + ib_itag="name" + ib_icount="post_count" + ib_irecode="HTML" + ib_page_url="${ib_api}/wiki_pages/" + ;; + (*) + output_text="Unsupported image board" + ;; + esac + ;; + (g) + ib_name="Gelbooru" + ib_api="https://gelbooru.com" + + ib_ratings=" + safe safe + general general + sensitive sensitive + questionable questionable + explicit explicit" + + case "${ib_mode}" in + (p) + ib_data_url="${ib_api}/index.php" + ib_dfield1="page=dapi" + ib_dfield2="s=post" + ib_dfield3="q=index" + ib_dfield4="json=1" + ib_dlimit="limit" + ib_dpage="pid" + ib_dquery="tags" + ib_ioffset="-1" + ib_iarray="post" + ib_iid="id" + ib_icreated="created_at" + ib_ifile="file_url" + ib_isize="deprecated" + ib_isample="sample_url" + ib_ipreview="preview_url" + ib_iwidth="width" + ib_iheight="height" + ib_irating="rating" + ib_iparent="parent_id" + ib_ichildren="has_children" + ib_imd5="md5" + ib_isource="source" + ib_itags="tags" + ib_itzfield=5 + ib_idate="%a %b %d %X %Y" + ib_ifilename="cut -d '/' -f 7" + ib_page_url="${ib_api}/index.php?page=post&s=view&id=" + ;; + (t) + ib_data_url="${ib_api}/index.php" + ib_dfield1="page=dapi" + ib_dfield2="s=tag" + ib_dfield3="q=index" + ib_dfield4="json=1" + ib_dlimit="limit" + ib_dpage="pid" + ib_dquery="name_pattern" + ib_iwildcard="%" + ib_ioffset="-1" + ib_iarray="tag" + ib_iid="id" + ib_itag="name" + ib_icount="count" + ib_irecode="HTML" + ib_page_url="${ib_api}/index.php?page=wiki&s=list&search=" + ;; + (*) + output_text="Unsupported image board" + ;; + esac + ;; + (i) + ib_name="Idol Complex" + ib_api="https://iapi.sankakucomplex.com" + + ib_ratings=" + s safe + q questionable + e explicit" + + case "${ib_mode}" in + (l) + ib_exception_idol=0 + + ib_data_url="${ib_api}/pools.json" + ib_dlimit="limit" + ib_dpage="page" + ib_dquery="name" + ib_iid="id" + ib_icreated="created_at" + ib_ipool="name" + ib_icount="post_count" + ib_idate="%Y-%m-%d %H:%M" + ib_ispace="_" + ib_page_url="https://idol.sankakucomplex.com/pools/" + ;; + (p) + ib_exception_idol=0 + + ib_data_url="${ib_api}/posts.json" + ib_dlimit="limit" + ib_dpage="page" + ib_dquery="tags" + ib_iid="id" + ib_icreated="created_at" + ib_ifile="file_url" + ib_isize="file_size" + ib_isample="sample_url" + ib_ipreview="preview_url" + ib_iwidth="width" + ib_iheight="height" + ib_irating="rating" + ib_iparent="parent_id" + ib_ichildren="has_children" + ib_imd5="md5" + ib_isource="deprecated" + ib_itags="tags[].name" + ib_idate="%Y-%m-%dT%X" + ib_ifilename="cut -d '?' -f 1 | cut -d '/' -f 7" + ib_page_url="https://idol.sankakucomplex.com/posts/" + ;; + (t) + ib_exception_idol=0 + + ib_data_url="${ib_api}/tags.json" + ib_dlimit="limit" + ib_dpage="page" + ib_dquery="name" + ib_iid="id" + ib_itag="name" + ib_icount="count" + ib_irecode="UTF-8" + ib_page_url="https://idol.sankakucomplex.com/wiki/" + ;; + (*) + output_text="Unsupported image board" + ;; + esac + ;; + (s) + ib_name="Sankaku Channel" + ib_api="https://capi-v2.sankakucomplex.com" + + ib_ratings=" + s safe + q questionable + e explicit" + + case "${ib_mode}" in + (l) + ib_data_url="${ib_api}/pools" + ib_dlimit="limit" + ib_dpage="page" + ib_dquery="name" + ib_iid="id" + ib_icreated="created_at" + ib_ipool="name" + ib_icount="post_count" + ib_idate="%Y-%m-%d %H:%M" + ib_page_url="https://chan.sankakucomplex.com/pools/" + ;; + (p) + ib_data_url="${ib_api}/posts" + ib_dlimit="limit" + ib_dpage="page" + ib_dquery="tags" + ib_iid="id" + ib_icreated="created_at.s" + ib_ifile="file_url" + ib_isize="file_size" + ib_isample="sample_url" + ib_ipreview="preview_url" + ib_iwidth="width" + ib_iheight="height" + ib_irating="rating" + ib_iparent="parent_id" + ib_ichildren="has_children" + ib_imd5="md5" + ib_isource="deprecated" + ib_itags="tags[].name" + ib_ifilename="cut -d '?' -f 1 | cut -d '/' -f 7" + ib_page_url="https://chan.sankakucomplex.com/posts/" + ;; + (t) + ib_data_url="${ib_api}/tags" + ib_dlimit="limit" + ib_dpage="page" + ib_dquery="name" + ib_iid="id" + ib_itag="name" + ib_icount="post_count" + ib_page_url="https://chan.sankakucomplex.com/wiki/" + ;; + (*) + output_text="Unsupported image board" + ;; + esac + ;; + (k | y) + case "${ib_board}" in + (k) + ib_name="Konachan.com" + ib_api="https://konachan.com" + ;; + (y) + ib_name="yande.re" + ib_api="https://yande.re" + ;; + esac + + ib_ratings=" + s safe + q questionable + e explicit" + + case "${ib_mode}" in + (l) + ib_data_url="${ib_api}/pool.json" + ib_dlimit="limit" + ib_dpage="page" + ib_dquery="query" + ib_iid="id" + ib_icreated="created_at" + ib_ipool="name" + ib_icount="post_count" + ib_idate="%Y-%m-%dT%X" + ib_ispace="_" + ib_page_url="${ib_api}/pool/show/" + ;; + (p) + ib_data_url="${ib_api}/post.json" + ib_dlimit="limit" + ib_dpage="page" + ib_dquery="tags" + ib_iid="id" + ib_icreated="created_at" + ib_ifile="file_url" + ib_isize="file_size" + ib_isample="sample_url" + ib_ipreview="preview_url" + ib_iwidth="width" + ib_iheight="height" + ib_irating="rating" + ib_iparent="parent_id" + ib_ichildren="has_children" + ib_imd5="md5" + ib_isource="source" + ib_itags="tags" + ib_ifilename="sed 's/\/${ib_name}.*\./\./' | cut -d '/' -f 5" + ib_page_url="${ib_api}/post/show/" + ;; + (t) + ib_data_url="${ib_api}/tag.json" + ib_dlimit="limit" + ib_dpage="page" + ib_dquery="name" + ib_iid="id" + ib_itag="name" + ib_icount="count" + ib_irecode="UTF-8" + ib_page_url="${ib_api}/wiki/show?title=" + ;; + (*) + output_text="Unsupported image board" + ;; + esac + ;; + (*) + output_text="Unsupported image board" + ;; +esac diff --git a/functions/ib_date b/functions/ib_date new file mode 100644 index 0000000..a476480 --- /dev/null +++ b/functions/ib_date @@ -0,0 +1,33 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +if [ -n "${ib_created_at}" ] && [ "${ib_created_at}" != "null" ] +then + if [ -n "${ib_itzfield}" ] + then + shift ${#} + + field_count=0 + + for field in ${ib_created_at} + do + field_count=$((field_count + 1)) + + if ! [ ${field_count} -eq ${ib_itzfield} ] + then + set -- ${@} ${field} + fi + done + + ib_created_at="${@}" + fi + + if [ -n "${ib_idate}" ] + then + ib_date_text="$(date -ud "${ib_created_at}" -D "${ib_idate}" +"%Y-%m-%d %H:%M")" + else + ib_date_text="$(date -ud "@${ib_created_at}" +"%Y-%m-%d %H:%M")" + fi +fi diff --git a/functions/ib_lock b/functions/ib_lock new file mode 100644 index 0000000..2c9dc1a --- /dev/null +++ b/functions/ib_lock @@ -0,0 +1,13 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +until mkdir "${config}/${user_id}_auth.lock" > /dev/null 2>&1 +do + sleep 1 +done + +. "${functions}/ib_auth" + +rm -fr "${config}/${user_id}_auth.lock" diff --git a/functions/ib_meta b/functions/ib_meta new file mode 100644 index 0000000..6c991ee --- /dev/null +++ b/functions/ib_meta @@ -0,0 +1,110 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +if [ -n "${ib_file_url}" ] && [ "${ib_file_url}" != "null" ] +then + ib_sample_url="$(jq -r ".${ib_iarray}[${array_count}].${ib_isample}" "${ib_file}")" + ib_preview_url="$(jq -r ".${ib_iarray}[${array_count}].${ib_ipreview}" "${ib_file}")" + ib_width="$(jq -r ".${ib_iarray}[${array_count}].${ib_iwidth}" "${ib_file}")" + ib_height="$(jq -r ".${ib_iarray}[${array_count}].${ib_iheight}" "${ib_file}")" + ib_type="$(printf "%s" "${ib_file_url}" | eval ${ib_ifilename} | cut -d '.' -f 2)" + + if [ -n "${ib_exception_idol}" ] + then + ib_file_url="https:${ib_file_url}" + fi + + if [ -z "${ib_sample_url}" ] || [ "${ib_sample_url}" = "null" ] + then + ib_sample_url=${ib_file_url} + elif [ -n "${ib_exception_idol}" ] + then + ib_sample_url="https:${ib_sample_url}" + fi + + if [ -z "${ib_preview_url}" ] || [ "${ib_preview_url}" = "null" ] + then + ib_preview_url=${ib_error_url} + elif [ -n "${ib_exception_idol}" ] + then + ib_preview_url="https:${ib_preview_url}" + fi + + if [ -n "${ib_width}" ] && [ "${ib_width}" != "null" ] && [ ${ib_width} -gt 0 ] + then + ib_resolution_text="${ib_width}x${ib_height}" + fi + + if [ -n "${ib_type}" ] + then + ib_type_text="$(printf "%s" "${ib_type}" | tr '[:lower:]' '[:upper:]')" + fi + + case "${ib_type}" in + (jpeg | jpg | png | webp) + ib_type="photo" + ;; + (gif) + ib_type="gif" + ;; + (mp4) + ib_type="video" + ;; + (zip | webm) + ib_sample_url="${ib_preview_url}" + ib_type="photo" + ;; + (*) + ib_sample_url="${ib_error_url}" + ib_preview_url="${ib_error_url}" + ib_width="${ib_error_width}" + ib_height="${ib_error_height}" + ib_type="photo" + ;; + esac +else + ib_file_url="${ib_error_url}" + ib_file_size=0 + + ib_sample_url="${ib_error_url}" + ib_preview_url="${ib_error_url}" + ib_width="${ib_error_width}" + ib_height="${ib_error_height}" + ib_type="photo" +fi + +if [ -n "${ib_file_size}" ] && [ "${ib_file_size}" != "null" ] && [ ${ib_file_size} -gt 0 ] +then + if [ ${ib_file_size} -gt ${max_size} ] + then + if [ "${ib_sample_url}" = "${ib_file_url}" ] + then + ib_sample_url="${ib_preview_url}" + fi + + ib_type="photo" + fi + + unit_offset=0 + size_offset=1 + + for unit in B KiB MiB GiB TiB PiB + do + unit_offset=${size_offset} + size_offset=$((size_offset * 1024)) + + if [ ${ib_file_size} -lt ${size_offset} ] + then + break + fi + done + + if [ ${ib_file_size} -ge 1024 ] + then + ib_size_text="$(printf "%.2f %s" "$(printf "%s" "${ib_file_size} / ${unit_offset}" | bc -l)" "${unit}")" + else + ib_size_text="$(printf "%u %s" "${ib_file_size}" "${unit}")" + fi +fi diff --git a/functions/ib_original b/functions/ib_original new file mode 100644 index 0000000..b54f3ed --- /dev/null +++ b/functions/ib_original @@ -0,0 +1,42 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +ib_file_url="$(jq -r ".${ib_iarray}[0].${ib_ifile}" "${ib_file}")" +ib_file_size="$(jq -r ".${ib_iarray}[0].${ib_isize}" "${ib_file}")" + +. "${functions}/ib_size" + +if [ -n "${ib_file_url}" ] && [ "${ib_file_url}" != "null" ] +then + ib_preview_url="$(jq -r ".${ib_iarray}[0].${ib_ipreview}" "${ib_file}")" + + if [ -n "${ib_exception_idol}" ] + then + ib_file_url="https:${ib_file_url}" + fi + + if [ -z "${ib_preview_url}" ] || [ "${ib_preview_url}" = "null" ] + then + ib_preview_url=${ib_error_url} + elif [ -n "${ib_exception_idol}" ] + then + ib_preview_url="https:${ib_preview_url}" + fi +else + output_text="No original file found" + return 0 +fi + +if [ -n "${ib_file_size}" ] && [ "${ib_file_size}" != "null" ] && [ ${ib_file_size} -gt 0 ] +then + if [ ${ib_file_size} -gt ${max_size} ] + then + output_text="File size is too large" + return 0 + fi +else + output_text="Failed to get file size" + return 0 +fi diff --git a/functions/ib_post b/functions/ib_post new file mode 100644 index 0000000..02a426d --- /dev/null +++ b/functions/ib_post @@ -0,0 +1,92 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +ib_id="$(jq -r ".${ib_iarray}[0].${ib_iid}" "${ib_file}")" +ib_created_at="$(jq -r ".${ib_iarray}[${array_count}].${ib_icreated}" "${ib_file}")" +ib_file_url="$(jq -r ".${ib_iarray}[0].${ib_ifile}" "${ib_file}")" +ib_file_size="$(jq -r ".${ib_iarray}[0].${ib_isize}" "${ib_file}")" +ib_rating="$(jq -r ".${ib_iarray}[0].${ib_irating}" "${ib_file}")" +ib_parent_id="$(jq -r ".${ib_iarray}[0].${ib_iparent}" "${ib_file}")" +ib_has_children="$(jq -r ".${ib_iarray}[0].${ib_ichildren}" "${ib_file}")" +ib_md5="$(jq -r ".${ib_iarray}[0].${ib_imd5}" "${ib_file}")" +ib_source="$(jq -r ".${ib_iarray}[0].${ib_isource}" "${ib_file}" | htmlescape)" +ib_tags="$(jq -r ".${ib_iarray}[0].${ib_itags}" "${ib_file}")" +ib_tags_count=0 + +. "${functions}/ib_size" +. "${functions}/ib_date" +. "${functions}/ib_meta" + +output_text="$(printf "<b>%s</b>\n<b>ID:</b> <code>%s</code>" "${ib_name}" "${ib_id}")" + +if [ -n "${ib_date_text}" ] +then + output_text="$(printf "%s\n<b>Date:</b> <code>%s</code>" "${output_text}" "${ib_date_text}")" +fi + +if [ -n "${ib_resolution_text}" ] +then + output_text="$(printf "%s\n<b>Resolution:</b> %s" "${output_text}" "${ib_resolution_text}")" +fi + +if [ -n "${ib_size_text}" ] +then + output_text="$(printf "%s\n<b>Size:</b> %s" "${output_text}" "${ib_size_text}")" +fi + +if [ -n "${ib_type_text}" ] +then + output_text="$(printf "%s\n<b>Type:</b> %s" "${output_text}" "${ib_type_text}")" +fi + +if [ -n "${ib_rating}" ] && [ "${ib_rating}" != "null" ] +then + set -- ${ib_ratings} + + while [ -n "${2}" ] + do + if [ "${ib_rating}" = "${1}" ] + then + output_text="$(printf "%s\n<b>Rating:</b> <code>%s</code>" "${output_text}" "${2}")" + break + else + shift 2 + fi + done +fi + +if [ -n "${ib_parent_id}" ] && [ "${ib_parent_id}" != "null" ] && [ ${ib_parent_id} -gt 0 ] +then + output_text="$(printf "%s\n<b>Parent ID:</b> <code>%s</code>" "${output_text}" "${ib_parent_id}")" +fi + +if [ "${ib_has_children}" = "true" ] +then + output_text="$(printf "%s\n<b>Has children:</b> yes" "${output_text}")" +fi + +if [ -n "${ib_md5}" ] && [ "${ib_md5}" != "null" ] +then + output_text="$(printf "%s\n<b>MD5:</b> <code>%s</code>" "${output_text}" "${ib_md5}")" +fi + +if [ -n "${ib_source}" ] && [ "${ib_source}" != "null" ] +then + if echo "${ib_source}" | grep -q "pximg" + then + ib_source="https://www.pixiv.net/artworks/$(printf "%s" "${ib_source##*/}" | cut -d '_' -f 1)" + fi + + if [ ${#ib_source} -le 2048 ] + then + output_text="$(printf "%s\n<b>Source:</b> %s" "${output_text}" "${ib_source}")" + fi +fi + +if [ -n "${ib_tags}" ] && [ "${ib_tags}" != "null" ] +then + set -- ${ib_tags} + ib_tags_count=${#} +fi diff --git a/functions/ib_size b/functions/ib_size new file mode 100644 index 0000000..34603af --- /dev/null +++ b/functions/ib_size @@ -0,0 +1,21 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +if [ -n "${ib_file_size}" ] && [ "${ib_file_size}" != "null" ] +then + return 0 +fi + +if [ -z "${ib_file_url}" ] || [ "${ib_file_url}" = "null" ] +then + return 0 +fi + +ib_file_size="$(curl --head \ + --max-time 2 \ + --proxy "${ib_proxy}" \ + --silent \ + --user-agent "Sekoohaka" \ + "${ib_file_url}" | grep -i "content-length" | awk '{print $2}')" diff --git a/functions/ib_token b/functions/ib_token new file mode 100644 index 0000000..a95bb14 --- /dev/null +++ b/functions/ib_token @@ -0,0 +1,38 @@ +#!/usr/bin/env dash +# +# Copyright (C) 2024 Maria Lisina +# Copyright (C) 2024 Danil Lisin + +until mkdir "${config}/${user_id}_auth.lock" > /dev/null 2>&1 +do + sleep 1 +done + +if [ -f "${ib_config}/legacy" ] +then + . "${ib_config}/legacy" +fi + +if [ -f "${ib_config}/time" ] +then + current_date=$(date +%s) + previous_date=$(cat "${ib_config}/time") + + if [ $((current_date - previous_date)) -ge ${ib_time} ] + then + if [ -n "${ib_lock}" ] + then + . "${functions}/ib_lock" & + output_text="Refreshing access token..." + else + . "${functions}/ib_auth" + fi + fi +fi + +if [ -f "${ib_config}/token" ] +then + ib_header="${ib_authorization} $(cat "${ib_config}/token")" +fi + +rm -fr "${config}/${user_id}_auth.lock" |
