This item will automatically be included in the "Statements and Opinions"\ + list of any linked Commissioners.
', + heading='ITEM HELP', + ), + MultiFieldPanel( + [ + FieldPanel('link_html'), + FieldPanel('link_pdf'), + FieldPanel('link_video'), + StreamFieldPanel('related_document'), + ], + heading='Content' + ), + FieldPanel('display_date'), + FieldPanel('category'), + StreamFieldPanel('commissioners', help_text='Not required, but choose as many as needed.'), + ] + + @property + def slug_category(self): + cat_slug = '' + cat_slug = self.category.split('/')[0] + return cat_slug + + @property + def slug_subject(self): + subj_slug = '' + subj_slug = self.category.split('/')[1] + return subj_slug + + @property + def pretty_category(self): + parent_category = '' + parent_category = self.category.split('/')[0] + + pretty_cat = str(constants.commissioner_item_categories[parent_category]) + return pretty_cat + + @property + def pretty_subject(self): + pretty_subj = str(constants.commissioner_item_categories[self.category]) + # If there's no slash in the category, we're dealing with a category and not a subject + # so return nothing + # + # The 'secondary' category / taxonomy label starts with two special characters + # so they display correctly in the admin pull-downs. + # We're going to pull them off for the pretty label + if len(self.category.split('/')) == 1: + pretty_subj = '' + elif pretty_subj.find('↳ ') == 0: + pretty_subj = pretty_subj[2:] + + return pretty_subj + + @property + def link_doc(self): + # Check whether the StreamValue has a related document + rel_doc_url = False + for block in self.related_document: + rel_doc_url = block.value.url + + return rel_doc_url + + @property + def links_count(self): + count = 0 + count = count + 1 if self.link_doc else count + count = count + 1 if self.link_html else count + count = count + 1 if self.link_pdf else count + count = count + 1 if self.link_video else count + return count + + @property + def links_string(self): + links = [] + + if self.link_doc: + links.append( + '\ + PDF'.format(self.link_doc) + ) + if self.link_pdf: + links.append( + '\ + PDF'.format(self.link_pdf) + ) + if self.link_html: + links.append( + '\ + HTML'.format(self.link_html) + ) + if self.link_video: + links.append( + '\ + VIDEO'.format(self.link_video) + ) + + return ' | '.join(links) + + class CollectionPage(Page): body = stream_factory(null=True, blank=True) sidebar_title = models.CharField(max_length=255, null=True, blank=True) diff --git a/fec/home/templates/home/commissioner_items_feed.html b/fec/home/templates/home/commissioner_items_feed.html new file mode 100644 index 0000000000..c459fd29df --- /dev/null +++ b/fec/home/templates/home/commissioner_items_feed.html @@ -0,0 +1,137 @@ +{# USAGE: Template for the single commissioner pages, #} +{# /about/leadership-and-structure/[commissioner-name-slug]/ #} + +{% extends "home/feed_base.html" %} +{% load wagtailcore_tags %} +{% load staticfiles %} +{% load filters %} + + +{% block intro %} +Search or browse the statements and opinions made by Commissioner {{ self.commissioner_name }}.
+{% endblock %} + +{% block filters %} + +{% endblock %} + +{% block feed %} + {% if self.items %} + {% for item in self.items %} + {% include 'partials/commissioner-item.html' with update=update show_tag=True %} + {% endfor %} +While all press releases, weekly digests and tips for treasurers are searchable, FEC Record articles published before 2005 exist only in PDF format and are not included in these search results. Please try another search or visit our archive of Record articles from 1975-2004.
-+
diff --git a/fec/home/views.py b/fec/home/views.py index 95dfe1bd00..74d82b9ba4 100644 --- a/fec/home/views.py +++ b/fec/home/views.py @@ -10,7 +10,7 @@ from wagtail.documents.models import Document from fec.forms import ContactRAD # form_categories -from home.models import (CommissionerPage, DigestPage, MeetingPage, +from home.models import (CommissionerItem, CommissionerPage, DigestPage, MeetingPage, PressReleasePage, RecordPage, TipsForTreasurersPage) @@ -95,6 +95,52 @@ def get_tips(year=None, search=None): return tips +def get_commissioner(slug=None): + """ + Returns either a full or filtered QuerySet of every CommissionerPage object, the commssioners themselves + """ + commissioners = CommissionerPage.objects.live() + if slug: + commissioners = commissioners.filter(slug=slug).first() + + return commissioners + + +def get_commissioner_items(commissioner_slug=None, category=None, subject=None, year=None, request=None): + items = CommissionerItem.objects.live().order_by('-display_date') # live objects, most recent first + + if category: + items = items.filter(category__contains=category) + + if subject and category: + categorySubjectCombo = category + "/" + subject + items = items.filter(category__contains=categorySubjectCombo) + + if year: + year = int(year) + items = items.filter(display_date__gte=datetime(year, 1, 1)).filter( + display_date__lte=datetime(year, 12, 31) + ) + + # Finally, remove any without the requested slug in its commissioners list + if commissioner_slug: # If we're filtering to one commissioner, + for item in items: # For each commissioner item, + # for comm_item in item.commissioners: # Check its commissioners + if (commissioner_slug not in str(item.commissioners)): + items = items.not_page(item) + + page_num = request.GET.get("page", 1) + paginator = Paginator(items, 20) + try: + items = paginator.page(page_num) + except PageNotAnInteger: + items = paginator.page(1) + except EmptyPage: + items = paginator.page(paginator.num_pages) + + return items + + def updates(request): digests = "" records = "" @@ -149,6 +195,7 @@ def updates(request): tips = tips.filter(date__gte=datetime(year, 1, 1)).filter( date__lte=datetime(year, 12, 31) ) + # Not going to filter commissioner items by year here if search: press_releases = press_releases.search(search) @@ -199,6 +246,9 @@ def calendar(request): def commissioners(request): + """ + For the list of all commissioners + """ chair_commissioner = ( CommissionerPage.objects.filter(commissioner_title__contains="Chair") .exclude(commissioner_title__contains="Vice") @@ -234,6 +284,59 @@ def commissioners(request): return render(request, "home/commissioners.html", {"self": page_context}) +def commissioner_statements_and_opinions(request, commissioner_slug): + """ + TODO: DOCUMENTATION + """ + # We're only going to look at one requested category, subject, or year + req_category = request.GET.get("category", "") + req_subject = request.GET.get("subject", "") + req_year = request.GET.get("year", "") + + commissioner = get_commissioner(slug=commissioner_slug) + commissioner_name = commissioner.title + + commissioner_items = get_commissioner_items( + commissioner_slug=commissioner_slug, + category=req_category, + subject=req_subject, + year=req_year, + request=request + ) + + page_context = { + "category": req_category, + "subject": req_subject, + "year": req_year, + "title": "Commissioner %s statements and opinions" % (commissioner_name), + "content_section": "about", + "commissioner_slug": commissioner_slug, + "commissioner_name": commissioner_name, + "items": commissioner_items, + "ancestors": [ + {"title": "About the FEC", "url": "/about/"}, + { + "title": "Leadership and structure", + "url": "/about/leadership-and-structure", + }, + { + "title": "All Commissioners", + "url": "/about/leadership-and-structure/commissioners", + }, + { + "title": commissioner_name, + "url": "/about/leadership-and-structure/commissioners/%s/" % (commissioner_slug), + }, + { + "title": "Statements and Opinions", + "url": "/about/leadership-and-structure/commissioners/%s/statements-and-opinions" % (commissioner_slug), + }, + ], + } + + return render(request, "home/commissioner_items_feed.html", {"self": page_context}) + + def contact_rad(request): page_context = { "title": "Submit a question to the Reports Analysis Division (RAD)", diff --git a/requirements.txt b/requirements.txt index 55fbd4725c..66412267b3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,9 +9,10 @@ psycopg2==2.8.5 requests==2.21.0 slacker==0.8.6 whitenoise==2.0.3 -wagtail==2.7.3 +wagtail==2.7.4 Jinja2==2.10.1 django_jinja==2.4.1 +pillow==7.1.0 CacheControl==0.11.5 cachetools==1.0.2 github3.py==0.9.6