#!/usr/bin/env bash italic="\033[3m" underline="\033[4m" ita_under="\033[3;4m" bgd="\033[1;4;31m" red="\033[1;31m" bold="\033[1m" bold_ita="\033[1;3m" box="\033[1;41m" redbold="\033[1;31m" redbox="\033[1;41m" green="\033[0;32m" reset="\033[0m" # Fine-grained personal access tokens: if [[ "$OSTYPE" == "darwin"* ]]; then # Put token in macOS Keychain # security add-generic-password -s service_name -a account -w github_pat_blablablablabla # Get token from macOS Keychain gh_access_tokens=$(security find-generic-password -w -s gh_access_tokens) elif [[ "$OSTYPE" == "linux-gnu" ]]; then gh_access_tokens= fi if [ ! -f ./applis.db ]; then cmd0="CREATE TABLE latest (App string, Latest string, Published date, Url string);" echo "$cmd0" | sqlite3 ./applis.db fi upd_avail=0 vercomp() { if [[ $1 == $2 ]] then return 0 fi local IFS=. local i ver1=($1) ver2=($2) # fill empty fields in ver1 with zeros for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)) do ver1[i]=0 done for ((i=0; i<${#ver1[@]}; i++)) do if [[ -z ${ver2[i]} ]] then # fill empty fields in ver2 with zeros ver2[i]=0 fi if ((10#${ver1[i]} > 10#${ver2[i]})) then return 1 fi if ((10#${ver1[i]} < 10#${ver2[i]})) then return 2 fi done return 0 } testvercomp() { vercomp $2 $3 case $? in 0) op='=';; 1) op='>';; 2) op='<';; esac if [[ $op != $4 ]] then #echo "Fail: Expected '$3', Actual '$op', Arg1 '$1', Arg2 '$2'" echo -e " - $1: $2 (last: $3)" upd_avail=0 else #echo "Pass: '$1 $op $2'" echo -e "${red} - $1: $2 (last: $3)${reset}" echo -e " - $1: $2 (last: **$3**)" >> update.md upd_avail=1 fi } insert() { #echo "app: $1" #query='SELECT App FROM latest WHERE App LIKE "$1";' query="SELECT App FROM latest WHERE App LIKE \"$1\"" #echo $query result=$(sqlite3 ./applis.db "$query") #echo "result: $result" if [ -n "$result" ]; then cmd1="UPDATE latest SET Latest = '$2', Url = '$4', Published = '$3' WHERE App = '$1';" else cmd1="INSERT INTO latest (App, Latest, Published, Url) VALUES ('$1','$2','$3','$4');" fi echo "$cmd1" | sqlite3 ./applis.db } ############################# # # # find latest versions # # # ############################# declare -A latest echo -e "${green}Let's find latest versions on SourceForge...${reset}\n" # https://sourceforge.net/projects/asuswrt-merlin/files/RT-AC88U/Release/ # https://www.asuswrt-merlin.net/download # curl -qsL "https://sourceforge.net/projects/asuswrt-merlin/best_release.json" | sed "s/, /,\n/g" | sed -rn "/release/,/\}/{ /filename/{ 0,//s/([^0-9]*)([0-9\.]+)([^0-9]*.*)/\2/ p }}" #curl -H "Accept: application/json" -X PUT -d "default=windows&default=mac&default=linux&default=bsd&default=solaris&default=others" -d "api_key=54fa10c5-1038-4238-8a8f-f24d34659ddb" https://sourceforge.net/projects/asuswrt-merlin/files/RT-AC88U # ok # curl -H "Accept: application/json" -X PUT -d "default=windows&default=mac&default=linux&default=bsd&default=solaris&default=others" -d "api_key=54fa10c5-1038-4238-8a8f-f24d34659ddb" "https://sourceforge.net/projects/asuswrt-merlin/files/RT-AC88U/stats/json?start_date=2023-07-01&end_date=2023-08-05" | jq asus=$(curl -s "https://sourceforge.net/projects/asuswrt-merlin/rss?path=/RT-AC88U/Release" | xmllint --nocdata --xpath "//title/text() | //pubDate/text() | //link/text()" - | awk NR\>3 | head -n3) while IFS= read -r line; do merlin+=("${line}") done <<< "$asus" release=$(echo "${merlin[0]}" | awk -F"/" '{print $NF}') # RT-AC88U_386.12_0.zip release=${release:0:-4} # RT-AC88U_386.12_0 router=$(echo "$release" | awk -F"_" '{print $1}') # ok last=${release//$router/} last=${last:1} url=$(echo "${merlin[1]}") url=${url///download/} url=$(echo "$url" | awk -F"/" 'BEGIN{OFS=FS} {NF--; print}') dat=$(date -d "${merlin[2]}" +%Y-%m-%d) app="Asus $router" insert "$app" "$last" "$dat" "$url" latest+=(["Asuswrt-Merlin $router"]="$last") echo -e "${bold}Asus $router${reset}" echo -e "Latest release: $last" echo -e "Url: $url" echo -e "Published date: $dat" echo -e "\n${green}Let's find latest versions on Github...${reset}\n" last_joplin_server=$(git ls-remote --tags --sort="-v:refname" https://github.com/laurent22/joplin.git | grep "server" | head -n1 | sed 's/.*\///') latest_joplin_server="${last_joplin_server/server-v/}" latest+=([Joplin server]="$latest_joplin_server") echo -e "${bold}Joplin server${reset}" echo -e "Latest tag: $latest_joplin_server" echo -e "Url: https://github.com/laurent22/joplin/releases/tag/$last_joplin_server" echo app="Joplin server" dat="" url="https://github.com/laurent22/joplin/releases/tag/$last_joplin_server" insert "$app" "$latest_joplin_server" "$dat" "$url" declare -A repositories repositories=(['Gitea']="go-gitea/gitea" ['Nextcloud']="nextcloud/server" ['nvm']="nvm-sh/nvm" ['Zenphoto']="zenphoto/zenphoto" ['Joplin']="laurent22/joplin" ['MkDocs']="mkdocs/mkdocs" ['Piwigo']="Piwigo/Piwigo" ['SoCo-CLI']="avantrec/soco-cli" ['thumbsup']="thumbsup/thumbsup" ['Vegas']="jaysalvat/vegas" ['WordPress']="WordPress/wordpress-develop" ) for app in "${!repositories[@]}"; do last=$(curl -s --header "Authorization: Bearer $gh_access_tokens" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${repositories[${app}]}/releases/latest" | jq -r '.name, .tag_name, .html_url, .published_at') echo -e "${bold}${app}${reset}" release=$(echo "$last" | head -n1) [ -z "$release" ] & release=$(echo "$last" | awk 'FNR == 2 {print}') # name="" tag_name=1.5.2 (MkDocs) if [ "$release" == "null" ]; then # tag: Vegas, SoCo-CLI, WordPress, thumbsup, Joplin server last=$(curl -s --header "Authorization: Bearer $gh_access_tokens" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${repositories[${app}]}/tags" | jq -r '.[].name' | grep -v -E 'rc|dev|beta' | head -n1) url="https://github.com/${repositories[${app}]}/releases/tag/$last" last="${last/v/}" echo -e "Latest tag: $last" echo -e "Url: $url\n" latest+=([$app]="$last") dat="" insert "$app" "$last" "$dat" "$url" else # release: MkDocs, Nextcloud, Piwigo, Joplin, Gitea, Zenphoto, nvm url=$(echo "$last" | grep "http") dat=$(echo "$last" | tail -n1 | awk -F "T" '{print $1}') release="${release/v/}" release="${release/Zenphoto\ /}" echo -e "Latest release: $release" echo -e "Published date: $dat" echo -e "Url: $url\n" latest+=([$app]="$release") insert "$app" "$release" "$dat" "$url" fi done for app in "${!latest[@]}"; do echo "${app} - ${latest[${app}]}" done ############################# # # # sur-le-sentier.fr # # # ############################# surlesentier(){ # thumbsup, wordpress, vegas surlesentier=( "thumbsup" "wordpress" "vegas" ) clear for app in ${!surlesentier[@]} do echo "${surlesentier[$app]}" done } ############################# # # # maboiteverte.fr # # # ############################# maboiteverte(){ # gitea, joplin server, nextcloud maboiteverte=( "gitea" "joplin server" "nextcloud" ) query="SELECT * FROM latest;" clear echo -e "${bold}maboiteverte.fr${reset}" echo -e "## maboiteverte.fr" >> update.md echo #current_gitea= #current_nextcloud= #current_joplinserver= if nmap "maboiteverte.fr" -PN -p 22 | grep open &>/dev/null; then mbv_gitea=$(ssh bruno@maboiteverte.fr 'gitea --version 2>/dev/null' | awk '{print $3}') #if [[ $mbv_gitea =~ ^[0-9]{1,2}\.[0-9]{0,2}\.[0-9]{0,2}$ ]]; then # current_gitea=$mbv_gitea #fi [[ $mbv_gitea =~ ^[0-9]{1,2}\.[0-9]{0,2}\.[0-9]{0,2}$ ]] && current_gitea=$mbv_gitea || current_gitea="" mbv_nextcloud=$(ssh bruno@maboiteverte.fr 'cd httpdocs/nextcloud/ 2>/dev/null; /opt/plesk/php/8.2/bin/php -d memory_limit=-1 occ --version' | awk '{print $2}' 2>/dev/null) #if [[ $mbv_nextcloud =~ ^[0-9]{1,2}\.[0-9]{0,2}\.[0-9]{0,2}$ ]]; then # current_nextcloud=$mbv_nextcloud #fi [[ $mbv_nextcloud =~ ^[0-9]{1,2}\.[0-9]{0,2}\.[0-9]{0,2}$ ]] && current_nextcloud=$mbv_nextcloud || current_nextcloud="" elif nmap "maboiteverte.fr" -PN -p 443 | grep open &>/dev/null; then mbv_joplinserver=$(curl --silent https://joplin.maboiteverte.fr/login 2>/dev/null | grep -E 'copyright' | xargs | awk '{print $3}' | sed 's/,//') #if [[ $mbv_joplinserver =~ ^[0-9]{1,2}\.[0-9]{0,2}\.[0-9]{0,2}$ ]]; then # current_joplinserver=$mbv_joplinserver #fi [[ $mbv_joplinserver =~ ^[0-9]{1,2}\.[0-9]{0,2}\.[0-9]{0,2}$ ]] && current_joplinserver=$mbv_joplinserver || current_joplinserver="" fi echo $current_gitea echo $current_nextcloud echo $current_joplinserver for appli in ${!maboiteverte[@]} do a="${maboiteverte[$appli]}" query="SELECT * FROM latest WHERE App LIKE \"$a\"" result=$(sqlite3 ./applis.db "$query") app=$(echo "$result" | awk -F "|" '{print $1}') latest=$(echo "$result" | awk -F "|" '{print $2}') published=$(echo "$result" | awk -F "|" '{print $3}') url=$(echo "$result" | awk -F "|" '{print $4}') echo -e "${bold}${app}${reset}" if [ -n "$published" ]; then echo -e "Latest release: $latest" echo -e "Published date: $published" else echo -e "Latest tag: $latest" fi echo -e "Url: $url\n" done } ############################# # # # clicclac.info # # # ############################# clicclac(){ # vegas, wordpress, zenphoto clicclac=( "vegas" "wordpress" "zenphoto" ) clear if ssh funnymac@ftp.cluster011.ovh.net "true"; then clicclac_vegas=$(ssh -q -t funnymac@ftp.cluster011.ovh.net "cd www/photoblog/js/vegas 2>/dev/null && git show | grep -m 1 \"Build\"" | awk -F"v" '{print $2}' | sed 's/.$//' 2>/dev/null) [[ $clicclac_vegas =~ ^[0-9]{1,2}\.[0-9]{0,2}\.{0,1}[0-9]{0,2}$ ]] && current_vegas=$clicclac_vegas || current_vegas="" clicclac_wordpress=$(ssh funnymac@ftp.cluster011.ovh.net 'cat www/wordpress/wp-includes/version.php 2>/dev/null' | grep 'wp_version =' | awk -F"'" '{print $2}') [[ $clicclac_wordpress =~ ^[0-9]{1,2}\.[0-9]{0,2}\.{0,1}[0-9]{0,2}$ ]] && current_wordpress=$clicclac_wordpress || current_wordpress="" clicclac_zenphoto=$(ssh funnymac@ftp.cluster011.ovh.net 'cat www/zenphoto/zp-core/version.php 2>/dev/null' | awk -F"," '{print $2}' | awk -F"'" '{print $2}') [[ $clicclac_zenphoto =~ ^[0-9]{1,2}\.[0-9]{0,2}\.{0,1}[0-9]{0,2}$ ]] && current_zenphoto=$clicclac_zenphoto || current_zenphoto="" fi echo $current_vegas echo $current_wordpress echo $current_zenphoto for app in ${!clicclac[@]} do echo "${clicclac[$app]}" done } ############################# # # # clicclac.synology.me # # # ############################# synology(){ # adminer (editor) #docker synology=( "wordpress" "mkdocs" "nextcloud" "thumbsup" "vegas" "zenphoto" "piwigo" "plex" "gitea" "adminer" "phpmyadmin") clear for app in ${!synology[@]} do echo "${synology[$app]}" done } airbook(){ # mkdocs, thumbsup, vegas airbook=( "mkdocs" "thumbsup" "vegas" ) clear for app in ${!airbook[@]} do echo "${airbook[$app]}" done } ############################# # # # router Asus # # # ############################# asus(){ # asus, diversion asus=( "Asus RT-AC88U" ) clear if nmap "192.168.2.1" -PN -p 56222 | grep open &>/dev/null; then motd=$(ssh -p56222 bruno@192.168.2.1 'cat /rom/etc/motd' | awk NF) # ASUSWRT-Merlin RT-AC88U 386.12_0 Mon Sep 4 15:47:31 UTC 2023 firmw=$(echo "$motd" | awk '{print $1}') router=$(echo "$motd" | awk '{print $2}') version_fw=$(echo "$motd" | awk '{print $3}') echo -e "${bold}Asus $router${reset}" testvercomp "$firmw" $version_fw ${latest[Asuswrt-Merlin $router]} "<" fi for app in ${!asus[@]} do echo "${asus[$app]}" done } # Main menu menu(){ options=( "sur-le-(s)entier.fr" "maboite(v)erte.fr" "(c)licclac.info" "clicclac.s(y)nology.me" "(a)irbook.local" "Asus (r)outer" "(Q)uit" ) echo -e "\n\033[1mFind Updates: \033[0m\n" select option in "${options[@]}"; do case "$REPLY" in 1|s|S) surlesentier ; menu ;; 2|v|V) maboiteverte ; menu ;; 3|c|C) clicclac ; menu ;; 4|y|Y) synology ; menu ;; 5|a|A) airbook ; menu ;; 6|r|R) asus ; menu ;; 7|q|Q) exit 0 ;; esac done } menu