diff --git a/events/digitools.py b/events/digitools.py index 3ed7589..a09055a 100644 --- a/events/digitools.py +++ b/events/digitools.py @@ -67,6 +67,7 @@ def updateScraper(scraper, item_count_start): scraper.new_items = len(num_of_events) - item_count_start scraper.last_ran = datetime.now() scraper.save() + print("Scaper Updated") return # Get site HTML content for XPATH travel @@ -175,7 +176,7 @@ def createDashURL(site_url): # Add Calendar to Event Object (maybe extraneous) def add_calendar(event, calendar): - print("Add Calendar", type(event), event, calendar) + # print("Add Calendar", type(event), event, calendar) if type(event) is tuple: event = event[0] cal = Calendar.objects.get(shortcode=calendar) @@ -208,7 +209,8 @@ def createBasicEvent(event, event_type, venue): print("\n+new event+") return new_event, created except Exception as e: - print("Error: ", e) + print("DT Error: ", e) + ppr(event) return None, None # Create iCal Event diff --git a/events/migrations/0045_event_event_image_event_event_image_url_and_more.py b/events/migrations/0045_event_event_image_event_event_image_url_and_more.py new file mode 100644 index 0000000..bc52126 --- /dev/null +++ b/events/migrations/0045_event_event_image_event_event_image_url_and_more.py @@ -0,0 +1,40 @@ +# Generated by Django 6.0.1 on 2026-01-24 20:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0044_rename_is_listed_organization_is_member_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='event', + name='event_image', + field=models.ImageField(blank=True, upload_to='events'), + ), + migrations.AddField( + model_name='event', + name='event_image_url', + field=models.URLField(blank=True, null=True), + ), + migrations.AddField( + model_name='person', + name='ad_prefs', + field=models.CharField(default='Test'), + preserve_default=False, + ), + migrations.AddField( + model_name='person', + name='event_prefs', + field=models.CharField(default='Test prefes\x08\x08s\x08\x08'), + preserve_default=False, + ), + migrations.AlterField( + model_name='promo', + name='promo_type', + field=models.CharField(choices=[('Ar', 'ðŸŽĻ'), ('Fo', 'ðŸĨ™'), ('Ev', '🎟ïļ'), ('Re', '🛍ïļ'), ('Sv', '☎ïļ'), ('Ma', 'ðŸŠĒ'), ('Ca', '📌'), ('Jo', 'ðŸŠĪ'), ('Ja', '✒ïļ'), ('Sp', 'ðŸ’Ą'), ('An', 'ðŸĐš'), ('Su', 'ðŸ§Đ')], default='Ar', max_length=15), + ), + ] diff --git a/events/migrations/0046_organization_address_complete_alter_event_event_type_and_more.py b/events/migrations/0046_organization_address_complete_alter_event_event_type_and_more.py new file mode 100644 index 0000000..476d7ac --- /dev/null +++ b/events/migrations/0046_organization_address_complete_alter_event_event_type_and_more.py @@ -0,0 +1,66 @@ +# Generated by Django 6.0.1 on 2026-01-29 01:23 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0045_event_event_image_event_event_image_url_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='organization', + name='address_complete', + field=models.CharField(blank=True, max_length=127, null=True), + ), + migrations.AlterField( + model_name='event', + name='event_type', + field=models.CharField(choices=[('Ce', 'Civic Engagement'), ('Co', 'ðŸŋ'), ('Da', '🊇'), ('Ed', '🍎'), ('Ex', '💊'), ('Gv', '🛠ïļ'), ('Mu', 'ðŸŽķ'), ('Na', '🍃'), ('Ot', 'ðŸĪ”'), ('Th', '🎭'), ('Va', 'Visual Art')], default='Mu', max_length=15), + ), + migrations.AlterField( + model_name='organization', + name='cal', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='org_cal', to='events.calendar'), + ), + migrations.AlterField( + model_name='organization', + name='city', + field=models.CharField(blank=True, max_length=127, null=True), + ), + migrations.AlterField( + model_name='organization', + name='org_type', + field=models.CharField(choices=[('Fb', 'Food & Beverage'), ('Re', 'Retail'), ('Se', 'Service'), ('Vn', 'Venue'), ('Ud', 'Undefined')], default='Re', max_length=31), + ), + migrations.AlterField( + model_name='organization', + name='state', + field=models.CharField(blank=True, max_length=127, null=True), + ), + migrations.AlterField( + model_name='promo', + name='promo_type', + field=models.CharField(choices=[('Ar', 'ðŸŽĻ'), ('Bv', 'ðŸŧ'), ('Fo', 'ðŸĨ—'), ('Ev', '🎟ïļ'), ('Re', '🛍ïļ'), ('Sv', '📌'), ('Ma', 'ðŸŠĒ'), ('Ca', '🔍'), ('Jo', '📝'), ('Ja', '✒ïļ'), ('Sp', '⚙ïļ'), ('An', 'ðŸĐš'), ('Su', 'ðŸ§Đ')], default='Ar', max_length=15), + ), + migrations.CreateModel( + name='Place', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=31, unique=True)), + ('place_type', models.CharField(blank=True, max_length=31, null=True)), + ('num_of_divs', models.CharField(blank=True, max_length=4, null=True)), + ('div_type', models.CharField(blank=True, max_length=7, null=True)), + ('connection_type', models.CharField(choices=[('Ci', 'City'), ('Co', 'County'), ('St', 'State')], default='Ci', max_length=31)), + ('notes', models.TextField(blank=True, null=True)), + ('calendar', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='events.calendar')), + ('connection', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='events.place')), + ], + ), + migrations.DeleteModel( + name='Person', + ), + ] diff --git a/events/migrations/0047_organization_gmap_link_alter_organization_website.py b/events/migrations/0047_organization_gmap_link_alter_organization_website.py new file mode 100644 index 0000000..f479af0 --- /dev/null +++ b/events/migrations/0047_organization_gmap_link_alter_organization_website.py @@ -0,0 +1,23 @@ +# Generated by Django 6.0.1 on 2026-02-03 05:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0046_organization_address_complete_alter_event_event_type_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='organization', + name='gmap_link', + field=models.CharField(blank=True, max_length=253, null=True), + ), + migrations.AlterField( + model_name='organization', + name='website', + field=models.CharField(blank=True, max_length=127, null=True), + ), + ] diff --git a/events/migrations/0048_organization_has_map.py b/events/migrations/0048_organization_has_map.py new file mode 100644 index 0000000..aa5d328 --- /dev/null +++ b/events/migrations/0048_organization_has_map.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0.1 on 2026-02-03 05:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0047_organization_gmap_link_alter_organization_website'), + ] + + operations = [ + migrations.AddField( + model_name='organization', + name='has_map', + field=models.BooleanField(default=False), + ), + ] diff --git a/events/models.py b/events/models.py index 4a6754d..c0bae15 100644 --- a/events/models.py +++ b/events/models.py @@ -55,8 +55,63 @@ class Tags(models.Model): return u'%s' % self.name +class Place(models.Model): + PLACE_TYPE = ( + ('Pc', 'Precinct'), + ('Mu', 'Municipality'), + ('Ci', 'City'), + ('Co', 'County'), + ('Ld', 'Legislative District'), + ('St', 'State'), + ) + name = models.CharField(max_length=31, unique=True) + place_type = models.CharField(max_length=31,blank=True, null=True) + num_of_divs = models.CharField(max_length=4, blank=True, null=True) + div_type = models.CharField(max_length=7, blank=True, null=True) + connection = models.ForeignKey("Place", on_delete=models.CASCADE) + connection_type = models.CharField(max_length=31, choices=PLACE_TYPE, default='Ci') + calendar = models.ForeignKey(Calendar, on_delete=models.CASCADE) + notes = models.TextField(blank=True, null=True) + + def __unicode__(self): + return "%s" % self.name + + def __str__(self): + return u'%s' % self.name + + + +class Official(models.Model): + POSITION_TYPE = ( + ('Gv', 'Governor'), + ('Sc', 'Secretary'), + ('Re', 'Representative'), + ('Sn', 'Senator'), + ('Sr', 'State Rep'), + ('Ss', 'State Senator'), + ('Cc', 'County Commissioner'), + ('Cm', 'Council Member'), + ('Ju', 'Judge'), + ('Bm', 'Board Member'), + ) + + name = models.CharField(max_length=31, unique=True) + website = models.CharField(max_length=31,blank=True, null=True) + boss = models.ForeignKey("Place", on_delete=models.CASCADE) + employer = models.ForeignKey("Organization", on_delete=models.CASCADE) + position = models.CharField(max_length=31, choices=POSITION_TYPE, default='Ci') + notes = models.TextField(blank=True, null=True) + + def __unicode__(self): + return "%s" % self.name + + def __str__(self): + return u'%s' % self.name + + class Organization(models.Model): ORG_TYPE = ( + ('Gv', 'Government'), ('Fb', 'Food & Beverage'), ('Re', 'Retail'), ('Se', 'Service'), @@ -65,20 +120,23 @@ class Organization(models.Model): ) name = models.CharField(max_length=63) - website = models.CharField(max_length=126, blank=True, null=True) - org_type = models.CharField(max_length=31, choices=ORG_TYPE, default='3') - cal = models.ForeignKey(Calendar, on_delete=models.CASCADE, blank=True, null=True, related_name="cal_events") + website = models.CharField(max_length=127, blank=True, null=True) + org_type = models.CharField(max_length=31, choices=ORG_TYPE, default='Re') + cal = models.ForeignKey(Calendar, on_delete=models.CASCADE, blank=True, null=True, related_name="org_cal") short_desc = models.CharField(max_length=63, blank=True, null=True) long_desc = models.TextField(blank=True, null=True) + gmap_link = models.CharField(max_length=253, blank=True, null=True) tags = models.ManyToManyField(Tags, blank=True) + address_complete = models.CharField(max_length=127, blank=True, null=True) address_numbers = models.CharField(max_length=63, blank=True, null=True) address_type = models.CharField(max_length=31, blank=True, null=True) - barrio = models.CharField(max_length=127, blank=True, null=True) - city = models.CharField(max_length=31, blank=True, null=True) - state = models.CharField(max_length=15, blank=True, null=True) + city = models.CharField(max_length=127, blank=True, null=True) + state = models.CharField(max_length=127, blank=True, null=True) + city = models.ForeignKey(Place, on_delete=models.CASCADE, related_name="org_city") + state = models.ForeignKey(Place, on_delete=models.CASCADE, related_name="org_state" ) zip_code = models.CharField(max_length=15, blank=True, null=True) phone_number = models.CharField(max_length=255, blank=True, null=True) @@ -87,6 +145,7 @@ class Organization(models.Model): is_member= models.BooleanField(default=False) is_501c = models.BooleanField(default=False) is_venue= models.BooleanField(default=False) + has_map = models.BooleanField(default=False) latitude = models.FloatField(blank=True, null=True) longitude = models.FloatField(blank=True, null=True) @@ -104,27 +163,6 @@ class Organization(models.Model): return u'%s' % self.name -class Person(models.Model): - username = models.CharField(max_length=63, blank=True, null=True) - email = models.CharField(max_length=63, blank=True, null=True) - calendar = models.ManyToManyField(Calendar, blank=True, null=True) - event_prefs = models.CharField() - ad_prefs = models.CharField() - - - class Meta: - verbose_name_plural = "People" - ordering = ['username'] - - def __unicode__(self): - return "%s" % self.username - - def __str__(self): - return u'%s' % self.username - - - - class Event(models.Model): EVENT_TYPE = ( ('Ce', 'Civic Engagement'), @@ -133,8 +171,8 @@ class Event(models.Model): ('Ed', '🍎'), ('Ex' ,'💊'), ('Gv', '🛠ïļ'), - ('Ma', 'ðŸĪ'), ('Mu', 'ðŸŽķ'), + ('Na', '🍃'), ('Ot', 'ðŸĪ”'), ('Th', '🎭'), ('Va', 'Visual Art'), @@ -177,15 +215,16 @@ class Event(models.Model): class Promo(models.Model): PROMO_TYPE = ( ('Ar', 'ðŸŽĻ'), - ('Fo', 'ðŸĨ™'), + ('Bv', 'ðŸŧ'), + ('Fo', 'ðŸĨ—'), ('Ev', '🎟ïļ'), ('Re', '🛍ïļ'), - ('Sv', '☎ïļ'), + ('Sv', '📌'), ('Ma', 'ðŸŠĒ'), - ('Ca', '📌'), - ('Jo', 'ðŸŠĪ'), + ('Ca', '🔍'), + ('Jo', '📝'), ('Ja', '✒ïļ'), - ('Sp', 'ðŸ’Ą'), + ('Sp', '⚙ïļ'), ('An', 'ðŸĐš'), ('Su', 'ðŸ§Đ'), ) @@ -213,6 +252,47 @@ class Promo(models.Model): return u'%s' % self.title + + +# class Person(models.Model): +# username = models.CharField(max_length=63, blank=True, null=True) +# email = models.CharField(max_length=63, blank=True, null=True) +# membership = models.CharField() +# business = models.OneToOneField() +# calendar = models.ManyToManyField(Calendar, blank=True, null=True) +# event_prefs = models.CharField() +# ad_prefs = models.CharField() +# api_key = model.CharField() + + +# class Meta: +# verbose_name_plural = "People" +# ordering = ['username'] + +# def __unicode__(self): +# return "%s" % self.username + +# def __str__(self): +# return u'%s' % self.username + + +# class ProfileStat(models.Model): +# user_profile = models.OneToOneField() +# num_of_cals = models.SmallIntegerField() +# num_of_ads = models.SmallIntegerField() +# num_of_api_calls = models.SmallIntegerField() + +# class Meta: +# verbose_name_plural = "Profile Stats" +# ordering = ['user_profile'] + +# def __unicode__(self): +# return "%s" % self.user_profile + +# def __str__(self): +# return u'%s' % self.user_profile + + # class UserThrottle(models.Model): # user = models.ForeignKey(User, on_delete=models.CASCADE) # scope = models.CharField(max_length=20, choices=( diff --git a/events/serializers.py b/events/serializers.py index 3556551..26cad95 100644 --- a/events/serializers.py +++ b/events/serializers.py @@ -39,7 +39,7 @@ class ScopesPermission(BasePermission): class OrganizationSerializer(serializers.ModelSerializer): class Meta: model = Organization - fields = ('id', 'name', 'website', 'city') + fields = ('id', 'name', 'website', 'city', 'latitude', 'longitude', 'has_map') # fields = '__all__' diff --git a/events/urls.py b/events/urls.py index 51dccfd..679b4ec 100644 --- a/events/urls.py +++ b/events/urls.py @@ -21,6 +21,7 @@ urlpatterns = [ re_path(r'^events/', EventsAPIView.as_view(), name="get-events"), re_path(r'^promo/', PromoAPIView.as_view(), name="get-promo"), re_path(r'^cals/', CalAPIView.as_view(), name="get-cals"), + re_path(r'^biz/', BizAPIView.as_view(), name="get-bizs"), # re_path(r'^events-token/', EventsTokenAPIView.as_view(), name="get-token-events"), ] diff --git a/events/views.py b/events/views.py index c13b7c9..6a77c76 100644 --- a/events/views.py +++ b/events/views.py @@ -49,9 +49,9 @@ class EventsAPIView(generics.ListAPIView): show_day = self.request.GET.get('show_date') if self.request.GET.get('event_type') != None: event_type = self.request.GET.get('event_type') - queryset = Event.objects.filter(event_type=event_type,calendar__shortcode=calendar,show_date__gte=show_day).order_by('show_date') + queryset = Event.objects.filter(event_type=event_type,calendar__shortcode=calendar,show_date__gte=show_day).order_by('show_date')[:126] return queryset - queryset = Event.objects.filter(calendar__shortcode=calendar,show_date__gte=show_day).order_by('show_date') + queryset = Event.objects.filter(calendar__shortcode=calendar,show_date__gte=show_day).order_by('show_date')[:126] return queryset @@ -67,6 +67,18 @@ class PromoAPIView(generics.ListAPIView): queryset = Promo.objects.filter(published=True, calendar__shortcode=calendar).order_by('?') return queryset +class BizAPIView(generics.ListAPIView): + serializer_class = OrganizationSerializer + queryset = Organization.objects.all()[:10] + # filterset_fields = ['organization__name', 'calendar__shortcode',] + # search_fields = ['organization__name', 'calendar__shortcode',] + permission_classes = [HasAPIKey] + + # def get_queryset(self): + # calendar = self.request.GET.get('calendar__shortcode') + # queryset = Promo.objects.filter(published=True, calendar__shortcode=calendar).order_by('?') + # return queryset + # class EventsTokenAPIView(APIAccessTokenView): # serializer_class = EventSerializer # authentication_classes = (TokenAuthentication, BasicAuthentication,)