| 
									
										
										
										
											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-09-05 14:41:52 +04:00
										 |  |  | REPO_DIR= | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  | # Specify the tournament here | 
					
						
							|  |  |  | TOURNAMENT= | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  | # Version information | 
					
						
							| 
									
										
										
										
											2015-01-01 14:27:23 +03:00
										 |  |  | VERSION="0.5" | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-22 11:07:18 +03:00
										 |  |  | # Firefox User Agent | 
					
						
							|  |  |  | FIREFOX_UA="Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0" | 
					
						
							| 
									
										
										
										
											2014-12-28 17:09:30 +03:00
										 |  |  | # Regular expressions | 
					
						
							|  |  |  | URL_RE="^(http://[^/]*)/(.{8}).*" | 
					
						
							|  |  |  | DATE_RE="[0-9?]{2}\.[0-9?]{2}\.[0-9?]{4}" | 
					
						
							| 
									
										
										
										
											2014-11-22 11:07:18 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  | argv0=${0##*/} | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  | function usage { | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  |     cat <<EOF | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  | Store chess games played on lichess.org | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Usage: | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  |   $argv0 [options] -t <num> <url>... | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  |   $argv0 -h | 
					
						
							|  |  |  |   $argv0 -v | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-05 14:41:52 +04:00
										 |  |  |   Put the script under the root directory of your repository or set | 
					
						
							|  |  |  |   inner variable REPO_DIR to it. If the tournament is not the last one | 
					
						
							|  |  |  |   (default), store its sub-directory in inner variable TOURNAMENT. | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  |   The first form fills the results of chess games and stores their PGN | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  |   files, assuming that all the games were played by the same pair of | 
					
						
							| 
									
										
										
										
											2014-12-15 20:39:07 +03:00
										 |  |  |   players on tour <num> of the tournament. Each game should be | 
					
						
							|  |  |  |   available at the corresponding <url> (lichess.org). The PGN files | 
					
						
							|  |  |  |   are sorted by their timestamps, unless '-u' is set. The date of | 
					
						
							|  |  |  |   games is assigned to that of the game closing the tour, i.e., the | 
					
						
							|  |  |  |   last one. | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   The second form shows this help output. The third form shows version | 
					
						
							|  |  |  |   information. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Options: | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |   -a            Add current games to existing games | 
					
						
							|  |  |  |   -c            Clean up existing games before adding | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  |   -u            Don't sort games by their timestamps | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  | EOF | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     exit "${1:-0}" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  | function version { | 
					
						
							| 
									
										
										
										
											2014-05-21 22:19:45 +03:00
										 |  |  |     exec echo "${argv0}-${VERSION}" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-15 20:39:07 +03:00
										 |  |  | function game_check_args { | 
					
						
							|  |  |  |     # For now, tour number should be given explicitly | 
					
						
							|  |  |  |     [[ -z $TOUR || $# == 0 ]] && usage 1 | 
					
						
							|  |  |  |     # Don't add and clean up games simultaneously | 
					
						
							|  |  |  |     $ADD_GAMES && $CLEANUP_GAMES && usage 1 | 
					
						
							| 
									
										
										
										
											2014-12-23 07:37:54 +03:00
										 |  |  |     # Check for duplicate game ID | 
					
						
							| 
									
										
										
										
											2014-12-28 17:09:30 +03:00
										 |  |  |     local uniq_ids=$(xargs -n1 <<< $@ | sed -E "s|${URL_RE}|\2|" | sort -u | wc -l) | 
					
						
							| 
									
										
										
										
											2014-12-23 07:37:54 +03:00
										 |  |  |     (( $# == $uniq_ids )) || die "Game IDs not unique." | 
					
						
							| 
									
										
										
										
											2014-12-15 20:39:07 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  | function game_setup { | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  |     : ${REPO_DIR:=`dirname "$0"`} | 
					
						
							| 
									
										
										
										
											2014-12-12 21:09:28 +03:00
										 |  |  |     # Synchronize the repository | 
					
						
							|  |  |  |     git --git-dir=${REPO_DIR}/.git pull | 
					
						
							| 
									
										
										
										
											2014-08-31 20:00:00 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  |     # If no tournament given, set it to the last one | 
					
						
							|  |  |  |     if [[ -z $TOURNAMENT ]]; then | 
					
						
							| 
									
										
										
										
											2014-08-31 20:00:00 +04:00
										 |  |  |         local year_dir=$(ls -1 -d ${REPO_DIR}/[0-9][0-9][0-9][0-9]/ | tail -1) | 
					
						
							|  |  |  |         TOURNAMENT=$(ls -1 -d ${year_dir}[0-9]-*/ | tail -1 \ | 
					
						
							| 
									
										
										
										
											2014-12-19 21:09:38 +03:00
										 |  |  |                             | sed -E "s|${REPO_DIR}/(.*)/|\1|") | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  |     fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Configuration file for players | 
					
						
							| 
									
										
										
										
											2014-08-31 20:00:00 +04:00
										 |  |  |     ply_ini=${REPO_DIR}/${TOURNAMENT}/players.ini | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  |     [[ -f $ply_ini ]] || die "File ${ply_ini} not found." | 
					
						
							|  |  |  |     # Pairs of players on the tour | 
					
						
							|  |  |  |     tour_info=${REPO_DIR}/${TOURNAMENT}/tours/${TOUR}/tour_info | 
					
						
							|  |  |  |     [[ -f $tour_info ]] || die "File ${tour_info} not found." | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  | function game_tmp_pgns { | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  |     # Don't sort just one game | 
					
						
							|  |  |  |     [[ $# == 1 ]] && SORT_GAMES=false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for url in $@; do | 
					
						
							| 
									
										
										
										
											2014-12-12 19:57:09 +03:00
										 |  |  |         local timestamp= | 
					
						
							| 
									
										
										
										
											2014-12-28 17:09:30 +03:00
										 |  |  |         [[ $url =~ $URL_RE ]] | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  |         # Link to annotated game PGN | 
					
						
							| 
									
										
										
										
											2014-12-28 17:09:30 +03:00
										 |  |  |         local game_url=${BASH_REMATCH[1]}/game/export/${BASH_REMATCH[2]}.pgn | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 19:57:09 +03:00
										 |  |  |         # Get the timestamp of game for sorting | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  |         if $SORT_GAMES; then | 
					
						
							| 
									
										
										
										
											2014-12-28 17:09:30 +03:00
										 |  |  |             local game_api=${BASH_REMATCH[1]}/api/game/${BASH_REMATCH[2]} | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  |             local api_response=$(curl -q --fail --location --silent "$game_api") | 
					
						
							|  |  |  |             [[ -z $api_response ]] && die "Unreachable game API ${game_api}" | 
					
						
							| 
									
										
										
										
											2014-12-12 19:57:09 +03:00
										 |  |  |             timestamp=$(sed -En "s/.*\"timestamp\":([0-9]+).*/\1/p" <<< "$api_response") | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  |         fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Store PGN file in a temporal location | 
					
						
							| 
									
										
										
										
											2014-12-12 19:57:09 +03:00
										 |  |  |         local tmp_pgn=$(mktemp -t ${timestamp:-1}.pgn-XXXXXX) | 
					
						
							| 
									
										
										
										
											2014-12-13 20:05:13 +03:00
										 |  |  |         TMP_PGN_FILES+=($tmp_pgn) | 
					
						
							|  |  |  |         trap "rm ${TMP_PGN_FILES[*]}" EXIT | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  |         wget -q -U "$FIREFOX_UA" -O $tmp_pgn "$game_url" \ | 
					
						
							|  |  |  |             || die "Unreachable game PGN ${game_url}" | 
					
						
							|  |  |  |     done | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-19 21:09:38 +03:00
										 |  |  |     $SORT_GAMES && TMP_PGN_FILES=( $(xargs -n1 <<< ${TMP_PGN_FILES[@]} | sort -n) ) | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  | function game_get_info { | 
					
						
							|  |  |  |     # Get the names of players, whose games are in PGN files | 
					
						
							| 
									
										
										
										
											2014-12-13 20:05:13 +03:00
										 |  |  |     ply_names= | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  |     game_get_names | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Select the names of two players | 
					
						
							| 
									
										
										
										
											2014-12-14 18:00:28 +03:00
										 |  |  |     local players=( $(echo -en "${ply_names// /\n}" | sort -u) ) | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  |     [[ ${#players[@]} == 2 ]] || die "Players of the games are not the same." | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Find the white and black players | 
					
						
							| 
									
										
										
										
											2014-12-12 21:16:19 +03:00
										 |  |  |     local line0=$(grep " ${players[0]}" $tour_info) | 
					
						
							|  |  |  |     local line1=$(grep " ${players[1]}" $tour_info) | 
					
						
							| 
									
										
										
										
											2014-12-12 08:22:07 +03:00
										 |  |  |     [[ -z $line0 || -z $line1 || $line0 != $line1 ]] \ | 
					
						
							|  |  |  |         && die "No game between ${players[0]} and ${players[1]} found in ${tour_info}." | 
					
						
							| 
									
										
										
										
											2014-12-28 17:09:30 +03:00
										 |  |  |     [[ $line0 =~ ^(${DATE_RE}\ +([^\ ]+)\ +-\ +([^\ ]+))(.*)$ ]] | 
					
						
							| 
									
										
										
										
											2014-12-14 15:33:34 +03:00
										 |  |  |     white=${BASH_REMATCH[2]} | 
					
						
							|  |  |  |     black=${BASH_REMATCH[3]} | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Additional information about the game record | 
					
						
							|  |  |  |     rec_length=${#BASH_REMATCH[1]} | 
					
						
							| 
									
										
										
										
											2014-12-14 15:33:34 +03:00
										 |  |  |     res_old=$(xargs <<< ${BASH_REMATCH[4]}) | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |     game_validate | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 15:33:34 +03:00
										 |  |  |     # Assign the date of games to the date of the last game | 
					
						
							|  |  |  |     local pgn_last=${TMP_PGN_FILES[${#TMP_PGN_FILES[@]} - 1]} | 
					
						
							|  |  |  |     game_date=$(sed -En "s/\[Date \"([^\"]*)\"\]/\1/p" $pgn_last) | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  | function game_get_names { | 
					
						
							|  |  |  |     # Make an associative array from Lichess nicks to players' names | 
					
						
							| 
									
										
										
										
											2014-05-09 20:24:14 +03:00
										 |  |  |     game_parse_config | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  |     local sections=$(grep -o "config_section_player[0-9]*" $tmp_ini) | 
					
						
							| 
									
										
										
										
											2014-12-14 18:00:28 +03:00
										 |  |  |     declare -A NAMES | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  |     for sect in $sections; do | 
					
						
							|  |  |  |         eval $sect | 
					
						
							|  |  |  |         NAMES+=( [$lichess]=$name ) | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     done | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-13 20:05:13 +03:00
										 |  |  |     for pgn in ${TMP_PGN_FILES[@]}; do | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  |         # Extract players on Lichess | 
					
						
							|  |  |  |         local wt_lichess=$(sed -En "s/\[White \"([^\"]*)\"\]/\1/p" $pgn) | 
					
						
							|  |  |  |         local bk_lichess=$(sed -En "s/\[Black \"([^\"]*)\"\]/\1/p" $pgn) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         game_add_player $wt_lichess | 
					
						
							| 
									
										
										
										
											2014-12-14 11:06:47 +03:00
										 |  |  |         ply_names+=" " | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  |         game_add_player $bk_lichess | 
					
						
							| 
									
										
										
										
											2014-12-14 11:06:47 +03:00
										 |  |  |         ply_names+="\n" | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  |     done | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  | function game_parse_config { | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  |     # Temporary files | 
					
						
							|  |  |  |     tmp_ini=$(mktemp -t `basename $ply_ini`.XXXXXX) | 
					
						
							|  |  |  |     TMP_INI_FILES="${tmp_ini} ${tmp_ini}.prev" | 
					
						
							| 
									
										
										
										
											2014-12-13 20:05:13 +03:00
										 |  |  |     trap "rm $TMP_INI_FILES ${TMP_PGN_FILES[*]}" EXIT | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  |     echo > $tmp_ini | 
					
						
							|  |  |  |     cat "$ply_ini" >> $tmp_ini | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Remove tabs or spaces around the `=' | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |     sed -E -i.prev "s/[[:blank:]]*=[[:blank:]]*/=/" $tmp_ini | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Transform section labels into function declaration | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |     sed -E -i.prev "1,/^\[.*\]/s/^\[([^]]*)\]/config_section_\1() {/" $tmp_ini | 
					
						
							|  |  |  |     sed -E -i.prev "s/^\[([^]]*)\]/}\\"$'\n'"config_section_\1() {/" $tmp_ini | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  |     echo -e "\n}" >> $tmp_ini | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  |     # Source the file | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |     source $tmp_ini | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  | function game_add_player { | 
					
						
							|  |  |  |     local lichess_ply=$1 | 
					
						
							|  |  |  |     local ply=${NAMES[$lichess_ply]} | 
					
						
							| 
									
										
										
										
											2014-12-19 21:09:38 +03:00
										 |  |  |     while [[ ! " ${NAMES[*]} " =~ \ $ply\  ]]; do | 
					
						
							| 
									
										
										
										
											2014-12-14 11:47:12 +03:00
										 |  |  |         echo -n "$(tput setaf 2)The list of players:$(tput sgr0)" | 
					
						
							| 
									
										
										
										
											2014-12-19 21:09:38 +03:00
										 |  |  |         sed "s/ /\\"$'\n'"$(tput setaf 6)*$(tput sgr0) /g" <<< " ${NAMES[*]}" | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  |         echo -n "Type the name of ${lichess_ply}> " | 
					
						
							|  |  |  |         read ply | 
					
						
							|  |  |  |     done | 
					
						
							| 
									
										
										
										
											2014-12-14 11:06:47 +03:00
										 |  |  |     ply_names+=$ply | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  | function game_validate { | 
					
						
							|  |  |  |     # By default, other games between the players are not allowed | 
					
						
							| 
									
										
										
										
											2014-12-14 15:33:34 +03:00
										 |  |  |     if ! $ADD_GAMES && ! $CLEANUP_GAMES && [[ -n $res_old ]]; then | 
					
						
							|  |  |  |         die "Results of some games between ${white} and ${black} already recorded." | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |     fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Players' sides should interchange | 
					
						
							| 
									
										
										
										
											2014-12-13 18:38:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 11:06:47 +03:00
										 |  |  |     local length=$(echo -en "$ply_names" | wc -l) | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  |     if $ADD_GAMES && [[ -n $res_old ]]; then | 
					
						
							|  |  |  |         local residue=$(( $(wc -w <<< "$res_old") % 2 )) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         local residue=0 | 
					
						
							|  |  |  |     fi | 
					
						
							| 
									
										
										
										
											2014-12-13 18:38:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |     local ply_ordered= | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  |     for ((i = 0; i < length; i++)); do | 
					
						
							|  |  |  |         if (( i % 2 == residue )); then | 
					
						
							| 
									
										
										
										
											2014-12-14 11:06:47 +03:00
										 |  |  |             ply_ordered+="${white} ${black}\n" | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2014-12-14 11:06:47 +03:00
										 |  |  |             ply_ordered+="${black} ${white}\n" | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |         fi | 
					
						
							|  |  |  |     done | 
					
						
							| 
									
										
										
										
											2014-12-13 18:38:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # List found games | 
					
						
							|  |  |  |     echo "$(tput setaf 2)Found games:$(tput sgr0)" | 
					
						
							| 
									
										
										
										
											2014-12-14 11:47:12 +03:00
										 |  |  |     echo -en "$ply_names" \ | 
					
						
							| 
									
										
										
										
											2014-12-14 11:06:47 +03:00
										 |  |  |         | sed "s/ / - /;s/^/$(tput setaf 6)*$(tput sgr0) /" | 
					
						
							| 
									
										
										
										
											2014-12-13 18:38:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |     if [[ "$ply_names" != "$ply_ordered" ]]; then | 
					
						
							| 
									
										
										
										
											2014-12-13 18:38:57 +03:00
										 |  |  |         # List expected games | 
					
						
							|  |  |  |         echo "$(tput setaf 2)Expected games:$(tput sgr0)" | 
					
						
							| 
									
										
										
										
											2014-12-14 11:06:47 +03:00
										 |  |  |         echo -en "$ply_ordered" \ | 
					
						
							|  |  |  |             | sed "s/ / - /;s/^/$(tput setaf 6)*$(tput sgr0) /" | 
					
						
							| 
									
										
										
										
											2014-12-13 18:38:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |         local answer | 
					
						
							|  |  |  |         echo -n "Approve games with wrong players' sides? (Y/n)> " | 
					
						
							|  |  |  |         read answer | 
					
						
							|  |  |  |         [[ $answer =~ ^(Y|y|Yes|yes)$ ]] || exit 1 | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function game_store_pgns { | 
					
						
							| 
									
										
										
										
											2014-12-14 15:33:34 +03:00
										 |  |  |     local game_dir_old=$(ls -1 -d 2>/dev/null \ | 
					
						
							|  |  |  |                             ${REPO_DIR}/${TOURNAMENT}/tours/${TOUR}/*-${white}-vs-${black}) | 
					
						
							|  |  |  |     if [[ -n $game_dir_old ]]; then | 
					
						
							|  |  |  |         if $CLEANUP_GAMES; then | 
					
						
							|  |  |  |             git --git-dir=${REPO_DIR}/.git rm --ignore-unmatch -q ${game_dir_old}/*.pgn | 
					
						
							|  |  |  |             [[ -d $game_dir_old ]] || game_dir_old= | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             $ADD_GAMES || die "Directory ${game_dir_old} already exist." | 
					
						
							|  |  |  |         fi | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |     fi | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 15:33:34 +03:00
										 |  |  |     local pgn_dir=${game_date//./-}-${white}-vs-${black} | 
					
						
							|  |  |  |     local game_dir=${REPO_DIR}/${TOURNAMENT}/tours/${TOUR}/${pgn_dir} | 
					
						
							|  |  |  |     if [[ $game_dir != $game_dir_old ]]; then | 
					
						
							|  |  |  |         echo "Creating directory ${game_dir}..." | 
					
						
							|  |  |  |         mkdir $game_dir | 
					
						
							|  |  |  |         if [[ -n $game_dir_old ]]; then | 
					
						
							|  |  |  |             git --git-dir=${REPO_DIR}/.git mv ${game_dir_old}/* ${game_dir} | 
					
						
							|  |  |  |             rm -r $game_dir_old | 
					
						
							| 
									
										
										
										
											2014-12-12 21:50:34 +03:00
										 |  |  |         fi | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |     fi | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 15:33:34 +03:00
										 |  |  |     local pgn_index=0 | 
					
						
							|  |  |  |     if $ADD_GAMES; then | 
					
						
							|  |  |  |         local old_pgns=$(ls -1 2>/dev/null ${game_dir}/*.pgn) | 
					
						
							|  |  |  |         [[ -n $old_pgns ]] && pgn_index=$(wc -l <<< "$old_pgns") | 
					
						
							|  |  |  |     fi | 
					
						
							| 
									
										
										
										
											2014-12-13 20:05:13 +03:00
										 |  |  |     for pgn in ${TMP_PGN_FILES[@]}; do | 
					
						
							| 
									
										
										
										
											2014-12-07 00:23:59 +03:00
										 |  |  |         (( pgn_index += 1 )) | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  |         echo "Storing file ${game_dir}/${pgn_index}.pgn..." | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |         cp $pgn ${game_dir}/${pgn_index}.pgn | 
					
						
							|  |  |  |     done | 
					
						
							| 
									
										
										
										
											2014-12-14 15:33:34 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     git --git-dir=${REPO_DIR}/.git add ${game_dir} | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-07 00:23:59 +03:00
										 |  |  | function game_update_info { | 
					
						
							| 
									
										
										
										
											2014-12-13 23:10:14 +03:00
										 |  |  |     # The maximal length of game records, excepting results | 
					
						
							| 
									
										
										
										
											2014-12-28 17:09:30 +03:00
										 |  |  |     local length_max=$(grep -Eo "^${DATE_RE} +[^ ]+ +- +[^ ]+" $tour_info \ | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  |                               | awk '{print length}' | sort -nr | head -1) | 
					
						
							| 
									
										
										
										
											2014-12-13 23:10:14 +03:00
										 |  |  |     local spaces=$(( length_max - rec_length )) sep= | 
					
						
							|  |  |  |     (( spaces == 0 )) || sep=$(printf "%${spaces}s" " ") | 
					
						
							| 
									
										
										
										
											2014-05-09 15:43:20 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-07 00:23:59 +03:00
										 |  |  |     local result= | 
					
						
							| 
									
										
										
										
											2014-12-13 20:05:13 +03:00
										 |  |  |     game_get_result | 
					
						
							| 
									
										
										
										
											2014-05-09 14:38:59 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  |     echo "Updating file ${tour_info}..." | 
					
						
							| 
									
										
										
										
											2014-12-14 15:33:34 +03:00
										 |  |  |     local date=${game_date:8:2}.${game_date:5:2}.${game_date::4} | 
					
						
							| 
									
										
										
										
											2014-08-31 22:49:32 +04:00
										 |  |  |     sed -E -i.orig \ | 
					
						
							| 
									
										
										
										
											2015-01-08 13:22:13 +03:00
										 |  |  |         "s/^${DATE_RE}( +${white} +- +${black}).*/${date}\1${sep}${result}/" \ | 
					
						
							| 
									
										
										
										
											2014-12-07 00:23:59 +03:00
										 |  |  |         $tour_info | 
					
						
							|  |  |  |     rm ${tour_info}.orig | 
					
						
							| 
									
										
										
										
											2014-12-14 15:33:34 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     git --git-dir=${REPO_DIR}/.git add $tour_info | 
					
						
							| 
									
										
										
										
											2014-05-09 14:38:59 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-13 20:05:13 +03:00
										 |  |  | function game_get_result { | 
					
						
							| 
									
										
										
										
											2014-12-13 23:10:14 +03:00
										 |  |  |     local res_index=0 | 
					
						
							| 
									
										
										
										
											2014-12-13 20:05:13 +03:00
										 |  |  |     while read ply_fst ply_snd; do | 
					
						
							|  |  |  |         local pgn=${TMP_PGN_FILES[$res_index]} | 
					
						
							|  |  |  |         local res=$(sed -En "s/\[Result \"([^\"]*)\"\]/\1/p" $pgn) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if [[ $res == 1/2-1/2 ]]; then | 
					
						
							|  |  |  |             # Representation of draw | 
					
						
							| 
									
										
										
										
											2015-01-01 13:54:56 +03:00
										 |  |  |             res="½-½" | 
					
						
							| 
									
										
										
										
											2014-12-13 20:05:13 +03:00
										 |  |  |         elif [[ $ply_fst != $white ]]; then | 
					
						
							|  |  |  |             res=$(rev <<< $res) | 
					
						
							|  |  |  |         fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         result+=" $res" | 
					
						
							| 
									
										
										
										
											2014-12-13 23:10:14 +03:00
										 |  |  |         (( res_index += 1 )) | 
					
						
							| 
									
										
										
										
											2014-12-14 11:06:47 +03:00
										 |  |  |     done <<< "$(echo -e "$ply_names")" | 
					
						
							| 
									
										
										
										
											2014-12-13 20:05:13 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $ADD_GAMES && [[ -n $res_old ]] && result=" ${res_old}${result}" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  | function game_git_commit { | 
					
						
							| 
									
										
										
										
											2014-12-12 21:09:28 +03:00
										 |  |  |     local title=$(awk '{print toupper(substr($0,1,1)) tolower(substr($0,2))}' \ | 
					
						
							|  |  |  |                       <<< ${TOURNAMENT##*-}) | 
					
						
							| 
									
										
										
										
											2014-12-14 15:33:34 +03:00
										 |  |  |     local git_message="Tournament ${title}, tour ${TOUR#0}: " | 
					
						
							|  |  |  |     if $ADD_GAMES; then | 
					
						
							|  |  |  |         git_message+="add" | 
					
						
							|  |  |  |     elif $CLEANUP_GAMES; then | 
					
						
							|  |  |  |         git_message+="replace" | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         git_message+="new" | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  |     git_message+=" games ${white} vs. ${black}." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     git --git-dir=${REPO_DIR}/.git commit -m "$git_message" | 
					
						
							| 
									
										
										
										
											2014-12-07 00:23:59 +03:00
										 |  |  |     git --git-dir=${REPO_DIR}/.git push | 
					
						
							| 
									
										
										
										
											2014-05-09 20:24:14 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  | function die { | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  |     echo "$@" >&2 | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     exit 1 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-15 20:39:07 +03:00
										 |  |  | function game_tour { | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  |     [[ $OPTARG =~ ^[0-9]+$ ]] || die "Incorrect tour number." | 
					
						
							|  |  |  |     TOUR=$(printf "%02g" $OPTARG) | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  | ADD_GAMES=false | 
					
						
							|  |  |  | CLEANUP_GAMES=false | 
					
						
							| 
									
										
										
										
											2014-09-29 13:18:47 +04:00
										 |  |  | SORT_GAMES=true | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  | while getopts act:uhv opt; do | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  |     case $opt in | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |         a) ADD_GAMES=true     ;; | 
					
						
							|  |  |  |         c) CLEANUP_GAMES=true ;; | 
					
						
							| 
									
										
										
										
											2014-12-15 20:39:07 +03:00
										 |  |  |         t) game_tour          ;; | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  |         u) SORT_GAMES=false   ;; | 
					
						
							|  |  |  |         h) usage              ;; | 
					
						
							|  |  |  |         v) version            ;; | 
					
						
							|  |  |  |         *) usage 1            ;; | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  |     esac | 
					
						
							|  |  |  | done | 
					
						
							|  |  |  | shift $(($OPTIND - 1)) | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-15 20:39:07 +03:00
										 |  |  | game_check_args $@ | 
					
						
							| 
									
										
										
										
											2014-08-31 00:44:06 +04:00
										 |  |  | game_setup | 
					
						
							| 
									
										
										
										
											2014-12-13 20:05:13 +03:00
										 |  |  | declare -a TMP_PGN_FILES | 
					
						
							| 
									
										
										
										
											2014-11-28 16:11:24 +03:00
										 |  |  | game_tmp_pgns $@ | 
					
						
							| 
									
										
										
										
											2014-12-10 23:09:24 +03:00
										 |  |  | game_get_info | 
					
						
							| 
									
										
										
										
											2014-12-06 18:01:41 +03:00
										 |  |  | game_store_pgns | 
					
						
							| 
									
										
										
										
											2014-12-07 00:23:59 +03:00
										 |  |  | game_update_info | 
					
						
							| 
									
										
										
										
											2014-05-09 20:24:14 +03:00
										 |  |  | game_git_commit | 
					
						
							| 
									
										
										
										
											2014-05-08 16:46:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | exit 0 |