Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ bin
include
lib
.Python
tests/
# tests/
.envrc
__pycache__
__pycache__
.env
venv
.venv
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@

3. Installation

- After cloning, change into the directory and type <code>virtualenv .</code>. This will then set up a a virtual python environment within that directory.
- After cloning, change into the directory and type <code>virtualenv env</code>. This will then set up a a virtual python environment within that directory.

- 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>

- 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>

- 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
- 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>(exemple: set FLASK_APP=server.py in terminal and set FLASK_ENV=development to change for development environment). Check [here](https://flask.palletsprojects.com/en/1.1.x/quickstart/#a-minimal-application) for more details

- 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.

Expand Down
35 changes: 19 additions & 16 deletions clubs.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
{"clubs":[
{
"name":"Simply Lift",
"email":"john@simplylift.co",
"points":"13"
},
{
"name":"Iron Temple",
"email": "admin@irontemple.com",
"points":"4"
},
{ "name":"She Lifts",
"email": "kate@shelifts.co.uk",
"points":"12"
}
]}
{
"clubs": [
{
"name": "Simply Lift",
"email": "john@simplylift.co",
"points": "8"
},
{
"name": "Iron Temple",
"email": "admin@irontemple.com",
"points": "4"
},
{
"name": "She Lifts",
"email": "kate@shelifts.co.uk",
"points": "15"
}
]
}
9 changes: 7 additions & 2 deletions competitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@
"competitions": [
{
"name": "Spring Festival",
"date": "2020-03-27 10:00:00",
"date": "2023-03-27 10:00:00",
"numberOfPlaces": "25"
},
{
"name": "Fall Classic",
"date": "2023-10-22 13:30:00",
"numberOfPlaces": "5"
},
{
"name": "Freebie Shark",
"date": "2020-10-22 13:30:00",
"numberOfPlaces": "13"
"numberOfPlaces": "7"
}
]
}
14 changes: 14 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Config(object):
FLASK_ENV = 'development'
DEBUG = True
TESTING = True
DATABASE_URI = 'sqlite:///:memory:'

class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo'

class DevelopmentConfig(Config):
DEBUG = True

class TestingConfig(Config):
TESTING = True
11 changes: 11 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
attrs==22.2.0
click==7.1.2
colorama==0.4.6
config==0.5.1
coverage==7.0.0
exceptiongroup==1.1.0
Flask==1.1.2
iniconfig==1.1.1
itsdangerous==1.1.0
Jinja2==2.11.2
MarkupSafe==1.1.1
packaging==22.0
pluggy==1.0.0
pytest==7.2.0
pytest-flask==1.2.0
tomli==2.0.1
Werkzeug==1.0.1
151 changes: 137 additions & 14 deletions server.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import json
import json, os
from flask import Flask,render_template,request,redirect,flash,url_for
from config import Config, DevelopmentConfig
from datetime import datetime


MAX_BOOKING = 12


def loadClubs():
Expand All @@ -14,46 +19,164 @@ def loadCompetitions():
return listOfCompetitions


def loadCompetition(competition_name):
with open('competitions.json') as comps:
listOfCompetitions = json.load(comps)['competitions']
for comp in listOfCompetitions:
if comp['name'] == competition_name:
return comp
return None


def update_competitions_places(competitions_data, competition):
competitions_file = open("competitions.json", "w")
for d in competitions_data:
if d['name'] == competition['name']:
d['numberOfPlaces'] = str(competition['numberOfPlaces'])
json.dump({'competitions':competitions_data}, competitions_file, indent=4)


def update_club_points_balance(clubs_data, club):
club_file = open("clubs.json", "w")
for d in clubs_data:
if d['name'] == club['name']:
d['points'] = str(club['points'])
json.dump({'clubs':clubs_data}, club_file, indent=4)


app = Flask(__name__)
app.secret_key = 'something_special'
# app.config.from_object(DevelopmentConfig)
app.config.update(TESTING=True, DEBUG=True)

competitions = loadCompetitions()
clubs = loadClubs()


@app.route('/')
def index():
return render_template('index.html')


def search_club_by_email(clubs, email):
found_club = None
for club in clubs:
if club['email'] == email:
found_club = club
break
return found_club


@app.route('/showSummary',methods=['POST'])
def showSummary():
club = [club for club in clubs if club['email'] == request.form['email']][0]
return render_template('welcome.html',club=club,competitions=competitions)
clubs = loadClubs()
club = search_club_by_email(clubs, email=request.form['email'])
if not club:
message = "Sorry, that email wasn't found."
flash(message)
return render_template('index.html'), 401
else:
return render_template('welcome.html',club=club,competitions=competitions)


def search_club_by_name(clubs, name):
found_club = None
for club in clubs:
if club['name'] == name:
found_club = club
break
return found_club


def search_competition_by_name(competitions, name):
found_competition = None
for competition in competitions:
if competition['name'] == name:
found_competition = competition
break
return found_competition


