Initial commit
This commit is contained in:
commit
45fa779bc6
3 changed files with 168 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Ignore remote emoji data cache
|
||||||
|
.cache
|
62
README.rst
Normal file
62
README.rst
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
===========
|
||||||
|
Yoink-Emoji
|
||||||
|
===========
|
||||||
|
|
||||||
|
Lets you yoink emoji packs from any other instance with MastoAPI suppport,
|
||||||
|
instead of only shareable packs from other \*oma instances like admin-fe does.
|
||||||
|
|
||||||
|
Note this currently might not work as well for updating packs not created by this script.
|
||||||
|
It expects files t be named after their shortocde, if an meoji already exists but with
|
||||||
|
a different filename this will leave duplicate images behind.
|
||||||
|
*(shortocde names are checked to be safe wrt to path traversal before writing anything)*
|
||||||
|
|
||||||
|
Installing
|
||||||
|
==========
|
||||||
|
|
||||||
|
Just plop the script somewhere.
|
||||||
|
|
||||||
|
A ``.cache`` for remote emoji data will be created at the script location.
|
||||||
|
*(Caches remain valid within the same UTC day, currently not cleaned up automatically so just `rm -fr .cache` from time to time if it becomes too big)*
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
Enter the emoji pack dir (or create an new empty dir for this), then incoke the script;
|
||||||
|
the third argument is optional:
|
||||||
|
|
||||||
|
```
|
||||||
|
yoink-or-update-emoj.sh domain_of_server_to_be_yoinked_from category_to yoink [additional_conditions]
|
||||||
|
```
|
||||||
|
|
||||||
|
Additionally the follwoing env vars affect the result:
|
||||||
|
|
||||||
|
- ``OVERWRITE_IMG=YES``: overwrite existing images instead of skipping download
|
||||||
|
- ``OVERWRITE_METAKEYS=YES``: overwrite existing shortcode file path entries instead of preserving the original
|
||||||
|
|
||||||
|
Example
|
||||||
|
-------
|
||||||
|
|
||||||
|
Yoinking the blobcat pack from an Akkoma instance and also merge any blobcat emotes from another category into the local pack:
|
||||||
|
```sh
|
||||||
|
yoink-or-update-emoji.sh example.org "pack:blobcat" 'or (.shortcode | test("blobcatpnd|^ameow|^blobcat|^ablobcat"))'
|
||||||
|
```
|
||||||
|
|
||||||
|
Yoink woozy pack from a Sharkey instance *(no ``pack:`` prefix)*:
|
||||||
|
```sh
|
||||||
|
yoink-or-update-emoji.sh example.org "woozy"
|
||||||
|
```
|
||||||
|
|
||||||
|
Merge multiple remote packs into one local pack:
|
||||||
|
```sh
|
||||||
|
yoink-or-update-emoji.sh example.org "pack:touhou" 'or .category == "pack:reimu" or .category == "pack:marisa"'
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
============
|
||||||
|
|
||||||
|
- POSIX ``sh`` and ``awk`` _(in general all POSIX tools)_
|
||||||
|
- ``date`` with ``-I`` extension
|
||||||
|
- jq
|
||||||
|
- wget **and** curl _(idk why i used both, might remove one at some point)_
|
||||||
|
- ``mktemp``
|
104
yoink-or-update-emojipack.sh
Executable file
104
yoink-or-update-emojipack.sh
Executable file
|
@ -0,0 +1,104 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
if [ "$#" -lt 2 ] ; then
|
||||||
|
echo "Usage: $0 <base domain> <emoji pack name> [<conditional addition>]" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
DOMAIN="$1"
|
||||||
|
CATEGORY="$2"
|
||||||
|
ADDCOND="${3:-}"
|
||||||
|
|
||||||
|
OVERWRITE_IMG="${OVERWRITE_IMG:-NO}"
|
||||||
|
OVERWRITE_METAKEYS="${OVERWRITE_METAKEYS:-NO}"
|
||||||
|
|
||||||
|
json_str_escape() {
|
||||||
|
echo "$1" | sed -e 's/"/\\"/g'
|
||||||
|
}
|
||||||
|
|
||||||
|
CACHE_DIR="$(dirname "$0")"/.cache
|
||||||
|
cached_list="$CACHE_DIR"/"$(date -I)_${DOMAIN}"
|
||||||
|
|
||||||
|
if [ ! -e "$cached_list" ] ; then
|
||||||
|
mkdir -p "$CACHE_DIR"
|
||||||
|
curl https://"$DOMAIN"/api/v1/custom_emojis | jq > "$cached_list"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Track additions in "pack.json".files format
|
||||||
|
META_ADD="$(mktemp)"
|
||||||
|
meta_prefix="{"
|
||||||
|
|
||||||
|
# @tsv doesn't actually directly produce TSV, but for each line a string which escapes tabs as \t...
|
||||||
|
cat "$cached_list" \
|
||||||
|
| jq '.[] | select(.category == "'"$CATEGORY"'"'"${ADDCOND:+ }${ADDCOND}"') | [.shortcode, .static_url] | @tsv' \
|
||||||
|
| awk '1 {gsub(/^"|"$/, ""); sub(/\\t/, "\t"); print}' \
|
||||||
|
| while IFS="$(printf '\t')" read -r name url; do
|
||||||
|
urlfile="$(basename "$url")"
|
||||||
|
ext="${urlfile##*.}";
|
||||||
|
if [ "$ext" = "$urlfile" ] ; then
|
||||||
|
ext=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$name" != "$(basename "$name")" ] ; then
|
||||||
|
echo "ERROR: unsafe, potentially malicious shortcode '$name'; aborting!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
out="${name}${ext:+.}${ext}"
|
||||||
|
if [ "$OVERWRITE_IMG" = "YES" ] || [ ! -e "$out" ] ; then
|
||||||
|
echo "Downloading $out ..."
|
||||||
|
wget --quiet --output-document="$out" "$url"
|
||||||
|
printf '%s\n\t"%s": "%s"' "$meta_prefix" \
|
||||||
|
"$(json_str_escape "$name")" "$(json_str_escape "$out")" \
|
||||||
|
>> "$META_ADD"
|
||||||
|
meta_prefix=","
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$meta_prefix" = "{" ] ; then
|
||||||
|
echo "No emoji matched search criteria"
|
||||||
|
rm "$META_ADD"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
printf '\n}\n' >> "$META_ADD"
|
||||||
|
|
||||||
|
cnt_dl="$(jq '. | length' "$META_ADD")"
|
||||||
|
echo "Finished downloading $cnt_dl images."
|
||||||
|
|
||||||
|
if [ ! -e pack.json ] ; then
|
||||||
|
printf '{"files": {}, "files_count": 0, "pack": {"description": "%s: %s%s%s"}}' \
|
||||||
|
"$(json_str_escape "$DOMAIN")" \
|
||||||
|
"$(json_str_escape "$CATEGORY")" \
|
||||||
|
"${ADDCOND:+ }" \
|
||||||
|
"$(json_str_escape "$ADDCOND")" \
|
||||||
|
> pack.json
|
||||||
|
fi
|
||||||
|
|
||||||
|
cnt_old="$(jq '.files | length' pack.json)"
|
||||||
|
echo "Found $cnt_old preëxisting emoji."
|
||||||
|
|
||||||
|
new_files="$(
|
||||||
|
if [ "$OVERWRITE_METAKEYS" = "YES" ] ; then
|
||||||
|
jq --sort-keys -s '.[0].files + .[1]' pack.json "$META_ADD"
|
||||||
|
else
|
||||||
|
jq --sort-keys -s '.[0] + .[1].files' "$META_ADD" pack.json
|
||||||
|
fi
|
||||||
|
)"
|
||||||
|
echo "$new_files" > "$META_ADD"
|
||||||
|
|
||||||
|
cnt_new="$(jq '. | length' "$META_ADD")"
|
||||||
|
cnt_diff=$((cnt_new - cnt_old))
|
||||||
|
echo "After merging there are a total of $cnt_new emoji."
|
||||||
|
if [ "$cnt_diff" != "$cnt_dl" ] ; then
|
||||||
|
echo "WARNING: expected a gain of $cnt_dl but got $cnt_diff additional entries!"
|
||||||
|
echo " (the existing pack may not follow the expected filename scheme)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
jq --argjson new_files "$new_files" \
|
||||||
|
--arg cnt_new "$cnt_new" \
|
||||||
|
'.files = $new_files | .files_count = $cnt_new' \
|
||||||
|
pack.json \
|
||||||
|
> "$META_ADD"
|
||||||
|
|
||||||
|
mv "$META_ADD" pack.json
|
Loading…
Reference in a new issue