Refactor, implement countdown
This commit is contained in:
parent
f78c9d349a
commit
1ba8fc71a8
22 changed files with 111 additions and 100 deletions
|
@ -1,7 +0,0 @@
|
|||
from flask import Blueprint
|
||||
|
||||
api_v1 = Blueprint('api.v1', __name__)
|
||||
|
||||
import api.v1.clock
|
||||
import api.v1.countdown
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
from time import time
|
||||
|
||||
from api.v1 import api_v1
|
||||
|
||||
@api_v1.route('/time/<float:t1>')
|
||||
def netime_time(t1: float) -> str:
|
||||
return str(time())
|
|
@ -1,31 +0,0 @@
|
|||
from flask import request, jsonify
|
||||
from walrus import Walrus
|
||||
from time import time
|
||||
|
||||
import uuid
|
||||
import struct
|
||||
|
||||
from api.v1 import api_v1
|
||||
|
||||
db = Walrus(host='localhost', port=6379, db=0)
|
||||
|
||||
@api_v1.route('/countdown/<uuid:id>', methods=['GET'])
|
||||
def get_countdown(id):
|
||||
ct = db.Hash(str(id))
|
||||
|
||||
resp = ct.as_dict(decode=True)
|
||||
resp['left'] = float(ct['total']) - (time() - float(ct['start']))
|
||||
|
||||
return resp
|
||||
|
||||
@api_v1.route('/countdown', methods=['POST'])
|
||||
def create_countdown():
|
||||
countdown = request.json
|
||||
ct_id = str(uuid.uuid4())
|
||||
ct = db.Hash(ct_id)
|
||||
ct.update(start=time(), total=countdown['total'])
|
||||
|
||||
resp = ct.as_dict(decode=True)
|
||||
resp['id'] = ct_id
|
||||
|
||||
return resp
|
|
@ -1,6 +1,5 @@
|
|||
from flask import Blueprint
|
||||
|
||||
app = Blueprint('countdown', __name__)
|
||||
|
||||
import views
|
||||
import apii
|
||||
app = Blueprint('countdown', __name__, template_folder='templates')
|
||||
from . import views
|
||||
from . import api
|
||||
|
|
|
@ -5,11 +5,11 @@ from time import time
|
|||
import uuid
|
||||
import struct
|
||||
|
||||
from countdown import api_api
|
||||
from . import app
|
||||
|
||||
db = Walrus(host='localhost', port=6379, db=0)
|
||||
|
||||
@app.route('/api/vi1/<uuid:id>', methods=['GET'])
|
||||
@app.route('/api/v1/<uuid:id>', methods=['GET'])
|
||||
def get_countdown(id):
|
||||
ct = db.Hash(str(id))
|
||||
|
||||
|
@ -18,7 +18,7 @@ def get_countdown(id):
|
|||
|
||||
return resp
|
||||
|
||||
@api_v1.route('/api/v1', methods=['POST'])
|
||||
@app.route('/api/v1', methods=['POST'])
|
||||
def create_countdown():
|
||||
countdown = request.json
|
||||
ct_id = str(uuid.uuid4())
|
48
countdown/countdown.js
Normal file
48
countdown/countdown.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
// This file is packed by webpack into /static/dist/countdown.bundle.js
|
||||
// Use with: `url_for('static', filename='dist/countdown.bundle.js')`
|
||||
// See: webpack.common.js
|
||||
import log from 'loglevel';
|
||||
import $ from 'jquery';
|
||||
|
||||
import './countdown.scss';
|
||||
|
||||
let api_base = "/countdown/api/v1/";
|
||||
|
||||
|
||||
const updateCountdown = () => $.getJSON({
|
||||
url: api_base+countdown_id,
|
||||
data: Date.now(),
|
||||
success: function(countdown) {
|
||||
if(countdown.left <= 0) {
|
||||
// clear interval, don't count below 0
|
||||
clearInterval(scheduledUpdater);
|
||||
$("#countdown").text("Time is up!");
|
||||
let end = new Date(Math.floor(countdown.start*1000 + countdown.total*1000));
|
||||
$("#subtext").text("This countdown ended on "+ end.toLocaleDateString()+" "+end.toLocaleTimeString());
|
||||
return;
|
||||
}
|
||||
|
||||
// total seconds left
|
||||
let sec = Math.floor(countdown.left);
|
||||
// milliseconds left in seconds resolution
|
||||
let frac = countdown.left - sec;
|
||||
// milliseconds left in millisecond resolution
|
||||
let milli = Math.floor(frac * 1000);
|
||||
// seconds in hrs, minutes, seconds
|
||||
let h = Math.floor(sec/(60*60));
|
||||
let m = Math.floor(sec/60) - (h*60);
|
||||
let s = sec - (m*60) - (h*60*60);
|
||||
|
||||
// let milliseconds pass, then set element to
|
||||
// amount of full seconds left
|
||||
let htext = padTime(h);
|
||||
let mtext = padTime(m);
|
||||
htext = htext !== "00" ? htext+":": "";
|
||||
mtext = mtext !== "00" ? mtext+":": "";
|
||||
setTimeout(() => $("#countdown").text(htext+mtext+padTime(s)), milli);
|
||||
}
|
||||
});
|
||||
|
||||
let scheduledUpdater = setInterval(updateCountdown, 1000);
|
||||
let padTime = t => `${"0".repeat(2-t.toString().length)+t}`;
|
||||
|
7
countdown/countdown.scss
Normal file
7
countdown/countdown.scss
Normal file
|
@ -0,0 +1,7 @@
|
|||
#countdown {
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
#subtext {
|
||||
margin-top: 1em;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
from flask_wtf import FlaskForm, TimeField
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import TimeField
|
||||
|
||||
class CountdownAdminForm(FlaskForm):
|
||||
totalTime = TimeField('Time')
|
||||
|
|
|
@ -2,10 +2,15 @@
|
|||
{% block title %}Countdown{% endblock title %}
|
||||
|
||||
{% block body %}
|
||||
Hello from Countdown
|
||||
<div id="clock"></div>
|
||||
<div class="center">
|
||||
<p id="countdown" />
|
||||
<p id="subtext" />
|
||||
</div>
|
||||
{% endblock body %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
var countdown_id = "{{ countdown_id }}";
|
||||
</script>
|
||||
<script src="{{ url_for('static', filename='dist/countdown.bundle.js') }}"></script>
|
||||
{% endblock scripts %}
|
|
@ -1,19 +1,20 @@
|
|||
from flask import render_template, request, flash, redirect, url_for
|
||||
|
||||
from countdown import app, forms
|
||||
from . import app
|
||||
from . import forms
|
||||
|
||||
@app.route('/<uuid:id>', methods=['GET'])
|
||||
def countdown(id):
|
||||
return render_template('countdown.html', id)
|
||||
@app.route('/<uuid:countdown_id>', methods=['GET'])
|
||||
def countdown(countdown_id):
|
||||
return render_template('countdown/countdown.html', countdown_id=countdown_id)
|
||||
|
||||
@app.route('/', methods=['GET', 'POST', 'PUT'])
|
||||
def countdown_admin():
|
||||
form = CountdownAdminForm(request.form)
|
||||
form = forms.CountdownAdminForm(request.form)
|
||||
if request.method == 'POST' and form.validate():
|
||||
user = User(form.username.data, form.email.data,
|
||||
form.password.data)
|
||||
db_session.add(user)
|
||||
# user = User(form.username.data, form.email.data,
|
||||
# form.password.data)
|
||||
# db_session.add(user)
|
||||
flash('Thanks for registering')
|
||||
return redirect(url_for('login'))
|
||||
|
||||
return render_template('countdown_admin.html', form=form, clock=None)
|
||||
return render_template('countdown/countdown_admin.html', form=form, clock=None)
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
body {
|
||||
color: red;
|
||||
@import "~reset-css/sass/reset";
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
4
forms.py
4
forms.py
|
@ -1,4 +0,0 @@
|
|||
from flask_wtf import FlaskForm, TimeField
|
||||
|
||||
class CountdownAdminForm(FlaskForm):
|
||||
totalTime = TimeField('Time')
|
|
@ -1,24 +0,0 @@
|
|||
import log from 'loglevel';
|
||||
import $ from 'jquery';
|
||||
|
||||
|
||||
const updateCountdown = () => $.getJSON({
|
||||
url: "api/v1/countdown/070f478f-e168-488c-918e-adb37c9c0cbd",
|
||||
data: Date.now(),
|
||||
success: function(countdown) {
|
||||
if(countdown.left <= 0) {
|
||||
clearInterval(scheduledUpdater);
|
||||
$('#clock').text(0);
|
||||
return;
|
||||
}
|
||||
|
||||
let floor = Math.floor(countdown.left);
|
||||
|
||||
let frac = countdown.left - floor;
|
||||
let milli = Math.floor(frac * 1000); // get in millisecond resolution
|
||||
|
||||
setTimeout(() => $('#clock').text(floor), milli);
|
||||
}
|
||||
});
|
||||
|
||||
let scheduledUpdater = setInterval(updateCountdown, 1000);
|
|
@ -1,5 +1,6 @@
|
|||
import '../css/netclock.scss';
|
||||
import log from 'loglevel';
|
||||
import $ from 'jquery';
|
||||
|
||||
if (process.env.LOG_LEVEL) {
|
||||
log.setDefaultLevel(process.env.LOG_LEVEL);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
|
||||
from api.v1 import api_v1
|
||||
app.register_blueprint(api_v1, url_prefix="/api/v1")
|
||||
from countdown import app as countdown
|
||||
app.register_blueprint(countdown, url_prefix="/countdown")
|
||||
|
||||
import views
|
||||
|
|
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -2991,6 +2991,11 @@
|
|||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
||||
"dev": true
|
||||
},
|
||||
"reset-css": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/reset-css/-/reset-css-5.0.1.tgz",
|
||||
"integrity": "sha512-VyuJdNFfp5x/W6e5wauJM59C02Vs0P22sxzZGhQMPaqu/NGTeFxlBFOOw3eq9vQd19gIDdZp7zi89ylyKOJ33Q=="
|
||||
},
|
||||
"resolve-cwd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"jquery": "^3.5.1",
|
||||
"loglevel": "^1.7.0"
|
||||
"loglevel": "^1.7.0",
|
||||
"reset-css": "^5.0.1"
|
||||
}
|
||||
}
|
||||
|
|
6
querysheet.http
Normal file
6
querysheet.http
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Create a new countdown clock with
|
||||
# 5000 seconds
|
||||
POST http://localhost:5000/countdown/api/v1
|
||||
Content-Type: application/json
|
||||
|
||||
{"total": "150"}
|
4
views.py
4
views.py
|
@ -1,9 +1,9 @@
|
|||
from flask import Flask, render_template, request, flash
|
||||
from netclock import app
|
||||
|
||||
from forms import CountdownAdminForm
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
breakpoint()
|
||||
|
||||
return render_template('netclock.html')
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ const path = require('path');
|
|||
module.exports = {
|
||||
entry: {
|
||||
netclock: './js/netclock.js',
|
||||
countdown: './js/countdown.js'
|
||||
countdown: './countdown/countdown.js'
|
||||
},
|
||||
plugins: [
|
||||
new CleanWebpackPlugin()
|
||||
|
|
Loading…
Reference in a new issue