279 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			279 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/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.3"
 | 
						||
 | 
						||
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
 | 
						||
                # PLAYER is a part of 'game_url' or 'result'
 | 
						||
                [[ "$name" =~ ^http:\/\/ || "$name" =~ ^(1-0|0-1|1\/2)$ ]] && continue
 | 
						||
 | 
						||
                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
 |