#! /bin/bash # # Download and install The Bezel Project for Batocera # # @evoflash and @lbrpdx on Batocera Forums and Discord # # Usage: # batocera-es-thebezelproject 'list', 'install or remove ' # # DECODIR="/storage/roms/" ROMSDIR="/storage/roms/" DEFAULTBEZELDIR="default/systems/" BEZELPROJECTDIR="bezels/" BEZELPROJECTGAMESDIR="${BEZELPROJECTDIR}" BEZELPROJECTSYSTEMDIR="${BEZELPROJECTDIR}" BEZELSLIST="https://pastebin.com/raw/C4wdxTMv" LOCALBEZELSLIST="/storage/.config/distribution/configs/bezels.txt" # bezels.txt must be a plain file with the format 'bezel_name https://githubURL' (spaces or tabs) # Example of a bezels.txt file: # fba https://github.com/thebezelproject/bezelproject-MAME # snes https://github.com/thebezelproject/bezelproject-SNES DEBUG=0 EE_TMP="/tmp/overlays" ############################### # function usage() { echo "$(basename $0) - downloads and installs The Bezel Project for Batocera" echo " " echo "It accepts three modes: 'list', 'install' and 'remove' '" echo "- 'list' for the list of systems installed on the system, and available within TheBezelProject, and if they are" echo " [A]vailable to install, [I]nstalled or [?]unknown." echo "- 'install ' to install the bezels for this ." echo "- 'remove ' to remove the bezels for this ." echo "- 'remove all' to remove all the bezels." echo " " echo "If you have a local $LOCALBEZELSLIST file," echo "it will override the one hosted on Batocera website." return 1 } ############################### # check if url format is valid function check_url() { [[ "$1" =~ ^(https?|ftp)://.*$ ]] && echo "[A]" || echo "[?]" } ############################### # return the git name function git_name() { echo "$1" | sed "s,.*/\(.*\),\1," } ############################### # return the number of files in a directory function files_count() { echo `find "$1" -maxdepth 1 -type f -name "[!.]*" | wc -l` } ############################### # function list() { local count=0 local fn=$(date +"%s") local tmp="$EE_TMP/bezels_$fn" local filescount local systemname local url [ $DEBUG -eq 1 ] && echo "DEBUG: path to bezels ${DECODIR}${BEZELPROJECTGAMESDIR}" echo "* 351ELEC bezels *" # create temporary files in /tmp if [ -f $LOCALBEZELSLIST ]; then cp -f "$LOCALBEZELSLIST" "${tmp}" else curl -H 'Cache-Control: no-cache' -sfL "$BEZELSLIST" -o "${tmp}" || return 1 sed -i 's/\r$//' "${tmp}" fi # reading bezels list from configuration file while IFS=$' \t' read systemname url ; do [ -z "${systemname}" ] && continue let count+=1 [ $DEBUG -eq 1 ] && echo "DEBUG: bezels for system ${systemname} (from bezels list)" # check if roms/ directory exist if [ ! -d "${ROMSDIR}${systemname}" ]; then continue; fi # there is at least one file in each roms/ directory (i.e. _info.txt) filescount=$(files_count "${ROMSDIR}${systemname}") if [ "${filescount}" -le 1 ]; then continue; fi # check if url is valid and return [A] else [?] ia=$(check_url "${url}") # if games/ directory exist we assume the bezels are already installed if [ -d "${DECODIR}${BEZELPROJECTGAMESDIR}${systemname}" ]; then ia="[I]"; fi echo "$ia ${systemname} - ${url}" done < "${tmp}" [ $DEBUG -eq 1 ] && echo "DEBUG: there are $count systems (from bezels list)" rm "${tmp}" } ############################### # function install() { local count=0 local installed_count=0 local fn=$(date +"%s") local tmp="$EE_TMP/bezels_$fn" local gitname local gitsystem local filescount local filename local romname local systemname local url local systemtoinstall="$1" local systemfound=0 [ $DEBUG -eq 1 ] && echo "DEBUG: path to bezels ${DECODIR}${BEZELPROJECTGAMESDIR}" # create temporary files in /tmp if [ -f $LOCALBEZELSLIST ]; then cp -f "$LOCALBEZELSLIST" "${tmp}" else curl -H 'Cache-Control: no-cache' -sfL "$BEZELSLIST" -o "${tmp}" || return 1 sed -i 's/\r$//' "${tmp}" fi # reading bezels list from configuration file while IFS=$' \t' read systemname url ; do [ -z "${systemname}" ] && continue [ $DEBUG -eq 1 ] && echo "DEBUG: bezels for system ${systemname} (from bezels list)" [ "${systemname}" != "${systemtoinstall}" ] && continue # check if url is valid and return [A] else [?] ia=$(check_url "${url}") if [ "$ia" != "[A]" ]; then echo "Error - invalid bezels URL ${url}" return 1 else systemfound=1 break fi done < "${tmp}" rm "${tmp}" # in case of TheBezelProject does not own the system we want to install if [ "$systemfound" -eq 0 ]; then echo -n "Error - system ${systemtoinstall} could not be found in " [ -f $LOCALBEZELSLIST ] && echo "$LOCALBEZELSLIST" || echo "$BEZELSLIST" return 1 fi # check if roms/ directory exists if [ ! -d "${ROMSDIR}${systemtoinstall}" ]; then echo "Error - ROMs directory for system ${systemtoinstall} could not be found" return 1 fi # there is at least one file in each roms/ directory (i.e. _info.txt) filescount=$(files_count "${ROMSDIR}${systemtoinstall}") [ $DEBUG -eq 1 ] && echo "DEBUG: roms files count ${filescount}" if [ "${filescount}" -le 1 ]; then echo "Error - ROMs directory for system ${systemtoinstall} is empty" return 1 fi # create temporary directory in /tmp fn=$(date +"%s") tmp="$EE_TMP/dl_$fn" [ $DEBUG -eq 1 ] && echo "DEBUG: path to roms ${ROMSDIR}${systemtoinstall}" [ $DEBUG -eq 1 ] && echo "DEBUG: path for downloading ${tmp}" # extract gitname from the url gitname=$(git_name "${url}") # keep only the final word for searching sub-folders of /retroarch/overlay/GameBezels/ gitsystem=${gitname#bezelproject-} mkdir -p "${tmp}" cd "${tmp}" echo "Downloading bezels for system ${systemtoinstall}" [ $DEBUG -eq 1 ] && echo "DEBUG: URL: ${url} OUT: ${gitname}.zip GITNAME: $gitname GITSYSTEM: $gitsystem" curl -H 'Cache-Control: no-cache' -sfL "${url}/archive/master.zip" -o "${gitname}.zip" # error while downloading ? if [[ "$?" -ne 0 || ! -f "${gitname}.zip" ]]; then echo "Error - ${gitname} zip file could not be downloaded from ${url}" # leave current directory and remove all downloads cd rm -r "${tmp}" return 1 fi # if it doesn't already exist, create the games bezels directory if [ ! -d "${DECODIR}${BEZELPROJECTGAMESDIR}${systemtoinstall}" ]; then [ $DEBUG -eq 1 ] && echo "DEBUG: creating ${DECODIR}${BEZELPROJECTGAMESDIR}${systemtoinstall}" mkdir -p "${DECODIR}${BEZELPROJECTGAMESDIR}${systemtoinstall}" else [ $DEBUG -eq 1 ] && echo "DEBUG: directory ${DECODIR}${BEZELPROJECTGAMESDIR}${systemtoinstall} already exist" fi # if it doesn't already exist, create the systems bezels directory if [ ! -d "${DECODIR}${BEZELPROJECTSYSTEMDIR}" ]; then [ $DEBUG -eq 1 ] && echo "DEBUG: creating ${DECODIR}${BEZELPROJECTSYSTEMDIR}" mkdir -p "${DECODIR}${BEZELPROJECTSYSTEMDIR}" else [ $DEBUG -eq 1 ] && echo "DEBUG: directory ${DECODIR}${BEZELPROJECTSYSTEMDIR} already exist" fi # unzip archive for working on and remove the zip file echo "Installing/Updating bezels for system ${systemtoinstall}..." unzip -q "${gitname}.zip" mv "${gitname}-master" "${gitname}" rm "${gitname}.zip" # install games bezels if provided by TheBezelProject echo "installing games bezels" echo 0 > "/tmp/bcount" echo 0 > "/tmp/bicount" find "${ROMSDIR}${systemtoinstall}" -maxdepth 1 -type f -iname "[!.]*" | sort -V | while read filename; do filename=$(basename "$filename") romname=${filename%%.*} [ -z "${romname}" ] && continue count=$((count + 1)) echo $count > "/tmp/bcount" [ $DEBUG -eq 1 ] && echo "DEBUG: count -> $count" [ $DEBUG -eq 1 ] && echo "DEBUG: rom -> ${romname}" if [ "${systemtoinstall}" == "mame" ] || [ "${systemtoinstall}" == "arcade" ] || [ "${systemtoinstall}" == "fba" ] || [ "${systemtoinstall}" == "neogeo" ]; then # is there a matching PNG for arcade rom name ? EE_REALSYSTEM="ArcadeBezels" else EE_REALSYSTEM="GameBezels/${gitsystem}" fi if [ -f "${tmp}/${gitname}/retroarch/overlay/$EE_REALSYSTEM/${romname}.png" ]; then [ $DEBUG -eq 1 ] && echo "DEBUG: found PNG for ${romname}" # copy the matching PNG cp "${tmp}/${gitname}/retroarch/overlay/$EE_REALSYSTEM/${romname}.png" "${DECODIR}${BEZELPROJECTGAMESDIR}${systemtoinstall}" cp "${tmp}/${gitname}/retroarch/overlay/$EE_REALSYSTEM/${romname}.cfg" "${DECODIR}${BEZELPROJECTGAMESDIR}${systemtoinstall}" sed -i '/overlay0_overlay/d' "${DECODIR}${BEZELPROJECTGAMESDIR}${systemtoinstall}/${romname}.cfg" echo "overlay0_overlay = \"${romname}.png\"" >> "${DECODIR}${BEZELPROJECTGAMESDIR}${systemtoinstall}/${romname}.cfg" installed_count=$((installed_count + 1)) echo $installed_count > "/tmp/bicount" [ $DEBUG -eq 1 ] && echo "DEBUG: installed_count -> $installed_count" fi done echo "Bezels found" $(cat /tmp/bcount) "Bezels installed" $(cat /tmp/bicount) rm /tmp/bcount rm /tmp/bicount # install system bezel if provided by TheBezelProject echo "installing system bezel" # * Arcade * if [ "${systemtoinstall}" == "mame" ] || [ "${systemtoinstall}" == "arcade" ] || [ "${systemtoinstall}" == "fba" ] || [ "${systemtoinstall}" == "neogeo" ]; then # copy the HORIZONTAL system bezel to the correct directory and rename it cp "${tmp}/${gitname}/retroarch/overlay/MAME-Horizontal.png" "${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemtoinstall}.png" else # * Other * filescount=$(find "${tmp}/${gitname}/retroarch/overlay" -maxdepth 1 -type f -name "*.png" | wc -l) if [ "${filescount}" -eq 1 ]; then rm -f "${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemname}.png" rm -f "${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemname}.info" # copy the system bezel to the correct directory and rename it filename=$(ls -1 "${tmp}/${gitname}"/retroarch/overlay/*.png) [ $DEBUG -eq 1 ] && echo "DEBUG: $filename ${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemtoinstall}/default.png" cp "$filename" "${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemtoinstall}/default.png" filename=${filename%.*} [ $DEBUG -eq 1 ] && echo "DEBUG: ${filename}.cfg ${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemtoinstall}/default.cfg" cp "${filename}.cfg" "${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemtoinstall}/default.cfg" sed -i '/overlay0_overlay/d' "${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemtoinstall}/default.cfg" echo "overlay0_overlay = \"default.png\"" >> "${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemtoinstall}/default.cfg" else # make a symbolic link to the Batocera's bezel default system pack ln -fs "${DECODIR}${DEFAULTBEZELDIR}${systemtoinstall}.png" "${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemtoinstall}.png" ln -fs "${DECODIR}${DEFAULTBEZELDIR}${systemtoinstall}.info" "${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemtoinstall}.info" fi fi # # install default bezel (i.e. system not supported in TheBezelProject) # echo "installing default bezels" # if [ -d "${DECODIR}${BEZELPROJECTDIR}" ]; then # echo "TODO : install the @fery65's default.png bezel" # fi # leave current directory and remove all downloads echo "Bezels for system ${systemtoinstall} are now installed" cd rm -r "${tmp}" } ############################### # function remove() { systemname="$1" # do we want to remove all TheBezelProject ? if [ "${systemname}" == "all" ]; then if [ -d "${DECODIR}${BEZELPROJECTDIR}" ]; then read -p "Do you wish to remove all bezels ? " yn if [[ "$yn" = "y" || "$yn" = "Y" ]]; then rm -rf "${DECODIR}${BEZELPROJECTDIR}" fi else echo "Error - bezels directory ${DECODIR}${BEZELPROJECTDIR} is not valid" return 1 fi else # check if games/ directory exist if [ ! -d "${DECODIR}${BEZELPROJECTGAMESDIR}${systemname}" ]; then echo "Error - bezels for system ${systemname} could not be found" return 1 else rm -rf "${DECODIR}${BEZELPROJECTGAMESDIR}${systemname}" rm -f "${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemname}.png" rm -f "${DECODIR}${BEZELPROJECTSYSTEMDIR}${systemname}.info" fi fi } ############################### #### Main loop # command="$1" system="$2" count=1 installed_count=1 if [ ! -d "${DECODIR}" ]; then echo "Error - decorations directory ${DECODIR} is not valid" exit 1 fi if [[ "$command" == "list" ]]; then list elif [[ "$command" == "install" && -n "$system" ]]; then install "$system" elif [[ "$command" == "remove" && -n "$system" ]]; then remove "$system" else usage fi