Auto commit: 2026-02-09T19:20:56.861Z

This commit is contained in:
Flatlogic Bot 2026-02-09 19:20:57 +00:00
parent 42369b6e1a
commit 97ab8247f6
12 changed files with 165 additions and 5 deletions

View File

@ -164,3 +164,46 @@ you should set broker_connection_retry_on_startup to True.
[2026-02-09 18:31:03,713: INFO/ForkPoolWorker-1] Decoded JSON for 27: summary=True, tags=['development', 'research', 'new', 'company']
[2026-02-09 18:31:03,987: INFO/ForkPoolWorker-1] Successfully added tags ['development', 'research', 'new', 'company'] to bookmark 27
[2026-02-09 18:31:04,321: INFO/ForkPoolWorker-1] Task core.tasks.generate_summary[944ef664-f321-45b6-82f8-607291008ea6] succeeded in 13.666462198016234s: 'Generated summary and tags for bookmark 27'
[2026-02-09 19:04:23,495: INFO/MainProcess] Task core.tasks.process_bookmark[70bb649c-6afd-477d-ac5f-959b9ea12bb0] received
[2026-02-09 19:04:26,064: INFO/ForkPoolWorker-2] HTTP Request: GET https://facebook.com "HTTP/1.1 301 Moved Permanently"
[2026-02-09 19:04:26,361: INFO/ForkPoolWorker-2] HTTP Request: GET https://www.facebook.com/ "HTTP/1.1 400 Bad Request"
[2026-02-09 19:04:26,399: WARNING/ForkPoolWorker-2] Error fetching bookmark 28 (https://facebook.com): Client error '400 Bad Request' for url 'https://www.facebook.com/'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400. Trying base domain backup.
[2026-02-09 19:04:26,403: ERROR/ForkPoolWorker-2] Error fetching base domain for bookmark 28: Client error '400 Bad Request' for url 'https://www.facebook.com/'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400
[2026-02-09 19:04:27,088: INFO/MainProcess] Task core.tasks.generate_summary[b0feb8a7-8741-4581-a7f0-7e703e4a2e70] received
[2026-02-09 19:04:27,151: INFO/ForkPoolWorker-2] Task core.tasks.process_bookmark[70bb649c-6afd-477d-ac5f-959b9ea12bb0] succeeded in 3.190528256993275s: 'Processed bookmark 28'
[2026-02-09 19:04:28,313: INFO/ForkPoolWorker-1] Generating summary/tags for bookmark 28...
[2026-02-09 19:04:39,614: INFO/ForkPoolWorker-1] AI Raw Response for 28: {
"summary": "The webpage content could not be retrieved; requests to https://facebook.com and its base domain failed. No content was available for analysis, so no page details can be provided."
}
[2026-02-09 19:04:39,614: INFO/ForkPoolWorker-1] Decoded JSON for 28: summary=True, tags=[]
[2026-02-09 19:04:40,920: INFO/ForkPoolWorker-1] Task core.tasks.generate_summary[b0feb8a7-8741-4581-a7f0-7e703e4a2e70] succeeded in 13.627130784036126s: 'Generated summary for bookmark 28'
[2026-02-09 19:08:50,036: INFO/MainProcess] Task core.tasks.process_bookmark[ff409078-4458-47ef-b732-facaaf2cd761] received
[2026-02-09 19:08:50,262: INFO/ForkPoolWorker-2] HTTP Request: GET https://youtube.com "HTTP/1.1 301 Moved Permanently"
[2026-02-09 19:08:50,403: INFO/ForkPoolWorker-2] HTTP Request: GET https://www.youtube.com/ "HTTP/1.1 200 OK"
[2026-02-09 19:08:50,858: INFO/MainProcess] Task core.tasks.generate_summary[57582068-b4a2-48dc-9357-6d22a1ba1778] received
[2026-02-09 19:08:50,865: INFO/ForkPoolWorker-2] Task core.tasks.process_bookmark[ff409078-4458-47ef-b732-facaaf2cd761] succeeded in 0.824686923995614s: 'Processed bookmark 29'
[2026-02-09 19:08:50,927: INFO/ForkPoolWorker-1] Generating summary/tags for bookmark 29...
[2026-02-09 19:09:01,754: INFO/ForkPoolWorker-1] AI Raw Response for 29: {
"summary": "This is a YouTube footer listing navigational and legal links (About, Press, Copyright, Contact, Creators, Advertise, Developers, Terms, Privacy, Policy & Safety, How YouTube works, and Test new features). It also includes a 2026 copyright attribution to Google LLC."
}
[2026-02-09 19:09:01,754: INFO/ForkPoolWorker-1] Decoded JSON for 29: summary=True, tags=[]
[2026-02-09 19:09:01,769: INFO/ForkPoolWorker-1] Task core.tasks.generate_summary[57582068-b4a2-48dc-9357-6d22a1ba1778] succeeded in 10.908533619949594s: 'Generated summary for bookmark 29'
[2026-02-09 19:09:42,382: INFO/MainProcess] Task core.tasks.process_bookmark[21590aeb-6045-4341-8f97-80291d55e5bb] received
[2026-02-09 19:09:42,476: INFO/ForkPoolWorker-2] HTTP Request: GET https://youtube.com "HTTP/1.1 301 Moved Permanently"
[2026-02-09 19:09:42,577: INFO/ForkPoolWorker-2] HTTP Request: GET https://www.youtube.com/ "HTTP/1.1 200 OK"
[2026-02-09 19:09:42,874: INFO/MainProcess] Task core.tasks.generate_summary[3a3f1ae2-e049-44a0-8743-e0dd2392820f] received
[2026-02-09 19:09:42,877: INFO/ForkPoolWorker-2] Task core.tasks.process_bookmark[21590aeb-6045-4341-8f97-80291d55e5bb] succeeded in 0.48919728299370036s: 'Processed bookmark 29'
[2026-02-09 19:09:43,056: INFO/ForkPoolWorker-2] Generating summary/tags for bookmark 29...
[2026-02-09 19:09:53,936: INFO/ForkPoolWorker-2] AI Raw Response for 29: {
"summary": "The content is a YouTube footer listing navigation links to corporate and support resources — About, Press, Copyright, Contact, Creators, Advertise, Developers, Terms, Privacy, Policy & Safety, How YouTube works, and Test new features. It also includes a copyright notice attributing the site to Google LLC (2026)."
}
[2026-02-09 19:09:53,938: INFO/ForkPoolWorker-2] Decoded JSON for 29: summary=True, tags=[]
[2026-02-09 19:09:53,962: INFO/ForkPoolWorker-2] Task core.tasks.generate_summary[3a3f1ae2-e049-44a0-8743-e0dd2392820f] succeeded in 11.077497629041318s: 'Generated summary for bookmark 29'
[2026-02-09 19:20:12,359: INFO/MainProcess] Task core.tasks.process_bookmark[e19646b8-ea58-48a7-89e1-3d0429b9030a] received
[2026-02-09 19:20:26,876: INFO/ForkPoolWorker-2] HTTP Request: GET https://instagram.com "HTTP/1.1 301 Moved Permanently"
[2026-02-09 19:20:28,386: INFO/ForkPoolWorker-2] HTTP Request: GET https://www.instagram.com/ "HTTP/1.1 200 OK"
[2026-02-09 19:20:39,598: INFO/MainProcess] Task core.tasks.generate_summary[cfcfea70-d5a2-4694-9467-45333ac44d3f] received
[2026-02-09 19:20:40,610: INFO/ForkPoolWorker-2] Task core.tasks.process_bookmark[e19646b8-ea58-48a7-89e1-3d0429b9030a] succeeded in 24.209723198961s: 'Processed bookmark 30'
[2026-02-09 19:20:51,094: INFO/ForkPoolWorker-1] Task core.tasks.generate_summary[cfcfea70-d5a2-4694-9467-45333ac44d3f] succeeded in 8.763452520011924s: None

View File

@ -58,6 +58,7 @@ INSTALLED_APPS = [
'rest_framework',
'taggit',
'django_filters',
'auditlog',
'core',
]
@ -67,6 +68,7 @@ MIDDLEWARE = [
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'auditlog.middleware.AuditlogMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Disable X-Frame-Options middleware to allow Flatlogic preview iframes.
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
@ -213,4 +215,4 @@ CELERY_TASK_EAGER_PROPAGATES = True
# Login/Logout Redirects
LOGIN_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'

View File

@ -82,4 +82,10 @@ class APIToken(models.Model):
super().save(*args, **kwargs)
def __str__(self):
return f"{self.name} - {self.user.username}"
return f"{self.name} - {self.user.username}"
from auditlog.registry import auditlog
auditlog.register(Bookmark)
auditlog.register(Team)
auditlog.register(TeamMembership)
auditlog.register(APIToken)

View File

@ -140,6 +140,7 @@
<li><a class="dropdown-item" href="/admin/">Admin Panel</a></li>
<li><a class="dropdown-item" href="/flower/">Task Monitor</a></li>
{% endif %}
<li><a class="dropdown-item" href="{% url 'activity-log' %}">Activity Log</a></li>
<li><hr class="dropdown-divider"></li>
<li>
<form method="post" action="{% url 'logout' %}">

View File

@ -0,0 +1,94 @@
{% extends "base.html" %}
{% block title %}Activity Log{% endblock %}
{% block content %}
<div class="row mb-4">
<div class="col-12">
<h1 class="display-6 fw-bold text-primary">Activity Log</h1>
<p class="text-muted">History of your actions and changes.</p>
</div>
</div>
<div class="card shadow-sm border-0">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="bg-light">
<tr>
<th class="ps-4">Time</th>
<th>Action</th>
<th>Resource</th>
<th>Details</th>
</tr>
</thead>
<tbody>
{% for entry in log_entries %}
<tr>
<td class="ps-4 text-nowrap text-muted small">
{{ entry.timestamp|date:"M d, Y H:i" }}
</td>
<td>
{% if entry.action == 0 %}
<span class="badge bg-success bg-opacity-10 text-success rounded-pill">Created</span>
{% elif entry.action == 1 %}
<span class="badge bg-primary bg-opacity-10 text-primary rounded-pill">Updated</span>
{% elif entry.action == 2 %}
<span class="badge bg-danger bg-opacity-10 text-danger rounded-pill">Deleted</span>
{% else %}
<span class="badge bg-secondary rounded-pill">Accessed</span>
{% endif %}
</td>
<td>
<span class="fw-medium">{{ entry.content_type.name|capfirst }}</span>
<br>
<small class="text-muted">{{ entry.object_repr }}</small>
</td>
<td class="small text-muted">
<div style="max-width: 400px; overflow-wrap: break-word;">
{% if entry.changes %}
{{ entry.changes|truncatechars:100 }}
{% else %}
-
{% endif %}
</div>
</td>
</tr>
{% empty %}
<tr>
<td colspan="4" class="text-center py-5 text-muted">
<i class="bi bi-clock-history fs-1 d-block mb-3"></i>
No activity recorded yet.
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% if is_paginated %}
<div class="mt-4">
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link rounded-pill px-3 me-1" href="?page={{ page_obj.previous_page_number }}">Previous</a>
</li>
{% endif %}
<li class="page-item disabled">
<span class="page-link border-0 bg-transparent">Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}</span>
</li>
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link rounded-pill px-3 ms-1" href="?page={{ page_obj.next_page_number }}">Next</a>
</li>
{% endif %}
</ul>
</nav>
</div>
{% endif %}
{% endblock %}

