This commit is contained in:
rizwanisready
2024-06-03 16:49:19 +05:30
parent 10171170f4
commit 5ddccc0860
6 changed files with 344 additions and 236 deletions

View File

@@ -1,5 +1,13 @@
from django.contrib import admin
from .models import EventCategory, EventView, Venue, EventMaster, Event, EventPrincipalInteraction
from .models import (
EventCategory,
EventShare,
EventView,
Venue,
EventMaster,
Event,
EventPrincipalInteraction,
)
# Register your models here.
@@ -78,7 +86,7 @@ class EventAdmin(admin.ModelAdmin):
},
),
)
filter_horizontal = () # Use this if there are many-to-many fields
filter_horizontal = () # if there are many-to-many fields
raw_id_fields = ("venue", "category", "event_master")
@@ -88,17 +96,24 @@ class EventPrincipalInteractionAdmin(admin.ModelAdmin):
search_fields = (
"principal__name",
"event__title",
) # 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',)
list_display = ("id", "event", "principal", "view_date", "location")
search_fields = ("event__title", "principal__email", "location")
list_filter = ("id", "view_date", "location", "event__title", "principal__email")
ordering = ("-view_date",)
readonly_fields = ("id",)
class EventShareAdmin(admin.ModelAdmin):
list_display = ("id", "event", "principal", "created_on")
search_fields = ("event__title", "principal__username")
list_filter = ("id", "event", "principal", "created_on")
admin.site.register(EventShare, EventShareAdmin)
admin.site.register(EventView, EventViewAdmin)
admin.site.register(EventPrincipalInteraction, EventPrincipalInteractionAdmin)
admin.site.register(Event, EventAdmin)

View File

@@ -117,4 +117,10 @@ urlpatterns = [
views.CaptureEventViewAPIView.as_view(),
name="capture_event_view",
),
# For counting event shares
path(
"event/<int:pk>/share/",
views.EventShareView.as_view(),
name="capture_event_share",
),
]

View File

@@ -34,6 +34,7 @@ from manage_events.models import (
EventCategory,
EventPrincipalInteraction,
EventReview,
EventShare,
EventView,
Favorites,
PrincipalPreference,
@@ -890,3 +891,30 @@ class CaptureEventViewAPIView(APIView):
errors="Event not found.",
status=status.HTTP_400_BAD_REQUEST,
)
class EventShareView(APIView):
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
def post(self, request, pk):
try:
event = Event.objects.get(id=pk)
except Event.DoesNotExist:
return ApiResponse.error(
message=constants.FAILURE,
errors="Event not found.",
status=status.HTTP_400_BAD_REQUEST,
)
# Incrementing the social media shares count
event.increment_shares()
user = request.user # Assuming the user is authenticated
EventShare.objects.create(principal=user, event=event)
return ApiResponse.success(
message=constants.SUCCESS,
data="Event shared successfully.",
status=status.HTTP_200_OK,
)

View File

@@ -0,0 +1,78 @@
# Generated by Django 5.0.2 on 2024-06-01 15:06
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("manage_events", "0009_eventview"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name="event",
name="social_media_shares_count",
field=models.IntegerField(default=0),
),
migrations.CreateModel(
name="EventShare",
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)),
(
"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="social_media_shares",
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_shares",
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"abstract": False,
},
),
]

View File

@@ -84,6 +84,11 @@ class Event(BaseModel):
tags = TaggableManager(blank=True)
age_group = models.CharField(max_length=100, blank=True, null=True)
draft = models.BooleanField(default=False)
social_media_shares_count = models.IntegerField(default=0)
def increment_shares(self):
self.social_media_shares_count += 1
self.save()
def __str__(self):
return self.title
@@ -187,3 +192,12 @@ class EventView(BaseModel):
def __str__(self):
return f"{self.principal.email} viewed {self.event.title} from {self.location}"
class EventShare(BaseModel):
event = models.ForeignKey(
Event, on_delete=models.CASCADE, related_name="social_media_shares"
)
principal = models.ForeignKey(
IAmPrincipal, on_delete=models.CASCADE, related_name="event_shares"
)

