kopia lustrzana https://github.com/dsblank/activitypub
				
				
				
			Working FlaskManager
							rodzic
							
								
									6e8d6be29a
								
							
						
					
					
						commit
						1dd0eb3e97
					
				|  | @ -2,6 +2,52 @@ import binascii | ||||||
| import os | import os | ||||||
| import uuid | import uuid | ||||||
| 
 | 
 | ||||||
|  | class Data(): | ||||||
|  |     routes = [] | ||||||
|  |     filters = [] | ||||||
|  | 
 | ||||||
|  | class DataWrapper(): | ||||||
|  |     """ | ||||||
|  |     Instance for saving routes, filters, etc. for app. | ||||||
|  | 
 | ||||||
|  |     >>> @app.filter | ||||||
|  |     ... def upper(item): | ||||||
|  |     ...     return item.upper() | ||||||
|  |     >>> len(app._data.filters) == 1 | ||||||
|  |     True | ||||||
|  |     >>> app._data.filters[0]("testing") | ||||||
|  |     'TESTING' | ||||||
|  |     >>> class Test(): | ||||||
|  |     ...     @app.route("/test") | ||||||
|  |     ...     def route_test(self, *args, **kwargs): | ||||||
|  |     ...         print(args, kwargs) | ||||||
|  |     ...         return 42 | ||||||
|  |     >>> t = Test() | ||||||
|  |     >>> len(app._data.routes) == 1 | ||||||
|  |     True | ||||||
|  |     >>> path, methods, function = app._data.routes[0] | ||||||
|  |     >>> function(t, 1, 2, 3, hello="world") | ||||||
|  |     (1, 2, 3) {'hello': 'world'} | ||||||
|  |     42 | ||||||
|  |     """ | ||||||
|  |     _data = Data() | ||||||
|  | 
 | ||||||
|  |     def filter(self, f): | ||||||
|  |         """ | ||||||
|  |         Wrap a plain function/method to provide template function. | ||||||
|  |         """ | ||||||
|  |         self._data.filters.append(f) | ||||||
|  |         return f | ||||||
|  | 
 | ||||||
|  |     def route(self, path, methods=None): | ||||||
|  |         """ | ||||||
|  |         Wrap a function/method as a route. | ||||||
|  |         """ | ||||||
|  |         def decorator(f): | ||||||
|  |             self._data.routes.append((path, methods, f)) | ||||||
|  |             return f | ||||||
|  |         return decorator | ||||||
|  | 
 | ||||||
| class Routes(): | class Routes(): | ||||||
|     routes = [] |     routes = [] | ||||||
| 
 | 
 | ||||||
|  | @ -45,6 +91,19 @@ class Manager(): | ||||||
|         for class_ in ActivityPubBase.CLASSES: |         for class_ in ActivityPubBase.CLASSES: | ||||||
|             setattr(self, class_, make_wrapper(self, class_)) |             setattr(self, class_, make_wrapper(self, class_)) | ||||||
| 
 | 
 | ||||||
|  |     def setup_css(self, folder="."): | ||||||
|  |         import sass | ||||||
|  |         THEME_STYLE = "light" | ||||||
|  |         THEME_COLOR = "#1d781d" | ||||||
|  |         SASS_DIR = os.path.join(os.path.abspath(folder), "sass") | ||||||
|  |         theme_css = f"$primary-color: {THEME_COLOR};\n" | ||||||
|  |         with open(os.path.join(SASS_DIR, f"{THEME_STYLE}.scss")) as f: | ||||||
|  |             theme_css += f.read() | ||||||
|  |             theme_css += "\n" | ||||||
|  |         with open(os.path.join(SASS_DIR, "base_theme.scss")) as f: | ||||||
|  |             raw_css = theme_css + f.read() | ||||||
|  |             self.CSS = sass.compile(string=raw_css, output_style="compressed") | ||||||
|  | 
 | ||||||
|     def make_defaults(self): |     def make_defaults(self): | ||||||
|         """ |         """ | ||||||
|         A default field can refer to itself, which means that it needs a |         A default field can refer to itself, which means that it needs a | ||||||
|  | @ -249,3 +308,8 @@ class Manager(): | ||||||
|         def decorator(function): |         def decorator(function): | ||||||
|             return function |             return function | ||||||
|         return decorator |         return decorator | ||||||
|  | 
 | ||||||
|  | ## Singleton for the Application | ||||||
|  | ## Allows it to be in scope for decorating the app's | ||||||
|  | ## methods and functions | ||||||
|  | app = DataWrapper() | ||||||
|  |  | ||||||
|  | @ -1,36 +1,58 @@ | ||||||
| from flask import (Flask, Response, abort, | try: | ||||||
|                    jsonify as flask_jsonify, |     from flask import (Flask, Response, abort, | ||||||
|                    redirect, render_template, |                        jsonify as flask_jsonify, | ||||||
|                    request, session, url_for) |                        redirect, render_template, | ||||||
| from flask_wtf.csrf import CSRFProtect |                        request, session, url_for) | ||||||
|  |     from flask_wtf.csrf import CSRFProtect | ||||||
|  | except: | ||||||
|  |     pass # flask not available | ||||||
| 
 | 
 | ||||||
