<commit_before>from datetime import datetime
from datetime import date as pythondate

from django.conf import settings
from django.db import models
from django.db.models import Q
from django.db.models.signals import post_save
from django.template.defaultfilters import date, time, slugify

import mptt

from cms.models import CMSPlugin
from cms.models.fields import PlaceholderField

from filer.fields.image import FilerImageField

from contacts_and_people.models import Entity, Person, Building, default_entity_id

from links.models import ExternalLink

from arkestra_utilities.output_libraries.dates import nice_date
from arkestra_utilities.universal_plugins import UniversalPluginModelMixin, UniversalPluginOptions
from arkestra_utilities.mixins import URLModelMixin

from managers import NewsArticleManager, EventManager

PLUGIN_HEADING_LEVELS = settings.PLUGIN_HEADING_LEVELS
PLUGIN_HEADING_LEVEL_DEFAULT = settings.PLUGIN_HEADING_LEVEL_DEFAULT
COLLECT_TOP_ALL_FORTHCOMING_EVENTS = settings.COLLECT_TOP_ALL_FORTHCOMING_EVENTS
DATE_FORMAT = settings.ARKESTRA_DATE_FORMAT

class NewsAndEvents(UniversalPluginModelMixin, URLModelMixin):

    content = models.TextField(null=True, blank=True, 
        help_text="Not used or required for external items")
    
    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        super(NewsAndEvents, self).save(*args, **kwargs)
    
    def get_entity(self):
        """
        Real-world information, can be None
        """
        return self.hosted_by or Entity.objects.get(id=default_entity_id)
    
    def get_website(self):
        """
        for internal Arkestra purposes only
        """
        if self.get_entity():
            return self.get_entity().get_website()
        else:
            return None
        

class NewsArticle(NewsAndEvents):
    date = models.DateTimeField(default=datetime.now,
        help_text=u"Dateline for the item (the item will not be published until then" ,  )
    display_indefinitely = models.BooleanField(
        help_text=u"Important news; it won't expire from news lists" , )    
    external_news_source = models.ForeignKey('NewsSource', null=True, blank=True, 
        help_text=u"If this news item is from an external source")
    sticky_until = models.DateField(u"Featured until", 
        null=True, blank=True, default=pythondate.today,
        help_text=u"Will remain a featured item until this date")
    is_sticky_everywhere = models.BooleanField(u"Featured everywhere",
        default=False, help_text=u"Will be featured in other entities's news lists") 
    objects = NewsArticleManager()
    
    class Meta:
        ordering = ['-date']
        
    def get_absolute_url(self):
        if self.external_url:
            return self.external_url.url
        else:
            return "/news/%s/" % self.slug
        
    def get_when(self):
        """
        get_when() provides a human-readable attribute under which items can be grouped.
        Usually, this is an easily-readble rendering of the date (e.g. "April 2010") but it can also be "Top news", for items to be given special prominence.
        """
        if getattr(self, "sticky", None):
            return "Top news"        
        get_when = nice_date(self.date, DATE_FORMAT["date_groups"])
        return get_when


