diff --git a/aacstats.py b/aacstats.py
index 0088178..09d5a25 100644
--- a/aacstats.py
+++ b/aacstats.py
@@ -1,53 +1,91 @@
-from flask import Flask, request, render_template, url_for
+from flask import Flask, abort, request, render_template, url_for
import math
import MySQLdb
import MySQLdb.cursors
import datetime as dt
app = Flask(__name__)
+PAGE_SIZE=20
+# TODO: Search
+
+def now():
+ # TODO: If it's January and no races have been run this year, return last year
+ return dt.datetime.now()
@app.route('/')
-def index():
+@app.route('/list')
+@app.route('/list/
') # title = { races, rankings, runners, licence }
+@app.route('/list//')
+def list(title=None, year=None):
+ ''' Set defaults for the index page '''
+ if year is None and title is None:
+ year = now().year
+ title = 'runners'
+ if title not in ( 'races', 'rankings', 'runners', 'licence', ):
+ abort(404)
start = int(request.args.get('start', '0'))
- limit = int(request.args.get('limit', '10'))
- results = read_db(start, limit)
- total = int(total_entries())
- return render_template('index.html', ltype='index', request=request, start=start, limit=limit, results=results, total=total)
+ limit = int(request.args.get('limit', PAGE_SIZE))
+ results = read_db(start, limit, listing=title, year=year)
+ return render_template('list-'+title+'.html', ltype='listing', title=title, year=year,
+ results=results, start=start, limit=limit,
+ request=request, now=now(), PAGE_SIZE=PAGE_SIZE)
+@app.route('/all')
+@app.route('/all/')
+@app.route('/all//') # this does nothing, and is simply here to prevent title from being added to the query string
+def index(title=None, year=None):
+ start = int(request.args.get('start', '0'))
+ limit = int(request.args.get('limit', PAGE_SIZE))
+ results = read_db(start, limit, year=year)
+ return render_template('index.html', ltype='index', year=year,
+ results=results, start=start, limit=limit,
+ request=request, now=now(), PAGE_SIZE=PAGE_SIZE)
-@app.route('/race//')
-def race(start=0, year=None, title=None):
+
+@app.route('/race//')
+def race(year=None, title=None):
start = int(request.args.get('start', '0'))
- limit = int(request.args.get('limit', '10'))
- total = int(total_entries(event=title, year=year))
+ limit = int(request.args.get('limit', PAGE_SIZE))
results = read_db(start, limit, event=title, year=year)
- return render_template('index.html', ltype='race', title=title, year=year, request=request, start=start, limit=limit, results=results, total=total)
+ return render_template('index.html', ltype='race', title=title, year=year,
+ results=results, start=start, limit=limit,
+ request=request, now=now(), PAGE_SIZE=PAGE_SIZE)
@app.route('/person/')
-@app.route('/person//')
-def person(start=0, title=None, year=None):
+@app.route('/person//')
+def person(title=None, year=None):
start = int(request.args.get('start', '0'))
- limit = int(request.args.get('limit', '10'))
- total = int(total_entries(person=title, year=year))
+ limit = int(request.args.get('limit', PAGE_SIZE))
results = read_db(start, limit, person=title, year=year)
- return render_template('index.html', ltype='person', title=title, year=year, request=request, start=start, limit=limit, results=results, total=total)
+ return render_template('index.html', ltype='person', title=title, year=year,
+ results=results, start=start, limit=limit,
+ request=request, now=now(), PAGE_SIZE=PAGE_SIZE)
-@app.route('/licence//')
-def licence(start=0, year=dt.datetime.now().year, title=None):
+@app.route('/licence/')
+@app.route('/licence//')
+def licence(year=now().year, title=None):
start = int(request.args.get('start', '0'))
- limit = int(request.args.get('limit', '10'))
- total = int(total_entries(licence=title, year=year))
+ limit = int(request.args.get('limit', PAGE_SIZE))
results = read_db(start, limit, licence=title, year=year)
- return render_template('index.html', ltype='licence', title=title, year=year, request=request, start=start, limit=limit, results=results, total=total)
+ return render_template('index.html', ltype='licence', title=title, year=year,
+ results=results, start=start, limit=limit,
+ request=request, now=now(), PAGE_SIZE=PAGE_SIZE)
-def read_db(start=0, limit=10, person=None, licence=None, event=None, year=None):
+def read_db(start=0, limit=PAGE_SIZE, listing=None, event=None, person=None, licence=None, year=None):
db = MySQLdb.connect(user = 'aac', passwd = 'saOAcCWHg4LaoSSA', db = 'AAC', cursorclass = MySQLdb.cursors.DictCursor)
c = db.cursor()
- where = 'club LIKE "AAC"'
- if person:
- where += ' AND CONCAT_WS(" ", name, surname) LIKE "{}"'.format(person)
+
+ count = 0
+
+ select = '*'
+ where = 'WHERE club LIKE "AAC"'
+ group = ''
+ order = 'date DESC, event, position'
+ close = ''
if event:
where += ' AND event LIKE "{}"'.format(event)
+ if person:
+ where += ' AND CONCAT_WS(" ", name, surname) LIKE "{}"'.format(person)
if licence:
where += ' AND licence LIKE "{}"'.format(licence)
if year:
@@ -56,51 +94,77 @@ def read_db(start=0, limit=10, person=None, licence=None, event=None, year=None)
firstdate = firstdate.replace(year=int(year))
lastdate = lastdate.replace(year=int(year))
where += ' AND date > "{}" AND date < "{}"'.format(firstdate, lastdate)
- sql = 'SELECT * FROM `results` WHERE {} ORDER BY date DESC, event, position LIMIT {},{};'.format(where, start, limit)
- c.execute(sql)
- results = c.fetchall()
- return results
-@app.template_filter('total_entries')
-def total_entries(person=None, licence=None, event=None, year=None):
- db = MySQLdb.connect(user = 'aac', passwd = 'saOAcCWHg4LaoSSA', db = 'AAC', cursorclass = MySQLdb.cursors.DictCursor)
- c = db.cursor()
- where = 'club LIKE "AAC"'
- if person:
- where += ' AND CONCAT_WS(" ", name, surname) LIKE "{}"'.format(person)
- if event:
- where += ' AND event LIKE "{}"'.format(event)
- if licence:
- where += ' AND licence LIKE "{}"'.format(licence)
- if year:
- firstdate = dt.datetime.min
- lastdate = dt.datetime.max
- firstdate = firstdate.replace(year=int(year))
- lastdate = lastdate.replace(year=int(year))
- where += ' AND date > "{}" AND date < "{}"'.format(firstdate, lastdate)
- sql = 'SELECT COUNT(*) FROM `results` WHERE {}'.format(where)
+ if listing:
+ if listing == 'races':
+ select = 'event, date'
+ group = 'GROUP BY event'
+ elif listing == 'runners':
+ select = 'CONCAT_WS(" ", name, surname) person, FORMAT(SUM(distance),0) total'
+ where += ' AND CONCAT_WS(" ", name, surname) NOT LIKE "%NO RETURN%"'
+ where += ' AND CONCAT_WS(" ", name, surname) NOT LIKE "%BLANK CARD%"'
+ group = 'GROUP BY CONCAT_WS(" ", name, surname)'
+ order = 'SUM(distance) DESC, surname'
+ elif listing == 'rankings':
+ select = 'CONCAT_WS(" ", name, surname) person, SUM(position) positions, COUNT(event) races, SUM(position)/COUNT(event) podiums, FORMAT(SUM(position)/COUNT(event),1) score'
+ group = 'GROUP BY CONCAT_WS(" ", name, surname)'
+ order = 'podiums, races DESC'
+ elif listing == 'licence':
+ select = 'licence, date, CONCAT_WS(" ", name, surname) person'
+ group = 'GROUP BY licence'
+ order = 'surname, date DESC'
+
+ sql = 'SELECT {} FROM `results` {} {} ORDER BY {} LIMIT {},{} {};'.format(select, where, group, order, start, limit, close)
+ #app.logger.debug(sql)
c.execute(sql)
- for x in c.fetchone().values():
- return x
+ queryresults = c.fetchall()
+
+ select = 'COUNT(*)'
+ if listing:
+ if listing == 'races':
+ select = 'COUNT(*) FROM ( SELECT COUNT(event)'
+ close = ') races'
+ elif listing == 'runners':
+ select = 'COUNT(*) FROM ( SELECT COUNT(name)'
+ group = 'GROUP BY CONCAT_WS(" ", name, surname)'
+ close = ') runners'
+ elif listing == 'rankings':
+ select = 'COUNT(*) FROM ( SELECT COUNT(name)'
+ group = 'GROUP BY CONCAT_WS(" ", name, surname)'
+ close = ') rankings'
+ elif listing == 'licence':
+ pass
+
+ sql = 'SELECT {} FROM `results` {} {} {};'.format(select, where, group, close)
+ #app.logger.debug(sql)
+ c.execute(sql)
+ countresult = c.fetchone()
+ for x in countresult.keys():
+ count = countresult[x]
+ app.logger.debug(count)
+
+ return { 'count': int(count), 'rows': queryresults }
+
@app.template_filter('pace')
def pace(time):
return (dt.datetime(1,1,1) + time).strftime('%M:%S')
-@app.template_filter('clean_date')
+@app.template_filter('year')
+def year(time):
+ return time.strftime('%Y')
+
+@app.template_filter('cleandate')
def clean_date(time):
if time.month == 1 and time.day == 1:
return time.strftime('%Y')
return time.strftime('%Y-%m-%d')
-@app.template_filter('year')
-def year(time):
- return time.strftime('%Y')
-
@app.template_filter('ordinal')
def ordinal(n):
return "%d%s" % (n,"tsnrhtdd"[(math.floor(n/10)%10!=1)*(n%10<4)*n%10::4])
+
if __name__ == '__main__':
app.run(debug=True)
@@ -112,9 +176,15 @@ if __name__ == '__main__':
# by race
# - and by gender
-# default: list of races (sorted by recent)
-# tabs: list of [races (sorted by recent), people (sorted by total kms for the year), licences for the year (sorted by number of races), podiums/winners (people sorted by total_position/total_races), ]
-# click to expand by [race (all AAC members by position), person (races by recent), person (races by pace)]
+# tabs:
+# list of races (sorted by recent)
+# list of people (sorted by total kms for the year)
+# list of licences for the year (sorted by number of races)
+# list of podiums/rankings (people sorted by total_position/total_races)
+# click to expand by
+# person (races by recent)
+# person (races by pace)]
+# race (all AAC members by position)
# SEARCH
# /?sort={distance,pace}&sex={m,f}
@@ -122,6 +192,4 @@ if __name__ == '__main__':
# /person/Timothy Allen?sort={pace,date}
# /person/Timothy Allen/2018
# /license/2018/4356
-# /license/2018/4356/2018
-#
-# TODO LIMIT/pagination
+# /license/2018/4356
diff --git a/static/AAC_224x224.png b/static/AAC_224x224.png
new file mode 100644
index 0000000..0d7abd5
Binary files /dev/null and b/static/AAC_224x224.png differ
diff --git a/static/AAC_224x95.png b/static/AAC_224x95.png
new file mode 100644
index 0000000..0c34863
Binary files /dev/null and b/static/AAC_224x95.png differ
diff --git a/static/style.css b/static/style.css
index 33295ea..d06f674 100644
--- a/static/style.css
+++ b/static/style.css
@@ -1,9 +1,16 @@
body {
- margin: 0 auto;
+ margin: 0 auto 15px;
+ padding: 0 8px;
max-width: 800px;
font-family: 'Roboto Condensed', sans-serif;
font-size: 11pt;
}
+a {
+ color: #154996;
+}
+h1 {
+ text-align: center;
+}
table {
border-collapse: collapse;
width: 100%;
@@ -22,11 +29,45 @@ table tr td:last-child {
table tr td.nowrap {
white-space: nowrap;
}
-nav.nextprev {
+nav {
+ display: flex;
+ background-color: #154996;
text-align: center;
+}
+nav span {
+ flex: 1 1 auto;
+}
+nav span {
+}
+nav span a {
+ display: block;
+ color: #FFF;
+}
+nav.nextprev {
margin-top: 10px;
+ padding: 0 15px;
}
-nav.nextprev span.prev {
-}
+nav.nextprev span.first,
+nav.nextprev span.last,
+nav.nextprev span.prev,
nav.nextprev span.next {
+ padding: 0 2px;
+}
+nav.nextprev span.plain,
+nav.nextprev span a {
+ display: block;
+ padding: 10px 5px;
+}
+nav.tabs {
+}
+nav.tabs span {
+ border-right: 1px solid #FFF;
+}
+nav.tabs span:last-child {
+ border-right: none;
+}
+nav.tabs span a {
+ padding: 15px 10px;
+ font-size: 11pt;
+ font-weight: bold;
}
diff --git a/templates/head.html b/templates/head.html
new file mode 100644
index 0000000..d153e9c
--- /dev/null
+++ b/templates/head.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+ Atlantic Athletic Club
+
+
+
+{%- set ns.limit = limit -%}
+{%- if ns.limit == 0 or ns.limit == PAGE_SIZE -%}
+ {%- set ns.limit = None -%}
+{%- endif -%}
+
+{% include 'tabs.html' with context %}
diff --git a/templates/index.html b/templates/index.html
index 7cd5cd8..c11cdee 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -1,29 +1,13 @@
-
-
-
-
-
- AAC Statistics
-
-
-
-{%- set ns = namespace() -%}
+{% set ns = namespace() -%}
-{%- set ns.limit = limit -%}
-{%- if ns.limit == 0 or ns.limit == 10 -%}
- {%- set ns.limit = None -%}
-{%- endif -%}
-
-{%- set ns.year = year -%}
-{%- if ns.year == 0 -%}
- {%- set ns.year = None -%}
-{%- endif -%}
-
-
-
+{% include 'head.html' with context %}
-
AAC Statistics {% if title %}: {{ title }}{% endif %}
-{%- if results -%}
+
AAC Statistics {% if title %}: {{ title }}{% endif %}{% if year %} {{ year }}{% endif %}
+{% if results -%}
+ {%- set ns.total = 0 -%}
+ {%- if 'count' in results -%}
+ {%- set ns.total = results['count'] -%}
+ {%- endif -%}
@@ -42,7 +26,7 @@
- {%- for row in results -%}
+ {%- for row in results['rows'] -%}
{%- set person='{} {}'.format(row.name, row.surname) -%}
{%- if distance %}{# set total_km += row.distance #}{% endif -%}