#!/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 "" 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