View File

@ -5,7 +5,8 @@ from core.views import (
BookmarkListView, BookmarkCreateView, BookmarkDetailView,
BookmarkUpdateView, BookmarkDeleteView,
TeamListView, TeamDetailView, BookmarkShareToggleView,
BookmarkRegenerateView, SummaryUpdateView, ExtractionUpdateView
BookmarkRegenerateView, SummaryUpdateView, ExtractionUpdateView,
UserActivityLogView
)
router = DefaultRouter()
@ -26,6 +27,8 @@ urlpatterns = [
path("teams/", TeamListView.as_view(), name="team-list"),
path("teams/<int:pk>/", TeamDetailView.as_view(), name="team-detail"),
path("activity/", UserActivityLogView.as_view(), name="activity-log"),
path("api/status/", ApiStatusView.as_view(), name="api-status"),
path("api/", include(router.urls)),
]
]

View File

@ -8,6 +8,7 @@ from django.db import transaction
from django.http import JsonResponse, HttpResponseRedirect
from .models import Bookmark, Team, Extraction, BookmarkShare, Summary
from .tasks import process_bookmark
from auditlog.models import LogEntry
class BookmarkListView(LoginRequiredMixin, ListView):
model = Bookmark
@ -187,4 +188,13 @@ class BookmarkShareToggleView(LoginRequiredMixin, View):
else:
shared = True
return JsonResponse({'shared': shared})
return JsonResponse({'shared': shared})
class UserActivityLogView(LoginRequiredMixin, ListView):
model = LogEntry
template_name = 'core/activity_log.html'
context_object_name = 'log_entries'
paginate_by = 20
def get_queryset(self):
return LogEntry.objects.filter(actor=self.request.user).select_related('content_type', 'actor').order_by('-timestamp')

View File

@ -11,3 +11,4 @@ redis==5.0.8
django-filter==24.3
flower==2.0.1
django-revproxy==0.11.0
django-auditlog==3.4.1