From 634c652d579a4fec44fb124e1080adaf2d3ad45a Mon Sep 17 00:00:00 2001 From: Tykayn Date: Sun, 21 Sep 2025 13:35:01 +0200 Subject: [PATCH] demo signal buttons --- backend.py | 1 + oedb/resources/demo.py | 996 +----------------------- oedb/resources/demo/__init__.py | 28 + oedb/resources/demo/demo_main.py | 417 ++++++++++ oedb/resources/demo/demo_traffic.py | 794 +++++++++++++++++++ oedb/resources/demo/demo_view_events.py | 424 ++++++++++ 6 files changed, 1680 insertions(+), 980 deletions(-) create mode 100644 oedb/resources/demo/__init__.py create mode 100644 oedb/resources/demo/demo_main.py create mode 100644 oedb/resources/demo/demo_traffic.py create mode 100644 oedb/resources/demo/demo_view_events.py diff --git a/backend.py b/backend.py index 8fac739..7f36ad7 100644 --- a/backend.py +++ b/backend.py @@ -63,6 +63,7 @@ def create_app(): app.add_route('/demo/map-by-what', demo, suffix='map_by_what') # Handle map by event type page app.add_route('/demo/edit/{id}', demo, suffix='edit') # Handle event editing page app.add_route('/demo/traffic', demo, suffix='traffic') # Handle traffic jam reporting page + app.add_route('/demo/view-events', demo, suffix='view_events') # Handle view saved events page logger.success("Application initialized successfully") return app diff --git a/oedb/resources/demo.py b/oedb/resources/demo.py index c6a8bfc..d0cdc43 100644 --- a/oedb/resources/demo.py +++ b/oedb/resources/demo.py @@ -1,5 +1,6 @@ """ Demo resource for the OpenEventDatabase. +This module imports and re-exports the demo resources from the demo package. """ import falcon @@ -9,6 +10,7 @@ import os from collections import defaultdict from oedb.utils.logging import logger from oedb.utils.db import load_env_from_file +from oedb.resources.demo import demo_main, demo_traffic, demo_view_events class DemoResource: """ @@ -421,403 +423,13 @@ class DemoResource: def on_get(self, req, resp): """ Handle GET requests to the /demo endpoint. - Returns an HTML page with a MapLibre map showing current events. + Delegates to the demo_main resource. Args: req: The request object. resp: The response object. """ - logger.info("Processing GET request to /demo") - - try: - # Set content type to HTML - resp.content_type = 'text/html' - - # Create HTML response with MapLibre map - html = """ - - - - - - OpenEventDatabase Demo - - - - - - - -
-
-

OpenEventDatabase Demo

-

This map shows current events from the OpenEventDatabase.

-

API Endpoints:

- -

Demo Pages:

- -

+ Add New Event

-

- - - -

-
-
-

Map Style

