--- /dev/null
+#!/usr/bin/env python3
+#
+# FLASK_APP=restpublish.py flask run
+
+import datetime
+
+import flask
+from flask_restful import Resource, Api
+
+
+class Element:
+ def __init__(self, key, value):
+ self.key = key
+ self.update(value)
+
+ def update(self, value):
+ self.value = value
+ self.ctime = datetime.datetime.now()
+
+ def is_expired(self, maxage):
+ return datetime.datetime.now() - self.ctime >= maxage
+
+
+class ElementStore:
+ def __init__(self):
+ self.key_dict = dict()
+ self.chronolist = list()
+
+ def insert(self, key, value):
+ if key in self.key_dict:
+ el = self.key_dict[key]
+ el.update(value)
+ else:
+ el = Element(key, value)
+ self.key_dict[key] = el
+ self.chronolist.append(el)
+ return el
+
+ def remove(self, key):
+ del self.key_dict[key]
+ self.chronolist = [el for el in self.chronolist if el.key != key]
+
+ def garbagecollect(self):
+ maxage = datetime.timedelta(7)
+ oldestctime = datetime.datetime.now() - maxage
+ def is_expired(el):
+ return el.ctime < oldestctime
+
+ # Get idx such that self.chronolist[:idx] is expired and
+ # self.chronolist[idx:] is not expired.
+ idx = 0
+ while idx < len(self.chronolist) - 1:
+ if not is_expired(self.chronolist[idx]):
+ break
+ idx += 1
+
+ for el in self.chronolist[:idx]:
+ del self.key_dict[el.key]
+
+ self.chronolist = self.chronolist[idx:]
+
+
+class EntryPoint(Resource):
+ def get(self):
+ return { 'elements': [el.key for el in store.chronolist] }
+
+class ElementPoint(Resource):
+ def get(self, key):
+ if key not in store.key_dict:
+ return { 'message': 'No such element'}, 404
+
+ el = store.key_dict[key]
+ return { 'key': key, 'value': el.value, 'ctime': str(el.ctime) }
+
+ def delete(self, key):
+ if key in store.key_dict:
+ store.remove(key)
+ return { 'message': 'ok'}
+
+ def post(self, key):
+ req = flask.request.get_json(force=True)
+
+ if 'value' not in req:
+ return {'message': 'No value given.'}, 403
+
+ el = store.insert(key, req['value'])
+ store.garbagecollect()
+ return { 'key': key, 'value': el.value, 'ctime': str(el.ctime) }
+
+
+# Map of keys to values
+store = ElementStore()
+
+app = flask.Flask(__name__)
+api = Api(app)
+api.add_resource(EntryPoint, "/")
+api.add_resource(ElementPoint, "/<key>")
+