· 9 years ago · Oct 06, 2016, 09:00 PM
1#!/usr/bin/env python
2#! -*- encoding: utf-8 -*-
3
4#~ create cert
5#~ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt
6
7from __future__ import print_function
8from database import *
9
10import os, sys, json, ssl
11sys.dont_write_bytecode = 1
12import uuid
13import sqlite3
14from flask import Flask, session, redirect, url_for, request
15from flask_session import Session
16from haversine import haversine
17import apsw
18
19# Sample data
20madrid = (40.2459, 3.4209)
21alicante = (38.3043, 0.2853)
22#~ print str(haversine(madrid, alicante))
23
24### SQLITE3
25
26db='casuals.db'
27multithread=True
28
29if multithread:
30 sql=MultiThreadOK(db)
31else:
32 sql=SingleThreadOnly(db)
33
34#~ con = sqlite3.connect('casuals.db')
35#~ cur = con.cursor()
36sql.execute('SELECT SQLITE_VERSION()')
37sql.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, uuid TEXT, location TEXT, distance INTEGER, status INTEGER, speed INTEGER)')
38
39#~ Returns float rounded to 2 decimals, Km
40def check_distance(origin=madrid, destination=alicante):
41 return str(round(haversine(origin, destination), 2))
42
43#~ Get all users from db
44def fetch_users(distance=10):
45 print("fetch users", file=sys.stderr)
46 #~ sqldata = sql.select("SELECT * FROM users")
47 sqldata = sql.select("SELECT uuid, location, distance, speed, status FROM users WHERE distance='" + str(session["distance"]) + "'")
48 print(str(sqldata), file=sys.stderr)
49
50 return sqldata
51
52def users_in_range(location=madrid, distance=10):
53 users = fetch_users(distance) # a
54 users_in_range = []
55 print(str(users), file=sys.stderr)
56
57 for i in users:
58 try:
59 delta = check_distance(location, i["location"])
60 print(delta, file=sys.stderr)
61 except Exception as e:
62 print("Error, defaulting delta to 10", file=sys.stderr)
63 delta = 10
64 print(str(e), file=sys.stderr)
65 pass
66
67 if round(delta, 0) <= distance:
68 users_in_range.append(i)
69
70 return users_in_range
71
72### FLASK
73
74app = Flask(__name__)
75app.secret_key = "7d6a8sf97a89sd7f6a7s6df9as8df76asdf6s"
76SESSION_TYPE = 'filesystem'
77SESSION_PERMANENT = False
78app.config.from_object(__name__) # means getting info from THIS file
79Session(app)
80
81#~ Flask session flow, the only one entry point
82@app.route('/', methods=['GET', 'POST'])
83def index():
84 if not session:
85 print('session not found', file=sys.stderr)
86 return redirect(url_for("join"), 302)
87 else:
88 print('session found, redirecting', file=sys.stderr)
89 return redirect(url_for("sync"), 302)
90
91@app.route('/join')
92def join():
93 if not session:
94 print('session NOT found in join', file=sys.stderr)
95 return redirect(url_for("renew"), 302)
96 else:
97 print('session found in join AA', file=sys.stderr)
98 return redirect(url_for("sync"), 302)
99
100#~ Getting new uuid, with no status user is not shown to others
101@app.route('/renew/')
102def renew():
103 print('renew', file=sys.stderr)
104 session_uuid = str(uuid.uuid4())
105 session["uuid"] = session_uuid
106 session["location"] = ""
107 session["distance"] = ""
108 session["speed"] = ""
109 session["status"] = ""
110
111 print(str(session), file=sys.stderr)
112 return redirect(url_for("sync"), 302)
113
114@app.route('/sync/', methods=['GET', 'POST'])
115def sync():
116 if not session:
117 return redirect(url_for("renew"), 302)
118 else:
119 #session["uuid"] = request.values.get("uuid")
120 session["location"] = request.values.get("location") if request.values.get("location") else str(madrid)
121 session["distance"] = request.values.get("distance") if request.values.get("distance") else 10
122 session["speed"] = request.values.get("speed") if request.values.get("speed") else ""
123 session["status"] = request.values.get("status") if request.values.get("status") else 1
124 print('syncing', file=sys.stderr)
125
126 data = dict(session) # dumping data
127 print(str(data), file=sys.stderr)
128 sql.execute("DELETE FROM users WHERE uuid='" + session["uuid"] + "'")
129 sql.execute("INSERT INTO users (id, uuid, location, distance, speed, status) VALUES (NULL, :uuid, :location, :distance, :speed, :status);", data)
130
131 data["users_in_range"] = users_in_range(session["location"], session["distance"])
132 #~ return json.dumps(data)
133
134 return json.dumps(data["users_in_range"])
135
136if __name__ == "__main__":
137 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
138 context.load_cert_chain('localhost.crt', 'localhost.key')
139 app.run(host='0.0.0.0', port=5000, ssl_context=context, threaded=True, debug=True)