| from .base import Manager | import inspect | ||||||
| 
 | 
 | ||||||
| class FlaskRoutes(): | from .base import Manager, app | ||||||
|     def __init__(self, manager): |  | ||||||
|         self.manager = manager |  | ||||||
| 
 | 
 | ||||||
|     def __call__(self, path, methods=["GET"]): | def wrap_method(self, f): | ||||||
|         print("Calling FlaskRoutes() with path=", path) |     def function(*args, **kwargs): | ||||||
|         def decorator(function): |         print(f.__name__, "called with:", args, kwargs) | ||||||
|             print("wrapping!") |         return f(self, *args, **kwargs) | ||||||
|             @self.manager.app.route(path) |     function.__name__ = f.__name__ | ||||||
|             def f(*args, **kwargs): |     return function | ||||||
|                 print("calling wrapped function!") |  | ||||||
|                 function(*args, **kwargs) |  | ||||||
|             print("returning") |  | ||||||
|         return decorator |  | ||||||
| 
 | 
 | ||||||
| class FlaskManager(Manager): | class FlaskManager(Manager): | ||||||
|     def __init__(self, *args, **kwargs): |     def __init__(self, *args, **kwargs): | ||||||
|         super().__init__(*args, **kwargs) |         super().__init__(*args, **kwargs) | ||||||
|         self.app = Flask(__name__) |  | ||||||
|         self.app.config.update(WTF_CSRF_CHECK_DEFAULT=False) |  | ||||||
|         self.csrf = CSRFProtect(self.app) |  | ||||||
|         print("here!") |  | ||||||
|         self.route = FlaskRoutes(self) |  | ||||||
| 
 | 
 | ||||||
|     def run(self): |     def run(self): | ||||||
|  |         self.app = Flask(__name__, | ||||||
|  |                          template_folder="/home/dblank/activitypub/apps/blog/templates/", | ||||||
|  |                          static_folder="/home/dblank/activitypub/apps/blog/static") | ||||||
|  |         self.app.config.update(WTF_CSRF_CHECK_DEFAULT=False) | ||||||
|  |         self.csrf = CSRFProtect(self.app) | ||||||
|  | 
 | ||||||
|  |         #self.app.config["EXPLAIN_TEMPLATE_LOADING"] = True | ||||||
|  |         self.app.config["ME"] = {"url": "https://example.com", | ||||||
|  |                                  "icon": {"url": "https://example.com"}, | ||||||
|  |                                  "icon_url": 'https://cs.brynmawr.edu/~dblank/images/doug-sm-orig.jpg', | ||||||
|  |                                  "summary": "I'm just me."} | ||||||
|  |         self.app.config["CSS"] = self.CSS | ||||||
|  |         self.app.config["NAME"] =  "ActivityPub Blog" | ||||||
|  |         self.app.config["ID"] = "http://localhost:5000" | ||||||
|  |         ## Add routes: | ||||||
|  |         for path, methods, f in app._data.routes: | ||||||
|  |             params = [x.name for x in inspect.signature(f).parameters.values()] | ||||||
|  |             print(f.__name__, params) | ||||||
|  |             if len(params) > 0 and params[0] == "self": | ||||||
|  |                 self.app.route(path)(wrap_method(self, f)) | ||||||
|  |             else: | ||||||
|  |                 self.app.route(path)(f) | ||||||
|  |         ## Add filters: | ||||||
|  |         for f in app._data.filters: | ||||||
|  |             params = [x.name for x in inspect.signature(f).parameters.values()] | ||||||
|  |             print(f.__name__, params) | ||||||
|  |             if len(params) > 0 and params[0] == "self": | ||||||
|  |                 self.app.template_filter()(wrap_method(self, f)) | ||||||
|  |             else: | ||||||
|  |                 self.app.template_filter()(f) | ||||||
|         self.app.run(debug=1) |         self.app.run(debug=1) | ||||||
| 
 | 
 | ||||||
|     def load_secret_key(self, name): |     def load_secret_key(self, name): | ||||||
|  |  | ||||||
|  | @ -1,5 +1,8 @@ | ||||||
| import tornado | try: | ||||||
| from tornado.web import (Application, RequestHandler) |     import tornado | ||||||
|  |     from tornado.web import (Application, RequestHandler) | ||||||
|  | except: | ||||||
|  |     pass # tornado not available | ||||||
| 
 | 
 | ||||||
| from .base import Manager | from .base import Manager | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ def test_all(): | ||||||
| 
 | 
 | ||||||
|         p1 = manager.Person(id="alyssa") |         p1 = manager.Person(id="alyssa") | ||||||
|         p2 = manager.Person(id="brenda") |         p2 = manager.Person(id="brenda") | ||||||
|          | 
 | ||||||
|         manager.database.actors.insert_one(p1.to_dict()) |         manager.database.actors.insert_one(p1.to_dict()) | ||||||
|         manager.database.actors.insert_one(p2.to_dict()) |         manager.database.actors.insert_one(p2.to_dict()) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 Douglas Blank
						Douglas Blank