Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #29 from ic-labs/feature/event-content-listing-plugin
Browse files Browse the repository at this point in the history
Add `EventContentListingPlugin`
  • Loading branch information
jmurty authored Feb 28, 2017
2 parents 4b8ab97 + 2e1be81 commit d51df53
Show file tree
Hide file tree
Showing 13 changed files with 238 additions and 1 deletion.
1 change: 1 addition & 0 deletions icekit_events/plugins/event_content_listing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = '%s.apps.AppConfig' % __name__
76 changes: 76 additions & 0 deletions icekit_events/plugins/event_content_listing/abstract_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
from datetime import timedelta

from django.db import models
from django.db.models import Q
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _

from timezone import timezone as djtz # django-timezone

from icekit_events.models import EventType, Occurrence
from icekit.plugins.content_listing.abstract_models import \
AbstractContentListingItem


@python_2_unicode_compatible
class AbstractEventContentListingItem(AbstractContentListingItem):
"""
An embedded listing of event content items.
"""
limit_to_types = models.ManyToManyField(
EventType,
help_text="Leave empty to show all events.",
blank=True,
db_table="ik_event_listing_types",
)
from_date = models.DateTimeField(
blank=True, null=True,
help_text="Only show events with occurrences that end after this"
" date and time.",
)
to_date = models.DateTimeField(
blank=True, null=True,
help_text="Only show events with occurrences that start before this"
" date and time.",
)
from_days_ago = models.IntegerField(
blank=True, null=True,
help_text="Only show events with occurrences after this number of"
" days into the past. Set this to zero to show only events"
" with future occurrences.",
)
to_days_ahead = models.IntegerField(
blank=True, null=True,
help_text="Only show events with occurrences before this number of"
" days into the future. Set this to zero to show only events"
" with past occurrences.",
)

class Meta:
abstract = True
verbose_name = _('Event Content Listing')

def __str__(self):
return 'Event Content Listing of %s' % self.content_type

def get_items(self):
qs = Occurrence.objects.visible().distinct()
if self.limit_to_types.count():
types = self.limit_to_types.all()
qs = qs.filter(
Q(event__primary_type__in=types) |
Q(event__secondary_types__in=types)
)
# Apply `from_date` and `to_date` limits
qs = qs.overlapping(self.from_date, self.to_date)
# Apply `from_days_ago` and `to_days_ahead` limits
today = djtz.now().date()
from_date = to_date = None
if self.from_days_ago is not None:
from_date = today - timedelta(days=self.from_days_ago)
if self.to_days_ahead is not None:
to_date = today + timedelta(days=self.to_days_ahead)
qs = qs.overlapping(from_date, to_date)
if self.limit:
qs = qs[:self.limit]
return qs
7 changes: 7 additions & 0 deletions icekit_events/plugins/event_content_listing/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.apps import AppConfig


