From 03fbc559b950be69843146291d947f601f1ec467 Mon Sep 17 00:00:00 2001 From: B Stack Date: Tue, 28 Jan 2020 19:50:15 -0500 Subject: initial commit --- .gitignore | 4 + README.md | 24 ++ vooblystats.conf.example | 3 + vooblystats.sh | 661 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 692 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 vooblystats.conf.example create mode 100755 vooblystats.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4ddf8bb --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +cookies +old +*.conf +*.swp diff --git a/README.md b/README.md new file mode 100644 index 0000000..c3d6d49 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# Readme for vooblystats.sh +Voobly website scraper written in POSIX shell! Of course sh is not ideal for parsing html, but I suck at understanding the python3 requests library documentation. + +Use the config file to set username and password. I implemented the config file so I can exclude secrets for this scm repo. + +This is more of a library of functions to be used for whatever you want, as long as it scrapes the webpages from voobly.com. I use it to list my friends and me, then all the games in our history, and then pull all the stats for those games. + +# List available functions +View available functions + + grep -E '^[^_][a-z_]+\(\)' vooblystats.sh + +View available functions with brief explanation of how to call. + + grep -A2 -E '^[^_][a-z_]+\(\)' vooblystats.sh + +# License +CC-BY-SA 4.0 + +# Alternatives +* I should have used python implementation https://github.com/happyleavesaoc/python-voobly or at least augmented it. +* Haskell https://github.com/bowswung/voobly-scraper +* C++ https://github.com/kliu31415/aoe2data +* Another python implementation https://github.com/hepter/VooblyAPI-Parse diff --git a/vooblystats.conf.example b/vooblystats.conf.example new file mode 100644 index 0000000..baa38cc --- /dev/null +++ b/vooblystats.conf.example @@ -0,0 +1,3 @@ +VS_USERNAME="frodo" +VS_PASSWORD="NONE" +VS_MATCHLIST="name1,name2,__xX_gonzo_Xx__" diff --git a/vooblystats.sh b/vooblystats.sh new file mode 100755 index 0000000..2c56f68 --- /dev/null +++ b/vooblystats.sh @@ -0,0 +1,661 @@ +#!/bin/sh +# Filename: vooblystats.sh +# License: CC-BY-SA 4.0 +# Author: bgstack15@gmail.com +# Startdate: 2020-01-24 08:57:56 +# Title: +# Purpose: +# Package: +# History: +# Usage: +# Reference: ftemplate.sh 2019-05-02a ; framework.sh 2018-05-02a +# Improve: +# write a separate, no-auth-needed tool that scrapes https://www.voobly.com/games/view/Age-of-Empires-II-The-Conquerors for lobby attendance, and put it in cronjob. +# add debuglev ferror stuff +# Dependencies: +# framework.sh +fiversion="2019-05-02a" +vooblystatsversion="2020-01-28a" + +usage() { + ${PAGER:-/usr/bin/less -F} >&2 </dev/null + +} + +html_encode() { + # call: safevar="$( html_encode "unsafe;string" )" + # reference: + # https://stackoverflow.com/questions/296536/how-to-urlencode-data-for-curl-command/10797966#10797966 + ___he_input="${1}" + echo "${___he_input}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | sed -E 's/..(.*).../\1/' +} + +auth_to_voobly() { + # call: auth_to_voobly "${username}" "${password}" "${cookiefile}" + ___atv_username="${1}" + ___atv_password="${2}" + ___atv_cookiefile="${3}" + # transform password to html-safe + ___atv_password_safe="$( html_encode "${___atv_password}" )" + make_voobly_request "https://www.voobly.com/" "https://wwww.voobly.com" "true" "${___atv_cookiefile}" "false" "" "true" 1>"${VS_TMPDIR}/auth-response1" + make_voobly_request "https://www.voobly.com/login" "https://wwww.voobly.com/" "true" "${___atv_cookiefile}" "false" "" "true" 1>"${VS_TMPDIR}/auth-response2" + make_voobly_request "https://www.voobly.com/login/auth" "https://wwww.voobly.com/login" "true" "${___atv_cookiefile}" "true" "username=${___atv_username}&password=${___atv_password_safe}" "true" 1>"${VS_TMPDIR}/auth-response3" + make_voobly_request "https://www.voobly.com/welcome" "https://wwww.voobly.com/login" "true" "${___atv_cookiefile}" "false" "" "true" 1>"${VS_TMPDIR}/auth-response4" + make_voobly_request "https://www.voobly.com/profile/view/123989133" "https://wwww.voobly.com/welcome" "true" "${___atv_cookiefile}" "false" "" "true" 1>"${VS_TMPDIR}/auth-response5" +} + +parse_game_page() { + # call: parse_game_page "${inputfileORurl}" "${cookiefile}" + # output: to stdout, a csv that originally was planned to resemble: + # GAME,gameid,dateplayed,maptype,duration,playercount,gamemod + # PLAYER,playerid,gameid,playercountnum,playername,playercountry,playernewrating,playerpoints,playerteam,playerciv,playerwonbool,militaryscore,economyscore,technologyscore,societyscore,totalscore,unitskilled,unitslost,buildingsrazed,buildingslost,unitsconverted,food,wood,stone,gold,tradeprofit,tributerec,tributesent,feudaltime,castletime,imptime,mapexplored,researchcount,researchpercent,totalwonders,totalcastles,reliccount,relicgold,villagerhigh + ___pgp_infile="${1}" + ___pgp_cf="${2}" + if test "${___pgp_infile}" = "stdin" ; + then + fullpage="$( cat )" + else + # check if it contains a URL + if echo "${___pgp_infile}" | grep -qiE '^https?:\/\/' ; + then + # need to retrieve it + fullpage="$( make_voobly_request "${___pgp_infile}" "https://www.voobly.com/welcome" "true" "${___pgp_cf:-${VS_COOKIEFILE}}" "false" "" "false" )" + else + fullpage="$( cat "${___pgp_infile}" 2>/dev/null )" + fi + fi + + # test if valid page + if ! echo "${fullpage}" | grep -qiE "economy score" ; + then + # if the page does not contain the expression "economy score" then it is invalid + ferror "${scriptfile}: cannot parse game page ${___pgp_infile}. Skipping..." + return + fi + + # game info + gameid="$( echo "${fullpage}" | _get_simple_value "Match Details" | tr -d '#' )" + _reldate="$( echo "${fullpage}" | _get_simple_value "Date Played:" )" + absolute_date="$( date -d "$( echo "${_reldate}" | tr -d ',-' )" -u "+%FT%TZ" )" + map="$( echo "${fullpage}" | _get_simple_value "Map:" )" + duration="$( echo "${fullpage}" | _get_simple_value "Duration:" )" + playercount="$( echo "${fullpage}" | _get_simple_value "Players:" )" + gamemod="$( echo "${fullpage}" | _get_simple_value "Game Mod:" )" + gameladder="$( echo "${fullpage}" | awk '/Ladder:/' | grep -oE ">.*<" | tail -c +2 | head -c -2 )" + + echo "GAME,${gameid},${absolute_date},${map},${duration},${gameladder},${playercount},${gamemod}," # HEADERCSV + + # per player info + x=0 + while test $x -lt $playercount ; + do + x=$(( x + 1 )) + _playerline="$( echo "${fullpage}" | grep -E "^$" | sed -n "${x}p" )" + _playerline_num="$( echo "${fullpage}" | grep -n -E "^" | tr -dc '[0-9]' )" + playername="$( echo "${_playerline}" | grep -oE "profile\/view/[0-9]{1,15}.?>.*<\/a><\/" | sed -r -e 's/<\/a>.*$//;' -e 's/.*view\/[0-9]{1,15}\">//;' )" + playercountry="$( echo "${_playerline}" | grep -oE "res\/flags/[^\.]{1,20}\.(png|jpg)" | awk -F'/' '{print $NF}' | awk -F'.' '{print $1}' )" + playernewrating="$( echo "${_playerline2}" | awk -F'[<>]' '{print $5}' )" + playerpoints="$( echo "${_playerline2}" | awk -F'[<>]' '{print $11}' )" + playerteam="$( echo "${_playerline2}" | awk -F'[<>]' '{print $17}' )" + playerwinbool="$( echo "${_playerline}" | grep -qiE 'win.PNG' && echo "true" || echo "false" )" + playerpremiumbool="$( echo "${_playerline}" | grep -qiE 'user-premium' && echo "true" || echo "false" )" + playergamemvpbool="$( echo "${_playerline}" | grep -qiE 'high.PNG' && echo "true" || echo "false" )" + playerclan="$( echo "${_playerline}" | grep -oE ".{1,50}<\/a>.*$//' -e 's/^.*\.voobly\.com>//' )" + # if x > ( numplayers/2), then swap newrating and points + if test "$( printf '%s;%s>(%s/2);\n' "scale=2" "${x}" "${playercount}" | bc )" = "1" ; + then + tempvar="${playernewrating}" + playernewrating="${playerteam}" + playerteam="${tempvar}" + unset tempvar + fi + + # in-game stats + _playerstatslines="$( echo "${fullpage}" | grep -A4 -E "${playername}.*<\/a>(<\/b>|<\/span>)*$" | grep center )" + # works on webpage game stats sections 1, 2, and 5. + #echo "${_playerstatslines}" | sed -r -e 's/(<[^\>]+>)+/@/g;'| tr -d ',%' | awk -F'@' 'BEGIN{OFS="\t"} {print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10}' + _playerstatslines2="$( echo "${_playerstatslines}" | sed -r -e 's/(<[^\>]+>)+/@/g;' | tr -d ',%' | awk -F'@' '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10}' )" + _playerstatslines3="$( echo "${_playerstatslines2}" | tr -d '\n' | sed -r -e 's/\s+/ /g;' )" + + playerciv="$( echo "${fullpage}" | grep -B4 -E "${playername}.*<\/a>(<\/b>|<\/span>)*$" | head -n1 | sed -r -e 's/(<[^\>]+>)+//g;' )" + playercolorhex="$( echo "${fullpage}" | grep -B2 -E "${playername}.*<\/a>(<\/b>|<\/span>)*$" | head -n1 | tr -d ';' | awk '{print $3}' )" + # 0054A6 00A651 00FFFF 92278F C0C0C0 FF0000 FF8000 FFFF00 + playercolorname="nocolor" + case "${playercolorhex###}" in + 0054A6) playercolorname="blue" ;; + FF0000) playercolorname="red" ;; + FFFF00) playercolorname="yellow" ;; + 00A651) playercolorname="green" ;; + 00FFFF) playercolorname="cyan" ;; + 92278F) playercolorname="purple" ;; + C0C0C0) playercolorname="gray" ;; + FF8000) playercolorname="orange" ;; + esac + + # and because bash read is broken on devuan for an uknown reason... we have to use awk + milscore="$( echo "${_playerstatslines3}" | awk '{print $1}' )" + ecoscore="$( echo "${_playerstatslines3}" | awk '{print $2}' )" + techscore="$( echo "${_playerstatslines3}" | awk '{print $3}' )" + socscore="$( echo "${_playerstatslines3}" | awk '{print $4}' )" + totscore="$( echo "${_playerstatslines3}" | awk '{print $5}' )" + unitskilled="$( echo "${_playerstatslines3}" | awk '{print $6}' )" + unitslost="$( echo "${_playerstatslines3}" | awk '{print $7}' )" + buildingsrazed="$( echo "${_playerstatslines3}" | awk '{print $8}' )" + buildingslost="$( echo "${_playerstatslines3}" | awk '{print $9}' )" + unitsconverted="$( echo "${_playerstatslines3}" | awk '{print $10}' )" + food="$( echo "${_playerstatslines3}" | awk '{print $11}' )" + wood="$( echo "${_playerstatslines3}" | awk '{print $12}' )" + stone="$( echo "${_playerstatslines3}" | awk '{print $13}' )" + gold="$( echo "${_playerstatslines3}" | awk '{print $14}' )" + tradeprofit="$( echo "${_playerstatslines3}" | awk '{print $15}' )" + tributerec="$( echo "${_playerstatslines3}" | awk '{print $16}' )" + tributesent="$( echo "${_playerstatslines3}" | awk '{print $17}' )" + feudaltime="$( echo "${_playerstatslines3}" | awk '{print $18}' )" + castletime="$( echo "${_playerstatslines3}" | awk '{print $19}' )" + imptime="$( echo "${_playerstatslines3}" | awk '{print $20}' )" + mapexplored="$( echo "${_playerstatslines3}" | awk '{print $21}' )" + researchcount="$( echo "${_playerstatslines3}" | awk '{print $22}' )" + researchpercent="$( echo "${_playerstatslines3}" | awk '{print $23}' )" + totalwonders="$( echo "${_playerstatslines3}" | awk '{print $24}' )" + totalcastles="$( echo "${_playerstatslines3}" | awk '{print $25}' )" + reliccount="$( echo "${_playerstatslines3}" | awk '{print $26}' )" + relicgold="$( echo "${_playerstatslines3}" | awk '{print $27}' )" + villagerhigh="$( echo "${_playerstatslines3}" | awk '{print $28}' )" + + # end of player loop + echo "PLAYER,${playerid},${gameid},${x},${playername},${playercolorhex},${playercolorname},${playercountry},${playerpremiumbool},${playerclan},${playernewrating},${playerpoints},${playerteam},${playerciv},${playerwinbool},${milscore},${ecoscore},${techscore},${socscore},${totscore},${unitskilled},${unitslost},${buildingsrazed},${buildingslost},${unitsconverted},${food},${wood},${stone},${gold},${tradeprofit},${tributerec},${tributesent},${feudaltime},${castletime},${imptime},${mapexplored},${researchcount},${researchpercent},${totalwonders},${totalcastles},${reliccount},${relicgold},${villagerhigh}," # HEADERCSV + + unset -v playerclan _playerline _playerline2 _playerline_num playerid playername playercountry playernewrating playerpoints + done + +} # end of parse_game_page + +parse_profile_matchlist_page() { + # call: parse_profile_matchlist_page "${inputfileORurl}" "${cookiefile}" + # output: delimited list of match numbers found on the profile page. + # reference: parse_game_page + ___ppmp_infile="${1}" + ___ppmp_cf="${2}" + if test "${___ppmp_infile}" = "stdin" ; + then + fullpage="$( cat )" + else + # check if it contains a URL + if echo "${___ppmp_infile}" | grep -qiE '^https?:\/\/' ; + then + # need to retrieve it + fullpage="$( make_voobly_request "${___ppmp_infile}" "https://www.voobly.com/welcome" "true" "${___ppmp_cf:-${VS_COOKIEFILE}}" "false" "" "false" )" + else + fullpage="$( cat "${___ppmp_infile}" 2>/dev/null )" + fi + fi + + # test if valid page + results="$( echo "${fullpage}" | grep -oE "match\/view\/[0-9]+" | awk -F'/' '!x[$3]++ {print $3}' )" + if test "$( echo "${results}" | wc -l | tr -dc '[0-9]' )" -gt 0 ; + then + echo "${results}" + else + ferror "${scriptfile}: cannot parse matchlist page ${___ppmp_infile}. Skipping..." + echo "invalid_matchlist_page" + fi + +} # end parse_profile_matchlist_page + +get_match_url() { + # call: get_match_url "${matchid}" + ___gmu_gameid="${1}" + ___gmu_gameurl="https://www.voobly.com/match/view/$( echo "${___gmu_gameid}" | grep -oE "match\/view\/[0-9]+" | awk -F'/' '{print $3}' )" + echo "${___gmu_gameurl}" +} + +get_profile_matchlist_url() { + # call: get_profile_matchlist_url "123456789" "1" for page 1 + # call: get_profile_matchlist_url "https://www.voobly.com/profile/view/123989133/" + # call: get_profile_matchlist_url "https://www.voobly.com/profile/view/123989133/" "1" + # output: url of page that lists matches, including a page number if requested. + # we will use a cool shortcut i found, https://www.voobly.com/games/matches/user/123989133/0/0#pagebrowser1 + ___gpmu_url="${1}" + ___gpmu_pagenum="${2}" + + # if it is already a full page with a pagenumber, just return it + if echo "${___gpmu_url}" | grep -qiE "\/0\/[0-9]+#pagebrowser" ; + then + : # make no changes to it + else + if echo "${___gpmu_url}" | grep -qiE "voobly.com" ; + then + # derive userid + ___gpmu_url="$( echo "${___gpmu_url}" | grep -oE "(view|user)\/[0-9]+" | awk -F'/' '{print $2}' )" + fi + ___gpmu_url="https://www.voobly.com/games/matches/user/${___gpmu_url}" + # https://www.voobly.com/games/matches/user/123989133/0/0#pagebrowser1 + # https://www.voobly.com/games/matches/user/123989133/0/1#pagebrowser1 + if test -n "${___gpmu_pagenum}" ; + then + ___gpmu_url="${___gpmu_url}/0/${___gpmu_pagenum}#pagebrowser1" + fi + fi + echo "${___gpmu_url}" +} + +get_user_matchlist() { + # call: get_user_matchlist "useridORuserurl" "${mingamecount}" + # output: on stdout, a list of gameid numbers. + ___gum_userurl="${1}" + ___gum_min="${2}" ; test -z "${___gum_min}" && ___gum_min=10 + debuglev 9 && ferror "DEBUG9: get_user_matchlist $*" + if echo "${___gum_userurl}" | grep -qoE "^[0-9]{1,15}$" ; + then + # just userid, so make url + ___gum_userurl="https://www.voobly.com/profile/view/${___gum_userurl}/" + fi + results="" + + # start going through games, starting on page 1 + x=0 + ___gum_continue=0 + ___gum_previous_count=-1 + ___gum_count=0 + while test ${___gum_continue} -eq 0 ; + do + x=$(( x + 1 )) + # get game page + loopresults="$( parse_profile_matchlist_page "$( get_profile_matchlist_url "${___gum_userurl}" "${x}" )" "${VS_COOKIEFILE}" )" + debuglev 2 && ferror "DEBUG2: get_user_matchlist: $( echo "${loopresults}" | xargs )" + results="${results} ${loopresults}" + ___gum_count="$( echo "${results}" | wc -w )" + test ${___gum_count} -ge ${___gum_min} && ___gum_continue=1 + # if results have not increased, then we need to stop looping because we are not pulling any more gameids + test ${___gum_previous_count} -ge ${___gum_count} && ___gum_continue=1 + ___gum_previous_count="${___gum_count}" + done + # assume we are good now, where count >= min + echo "${results}" | xargs -n1 +} + +get_userid() { + # call: get_userid "gimli" "${cookiefile}" + # cookiefile is absolutely necessary for this function! + # output to stdout: "123456789" + ___gu_username="${1}" + ___gu_cf="${2}" ; test -z "${___gu_cf}" && ___gu_cf="${VS_COOKIEFILE}" + + # if the input is already a userid, just return it + if echo "${___gu_username}" | grep -qiE "^[0-9]+$" ; + then + echo "${___gu_username}" + elif echo "${___gu_username}" | grep -qiE "profile\/view\/[0-9]+" ; + then + response="$( echo "${___gu_username}" | grep -oE 'profile\/view\/[0-9]+' | cut -d'/' -f3 | head -n1 )" + echo "${response}" + else + # assume it is just a regular name to parse + # we need to pass the sessionid in the post data, or else we get an error, even though it is in the cookie. + sessionid="$( awk '/vbly_session1/{print $NF}' "${___gu_cf}" )" + response="$( make_voobly_request "https://www.voobly.com/friends/browse/Search/Search" "https://www.voobly.com/Welcome" "true" "${VS_COOKIEFILE}" "true" "query=${___gu_username}&session1=${sessionid}" )" + # the response will not be a real page; it will just be a redirect notice but it is good enough to get the userid + if echo "${response}" | grep -qiE "no results found" ; + then + ferror "get_userid: unable to find a userid for ${___gu_username}" + echo "invalid_userid" + else + response="$( echo "${response}" | grep -oE 'profile\/view\/[0-9]+' | cut -d'/' -f3 | head -n1 )" + echo "${response}" + fi + fi + +} + +get_game_page() { + # call: get_game_page "123456789" "${cookiefile}" | parse_game_page stdin + # output to stdout: the html of the game page. + ___ggp_number="${1}" + ___ggp_cf="${2}" + + # do some validation to make sure this is a valid game number + ___ggp_number_orig="${___ggp_number}" + if echo "${___ggp_number}" | grep -qE "voobly\.com" ; + then + # somebody passed a whole URL, so let us split it + ___ggp_number="${___ggp_number##*view/}" + fi + ___ggp_number="$( echo "${___ggp_number}" | grep -oE '^[0-9]+' )" + + debuglev 1 && ferror "Trying to read game ${___ggp_number}" + + response="$( make_voobly_request "https://www.voobly.com/match/view/${___ggp_number}" "https://www.voobly.com/" "true" "${____ggp_cf}" "no" "" "false" )" + if echo "${response}" | grep -qiE "economy score" ; + then + # is valid game page + echo "${response}" + else + ferror "${scriptfile}: ERROR! Invalid game page request: ${___ggp_number_orig}. Used match number ${___ggp_number}. Skipping..." + echo "invalid_page_request" + fi + +} + +_get_simple_value() { + # call: echo "${fullpage}" | _get_simple_value "Match Details" + grep -A1 "${1}<\/" | tail -n1 | awk -F'[<>]' '{print $3}' +} + +display_csv_headers() { + # output csv headers. + #echo "GAME,gameid,absolute_date,map,duration,playercount,gamemod," + #echo "PLAYER,playerid,gameid,x,playername,playercolorhex,playercolorname,playercountry,playerpremiumbool,playerclan,playernewrating,playerpoints,playerteam,playerciv,playerwinbool,milscore,ecoscore,techscore,socscore,totscore,unitskilled,unitslost,buildingsrazed,buildingslost,unitsconverted,food,wood,stone,gold,tradeprofit,tributerec,tributesent,feudaltime,castletime,imptime,mapexplored,researchcount,researchpercent,totalwonders,totalcastles,reliccount,relicgold,villagerhigh," + sed -n -r -e '/HEADERCSV$/{ s/^.*echo "//;s/"\s*# HEADERCSV$//;s/\$\{//g;s/\}//g;p}' "${scriptfile}" +} + +parse_matches_for_user() { + # call: parse_matches_for_user "gimli" "10" "${cookiefile}" + ___pmfu_username="${1}" + ___pmfu_min="${2}" + ___pmfu_cf="${3}" + for word in $( get_user_matchlist "$( get_userid "${___pmfu_username}" )" "${___pmfu_min}" ) ; + do + debuglev 1 && ferror "DEBUG1: parse_matches_for_user: found gameid ${word}" + get_game_page "${word}" "${___pmfu_cf}" | parse_game_page stdin + done +} + +cat_matchlist() { + # call: cat_matchlist "gimli,frodo,bilbo" "${userlistdelimiter}" "${minimum}" "${cookiefile}" + # call: echo "12345982 2985817 398282847" | cat_matchlist "stdin" + ___cm_userlist="${1}" + ___cm_delim="${2}" + ___cm_min="${3}" + ___cm_cf="${4}" + if echo "${___cm_userlist}" | grep -qiE "^stdin$" ; + then + awk '!x[$0]++' + else + # parse list of users, and make a master list of unique entries + results="$( + { + for word in $( echo "${___cm_userlist}" | tr "${___cm_delim}" '\n' ) ; + do + get_user_matchlist "$( get_userid "${word}" )" "${___cm_min}" + done + } | awk '!x[$0]++' + )" + # for sorting them. -n will go lowest to highest. + results="$( echo "${results}" | sort -n )" + echo "${results}" + fi +} + +# DEFINE TRAPS + +clean_vooblystats() { + # use at end of entire script if you need to clean up tmpfiles + # rm -f "${tmpfile1}" "${tmpfile2}" 2>/dev/null + + # Delayed cleanup + if test -z "${VS_NO_CLEAN}" ; + then + nohup /bin/bash </dev/null 2>&1 & +sleep "${VS_CLEANUP_SEC:-300}" ; /bin/rm -r "${VS_TMPDIR:-NOTHINGTODELETE}" 1>/dev/null 2>&1 ; +EOF + fi +} + +CTRLC() { + # use with: trap "CTRLC" 2 + # useful for controlling the ctrl+c keystroke + : +} + +CTRLZ() { + # use with: trap "CTRLZ" 18 + # useful for controlling the ctrl+z keystroke + : +} + +parseFlag() { + flag="$1" + hasval=0 + case ${flag} in + # INSERT FLAGS HERE + "d" | "debug" | "DEBUG" | "dd" ) setdebug ; ferror "debug level ${debug}" ; __debug_set_by_param=1 ;; + "u" | "usage" | "help" | "h" ) usage ; exit 1 ;; + "V" | "fcheck" | "version" ) ferror "${scriptfile} version ${vooblystatsversion}" ; exit 1 ;; + #"i" | "infile" | "inputfile" ) getval ; infile1=${tempval} ;; + "c" | "conf" | "conffile" | "config" ) getval ; conffile="${tempval}" ;; + esac + + debuglev 10 && { test ${hasval} -eq 1 && ferror "flag: ${flag} = ${tempval}" || ferror "flag: ${flag}" ; } +} + +# DETERMINE LOCATION OF FRAMEWORK +f_needed=20181030 +___frameworkpath="$( find $( echo "${FRAMEWORKPATH}" | tr ':' ' ' ) -maxdepth 1 -mindepth 0 -name 'framework.sh' 2>/dev/null )" +while read flocation ; do if test -e ${flocation} ; then __thisfver="$( sh ${flocation} --fcheck 2>/dev/null )" ; if test ${__thisfver:-0} -ge ${f_needed} ; then frameworkscript="${flocation}" ; break ; elif test -n "${___thisfver}" ; then printf "Obsolete: %s %s\n" "${flocation}" "${__thisfver}" 1>&2 ; fi ; fi ; done <&2 && exit 4 + +# INITIALIZE VARIABLES +# variables set in framework: +# today server thistty scriptdir scriptfile scripttrim +# is_cronjob stdin_piped stdout_piped stderr_piped sendsh sendopts +. ${frameworkscript} || echo "$0: framework did not run properly. Continuing..." 1>&2 +infile1= +outfile1= +logfile=${scriptdir}/${scripttrim}.${today}.out +define_if_new interestedparties "bgstack15@gmail.com" +# SIMPLECONF +define_if_new default_conffile "./vooblystats.conf" +#define_if_new defuser_conffile ~/.config/vooblystats/vooblystats.conf +define_if_new VS_TMPDIR "$( mktemp -d )" +define_if_new VS_COOKIEFILE "./cookies" +#tmpfile1="$( TMPDIR="${VS_TMPDIR}" mktemp )" +#tmpfile2="$( TMPDIR="${VS_TMPDIR}" mktemp )" + +# REACT TO OPERATING SYSTEM TYPE +case $( uname -s ) in + Linux) : ;; + FreeBSD) : ;; + *) echo "${scriptfile}: 3. Indeterminate OS: $( uname -s )" 1>&2 && exit 3 ;; +esac + +## REACT TO ROOT STATUS +#case ${is_root} in +# 1) # proper root +# : ;; +# sudo) # sudo to root +# : ;; +# "") # not root at all +# #ferror "${scriptfile}: 5. Please run as root or sudo. Aborted." +# #exit 5 +# : +# ;; +#esac + +# SET CUSTOM SCRIPT AND VALUES +#setval 1 sendsh sendopts<&2 +} + +# MAIN LOOP +#{ + + # Initial authentication and download a random game page + rm -f "${VS_COOKIEFILE}" + + # need to auth at least one for any other voobly function to work correctly. + auth_to_voobly "${VS_USERNAME}" "${VS_PASSWORD}" "${VS_COOKIEFILE}" + #get_game_page "${opt1}" "${VS_COOKIEFILE}" | parse_game_page stdin + #parse_matches_for_user "frodo" "300" "${VS_COOKIEFILE}" + display_csv_headers + + #get_user_matchlist "123989133" "150" + + { + for word in $( cat_matchlist "${VS_MATCHLIST:-frodo,bilbo,merry,pippin}" "," "300" "${VS_COOKIEFILE}" ) + do + get_game_page "${word}" | parse_game_page stdin + done + } | sort -k1,3 + +#} | tee -a ${logfile} + +# EMAIL LOGFILE +#${sendsh} ${sendopts} "${server} ${scriptfile} out" ${logfile} ${interestedparties} + +## STOP THE READ CONFIG FILE +#return_code 0 +#fi ; done ; } -- cgit