| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | #!/usr/bin/env bash | 
					
						
							|  |  |  | # Copyright 2014 Vladimir Ivanov <ivvl82@gmail.com> | 
					
						
							|  |  |  | # Distributed under the terms of the GNU General Public License v2 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-09 13:30:22 +03:00
										 |  |  | REPODIR="`dirname $0`" | 
					
						
							|  |  |  | TOURNAMENT="2014/2-summertime" | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Config file for players | 
					
						
							| 
									
										
										
										
											2014-05-09 13:30:22 +03:00
										 |  |  | ply_ini="${REPODIR}/${TOURNAMENT}/players.ini" | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  | # Version information | 
					
						
							|  |  |  | VERSION="0.1" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | argv0="${0##*/}" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | usage() { | 
					
						
							|  |  |  |     cat <<EOF | 
					
						
							|  |  |  | Store a chess game played on lichess.org | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Usage: | 
					
						
							|  |  |  |   $argv0 -t <num> <url> | 
					
						
							|  |  |  |   $argv0 -h | 
					
						
							|  |  |  |   $argv0 -v | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The first form fills the result of a chess game and stores its PGN | 
					
						
							|  |  |  | file. Assumes that the game is available at <url> (lichess.org) and | 
					
						
							|  |  |  | corresponds to tournament tour <num>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The second form shows this help output. The third form shows version | 
					
						
							|  |  |  | information. | 
					
						
							|  |  |  | EOF | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     exit "${1:-0}" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | version() { | 
					
						
							|  |  |  |     exec echo "${argv0}-${VERSION}" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-09 20:24:14 +03:00
										 |  |  | game_get_players() { | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     # Extract players on Lichess | 
					
						
							|  |  |  |     local w_lichess=$(sed -En "s/\[White \"([^\"]*)\"\]/\1/p" < "$tmp_pgn") | 
					
						
							|  |  |  |     local b_lichess=$(sed -En "s/\[Black \"([^\"]*)\"\]/\1/p" < "$tmp_pgn") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Get names of white and black players | 
					
						
							|  |  |  |     local counter=1 players=() | 
					
						
							| 
									
										
										
										
											2014-05-09 20:24:14 +03:00
										 |  |  |     game_parse_config | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     while eval "config_section_player${counter}" 2>/dev/null; do | 
					
						
							|  |  |  |         players+=("$name") | 
					
						
							|  |  |  |         [[ "$lichess" == "$w_lichess" ]] && white="$name" | 
					
						
							|  |  |  |         [[ "$lichess" == "$b_lichess" ]] && black="$name" | 
					
						
							|  |  |  |         counter=$((counter+1)) | 
					
						
							|  |  |  |     done | 
					
						
							|  |  |  |     [[ -z "$white" ]] && fix_white_player | 
					
						
							|  |  |  |     [[ -z "$black" ]] && fix_black_player | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-09 20:24:14 +03:00
										 |  |  | game_parse_config() { | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     # Copy player INI file to the temporary location | 
					
						
							| 
									
										
										
										
											2014-05-08 19:06:57 +03:00
										 |  |  |     # NOTE: an empty line is added to the file beginning in order to | 
					
						
							|  |  |  |     # match the only first occurrence for non-GNU sed | 
					
						
							|  |  |  |     echo > "$tmp_ini" | 
					
						
							|  |  |  |     cat "$ply_ini" >> "$tmp_ini" | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Remove tabs or spaces around the `=' | 
					
						
							| 
									
										
										
										
											2014-05-08 19:06:57 +03:00
										 |  |  |     sed -i".prev" -E "s/[[:blank:]]*=[[:blank:]]*/=/g" "$tmp_ini" | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Transform section labels into function declaration | 
					
						
							| 
									
										
										
										
											2014-05-08 19:06:57 +03:00
										 |  |  |     sed -i".prev" -E "1,/^\[.*\]/s/^\[([^]]*)\]/config_section_\1() {/g" "$tmp_ini" | 
					
						
							|  |  |  |     sed -i".prev" -E "s/^\[([^]]*)\]/}\\"$'\n'"config_section_\1() {/g" "$tmp_ini" | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     echo -e "\n}" >> "$tmp_ini" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Load the file | 
					
						
							|  |  |  |     source "$tmp_ini" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | fix_white_player() { | 
					
						
							|  |  |  |     local number | 
					
						
							| 
									
										
										
										
											2014-05-08 19:06:57 +03:00
										 |  |  |     echo "Lichess player '${w_lichess}' not found." | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     choose_player | 
					
						
							|  |  |  |     white="${players[$number]}" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | fix_black_player() { | 
					
						
							|  |  |  |     local number | 
					
						
							| 
									
										
										
										
											2014-05-08 19:06:57 +03:00
										 |  |  |     echo "Lichess player '${b_lichess}' not found." | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     choose_player | 
					
						
							|  |  |  |     black="${players[$number]}" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | choose_player() { | 
					
						
							| 
									
										
										
										
											2014-05-09 15:43:20 +03:00
										 |  |  |     echo "Please choose a proper name from the list below:" | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     for ((i=0; i<${#players[@]}; ++i)); do | 
					
						
							|  |  |  |         echo "$((i+1)) ${players[$i]}" | 
					
						
							|  |  |  |     done \ | 
					
						
							|  |  |  |         | column -t \ | 
					
						
							|  |  |  |         | sed -E "s/^([0-9]*)/$(tput setaf 6)\1$(tput sgr0)/g" # highlight number | 
					
						
							|  |  |  |     echo -n "Put number> " | 
					
						
							|  |  |  |     read number | 
					
						
							| 
									
										
										
										
											2014-05-08 19:06:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (( "$number" < 1 || "$number" > ${#players[@]} )); then | 
					
						
							|  |  |  |         die "Incorrect player number." | 
					
						
							|  |  |  |     fi | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     number=$((number-1)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-09 20:24:14 +03:00
										 |  |  | game_add_to_repo() { | 
					
						
							| 
									
										
										
										
											2014-05-09 14:38:59 +03:00
										 |  |  |     local date_re="[0-9?]{2}\.[0-9?]{2}\.[0-9?]{4}" | 
					
						
							| 
									
										
										
										
											2014-05-09 15:43:20 +03:00
										 |  |  |     # Check if the tour number is correct | 
					
						
							|  |  |  |     local correct=false | 
					
						
							|  |  |  |     while IFS= read line; do | 
					
						
							|  |  |  |         if [[ "$line" =~ ${date_re}\ *[-—]\ *${white}\ *${black} ]]; then | 
					
						
							|  |  |  |             correct=true | 
					
						
							|  |  |  |             break | 
					
						
							|  |  |  |         fi | 
					
						
							|  |  |  |     done < "$tour_info" | 
					
						
							|  |  |  |     if ! $correct; then | 
					
						
							|  |  |  |         die "Game '${white} vs. ${black}' not found in ${tour_info}." | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[ -d "$pgn_dir" ]] && die "Directory ${pgn_dir} already exist." | 
					
						
							|  |  |  |     echo "Creating directory ${pgn_dir}..." | 
					
						
							|  |  |  |     mkdir -p "$pgn_dir" | 
					
						
							| 
									
										
										
										
											2014-05-09 14:38:59 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-09 15:43:20 +03:00
										 |  |  |     echo "Storing PGN file..." | 
					
						
							|  |  |  |     cp "$tmp_pgn" "${pgn_dir}/1.pgn" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     echo "Updating tour_info..." | 
					
						
							|  |  |  |     local game_date="${pgn_date:8:2}.${pgn_date:5:2}.${pgn_date::4}" | 
					
						
							| 
									
										
										
										
											2014-05-09 14:38:59 +03:00
										 |  |  |     local result=$(sed -En "s/\[Result \"([^\"]*)\"\]/\1/p" < "$tmp_pgn") | 
					
						
							|  |  |  |     case "$result" in | 
					
						
							|  |  |  |         "1-0")     result="1:0" ;; | 
					
						
							|  |  |  |         "0-1")     result="0:1" ;; | 
					
						
							|  |  |  |         "1/2-1/2") result="0.5:0.5" ;; | 
					
						
							|  |  |  |     esac | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sed -i".orig" \ | 
					
						
							|  |  |  |         -E "s/${date_re}( *[-—] *)${white} *${black}/${game_date}\1${white} ${result} ${black}/g" \ | 
					
						
							|  |  |  |         "$tour_info" | 
					
						
							|  |  |  |     rm "${tour_info}.orig" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-09 20:24:14 +03:00
										 |  |  | game_git_commit() { | 
					
						
							|  |  |  |     git pull | 
					
						
							|  |  |  |     git add "${pgn_dir}/1.pgn" "$tour_info" | 
					
						
							|  |  |  |     git commit -m "Tour ${TOUR#0}: ${white} vs. ${black}." | 
					
						
							|  |  |  |     git push | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | die() { | 
					
						
							|  |  |  |     echo "$@" 1>&2 | 
					
						
							|  |  |  |     exit 1 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | checkargs() { | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  |     if [[ "$opt" == t && "$OPTARG" =~ ^[0-9]+$ ]]; then | 
					
						
							|  |  |  |         TOUR=$(printf "%02g" "$OPTARG") | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     fi | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TOUR="" | 
					
						
							|  |  |  | while getopts "t:hv" opt; do | 
					
						
							|  |  |  |     case "$opt" in | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  |         t) checkargs ;; | 
					
						
							|  |  |  |         h) usage ;; | 
					
						
							|  |  |  |         v) version ;; | 
					
						
							|  |  |  |         *) usage 1 ;; | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     esac | 
					
						
							|  |  |  | done | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | shift $(($OPTIND - 1)) | 
					
						
							|  |  |  | # For now, tour number should be given explicitly | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  | [[ -z "$TOUR" || -z "$1" ]] && usage 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-09 15:43:20 +03:00
										 |  |  | tour_info="${REPODIR}/${TOURNAMENT}/tours/${TOUR}/tour_info" | 
					
						
							|  |  |  | [[ ! -f "$tour_info" ]] && die "File ${tour_info} not found." | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Temporary files | 
					
						
							|  |  |  | tmp_ini=$(mktemp -t `basename $ply_ini`.XXXXXX) | 
					
						
							|  |  |  | tmp_pgn=$(mktemp -t pgn.XXXXXX) | 
					
						
							|  |  |  | trap "rm ${tmp_ini} ${tmp_ini}.prev ${tmp_pgn}" EXIT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Download PGN file | 
					
						
							|  |  |  | [[ "$1" =~ ^(http://[^/]*)/([^/]*) ]] | 
					
						
							| 
									
										
										
										
											2014-05-09 20:24:14 +03:00
										 |  |  | pgn_url="${BASH_REMATCH[1]}/${BASH_REMATCH[2]::8}/pgn" | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | curl -q --fail --location --silent "$pgn_url" > "$tmp_pgn" \ | 
					
						
							|  |  |  |     || die "PGN file not found." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | white="" black="" | 
					
						
							| 
									
										
										
										
											2014-05-09 20:24:14 +03:00
										 |  |  | game_get_players | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Extract the game date from PGN | 
					
						
							|  |  |  | pgn_date=$(sed -En "s/\[Date \"([^\"]*)\"\]/\1/p" < "$tmp_pgn") | 
					
						
							|  |  |  | pgn_date=$(tr '.' '-' <<< "$pgn_date") | 
					
						
							|  |  |  | pgn_dir="${REPODIR}/${TOURNAMENT}/tours/${TOUR}/${pgn_date}-${white}-vs-${black}" | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-09 20:24:14 +03:00
										 |  |  | game_add_to_repo | 
					
						
							|  |  |  | game_git_commit | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | exit 0 |