distribution/packages/jelos/sources/scripts/batocera-retroachievements-info
2022-02-05 09:23:32 -05:00

104 lines
5.2 KiB
Bash
Executable file

#!/bin/bash
#
# Get RetroAchievements information for Batocera
#
# @lbrpdx on Batocera Forums and Discord
#
# 20191124 - v2 with now outputs in XML format (for Batocera 5.25+)
# 20200113 - updated for retroachievements.org HTML changes
# 20200124 - added badges for each game played
# 20200304 - fixed a bug in rare cases where a RA game has no success icons
# 20200410 - updated for retroachievements.org HTML changes, again
# 20200625 - retroachievements.org HTML changes, again
# 20201104 - retroachievements.org HTML changes, again, again
#
# Usage:
# batocera-retroachievements-info
#
CONFIGFILE="/storage/.config/distribution/configs/distribution.conf"
TIMEOUT=4 # seconds before timeout (>2 sec)
USER=""
###############################
#
function usage() {
echo "$0 username"
echo " - where username is the RetroAchievements username you want to check out"
exit 1
}
###############################
#
function process() {
fn=$(date +"%s")
tmpfile=/tmp/ra_$fn
curl -H 'Cache-Control: no-cache' -m "$TIMEOUT" -o $tmpfile https://retroachievements.org/user/$USER 2>/dev/null
if [ x"$?" != x0 ]; then
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
echo "<retroachievements>"
echo " <lastrefresh>$fn</lastrefresh>"
echo " <error>RetroAchievements website is too slow to respond</error>"
echo "</retroachievements>"
exit 1;
fi
cat "$tmpfile" | awk -v FS="(<div class='username'><span class='username'>|</div><div class='userpage recentlyplayed' >)" '{print $2}' | uniq > "$tmpfile"_2
idcard=$(cat "$tmpfile" | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(</span></div><br/?>Member Since: |<br/?>Account Type:)" '{print $2}' | uniq)
parsedid=$(echo "$idcard" | sed -e "/^[[:blank:]]*$/d" | sed -e "s;\(.*\)<br>Last Activity: \(.*\);\1@\2;")
avcompletion=$(cat "$tmpfile" | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(</span><br/?>Average Completion: <b>|</b><br/?>Site Rank:)" '{print $2}' | sed -e "/^[[:blank:]]*$/d" | uniq)
points=$(cat "$tmpfile"_2 | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(</strong></a>&nbsp;|<span class='TrueRatio'>)" '{print $2}' | sed -e "s;(\([0-9]*\) points);\1;")
if [ x"$points" != x ] && [ "$points" -ge 1 ]; then
rank=$(cat "$tmpfile"_2 | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(globalRanking.php|<br/?><br/?>)" '{print $3}' | sed -e "s/\?[a-zA-Z0-9=&;']*>//" -e "s;</a>;;" -e "s;%).*;%);")
## For future use: UserPic is RetroAchievements' user avatar - however the S3 bucket is protected.
# UserPic=$(cat $tmpfile | grep 'meta property=.og:image. content=' | cut -d= -f3 | awk -F\' '{print $2}')
# Workaround: use the line below
UserPic="https://retroachievements.org/UserPic/$USER".png
pic=""
curl -H 'Cache-Control: no-cache' -m "$TIMEOUT" -f -s "$UserPic" >/dev/null 2>/dev/null
if [ x"$?" == x0 ]; then
pic=" <userpic>$UserPic</userpic>\n"
fi
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
echo "<retroachievements>"
echo " <lastrefresh>$fn</lastrefresh>"
echo " <username>$USER</username>"
echo " <totalpoints>$points</totalpoints>"
echo " <rank>$rank</rank>"
echo " <averagecompletion>$avcompletion</averagecompletion>"
echo -ne "$pic"
echo "$parsedid" | sed -e "s;\(.*\)@\(.*\); <registered>\1</registered>\n <lastactivity>\2</lastactivity>;"
xmllint --html "$tmpfile" 2>/dev/null | grep '<a href="/[gG]ame/[0-9]*\">.*points.<br\?>' | sed -e "/^[[:blank:]]*$/d" | sed -e 's:\(<a href=\"/[gG]ame/[0-9]*\">.*\)points\.<br>:\1points\@\\\n:g;' > "$tmpfile"_2
cat "$tmpfile"_2 | awk -v FS="(href=\"/[gG]ame/[0-9]*\">|@)" '{print $2}' | sed -e "s;</a><br/*>\(Last played[ 0-9:-]*\)<br/*>\(.*\);@\2@\1;" | sed -e "s;achievements, ;achievements@;" | sed -e "s;Earned ;;" | sed -e "/^[[:blank:]]*$/d" > "$tmpfile"_st
cat "$tmpfile"_2 | grep -e 'div class="bb_inline" onmouseover' -e '^$' | sed "s:.*src=\"\(.*/Badge/.*\.png\)\".*:\1:" | sed "s;^$;https://batocera.org/favicon-64.png;" > "$tmpfile"_ba
i=0
if [ $(cat "$tmpfile"_ba | wc -l) -eq $(cat "$tmpfile"_st | wc -l) ]; then
while IFS= read -r line || [[ -n "$line" ]]; do
i=$((i+1))
echo "$line" | sed -e "s;\(.*\)@\(.*\) achievements@\(.*\) points@Last played \(.*\); <game>\n <name>\1</name>\n <achievements>\2</achievements>\n <points>\3</points>\n <lastplayed>\4</lastplayed>;"
cat "$tmpfile"_ba | head -n "$i" | tail -n 1 | sed "s:^: <badge>:;s:$:</badge>:"
echo " </game>"
done < "$tmpfile"_st
else
echo "$res" | sed -e "s;\(.*\)@\(.*\) achievements@\(.*\) points@Last played \(.*\); <game>\n <name>\1</name>\n <achievements>\2</achievements>\n <points>\3</points>\n <lastplayed>\4</lastplayed>\n </game>;"
fi
echo "</retroachievements>"
else
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
echo "<retroachievements>"
echo " <lastrefresh>$fn</lastrefresh>"
echo " <error>Player $USER hasn't unlocked any RetroAchievement yet</error>"
echo "</retroachievements>"
fi
rm "$tmpfile" "$tmpfile"_2 "$tmpfile"_st "$tmpfile"_ba 2>/dev/null
}
#### Main loop
#
if [ $# -lt 1 ]; then
[ -f "$CONFIGFILE" ] && USER=$(grep -E "^[ \t]*global.retroachievements.username=" "$CONFIGFILE" | cut -d= -f2 | uniq)
else
tmp="$1"
[ x"${tmp::1}" == "x-" ] && usage || USER="$1"
fi
[ x"$USER" == x ] && usage || process