Skip to content

Instantly share code, notes, and snippets.

@code
Created December 2, 2009 11:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save code/247150 to your computer and use it in GitHub Desktop.
Save code/247150 to your computer and use it in GitHub Desktop.
# Editable Folder
#
# Author: luke hubbard - http://twitter.com/lukeinth
#
# Simple interface and handler to serve editable files out of memcache, db, or disk.
#
# Usage:
# - save this file as editable.py
# - create a folder called 'editable' and place your default css / html files in there
# - add handler to webapp or django or whatever framework you use
# - note this uses gaerun, see http://bit.ly/gaerun (you can comment out if you like)
#
# Example:
#
# import wsgiref.handlers
# from google.appengine.ext import webapp
# import editable
#
# def main():
# application = webapp.WSGIApplication([
# ('/editable/(.*)', editable.Handler),
# ],debug=True)
# wsgiref.handlers.CGIHandler().run(application)
#
# if __name__ == '__main__':
# main()
import gaerun
import os, sys
from google.appengine.api import memcache
from google.appengine.ext import db
import logging
import md5
def editable_key_name(folder, path):
return md5.new(os.path.join(folder,path)).hexdigest()
EDITABLE_DIR = 'editable'
class EditableFile(db.Model):
created_at = db.DateTimeProperty(auto_now_add=True)
updated_at = db.DateTimeProperty(auto_now=True)
content = db.TextProperty(required=True)
def load(path, folder=EDITABLE_DIR):
key_name = editable_key_name(folder,path)
logging.debug("Load editable file: %s key_name: %s" % (path, key_name))
content = memcache.get(key_name, None)
if content:
logging.debug("Load from memcache")
return content
editable_file = EditableFile.get_by_key_name(key_name)
if editable_file:
logging.debug("Load from DB")
memcache.set(key_name, editable_file.content)
return editable_file.content
dirname = os.path.dirname(__file__)
file = os.path.join(dirname, folder, path)
if os.path.exists(file):
logging.debug("Load from file")
f = open(file)
content = f.read()
f.close()
EditableFile(key_name=key_name, content=content).put()
memcache.set(key_name, content)
return content
def save(path, content, folder=EDITABLE_DIR):
key_name = editable_key_name(folder,path)
logging.debug("Save editable file: %s key_name: %s" % (path, key_name))
editable_file = EditableFile.get_by_key_name(key_name)
if editable_file:
editable_file.content = content
else:
editable_file = EditableFile(key_name=key_name, content=content)
editable_file.put()
memcache.set(key_name, content)
def restore(path, folder=EDITABLE_DIR):
key_name = editable_key_name(folder,path)
logging.debug("Restore editable file: %s key_name: %s" % (path, key_name))
editable_file = EditableFile.get_by_key_name(key_name)
if editable_file:
editable_file.delete()
memcache.set(key_name, None)
from google.appengine.ext import webapp
class Handler(webapp.RequestHandler):
def get(self, path):
import mimetypes
content = load(path)
if not content:
self.error(404)
return
(type, encoding) = mimetypes.guess_type(path)
if type:
self.response.headers["Content-Type"] = type
if encoding:
self.response.headers["Content-Encoding"] = encoding
self.response.out.write(content)
if __name__ == "__main__":
original = load('style.css')
print original
modified = original + "\nh2{color:black;}"
save('style.css', modified)
changed = load('style.css')
print changed
restore('style.css')
restored = load('style.css')
print restored
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment