· 9 years ago · Oct 06, 2016, 11:14 AM
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='" + 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 = str(check_distance(location, i["location"]))
60 except Exception as e:
61 print("Error, defaulting delta to 10", file=sys.stderr)
62 delta = 10
63 print(str(e), file=sys.stderr)
64 pass
65
66 if round(delta, 0) <= distance:
67 users_in_range.append(i)
68
69 return users_in_range
70
71### FLASK
72
73app = Flask(__name__)
74app.secret_key = "7d6a8sf97a89sd7f6a7s6df9as8df76asdf6s"
75SESSION_TYPE = 'filesystem'
76SESSION_PERMANENT = False
77app.config.from_object(__name__) # means getting info from THIS file
78Session(app)
79
80#~ Flask session flow, the only one entry point
81@app.route('/', methods=['GET', 'POST'])
82def index():
83 if not session:
84 print('session not found', file=sys.stderr)
85 return redirect(url_for("join"), 302)
86 else:
87 print('session found, redirecting', file=sys.stderr)
88 return redirect(url_for("sync"), 302)
89
90@app.route('/join')
91def join():
92 if not session:
93 print('session NOT found in join', file=sys.stderr)
94 return redirect(url_for("renew"), 302)
95 else:
96 print('session found in join AA', file=sys.stderr)
97 return redirect(url_for("sync"), 302)
98
99#~ Getting new uuid, with no status user is not shown to others
100@app.route('/renew/')
101def renew():
102 print('renew', file=sys.stderr)
103 session_uuid = str(uuid.uuid4())
104 session["uuid"] = session_uuid
105 session["location"] = ""
106 session["distance"] = ""
107 session["speed"] = ""
108 session["status"] = ""
109
110 print(str(session), file=sys.stderr)
111 return redirect(url_for("sync"), 302)
112
113@app.route('/sync/', methods=['GET', 'POST'])
114def sync():
115 if not session:
116 return redirect(url_for("renew"), 302)
117 else:
118 #session["uuid"] = request.values.get("uuid")
119 session["location"] = request.values.get("location") if request.values.get("location") else str(madrid)
120 session["distance"] = request.values.get("distance") if request.values.get("distance") else 10
121 session["speed"] = request.values.get("speed") if request.values.get("speed") else ""
122 session["status"] = request.values.get("status") if request.values.get("status") else 1
123 print('syncing', file=sys.stderr)
124
125 data = dict(session) # dumping data
126 print(str(data), file=sys.stderr)
127 sql.execute("DELETE FROM users WHERE uuid='" + session["uuid"] + "'")
128 sql.execute("INSERT INTO users (id, uuid, location, distance, speed, status) VALUES (NULL, :uuid, :location, :distance, :speed, :status);", data)
129 data["users_in_range"] = users_in_range(session["location"], session["distance"])
130
131 #~ return json.dumps(data)
132 return json.dumps(data["users_in_range"])
133
134if __name__ == "__main__":
135 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
136 context.load_cert_chain('localhost.crt', 'localhost.key')
137 app.run(host='0.0.0.0', port=5000, ssl_context=context, threaded=True, debug=True)