API for Calendars
This commit is contained in:
@@ -3,12 +3,12 @@ from .models import *
|
|||||||
|
|
||||||
class CalendarAdmin(admin.ModelAdmin):
|
class CalendarAdmin(admin.ModelAdmin):
|
||||||
# prepopulated_fields = {"slug": ("shortname",)}
|
# prepopulated_fields = {"slug": ("shortname",)}
|
||||||
list_display = ("name", "shortcode")
|
list_display = ("name", "shortcode", "published")
|
||||||
|
|
||||||
|
|
||||||
class ScraperAdmin(admin.ModelAdmin):
|
class ScraperAdmin(admin.ModelAdmin):
|
||||||
# prepopulated_fields = {"slug": ("shortname",)}
|
# prepopulated_fields = {"slug": ("shortname",)}
|
||||||
list_display = ("name", "items", "new_items", "last_ran")
|
list_display = ("name", "items", "new_items", "last_ran", "calendar")
|
||||||
|
|
||||||
class OrganizationAdmin(admin.ModelAdmin):
|
class OrganizationAdmin(admin.ModelAdmin):
|
||||||
# prepopulated_fields = {"slug": ("shortname",)}
|
# prepopulated_fields = {"slug": ("shortname",)}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import os, sys
|
import os, sys
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
from dateutil import relativedelta
|
from dateutil import relativedelta
|
||||||
from time import sleep
|
from time import sleep
|
||||||
import pytz
|
import pytz
|
||||||
@@ -19,7 +19,7 @@ odt_next_month = datetime.now() + plus_one_month
|
|||||||
|
|
||||||
|
|
||||||
# Get Scraper name, item count and online_calendar (virtcal)
|
# Get Scraper name, item count and online_calendar (virtcal)
|
||||||
def getScraper(venue, webite, cal):
|
def getScraper(venue, website, cal):
|
||||||
virtcal = Calendar.objects.get(shortcode='000')
|
virtcal = Calendar.objects.get(shortcode='000')
|
||||||
try:
|
try:
|
||||||
scraper, created = Scraper.objects.get_or_create(
|
scraper, created = Scraper.objects.get_or_create(
|
||||||
@@ -183,7 +183,7 @@ def createBasicEvent(event, event_type, venue):
|
|||||||
venue = venue
|
venue = venue
|
||||||
)
|
)
|
||||||
new_event = add_calendars(new_event, event)
|
new_event = add_calendars(new_event, event)
|
||||||
print("\n+new event+\n")
|
# print("\n+new event+")
|
||||||
return new_event, created
|
return new_event, created
|
||||||
|
|
||||||
# Create iCal Event
|
# Create iCal Event
|
||||||
@@ -198,7 +198,7 @@ def createBasiciCalEvent(event, event_type, venue):
|
|||||||
venue = venue
|
venue = venue
|
||||||
)
|
)
|
||||||
new_event = add_calendars(new_event, event)
|
new_event = add_calendars(new_event, event)
|
||||||
print("\n+new event+\n")
|
print("Success")
|
||||||
return new_event, created
|
return new_event, created
|
||||||
|
|
||||||
# Create Detailed Event with Details & Guests
|
# Create Detailed Event with Details & Guests
|
||||||
@@ -216,7 +216,7 @@ def createDetailedEvent(event, event_type, venue, scraper):
|
|||||||
venue = venue
|
venue = venue
|
||||||
)
|
)
|
||||||
new_event = add_calendars(new_event, event)
|
new_event = add_calendars(new_event, event)
|
||||||
print("\n+new event+\n")
|
print("Success")
|
||||||
return new_event, created
|
return new_event, created
|
||||||
|
|
||||||
# Create iCal event from DF_Online & Medellin
|
# Create iCal event from DF_Online & Medellin
|
||||||
@@ -260,7 +260,7 @@ def getiCalEvents(gcal, scraper, venue, event_type):
|
|||||||
return events
|
return events
|
||||||
|
|
||||||
# Build iCal Events and Send to Create
|
# Build iCal Events and Send to Create
|
||||||
def buildiCalEvents(events, event_type, scraper):
|
def buildiCalEvents(events, event_type, scraper, venue):
|
||||||
for event in events:
|
for event in events:
|
||||||
e = {}
|
e = {}
|
||||||
e['calendars'] = event['calendars']
|
e['calendars'] = event['calendars']
|
||||||
@@ -322,7 +322,7 @@ def getiCalRepeateEvents(gcal, scraper, venue, event_type, cal):
|
|||||||
try:
|
try:
|
||||||
if rules['FREQ'][0] == 'WEEKLY':
|
if rules['FREQ'][0] == 'WEEKLY':
|
||||||
if datetime.today().weekday() != 0:
|
if datetime.today().weekday() != 0:
|
||||||
event = digitools.splitLocation(event, "Medellin")
|
event = splitLocation(event, city="Medellin")
|
||||||
date = datetime.today().date() - timedelta(days=datetime.today().weekday())
|
date = datetime.today().date() - timedelta(days=datetime.today().weekday())
|
||||||
date = datetime.combine(date, event['dateStart'].time())
|
date = datetime.combine(date, event['dateStart'].time())
|
||||||
days = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"]
|
days = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"]
|
||||||
@@ -333,27 +333,28 @@ def getiCalRepeateEvents(gcal, scraper, venue, event_type, cal):
|
|||||||
iCalEventRepeatFilter(day, date, event, scraper, event['venue'], "Ed")
|
iCalEventRepeatFilter(day, date, event, scraper, event['venue'], "Ed")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Error: ", e, "\n\n\n\n")
|
print("Error: ", event, e, "\n\n\n\n")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def iCalEventRepeatFilterteEvent(day, date, event, scraper, venue, event_type):
|
def iCalEventRepeatFilter(day, date, event, scraper, venue, event_type):
|
||||||
days = [day-1, day+6, day+13]
|
days = [day-1, day+6, day+13]
|
||||||
for day in days:
|
for day in days:
|
||||||
event['dateStamp'] = date + timedelta(days=day)
|
event['dateStamp'] = date + timedelta(days=day)
|
||||||
event['dateStart'] = event['dateStamp']
|
event['dateStart'] = event['dateStamp']
|
||||||
digitools.createCleanIcalEvent(event, scraper, venue, event_type)
|
createCleanIcalEvent(event, scraper, venue, event_type)
|
||||||
return
|
return
|
||||||
|
|
||||||
def splitLocation(event, **kwargs):
|
def splitLocation(event, **kwargs):
|
||||||
loc_split = event['strLocation'].split(',')
|
loc_split = event['strLocation'].split(',')
|
||||||
|
ppr(loc_split)
|
||||||
venue_name = loc_split[0]
|
venue_name = loc_split[0]
|
||||||
venue, created = Organization.objects.get_or_create(
|
venue, created = Organization.objects.get_or_create(
|
||||||
name=venue_name,
|
name=venue_name,
|
||||||
)
|
)
|
||||||
event['venue'] = venue
|
event['venue'] = venue
|
||||||
if city:
|
# if kwargs['city']:
|
||||||
venue.city = kwargs['city']
|
# venue.city = kwargs['city']
|
||||||
venue.save()
|
# venue.save()
|
||||||
return event
|
return event
|
||||||
|
|
||||||
# ARCHIVED Methods
|
# ARCHIVED Methods
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# Generated by Django 5.1.1 on 2026-01-12 23:30
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('events', '0038_remove_event_calendar_event_calendar'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='calendar',
|
||||||
|
options={'ordering': ['name'], 'verbose_name_plural': 'Calendars'},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='calendar',
|
||||||
|
name='published',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='organization',
|
||||||
|
name='cal',
|
||||||
|
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='events.calendar'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='organization',
|
||||||
|
name='membership',
|
||||||
|
field=models.CharField(choices=[('Nm', 'Non-Member'), ('Ds', 'DigiSnaxx'), ('Dsp', 'DigiSnaxx +')], default='0', max_length=31),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='organization',
|
||||||
|
name='org_type',
|
||||||
|
field=models.CharField(choices=[('Fb', 'Food & Beverage'), ('Re', 'Retail'), ('Se', 'Service'), ('Vn', 'Venue'), ('Ud', 'Undefined')], default='3', max_length=31),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='promo',
|
||||||
|
name='promo_type',
|
||||||
|
field=models.CharField(choices=[('Ar', 'Art'), ('Fo', 'Food'), ('Ev', 'Event'), ('Re', 'Retail'), ('Sv', 'Service'), ('Ma', 'Mutual Aid'), ('Ca', 'Classified'), ('Jo', 'Job Opening'), ('Ja', 'Journal Article'), ('Sp', 'Startup Pitch'), ('An', 'Academia Nut'), ('Su', 'Survey Question')], default='0', max_length=15),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 5.1.1 on 2026-01-12 23:49
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('events', '0039_alter_calendar_options_calendar_published_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='calendar',
|
||||||
|
options={'ordering': ['-published', 'id'], 'verbose_name_plural': 'Calendars'},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='organization',
|
||||||
|
name='cal',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cal_events', to='events.calendar'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
events/migrations/0041_alter_event_calendar.py
Normal file
18
events/migrations/0041_alter_event_calendar.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.1 on 2026-01-13 00:13
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('events', '0040_alter_calendar_options_alter_organization_cal'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='event',
|
||||||
|
name='calendar',
|
||||||
|
field=models.ManyToManyField(blank=True, null=True, related_name='events', to='events.calendar'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -9,10 +9,12 @@ class Calendar(models.Model):
|
|||||||
name = models.CharField(max_length=31, unique=True)
|
name = models.CharField(max_length=31, unique=True)
|
||||||
shortcode = models.CharField(max_length=3, unique=True)
|
shortcode = models.CharField(max_length=3, unique=True)
|
||||||
desc = models.TextField(blank=True, null=True)
|
desc = models.TextField(blank=True, null=True)
|
||||||
|
published = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name_plural = "Calendars"
|
verbose_name_plural = "Calendars"
|
||||||
ordering = ['name',]
|
ordering = ['-published', 'id',]
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return "%s" % self.shortcode
|
return "%s" % self.shortcode
|
||||||
@@ -29,6 +31,7 @@ class Scraper(models.Model):
|
|||||||
new_items = models.IntegerField(blank=True, null=True)
|
new_items = models.IntegerField(blank=True, null=True)
|
||||||
last_ran = models.DateTimeField(blank=True, null=True)
|
last_ran = models.DateTimeField(blank=True, null=True)
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name_plural = "Scrapers"
|
verbose_name_plural = "Scrapers"
|
||||||
ordering = ['name',]
|
ordering = ['name',]
|
||||||
@@ -78,7 +81,7 @@ class Organization(models.Model):
|
|||||||
address_type = models.CharField(max_length=31, blank=True, null=True)
|
address_type = models.CharField(max_length=31, blank=True, null=True)
|
||||||
address_complete = models.CharField(max_length=63, blank=True, null=True)
|
address_complete = models.CharField(max_length=63, blank=True, null=True)
|
||||||
|
|
||||||
|
cal = models.ForeignKey(Calendar, on_delete=models.CASCADE, related_name="cal_events")
|
||||||
barrio = models.CharField(max_length=127, blank=True, null=True)
|
barrio = models.CharField(max_length=127, blank=True, null=True)
|
||||||
city = models.CharField(max_length=31, blank=True, null=True)
|
city = models.CharField(max_length=31, blank=True, null=True)
|
||||||
state = models.CharField(max_length=15, blank=True, null=True)
|
state = models.CharField(max_length=15, blank=True, null=True)
|
||||||
@@ -113,15 +116,15 @@ class Organization(models.Model):
|
|||||||
|
|
||||||
class Event(models.Model):
|
class Event(models.Model):
|
||||||
EVENT_TYPE = (
|
EVENT_TYPE = (
|
||||||
('Ot', 'Other'),
|
('Ot', '🤔'),
|
||||||
('Mu', 'Music'),
|
('Mu', '🎶'),
|
||||||
('Va', 'Visual Art'),
|
('Va', 'Visual Art'),
|
||||||
('Gv', 'Government'),
|
('Gv', '🛠️'),
|
||||||
('Ce', 'Civic Engagement'),
|
('Ce', 'Civic Engagement'),
|
||||||
('Ed', 'Educational'),
|
('Ed', '🍎'),
|
||||||
('Ma', 'Mutual Aid'),
|
('Ma', 'Mutual Aid'),
|
||||||
('Th', 'Theater'),
|
('Th', '🎭'),
|
||||||
('Co', 'Comedy'),
|
('Co', '🍿'),
|
||||||
)
|
)
|
||||||
EVENT_STATE = (
|
EVENT_STATE = (
|
||||||
('live', 'Live & Direct'),
|
('live', 'Live & Direct'),
|
||||||
@@ -134,7 +137,7 @@ class Event(models.Model):
|
|||||||
show_date = models.DateTimeField()
|
show_date = models.DateTimeField()
|
||||||
show_day = models.DateField()
|
show_day = models.DateField()
|
||||||
|
|
||||||
calendar = models.ManyToManyField(Calendar, blank=True, null=True)
|
calendar = models.ManyToManyField(Calendar, blank=True, null=True, related_name="events")
|
||||||
scraper = models.ForeignKey(Scraper, on_delete=models.CASCADE, null=True)
|
scraper = models.ForeignKey(Scraper, on_delete=models.CASCADE, null=True)
|
||||||
venue = models.ForeignKey(Organization, on_delete=models.CASCADE)
|
venue = models.ForeignKey(Organization, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from .models import Event, Organization, Promo
|
from .models import Calendar, Event, Organization, Promo
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
@@ -35,6 +35,7 @@ class ScopesPermission(BasePermission):
|
|||||||
## Events ##
|
## Events ##
|
||||||
############
|
############
|
||||||
|
|
||||||
|
|
||||||
class OrganizationSerializer(serializers.ModelSerializer):
|
class OrganizationSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Organization
|
model = Organization
|
||||||
@@ -52,6 +53,18 @@ class EventSerializer(serializers.ModelSerializer):
|
|||||||
depth = 2
|
depth = 2
|
||||||
# fields = ('id', 'name',)
|
# fields = ('id', 'name',)
|
||||||
|
|
||||||
|
class CalSerializer(serializers.ModelSerializer):
|
||||||
|
events_count = serializers.SerializerMethodField()
|
||||||
|
class Meta:
|
||||||
|
model = Calendar
|
||||||
|
fields = ['id', 'name', 'shortcode', 'events_count', 'published']
|
||||||
|
# fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
def get_events_count(self, obj):
|
||||||
|
# obj is the current Tag instance
|
||||||
|
return obj.events.count()
|
||||||
|
|
||||||
class PromoSerializer(serializers.ModelSerializer):
|
class PromoSerializer(serializers.ModelSerializer):
|
||||||
organization = OrganizationSerializer(many=False)
|
organization = OrganizationSerializer(many=False)
|
||||||
# event_type = serializers.CharField(source='get_event_type_display')
|
# event_type = serializers.CharField(source='get_event_type_display')
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from .views import *
|
|||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
re_path(r'^events/', EventsAPIView.as_view(), name="get-events"),
|
re_path(r'^events/', EventsAPIView.as_view(), name="get-events"),
|
||||||
re_path(r'^promo/', PromoAPIView.as_view(), name="get-promo"),
|
re_path(r'^promo/', PromoAPIView.as_view(), name="get-promo"),
|
||||||
|
re_path(r'^cals/', CalAPIView.as_view(), name="get-cals"),
|
||||||
# re_path(r'^events-token/', EventsTokenAPIView.as_view(), name="get-token-events"),
|
# re_path(r'^events-token/', EventsTokenAPIView.as_view(), name="get-token-events"),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from .models import *
|
|||||||
from .serializers import *
|
from .serializers import *
|
||||||
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
from django.db.models import Count
|
||||||
|
|
||||||
from rest_framework import generics
|
from rest_framework import generics
|
||||||
from rest_framework.decorators import authentication_classes, permission_classes
|
from rest_framework.decorators import authentication_classes, permission_classes
|
||||||
@@ -26,6 +27,14 @@ td = timedelta(hours=7)
|
|||||||
odt = datetime.now() - td
|
odt = datetime.now() - td
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
class CalAPIView(generics.ListAPIView):
|
||||||
|
serializer_class = CalSerializer
|
||||||
|
queryset = Calendar.objects.all()
|
||||||
|
# queryset = Calendar.objects.filter(published=True)
|
||||||
|
permission_classes = [HasAPIKey]
|
||||||
|
|
||||||
|
|
||||||
class EventsAPIView(generics.ListAPIView):
|
class EventsAPIView(generics.ListAPIView):
|
||||||
serializer_class = EventSerializer
|
serializer_class = EventSerializer
|
||||||
queryset = Event.objects.filter(show_date__gte=odt).order_by('show_date')
|
queryset = Event.objects.filter(show_date__gte=odt).order_by('show_date')
|
||||||
|
|||||||
Reference in New Issue
Block a user