class Event(NewsAndEvents):
    type = models.ForeignKey('EventType')
    featuring = models.ManyToManyField(Person, related_name='%(class)s_featuring',
        null=True, blank=True,
        help_text="The speakers, lecturers, instructors or other people featured in this event")
    parent = models.ForeignKey('self', blank=True, null=True, related_name='children')
    SERIES = (
        (False, u"an actual event"),
        (True, u"a series of events"),
    )
    series = models.BooleanField("This is", default=False, choices=SERIES)
    SHOW_TITLES = (
        ("series children", u"show title of series followed by title of children"),
        ("series", u"show title of series only"),
        ("children", u"show title of children only"),
    )
    show_titles = models.CharField(u"Titles",
        max_length = 25,
        default="children",
        choices=SHOW_TITLES,
        )
    DISPLAY_SERIES_SUMMARY = (
        (False, u"display children's summaries"),
        (True, u"display the summary for the series"),
    ) 
    display_series_summary = models.BooleanField(u"Summaries",
        default=False,
        choices=DISPLAY_SERIES_SUMMARY,
        )
    child_list_heading = models.CharField(max_length=50, null=True, blank=True, 
        help_text= u"e.g. Conference sessions; Lectures in this series")
    start_date = models.DateField(null=True, blank=True,
        help_text=u"Not required for a series of events")    
    start_time = models.TimeField(null=True, blank=True)    
    end_date = models.DateField(null=True, blank=True)
    end_time = models.TimeField(null=True, blank=True)
    single_day_event = models.BooleanField(default=False)
    building = models.ForeignKey(Building, null=True, blank=True)
    precise_location = models.CharField(max_length=50, null=True, blank=True,
        help_text=u"Precise location within building, for visitors")
    access_note = models.CharField(max_length=255, null=True, blank=True,
        help_text=u"Notes on access/visiting hours/etc")
    # this won't appear in the admin
    jumps_queue_on = models.DateField(null=True, blank=True,
        help_text=u"Will become a featured item on this date") 
    jumps_queue_everywhere = models.BooleanField(default=False)
    registration_enquiries = models.ManyToManyField(Person, 
        related_name = '%(class)s_registration', 
        null = True, blank = True,
        help_text=u"The people who responsible for registration, if different from those in <em>Please contact</em>"
        ) 
    objects = EventManager()
    
    class Meta:
        ordering = ['type', 'start_date', 'start_time']
    
    def get_absolute_url(self):
        if self.external_url:
            return self.external_url.url
        else:
            return "/event/%s/" % self.slug

    @property
    def informative_url(self):
        """ 
        An event has an 'informative_url' if it itself is uninformative, but it is a child of a series
        """
        # print self, "checking"
        if self.is_uninformative and self.parent and self.parent.series:
            # print self, "parent!"
            return self.parent.get_absolute_url()
        else:
            # print self, "self!"
            return self.get_absolute_url()
  
    @property
    def show_parent_series(self):
        """
        checks whether we should show the parent series too in lists
        """
        if self.parent and self.parent.series:
            return self.parent.show_titles

    @property
    def is_uninformative(self):
        if self.body and self.body.cmsplugin_set.all() or self.external_url or self.please_contact.all() or self.registration_enquiries.all() or self.links:
            # print "uninformative"
            return False
        else:
            return "informative"
            return True
        
    def save(self):
        def slug_is_bad(self):
            if self.slug in [slug.values()[0] for slug in Event.objects.exclude(id=self.id).values("slug")]:
                return True

        if self.slug == "" or slug_is_bad(self):
            self.slug=slugify(self.short_title)
        if slug_is_bad(self):
            suffix = slugify(date(self.start_date, "Y"))
            if not suffix in self.slug:
                self.slug = self.slug + "-" + suffix
                # print "adding suffix:", suffix, self.slug<commit_msg>checking for links on events caused exception; removed<commit_after>from datetime import datetime
from datetime import date as pythondate

from django.conf import settings
from django.db import models
from django.db.models import Q
from django.db.models.signals import post_save
from django.template.defaultfilters import date, time, slugify

import mptt

from cms.models import CMSPlugin
from cms.models.fields import PlaceholderField

from filer.fields.image import FilerImageField

from contacts_and_people.models import Entity, Person, Building, default_entity_id

from links.models import ExternalLink

from arkestra_utilities.output_libraries.dates import nice_date
from arkestra_utilities.universal_plugins import UniversalPluginModelMixin, UniversalPluginOptions
from arkestra_utilities.mixins import URLModelMixin

from managers import NewsArticleManager, EventManager

PLUGIN_HEADING_LEVELS = settings.PLUGIN_HEADING_LEVELS
PLUGIN_HEADING_LEVEL_DEFAULT = settings.PLUGIN_HEADING_LEVEL_DEFAULT
COLLECT_TOP_ALL_FORTHCOMING_EVENTS = settings.COLLECT_TOP_ALL_FORTHCOMING_EVENTS
DATE_FORMAT = settings.ARKESTRA_DATE_FORMAT

class NewsAndEvents(UniversalPluginModelMixin, URLModelMixin):

    content = models.TextField(null=True, blank=True, 
        help_text="Not used or required for external items")
    
    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        super(NewsAndEvents, self).save(*args, **kwargs)
    
    def get_entity(self):
        """
        Real-world information, can be None
        """
        return self.hosted_by or Entity.objects.get(id=default_entity_id)
    
    def get_website(self):
        """
        for internal Arkestra purposes only
        """
        if self.get_entity():
            return self.get_entity().get_website()
        else:
            return None
        

class NewsArticle(NewsAndEvents):
    date = models.DateTimeField(default=datetime.now,
        help_text=u"Dateline for the item (the item will not be published until then" ,  )
    display_indefinitely = models.BooleanField(
        help_text=u"Important news; it won't expire from news lists" , )    
    external_news_source = models.ForeignKey('NewsSource', null=True, blank=True, 
        help_text=u"If this news item is from an external source")
    sticky_until = models.DateField(u"Featured until", 
        null=True, blank=True, default=pythondate.today,
        help_text=u"Will remain a featured item until this date")
    is_sticky_everywhere = models.BooleanField(u"Featured everywhere",
        default=False, help_text=u"Will be featured in other entities's news lists") 
    objects = NewsArticleManager()
    
    class Meta:
        ordering = ['-date']
        
    def get_absolute_url(self):
        if self.external_url:
            return self.external_url.url
        else:
            return "/news/%s/" % self.slug
        
    def get_when(self):
        """
        get_when() provides a human-readable attribute under which items can be grouped.
        Usually, this is an easily-readble rendering of the date (e.g. "April 2010") but it can also be "Top news", for items to be given special prominence.
        """
        if getattr(self, "sticky", None):
            return "Top news"        
        get_when = nice_date(self.date, DATE_FORMAT["date_groups"])
        return get_when