- - - -
- - - - - """ - - # Set the response body and status - resp.text = html - resp.status = falcon.HTTP_200 - logger.success("Successfully processed GET request to /demo") - except Exception as e: - logger.error(f"Error processing GET request to /demo: {e}") - resp.status = falcon.HTTP_500 - resp.text = f"Error: {str(e)}" + return demo_main.on_get(req, resp) def on_get_by_what(self, req, resp): """ @@ -2309,600 +1921,24 @@ class DemoResource: def on_get_traffic(self, req, resp): """ Handle GET requests to the /demo/traffic endpoint. - Returns an HTML page with a form for reporting traffic jams. + Delegates to the demo_traffic resource. Args: req: The request object. resp: The response object. """ - logger.info("Processing GET request to /demo/traffic") + return demo_traffic.on_get(req, resp) + + def on_get_view_events(self, req, resp): + """ + Handle GET requests to the /demo/view-events endpoint. + Delegates to the demo_view_events resource. - try: - # Set content type to HTML - resp.content_type = 'text/html' - - # Load environment variables from .env file - load_env_from_file() - - # Get OAuth2 configuration parameters - client_id = os.getenv("CLIENT_ID", "") - client_secret = os.getenv("CLIENT_SECRET", "") - client_authorizations = os.getenv("CLIENT_AUTORIZATIONS", "read_prefs") - client_redirect = os.getenv("CLIENT_REDIRECT", "") - - # Check if we have an authorization code in the query parameters - auth_code = req.params.get('code', None) - auth_state = req.params.get('state', None) - - # Variables to track authentication state - is_authenticated = False - osm_username = "" - osm_user_id = "" - - # If we have an authorization code, exchange it for an access token - if auth_code: - logger.info(f"Received authorization code: {auth_code}") - - try: - # Exchange authorization code for access token - token_url = "https://www.openstreetmap.org/oauth2/token" - token_data = { - "grant_type": "authorization_code", - "code": auth_code, - "redirect_uri": client_redirect, - "client_id": client_id, - "client_secret": client_secret - } - - token_response = requests.post(token_url, data=token_data) - token_response.raise_for_status() - token_info = token_response.json() - - access_token = token_info.get("access_token") - - if access_token: - # Use access token to get user information - user_url = "https://api.openstreetmap.org/api/0.6/user/details.json" - headers = {"Authorization": f"Bearer {access_token}"} - - user_response = requests.get(user_url, headers=headers) - user_response.raise_for_status() - user_info = user_response.json() - - # Extract user information - user = user_info.get("user", {}) - osm_username = user.get("display_name", "") - osm_user_id = user.get("id", "") - - if osm_username: - is_authenticated = True - logger.info(f"User authenticated: {osm_username} (ID: {osm_user_id})") - else: - logger.error("Failed to get OSM username from user details") - else: - logger.error("Failed to get access token from token response") - except Exception as e: - logger.error(f"Error during OAuth2 token exchange: {e}") - - # Create HTML response with form - # Start with the common HTML header - html_header = f""" - - - - - - Report Traffic Jam - OpenEventDatabase - - - - - -
- - -

Report Traffic Jam

- -
-

OpenStreetMap Authentication

- """ - - # Add authentication section based on authentication status - if is_authenticated: - auth_section = f""" -
-
-

Logged in as {osm_username}

-

View OSM Profile

- - -
-
- """ - else: - auth_section = f""" -

Authenticate with your OpenStreetMap account to include your username in the traffic report.

- - """ - - # Add the rest of the HTML template - html_footer = """ -
- - - -
-
- - -
- -
-
- - -
- -
- - -
-
- -
-
- - -
- -
- - -
-
- -
- - -
- -
- -
-
Click on the map to set the traffic jam location or use the "Get My Current Location" button
-
- - -
- -
-
- - - - - """ - - # Concatenate the HTML parts to form the complete template - html = html_header + auth_section + html_footer - - # Set the response body and status - resp.text = html - resp.status = falcon.HTTP_200 - logger.success("Successfully processed GET request to /demo/traffic") - except Exception as e: - logger.error(f"Error processing GET request to /demo/traffic: {e}") - resp.status = falcon.HTTP_500 - resp.text = f"Error: {str(e)}" + Args: + req: The request object. + resp: The response object. + """ + return demo_view_events.on_get(req, resp) # Create a global instance of DemoResource demo = DemoResource() \ No newline at end of file diff --git a/oedb/resources/demo/__init__.py b/oedb/resources/demo/__init__.py new file mode 100644 index 0000000..f47cd7f --- /dev/null +++ b/oedb/resources/demo/__init__.py @@ -0,0 +1,28 @@ +""" +Demo package for the OpenEventDatabase. +This package contains modules for the demo endpoints. +""" + +from oedb.resources.demo.demo_main import demo_main +from oedb.resources.demo.demo_traffic import demo_traffic +from oedb.resources.demo.demo_view_events import demo_view_events + +# Import DemoResource class from the original demo.py file +import sys +import os +import importlib.util + +# Get the path to the original demo.py file +demo_py_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'demo.py') + +# Load the demo.py module +spec = importlib.util.spec_from_file_location("oedb.resources.demo_original", demo_py_path) +demo_original = importlib.util.module_from_spec(spec) +sys.modules["oedb.resources.demo_original"] = demo_original +spec.loader.exec_module(demo_original) + +# Get the demo object from the original module +demo = demo_original.demo + +# Export the demo resources and the demo object +__all__ = ['demo_main', 'demo_traffic', 'demo_view_events', 'demo'] \ No newline at end of file diff --git a/oedb/resources/demo/demo_main.py b/oedb/resources/demo/demo_main.py new file mode 100644 index 0000000..8e91b16 --- /dev/null +++ b/oedb/resources/demo/demo_main.py @@ -0,0 +1,417 @@ +""" +Main demo page resource for the OpenEventDatabase. +""" + +import falcon +from oedb.utils.logging import logger + +class DemoMainResource: + """ + Resource for the main demo page. + Handles the /demo endpoint. + """ + + def on_get(self, req, resp): + """ + Handle GET requests to the /demo endpoint. + Returns an HTML page with a MapLibre map showing current events. + + Args: + req: The request object. + resp: The response object. + """ + logger.info("Processing GET request to /demo") + + try: + # Set content type to HTML + resp.content_type = 'text/html' + + # Create HTML response with MapLibre map + html = """ + + + + + + OpenEventDatabase Demo + + + + + + + +
+
+