View File

@@ -5,14 +5,24 @@ from datetime import timedelta
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.graphics.shapes import Drawing
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.graphics.charts.piecharts import Pie
from reportlab.platypus import (
SimpleDocTemplate,
Table,
TableStyle,
Paragraph,
Spacer,
PageBreak,
)
from io import BytesIO
from django.conf import settings
from collections import defaultdict
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, EventView
from manage_events.models import Event, EventInteractionType, EventShare, EventView
User = get_user_model()
@@ -40,13 +50,26 @@ def generate_event_report(user_id):
start_date, end_date = get_previous_month_date_range()
user = User.objects.get(id=user_id)
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)),
events = Event.objects.filter(
created_by=user, start_date__gte=start_date, start_date__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)
),
views_count=Count("views", filter=Q(views__active=True, views__deleted=False)),
)
print("events: ", events)
report_data = []
for event in events:
@@ -55,154 +78,35 @@ def generate_event_report(user_id):
for view in views:
locations[view.location] += 1
report_data.append({
"event_name": event.title,
"event_type": event.category.title,
"event_date": str(event.start_date),
"favorites_count": event.favorites_count,
"interested_count": event.interested_count,
"going_count": event.going_count,
"reviews_count": event.reviews_count,
"views_count": event.views_count,
"locations": dict(locations),
})
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)
shares = (
EventShare.objects.filter(event=event)
.values("principal")
.annotate(share_count=Count("principal"))
)
shares_data = {
User.objects.get(id=share["principal"]).get_full_name(): share[
"share_count"
]
for share in shares
}
# 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
report_data.append(
{
"event_name": event.title,
"event_type": event.category.title,
"event_date": str(event.start_date),
"favorites_count": event.favorites_count,
"interested_count": event.interested_count,
"going_count": event.going_count,
"reviews_count": event.reviews_count,
"views_count": event.views_count,
"locations": dict(locations),
"social_media_shares": event.social_media_shares_count,
"shares_data": shares_data,
}
)
print("report_data: ", report_data)
return report_data
def generate_event_report_pdf_three(user, report_data):
@@ -210,116 +114,179 @@ def generate_event_report_pdf_three(user, report_data):
filename = generate_filename(user.email, start_date)
buffer = BytesIO()
pdf = canvas.Canvas(buffer, pagesize=letter)
# pdf = canvas.Canvas(buffer, pagesize=letter)
pdf = SimpleDocTemplate(buffer, pagesize=letter)
width, height = letter
elements = []
styles = getSampleStyleSheet()
# Header Section
title = "Good Times Ltd. Monthly Report"
report_for_month = f"Report for the month of - {start_date.strftime('%B %Y')}"
organiser_name = f"Name of the Organiser - {user.get_full_name()}"
contact_name = f"Contact Name - {user.get_full_name()}"
title = Paragraph("Good Times Ltd. Monthly Report", styles["Title"])
report_for_month = Paragraph(
f"Report for the month of - {start_date.strftime('%B %Y')}", styles["Title"]
)
organiser_name = Paragraph(
f"Name of the Organiser - {user.get_full_name()}", styles["Title"]
)
contact_name = Paragraph(f"Contact Name - {user.get_full_name()}", styles["Title"])
pdf.setFont("Helvetica-Bold", 20)
title_width = pdf.stringWidth(title, "Helvetica-Bold", 20)
pdf.drawString((width - title_width) / 2, 750, title)
elements.extend(
[
title,
Spacer(1, 12),
report_for_month,
Spacer(1, 12),
organiser_name,
Spacer(1, 12),
contact_name,
PageBreak(),
]
)
pdf.setFont("Helvetica", 16)
report_for_month_width = pdf.stringWidth(report_for_month, "Helvetica", 16)
pdf.drawString((width - report_for_month_width) / 2, 720, report_for_month)
organiser_name_width = pdf.stringWidth(organiser_name, "Helvetica", 16)
pdf.drawString((width - organiser_name_width) / 2, 690, organiser_name)
contact_name_width = pdf.stringWidth(contact_name, "Helvetica", 16)
pdf.drawString((width - contact_name_width) / 2, 660, contact_name)
pdf.showPage()
# Summary Section
pdf.setFont("Helvetica-Bold", 12)
pdf.drawString(
100,
640,
f"Number of Events added in {start_date.strftime('%B %Y')} - {len(report_data)}",
summary_text = (
f"Number of Events added in {start_date.strftime('%B %Y')} - {len(report_data)}"
)
elements.append(Paragraph(summary_text, styles["Normal"]))
elements.append(Spacer(1, 12))
y_pos = 620
pdf.setFont("Helvetica-Bold", 10)
pdf.drawString(50, y_pos, "Event Name")
pdf.drawString(200, y_pos, "Event Type")
pdf.drawString(350, y_pos, "Date")
y_pos -= 20
data = [["Sr No.", "Name of the Event", "Event Type", "Date"]]
for idx, event in enumerate(report_data, start=1):
data.append(
[
idx,
event["event_name"],
event["event_type"],
event["event_date"],
]
)
pdf.setFont("Helvetica", 10)
table = Table(data, colWidths=[50, 200, 150, 100])
style = TableStyle(
[
("BACKGROUND", (0, 0), (-1, 0), colors.grey),
("TEXTCOLOR", (0, 0), (-1, 0), colors.whitesmoke),
("ALIGN", (0, 0), (-1, -1), "CENTER"),
("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
("BOTTOMPADDING", (0, 0), (-1, 0), 12),
("BACKGROUND", (0, 1), (-1, -1), colors.beige),
("GRID", (0, 0), (-1, -1), 1, colors.black),
]
)
table.setStyle(style)
elements.append(table)
elements.append(PageBreak())
# Traffic Details Section
traffic_header = "Traffic Details for profile - Event Organisers London Ltd."
elements.append(Paragraph(traffic_header, styles["Heading2"]))
elements.append(Spacer(1, 12))
views_count = sum(event["views_count"] for event in report_data)
favorites_count = sum(event["favorites_count"] for event in report_data)
social_media_shares = sum(event["social_media_shares"] for event in report_data)
elements.append(
Paragraph(f"Number of Event Views - {views_count}", styles["Normal"])
)
elements.append(Spacer(1, 12))
elements.append(
Paragraph(f"Number of Event Favorites - {favorites_count}", styles["Normal"])
)
elements.append(Spacer(1, 12))
elements.append(
Paragraph(f"Social Media Shares - {social_media_shares}", styles["Normal"])
)
# elements.append(PageBreak())
elements.append(Spacer(1, 60))
# Top 5 Locations and Top 5 Viewed Events
all_locations = defaultdict(int)
for event in report_data:
pdf.drawString(50, y_pos, event["event_name"])
pdf.drawString(200, y_pos, event["event_type"])
pdf.drawString(350, y_pos, event["event_date"])
y_pos -= 20
for location, count in event["locations"].items():
all_locations[location] += count
# Start a new page for Traffic Details Section
pdf.showPage()
top_locations = sorted(all_locations.items(), key=lambda x: x[1], reverse=True)[:5]
top_events = sorted(report_data, key=lambda x: x["views_count"], reverse=True)[:5]
pdf.setFont("Helvetica-Bold", 12)
pdf.drawString(
50, height - 50, "Traffic Details for profile - Event Organisers London Ltd."
data = [
["Top 5 Locations Viewed From", "Top 5 Viewed Events"],
]
for i in range(5):
location = top_locations[i][0] if i < len(top_locations) else ""
event = top_events[i]["event_name"] if i < len(top_events) else ""
data.append([location, event])
table = Table(data, colWidths=[200, 200])
style = TableStyle(
[
("BACKGROUND", (0, 0), (-1, 0), colors.grey),
("TEXTCOLOR", (0, 0), (-1, 0), colors.whitesmoke),
("ALIGN", (0, 0), (-1, -1), "CENTER"),
("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
("BOTTOMPADDING", (0, 0), (-1, 0), 12),
("BACKGROUND", (0, 1), (-1, -1), colors.beige),
("GRID", (0, 0), (-1, -1), 1, colors.black),
]
)
table.setStyle(style)
elements.append(table)
elements.append(PageBreak())
# Detailed Review of Each Event
for event in report_data:
pdf.showPage()
pdf.setFont("Helvetica-Bold", 12)
pdf.drawString(50, height - 50, f"Event Name - {event['event_name']}")
pdf.setFont("Helvetica", 10)
pdf.drawString(50, height - 70, f"Event Type - {event['event_type']}")
pdf.drawString(50, height - 90, f"Event Date - {event['event_date']}")
elements.append(Paragraph(f"Event Name - {event['event_name']}", styles['Heading2']))
elements.append(Spacer(1, 12))
elements.append(Paragraph(f"Event Type - {event['event_type']}", styles['Normal']))
elements.append(Paragraph(f"Event Date - {event['event_date']}", styles['Normal']))
y_pos = height - 120
pdf.drawString(50, y_pos, f"Number of Views - {event['views_count']}")
pdf.drawString(200, y_pos, f"Favorites Count - {event['favorites_count']}")
pdf.drawString(350, y_pos, f"Interested in Going - {event['interested_count']}")
pdf.drawString(500, y_pos, f"Going - {event['going_count']}")
pdf.drawString(650, y_pos, f"Reviews - {event['reviews_count']}")
y_pos -= 40
views = f"Number of Views - {event['views_count']}"
favorites = f"Favorites Count - {event['favorites_count']}"
interested = f"Interested in Going - {event['interested_count']}"
going = f"Going - {event['going_count']}"
reviews = f"Reviews - {event['reviews_count']}"
shares = f"Social Media Shares - {event['social_media_shares']}"
pdf.setFont("Helvetica-Bold", 10)
pdf.drawString(50, y_pos, "View Details:")
y_pos -= 20
pdf.setFont("Helvetica", 10)
pdf.drawString(100, y_pos, "User Email")
pdf.drawString(300, y_pos, "Location")
pdf.drawString(500, y_pos, "View Date")
y_pos -= 20
for view in event["locations"]:
pdf.drawString(100, y_pos, view["user__email"])
pdf.drawString(300, y_pos, view["location"])
pdf.drawString(500, y_pos, view["view_date"].strftime("%d %B %Y %H:%M"))
y_pos -= 20
elements.append(Paragraph(views, styles['Normal']))
elements.append(Paragraph(shares, styles['Normal']))
elements.append(Paragraph(favorites, styles['Normal']))
elements.append(Paragraph(interested, styles['Normal']))
elements.append(Paragraph(going, styles['Normal']))
elements.append(Paragraph(reviews, styles['Normal']))
elements.append(Spacer(1, 12))
# Draw pie chart on a new page if there's not enough space
if y_pos < 150:
pdf.showPage()
y_pos = height - 150
location_details = []
for location, count in event["locations"].items():
location_details.append(f"{location}: {count}")
elements.append(Paragraph("Event viewed from:", styles['Normal']))
elements.append(Paragraph(", ".join(location_details), styles['Normal']))
# elements.append(PageBreak())
elements.append(Spacer(1, 60))
pie_data = [
event["views_count"],
event["social_media_shares"],
event["favorites_count"],
event["interested_count"],
event["going_count"],
]
pie_labels = ["Views", "Favorites", "Interested", "Going"]
pie_labels = ["Views", "Shares", "Favorites", "Interested", "Going"]
drawing = Drawing(200, 100)
pie = Pie()
pie.x = 50
pie.y = y_pos - 100
pie.data = pie_data
pie.labels = pie_labels
pie.width = 100
pie.height = 100
drawing.add(pie)
renderPDF.draw(drawing, pdf, 50, y_pos - 100)
y_pos -= 150 # Adjust for pie chart height
pdf.save()
elements.append(drawing)
elements.append(PageBreak())
pdf.build(elements)
buffer.seek(0)
pdf_data = buffer.read()
buffer.close()