@app.route('/book/<competition>/<club>')
def book(competition,club):
foundClub = [c for c in clubs if c['name'] == club][0]
foundCompetition = [c for c in competitions if c['name'] == competition][0]
clubs = loadClubs()
competitions = loadCompetitions()
foundClub = search_club_by_name(clubs, name=club)
foundCompetition = search_competition_by_name(competitions, name=competition)
if foundClub and foundCompetition:
return render_template('booking.html',club=foundClub,competition=foundCompetition)
else:
flash("Something went wrong-please try again")
return render_template('welcome.html', club=club, competitions=competitions)


def club_points_substrations(club, clubPoints, placesRequired):
club['points'] = clubPoints - placesRequired
return club['points']


def is_past_competition(competition):
competition_date = competition["date"]
competition_date = datetime.strptime(
competition_date,
"%Y-%m-%d %H:%M:%S")
now = datetime.now()
if competition_date < now :
return True
return False


@app.route('/purchasePlaces',methods=['POST'])
def purchasePlaces():
competition = [c for c in competitions if c['name'] == request.form['competition']][0]
club = [c for c in clubs if c['name'] == request.form['club']][0]
clubs = loadClubs()
competitions = loadCompetitions()
club = search_club_by_name(clubs, name=request.form['club'])
competition = search_competition_by_name(competitions, request.form['competition'])
placesRequired = int(request.form['places'])
competition['numberOfPlaces'] = int(competition['numberOfPlaces'])-placesRequired
flash('Great-booking complete!')
return render_template('welcome.html', club=club, competitions=competitions)


# TODO: Add route for points display
availablesCompetitionPlaces = int(competition['numberOfPlaces'])
clubPoints = int(club['points'])
if placesRequired > availablesCompetitionPlaces:
message = "You can't book more places than availables competition places : " + str(availablesCompetitionPlaces)
flash(message)
return render_template('booking.html',club=club,competition=competition), 405
elif placesRequired > clubPoints:
message = "You have " + str(clubPoints) + " points which is not enough to book " + str(placesRequired) + " places."
flash(message)
return render_template('booking.html',club=club,competition=competition), 405
elif placesRequired <= 0:
message = "Booking a negative number of places or 0 is forbidden."
flash(message)
return render_template('booking.html',club=club,competition=competition), 405
elif placesRequired > MAX_BOOKING:
message = "Booking more than " + str(MAX_BOOKING) + " places is forbidden."
flash(message)
return render_template('booking.html',club=club,competition=competition), 405
elif is_past_competition(competition):
message = "Booking a past competition is forbidden."
flash(message)
return render_template('booking.html',club=club,competition=competition), 405
else:
competition['numberOfPlaces'] = availablesCompetitionPlaces - placesRequired
club['points'] = club_points_substrations(club, clubPoints, placesRequired)
competitions_data = loadCompetitions()
clubs_data = loadClubs()
update_competitions_places(competitions_data, competition)
update_club_points_balance(clubs_data, club)
# competitions_file = open("competitions.json", "w")
# for d in data:
# if d['name'] == competition['name']:
# d['numberOfPlaces'] = str(competition['numberOfPlaces'])
# json.dump({'competitions':data}, competitions_file, indent=4)
flash('Great-booking complete!')
return render_template('welcome.html', club=club, competitions=competitions)


@app.route('/logout')
def logout():
return redirect(url_for('index'))
return redirect(url_for('index'))


# TODO:
# Add route for points display


9 changes: 9 additions & 0 deletions templates/booking.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
<body>
<h2>{{competition['name']}}</h2>
Places available: {{competition['numberOfPlaces']}}
{% with messages = get_flashed_messages()%}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{message}}</li>
{% endfor %}
</ul>
{% endif%}
{% endwith%}
<form action="/purchasePlaces" method="post">
<input type="hidden" name="club" value="{{club['name']}}">
<input type="hidden" name="competition" value="{{competition['name']}}">
Expand Down
9 changes: 9 additions & 0 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
<body>
<h1>Welcome to the GUDLFT Registration Portal!</h1>
Please enter your secretary email to continue:
{% with messages = get_flashed_messages()%}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{message}}</li>
{% endfor %}
</ul>
{% endif%}
{% endwith%}
<form action="showSummary" method="post">
<label for="email">Email:</label>
<input type="email" name="email" id=""/>
Expand Down
Empty file added tests/__init__.py
Empty file.
10 changes: 10 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import pytest
from server import app as app_flask


@pytest.fixture
def client():
app = app_flask
with app.test_client() as client:
yield client

16 changes: 16 additions & 0 deletions tests/datas/clubs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{"clubs":[
{
"name":"Simply Lift",
"email":"john@simplylift.co",
"points":"13"
},
{
"name":"Iron Temple",
"email": "admin@irontemple.com",
"points":"4"
},
{ "name":"She Lifts",
"email": "kate@shelifts.co.uk",
"points":"15"
}
]}
19 changes: 19 additions & 0 deletions tests/datas/competitions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"competitions": [
{
"name": "Spring Festival",
"date": "2023-03-27 10:00:00",
"numberOfPlaces": "25"
},
{
"name": "Fall Classic",
"date": "2023-10-22 13:30:00",
"numberOfPlaces": "10"
},
{
"name": "Freebie Shark",
"date": "2020-10-22 13:30:00",
"numberOfPlaces": "7"
}
]
}
Loading