meow.sh/meow.sh

111 lines
2.6 KiB
Bash

#!/usr/bin/env bash
SEP=$'\t'
curl=(curl -sS -m 32 --connect-timeout 8 --retry 3 --retry-delay 1)
# all timestamps are given in seconds since the epoch
declare -A searchquery
declare -A searchregex
declare -A searchtime # last seen release
die() {
echo -E "$@" >&2
exit 1
}
retrieve() {
${curl[@]} -G --data-urlencode "term=[$1]" -d page=rss \
"http://www.nyaa.se/"
}
nullcheck() { # {query}
[[ -n "$1" ]] || die "Null search query";
}
sanitize() {
sed -e 's/[^0-9a-zA-Z_]/_/g'
}
splittags() { # {tag}
awk -v tag="$1" -f "$SRCDIR/splittags.awk"
}
scrape() {
TZ=UTC0 awk -v sep="$SEP" -f "$SRCDIR/scrape.awk"
}
watch() { # {search query} [regex...]
nullcheck "$1"
local gs="$(sanitize<<<"$1")" regex=
searchquery[$gs]="$1"
shift
for regex; do
searchregex[$gs]+="|($regex)"
done
}
touchquery() { # {search query} {timestamp}
nullcheck "$1"
local gs="$(sanitize<<<"$1")"
searchtime[$gs]="$2"
}
search() {
nullcheck "$1"
retrieve "$1" | tr -d '\r\n'"$SEP" | splittags item | scrape
[ ${PIPESTATUS[0]} = 0 ] || die "Failed to search for $1"
}
searchfilter() { # key regex [timestamp]
while IFS=$SEP read -r title etc; do
grep -P "$2" <<< "$title" >/dev/null && echo -E "$title$SEP$etc"
done < db.txt
[ ${PIPESTATUS[0]} = 0 ] || exit 1
}
cleanup() {
local gs= v=
for gs in "${!searchtime[@]}"; do
v="${searchtime[$gs]}"
echo -E "touchquery $gs $v" >> times.sh
[ -e "$gs.xml" ] && rm "$gs.xml"
done
exit ${1:-1}
}
runfilter() {
local query= regex= timestamp= res= _= recent=
query="${searchquery[$1]}"
regex="${searchregex[$1]:1}" # exclude first | character
timestamp="${searchtime[$1]}"
res="$(searchfilter "$query" "$regex" "$timestamp")"
[ $? = 0 ] || return $?
IFS=$SEP read -r _ _ recent <<< "$res"
[ -n "$recent" ] && {
searchtime[$1]="$recent"
echo -E "$res"
}
return 0
}
runsearch() { # [database]
local db="${1:-db.txt}"
local tmp=`mktemp`
touch "$db"
for q in "${!searchquery[@]}"; do
search "${searchquery[$q]}" \
| while IFS=$SEP read -r title torrent time; do
echo -E "$time$SEP$q$SEP$title$SEP$torrent"
done
done | sort -n -- "$db" - | uniq > $tmp
# TODO: don't accidentally overwrite $db with something blank/incomplete
# maybe check if filesize has decreased and die if so
mv $tmp "$db"
}
runall() {
trap cleanup INT
local ret=0 gs=
for gs in "${!searchregex[@]}"; do runfilter "$gs" || ret=1; done
cleanup $ret
}