Script 'game-add': small but useful improvements made.
This commit is contained in:
parent
75363e622c
commit
42f22c274e
151
game-add
151
game-add
@ -20,7 +20,7 @@ function usage {
|
|||||||
Store chess games played on lichess.org
|
Store chess games played on lichess.org
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
$argv0 [options] -t <num> [<url>]
|
$argv0 [options] -t <num> <url>...
|
||||||
$argv0 -h
|
$argv0 -h
|
||||||
$argv0 -v
|
$argv0 -v
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ Usage:
|
|||||||
inner variable REPO_DIR to it. If the tournament is not the last one
|
inner variable REPO_DIR to it. If the tournament is not the last one
|
||||||
(default), store its sub-directory in inner variable TOURNAMENT.
|
(default), store its sub-directory in inner variable TOURNAMENT.
|
||||||
|
|
||||||
The first form fills the results of chess games and stores its PGN
|
The first form fills the results of chess games and stores their PGN
|
||||||
files, assuming that all the games were played by the same pair of
|
files, assuming that all the games were played by the same pair of
|
||||||
players on tour <num> of the tournament. The PGN files are sorted by
|
players on tour <num> of the tournament. The PGN files are sorted by
|
||||||
their timestamps, unless '-u' is set. Each game should be available
|
their timestamps, unless '-u' is set. Each game should be available
|
||||||
@ -100,12 +100,47 @@ function game_tmp_pgns {
|
|||||||
$SORT_GAMES && TMP_PGN_FILES=$(xargs -n1 <<< "$TMP_PGN_FILES" | sort | xargs)
|
$SORT_GAMES && TMP_PGN_FILES=$(xargs -n1 <<< "$TMP_PGN_FILES" | sort | xargs)
|
||||||
}
|
}
|
||||||
|
|
||||||
function game_get_players {
|
function game_get_info {
|
||||||
# Make an associative array from Lichess nicks to players' names
|
# Get the names of players, whose games are in PGN files
|
||||||
declare -A NAMES=()
|
|
||||||
game_assoc_names
|
|
||||||
|
|
||||||
local ply_names=
|
local ply_names=
|
||||||
|
game_get_names
|
||||||
|
|
||||||
|
# Select the names of two players
|
||||||
|
local players=( $(echo -en "$ply_names" | sort -u) )
|
||||||
|
[[ ${#players[@]} == 2 ]] || die "Players of the games are not the same."
|
||||||
|
|
||||||
|
# Find the white and black players
|
||||||
|
local line0=$(grep " ${players[0]} " $tour_info)
|
||||||
|
local line1=$(grep " ${players[1]} " $tour_info)
|
||||||
|
[[ $line0 == $line1 ]] \
|
||||||
|
|| die "No game between ${players[0]} and ${players[1]} found in ${tour_info}."
|
||||||
|
[[ $line0 =~ ^((${date_re})\ +([^\ ]+)\ +-\ +([^\ ]+))(.*)$ ]]
|
||||||
|
white=${BASH_REMATCH[3]}
|
||||||
|
black=${BASH_REMATCH[4]}
|
||||||
|
|
||||||
|
# Additional information about the game record
|
||||||
|
rec_length=${#BASH_REMATCH[1]}
|
||||||
|
game_date=${BASH_REMATCH[2]}
|
||||||
|
res_old=$(xargs <<< ${BASH_REMATCH[5]})
|
||||||
|
game_validate
|
||||||
|
|
||||||
|
if ! $ADD_GAMES || [[ $game_date =~ \? ]]; then
|
||||||
|
local fst_pgn=$(awk '{print $1}' <<< "$TMP_PGN_FILES")
|
||||||
|
local date=$(sed -En "s/\[Date \"([^\"]*)\"\]/\1/p" $fst_pgn)
|
||||||
|
game_date=${date:8:2}.${date:5:2}.${date::4}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function game_get_names {
|
||||||
|
# Make an associative array from Lichess nicks to players' names
|
||||||
|
game_parse_config
|
||||||
|
local sections=$(grep -o "config_section_player[0-9]*" $tmp_ini)
|
||||||
|
declare -A NAMES=()
|
||||||
|
for sect in $sections; do
|
||||||
|
eval $sect
|
||||||
|
NAMES+=( [$lichess]=$name )
|
||||||
|
done
|
||||||
|
|
||||||
for pgn in $TMP_PGN_FILES; do
|
for pgn in $TMP_PGN_FILES; do
|
||||||
# Extract players on Lichess
|
# Extract players on Lichess
|
||||||
local wt_lichess=$(sed -En "s/\[White \"([^\"]*)\"\]/\1/p" $pgn)
|
local wt_lichess=$(sed -En "s/\[White \"([^\"]*)\"\]/\1/p" $pgn)
|
||||||
@ -114,29 +149,6 @@ function game_get_players {
|
|||||||
game_add_player $wt_lichess
|
game_add_player $wt_lichess
|
||||||
game_add_player $bk_lichess
|
game_add_player $bk_lichess
|
||||||
done
|
done
|
||||||
|
|
||||||
# Select the names of two players
|
|
||||||
local players=( $(echo -en "$ply_names" | sort -u) )
|
|
||||||
[[ ${#players[@]} == 2 ]] || die "Players of the games are not the same."
|
|
||||||
|
|
||||||
# Find the white and black players
|
|
||||||
local line=$(grep -E "( ${players[0]} | ${players[1]} )" $tour_info)
|
|
||||||
[[ -n $line && $(wc -l <<< "$line") == 1 ]] \
|
|
||||||
|| die "No game between ${players[0]} and ${players[1]} found in ${tour_info}."
|
|
||||||
[[ $line =~ ^${date_re}\ +([^\ ]+)\ +-\ +([^\ ]+)(.*)$ ]]
|
|
||||||
white=${BASH_REMATCH[1]}
|
|
||||||
black=${BASH_REMATCH[2]}
|
|
||||||
res_old=$(xargs <<< ${BASH_REMATCH[3]})
|
|
||||||
game_validate
|
|
||||||
}
|
|
||||||
|
|
||||||
function game_assoc_names {
|
|
||||||
game_parse_config
|
|
||||||
local sections=$(grep -o "config_section_player[0-9]*" $tmp_ini)
|
|
||||||
for sect in $sections; do
|
|
||||||
eval $sect
|
|
||||||
NAMES+=( [$lichess]=$name )
|
|
||||||
done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function game_parse_config {
|
function game_parse_config {
|
||||||
@ -167,8 +179,8 @@ function game_add_player {
|
|||||||
local lichess_ply=$1
|
local lichess_ply=$1
|
||||||
local ply=${NAMES[$lichess_ply]}
|
local ply=${NAMES[$lichess_ply]}
|
||||||
while [[ ! " ${NAMES[@]} " =~ \ $ply\ ]]; do
|
while [[ ! " ${NAMES[@]} " =~ \ $ply\ ]]; do
|
||||||
echo "The list of players:"
|
echo -n "The list of players:"
|
||||||
echo "${NAMES[@]}" | tr ' ' '\n' | sed "s/^/$(tput setaf 6)*$(tput sgr0) /"
|
sed "s/ /\\"$'\n'"$(tput setaf 6)*$(tput sgr0) /g" <<< " ${NAMES[@]}"
|
||||||
echo -n "Type the name of ${lichess_ply}> "
|
echo -n "Type the name of ${lichess_ply}> "
|
||||||
read ply
|
read ply
|
||||||
done
|
done
|
||||||
@ -177,21 +189,25 @@ function game_add_player {
|
|||||||
|
|
||||||
function game_validate {
|
function game_validate {
|
||||||
# By default, other games between the players are not allowed
|
# By default, other games between the players are not allowed
|
||||||
if [[ -n $res_old ]]; then
|
if ! $ADD_GAMES && ! $CLEANUP_GAMES; then
|
||||||
$ADD_GAMES || $CLEANUP_GAMES || die "Results of some games already stored."
|
if ! [[ $game_date =~ \? && -z $res_old ]]; then
|
||||||
local index=$(wc -w <<< "$res_old")
|
die "Some games between ${white} and ${black} already recorded."
|
||||||
else
|
fi
|
||||||
local index=0
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Players' sides should interchange
|
# Players' sides should interchange
|
||||||
local length=$(echo -en "$ply_names" | wc -l)
|
local length=$(echo -en "$ply_names" | wc -l)
|
||||||
local ply_ordered=
|
if $ADD_GAMES && [[ -n $res_old ]]; then
|
||||||
for ((i = index; i < length; i++)); do
|
local residue=$(( $(wc -w <<< "$res_old") % 2 ))
|
||||||
if (( i % 2 == 1 )); then
|
|
||||||
ply_ordered="${white}\n${black}\n"
|
|
||||||
else
|
else
|
||||||
ply_ordered="${black}\n${white}\n"
|
local residue=0
|
||||||
|
fi
|
||||||
|
local ply_ordered=
|
||||||
|
for ((i = 0; i < length; i++)); do
|
||||||
|
if (( i % 2 == residue )); then
|
||||||
|
ply_ordered+="${white}\n"
|
||||||
|
else
|
||||||
|
ply_ordered+="${black}\n"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
if [[ "$ply_names" != "$ply_ordered" ]]; then
|
if [[ "$ply_names" != "$ply_ordered" ]]; then
|
||||||
@ -203,7 +219,6 @@ function game_validate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function game_store_pgns {
|
function game_store_pgns {
|
||||||
local pgn_index=0
|
|
||||||
game_dir=$(ls -1 -d 2>/dev/null \
|
game_dir=$(ls -1 -d 2>/dev/null \
|
||||||
${REPO_DIR}/${TOURNAMENT}/tours/${TOUR}/*-${white}-vs-${black})
|
${REPO_DIR}/${TOURNAMENT}/tours/${TOUR}/*-${white}-vs-${black})
|
||||||
if $CLEANUP_GAMES && [[ -n $game_dir ]]; then
|
if $CLEANUP_GAMES && [[ -n $game_dir ]]; then
|
||||||
@ -211,46 +226,29 @@ function game_store_pgns {
|
|||||||
game_dir=
|
game_dir=
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local pgn_index=0
|
||||||
if [[ -z $game_dir ]]; then
|
if [[ -z $game_dir ]]; then
|
||||||
# Get the game date
|
local date=${game_date:6:4}-${game_date:3:2}-${game_date::2}
|
||||||
date=
|
game_dir=${REPO_DIR}/${TOURNAMENT}/tours/${TOUR}/${date}-${white}-vs-${black}
|
||||||
game_get_date
|
|
||||||
game_date=$(tr '.' '-' <<< "$date")
|
|
||||||
|
|
||||||
game_dir=${REPO_DIR}/${TOURNAMENT}/tours/${TOUR}/${game_date}-${white}-vs-${black}
|
|
||||||
echo "Creating directory ${game_dir}..."
|
echo "Creating directory ${game_dir}..."
|
||||||
mkdir "$game_dir"
|
mkdir "$game_dir"
|
||||||
else
|
else
|
||||||
$ADD_GAMES || die "Directory ${game_dir} already exist."
|
$ADD_GAMES || die "Directory ${game_dir} already exist."
|
||||||
local old_pgns=$(ls -1 -p 2>/dev/null ${game_dir}/[0-9]*.pgn | grep -v "/$")
|
local old_pgns=$(ls -1 -p 2>/dev/null ${game_dir}/*.pgn)
|
||||||
[[ -n $old_pgns ]] && pgn_index=$(wc -l <<< "$old_pgns")
|
[[ -n $old_pgns ]] && pgn_index=$(wc -l <<< "$old_pgns")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for pgn in $TMP_PGN_FILES; do
|
for pgn in $TMP_PGN_FILES; do
|
||||||
(( pgn_index += 1 ))
|
(( pgn_index += 1 ))
|
||||||
|
echo "Storing file ${game_dir}/${pgn_index}.pgn..."
|
||||||
cp $pgn ${game_dir}/${pgn_index}.pgn
|
cp $pgn ${game_dir}/${pgn_index}.pgn
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function game_get_date {
|
|
||||||
local fst_pgn others
|
|
||||||
read fst_pgn others <<< "$TMP_PGN_FILES"
|
|
||||||
date=$(sed -En "s/\[Date \"([^\"]*)\"\]/\1/p" $fst_pgn)
|
|
||||||
}
|
|
||||||
|
|
||||||
function game_update_info {
|
function game_update_info {
|
||||||
local length_max=0
|
|
||||||
while read line; do
|
|
||||||
[[ $line =~ ^((${date_re})\ +([^\ ]+)\ +-\ +([^\ ]+)) ]]
|
|
||||||
|
|
||||||
# Get the maximal length of game records, excepting results
|
# Get the maximal length of game records, excepting results
|
||||||
local length=${#BASH_REMATCH[1]}
|
local length_max=$(grep -Eo "^${date_re} +[^ ]+ +- +[^ ]+" $tour_info \
|
||||||
(( $length > $length_max )) && length_max=$length
|
| awk '{print length}' | sort -nr | head -1)
|
||||||
|
|
||||||
if [[ ${BASH_REMATCH[3]} == $white && ${BASH_REMATCH[4]} == $black ]]; then
|
|
||||||
local length_rec=${#BASH_REMATCH[1]} game_date=${BASH_REMATCH[2]}
|
|
||||||
fi
|
|
||||||
done < $tour_info
|
|
||||||
|
|
||||||
local result=
|
local result=
|
||||||
for pgn in $TMP_PGN_FILES; do
|
for pgn in $TMP_PGN_FILES; do
|
||||||
@ -258,18 +256,11 @@ function game_update_info {
|
|||||||
[[ $res == 1/2-1/2 ]] && res=1/2 # representation of a draw
|
[[ $res == 1/2-1/2 ]] && res=1/2 # representation of a draw
|
||||||
result+=" $res"
|
result+=" $res"
|
||||||
done
|
done
|
||||||
|
$ADD_GAMES && [[ -n $res_old ]] && result=" ${res_old}${result}"
|
||||||
|
|
||||||
if $ADD_GAMES && [[ -n $res_old ]]; then
|
local spaces=$(( length_max - rec_length ))
|
||||||
result=" ${res_old}${result}"
|
|
||||||
else
|
|
||||||
date=
|
|
||||||
game_get_date
|
|
||||||
game_date=${date:8:2}.${date:5:2}.${date::4}
|
|
||||||
fi
|
|
||||||
|
|
||||||
local spaces=$(( length_max - length_rec ))
|
|
||||||
local sep=$(printf "%${spaces}s" " ")
|
local sep=$(printf "%${spaces}s" " ")
|
||||||
echo "Updating ${tour_info}..."
|
echo "Updating file ${tour_info}..."
|
||||||
sed -E -i.orig \
|
sed -E -i.orig \
|
||||||
"s|^${date_re}( +${white} +- +${black}).*|${game_date}\1${sep}${result}|" \
|
"s|^${date_re}( +${white} +- +${black}).*|${game_date}\1${sep}${result}|" \
|
||||||
$tour_info
|
$tour_info
|
||||||
@ -277,7 +268,7 @@ function game_update_info {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function game_git_commit {
|
function game_git_commit {
|
||||||
git --git-dir=${REPO_DIR}/.git add ${game_dir}/[0-9]*.pgn $tour_info
|
git --git-dir=${REPO_DIR}/.git add ${game_dir}/*.pgn $tour_info
|
||||||
git --git-dir=${REPO_DIR}/.git commit -m "Tour ${TOUR#0}: ${white} vs. ${black}."
|
git --git-dir=${REPO_DIR}/.git commit -m "Tour ${TOUR#0}: ${white} vs. ${black}."
|
||||||
git --git-dir=${REPO_DIR}/.git push
|
git --git-dir=${REPO_DIR}/.git push
|
||||||
}
|
}
|
||||||
@ -310,11 +301,13 @@ done
|
|||||||
shift $(($OPTIND - 1))
|
shift $(($OPTIND - 1))
|
||||||
# For now, tour number should be given explicitly
|
# For now, tour number should be given explicitly
|
||||||
[[ -z $TOUR || $# == 0 ]] && usage 1
|
[[ -z $TOUR || $# == 0 ]] && usage 1
|
||||||
|
# Don't add and clean up games simultaneously
|
||||||
|
$ADD_GAMES && $CLEANUP_GAMES && usage 1
|
||||||
|
|
||||||
game_setup
|
game_setup
|
||||||
git --git-dir=${REPO_DIR}/.git pull # synchronize the repository
|
git --git-dir=${REPO_DIR}/.git pull # synchronize the repository
|
||||||
game_tmp_pgns $@
|
game_tmp_pgns $@
|
||||||
game_get_players
|
game_get_info
|
||||||
game_store_pgns
|
game_store_pgns
|
||||||
game_update_info
|
game_update_info
|
||||||
game_git_commit
|
game_git_commit
|
||||||
|
Loading…
Reference in New Issue
Block a user