OpenEventDatabase Demo

+

This map shows current events from the OpenEventDatabase.

+

API Endpoints:

+ +

Demo Pages:

+ +

+ Add New Event

+

+ + + +

+
+
+

Map Style

+ + + +
+ + + + + """ + + # Set the response body and status + resp.text = html + resp.status = falcon.HTTP_200 + logger.success("Successfully processed GET request to /demo") + except Exception as e: + logger.error(f"Error processing GET request to /demo: {e}") + resp.status = falcon.HTTP_500 + resp.text = f"Error: {str(e)}" + +# Create a global instance of DemoMainResource +demo_main = DemoMainResource() \ No newline at end of file diff --git a/oedb/resources/demo/demo_traffic.py b/oedb/resources/demo/demo_traffic.py new file mode 100644 index 0000000..d16594d --- /dev/null +++ b/oedb/resources/demo/demo_traffic.py @@ -0,0 +1,794 @@ +""" +Traffic jam reporting resource for the OpenEventDatabase. +""" + +import falcon +import os +import requests +from oedb.utils.logging import logger +from oedb.utils.db import load_env_from_file + +class DemoTrafficResource: + """ + Resource for the traffic jam reporting page. + Handles the /demo/traffic endpoint. + """ + + def on_get(self, req, resp): + """ + Handle GET requests to the /demo/traffic endpoint. + Returns an HTML page with a form for reporting traffic jams. + + Args: + req: The request object. + resp: The response object. + """ + logger.info("Processing GET request to /demo/traffic") + + try: + # Set content type to HTML + resp.content_type = 'text/html' + + # Load environment variables from .env file + load_env_from_file() + + # Get OAuth2 configuration parameters + client_id = os.getenv("CLIENT_ID", "") + client_secret = os.getenv("CLIENT_SECRET", "") + client_authorizations = os.getenv("CLIENT_AUTORIZATIONS", "read_prefs") + client_redirect = os.getenv("CLIENT_REDIRECT", "") + + # Check if we have an authorization code in the query parameters + auth_code = req.params.get('code', None) + auth_state = req.params.get('state', None) + + # Variables to track authentication state + is_authenticated = False + osm_username = "" + osm_user_id = "" + + # If we have an authorization code, exchange it for an access token + if auth_code: + logger.info(f"Received authorization code: {auth_code}") + + try: + # Exchange authorization code for access token + token_url = "https://www.openstreetmap.org/oauth2/token" + token_data = { + "grant_type": "authorization_code", + "code": auth_code, + "redirect_uri": client_redirect, + "client_id": client_id, + "client_secret": client_secret + } + + token_response = requests.post(token_url, data=token_data) + token_response.raise_for_status() + token_info = token_response.json() + + access_token = token_info.get("access_token") + + if access_token: + # Use access token to get user information + user_url = "https://api.openstreetmap.org/api/0.6/user/details.json" + headers = {"Authorization": f"Bearer {access_token}"} + + user_response = requests.get(user_url, headers=headers) + user_response.raise_for_status() + user_info = user_response.json() + + # Extract user information + user = user_info.get("user", {}) + osm_username = user.get("display_name", "") + osm_user_id = user.get("id", "") + + if osm_username: + is_authenticated = True + logger.info(f"User authenticated: {osm_username} (ID: {osm_user_id})") + else: + logger.error("Failed to get OSM username from user details") + else: + logger.error("Failed to get access token from token response") + except Exception as e: + logger.error(f"Error during OAuth2 token exchange: {e}") + + # Create HTML response with form + # Start with the common HTML header + html_header = f""" + + + + + + Report Traffic Jam - OpenEventDatabase + + + + + + +
+ + +