class Event(NewsAndEvents):
    type = models.ForeignKey('EventType')
    featuring = models.ManyToManyField(Person, related_name='%(class)s_featuring',
        null=True, blank=True,
        help_text="The speakers, lecturers, instructors or other people featured in this event")
    parent = models.ForeignKey('self', blank=True, null=True, related_name='children')
    SERIES = (
        (False, u"an actual event"),
        (True, u"a series of events"),
    )
    series = models.BooleanField("This is", default=False, choices=SERIES)
    SHOW_TITLES = (
        ("series children", u"show title of series followed by title of children"),
        ("series", u"show title of series only"),
        ("children", u"show title of children only"),
    )
    show_titles = models.CharField(u"Titles",
        max_length = 25,
        default="children",
        choices=SHOW_TITLES,
        )
    DISPLAY_SERIES_SUMMARY = (
        (False, u"display children's summaries"),
        (True, u"display the summary for the series"),
    ) 
    display_series_summary = models.BooleanField(u"Summaries",
        default=False,
        choices=DISPLAY_SERIES_SUMMARY,
        )
    child_list_heading = models.CharField(max_length=50, null=True, blank=True, 
        help_text= u"e.g. Conference sessions; Lectures in this series")
    start_date = models.DateField(null=True, blank=True,
        help_text=u"Not required for a series of events")    
    start_time = models.TimeField(null=True, blank=True)    
    end_date = models.DateField(null=True, blank=True)
    end_time = models.TimeField(null=True, blank=True)
    single_day_event = models.BooleanField(default=False)
    building = models.ForeignKey(Building, null=True, blank=True)
    precise_location = models.CharField(max_length=50, null=True, blank=True,
        help_text=u"Precise location within building, for visitors")
    access_note = models.CharField(max_length=255, null=True, blank=True,
        help_text=u"Notes on access/visiting hours/etc")
    # this won't appear in the admin
    jumps_queue_on = models.DateField(null=True, blank=True,
        help_text=u"Will become a featured item on this date") 
    jumps_queue_everywhere = models.BooleanField(default=False)
    registration_enquiries = models.ManyToManyField(Person, 
        related_name = '%(class)s_registration', 
        null = True, blank = True,
        help_text=u"The people who responsible for registration, if different from those in <em>Please contact</em>"
        ) 
    objects = EventManager()
    
    class Meta:
        ordering = ['type', 'start_date', 'start_time']
    
    def get_absolute_url(self):
        if self.external_url:
            return self.external_url.url
        else:
            return "/event/%s/" % self.slug

    @property
    def informative_url(self):
        """ 
        An event has an 'informative_url' if it itself is uninformative, but it is a child of a series
        """
        # print 
        # print "========================================"
        # print "checking", self
        # print "is_uninformative", self.is_uninformative
        # print "self.parent", self.parent
        # 
        if self.is_uninformative and self.parent and self.parent.series:
            # print self, "parent!"
            return self.parent.get_absolute_url()
        else:
            # print self, "self!"
            return self.get_absolute_url()
  
    @property
    def show_parent_series(self):
        """
        checks whether we should show the parent series too in lists
        """
        if self.parent and self.parent.series:
            return self.parent.show_titles

    @property
    def is_uninformative(self):
        print 
        print "============================"
        print self.body
        if self.body:
            print 1, self.body.cmsplugin_set.all()
            print 2, self.external_url
            print 3, self.please_contact.all()
            print 4, self.registration_enquiries.all()
        print "----------------------------"
        if self.body and self.body.cmsplugin_set.all() or self.external_url or self.please_contact.all() or self.registration_enquiries.all(): # or self.links_set.all():
            print "uninformative"
            return False
        else:
            print "informative"
            return True
        
    def save(self):
        def slug_is_bad(self):
            if self.slug in [slug.values()[0] for slug in Event.objects.exclude(id=self.id).values("slug")]:
                return True

        if self.slug == "" or slug_is_bad(self):
            self.slug=slugify(self.short_title)
        if slug_is_bad(self):
            suffix = slugify(date(self.start_date, "Y"))
            if not suffix in self.slug:
                self.slug = self.slug + "-" + suffix
                # print "adding suffix:", suffix, self.slug
{'fraction_non_alphanumeric': 0.0968267904176596, 'fraction_numerical': 0.0020067728583970904, 'mean_word_length': 2.8631298449612403, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2100873', 'n_tokens_mistral': 4687, 'n_tokens_neox': 4558, 'n_words': 1203}