From 78c426ccebd4c9c45c080ce262428328dfe6b74e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20B=C3=BCchner?= Date: Fri, 5 Apr 2024 04:45:27 +0200 Subject: [PATCH] support launchpad group member placeholder in facts --- requirements.txt | 2 ++ ubottu/factoids/serializers.py | 22 +++++++++++++++++++++- ubottu/factoids/views.py | 2 +- ubottu/launchpad/urls.py | 7 +++++++ ubottu/launchpad/utils.py | 32 ++++++++++++++++++++++++++++++++ ubottu/launchpad/views.py | 31 +++++++++++++++++++++++++++++++ ubottu/ubottu/urls.py | 1 + 7 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 ubottu/launchpad/urls.py create mode 100644 ubottu/launchpad/utils.py create mode 100644 ubottu/launchpad/views.py diff --git a/requirements.txt b/requirements.txt index 104c170..1c760ec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -39,3 +39,5 @@ uWSGI==2.0.24 wcwidth==0.2.13 wheel==0.43.0 yarl==1.9.4 +redis==5.0.3 + diff --git a/ubottu/factoids/serializers.py b/ubottu/factoids/serializers.py index 37dece8..9c72538 100644 --- a/ubottu/factoids/serializers.py +++ b/ubottu/factoids/serializers.py @@ -1,12 +1,32 @@ +import re +import json from rest_framework import serializers from .models import Fact +from launchpad.utils import fetch_group_members class FactSerializer(serializers.ModelSerializer): author_name = serializers.SerializerMethodField() + value = serializers.SerializerMethodField() class Meta: model = Fact fields = ['id', 'name', 'value', 'ftype', 'author_name', 'create_date', 'change_date', 'popularity'] def get_author_name(self, obj): # Assuming the author field can be null - return obj.author.username if obj.author else None \ No newline at end of file + return obj.author.username if obj.author else None + + def get_value(self, obj): + value = obj.value # The original text with placeholders + launchpad_group_pattern = r'\{launchpad_group\.([^}]+)\}' + matches = re.findall(launchpad_group_pattern, value) + if not matches: + return value + group_name = matches[0] + members = fetch_group_members(group_name) + if members is None: + return value + if 'mxids' in members: + return value.replace( '{launchpad_group.' + group_name + '}', 'https://matrix.to/#/' + ' https://matrix.to/#/'.join(members['mxids'])) + + return value + diff --git a/ubottu/factoids/views.py b/ubottu/factoids/views.py index 93a185a..cbf21e6 100644 --- a/ubottu/factoids/views.py +++ b/ubottu/factoids/views.py @@ -68,7 +68,7 @@ class FactList(APIView): fact_id = kwargs.get('id') # Check if a 'name' parameter is provided in the URL. name = kwargs.get('name') - + if fact_id: # Fetching the Fact item by id. try: diff --git a/ubottu/launchpad/urls.py b/ubottu/launchpad/urls.py new file mode 100644 index 0000000..b294c0b --- /dev/null +++ b/ubottu/launchpad/urls.py @@ -0,0 +1,7 @@ +from django.urls import path +from . import views + +urlpatterns = [ + #path('', views.list_facts, name='facts-list'), + path('api/groups/members//', views.group_members, name='get_group_members') +] diff --git a/ubottu/launchpad/utils.py b/ubottu/launchpad/utils.py new file mode 100644 index 0000000..c1e86bb --- /dev/null +++ b/ubottu/launchpad/utils.py @@ -0,0 +1,32 @@ +import redis +import json +from bugtracker.launchpad_singleton import get_launchpad + +# Connect to Redis +cache = redis.Redis(host='localhost', port=6379, db=0) + +def fetch_group_members(group_name): + try: + # Try to fetch from cache first + cached_result = cache.get(f"group_members_{group_name}") + if cached_result: + return json.loads(cached_result) + + # If not cached, fetch from Launchpad + launchpad = get_launchpad() + group = launchpad.people[group_name] + group_members = [person.name for person in group.members] + mxids = ['@' + person.name + ':ubuntu.com' for person in group.members] + result = {'group_members': group_members, 'group_name': group_name, 'mxids': mxids} + + # Cache the result with expiration time of 30 minutes (1800 seconds) + cache.setex(f"group_members_{group_name}", 1800, json.dumps(result)) + + return result + except KeyError as e: + print(f"Group with name {group_name} was not found. Error: {e}") + return False + except Exception as e: + print(f"An error occurred: {e}") + print(f"Error processing request for launchpad group {group_name}: {str(e)}") + return False diff --git a/ubottu/launchpad/views.py b/ubottu/launchpad/views.py new file mode 100644 index 0000000..b1bc16d --- /dev/null +++ b/ubottu/launchpad/views.py @@ -0,0 +1,31 @@ +from django.http import HttpResponse, Http404 +from rest_framework.views import APIView +from rest_framework.decorators import api_view +from rest_framework.response import Response +from django.shortcuts import render +from django.utils.decorators import method_decorator +from django.views.decorators.cache import cache_page +from datetime import datetime +from rest_framework import status +from bugtracker.launchpad_singleton import get_launchpad +from .utils import fetch_group_members # Adjust the import path as necessary +import pytz +import json +import requests + +@api_view(['GET']) +@cache_page(60 * 15) # Cache for 15 minutes +def group_members(self, group_name): + try: + result = fetch_group_members(group_name) + return Response({'group_members': group_members, 'group_name': group_name, 'mxids': mxids}) + except KeyError as e: + # Handle the case where the bug is not found + print(f"Group with name {group_name} was not found. Error: {e}") + return Response({'error': 'Group not found'}, status=status.HTTP_404_NOT_FOUND) + except Exception as e: + # Handle other potential exceptions + print(f"An error occurred: {e}") + print(f"Error processing request for launchpad group {group_name}: {str(e)}") + return Response({'error': 'An error occurred processing your request'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + diff --git a/ubottu/ubottu/urls.py b/ubottu/ubottu/urls.py index 8625bbb..06987ff 100644 --- a/ubottu/ubottu/urls.py +++ b/ubottu/ubottu/urls.py @@ -5,6 +5,7 @@ from django.shortcuts import redirect urlpatterns = [ path("factoids/", include("factoids.urls")), path("bugtracker/", include("bugtracker.urls")), + path("launchpad/", include("launchpad.urls")), path("admin/", admin.site.urls), path('', lambda request: redirect('factoids/', permanent=False)), # Redirect from root to 'factoids' ] \ No newline at end of file