class AppConfig(AppConfig):
name = '.'.join(__name__.split('.')[:-1])
label = "ik_event_listing"
verbose_name = "Event Content Listing"
17 changes: 17 additions & 0 deletions icekit_events/plugins/event_content_listing/content_plugins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""
Definition of the plugin.
"""
from django.utils.translation import ugettext_lazy as _

from fluent_contents.extensions import ContentPlugin, plugin_pool

from . import forms, models


@plugin_pool.register
class EventContentListingPlugin(ContentPlugin):
model = models.EventContentListingItem
category = _('Assets')
render_template = 'icekit_events/plugins/event_content_listing/default.html'
form = forms.EventContentListingAdminForm
cache_output = False
25 changes: 25 additions & 0 deletions icekit_events/plugins/event_content_listing/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from icekit.plugins.content_listing.forms import ContentListingAdminForm

from icekit_events.models import EventBase

from .models import EventContentListingItem


class EventContentListingAdminForm(ContentListingAdminForm):
# TODO Improve admin experience:
# - horizontal filter for `limit_to_types` choice
# - verbose_name for Content Type
# - default (required) value for No Items Message.

class Meta:
model = EventContentListingItem
fields = '__all__'

def filter_content_types(self, content_type_qs):
""" Filter the content types selectable to only event subclasses """
valid_ct_ids = []
for ct in content_type_qs:
model = ct.model_class()
if model and issubclass(model, EventBase):
valid_ct_ids.append(ct.id)
return content_type_qs.filter(pk__in=valid_ct_ids)
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('fluent_contents', '0001_initial'),
('contenttypes', '0002_remove_content_type_name'),
]

operations = [
migrations.CreateModel(
name='EventContentListingItem',
fields=[
('contentitem_ptr', models.OneToOneField(serialize=False, primary_key=True, to='fluent_contents.ContentItem', parent_link=True, auto_created=True)),
('limit', models.IntegerField(null=True, help_text=b'How many items to show? No limit is applied if this field is not set', blank=True)),
('content_type', models.ForeignKey(help_text=b'Content type of items to show in a listing', to='contenttypes.ContentType')),
],
options={
'db_table': 'contentitem_ik_event_listing_eventcontentlistingitem',
'abstract': False,
'verbose_name': 'Event Content Listing',
},
bases=('fluent_contents.contentitem',),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('icekit_events', '0016_auto_20161208_0030'),
('ik_event_listing', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='eventcontentlistingitem',
name='from_date',
field=models.DateTimeField(help_text=b'Only show events with occurrences that end after this date and time.', null=True, blank=True),
),
migrations.AddField(
model_name='eventcontentlistingitem',
name='from_days_ago',
field=models.IntegerField(help_text=b'Only show events with occurrences after this number of days into the past. Set this to zero to show only events with future occurrences.', null=True, blank=True),
),
migrations.AddField(
model_name='eventcontentlistingitem',
name='limit_to_types',
field=models.ManyToManyField(help_text=b'Leave empty to show all events.', to='icekit_events.EventType', db_table=b'ik_event_listing_types', blank=True),
),
migrations.AddField(
model_name='eventcontentlistingitem',
name='to_date',
field=models.DateTimeField(help_text=b'Only show events with occurrences that start before this date and time.', null=True, blank=True),
),
migrations.AddField(
model_name='eventcontentlistingitem',
name='to_days_ahead',
field=models.IntegerField(help_text=b'Only show events with occurrences before this number of days into the future. Set this to zero to show only events with past occurrences.', null=True, blank=True),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('ik_event_listing', '0002_auto_20170222_1136'),
]

operations = [
migrations.AddField(
model_name='eventcontentlistingitem',
name='no_items_message',
field=models.CharField(blank=True, help_text=b'Message to show if there are not items in listing.', null=True, max_length=255),
),
]
Empty file.
8 changes: 8 additions & 0 deletions icekit_events/plugins/event_content_listing/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from .abstract_models import AbstractEventContentListingItem


class EventContentListingItem(AbstractEventContentListingItem):
"""
An embedded listing of event content items.
"""
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<li><a href="{{ event.get_absolute_url }}">
{{ event.title|safe }}
</a></li>

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="content-listing">
{% for event in instance.get_items %}
{% include "icekit_events/plugins/event_content_listing/_event.html" %}
{% empty %}
<li>{{ instance.no_items_message|default:"There are no items to show" }}</li>
{% endfor %}
</div>

5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@
include_package_data=True,
install_requires=[
'Django<1.9',
'django-dynamic-fixture',
# TODO Specific version of django-dynamic-fixture is necessary to avoid
# AttributeError: can't set attribute` failures on polymorphic models.
# See https://github.com/paulocheque/django-dynamic-fixture/pull/59
'django-dynamic-fixture==1.9.0+0.caeb3427399edd3b0d589516993c7da55e0de560.ixc',
'django-icekit',
'django-polymorphic',
'django-polymorphic-tree',
Expand Down

0 comments on commit d51df53

Please sign in to comment.