Skip to content

Commit f485fb1

Browse files
committed
initial commit
1 parent 807f317 commit f485fb1

File tree

10 files changed

+221
-1
lines changed

10 files changed

+221
-1
lines changed

.DS_Store

6 KB
Binary file not shown.

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
bin
2+
include
3+
lib
4+
.Python
5+
tests/
6+
.envrc
7+
__pycache__

README.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,50 @@
1-
# Python_Testing
1+
# gudlift-registration
2+
3+
1. Why
4+
5+
6+
This is a proof of concept (POC) project to show a light-weight version of our competition booking platform. The aim is the keep things as light as possible, and use feedback from the users to iterate.
7+
8+
2. Getting Started
9+
10+
This project uses the following technologies:
11+
12+
* Python v3.x+
13+
14+
* [Flask](https://flask.palletsprojects.com/en/1.1.x/)
15+
16+
Whereas Django does a lot of things for us out of the box, Flask allows us to add only what we need
17+
18+
* [Virtual environment](https://virtualenv.pypa.io/en/stable/installation.html)
19+
20+
This ensures you'll be able to install the correct packages without interfering with Python on your machine.
21+
22+
Before you begin, please ensure you have this installed globally.
23+
24+
25+
3. Installation
26+
27+
- After cloning, change into the directory and type <code>virtualenv .</code>. This will then set up a a virtual python environment within that directory.
28+
29+
- Next, type <code>source bin/activate</code>. You should see that your command prompt has changed to the name of the folder. This means that you can install packages in here without affecting affecting files outside. To deactivate, type <code>deactivate</code>
30+
31+
- Rather than hunting around for the packages you need, you can install in one step. Type <code>pip install -r requirements.txt</code>. This will install all the packages listed in the respective file. If you install a package, make sure others know by updating the requirements.txt file. An easy way to do this is <code>pip freeze > requirements.txt</code>
32+
33+
- Flask requires that you set an environmental variable to the python file. However you do that, you'll want to set the file to be <code>server.py</code>. Check [here](https://flask.palletsprojects.com/en/1.1.x/quickstart/#a-minimal-application) for more details
34+
35+
- You should now be ready to test the application. In the directory, type either <code>flask run</code> or <code>python -m flask run</code>. The app should respond with an address you should be able to go to using your browser.
36+
37+
4. Current Setup
38+
39+
The app is powered by [JSON files](https://www.tutorialspoint.com/json/json_quick_guide.htm). This is to get around having a DB until we actually need one. The main ones are:
40+
41+
* competitions.json - list of competitions
42+
* clubs.json - list of clubs with relevant information. You can look here to see what email addresses the app will accept for login.
43+
44+
5. Testing
45+
46+
You are free to use whatever testing framework you like-the main thing is that you can show what tests you are using.
47+
48+
We also like to show how well we're testing, so we there's a module called
49+
[coverage](https://coverage.readthedocs.io/en/coverage-5.1/) you should add to your project.
50+

clubs.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{"clubs":[
2+
{
3+
"name":"Simply Lift",
4+
"email":"john@simplylift.co",
5+
"points":"13"
6+
},
7+
{
8+
"name":"Iron Temple",
9+
"email": "admin@irontemple.com",
10+
"points":"4"
11+
},
12+
{ "name":"She Lifts",
13+
"email": "kate@shelifts.co.uk",
14+
"points":"12"
15+
}
16+
]}

competitions.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"competitions": [
3+
{
4+
"name": "Spring Festival",
5+
"date": "2020-03-27 10:00:00",
6+
"numberOfPlaces": "25"
7+
},
8+
{
9+
"name": "Fall Classic",
10+
"date": "2020-10-22 13:30:00",
11+
"numberOfPlaces": "13"
12+
}
13+
]
14+
}

requirements.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
click==7.1.2
2+
Flask==1.1.2
3+
itsdangerous==1.1.0
4+
Jinja2==2.11.2
5+
MarkupSafe==1.1.1
6+
Werkzeug==1.0.1

server.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import json
2+
from flask import Flask,render_template,request,redirect,flash,url_for
3+
4+
5+
def loadClubs():
6+
with open('clubs.json') as c:
7+
listOfClubs = json.load(c)['clubs']
8+
return listOfClubs
9+
10+
11+
def loadCompetitions():
12+
with open('competitions.json') as comps:
13+
listOfCompetitions = json.load(comps)['competitions']
14+
return listOfCompetitions
15+
16+
17+
app = Flask(__name__)
18+
app.secret_key = 'something_special'
19+
20+
competitions = loadCompetitions()
21+
clubs = loadClubs()
22+
23+
@app.route('/')
24+
def index():
25+
return render_template('index.html')
26+
27+
@app.route('/showSummary',methods=['POST'])
28+
def showSummary():
29+
club = [club for club in clubs if club['email'] == request.form['email']][0]
30+
return render_template('welcome.html',club=club,competitions=competitions)
31+
32+
33+
@app.route('/book/<competition>/<club>')
34+
def book(competition,club):
35+
foundClub = [c for c in clubs if c['name'] == club][0]
36+
foundCompetition = [c for c in competitions if c['name'] == competition][0]
37+
if foundClub and foundCompetition:
38+
return render_template('booking.html',club=foundClub,competition=foundCompetition)
39+
else:
40+
flash("Something went wrong-please try again")
41+
return render_template('welcome.html', club=club, competitions=competitions)
42+
43+
44+
@app.route('/purchasePlaces',methods=['POST'])
45+
def purchasePlaces():
46+
competition = [c for c in competitions if c['name'] == request.form['competition']][0]
47+
club = [c for c in clubs if c['name'] == request.form['club']][0]
48+
placesRequired = int(request.form['places'])
49+
competition['numberOfPlaces'] = int(competition['numberOfPlaces'])-placesRequired
50+
flash('Great-booking complete!')
51+
return render_template('welcome.html', club=club, competitions=competitions)
52+
53+
54+
# TODO: Add route for points display
55+
56+
57+
@app.route('/logout')
58+
def logout():
59+
return redirect(url_for('index'))

templates/booking.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<html lang="en">
2+
<head>
3+
<meta charset="UTF-8">
4+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
5+
<title>Booking for {{competition['name']}} || GUDLFT</title>
6+
</head>
7+
<body>
8+
<h2>{{competition['name']}}</h2>
9+
Places available: {{competition['numberOfPlaces']}}
10+
<form action="/purchasePlaces" method="post">
11+
<input type="hidden" name="club" value="{{club['name']}}">
12+
<input type="hidden" name="competition" value="{{competition['name']}}">
13+
<label for="places">How many places?</label><input type="number" name="places" id=""/>
14+
<button type="submit">Book</button>
15+
</form>
16+
</body>
17+
</html>

templates/index.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<html lang="en">
2+
<head>
3+
<meta charset="UTF-8">
4+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
5+
<title>GUDLFT Registration</title>
6+
</head>
7+
<body>
8+
<h1>Welcome to the GUDLFT Registration Portal!</h1>
9+
Please enter your secretary email to continue:
10+
<form action="showSummary" method="post">
11+
<label for="email">Email:</label>
12+
<input type="email" name="email" id=""/>
13+
<button type="submit">Enter</button>
14+
</form>
15+
</body>
16+
</html>

templates/welcome.html

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<html lang="en">
2+
<head>
3+
<meta charset="UTF-8">
4+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
5+
<title>Summary | GUDLFT Registration</title>
6+
</head>
7+
<body>
8+
<h2>Welcome, {{club['email']}} </h2><a href="{{url_for('logout')}}">Logout</a>
9+
10+
{% with messages = get_flashed_messages()%}
11+
{% if messages %}
12+
<ul>
13+
{% for message in messages %}
14+
<li>{{message}}</li>
15+
{% endfor %}
16+
</ul>
17+
{% endif%}
18+
Points available: {{club['points']}}
19+
<h3>Competitions:</h3>
20+
<ul>
21+
{% for comp in competitions%}
22+
<li>
23+
{{comp['name']}}<br />
24+
Date: {{comp['date']}}</br>
25+
Number of Places: {{comp['numberOfPlaces']}}
26+
{%if comp['numberOfPlaces']|int >0%}
27+
<a href="{{ url_for('book',competition=comp['name'],club=club['name']) }}">Book Places</a>
28+
{%endif%}
29+
</li>
30+
<hr />
31+
{% endfor %}
32+
</ul>
33+
{%endwith%}
34+
35+
</body>
36+
</html>

0 commit comments

Comments
 (0)