mirror of
https://github.com/google/blockly.git
synced 2026-01-04 15:40:08 +01:00
Update storage.py to use ndb instead of db.
Back-ports from Blockly Games: * db is old and busted, ndb is the new hotness (there’s no known difference, just pointless API churn). * Use SHA1 which is consistent, rather than Python’s hash() which has started changing between executions. This stops duplicate programs from being stored. * Restructure so that storage.py can be used as a library, with xmlToKey and keyToXml being callable by external programs. * Use print function compatible with Python 3.
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
print("Status: 302")
|
print("Status: 301")
|
||||||
print("Location: /static/demos/index.html")
|
print("Location: /static/demos/index.html")
|
||||||
|
print("")
|
||||||
|
|||||||
@@ -22,35 +22,32 @@ limitations under the License.
|
|||||||
__author__ = "q.neutron@gmail.com (Quynh Neutron)"
|
__author__ = "q.neutron@gmail.com (Quynh Neutron)"
|
||||||
|
|
||||||
import cgi
|
import cgi
|
||||||
|
import hashlib
|
||||||
from random import randint
|
from random import randint
|
||||||
from google.appengine.ext import db
|
|
||||||
from google.appengine.api import memcache
|
from google.appengine.api import memcache
|
||||||
import logging
|
from google.appengine.ext import ndb
|
||||||
|
|
||||||
print "Content-Type: text/plain\n"
|
|
||||||
|
|
||||||
def keyGen():
|
def keyGen():
|
||||||
# Generate a random string of length KEY_LEN.
|
# Generate a random string of length KEY_LEN.
|
||||||
KEY_LEN = 6
|
KEY_LEN = 6
|
||||||
CHARS = "abcdefghijkmnopqrstuvwxyz23456789" # Exclude l, 0, 1.
|
CHARS = "abcdefghijkmnopqrstuvwxyz23456789" # Exclude l, 0, 1.
|
||||||
max_index = len(CHARS) - 1
|
max_index = len(CHARS) - 1
|
||||||
return "".join([CHARS[randint(0, max_index)] for x in range(KEY_LEN)])
|
return "".join([CHARS[randint(0, max_index)] for x in range(KEY_LEN)])
|
||||||
|
|
||||||
class Xml(db.Model):
|
class Xml(ndb.Model):
|
||||||
# A row in the database.
|
# A row in the database.
|
||||||
xml_hash = db.IntegerProperty()
|
xml_hash = ndb.IntegerProperty()
|
||||||
xml_content = db.TextProperty()
|
xml_content = ndb.TextProperty()
|
||||||
|
|
||||||
forms = cgi.FieldStorage()
|
def xmlToKey(xml_content):
|
||||||
if "xml" in forms:
|
|
||||||
# Store XML and return a generated key.
|
# Store XML and return a generated key.
|
||||||
xml_content = forms["xml"].value
|
xml_hash = long(hashlib.sha1(xml_content).hexdigest(), 16)
|
||||||
xml_hash = hash(xml_content)
|
xml_hash = int(xml_hash % (2 ** 64) - (2 ** 63))
|
||||||
lookup_query = db.Query(Xml)
|
lookup_query = Xml.query(Xml.xml_hash == xml_hash)
|
||||||
lookup_query.filter("xml_hash =", xml_hash)
|
|
||||||
lookup_result = lookup_query.get()
|
lookup_result = lookup_query.get()
|
||||||
if lookup_result:
|
if lookup_result:
|
||||||
xml_key = lookup_result.key().name()
|
xml_key = lookup_result.key.string_id()
|
||||||
else:
|
else:
|
||||||
trials = 0
|
trials = 0
|
||||||
result = True
|
result = True
|
||||||
@@ -59,27 +56,32 @@ if "xml" in forms:
|
|||||||
if trials == 100:
|
if trials == 100:
|
||||||
raise Exception("Sorry, the generator failed to get a key for you.")
|
raise Exception("Sorry, the generator failed to get a key for you.")
|
||||||
xml_key = keyGen()
|
xml_key = keyGen()
|
||||||
result = db.get(db.Key.from_path("Xml", xml_key))
|
result = Xml.get_by_id(xml_key)
|
||||||
xml = db.Text(xml_content, encoding="utf_8")
|
row = Xml(id = xml_key, xml_hash = xml_hash, xml_content = xml_content)
|
||||||
row = Xml(key_name = xml_key, xml_hash = xml_hash, xml_content = xml)
|
|
||||||
row.put()
|
row.put()
|
||||||
print xml_key
|
return xml_key
|
||||||
|
|
||||||
if "key" in forms:
|
def keyToXml(key_provided):
|
||||||
# Retrieve stored XML based on the provided key.
|
# Retrieve stored XML based on the provided key.
|
||||||
key_provided = forms["key"].value
|
|
||||||
# Normalize the string.
|
# Normalize the string.
|
||||||
key_provided = key_provided.lower().strip()
|
key_provided = key_provided.lower().strip()
|
||||||
# Check memcache for a quick match.
|
# Check memcache for a quick match.
|
||||||
xml = memcache.get("XML_" + key_provided)
|
xml = memcache.get("XML_" + key_provided)
|
||||||
if xml is None:
|
if xml is None:
|
||||||
# Check datastore for a definitive match.
|
# Check datastore for a definitive match.
|
||||||
result = db.get(db.Key.from_path("Xml", key_provided))
|
result = Xml.get_by_id(key_provided)
|
||||||
if not result:
|
if not result:
|
||||||
xml = ""
|
xml = ""
|
||||||
else:
|
else:
|
||||||
xml = result.xml_content
|
xml = result.xml_content
|
||||||
# Save to memcache for next hit.
|
# Save to memcache for next hit.
|
||||||
if not memcache.add("XML_" + key_provided, xml, 3600):
|
memcache.add("XML_" + key_provided, xml, 3600)
|
||||||
logging.error("Memcache set failed.")
|
return xml.encode("utf-8")
|
||||||
print xml.encode("utf-8")
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("Content-Type: text/plain\n")
|
||||||
|
forms = cgi.FieldStorage()
|
||||||
|
if "xml" in forms:
|
||||||
|
print(xmlToKey(forms["xml"].value))
|
||||||
|
if "key" in forms:
|
||||||
|
print(keyToXml(forms["key"].value))
|
||||||
|
|||||||
Reference in New Issue
Block a user