lorchess/schedule

276 lines
7.8 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# Copyright 2014 Vladimir Ivanov <ivvl82@gmail.com>
# Distributed under the terms of the GNU General Public License v2
REPO="https://raw.githubusercontent.com/fat0troll/lorchess/master"
TOURNAMENT="2014/1-tabiyas"
# Version information
VERSION="0.2"
argv0=${0##*/}
usage() {
cat <<EOF
List games on tours of tournament
Usage: $argv0 [options] [tours]
Tournament tours are restricted to sequence \`tours' given in
Bash-style syntax, i.e., \`tours' may include explicit numbers
(tours=1 3), intervals (tours={1..5}), or any combination of them.
If no tours are specified, display each tour until an empty
\`tour_info' is found. By default, only unaccomplished games are
listed.
Inner variable REPO points to the root of repository; REPO is a URL
link, absolute or relative path. Inner variable TOURNAMENT specifies
the sub-directory of tournament.
Options:
-a List accomplished games too
-p PLAYER Show game if PLAYER is a part of a player's name
-f FORMAT Specify the output format; FORMAT is \`term'
(default), \`html', or \`lor'
-l Add the URL link to game (if accomplished)
-h Show this help output
-v Show version information
EOF
}
version() {
echo "${argv0}-${VERSION}"
}
show_tour_sequence() {
local sequence
# Generate the sequence of tours to search in
if [[ -z "$@" ]]; then
sequence=$(seq -f "%02g" 1 99)
else
# Change tour numbers: '1' -> '01', '2' -> '02', and so on
sequence=$(for i in "$@"; do printf "%02g " "$i"; done)
fi
for tour in $sequence; do
convert_repo_url
local base_url="${REPO}/${TOURNAMENT}"
local info_url="${base_url}/tours/${tour}/tour_info"
# *NOTE* The incorporation of a newline at the end of
# 'tour_info' (--write-out '\n') is important and allows one
# to read the last line with no trailing '\n'
local tour_info="$(curl -q --fail --silent --write-out '\n' $info_url)"
# Produce output only if 'tour_info' exists
if [[ -n "$tour_info" ]]; then
local tour_num date_beg date_end
local white black result game_date game_url
# Lines with game info
local output_lines=""
while read line; do
get_tour_num "$line" && continue
get_tour_dates "$line" && continue
# Keep game info if needed, and store it in variables
# 'while', 'black', 'result', and 'game_date'
if keep_game_info "$line"; then
# Fix result
case "$result" in
1:0) result="1-0" ;;
0:1) result="0-1" ;;
0.5:0.5) result="1/2" ;;
esac
# Store the link to game in 'game_url'
game_url=""
if $SHOW_LINK; then
[[ -n "$result" ]] && store_game_url
fi
output_lines+="${white} ${black} ${result} ${game_url}\n"
fi
done <<< "$tour_info"
[[ -n "$output_lines" ]] && eval "info_output_$FORMAT \"${output_lines}\""
else
# If the tour numbers were not passed as arguments, exit
# once the first non-existing 'tour_info' is reached
[[ -z "$@" ]] && break
fi
done
}
convert_repo_url() {
if [[ ! "$REPO" =~ ^(https?|file):// ]]; then
if [[ ! "$REPO" =~ ^/ ]]; then
# REPO is a relative path
base_dir="$(dirname $0)"
REPO="$(cd ${base_dir}/${REPO}; pwd)"
fi
REPO="file://${REPO}"
fi
}
get_tour_num() {
if [[ "$1" =~ "Тур №"([0-9]+) ]]; then
tour_num="${BASH_REMATCH[1]}"
return 0
else
return 1
fi
}
get_tour_dates() {
local date_re="[0-9?]{2}\\.[0-9?]{2}\\.[0-9?]{4}"
if [[ "$1" =~ "Время проведения:"' '*($date_re)' '*[-—]' '*($date_re) ]]; then
date_beg="${BASH_REMATCH[1]}" date_end="${BASH_REMATCH[2]}"
# Use short dates
date_beg="${date_beg:0:5}" date_end="${date_end:0:5}"
return 0
else
return 1
fi
}
keep_game_info() {
local date_re="([0-9?]{2})\\.([0-9?]{2})\\.([0-9?]{4})"
local res_re="(0|1|0\\.5):(0|1|0\\.5)"
local line="$1" keep=1
if [[ "$line" =~ ($date_re)' '*[-—]' '*([^' ']+)' '*($res_re)?' '*([^' ']+) ]]; then
white="${BASH_REMATCH[5]}"
black="${BASH_REMATCH[9]}"
result="${BASH_REMATCH[6]}"
game_date="${BASH_REMATCH[4]}-${BASH_REMATCH[3]}-${BASH_REMATCH[2]}"
# If the player was passed as an argument, check if it is his game or not
if [[ -z "$PLAYER" || "$white" =~ "$PLAYER" || "$black" =~ "$PLAYER" ]]; then
if $SHOW_ALL; then
keep=0
else
# Keep line if the game is not finished
[[ -z "$result" ]] && keep=0
fi
fi
fi
return $keep
}
store_game_url() {
local tour=$(printf "%02g" "$tour_num")
local game_dir="${game_date}-${white}-vs-${black}"
local pgn_url="${base_url}/tours/${tour}/${game_dir}/1.pgn"
while read line; do
# Search for a URL inside PGN file
[[ "$line" =~ "[Site \""([a-z]+:[^\"]+)"\"]" ]]
game_url="${BASH_REMATCH[1]}"
[[ -n "$game_url" ]] && break
done <<< "$(curl -q --fail --silent $pgn_url)"
}
info_output_term() {
echo -n "$(tput setaf 2)${tour_num} тур "
echo "$(tput setaf 6)(${date_beg} - ${date_end})$(tput sgr0)"
echo -en "$1" | column -t | while IFS= read line; do
# Highlight player's name
if [[ -n "$PLAYER" ]]; then
players=$(grep -o "[^ ]*${PLAYER}[^ ]*" <<< "$line")
for name in $players; do
line=$(sed -E "s/(${name})/\\$(tput setaf 1)\1\\$(tput sgr0)/g" <<< "$line")
done
fi
# Highlight result
line=$(sed -E "s/(1-0|0-1|1\\/2)/\\$(tput setaf 6)\1\\$(tput sgr0)/g" <<< "$line")
echo "$line"
done
echo
}
info_output_lor() {
echo "[b]${tour_num} тур (${date_beg} - ${date_end})[/b]"
echo "[list]"
echo -en "$1" | while read white black result url; do
[[ -n "$url" ]] && result="[url=${url}]${result}[/url]"
echo " [*] [user]${white}[/user] - [user]${black}[/user] ${result}"
done
echo "[/list]"
echo
}
info_output_html() {
echo "<div class=\"tour-info\">"
echo " <table class=\"table table-condensed\">"
echo " <caption>"
echo " <strong>${tour_num} тур (${date_beg} - ${date_end})</strong>"
echo " </caption>"
echo " <tbody>"
echo -en "$1" | while read white black result url; do
[[ -n "$url" ]] && result="<a href=\"${url}\">${result}</a>"
echo " <tr>"
echo " <td>${white} - ${black}</td><td class=\"result\">${result}</td>"
echo " </tr>"
done
echo " </tbody>"
echo " </table>"
echo "</div>"
echo
}
checkargs() {
if [[ "$OPTARG" =~ ^-[apflhv]$ ]]; then
echo "Option -${opt}: argument not found"
exit 1
fi
if [[ "$opt" == f && ! "$OPTARG" =~ ^(term|html|lor)$ ]]; then
echo "Incorrect FORMAT specified"
exit 1
fi
}
SHOW_ALL=false
PLAYER=""
FORMAT=term
SHOW_LINK=false
while getopts "ap:f:lhv" opt; do
case "$opt" in
a) SHOW_ALL=true
;;
p) checkargs
PLAYER="$OPTARG"
;;
f) checkargs
FORMAT="$OPTARG"
;;
l) SHOW_LINK=true
;;
h) usage && exit 0
;;
v) version && exit 0
;;
esac
done
shift $(($OPTIND - 1))
show_tour_sequence "$@"
exit 0