Merge branch 'main' of ssh://git.buechner.me:2222/nbuechner/ubottu-web

This commit is contained in:
Nils Büchner 2024-07-18 16:33:41 +02:00
commit 5cfbbe4b28
8 changed files with 136 additions and 11 deletions

2
.gitignore vendored
View file

@ -16,3 +16,5 @@ src
*.log
plugins/*
ubottu/maubot.db
ubottu/ubottu/settings.py
ubottu/ubottu/static/*

View file

@ -2,9 +2,11 @@ aiohttp==3.9.3
aiosignal==1.3.1
aiosqlite==0.18.0
asgiref==3.8.1
async-timeout==4.0.3
asyncpg==0.28.0
attrs==23.2.0
bcrypt==4.1.2
blinker==1.4
Brotli==1.1.0
certifi==2024.2.2
cffi==1.16.0
@ -12,32 +14,60 @@ charset-normalizer==3.3.2
click==8.1.7
colorama==0.4.6
commonmark==0.9.1
cryptography==3.4.8
dbus-python==1.2.18
distro==1.7.0
Django==5.0.3
djangorestframework==3.15.1
feedparser==6.0.11
frozenlist==1.4.1
geographiclib==2.0
geopy==2.4.1
h3==3.7.7
httplib2==0.20.2
idna==3.6
importlib-metadata==4.6.4
jeepney==0.7.1
Jinja2==3.1.3
keyring==23.5.0
launchpadlib==1.10.16
lazr.restfulclient==0.14.4
lazr.uri==1.0.6
MarkupSafe==2.1.5
more-itertools==8.10.0
multidict==6.0.5
mysqlclient==2.2.4
mysqlclient==2.1.1
netifaces==0.11.0
numpy==2.0.0
oauthlib==3.2.0
packaging==24.0
prompt-toolkit==3.0.43
pycparser==2.21
PyGObject==3.42.1
PyJWT==2.3.0
pyparsing==2.4.7
python-apt==2.4.0+ubuntu3
python-olm==3.2.16
pytz==2024.1
PyYAML==5.4.1
questionary==1.10.0
redis==5.0.3
requests==2.31.0
ruamel.yaml==0.17.40
ruamel.yaml.clib==0.2.8
SecretStorage==3.3.1
sgmllib3k==1.0.0
six==1.16.0
SQLAlchemy==1.3.24
sqlparse==0.4.4
ssh-import-id==5.11
timezonefinder==6.5.2
typing_extensions==4.12.2
ubuntu-pro-client==8001
urllib3==2.2.1
uWSGI==2.0.24
wadllib==1.3.6
wcwidth==0.2.13
wheel==0.43.0
yarl==1.9.4
redis==5.0.3
zipp==1.0.0
bs4

View file

@ -0,0 +1,39 @@
# Generated by Django 5.0.3 on 2024-07-17 10:08
import django.db.models.deletion
import django.utils.timezone
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Author',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=64)),
],
),
migrations.CreateModel(
name='Fact',
fields=[
('name', models.CharField(max_length=32)),
('value', models.TextField()),
('ftype', models.CharField(choices=[('REPLY', 'Reply'), ('ALIAS', 'Alias')], default='REPLY', max_length=32)),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('room', models.CharField(blank=True, default=None, max_length=128, null=True)),
('create_date', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date published')),
('change_date', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date changed')),
('popularity', models.IntegerField(default=0)),
('author', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
],
),
]

View file

View file

@ -3,5 +3,6 @@ from . import views
urlpatterns = [
#path('', views.list_facts, name='facts-list'),
path('api/groups/members/<str:group_name>/', views.group_members, name='get_group_members')
path('api/groups/members/<str:group_name>/', views.group_members, name='get_group_members'),
path('api/people/<str:profile_id>/socials/matrix', views.matrix_profiles, name='get_matrix_accounts')
]

View file

@ -1,11 +1,48 @@
import redis
import json
import traceback
from bugtracker.launchpad_singleton import get_launchpad
from . launchpad_singleton import get_launchpad
import requests
from bs4 import BeautifulSoup
# Connect to Redis
cache = redis.Redis(host='localhost', port=6379, db=0)
def fetch_matrix_accounts(profile_id):
try:
#Try to fetch from cache first
cached_result = cache.get(f"matrix_{profile_id}")
if cached_result:
return json.loads(cached_result)
# Fetch the page
url = "https://launchpad.net/~" + profile_id
response = requests.get(url)
page_content = response.content
# Parse the page content
soup = BeautifulSoup(page_content, 'html.parser')
# Locate the elements containing the Matrix IDs
matrix_ids_elements = soup.find_all('dd', class_='user-social-accounts__item matrix-account')
# Extract the Matrix IDs
matrix_ids = []
for element in matrix_ids_elements:
matrix_id = element.find('a').text.strip()
matrix_ids.append(matrix_id)
# Cache the result with expiration time of 30 minutes (1800 seconds)
cache.setex(f"matrix_{profile_id}", 1800, json.dumps(matrix_ids))
except KeyError as e:
print(f"Profule with name {profile_id} was not found. Error: {e}")
print(traceback.format_exc())
return False
except Exception as e:
print(f"An error occurred: {e}")
print(traceback.format_exc())
return False
def fetch_group_members(group_name, recurse=False):
try:
@ -25,7 +62,6 @@ def fetch_group_members(group_name, recurse=False):
continue
# MXIDs should be generated for individuals only
print(group_members)
mxids = ['@' + member + ':ubuntu.com' for member in group_members]
result = {'group_members': tuple(group_members), 'group_name': group_name, 'mxids': mxids}

View file

@ -9,6 +9,7 @@ from datetime import datetime
from rest_framework import status
from .launchpad_singleton import get_launchpad
from .utils import fetch_group_members # Adjust the import path as necessary
from .utils import fetch_matrix_accounts # Adjust the import path as necessary
import pytz
import json
import requests
@ -29,3 +30,19 @@ def group_members(self, group_name):
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)
@api_view(['GET'])
#@cache_page(60 * 30) # Cache for 30 minutes
def matrix_profiles(self, profile_id):
try:
result = fetch_matrix_accounts(profile_id)
return Response(result)
except KeyError as e:
# Handle the case where the bug is not found
print(f"Profile with name {profile_id} 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 profile {profile_id}: {str(e)}")
return Response({'error': 'An error occurred processing your request'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

View file

@ -91,7 +91,7 @@ DATABASES = {
'ENGINE': 'django.db.backends.mysql',
'HOST': '127.0.0.1',
'USER': 'ubottu',
'PASSWORD': 'iyoiyiG7Kahy',
'PASSWORD': '',
'NAME': 'ubottu'
}
}
@ -131,9 +131,9 @@ USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/
STATIC_URL = 'static/'
#STATIC_ROOT = "/home/maubot/ubottu-web/static/"
STATICFILES_DIRS = [BASE_DIR / 'static']
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field