lorchess/schedule

293 lines
9.0 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env bash
# Copyright 2014 Vladimir Ivanov <ivvl82@gmail.com>
# Distributed under the terms of the GNU General Public License v2
# REPO_DIR="https://github.com/fat0troll/lorchess"
REPO_DIR=`dirname "$0"`
# Specify the tournament here
TOURNAMENT=
# Version information
VERSION="0.5"
argv0=${0##*/}
function 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; its default
value of \`dirname \$0\` can be replaced by 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
exit "${1:-0}"
}
function version {
exec echo "${argv0}-${VERSION}"
}
function setup_repo {
CURL_OPTS="-q --fail --location --silent"
# If no tournament given, set it to the last one
if [[ -z $TOURNAMENT ]]; then
if [[ $REPO_DIR =~ ^https://github\.com/(.*) ]]; then
REPO_NAME=${BASH_REMATCH[1]}
local year=$(curl $CURL_OPTS \
https://api.github.com/repos/${REPO_NAME}/contents \
| sed -En "/\"path\":/h;/\"type\": \"dir\"/{g;p;}" \
| sed -En "s|.*\"([0-9]{4})\".*|\1|p" | tail -1)
TOURNAMENT=$(curl $CURL_OPTS \
https://api.github.com/repos/${REPO_NAME}/contents/${year} \
| sed -En "/\"path\":/h;/\"type\": \"dir\"/{g;p;}" \
| sed -En "s|.*\"(${year}/[0-9]-.*)\".*|\1|p" | tail -1)
else
# Convert REPO_DIR to an absolute path
[[ $REPO_DIR =~ ^/ ]] || REPO_DIR=$(cd ${REPO_DIR}; pwd)
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 \
| sed -E "s|${REPO_DIR}/(.*)|\1|")
# Remove the trailing slash
TOURNAMENT=${TOURNAMENT%/}
fi
fi
}
function show_tour_sequence {
local tour_seq=$@
# If no tour sequence given, set it to all tours
if [[ -z $tour_seq ]]; then
2014-09-02 20:40:08 +04:00
if [[ $REPO_DIR =~ ^https://github\.com/ ]]; then
tour_seq=$(curl $CURL_OPTS \
https://api.github.com/repos/${REPO_NAME}/contents/${TOURNAMENT}/tours \
| sed -En "/\"path\":/h;/\"type\": \"dir\"/{g;p;}" \
| sed -En "s|.*\"${TOURNAMENT}/tours/([0-9]{2})\".*|\1|p")
else
tour_seq=$(ls -1 -d ${REPO_DIR}/${TOURNAMENT}/tours/[0-9][0-9]/ \
| sed -E "s|${REPO_DIR}/${TOURNAMENT}/tours/([0-9]{2})/|\1|")
fi
fi
for tour in $tour_seq; do
# Change tour numbers: '1' -> '01', '2' -> '02', and so on
tour=$(printf "%02g" $tour)
# *NOTE* The incorporation of a newline at the end of
# 'tour_info' is important and allows one to read the last
# line with no trailing '\n'
2014-09-02 20:40:08 +04:00
if [[ $REPO_DIR =~ ^https://github\.com/ ]]; then
local tour_info=$(curl $CURL_OPTS --write-out '\n' \
${REPO_DIR}/raw/master/${TOURNAMENT}/tours/${tour}/tour_info)
[[ -n $tour_info ]] && output_tour_info
else
local info_file=${REPO_DIR}/${TOURNAMENT}/tours/${tour}/tour_info
if [[ -f $info_file ]]; then
local tour_info=$(cat $info_file; echo)
output_tour_info
fi
fi
done
}
function output_tour_info {
2014-09-02 20:40:08 +04:00
local date_re="([0-9?]{2})\.([0-9?]{2})\.([0-9?]{4})"
local white= black= result= game_date=
# Lines with game info
local output_lines=
while read line; do
2014-04-30 23:38:43 +04:00
# Read 'tour_num'
2014-09-02 20:40:08 +04:00
if [[ -z $tour_num ]]; then
[[ $line =~ ^"Тур №"([0-9]+) ]] && local tour_num=${BASH_REMATCH[1]}
continue
fi
2014-04-30 23:38:43 +04:00
# Read 'date_beg' and 'date_end'
2014-09-02 20:40:08 +04:00
if [[ -z $date_beg || -z $date_end ]]; then
if [[ $line =~ ^"Время проведения:"\ +$date_re\ +-\ +$date_re ]]; then
# Use short dates
local date_beg=${BASH_REMATCH[1]}.${BASH_REMATCH[2]}
local date_end=${BASH_REMATCH[4]}.${BASH_REMATCH[5]}
fi
continue
fi
# Keep game info if needed, and store it in variables 'white',
# 'black', 'result', and 'game_date'
2014-09-02 20:40:08 +04:00
if keep_game_info; then
output_lines+=$(sed -E "s/^$date_re\ +//" <<< "$line")
# Append the link of game to the end of output line
if $SHOW_LINK; then
2014-09-02 20:40:08 +04:00
[[ -n $result ]] && append_game_url
fi
2014-09-02 20:40:08 +04:00
output_lines+="\n"
fi
done <<< "$tour_info"
[[ -n $output_lines ]] && eval "info_output_$FORMAT \"${output_lines}\""
}
function keep_game_info {
local res_re="(1|1/2|0)-(1|1/2|0)"
2014-09-02 20:40:08 +04:00
local keep=1
2014-09-02 20:40:08 +04:00
if [[ $line =~ ^$date_re\ +([^\ ]+)\ +-\ +([^\ ]+)(\ +$res_re)? ]]; then
white=${BASH_REMATCH[4]} black=${BASH_REMATCH[5]} result=${BASH_REMATCH[6]// /}
game_date=${BASH_REMATCH[3]}-${BASH_REMATCH[2]}-${BASH_REMATCH[1]}
# 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
}
2014-09-02 20:40:08 +04:00
function append_game_url {
2014-04-30 23:38:43 +04:00
local tour=$(printf "%02g" "$tour_num")
local game_dir=${game_date}-${white}-vs-${black}
2014-09-02 20:40:08 +04:00
if [[ $REPO_DIR =~ ^https://github\.com/ ]]; then
local pgn_text=$(curl $CURL_OPTS \
${REPO_DIR}/raw/master/${TOURNAMENT}/tours/${tour}/${game_dir}/1.pgn)
else
local pgn_text=$(cat ${REPO_DIR}/${TOURNAMENT}/tours/${tour}/${game_dir}/1.pgn)
fi
local game_url=$(echo "$pgn_text" | grep -Eo "\[Site \"[a-z]+:[^\"]+\"\]" \
| sed -E "s/\[Site \"([a-z]+:[^\"]+)\"\]/\1/")
output_lines+=" $game_url"
}
function 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
# PLAYER is a part of 'game_url' or 'result'
[[ $name =~ ^http:// || $name =~ ^(1-0|1/2-1/2|0-1|)$ ]] && continue
2014-04-27 19:34:14 +04:00
line=$(sed -E "s/(${name})/$(tput setaf 1)\1$(tput sgr0)/g" <<< "$line")
done
fi
# Highlight result
line=$(sed -E "s/ (1-0|1\/2-1\/2|0-1)( |$)/ $(tput setaf 6)\1$(tput sgr0)\2/g" <<< "$line")
echo "$line"
done
echo
}
function info_output_lor {
echo "[b]${tour_num} тур (${date_beg} - ${date_end})[/b]"
echo "[list]"
2014-09-02 20:40:08 +04:00
echo -en "$1" | while read white hyphen black result url; do
[[ -n $url ]] && result="[url=${url}]${result}[/url]"
echo " [*] [user]${white}[/user] - [user]${black}[/user] ${result}"
done
echo "[/list]"
echo
}
function info_output_html {
2014-03-27 19:31:56 +04:00
echo "<div class=\"tour-info\">"
echo " <table class=\"table table-condensed\">"
2014-03-27 19:31:56 +04:00
echo " <caption>"
echo " <strong>${tour_num} тур (${date_beg} - ${date_end})</strong>"
echo " </caption>"
echo " <tbody>"
2014-09-02 20:40:08 +04:00
echo -en "$1" | while read white hyphen black result url; do
[[ -n $url ]] && result="<a href=\"${url}\">${result}</a>"
2014-03-27 19:31:56 +04:00
echo " <tr>"
echo " <td>${white} - ${black}</td><td class=\"result\">${result}</td>"
2014-03-27 19:31:56 +04:00
echo " </tr>"
done
echo " </tbody>"
echo " </table>"
echo "</div>"
echo
}
function die {
echo "$@" 1>&2
exit 1
}
function checkargs {
[[ $OPTARG =~ ^-[apflhv]$ ]] && die "Option -${opt}: argument not found"
[[ $opt == f && ! $OPTARG =~ ^(term|html|lor)$ ]] && die "Incorrect FORMAT specified"
}
FORMAT=term
SHOW_ALL=false
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
;;
v) version
;;
*) usage 1
;;
esac
done
2013-09-26 00:11:13 +04:00
shift $(($OPTIND - 1))
setup_repo
show_tour_sequence $@
2013-09-26 00:11:13 +04:00
exit 0