Compare commits

..

No commits in common. "main" and "frontend" have entirely different histories.

13 changed files with 61 additions and 155 deletions

3
.gitignore vendored
View File

@ -1,3 +0,0 @@
__pycacahe__/*
freeriders/__pycacahe__/*
instance/

View File

@ -1,10 +1,3 @@
# freeriders # freeriders
Web app for tracking current ticket numbers Web app for tracking current ticket numbers
# Architecture
- keep all ticket numbers and timestamps in SQL table "tickets"
- display last ticket number
- don't allow tickets that are out of probable ticket number range
- if last submited ticket is timestamped more then 90 minutes ago, try to predict the next number

View File

@ -4,7 +4,7 @@ Priority: optional
Architecture: all Architecture: all
Essential: no Essential: no
Installed-Size: 2000 Installed-Size: 2000
Depends: gunicorn, python3-flask-sqlalchemy Depends: python3-flask, gunicorn
Homepage: https://gitea.dmz.rs/Decentrala/freeriders Homepage: https://gitea.dmz.rs/Decentrala/freeriders
Maintainer: Decentrala <dmz@dmz.rs> Maintainer: Decentrala <dmz@dmz.rs>
Description: Web app that tracks bus transport ticket numbers Description: Web app that tracks bus transport ticket numbers

View File

@ -1,16 +1,5 @@
from flask import Flask from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import os # if you wanna have db credenitalas in os.environ
app = Flask(__name__) app = Flask(__name__)
# SQLAlchemy setup
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///freeriders.db'
#MySql setup
#app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://user:pass@localhost/dbname'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
from freeriders import routes from freeriders import routes

View File

@ -1,21 +0,0 @@
import time
import datetime
def datetounix(day, month, year, hour, minute, second):
seconds = datetime.datetime(year, month, day, hour, minute, second).timestamp()
return int(seconds)
def formatprefix2(number):
return "{:02d}".format(number)
def formatprefix10(number):
return "{:010d}".format(number)
def predict(timestamp):
base_ticket = 7157662
base_timestamp = 1695887564
step = 0.688
ticket = base_ticket + (timestamp - base_timestamp) * step
return int(ticket)

View File

@ -1,6 +0,0 @@
from freeriders import db
class Tickets(db.Model):
id = db.Column(db.Integer, primary_key=True)
ticket = db.Column(db.Integer, nullable=False)
timestamp = db.Column(db.Integer, nullable=False)

View File

@ -1,58 +1,10 @@
from flask import render_template, request, redirect from flask import render_template, request, redirect
from freeriders import app, db from freeriders import app
from freeriders.functions import formatprefix2,formatprefix10, predict
from freeriders.models import Tickets
from datetime import datetime
import time
@app.route('/sms', methods=['GET']) @app.route('/', methods=['POST', 'GET'])
def sms(): def changepassword():
if request.method == 'GET': if request.method == 'GET':
timenow = int(time.time()) return render_template('index.html')
try:
lastticket = Tickets.query.order_by(Tickets.timestamp.desc()).first()
if lastticket.timestamp < timenow - (90 * 60):
lastticket = formatprefix10(predict(timenow))
else:
lastticket = formatprefix10(lastticket.ticket)
date = datetime.now()
datenow = f'{formatprefix2(date.day)}.{formatprefix2(date.month)}.{date.year}'
timenow = f'{formatprefix2(date.hour)}:{formatprefix2(date.minute)}:{formatprefix2(date.second)}'
return render_template('sms.html', ticket = lastticket, date = datenow, time = timenow)
except:
return 'Error retriving last ticket'
else:
return 'HTTP request method not recogniezed'
@app.route('/submit', methods=['POST', 'GET'])
def submit():
PREDICTTIMERANGE = 60 * 60 * 24
if request.method == 'GET':
return render_template('submit.html')
elif request.method == 'POST': elif request.method == 'POST':
timenow = int(time.time())
ticket_input = request.form['ticket']
if ticket_input.isdigit() and len(ticket_input) == 10 :
if int(ticket_input) < predict(timenow + PREDICTTIMERANGE ) and int(ticket_input) > predict(timenow - PREDICTTIMERANGE ) :
ticket = Tickets(ticket = int(ticket_input), timestamp = timenow)
else:
print(int(ticket_input))
print(predict(timenow - PREDICTTIMERANGE))
print(predict(timenow + PREDICTTIMERANGE))
print(predict(timenow))
return 'Ticket number is in unexpected range.'
else:
return 'Ticket format is wrong. Only 10 digits allowed.'
try:
db.session.add(ticket)
db.session.commit()
return 'Ticket added'
except:
return 'Adding ticket failed'
else: else:
return 'HTTP request method not recogniezed' return 'HTTP request method not recogniezed'

View File

@ -1,9 +1,9 @@
:root { :root {
--border-radus: 1rem; --border-radus: 1rem;
--background: #F9F9F9; --background: #EEE;
--header-background: #EEE; --header-background: #DDD;
--header-height: 3rem; --header-height: 3rem;
--input-bar-height: 3rem; --input-bar-height: 2rem;
} }
body{ body{
@ -14,13 +14,14 @@ body{
} }
main { main {
max-width: 400px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-self: flex-start; align-self: flex-start;
gap: 1rem; gap: 1rem;
margin: 0 auto; margin: 0 auto;
padding: 2rem 0.5rem; padding: 1rem 0.5rem;
height: calc(100vh - var(--header-height) - var(--input-bar-height)); height: calc(100vh - 5rem);
overflow-y: scroll; overflow-y: scroll;
box-sizing: border-box; box-sizing: border-box;
} }
@ -29,25 +30,22 @@ header {
background-color: var(--header-background); background-color: var(--header-background);
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; padding: 1rem;
padding: 0 1rem;
gap: 1rem; gap: 1rem;
font-weight: bold; font-weight: bold;
width: 100vw; width: 100vw;
height: var(--header-height); height: var(header-height);
box-sizing: border-box; box-sizing: border-box;
} }
footer { footer {
width: 100vw; width: 100vw;
height: var(--input-bar-height); height: var(input-bar-height);
background-color: var(--background); background-color: #FDD;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center;
padding: 0 1rem; padding: 0 1rem;
box-sizing: border-box; box-sizing: border-box;
gap: 1rem;
} }
.request { .request {
@ -69,12 +67,4 @@ footer {
.date { .date {
align-self: center; align-self: center;
margin-top: 0.5rem; margin-top: 0.5rem;
}
.textbox{
background-color: var(--header-background);
width: 80%;
height: 1rem;
padding: 0.2rem;
border-radius: 2rem;
} }

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/styles/style.css">
<link rel="shortcut icon" href="/img/favicon.ico" type="image/x-icon">
<title>Ticket tracking</title>
</head>
<body>
<main>
</main>
</body>
</html>

View File

@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Karta</title> <title>Karta</title>
<link rel="stylesheet" href="/static/style.css"> <link rel="stylesheet" href="style.css">
</head> </head>
<body> <body>
<header> <header>
@ -20,8 +20,35 @@
U Beogradu, za broj telefona ste kupili U Beogradu, za broj telefona ste kupili
VREMENSKU KARTU OD 90 MINUTA U ZONI A po VREMENSKU KARTU OD 90 MINUTA U ZONI A po
ceni od 50 din + osnovna cena poruke, ceni od 50 din + osnovna cena poruke,
koja vazi do {{ date }}, {{ time }}. koja vazi do 03.10.2023, 09:42:54.
Karta broj: {{ ticket }}. Karta broj: 0000343232.
Placanjem operateru izmirujete dugovanja
za ovu kartu prema JKP Naplata prevozne
usluge Beograd. Sacuvajte ovu poruku.
</section>
<section class='request'>
A90
</section>
<section class='ticket'>
U Beogradu, za broj telefona ste kupili
VREMENSKU KARTU OD 90 MINUTA U ZONI A po
ceni od 50 din + osnovna cena poruke,
koja vazi do 03.10.2023, 09:42:54.
Karta broj: 0000343232.
Placanjem operateru izmirujete dugovanja
za ovu kartu prema JKP Naplata prevozne
usluge Beograd. Sacuvajte ovu poruku.
</section>
<section class='date'>08:23</section>
<section class='request'>
A90
</section>
<section class='ticket'>
U Beogradu, za broj telefona ste kupili
VREMENSKU KARTU OD 90 MINUTA U ZONI A po
ceni od 50 din + osnovna cena poruke,
koja vazi do 03.10.2023, 09:42:54.
Karta broj: 0000343232.
Placanjem operateru izmirujete dugovanja Placanjem operateru izmirujete dugovanja
za ovu kartu prema JKP Naplata prevozne za ovu kartu prema JKP Naplata prevozne
usluge Beograd. Sacuvajte ovu poruku. usluge Beograd. Sacuvajte ovu poruku.
@ -32,4 +59,4 @@
<div>x</div> <div>x</div>
</footer> </footer>
</body> </body>
</html> </html>

View File

@ -1,18 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Submit</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<main>
<form action="/submit" method="POST">
<label for="ticket">ticket</label>
<input type="text" name="ticket" id="ticket" placeholder="1234567890" required>
<button> Submit </button>
</form>
</main>
</body>
</html>

View File

@ -1,10 +0,0 @@
#!/usr/bin/env python3
from freeriders import db
print('[i] Trying to create databse...')
try:
db.create_all()
print('[+] Success you can proceed with deployment!')
except:
print('[-] Creating db failed :/')

View File

@ -1,2 +1 @@
flask flask
SQLAlchemy