77import os
88import warnings
99from datetime import date , datetime
10- from typing import Dict , List , Optional , TYPE_CHECKING , Union
10+ from typing import Dict , List , Optional , TYPE_CHECKING , Union , Tuple
1111
1212# This is a requirement for icalendar, even if django doesn't require it
1313import pytz
@@ -798,7 +798,9 @@ def upcoming_occurrences(self):
798798 return self .query_occurrences (num_of_instances_to_return = 10 )
799799
800800 @property
801- def most_recent_occurrence (self ):
801+ def most_recent_occurrence (
802+ self ,
803+ ) -> Tuple [datetime , datetime , BaseOccurrence ]:
802804 """
803805 Gets the next upcoming, or last occurrence if the event has no more occurrences.
804806 """
@@ -807,23 +809,32 @@ def most_recent_occurrence(self):
807809 noc = self .next_occurrence ()
808810 if noc :
809811 return noc
810- aoc = []
811- for occurrence in self .occurrences .all ():
812- aoc += [instance for instance in occurrence .all_occurrences ()]
813- if len (aoc ) > 0 :
814- return aoc [- 1 ] # last one in the list
815812
816813 except AttributeError :
817814 # Triggers when a preview is initiated on an
818815 # EventPage because it uses a FakeQuerySet object.
819816 # Here we manually compute the next_occurrence
820817 occurrences = [e .next_occurrence () for e in self .occurrences .all ()]
821- if occurrences :
818+ # If there are no more occurrences, we find the last one instead
819+ if occurrences and None not in occurrences :
822820 return sorted (occurrences , key = lambda tup : tup [0 ])[0 ]
823821
822+ # If both of the above methods fail to find a future occurrence,
823+ # instead return the last occurrence.
824+ aoc = []
825+ for occurrence in self .occurrences .all ():
826+ aoc += [instance for instance in occurrence .all_occurrences ()]
827+ if len (aoc ) > 0 :
828+ return aoc [- 1 ] # last one in the list
829+
824830 @property
825831 def seo_struct_event_dict (self ) -> dict :
826832 next_occ = self .most_recent_occurrence
833+ if not next_occ :
834+ return {}
835+ # The method returns a tuple of the start, end, and object. We only care about
836+ # the object, so take it out of the tuple.
837+ next_occ = next_occ [2 ]
827838 sd_dict = {
828839 "@context" : "https://schema.org/" ,
829840 "@type" : "Event" ,
@@ -833,12 +844,18 @@ def seo_struct_event_dict(self) -> dict:
833844 "endDate" : next_occ .end ,
834845 "mainEntityOfPage" : {
835846 "@type" : "WebPage" ,
836- "@id" : self .get_full_url ,
847+ "@id" : self .get_full_url () ,
837848 },
838849 }
839850
840851 if self .seo_image :
841- sd_dict .update ({"image" : get_struct_data_images (self .seo_image )})
852+ sd_dict .update (
853+ {
854+ "image" : get_struct_data_images (
855+ self .get_site (), self .seo_image
856+ )
857+ }
858+ )
842859
843860 if self .address :
844861 sd_dict .update (
@@ -879,7 +896,6 @@ def query_occurrences(self, num_of_instances_to_return=None, **kwargs):
879896
880897 # For each occurrence rule in all of the occurrence rules for this event.
881898 for occurrence in self .occurrences .all ():
882-
883899 # Add the qualifying generated event instances to the list.
884900 event_instances += [
885901 instance
@@ -1280,7 +1296,6 @@ def process_data(self, form, request):
12801296 processed_data = {}
12811297 # Handle file uploads
12821298 for key , val in form .cleaned_data .items ():
1283-
12841299 if (
12851300 type (val ) == InMemoryUploadedFile
12861301 or type (val ) == TemporaryUploadedFile
@@ -1318,7 +1333,6 @@ def get_storage(self):
13181333 def process_form_submission (
13191334 self , request , form , form_submission , processed_data
13201335 ):
1321-
13221336 # Save to database
13231337 if self .save_to_database :
13241338 form_submission .save ()
@@ -1332,7 +1346,6 @@ def process_form_submission(
13321346 context = Context (self .data_to_dict (processed_data , request ))
13331347 # Render emails as if they are django templates.
13341348 for email in self .confirmation_emails .all ():
1335-
13361349 # Build email message parameters.
13371350 message_args = {}
13381351 # From
@@ -1437,7 +1450,6 @@ def send_mail(
14371450 message .send ()
14381451
14391452 def render_landing_page (self , request , form_submission = None ):
1440-
14411453 """
14421454 Renders the landing page.
14431455
@@ -1646,7 +1658,6 @@ class CoderedSubmissionRevision(SubmissionRevision, models.Model):
16461658
16471659
16481660class CoderedSessionFormSubmission (SessionFormSubmission ):
1649-
16501661 INCOMPLETE = "incomplete"
16511662 COMPLETE = "complete"
16521663 REVIEWED = "reviewed"
0 commit comments