Report Road Issue

+ +
+

OpenStreetMap Authentication

+ """ + + # Add authentication section based on authentication status + if is_authenticated: + auth_section = f""" +
+
+

Logged in as {osm_username}

+

View OSM Profile

+ + +
+
+ """ + else: + auth_section = f""" +

Authenticate with your OpenStreetMap account to include your username in the traffic report.

+ + """ + + # Add the rest of the HTML template + html_footer = """ +
+ +

Select Issue Type

+
+
+ + Pothole +
+
+ + Obstacle +
+
+ + Vehicle on Side +
+
+ + Danger +
+
+ + + +
+
+ + +
+ + + +
+
+ + +
+ +
+ + +
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+ + +
+ +
+ +
+
Click on the map to set the issue location or use the "Get My Current Location" button
+
+ + +
+ +
+ + + View All Saved Events on Map + +
+ + + + + """ + + # Concatenate the HTML parts to form the complete template + html = html_header + auth_section + html_footer + + # Set the response body and status + resp.text = html + resp.status = falcon.HTTP_200 + logger.success("Successfully processed GET request to /demo/traffic") + except Exception as e: + logger.error(f"Error processing GET request to /demo/traffic: {e}") + resp.status = falcon.HTTP_500 + resp.text = f"Error: {str(e)}" + +# Create a global instance of DemoTrafficResource +demo_traffic = DemoTrafficResource() \ No newline at end of file diff --git a/oedb/resources/demo/demo_view_events.py b/oedb/resources/demo/demo_view_events.py new file mode 100644 index 0000000..6500d03 --- /dev/null +++ b/oedb/resources/demo/demo_view_events.py @@ -0,0 +1,424 @@ +""" +View saved events resource for the OpenEventDatabase. +""" + +import falcon +from oedb.utils.logging import logger + +class DemoViewEventsResource: + """ + Resource for viewing saved events. + Handles the /demo/view-events endpoint. + """ + + def on_get(self, req, resp): + """ + Handle GET requests to the /demo/view-events endpoint. + Returns an HTML page with a map showing events stored in localStorage. + + Args: + req: The request object. + resp: The response object. + """ + logger.info("Processing GET request to /demo/view-events") + + try: + # Set content type to HTML + resp.content_type = 'text/html' + + # Create HTML response with MapLibre map + html = """ + + + + + + View Saved Events - OpenEventDatabase + + + + + + +
+ +
+

Your Saved Events

+ + + +
+ +
+ +
+ + +
+
+ + + + + """ + + # Set the response body and status + resp.text = html + resp.status = falcon.HTTP_200 + logger.success("Successfully processed GET request to /demo/view-events") + except Exception as e: + logger.error(f"Error processing GET request to /demo/view-events: {e}") + resp.status = falcon.HTTP_500 + resp.text = f"Error: {str(e)}" + +# Create a global instance of DemoViewEventsResource +demo_view_events = DemoViewEventsResource() \ No newline at end of file