#!/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/system/configs/system.cfg"
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 ""
echo ""
echo " $fn"
echo " RetroAchievements website is too slow to respond"
echo ""
exit 1;
fi
cat "$tmpfile" | awk -v FS="(
|
)" '{print $2}' | uniq > "$tmpfile"_2
idcard=$(cat "$tmpfile" | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(
Member Since: |
Account Type:)" '{print $2}' | uniq)
parsedid=$(echo "$idcard" | sed -e "/^[[:blank:]]*$/d" | sed -e "s;\(.*\)
Last Activity: \(.*\);\1@\2;")
avcompletion=$(cat "$tmpfile" | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(
Average Completion: |
Site Rank:)" '{print $2}' | sed -e "/^[[:blank:]]*$/d" | uniq)
points=$(cat "$tmpfile"_2 | sed -e "/^[[:blank:]]*$/d" | awk -v FS="( |)" '{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|
)" '{print $3}' | sed -e "s/\?[a-zA-Z0-9=&;']*>//" -e "s;;;" -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\n"
fi
echo ""
echo ""
echo " $fn"
echo " $USER"
echo " $points"
echo " $rank"
echo " $avcompletion"
echo -ne "$pic"
echo "$parsedid" | sed -e "s;\(.*\)@\(.*\); \1\n \2;"
xmllint --html "$tmpfile" 2>/dev/null | grep '.*points.
' | sed -e "/^[[:blank:]]*$/d" | sed -e 's:\(.*\)points\.
:\1points\@\\\n:g;' > "$tmpfile"_2
cat "$tmpfile"_2 | awk -v FS="(href=\"/[gG]ame/[0-9]*\">|@)" '{print $2}' | sed -e "s;
\(Last played[ 0-9:-]*\)
\(.*\);@\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 \(.*\); \n \1\n \2\n \3\n \4;"
cat "$tmpfile"_ba | head -n "$i" | tail -n 1 | sed "s:^: :;s:$::"
echo " "
done < "$tmpfile"_st
else
echo "$res" | sed -e "s;\(.*\)@\(.*\) achievements@\(.*\) points@Last played \(.*\); \n \1\n \2\n \3\n \4\n ;"
fi
echo ""
else
echo ""
echo ""
echo " $fn"
echo " Player $USER hasn't unlocked any RetroAchievement yet"
echo ""
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