feat: Added start times and all dates in UTC
Some checks failed
Build Docker / Build Image (push) Failing after 4m45s

This commit is contained in:
Nathan Woodburn 2024-02-26 23:32:34 +11:00
parent 93071c3763
commit 049141966a
Signed by: nathanwoodburn
GPG Key ID: 203B000478AD0EF1
3 changed files with 97 additions and 18 deletions

72
main.py
View File

@ -18,6 +18,7 @@ dotenv.load_dotenv()
DISCORD_WEBHOOK = os.getenv('DISCORD_WEBHOOK') DISCORD_WEBHOOK = os.getenv('DISCORD_WEBHOOK')
utc_now = datetime.datetime.utcnow()
# If votes file doesn't exist, create it # If votes file doesn't exist, create it
if not os.path.isfile('data/votes.json'): if not os.path.isfile('data/votes.json'):
@ -60,12 +61,12 @@ def index():
enabled = info["enabled"] enabled = info["enabled"]
end = datetime.datetime.strptime(info["end"], "%Y-%m-%d") end = datetime.datetime.strptime(info["end"], "%Y-%m-%d")
if end < datetime.datetime.now(): smallEnd = end.strftime("%Y-%m-%d")
enabled = False # Format as 2024-02-27T00:00:00Z
end = "Voting has closed" unixEnd = end.strftime("%Y-%m-%dT00:00:00Z")
info["public"] = True
else: if not hasStarted() or hasEnded():
end = f'Voting ends on {end.strftime("%B %d, %Y")}' enabled = False
revote = "not" if not info["revote"] else "" revote = "not" if not info["revote"] else ""
if info["public"]: if info["public"]:
@ -74,7 +75,11 @@ def index():
votes = "" votes = ""
return render_template('index.html',year=year,votes=votes, options=options, return render_template('index.html',year=year,votes=votes, options=options,
current_vote=info["vote"], description=info["description"], end=end,enabled=enabled, public=info["public"], revote=revote) current_vote=info["vote"], description=info["description"],
end=end,enabled=enabled, public=info["public"],
revote=revote, smallEnd=smallEnd,
unixEnd=unixEnd,ended=hasEnded(),
notStarted=not hasStarted(),starts=startTime().strftime("%Y-%m-%d") + " UTC")
@app.route('/<path:path>') @app.route('/<path:path>')
def catch_all(path): def catch_all(path):
@ -117,11 +122,12 @@ def vote():
# Make sure the voting is enabled and hasn't ended # Make sure the voting is enabled and hasn't ended
if not info['enabled']: if not info['enabled']:
return render_template('404.html', year=datetime.datetime.now().year) return render_template('404.html', year=datetime.datetime.now().year)
end = datetime.datetime.strptime(info['end'], "%Y-%m-%d") if hasEnded():
if end < datetime.datetime.now():
return render_template('404.html', year=datetime.datetime.now().year) return render_template('404.html', year=datetime.datetime.now().year)
if not hasStarted():
return render_template('404.html', year=datetime.datetime.now().year)
# Verify signature # Verify signature
try: try:
@ -298,7 +304,9 @@ def admin():
info = get_vote_info() info = get_vote_info()
options = ','.join(info['options']) options = ','.join(info['options'])
return render_template('admin.html', year=datetime.datetime.now().year, name=info['vote'], description=info['description'], end=info['end'], enabled=info['enabled'], public=info['public'], revote=info['revote'], options=options) return render_template('admin.html', year=datetime.datetime.now().year, name=info['vote'],
description=info['description'], end=info['end'], start=info['start'],
enabled=info['enabled'], public=info['public'], revote=info['revote'], options=options)
@app.route('/admin', methods=['POST']) @app.route('/admin', methods=['POST'])
def admin_post(): def admin_post():
@ -314,6 +322,7 @@ def admin_post():
info['vote'] = request.form['name'] info['vote'] = request.form['name']
info['description'] = request.form['description'] info['description'] = request.form['description']
info['end'] = request.form['end'] info['end'] = request.form['end']
info['start'] = request.form['start']
info['enabled'] = 'enabled' in request.form info['enabled'] = 'enabled' in request.form
info['public'] = 'public' in request.form info['public'] = 'public' in request.form
info['revote'] = 'revote' in request.form info['revote'] = 'revote' in request.form
@ -343,11 +352,12 @@ def clear():
def get_vote_info(): def get_vote_info():
if not os.path.isfile('data/info.json'): if not os.path.isfile('data/info.json'):
end = datetime.datetime.now() + datetime.timedelta(days=7)
end = end.strftime("%Y-%m-%d")
start = datetime.datetime.now() - datetime.timedelta(days=7)
start = start.strftime("%Y-%m-%d")
with open('data/info.json', 'w') as file: with open('data/info.json', 'w') as file:
end = datetime.datetime.now() + datetime.timedelta(days=7) json.dump({'vote': '','description':'', 'end': end,'start':start,'enabled': False, 'public': True, 'revote': True, 'options': []}, file)
end = end.strftime("%Y-%m-%d")
json.dump({'vote': '','description':'', 'end': end,'enabled': False, 'public': True, 'revote': True, 'options': []}, file)
with open('data/info.json') as file: with open('data/info.json') as file:
info = json.load(file) info = json.load(file)
return info return info
@ -359,5 +369,37 @@ def not_found(e):
return render_template('404.html', year=datetime.datetime.now().year), 404 return render_template('404.html', year=datetime.datetime.now().year), 404
# Time helper functions
def timeLeft():
info = get_vote_info()
end = utc_now.strptime(info["end"], "%Y-%m-%d")
left = end - utc_now
print(left)
return left
def endTime():
info = get_vote_info()
end = utc_now.strptime(info["end"], "%Y-%m-%d")
return end
def startTime():
info = get_vote_info()
start = utc_now.strptime(info["start"], "%Y-%m-%d")
return start
def hasStarted():
start = startTime()
if utc_now > start:
return True
return False
def hasEnded():
end = endTime()
if utc_now > end:
return True
return False
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True, port=5000, host='0.0.0.0') app.run(debug=True, port=5000, host='0.0.0.0')

