event view count

This commit is contained in:
rizwanisready
2024-05-31 17:16:30 +05:30
parent 051d8788bd
commit 6262afea17
10 changed files with 412 additions and 1 deletions

View File

@@ -0,0 +1,20 @@
# Generated by Django 5.0.2 on 2024-05-31 11:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("accounts", "0009_appversion_app_type"),
]
operations = [
migrations.AlterField(
model_name="appversion",
name="app_type",
field=models.CharField(
choices=[("android", "android"), ("ios", "ios")], max_length=10
),
),
]

View File

@@ -1,5 +1,5 @@
from django.contrib import admin
from .models import EventCategory, Venue, EventMaster, Event, EventPrincipalInteraction
from .models import EventCategory, EventView, Venue, EventMaster, Event, EventPrincipalInteraction
# Register your models here.
@@ -91,6 +91,15 @@ class EventPrincipalInteractionAdmin(admin.ModelAdmin):
) # Adjust these field lookups according to your models.
class EventViewAdmin(admin.ModelAdmin):
list_display = ('id', 'event', 'principal', 'view_date', 'location')
search_fields = ('event__title', 'principal__email', 'location')
list_filter = ('view_date', 'location', 'event__title', 'principal__email')
ordering = ('-view_date',)
readonly_fields = ('id',)
admin.site.register(EventView, EventViewAdmin)
admin.site.register(EventPrincipalInteraction, EventPrincipalInteractionAdmin)
admin.site.register(Event, EventAdmin)
admin.site.register(EventCategory, EventCategoryAdmin)

View File

@@ -111,4 +111,10 @@ urlpatterns = [
name="principal-events",
),
path("tags/", views.TagListView.as_view(), name="tag-list"),
# For counting event views
path(
"event/<int:pk>/view/",
views.CaptureEventViewAPIView.as_view(),
name="capture_event_view",
),
]

View File

@@ -34,6 +34,7 @@ from manage_events.models import (
EventCategory,
EventPrincipalInteraction,
EventReview,
EventView,
Favorites,
PrincipalPreference,
Venue,
@@ -123,6 +124,20 @@ class CreateVenueApi(APIView):
)
# # Prepare the email
# subject = f"Your Event Report for {start_date.month} {start_date.year}."
# body = f"Please find attached the event report for {start_date.month} {start_date.month}."
# email_service = EmailService(
# subject="Good Times - Report",
# to=[user.email],
# from_email=settings.EMAIL_HOST_USER,
# )
# email_service.attach(filename, buffer.getvalue(), "application/pdf")
# # Send the email
# email_service.send()
class VenueDeleteAPIView(APIView):
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
@@ -849,3 +864,29 @@ class TagListView(generics.ListAPIView):
data=serializer.data,
status=status.HTTP_200_OK,
)
class CaptureEventViewAPIView(APIView):
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
def post(self, request, pk):
try:
event = Event.objects.get(pk=pk)
user = request.user
location_parts = [user.city, user.state, user.country]
location = " ".join(part for part in location_parts if part)
EventView.objects.create(event=event, principal=user, location=location)
return ApiResponse.success(
message=constants.SUCCESS,
data="Event view recorded successfully.",
status=status.HTTP_200_OK,
)
except Event.DoesNotExist:
return ApiResponse.error(
message=constants.FAILURE,
errors="Event not found.",
status=status.HTTP_400_BAD_REQUEST,
)

View File

@@ -0,0 +1,75 @@
# Generated by Django 5.0.2 on 2024-05-31 11:31
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("manage_events", "0008_alter_eventprincipalinteraction_event_and_more"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="EventView",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("active", models.BooleanField(default=True)),
("deleted", models.BooleanField(default=False)),
("created_on", models.DateTimeField(auto_now_add=True)),
("modified_on", models.DateTimeField(auto_now=True)),
("view_date", models.DateTimeField(auto_now_add=True)),
("location", models.CharField(blank=True, max_length=255, null=True)),
(
"created_by",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="%(class)s_created",
to=settings.AUTH_USER_MODEL,
),
),
(
"event",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="views",
to="manage_events.event",
),
),
(
"modified_by",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="%(class)s_modified",
to=settings.AUTH_USER_MODEL,
),
),
(
"principal",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="event_views",
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"abstract": False,
},
),
]

View File

