diff --git a/.gitignore b/.gitignore index a2bf2de..2607aef 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,63 @@ -/.project -/.pydevproject +# eclipse +.project +.pydevproject + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Flask stuff: +instance/ +.webassets-cache + +# Sphinx documentation +docs/_build/ + +# Jupyter Notebook +.ipynb_checkpoints + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ \ No newline at end of file diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..533a43b --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding//src/webui/flaskr/zcm.py=utf8 diff --git a/src/webui/Dockerfile b/src/webui/Dockerfile index 6c3e285..290c13e 100644 --- a/src/webui/Dockerfile +++ b/src/webui/Dockerfile @@ -1,9 +1,7 @@ FROM python:3.9-slim -RUN apt-get update && apt-get install -y \ - gcc \ - && rm -rf /var/lib/apt/lists/* -RUN pip install flask==5.6.0 -ADD ./run.sh /run.sh -RUN chmod +x /run.sh +RUN pip install flask +COPY flaskr flaskr +COPY run.sh run.sh +ENV FLASK_APP=flaskr/zeo_db.py EXPOSE 5000 CMD /run.sh \ No newline at end of file diff --git a/src/webui/flaskr/__init__.py b/src/webui/flaskr/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/webui/flaskr/__main__.py b/src/webui/flaskr/__main__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/webui/flaskr/redis_db.py b/src/webui/flaskr/redis_db.py new file mode 100644 index 0000000..43bd109 --- /dev/null +++ b/src/webui/flaskr/redis_db.py @@ -0,0 +1,26 @@ +import time + +from flask import Flask +import redis + + +app = Flask(__name__) +cache = redis.Redis(host='redis', port=6379) + + +def get_hit_count(): + retries = 5 + while True: + try: + return cache.incr('hits') + except redis.exceptions.ConnectionError as exc: + if retries == 0: + raise exc + retries -= 1 + time.sleep(0.5) + + +@app.route('/') +def hello(): + count = get_hit_count() + return 'Hello World! I have been seen {} times.\n'.format(count) diff --git a/src/webui/flaskr/zcm.py b/src/webui/flaskr/zcm.py new file mode 100644 index 0000000..2e28135 --- /dev/null +++ b/src/webui/flaskr/zcm.py @@ -0,0 +1,94 @@ +# Copyright (c) 2016 Andreas +# See LICENSE for details. + +""" ZODB context manager """ + +# from BTrees.IOBTree import IOBTree +# from BTrees.OOBTree import OOBTree +# from persistent import Persistent +# from persistent.list import PersistentList as PList +# from persistent.mapping import PersistentMapping as PDict + +from ZEO.ClientStorage import ClientStorage +from ZODB import DB +from ZODB.FileStorage import FileStorage + + +class ZDatabase(): + """ Provides a ZODB database context manager """ + + def __init__(self, uri, **kwargs): + self.storage = create_storage(uri) + self.db = DB(self.storage, **kwargs) + + def __enter__(self): + return self.db + + def __exit__(self, exc_type, exc_value, traceback): + self.db.close() + return False + + +class ZConnection(): + """ Provides a ZODB connection with auto-abort (default). + Provides a tuple of connection and root object: + with ZConnection(db) as (cx, root): + root.one = "ok" + ZConnection implements a connection context manager. + Transaction context managers in contrast do auto-commit: + a) with db.transaction() as connection, or + b) with cx.transaction_manager as transaction, or + c) with transaction.manager as transaction (for the thread-local transaction manager) + See also http://www.zodb.org/en/latest/guide/transactions-and-threading.html + """ + def __init__(self, db, auto_commit=False, transaction_manager=None): + self.db = db + self.auto_commit = auto_commit + self.transaction_manager = transaction_manager + self.cx = None + + def __enter__(self): + if self.transaction_manager: + self.cx = self.db.open(self.transaction_manager) + else: + self.cx = self.db.open() + return self.cx, self.cx.root() + + def __exit__(self, exc_type, exc_value, traceback): + if self.auto_commit: + self.cx.transaction_manager.commit() + self.cx.close() + return False + + +def create_storage(uri): + """ supported URIs + file://e:/workspaces/zeo/bots.fs + zeo://localhost:8001 + e:/workspaces/zeo/bots.fs + @see https://en.wikipedia.org/wiki/Uniform_Resource_Identifier + """ + if uri.startswith("file://"): + storage = FileStorage(uri[7:]) + elif uri.startswith("zeo://"): + addr, port = uri[6:].split(":") + # addr_ = addr.encode("ASCII") + storage = ClientStorage((addr, int(port))) + else: + storage = FileStorage(uri) + return storage + + +def database(uri): + """ convenience function for single thread, return one connection from the pool """ + storage = create_storage(uri) + db = DB(storage) + return db + + +def connection(db): + """ Convenience function for multi thread, returns + connection, transaction manager and root + """ + cx = db.open() + return cx, cx.root() diff --git a/src/webui/flaskr/zeo_db.py b/src/webui/flaskr/zeo_db.py new file mode 100644 index 0000000..621188a --- /dev/null +++ b/src/webui/flaskr/zeo_db.py @@ -0,0 +1,25 @@ +from ZEO.ClientStorage import ClientStorage +from ZODB import DB +from flask import Flask + + +app = Flask(__name__) +storage = ClientStorage(("127.0.0.1", 8100)) +db = DB(storage) +cx = db.open() + + +def get_hit_count(): + root = cx.root() + if "hits" not in root: + root['hits'] = 0 + hits = root['hits'] + root['hits'] = hits + 1 + cx.transaction_manager.commit() + return hits + + +@app.route('/') +def hello(): + count = get_hit_count() + return 'Hello World! I have been seen {} times.\n'.format(count) diff --git a/src/webui/run.sh b/src/webui/run.sh old mode 100644 new mode 100755 index 3102c2d..149a140 --- a/src/webui/run.sh +++ b/src/webui/run.sh @@ -1,9 +1,3 @@ #!/bin/sh -# We need to add a empty Data.fs if it does not exist -# as zeo will not start without on. -if [ ! -f /var/zeo/fs/Data.fs ]; then - touch /var/zeo/fs/Data.fs -fi - -exec /usr/local/bin/runzeo -a 8100 -C /etc/zeo.conf \ No newline at end of file +exec python3 -m flask run --host=0.0.0.0 diff --git a/src/zeo/Dockerfile b/src/zeo/Dockerfile index c243f99..9b76660 100644 --- a/src/zeo/Dockerfile +++ b/src/zeo/Dockerfile @@ -4,8 +4,8 @@ RUN apt-get update && apt-get install -y \ && rm -rf /var/lib/apt/lists/* RUN pip install ZODB==5.6.0 RUN pip install ZEO==5.2.1 -ADD ./zeo.conf /etc/zeo.conf -ADD ./run.sh /run.sh +COPY ./zeo.conf /etc/zeo.conf +COPY ./run.sh /run.sh RUN chmod +x /run.sh VOLUME ["/var/zeo/fs", "/var/zeo/blobs"] EXPOSE 8100