View File

@ -37,7 +37,7 @@
<div class="text-center"> <div class="text-center">
<h1 class="display-4 fw-bold mb-5">Admin</h1> <h1 class="display-4 fw-bold mb-5">Admin</h1>
<form method="post"><input class="form-control" type="text" name="name" value="{{name}}" placeholder="Vote Name" style="margin-bottom: 5px;"><textarea class="form-control" style="margin-bottom: 5px;" name="description" placeholder="Vote Description">{{description}}</textarea><input class="form-control" type="text" name="options" value="{{options}}" placeholder="Vote Options comma separated" style="margin-bottom: 5px;"> <form method="post"><input class="form-control" type="text" name="name" value="{{name}}" placeholder="Vote Name" style="margin-bottom: 5px;"><textarea class="form-control" style="margin-bottom: 5px;" name="description" placeholder="Vote Description">{{description}}</textarea><input class="form-control" type="text" name="options" value="{{options}}" placeholder="Vote Options comma separated" style="margin-bottom: 5px;">
<div style="margin-bottom: 5px;"><label class="form-label" for="end" style="display: inline-block;margin-right: 10px;">End Date</label><input class="form-control" type="date" name="end" value="{{end}}" style="width: auto;display: inline-block;"></div>{% if revote %} <div style="margin-bottom: 5px;"><label class="form-label" for="end" style="display: inline-block;margin-right: 10px;">Start Date</label><input class="form-control" type="date" name="start" value="{{start}}" style="width: auto;display: inline-block;margin-right: 20px;"><label class="form-label" for="end" style="display: inline-block;margin-right: 10px;">End Date</label><input class="form-control" type="date" name="end" value="{{end}}" style="width: auto;display: inline-block;"></div>{% if revote %}
<div class="form-check form-switch form-check-inline"> <div class="form-check form-switch form-check-inline">
<input id="formCheck-1" class="form-check-input" type="checkbox" name="revote" checked /> <input id="formCheck-1" class="form-check-input" type="checkbox" name="revote" checked />
<label class="form-check-label" for="formCheck-1">Allow revotes</label> <label class="form-check-label" for="formCheck-1">Allow revotes</label>

View File

@ -53,9 +53,46 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-md-6 text-center"> <div class="col-md-6 text-center">
<h2 style="margin-bottom: 20px;">{{current_vote}}</h2> <h2>{{current_vote}}</h2>{% if ended %}
<h3 style="margin-bottom: 0px;">Voting has closed<span id="timer"></span>&nbsp;</h3>
{% elif notStarted %}
<h3 style="margin-bottom: 0px;">Opens on {{starts}} <span id="timer"></span>&nbsp;</h3>
{% else %}
<h3 style="margin-bottom: 0px;">Closes in <span id="timer"></span>&nbsp;</h3>
<span id="date" style="font-size: 16px;">({{smallEnd}})</span>
<script>
function updateTimer() {
const endDate = new Date('{{unixEnd}}'); // Set the end date here
const now = new Date();
const diff = endDate - now;
let days = Math.floor(diff / (1000 * 60 * 60 * 24));
let hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((diff % (1000 * 60)) / 1000);
let timerText = '';
if (days > 0) {
timerText += `${days} day${days > 1 ? 's' : ''} `;
}
if (hours > 0 || (days === 0 && minutes === 0)) {
timerText += `${hours} hour${hours > 1 ? 's' : ''} `;
}
if (minutes > 0 || (days === 0 && hours < 4)) {
timerText += `${minutes} minute${minutes > 1 ? 's' : ''} `;
}
if (seconds > 0 && (days === 0 && hours < 4)) {
timerText += `${seconds} second${seconds > 1 ? 's' : ''}`;
}
document.getElementById('timer').innerText = timerText;
}
setInterval(updateTimer, 1000);
updateTimer();
</script>
{% endif %}
<p style="margin: 0px;">{{description}}</p> <p style="margin: 0px;">{{description}}</p>
<p>{{end}}<br>You are {{revote}} allowed to redo your vote.</p>{{votes|safe}} <p>You are {{revote}} allowed to redo your vote.</p>{{votes|safe}}
</div> </div>
<div class="col-md-6 text-center"> <div class="col-md-6 text-center">
<h3>You have&nbsp;<span id="balance">0</span>&nbsp;votes.</h3> <h3>You have&nbsp;<span id="balance">0</span>&nbsp;votes.</h3>