@@ -3,16 +3,23 @@ from flask_redis import FlaskRedis | |||||
import json, abp, markdown | import json, abp, markdown | ||||
from pprint import pprint | from pprint import pprint | ||||
import raussendorf | import raussendorf | ||||
import humanhash | |||||
DAY = 60*60*24 | |||||
app = Flask(__name__) | app = Flask(__name__) | ||||
redis = FlaskRedis(app) | redis = FlaskRedis(app) | ||||
@app.route("/") | @app.route("/") | ||||
def index(): | def index(): | ||||
return render_template("index.html") | |||||
secret, uuid = humanhash.uuid() | |||||
return redirect("/{}".format(secret)) | |||||
@app.route("/graph", methods=["GET", "POST"]) | |||||
def graph(): | |||||
@app.route("/<uuid>") | |||||
def main(uuid): | |||||
return render_template("index.html", uuid=uuid) | |||||
@app.route("/<uuid>/graph", methods=["GET", "POST"]) | |||||
def graph(uuid): | |||||
if request.method == 'POST': | if request.method == 'POST': | ||||
# Convert the data to a graph state | # Convert the data to a graph state | ||||
g = abp.GraphState() | g = abp.GraphState() | ||||
@@ -22,21 +29,24 @@ def graph(): | |||||
data = json.dumps(g.to_json(stringify=True)) | data = json.dumps(g.to_json(stringify=True)) | ||||
# Insert into the database | # Insert into the database | ||||
redis.execute_command("SET", "graph", data) | |||||
redis.setex(uuid, data, DAY) | |||||
# Return success | # Return success | ||||
return "Posted {} bytes OK".format(len(data)) | return "Posted {} bytes OK".format(len(data)) | ||||
elif redis.exists(uuid): | |||||
return redis.get(uuid) | |||||
else: | else: | ||||
# Get from the database | |||||
return redis.get("graph") | |||||
g = abp.GraphState() | |||||
data = json.dumps(g.to_json(stringify=True)) | |||||
redis.setex(uuid, DAY, data) | |||||
return data | |||||
@app.route("/edit", methods=["POST"]) | |||||
def edit(): | |||||
@app.route("/<uuid>/edit", methods=["POST"]) | |||||
def edit(uuid): | |||||
# Load the graph from the database | # Load the graph from the database | ||||
g = abp.GraphState() | g = abp.GraphState() | ||||
g.from_json(json.loads(redis.get("graph"))) | |||||
g.from_json(json.loads(redis.get(uuid))) | |||||
# Apply the edit to the graph | # Apply the edit to the graph | ||||
edit = json.loads(request.data) | edit = json.loads(request.data) | ||||
@@ -66,7 +76,7 @@ def edit(): | |||||
# New state into JSON and database | # New state into JSON and database | ||||
data = json.dumps(g.to_json(stringify=True)) | data = json.dumps(g.to_json(stringify=True)) | ||||
redis.execute_command("SET", "graph", data) | |||||
redis.setex(uuid, DAY, data) | |||||
return data | return data | ||||
@@ -1,4 +1,5 @@ | |||||
html, body { margin: 0; padding: 0; overflow: hidden; font-size: 10pt; font-family: monospace; } | |||||
html, body { margin: 0; padding: 0; overflow: hidden; font-size: 10pt; | |||||
font-family: monospace; } | |||||
#node_info { | #node_info { | ||||
background: rgba(0, 0, 0, .8); | background: rgba(0, 0, 0, .8); | ||||
color:white; | color:white; | ||||
@@ -7,23 +8,20 @@ html, body { margin: 0; padding: 0; overflow: hidden; font-size: 10pt; font-fam | |||||
position: absolute; | position: absolute; | ||||
top:5px; | top:5px; | ||||
left:5px; | left:5px; | ||||
font-family: monospace; | |||||
/*font-family: monospace;*/ | |||||
text-align: center; | text-align: center; | ||||
font-size:9pt; | |||||
/*height:15px;*/ | /*height:15px;*/ | ||||
border-radius:3px; | border-radius:3px; | ||||
pointer-events: none; | pointer-events: none; | ||||
} | } | ||||
#server_info { | #server_info { | ||||
background-color: black; | |||||
background-color: rgba(0, 0, 0, .8); | |||||
color:white; | color:white; | ||||
padding: 10px; | padding: 10px; | ||||
font-family: monospace; | |||||
position: absolute; | position: absolute; | ||||
top: 10px; | top: 10px; | ||||
right: 10px; | right: 10px; | ||||
font-size: 9pt; | |||||
} | } | ||||
#node_name { | #node_name { | ||||
@@ -31,25 +29,21 @@ html, body { margin: 0; padding: 0; overflow: hidden; font-size: 10pt; font-fam | |||||
} | } | ||||
#node_data { | #node_data { | ||||
background-color: black; | |||||
background-color: rgba(0, 0, 0, .8); | |||||
color:white; | color:white; | ||||
padding: 10px; | padding: 10px; | ||||
font-family: monospace; | |||||
position: absolute; | position: absolute; | ||||
top: 10px; | top: 10px; | ||||
left: 10px; | left: 10px; | ||||
font-size: 9pt; | |||||
} | } | ||||
#controls { | #controls { | ||||
background-color: black; | |||||
background-color: rgba(0, 0, 0, .8); | |||||
color:white; | color:white; | ||||
padding: 10px; | padding: 10px; | ||||
font-family: monospace; | |||||
position: absolute; | position: absolute; | ||||
bottom: 10px; | bottom: 10px; | ||||
left: 10px; | left: 10px; | ||||
font-size: 9pt; | |||||
} | } | ||||
#controls a { | #controls a { | ||||
@@ -60,6 +54,7 @@ html, body { margin: 0; padding: 0; overflow: hidden; font-size: 10pt; font-fam | |||||
margin: 1px; | margin: 1px; | ||||
display: inline-block; | display: inline-block; | ||||
text-decoration: none; | text-decoration: none; | ||||
cursor: pointer; | |||||
} | } | ||||
#node_data a { | #node_data a { | ||||
@@ -70,31 +65,29 @@ html, body { margin: 0; padding: 0; overflow: hidden; font-size: 10pt; font-fam | |||||
margin: 1px; | margin: 1px; | ||||
display: inline-block; | display: inline-block; | ||||
text-decoration: none; | text-decoration: none; | ||||
cursor: pointer; | |||||
} | } | ||||
#version { | #version { | ||||
color:black; | color:black; | ||||
padding: 10px; | padding: 10px; | ||||
font-family: monospace; | |||||
position: absolute; | position: absolute; | ||||
bottom: 10px; | bottom: 10px; | ||||
left: 10px; | left: 10px; | ||||
font-size: 9pt; | |||||
} | } | ||||
#help { | #help { | ||||
color:black; | |||||
background-color: rgba(0, 0, 0, .8); | |||||
color:white; | |||||
padding: 10px; | padding: 10px; | ||||
font-family: monospace; | |||||
position: absolute; | position: absolute; | ||||
bottom: 10px; | bottom: 10px; | ||||
right: 10px; | right: 10px; | ||||
font-size: 9pt; | |||||
} | } | ||||
#help a{ | #help a{ | ||||
color: black; | |||||
color: white; | |||||
} | } | ||||
@@ -11,7 +11,7 @@ api.poll = function() { | |||||
}; | }; | ||||
// Send the request | // Send the request | ||||
xmlhttp.open("GET", "/graph", true); | |||||
xmlhttp.open("GET", window.location.href+"/graph", true); | |||||
xmlhttp.send(); | xmlhttp.send(); | ||||
}; | }; | ||||
@@ -32,7 +32,7 @@ api.edit = function(edit) { | |||||
}; | }; | ||||
// Send the request | // Send the request | ||||
xmlhttp.open("POST", "/edit", true); | |||||
xmlhttp.open("POST", window.location.href+"/edit", true); | |||||
xmlhttp.setRequestHeader("Content-Type", "application/json"); | xmlhttp.setRequestHeader("Content-Type", "application/json"); | ||||
xmlhttp.send(JSON.stringify(edit)); | xmlhttp.send(JSON.stringify(edit)); | ||||
} | } | ||||
@@ -6,5 +6,6 @@ window.onload = function() { | |||||
gui.prepare(); | gui.prepare(); | ||||
mouse.prepare(); | mouse.prepare(); | ||||
editor.prepare(); | editor.prepare(); | ||||
api.poll(); | |||||
gui.loop(); | gui.loop(); | ||||
}; | }; |
@@ -24,45 +24,33 @@ | |||||
<div id=node_info class=hidden> </div> | <div id=node_info class=hidden> </div> | ||||
<div id=server_info class=hidden> </div> | <div id=server_info class=hidden> </div> | ||||
<!--<div id=version>ABP version 0.4.27</div>--> | |||||
<div id=node_data class=hidden> | <div id=node_data class=hidden> | ||||
<div id=node_name></div> | <div id=node_name></div> | ||||
<ul> | <ul> | ||||
<li id=node_vop></li> | <li id=node_vop></li> | ||||
<li>Measure in | <li>Measure in | ||||
<a href="#" onclick="editor.measureX()">X</a> / | |||||
<a href="#" onclick="editor.measureY()">Y</a> / | |||||
<a href="#" onclick="editor.measureZ()">Z</a></li> | |||||
<a onclick="editor.measureX()">X</a> / | |||||
<a onclick="editor.measureY()">Y</a> / | |||||
<a onclick="editor.measureZ()">Z</a></li> | |||||
<li>Act | <li>Act | ||||
<a href="#" onclick="editor.hadamard()">Hadamard</a> / | |||||
<a href="#" onclick="editor.phase()">Phase</a></li> | |||||
<li><a href="#" onclick="editor.localComplementation()">Invert neighbourhood</a></li> | |||||
<li><a href="#" onclick="editor.deleteNode()">Delete</a></li> | |||||
<a onclick="editor.hadamard()">Hadamard</a> / | |||||
<a onclick="editor.phase()">Phase</a></li> | |||||
<li><a onclick="editor.localComplementation()">Invert neighbourhood</a></li> | |||||
<li><a onclick="editor.deleteNode()">Delete</a></li> | |||||
</ul> | </ul> | ||||
</div> | </div> | ||||
<div id=controls> | <div id=controls> | ||||
<ul> | <ul> | ||||
<li><a href="#" onclick="editor.clear()">Clear graph</a></li> | |||||
<li><a href="#" onclick="editor.raussendorf()">Replace with Raussendorf</a></li> | |||||
<li><a onclick="editor.clear()">Clear graph</a></li> | |||||
<li><a onclick="editor.raussendorf()">Raussendorf</a></li> | |||||
<li><a onclick="editor.raussendorf()">Share</a></li> | |||||
</ul> | </ul> | ||||
</div> | </div> | ||||
<div id=help> | <div id=help> | ||||
<h3>Usage:</h3> | |||||
Click on the grid to make a new node<br/> | |||||
Ctrl-click a node to do a Hadamard<br/> | |||||
Select a node, then shift-click another node to do a CZ<br/> | |||||
Press space to rotate the grid<br/> | |||||
<h3>API usage:</h3> | |||||
GET https://abv.peteshadbolt.co.uk/graph -> JSON<br/> | |||||
POST JSON -> https://abv.peteshadbolt.co.uk/graph<br/> | |||||
POST JSON -> https://abv.peteshadbolt.co.uk/edit | |||||
<p>See <a href="/doc">here</a> for docs.</p> | |||||
<a href="/doc">Help</a> | |||||
</div> | </div> | ||||
</body> | </body> | ||||