@@ -173,3 +173,17 @@ class EventReview(BaseModel):
def __str__(self):
return f"Review by {self.principal} on {self.event}"
class EventView(BaseModel):
event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name="views")
principal = models.ForeignKey(
IAmPrincipal, on_delete=models.CASCADE, related_name="event_views"
)
view_date = models.DateTimeField(auto_now_add=True)
location = models.CharField(
max_length=255, blank=True, null=True
) # Or use a more complex field for location data
def __str__(self):
return f"{self.principal.email} viewed {self.event.title} from {self.location}"

213
manage_events/report.py Normal file
View File

@@ -0,0 +1,213 @@
from django.core.mail import EmailMessage
from django.db.models import Count, Q
from django.utils import timezone
from datetime import timedelta
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.graphics.shapes import Drawing
from reportlab.graphics.charts.piecharts import Pie
from io import BytesIO
from django.conf import settings
from reportlab.graphics import renderPDF
from django.contrib.auth import get_user_model
from goodtimes.services import EmailService
from manage_events.models import Event, EventInteractionType
User = get_user_model()
def generate_filename(email, date):
# Extract the username from the email address
username = email.split("@")[0]
# Get the full month name from the date
month_name = date.strftime("%B")
# Create the filename
filename = f"{username}_{month_name}_report.pdf"
return filename
def get_previous_month_date_range():
today = timezone.now()
first_day_of_current_month = today.replace(day=1)
last_day_of_previous_month = first_day_of_current_month - timedelta(days=1)
first_day_of_previous_month = last_day_of_previous_month.replace(day=1)
return first_day_of_previous_month, last_day_of_previous_month
def generate_event_report(user_id):
# Calculate the start and end dates for the previous month
start_date, end_date = get_previous_month_date_range()
# Get the user (manager)
user = User.objects.get(id=user_id)
# Filter events created by the user in the previous month
events = Event.objects.filter(
created_by=user, created_on__gte=start_date, created_on__lte=end_date
).annotate(
favorites_count=Count(
"favorites", filter=Q(favorites__active=True, favorites__deleted=False)
),
interested_count=Count(
"interaction_event",
filter=Q(interaction_event__status=EventInteractionType.INTERESTED),
),
going_count=Count(
"interaction_event",
filter=Q(interaction_event__status=EventInteractionType.GOING),
),
reviews_count=Count(
"reviews", filter=Q(reviews__active=True, reviews__deleted=False)
),
)
# Generate the report
report_data = []
for event in events:
report_data.append(
{
"event_name": event.title,
"favorites_count": event.favorites_count,
"interested_count": event.interested_count,
"going_count": event.going_count,
"reviews_count": event.reviews_count,
}
)
return report_data
def generate_event_report_pdf(user, report_data):
start_date, _ = get_previous_month_date_range()
filename = generate_filename(user.email, start_date)
buffer = BytesIO()
pdf = canvas.Canvas(buffer, pagesize=letter)
width, height = letter
# Add a title and user information
pdf.setFont("Helvetica-Bold", 16)
pdf.drawString(100, 750, "Event Report - April 2024")
user_name = user.email.split("@")[0] # Use part of email before @ as username
pdf.setFont("Helvetica", 12)
pdf.drawString(100, 730, f"For Event Manager: {user_name}")
# Add a table header
pdf.setFont("Helvetica-Bold", 10)
pdf.drawString(50, 700, "Event Name")
pdf.drawString(250, 700, "Favorites")
pdf.drawString(350, 700, "Interested")
pdf.drawString(450, 700, "Going")
pdf.drawString(550, 700, "Reviews")
# Loop through data and add table rows
y_pos = 680
for event in report_data:
pdf.drawString(50, y_pos, event["event_name"])
pdf.drawString(250, y_pos, str(event["favorites_count"]))
pdf.drawString(350, y_pos, str(event["interested_count"]))
pdf.drawString(450, y_pos, str(event["going_count"]))
pdf.drawString(550, y_pos, str(event["reviews_count"]))
y_pos -= 15 # Adjust position for next row
# Draw the pie chart
if report_data:
pie_data = [
sum(event[key] for event in report_data)
for key in ("favorites_count", "interested_count", "going_count")
]
pie_labels = ["Favorites", "Interested", "Going"]
drawing = Drawing(width, height)
pie = Pie()
pie.x = 150
pie.y = 200
pie.width = 300
pie.height = 150
pie.data = pie_data
pie.labels = pie_labels
pie.slices.strokeWidth = 0.5
drawing.add(pie)
renderPDF.draw(drawing, pdf, 150, 200)
# Close the PDF object and write the buffer content to the PDF file
pdf.save()
buffer.seek(0)
pdf_data = buffer.read()
buffer.close()
return pdf_data, filename
def generate_event_report_pdf_two(user, report_data):
start_date, _ = get_previous_month_date_range()
filename = generate_filename(user.email, start_date)
buffer = BytesIO()
pdf = canvas.Canvas(buffer, pagesize=letter)
width, height = letter
# Add a title and user information
pdf.setFont("Helvetica-Bold", 16)
pdf.drawString(100, 750, "Event Report - April 2024")
user_name = user.email.split("@")[0] # Use part of email before @ as username
pdf.setFont("Helvetica", 12)
pdf.drawString(100, 730, f"For Event Manager: {user_name}")
# Event loop with row handling
y_pos = 650 # Starting position for charts (adjust as needed)
chart_width = 250 # Width of each pie chart
chart_height = 150 # Height of each pie chart
chart_spacing = 50 # Spacing between charts in a row
for i, event in enumerate(report_data):
# Add event name as a header
pdf.setFont("Helvetica-Bold", 12)
pdf.drawString(50, y_pos + 20, event["event_name"])
# Check if this is the first event in a row
if i % 2 == 0:
x_pos = 75 # Starting position for charts in the first column
else:
x_pos = (
width - chart_width - 75
) # Starting position for charts in the second column
# Draw pie charts for the event
for key, value in [
("favorites_count", "Favorites"),
("interested_count", "Interested"),
("going_count", "Going"),
]:
pie_data = [value]
pie_labels = [value]
drawing = Drawing(chart_width, chart_height)
pie = Pie()
pie.x = 0
pie.y = 0
pie.width = chart_width
pie.height = chart_height
pie.data = pie_data
pie.labels = pie_labels
pie.slices.strokeWidth = 0.5
drawing.add(pie)
renderPDF.draw(drawing, pdf, x_pos, y_pos)
x_pos += chart_width + chart_spacing # Adjust x position for the next chart
y_pos -= (
100 # Adjust y position for the next event (adjust based on chart heights)
)
# Close the PDF object and write the buffer content to the PDF file
pdf.save()
buffer.seek(0)
pdf_data = buffer.read()
buffer.close()
return pdf_data, filename

