Changeset - 9e39d7eadced
[Not reviewed]
0 37 0
Ben Sturmfels (bsturmfels) - 8 months ago 2023-09-07 13:15:48
ben@sturm.com.au
Apply `pyupgrade --py36-plus` (but skip f-strings as we're on Python 3.5)
37 files changed with 56 insertions and 107 deletions:
0 comments (0 inline, 0 general)
www/conservancy/__init__.py
Show inline comments
 
from builtins import object
 
import hashlib
 

	
 
from django.conf import settings
 

	
 
# This is backwards compatibilty support for a custom function we wrote
 
# ourselves that is no longer necessary in modern Django.
 
from django.shortcuts import render as render_template_with_context
 

	
 

	
 
class ParameterValidator(object):
 
class ParameterValidator:
 
    def __init__(self, given_hash_or_params, params_hash_key=None):
 
        if params_hash_key is None:
 
            self.given_hash = given_hash_or_params
 
        else:
 
            self.given_hash = given_hash_or_params.get(params_hash_key)
 
        seed = getattr(settings, 'CONSERVANCY_SECRET_KEY', '').encode('utf-8')
www/conservancy/apps/assignment/apps.py
Show inline comments
 
from __future__ import unicode_literals
 

	
 
from django.apps import AppConfig
 

	
 

	
 
class AssignmentConfig(AppConfig):
 
    name = 'assignment'
www/conservancy/apps/assignment/migrations/0001_initial.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.10.7 on 2021-11-30 00:24
 
from __future__ import unicode_literals
 

	
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
 

	
www/conservancy/apps/assignment/migrations/0002_auto_20211206_2237.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.11.29 on 2021-12-06 22:37
 
from __future__ import unicode_literals
 

	
 
import datetime
 
from django.db import migrations, models
 
import django_countries.fields
 

	
 

	
www/conservancy/apps/assignment/migrations/0003_auto_20211206_2249.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.11.29 on 2021-12-06 22:49
 
from __future__ import unicode_literals
 

	
 
from django.db import migrations, models
 
import uuid
 

	
 

	
 
class Migration(migrations.Migration):
www/conservancy/apps/assignment/migrations/0004_auto_20230127_0602.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.11.29 on 2023-01-27 06:02
 
from __future__ import unicode_literals
 

	
 
import conservancy.apps.assignment.models
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
www/conservancy/apps/assignment/models.py
Show inline comments
 
from __future__ import unicode_literals
 

	
 
import uuid
 

	
 
from django.core.validators import URLValidator, ValidationError
 
from django.db import models
 
from django_countries.fields import CountryField
 

	
www/conservancy/apps/assignment/terms.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
import textwrap
 

	
 
TERMS = textwrap.dedent("""\
 
    Copyright Assignment Agreement
 

	
 
    By checking the box below and submitting this form, you (``Assignor'') enter
www/conservancy/apps/blog/models.py
Show inline comments
 
from builtins import object
 
from django.db import models
 
from django.conf import settings
 
from conservancy import bsoup
 
from conservancy.apps.staff.models import Person
 
from datetime import datetime, timedelta
 

	
 
class EntryTag(models.Model):
 
    """Tagging for blog entries"""
 

	
 
    label = models.CharField(max_length=100)
 
    slug = models.SlugField()
 

	
 
    class Meta(object):
 
    class Meta:
 
        db_table = 'techblog_entrytag' # legacy
 

	
 
    def __str__(self):
 
        return self.label
 

	
 
    def get_absolute_url(self):
 
        return u"/blog/?tag=%s" % self.slug
 
        return "/blog/?tag=%s" % self.slug
 

	
 
class Entry(models.Model, bsoup.SoupModelMixin):
 
    """Blog entry"""
 

	
 
    headline = models.CharField(max_length=200)
 
    slug = models.SlugField(unique_for_date='pub_date')
...
 
@@ -31,37 +30,37 @@ class Entry(models.Model, bsoup.SoupModelMixin):
 
    author = models.ForeignKey(Person)
 
    tags = models.ManyToManyField(EntryTag, blank=True)
 

	
 
    date_created = models.DateTimeField(auto_now_add=True)
 
    date_last_modified = models.DateTimeField(auto_now=True)
 

	
 
    class Meta(object):
 
    class Meta:
 
        db_table = 'techblog_entries' # legacy
 
        verbose_name_plural = 'entries'
 
        ordering = ('-pub_date',)
 
        get_latest_by = 'pub_date'
 

	
 
    SOUP_ATTRS = ['body']
 

	
 
    def __str__(self):
 
        return self.headline
 

	
 
    def get_absolute_url(self):
 
        return (u"/blog/%s/%s/"
 
        return ("/blog/%s/%s/"
 
                % (self.pub_date.strftime("%Y/%b/%d").lower(),
 
                   self.slug))
 

	
 
    def is_recent(self):
 
        return self.pub_date > (datetime.now() - timedelta(days=30))
 
        # question: does datetime.now() do a syscall each time is it called?
 

	
 
    # Ping google blogs and technorati.  Taken from
 
    # http://blog.foozia.com/blog/2007/apr/21/ping-technorati-your-django-blog-using-xml-rpc/
 
    def save(self):
 
        if settings.CONSERVANCY_DEVEL or True: # "or True" means it is disabled always
 
            super(Entry, self).save()
 
            super().save()
 
            return
 

	
 
        blog_name = 'Software Freedom Conservancy Blog'
 
        blog_url =  'http://www.sfconservancy.org/blog/'
 
        post_url = ('http://www.sfconservancy.org'
 
                    + self.get_absolute_url())
...
 
@@ -74,7 +73,7 @@ class Entry(models.Model, bsoup.SoupModelMixin):
 

	
 
        # Ping Google Blog Search
 
        j = xmlrpc.client.Server('http://blogsearch.google.com/ping/RPC2')
 
        reply = j.weblogUpdates.ping(blog_name, blog_url, post_url)
 

	
 
        # Call any superclass's method
 
        super(Entry, self).save()
 
        super().save()
www/conservancy/apps/blog/views.py
Show inline comments
...
 
@@ -93,13 +93,13 @@ def query(request):
 
        if 'rss' in d:
 
            base_url = '/feeds/blog/'
 
            d.setlist('rss', []) # remove it
 

	
 
        query_string = d.urlencode()
 

	
 
        return relative_redirect(request, '%s%s%s' % (base_url, '?' if query_string else '', query_string))
 
        return relative_redirect(request, '{}{}{}'.format(base_url, '?' if query_string else '', query_string))
 

	
 
    else:
 
        authors = sorted(Person.objects.filter(currently_employed=True,
 
                                               entry__isnull=False).distinct(),
 
                         key=last_name)
 
        tags = EntryTag.objects.all().order_by('label')
...
 
@@ -110,45 +110,45 @@ def relative_redirect(request, path):
 
    from django.conf import settings
 

	
 
    host = request.get_host()
 
    if settings.FORCE_CANONICAL_HOSTNAME:
 
        host = settings.FORCE_CANONICAL_HOSTNAME
 

	
 
    url = "%s://%s%s" % (request.is_secure() and 'https' or 'http', host, path)
 
    url = "{}://{}{}".format(request.is_secure() and 'https' or 'http', host, path)
 
    return http.HttpResponseRedirect(url)
 

	
 
class BlogYearArchiveView(YearArchiveView):
 
    make_object_list = True
 
    allow_future = True
 
    extra_context = {}
 
    
 
    def get_context_data(self, **kwargs):
 
        context = super(BlogYearArchiveView, self).get_context_data(**kwargs)
 
        context = super().get_context_data(**kwargs)
 
        context.update(self.extra_context)
 
        return context
 

	
 
class BlogMonthArchiveView(MonthArchiveView):
 
    allow_future = True
 
    extra_context = {}
 
    
 
    def get_context_data(self, **kwargs):
 
        context = super(BlogMonthArchiveView, self).get_context_data(**kwargs)
 
        context = super().get_context_data(**kwargs)
 
        context.update(self.extra_context)
 
        return context
 

	
 
class BlogDayArchiveView(DayArchiveView):
 
    allow_future = True
 
    extra_context = {}
 
    
 
    def get_context_data(self, **kwargs):
 
        context = super(BlogDayArchiveView, self).get_context_data(**kwargs)
 
        context = super().get_context_data(**kwargs)
 
        context.update(self.extra_context)
 
        return context
 

	
 
class BlogDateDetailView(DateDetailView):
 
    allow_future = True
 
    extra_context = {}
 
    
 
    def get_context_data(self, **kwargs):
 
        context = super(BlogDateDetailView, self).get_context_data(**kwargs)
 
        context = super().get_context_data(**kwargs)
 
        context.update(self.extra_context)
 
        return context
www/conservancy/apps/contacts/models.py
Show inline comments
 
from builtins import object
 
from django.db import models
 

	
 
class ContactEntry(models.Model):
 
    """Conservancy contact system
 

	
 
    Hopefully this will be deprecated soon"""
 

	
 
    email = models.EmailField() # should make it unique, but we really cannot
 
    subscribe_conservancy = models.BooleanField(default=False)
 

	
 
    class Meta(object):
 
    class Meta:
 
        ordering = ('email',)
 

	
www/conservancy/apps/contacts/views.py
Show inline comments
 
from builtins import object
 
from django.shortcuts import render
 
from django import forms
 
from conservancy.apps.contacts.models import ContactEntry
 
from django.forms import ModelForm
 

	
 
def subscribe(request):
 
    """Mailing list subscription form
 
    """
 

	
 
    class ContactEntryForm(ModelForm):
 
        class Meta(object):
 
        class Meta:
 
            model = ContactEntry
 

	
 
    ContactEntryForm.base_fields['subscribe_conservancy'].label = 'Receive Software Freedom Conservancy updates'
 

	
 
    if request.method == 'POST':
 
        form = ContactEntryForm(request.POST)
www/conservancy/apps/events/models.py
Show inline comments
 
from builtins import object
 
from django.db import models
 
from conservancy.apps.staff.models import Person
 
from conservancy.apps.worldmap.models import EarthLocation
 
from datetime import datetime, timedelta
 

	
 
class EventTag(models.Model):
...
 
@@ -18,19 +17,19 @@ class EventTag(models.Model):
 
        return self.label
 

	
 
class PastEventManager(models.Manager):
 
    """Returns all past events"""
 

	
 
    def get_queryset(self):
 
        return super(PastEventManager, self).get_queryset().filter(date__lt=datetime.today())
 
        return super().get_queryset().filter(date__lt=datetime.today())
 

	
 
class FutureEventManager(models.Manager):
 
    """Returns all future events"""
 

	
 
    def get_queryset(self):
 
        return super(FutureEventManager, self).get_queryset().filter(date__gte=datetime.today())
 
        return super().get_queryset().filter(date__gte=datetime.today())
 

	
 
class Event(models.Model):
 
    """Model for Conservancy staff member events (presentations, etc)"""
 

	
 
    title = models.CharField(max_length=400)
 
    date = models.DateField()
...
 
@@ -44,20 +43,20 @@ class Event(models.Model):
 
                                       help_text="Label will not be displayed")
 
    tags = models.ManyToManyField(EventTag, blank=True)
 

	
 
    date_created = models.DateTimeField(auto_now_add=True)
 
    date_last_modified = models.DateTimeField(auto_now=True)
 

	
 
    class Meta(object):
 
    class Meta:
 
        ordering = ("-date",)
 

	
 
    def __str__(self):
 
        return u"%s (%s)" % (self.title, self.date)
 
        return "{} ({})".format(self.title, self.date)
 

	
 
    def get_absolute_url(self):
 
        return u"/events/%s/%s/" % (self.date.strftime("%Y"), self.slug)
 
        return "/events/{}/{}/".format(self.date.strftime("%Y"), self.slug)
 

	
 
    def day_after(self):
 
        return self.date + timedelta(days=1)
 

	
 
    # for aggregate feed
 
    pub_date = property(lambda self: self.date_created)
...
 
@@ -84,12 +83,12 @@ class EventMedia(models.Model):
 
                             help_text="Remote URL of the resource.  Required if 'local' is not given.")
 
    novel = models.BooleanField(help_text="Is it a new piece of media or another form of an old one?  If it is new it will be included in the event-media RSS feed and shown on the front page for a bit.", default=False)
 

	
 
    date_created = models.DateTimeField(auto_now_add=True)
 
    date_last_modified = models.DateTimeField(auto_now=True)
 

	
 
    class Meta(object):
 
    class Meta:
 
        verbose_name_plural = 'event media'
 

	
 
    def __str__(self):
 
        return u"%s media: %s" % (self.event, self.format)
 
        return "{} media: {}".format(self.event, self.format)
 

	
www/conservancy/apps/events/view_helpers.py
Show inline comments
...
 
@@ -11,10 +11,10 @@ def organize_media_by_event(eventmedia_queryset):
 

	
 
    media_by_event = {}
 
    for media in eventmedia_queryset:
 
        media_by_event.setdefault(media.event.id, []).append(media)
 
    mbe = [{'event': x[0].event,
 
            'date': max(y.date_created for y in x),
 
            'media_list': ', '.join(set(y.get_format_display() for y in x))}
 
            'media_list': ', '.join({y.get_format_display() for y in x})}
 
           for x in list(media_by_event.values())]
 
    mbe.sort(key=(lambda x: x['date']), reverse=True) # sort by date
 
    return mbe
www/conservancy/apps/fossy/migrations/0001_initial.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.11.29 on 2023-01-27 06:19
 
from __future__ import unicode_literals
 

	
 
from django.db import migrations, models
 
import uuid
 

	
 

	
 
class Migration(migrations.Migration):
www/conservancy/apps/fossy/migrations/0002_auto_20230130_1841.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.11.29 on 2023-01-30 18:41
 
from __future__ import unicode_literals
 

	
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
 

	
www/conservancy/apps/fundgoal/migrations/0001_initial.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.10.7 on 2018-11-18 12:09
 
from __future__ import unicode_literals
 

	
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
 

	
www/conservancy/apps/fundgoal/migrations/0002_goalprovider.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.10.7 on 2018-11-18 12:11
 
from __future__ import unicode_literals
 

	
 
from django.db import migrations, models
 
import django.db.models.deletion
 

	
 

	
 
class Migration(migrations.Migration):
www/conservancy/apps/fundgoal/migrations/0003_fundraisinggoal_fundraiser_endtime.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.10.7 on 2021-11-19 01:45
 
from __future__ import unicode_literals
 

	
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
 

	
www/conservancy/apps/fundgoal/models.py
Show inline comments
 
from __future__ import division
 
from builtins import object
 
import random
 

	
 
from django.db import models
 

	
 

	
 
class FundraisingGoal(models.Model):
...
 
@@ -18,13 +16,13 @@ class FundraisingGoal(models.Model):
 
    def __str__(self):
 
        return self.fundraiser_code_name
 

	
 
    def percentage_there(self):
 
        return self.fundraiser_so_far_amount / self.fundraiser_goal_amount * 100
 

	
 
    class Meta(object):
 
    class Meta:
 
        ordering = ('fundraiser_code_name',)
 

	
 
    def providers(self):
 
        return GoalProvider.objects.filter(fundraising_goal=self)
 

	
 
    def random_providers(self, k=None):
www/conservancy/apps/news/models.py
Show inline comments
 
from builtins import object
 
from django.db import models
 
from django.conf import settings
 
from conservancy import bsoup
 
from conservancy.apps.staff.models import Person
 
from conservancy.apps.events.models import Event
 
from django.contrib.sites.models import Site
...
 
@@ -19,23 +18,23 @@ class PressRelease(models.Model, bsoup.SoupModelMixin):
 
                            blank=True)
 
    pub_date = models.DateTimeField("date [to be] published")
 
    sites = models.ManyToManyField(Site)
 

	
 
    date_last_modified = models.DateTimeField(auto_now=True)
 

	
 
    class Meta(object):
 
    class Meta:
 
        ordering = ("-pub_date",)
 
        get_latest_by = "pub_date"
 

	
 
    SOUP_ATTRS = ['summary', 'body']
 

	
 
    def __str__(self):
 
        return self.headline
 

	
 
    def get_absolute_url(self):
 
        return u"/news/%s/%s/" % (self.pub_date.strftime("%Y/%b/%d").lower(),
 
        return "/news/{}/{}/".format(self.pub_date.strftime("%Y/%b/%d").lower(),
 
                                  self.slug)
 

	
 
    def is_recent(self):
 
        return self.pub_date > (datetime.now() - timedelta(days=5))
 
        # question: does datetime.now() do a syscall each time is it called?
 

	
...
 
@@ -43,13 +42,13 @@ class PressRelease(models.Model, bsoup.SoupModelMixin):
 
        # This function is deprecated.  Use the date_within template
 
        # filter instead (example in conservancy/templates/frontpage.html)
 
        return self.pub_date > (datetime.now() - timedelta(days=30))
 

	
 
    def save(self):
 
        if settings.CONSERVANCY_DEVEL or True:
 
            super(PressRelease, self).save()
 
            super().save()
 
            return
 

	
 
        blog_name = 'Software Freedom Conservancy News'
 
        blog_url = 'https://www.sfconservancy.org/news/'
 
        post_url = ('https://www.sfconservancy.org'
 
                    + self.get_absolute_url())
...
 
@@ -62,13 +61,13 @@ class PressRelease(models.Model, bsoup.SoupModelMixin):
 

	
 
        # Ping Google Blog Search
 
        j = xmlrpc.client.Server('http://blogsearch.google.com/ping/RPC2')
 
        reply = j.weblogUpdates.ping(blog_name, blog_url, post_url)
 

	
 
        # Call any superclass's method
 
        super(PressRelease, self).save()
 
        super().save()
 

	
 
class ExternalArticleTag(models.Model):
 
    """A way to tag external articles"""
 

	
 
    label = models.CharField(max_length=100)
 

	
...
 
@@ -76,13 +75,13 @@ class ExternalArticleTag(models.Model):
 

	
 
    def __str__(self):
 
        return self.label
 

	
 
class PublicExternalArticleManager(models.Manager):
 
    def get_queryset(self):
 
        return super(PublicExternalArticleManager, self).get_queryset().filter(visible=True)
 
        return super().get_queryset().filter(visible=True)
 

	
 
class ExternalArticle(models.Model):
 
    """A system for displaying Conservancy news mentions on the site.
 

	
 
    (Currently unused)
 
    """
...
 
@@ -100,16 +99,16 @@ class ExternalArticle(models.Model):
 
    people = models.ManyToManyField(Person, blank=True)
 
    event = models.ForeignKey(Event, null=True, blank=True)
 
    press_release = models.ForeignKey(PressRelease, null=True, blank=True)
 

	
 
    date_created = models.DateField(auto_now_add=True)
 

	
 
    class Meta(object):
 
    class Meta:
 
        ordering = ("-date_created",)
 
        get_latest_by = "date_created"
 

	
 
    def __str__(self):
 
        return u"%s (%s)" % (self.title, self.publication)
 
        return "{} ({})".format(self.title, self.publication)
 

	
 
    objects = models.Manager()
 
    public = PublicExternalArticleManager()
 

	
www/conservancy/apps/news/templatetags/fill_url.py
Show inline comments
 
from builtins import zip
 
import urllib.parse
 

	
 
from django import template
 

	
 
register = template.Library()
 

	
www/conservancy/apps/news/views.py
Show inline comments
...
 
@@ -11,13 +11,13 @@ from datetime import datetime
 
from django.http import HttpResponse
 

	
 

	
 
class NewsListView(ListView):
 
    extra_context = {}
 
    def get_context_data(self, **kwargs):
 
        context = super(NewsListView, self).get_context_data(**kwargs)
 
        context = super().get_context_data(**kwargs)
 
        # context['key'] = 'value'
 
        context.update(self.extra_context)
 
        return context
 
                                    
 
def listing(request, *args, **kwargs):
 
    news_queryset = PressRelease.objects.all()
www/conservancy/apps/staff/migrations/0001_initial.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.10.7 on 2021-11-28 21:12
 
from __future__ import unicode_literals
 

	
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
 

	
www/conservancy/apps/staff/migrations/0002_auto_20211128_2112.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.10.7 on 2021-11-28 21:12
 
from __future__ import unicode_literals
 

	
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
 

	
www/conservancy/apps/staff/models.py
Show inline comments
 
from builtins import object
 
from django.db import models
 

	
 
class Person(models.Model):
 
    """Staff members
 

	
 
    Referenced from other models (blog, events, etc)
...
 
@@ -17,14 +16,14 @@ class Person(models.Model):
 
#    gpg_fingerprint = models.CharField(max_length=100, blank=True)
 
    currently_employed = models.BooleanField(default=True)
 

	
 
    date_created = models.DateTimeField(auto_now_add=True)
 
    date_last_modified = models.DateTimeField(auto_now=True)
 

	
 
    class Meta(object):
 
    class Meta:
 
        verbose_name_plural = 'people'
 

	
 
    def __str__(self):
 
        return self.username
 

	
 
    def biography_url(self):
 
        return u"/about/#%s" % self.username
 
        return "/about/#%s" % self.username
www/conservancy/apps/summit_registration/models.py
Show inline comments
 
from builtins import object
 
from django.db import models
 

	
 
class SummitRegistration(models.Model):
 
    """Form fields for summit registrants"""
 

	
 
    name = models.CharField(max_length=300)
...
 
@@ -9,9 +8,9 @@ class SummitRegistration(models.Model):
 
    address = models.TextField(blank=True)
 
    email = models.EmailField(blank=True)
 
    phone = models.CharField(max_length=100, blank=True)
 
    date_created = models.DateField(auto_now_add=True)
 
    cle_credit = models.BooleanField(default=True)
 

	
 
    class Meta(object):
 
    class Meta:
 
        ordering = ('name',)
 

	
www/conservancy/apps/summit_registration/views.py
Show inline comments
 
from builtins import object
 
from django.shortcuts import render
 
from django import forms
 
from conervancy.apps.summit_registration.models import SummitRegistration
 

	
 
def register(request):
 
    """Summit registration form view
 
    """
 

	
 
    class SummitForm(ModelForm):
 
        class Meta(object):
 
        class Meta:
 
            model = SummitRegistration
 

	
 
    SummitForm.base_fields['email'].label = 'Email address'
 
    SummitForm.base_fields['phone'].label = 'Phone number'
 
    SummitForm.base_fields['address'].label = 'Mailing address'
 
    SummitForm.base_fields['cle_credit'].label = 'Attending for CLE credit?'
www/conservancy/apps/supporters/models.py
Show inline comments
 
from builtins import object
 
from django.db import models
 

	
 
class Supporter(models.Model):
 
    """Conservancy Supporter listing"""
 

	
 
    display_name = models.CharField(max_length=200, blank=False)
...
 
@@ -10,8 +9,8 @@ class Supporter(models.Model):
 

	
 
    def test(self):
 
        return "TESTING"
 
    def __str__(self):
 
        return self.display_name
 

	
 
    class Meta(object):
 
    class Meta:
 
        ordering = ('ledger_entity_id',)
www/conservancy/apps/worldmap/models.py
Show inline comments
 
from builtins import object
 
from django.db import models
 

	
 
class EarthLocation(models.Model):
 
    """Represents latitude and longitude, with a label"""
 

	
 
    label = models.CharField(max_length=300, unique=True)
 
    latitude = models.DecimalField(max_digits=9, decimal_places=6)
 
    longitude = models.DecimalField(max_digits=9, decimal_places=6)
 

	
 
    date_created = models.DateTimeField(auto_now_add=True)
 
    date_last_modified = models.DateTimeField(auto_now=True)
 

	
 
    class Meta(object):
 
    class Meta:
 
        unique_together = (("latitude", "longitude"),)
 

	
 
    def __str__(self):
 
        return self.label
 

	
 
    def google_maps_link(self):
www/conservancy/bsoup.py
Show inline comments
 
# -*- encoding: utf-8 -*-
 

	
 
from builtins import filter
 
from builtins import object
 
import io
 
import itertools
 
import re
 

	
 
import bs4
 
import bs4.element
...
 
@@ -24,13 +20,13 @@ class BeautifulSoup(bs4.BeautifulSoup):
 

	
 
    def __init__(self, src, parser='html5lib'):
 
        # WARNING!  It seems like it would be ideal to use the 'lxml' parser
 
        # for speed, but that doesn't work in our web application.  On
 
        # Debian stretch, at least, using lxml causes the web server WSGI
 
        # application to go into an infinite loop.
 
        super(BeautifulSoup, self).__init__(src, parser)
 
        super().__init__(src, parser)
 

	
 
    def _body_text(self, root):
 
        # "Body text" is all the strings under the root element, in order,
 
        # except:
 
        # * strings inside NON_BODY_TEXT_TAGS
 
        # * strings inside containers of NON_BODY_TEXT_TAGS.  A container is
...
 
@@ -44,14 +40,13 @@ class BeautifulSoup(bs4.BeautifulSoup):
 
            child_type = type(child)
 
            if issubclass(child_type, bs4.element.Tag):
 
                if child.name in self.NON_BODY_TEXT_TAGS:
 
                    if not started:
 
                        break
 
                else:
 
                    for s in self._body_text(child):
 
                        yield s
 
                    yield from self._body_text(child)
 
            # It's not worth it to use issubclass here, because elements that
 
            # don't have body text like Comments and CDATA are subclasses of
 
            # NavigableString.
 
            elif child_type is bs4.element.NavigableString:
 
                if started:
 
                    yield child
...
 
@@ -104,13 +99,13 @@ class BeautifulSoup(bs4.BeautifulSoup):
 

	
 
    def iter_videos(self):
 
        """Return an iterator of all video source elements in this document."""
 
        return self.find_all(self.is_video_source, src=True)
 

	
 

	
 
class SoupModelMixin(object):
 
class SoupModelMixin:
 
    """Mixin for models to parse HTML with BeautifulSoup.
 

	
 
    Classes that use this mixin must define `SOUP_ATTRS`, a list of strings
 
    that name attributes with HTML in them.  After that, all the public methods
 
    are usable.
 
    """
...
 
@@ -150,13 +145,13 @@ class SoupModelMixin(object):
 
            return itertools.islice(seq, *slice_args)
 
        else:
 
            return seq
 

	
 
    def get_description(self):
 
        """Return a string with a brief excerpt of body text from the HTML."""
 
        return u''.join(self._get_soup().some_body_text())
 
        return ''.join(self._get_soup().some_body_text())
 

	
 
    def get_image_urls(self, *slice_args):
 
        """Return an iterator of source URL strings of all images in the HTML.
 

	
 
        Images include <img> sources and <video> poster attributes.
 
        """
www/conservancy/feeds.py
Show inline comments
...
 
@@ -50,24 +50,24 @@ class PressReleaseFeed(Feed):
 

	
 
    def item_pubdate(self, item):
 
        return item.pub_date
 

	
 
class OmnibusFeedType(Rss201rev2Feed):
 
    def root_attributes(self):
 
        attrs = super(OmnibusFeedType, self).root_attributes()
 
        attrs = super().root_attributes()
 
        attrs['xmlns:itunes'] = 'http://www.itunes.com/dtds/podcast-1.0.dtd'
 
        attrs['xmlns:atom'] = 'http://www.w3.org/2005/Atom'
 
        attrs['xmlns:media'] = 'http://search.yahoo.com/mrss/'
 
        attrs['xmlns:dc'] = "http://purl.org/dc/elements/1.1/"
 
        return attrs
 

	
 
    def add_root_elements(self, handler):
 
        super(OmnibusFeedType, self).add_root_elements(handler)
 
        super().add_root_elements(handler)
 

	
 
    def add_item_elements(self, handler, item):
 
        super(OmnibusFeedType, self).add_item_elements(handler, item)
 
        super().add_item_elements(handler, item)
 
        # Block things that don't have an enclosure from iTunes in
 
        # case someone uploads this feed there.
 
        handler.addQuickElement("itunes:block", 'Yes')
 

	
 
class OmnibusFeed(ConservancyFeedBase):
 
    get_absolute_url = '/feeds/omnibus/'
...
 
@@ -144,13 +144,13 @@ class OmnibusFeed(ConservancyFeedBase):
 
        a  = [ ii for ii in itertools.chain(blogs, news)]
 
        a.sort(key=operator.attrgetter('pub_date'), reverse=True)
 
        return a
 

	
 

	
 
    def item_extra_kwargs(self, item):
 
        return super(OmnibusFeed, self).item_extra_kwargs(item)
 
        return super().item_extra_kwargs(item)
 

	
 
class BlogFeed(ConservancyFeedBase):
 
    link = "/blog/"
 
    get_absolute_url = '/feeds/blog/'
 

	
 
    def get_object(self, request):
...
 
@@ -231,13 +231,13 @@ class BlogFeed(ConservancyFeedBase):
 
    def items(self, obj):
 
        GET = obj.GET
 

	
 
        def OR_filter(field_name, subfield_name, objs):
 
            from django.db.models import Q
 
            return reduce(lambda x, y: x | y,
 
                          [Q(**{'%s__%s' % (field_name, subfield_name): x})
 
                          [Q(**{'{}__{}'.format(field_name, subfield_name): x})
 
                           for x in objs])
 

	
 
        queryset = BlogEntry.objects.filter(pub_date__lte=datetime.now())
 

	
 
        if 'author' in GET:
 
            authors = GET.getlist('author')
www/conservancy/local_context_processors.py
Show inline comments
 
from __future__ import unicode_literals
 

	
 
from datetime import datetime as DateTime
 

	
 
import conservancy.settings
 
from conservancy.apps.fundgoal.models import FundraisingGoal as FundraisingGoal
 

	
 
SITE_FUNDGOAL = 'cy2022-end-year-match'
...
 
@@ -18,12 +16,12 @@ def sitefundraiser(request):
 
    return {
 
        'datetime_now': DateTime.now(),
 
        'sitefundgoal': fundgoal_lookup(SITE_FUNDGOAL),
 
    }
 

	
 
if conservancy.settings.FORCE_CANONICAL_HOSTNAME:
 
    _HOST_URL_VAR = {'host_url': u'https://' + conservancy.settings.FORCE_CANONICAL_HOSTNAME}
 
    _HOST_URL_VAR = {'host_url': 'https://' + conservancy.settings.FORCE_CANONICAL_HOSTNAME}
 
    def host_url(request):
 
        return _HOST_URL_VAR
 
else:
 
    def host_url(request):
 
        return {'host_url': request.build_absolute_uri(u'/').rstrip(u'/')}
 
        return {'host_url': request.build_absolute_uri('/').rstrip('/')}
www/conservancy/middleware.py
Show inline comments
 
from builtins import object
 
from django import http
 
from django.conf import settings
 
from django.utils.cache import patch_response_headers
 

	
 
class ForceCanonicalHostnameMiddleware(object):
 
class ForceCanonicalHostnameMiddleware:
 

	
 
    def process_request(self, request):
 
        """Modified common middleware for Conservancy site
 

	
 
        * Performs redirects to strip trailing "index.html"
 
        * performs redirects based on APPEND_SLASH
...
 
@@ -25,13 +24,13 @@ class ForceCanonicalHostnameMiddleware(object):
 
        new_url = old_url[:]
 
        # Append a slash if append_slash is set and the URL doesn't have a
 
        # trailing slash or a file extension.
 
        if settings.APPEND_SLASH and (old_url[1][-1] != '/') and ('.' not in old_url[1].split('/')[-1]):
 
            new_url[1] = new_url[1] + '/'
 
            if settings.DEBUG and request.method == 'POST':
 
                raise(RuntimeError, "You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to %s%s (note the trailing slash), or set APPEND_SLASH=False in your Django settings." % (new_url[0], new_url[1]))
 
                raise(RuntimeError, "You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to {}{} (note the trailing slash), or set APPEND_SLASH=False in your Django settings.".format(new_url[0], new_url[1]))
 
        # Strip trailing index.html
 
        if new_url[1].endswith('/index.html'):
 
            new_url[1] = new_url[1][:new_url[1].rfind('index.html')]
 
        # Consult redirect table (if exists)
 
        if hasattr(settings, "REDIRECT_TABLE"):
 
            if new_url[1] in settings.REDIRECT_TABLE:
...
 
@@ -39,13 +38,13 @@ class ForceCanonicalHostnameMiddleware(object):
 
        if new_url != old_url:
 
            # Force canonical hostname
 
            if settings.FORCE_CANONICAL_HOSTNAME:
 
                new_url[0] = settings.FORCE_CANONICAL_HOSTNAME
 
            # Redirect
 
            if new_url[0]:
 
                newurl = "%s://%s%s" % (request.is_secure() and 'https' or 'http', new_url[0], new_url[1])
 
                newurl = "{}://{}{}".format(request.is_secure() and 'https' or 'http', new_url[0], new_url[1])
 
            else:
 
                newurl = new_url[1]
 
            if request.GET:
 
                newurl += '?' + request.GET.urlencode()
 
            return http.HttpResponseRedirect(newurl)
 

	
www/conservancy/settings.py
Show inline comments
...
 
@@ -23,13 +23,13 @@ from djangocommonsettings import *
 

	
 
SITE_ID = 2
 
ROOT_URLCONF = 'conservancy.urls'
 

	
 
FORCE_CANONICAL_HOSTNAME = False if DEBUG else 'sfconservancy.org'
 

	
 
ALLOWED_HOSTS = [ 'www.sfconservancy.org', 'aspen.sfconservancy.org', 'sfconservancy.org',  u'104.130.70.210' ]
 
ALLOWED_HOSTS = [ 'www.sfconservancy.org', 'aspen.sfconservancy.org', 'sfconservancy.org',  '104.130.70.210' ]
 
if DEBUG:
 
    ALLOWED_HOSTS.append('localhost')
 

	
 
REDIRECT_TABLE = {
 
    'www.sf-conservancy.org': 'sfconservancy.org',
 
}
www/conservancy/static/views.py
Show inline comments
 
from builtins import str
 
import mimetypes
 
import os.path
 
from django.http import HttpResponse
 
from django.template.response import TemplateResponse
 

	
 
from conservancy.local_context_processors import fundgoal_lookup
...
 
@@ -27,15 +26,15 @@ def handler404(request):
 
    return handler(request, 404)
 

	
 
def handler500(request):
 
    return handler(request, 500)
 

	
 
def index(request, *args, **kwargs):
 
    path = request.path.lstrip(u'/')
 
    if path.endswith(u'/'):
 
        path += u'index.html'
 
    path = request.path.lstrip('/')
 
    if path.endswith('/'):
 
        path += 'index.html'
 
    fullpath = os.path.join(STATIC_ROOT, path)
 
    try:
 
        # Junk URLs in production (Python 3.5) are causing UnicodeEncodeErrors
 
        # here. Can't reproduce in development in Python 3.9 - only Python 2.7.
 
        if not os.path.exists(fullpath):
 
            return handler404(request)
www/modpythoncustom.py
Show inline comments
 
from builtins import str
 
from mod_python import apache
 

	
 
# 404 should do NOTHING so apache can handle it.  This view is referenced
 
# in sflc.urls
 
def view404(request):
 
    from django.http import HttpResponseNotFound
0 comments (0 inline, 0 general)