diff --git a/.gitignore b/.gitignore index 5ceb3864c2911029f0a6010fadab352e4b8e2d07..7f93ebf8528206935415e66e1586654106ea434a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ venv +__pycache__ diff --git a/app.py b/app.py index 71d186343d407836002fdda0752c8ecfcef21473..a49bd990ec6c3bcc9ea202bd25fece5d715a6471 100644 --- a/app.py +++ b/app.py @@ -1,11 +1,13 @@ from urllib.parse import urlparse, urljoin import re from flask import Flask, render_template +from flask_caching import Cache from lxml import html import requests from scrape import scrape app = Flask(__name__) +cache = Cache(app, config={'CACHE_TYPE': 'simple'}) @app.after_request def add_header(response): @@ -13,6 +15,7 @@ def add_header(response): return response @app.route("/") +@cache.cached(timeout=300) def index(): tournament_name, tournament_details, events = scrape() return render_template('index.html', diff --git a/requirements.txt b/requirements.txt index 0255be6bce4b9cdd32e87c0020af6185e0ecdb30..66f8706f83dc4231172b917fd6b5d140d9143ec4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ lxml==3.6.4 requests==2.12.1 Flask==0.11.1 +Flask-Caching==1.3.3 diff --git a/scrape.py b/scrape.py index 66a6528a51409faa5b2fe22014fb2d197af364c1..a5a4463360987360058ec8be9f76fd63fff2417c 100644 --- a/scrape.py +++ b/scrape.py @@ -6,7 +6,7 @@ from itertools import repeat def scrape(): - results_url = "http://www.escrimeresults.com/cobra/index.htm" + results_url = "https://fencingresults.ant.sr/cobra/" results = requests.get(results_url) results_tree = html.fromstring(results.content) try: @@ -31,13 +31,13 @@ def scrape(): if event_tree.xpath('//a[text()="Final Results"]'): fencers = event_tree.xpath('//div[@id="finalResults"]/table/tr/td[2]/text()') fencers = dict(zip(fencers, repeat("Checked In"))) - event_status = "Event has closed.".format(len(fencers)) + event_status = "closed" elif event_tree.xpath('//a[text()="Seeding"]'): fencers = event_tree.xpath('//div[@id="Round1Seeding"]/table/tr/td[2]/text()') fencers = dict(zip(fencers, repeat("Checked In"))) - event_status = "Event is ongoing.".format(len(fencers)) + event_status = "ongoing" elif event_tree.xpath('//a[text()="Check-In Status"]'): - event_status = "Check-in is open." + event_status = "open" fencers_checked_in = [True if len(list(f)) else False for f in event_tree.xpath('//div[@id="checkIn"]/table/tr/td[1]')] fencers = event_tree.xpath('//div[@id="checkIn"]/table/tr/td[2]/text()') fencers = dict(zip(fencers, fencers_checked_in)) diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000000000000000000000000000000000000..8e366cf601cb30d27e39a2c43e0592ff84d2b91c --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,90 @@ +body { + font: 18px sans-serif; + color: #fff; + background-color: #000; + max-width: 100%; +} +main { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + align-content: flex-start; + max-width: 100%; + box-sizing: border-box; +} +h1 { + font-size: 1.2em; +} +div.name, +div.time { + margin: .5em 0; +} +div.name { + font-size: 1.1em; +} +div.time { + font-size: .80em; +} +section { + border-radius: 1em; + border: 2px solid #555; + margin: .5em; + padding: .75em; + flex: 15em 1 0; +} +section > :first-child { + margin-top: 0; +} +section > :last-child { + margin-bottom: 0; +} +h1, h2, h3, h4, h5, h6 { + margin: .35em 0; +} +p, ul { + margin: .25em 0; +} +a:link, +a:active, +a:visited { + text-decoration: none; + color: #fff; +} +a:hover { + text-decoration: underline; + color: #fff; +} + +/* Important text */ +.hl { + color: #ee4; + font-size: 1.15em; +} + +/* Event statuses */ +.status { + float: right; + color: #000; + border-radius: .25em; + border: 2px solid #fff; + padding: .1em; + font-size: .8em; + font-weight: bold; + margin-bottom: .1em; + vertical-align: top; +} +.status-open .status { + background-color: #0f0; +} +.status-ongoing .status { + background-color: #ff0; +} +.status-closed .status { + background-color: #f00; +} + +/* Numbers */ +span.number { + font-weight: bold; + font-size: 1.1em; +} diff --git a/templates/index.html b/templates/index.html index b68de2731202b15f73137cb658ca479b1dc8f622..53c3977bc7bfdc6c97ee80c48ec19ffcf00bae18 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,59 +4,38 @@ <meta charset="utf-8"> <title>Armory Dashboard</title> <meta name="viewport" content="width=device-width, initial-scale=1"> - <style> - body { - font: 18px sans-serif; - } - section { - border-bottom: 1px dashed #aaa; - margin: 1em 0; - } - h1, h2, h3, h4, h5, h6 { - margin: .35em 0; - } - p, ul { - margin: .25em 0; - } - a:link, - a:active, - a:visited { - text-decoration: none; - color: #000; - } - a:hover { - text-decoration: underline; - color: #000; - } - .hl { - background-color: #ee8; - } - </style> + <meta http-equiv="refresh" content="60; URL={{ url_for('index') }}"> + <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}"> </head> <body> - <h1>{{ tournament_name }}</h1> - <h2>{{ tournament_details }}</h2> - <h2>{{ events | length }} Events</h2> - <hr> + <header> + <h1>{{ tournament_name }} - {{ events | length }} events</h1> + </header> + <main> {% for e in events %} - <section> - <a name="{{ e['name'] }}"> - <h3><a href="#{{ e['name'] }}">{{ e['name'] }}</a></h3> - <h4>{{ e['time'] }}</h4> - <p>{{ e['status'] }}</p> - <p><strong>{{ e['fencers_checked_in'] | length }}</strong> of <strong>{{ e['fencers'] | length }}</strong> fencers have checked in.</p> + <section class="status-{{ e['status'] }}"> + <header> + <div class="status">{{ e['status'] }}</div> + <div class="name"> + <a name="{{ e['name'] }}" href="#{{ e['name'] }}">{{ e['name'] }}</a> + </div> + <div class="time">{{ e['time'] }}</div> + </header> + <h4></h4> + <p><span class="number">{{ e['fencers_checked_in'] | length }}</span> of <span class="number">{{ e['fencers'] | length }}</span> fencer(s) checked in.</p> {% if e['previously_fenced'] %} - <p><strong>{{ e['previous_total'] }}</strong> fencers have participated in prior events:</p> + <p><span class="number">{{ e['previous_total'] }}</span> fenced in prior events:</p> <ul> {% for pe in e['previously_fenced'] %} - <li><strong>{{ pe }}</strong> - {{ e['previously_fenced'][pe] }} fencers</li> + <li>{{ pe }} - {{ e['previously_fenced'][pe] }}</li> {% endfor %} </ul> {% endif %} {% if e['new_fencers_not_checked_in'] %} - <p class="hl">{{ e['new_fencers_not_checked_in'] | length }} new fencers not yet checked in</p> + <p class="hl">{{ e['new_fencers_not_checked_in'] | length }} new and not checked in</p> {% endif %} </section> {% endfor %} + </main> </body> </html>