View File

@@ -89,4 +89,9 @@ urlpatterns = [
views.VenueDeleteView.as_view(),
name="venue_delete",
),
path(
"generate-event-report/<int:user_id>/",
views.GenerateEventReportView.as_view(),
name="generate_event_report",
),
]

View File

@@ -13,6 +13,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.contrib import messages
from goodtimes import constants
from django.contrib.auth import get_user_model
# Create your views here.
@@ -477,3 +478,27 @@ class VenueDeleteView(LoginRequiredMixin, generic.View):
messages.success(request, self.error_message)
return redirect(self.success_url)
User = get_user_model()
from .report import generate_event_report, generate_event_report_pdf
from django.http import HttpResponse
class GenerateEventReportView(generic.View):
def get(self, request, user_id):
# Generate the event report
report_data = generate_event_report(user_id)
# Get the user
user = get_object_or_404(User, id=user_id)
# Generate the PDF
pdf_data, filename = generate_event_report_pdf(user, report_data)
# Create the HttpResponse object with the PDF data
response = HttpResponse(pdf_data, content_type="application/pdf")
response["Content-Disposition"] = f'attachment; filename="{filename}"'
return response

View File

@@ -8,6 +8,7 @@ certifi==2024.2.2
cffi==1.16.0
channels==4.0.0
channels-redis==4.2.0
chardet==5.2.0
charset-normalizer==3.3.2
colorama==0.4.6
colorlog==6.8.2
@@ -17,6 +18,7 @@ daphne==4.1.0
defusedxml==0.7.1
Django==5.0.2
django-allauth==0.61.1
django-channels==0.7.0
django-cors-headers==4.3.1
django-debug-toolbar==4.3.0
django-environ==0.11.2
@@ -56,6 +58,7 @@ python3-openid==3.2.0
pytz==2024.1
PyYAML==6.0.1
redis==5.0.2
reportlab==4.2.0
requests==2.31.0
requests-oauthlib==1.3.1
service-identity==24.1.0