diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..de60a5f44 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# Notify @EWDurbin for all opened Issues and Pull Requests +* @EWDurbin @JacobCoffee diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..fa82b4297 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,19 @@ + +#### Description + +- + + +#### Closes + +- + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5bd57ab9c..ed08f4b7f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: sudo dpkg -i pandoc-2.17.1.1-1-amd64.deb - uses: actions/setup-python@v5 with: - python-version: 3.9.16 + python-version-file: '.python-version' - name: Cache Python dependencies uses: actions/cache@v4 env: diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml new file mode 100644 index 000000000..3207b964e --- /dev/null +++ b/.github/workflows/static.yml @@ -0,0 +1,29 @@ +name: Check collectstatic +on: [push, pull_request] +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version-file: '.python-version' + - name: Cache Python dependencies + uses: actions/cache@v4 + env: + cache-name: pythondotorg-cache-pip + with: + path: ~/.cache/pip + key: ${{ runner.os }}-${{ github.job }}-${{ env.cache-name }}-${{ hashFiles('requirements.txt', '*-requirements.txt') }} + restore-keys: | + ${{ runner.os }}-${{ github.job }}-${{ env.cache-name }}- + ${{ runner.os }}-${{ github.job }}- + ${{ runner.os }}- + - name: Install Python dependencies + run: | + pip install -U pip setuptools wheel + pip install -r requirements.txt -r prod-requirements.txt + - name: Run Tests + run: | + DJANGO_SETTINGS_MODULE=pydotorg.settings.static python manage.py collectstatic --noinput diff --git a/.python-version b/.python-version index 9f3d4c178..35f236d6e 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.9.16 +3.12.6 diff --git a/Dockerfile b/Dockerfile index a3c351f5e..c701cd76c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9-bookworm +FROM python:3.12.6-bookworm ENV PYTHONUNBUFFERED=1 ENV PYTHONDONTWRITEBYTECODE=1 diff --git a/Dockerfile.cabotage b/Dockerfile.cabotage index d96e002a7..9bc9d27ad 100644 --- a/Dockerfile.cabotage +++ b/Dockerfile.cabotage @@ -1,4 +1,4 @@ -FROM python:3.9-bullseye +FROM python:3.12.6-bookworm COPY --from=ewdurbin/nginx-static:1.25.x /usr/bin/nginx /usr/bin/nginx ENV PYTHONUNBUFFERED=1 ENV PYTHONDONTWRITEBYTECODE=1 diff --git a/Makefile b/Makefile index dc296feb4..50585463a 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ default: @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null\ | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}'\ | sort\ - | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' + | grep -E -v -e '^[^[:alnum:]]' -e '^$@$$' @echo @exit 1 diff --git a/README.md b/README.md index fc59b7cdf..5bf04cbc6 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ https://github.com/python/cpython/issues/. * Source code: https://github.com/python/pythondotorg * Issue tracker: https://github.com/python/pythondotorg/issues -* Documentation: https://pythondotorg.readthedocs.org/ +* Documentation: https://pythondotorg.readthedocs.io/ * Mailing list: [pydotorg-www](https://mail.python.org/mailman/listinfo/pydotorg-www) * IRC: `#pydotorg` on Freenode * Staging site: https://staging.python.org/ (`main` branch) diff --git a/base-requirements.txt b/base-requirements.txt index a86bf74ae..67736daed 100644 --- a/base-requirements.txt +++ b/base-requirements.txt @@ -5,17 +5,17 @@ django-apptemplates==1.5 django-admin-interface==0.24.2 django-translation-aliases==0.1.0 Django==4.2.16 -docutils==0.12 -Markdown==3.3.4 +docutils==0.21.2 +Markdown==3.7 cmarkgfm==0.6.0 -Pillow==9.4.0 -psycopg2-binary==2.8.6 +Pillow==10.4.0 +psycopg2-binary==2.9.9 python3-openid==3.2.0 python-decouple==3.4 # lxml used by BeautifulSoup. lxml==5.2.2 cssselect==1.1.0 -feedparser==6.0.8 +feedparser==6.0.11 beautifulsoup4==4.11.2 icalendar==4.0.7 chardet==4.0.0 @@ -36,14 +36,14 @@ requests[security]>=2.26.0 django-honeypot==1.0.4 # 1.0.4 is first version that supports Django 4.2 django-markupfield==2.0.1 -django-allauth==0.57.2 # 0.55.0 is first version that supports Django 4.2 +django-allauth==64.2.1 django-waffle==2.2.1 djangorestframework==3.14.0 # 3.14.0 is first version that supports Django 4.1, 4.2 support hasnt been "released" django-filter==2.4.0 django-ordered-model==3.4.3 -django-widget-tweaks==1.4.8 +django-widget-tweaks==1.5.0 django-countries==7.2.1 num2words==0.5.10 django-polymorphic==3.1.0 # 3.1.0 is first version that supports Django 4.0, unsure if it fully supports 4.2 diff --git a/docs/source/administration.rst b/docs/source/administration.rst index 872222055..6ba820fd8 100644 --- a/docs/source/administration.rst +++ b/docs/source/administration.rst @@ -46,7 +46,7 @@ Pages are individual entire pages of markup content. They are require ``Title`` :Is Published: Controls whether or not the page is visible on the site. :Template Name: By default Pages use the template ``templates/pages/default.html`` to use a different template enter the template path here. -.. note:: Pages are automatically purge from Fastly.com upon save. +.. note:: Pages are automatically purged from Fastly.com upon save. .. _boxes: @@ -82,7 +82,7 @@ Release Files have a checkbox named 'Download button' that determines which bina Jobs ---- -The jobs application is using to display Python jobs on the site. The data items should be fairly self explanatory. There are a couple of things to keep in mind. Logged in users of the site can submit jobs for review. +The jobs application is used to display Python jobs on the site. The data items should be fairly self explanatory. There are a couple of things to keep in mind. Logged in users of the site can submit jobs for review. :Status: Jobs enter the system in 'review' status after the submitter has entered them. Only jobs in the 'approved' state are displayed on the site. :Featured: Featured jobs are displayed more prominently on the landing page. diff --git a/downloads/tests/test_models.py b/downloads/tests/test_models.py index f27e9517d..d31afae5c 100644 --- a/downloads/tests/test_models.py +++ b/downloads/tests/test_models.py @@ -82,8 +82,8 @@ def test_is_version_at_least(self): release_38 = Release.objects.create(name='Python 3.8.0') self.assertFalse(release_38.is_version_at_least_3_9) - self.assert_(release_38.is_version_at_least_3_5) + self.assertTrue(release_38.is_version_at_least_3_5) release_310 = Release.objects.create(name='Python 3.10.0') - self.assert_(release_310.is_version_at_least_3_9) - self.assert_(release_310.is_version_at_least_3_5) + self.assertTrue(release_310.is_version_at_least_3_9) + self.assertTrue(release_310.is_version_at_least_3_5) diff --git a/downloads/tests/test_views.py b/downloads/tests/test_views.py index e495b9e93..c585fe05c 100644 --- a/downloads/tests/test_views.py +++ b/downloads/tests/test_views.py @@ -5,11 +5,10 @@ from django.urls import reverse from django.test import TestCase, override_settings -from rest_framework.authtoken.models import Token from rest_framework.test import APITestCase from .base import BaseDownloadTests, DownloadMixin -from ..models import OS, Release +from ..models import Release from pages.factories import PageFactory from pydotorg.drf import BaseAPITestCase from users.factories import UserFactory diff --git a/events/importer.py b/events/importer.py index e47775060..fe04d35f5 100644 --- a/events/importer.py +++ b/events/importer.py @@ -22,7 +22,13 @@ def import_occurrence(self, event, event_data): # but won't add any timezone information. We will convert them to # aware datetime objects manually. dt_start = extract_date_or_datetime(event_data['DTSTART'].dt) - dt_end = extract_date_or_datetime(event_data['DTEND'].dt) + if 'DTEND' in event_data: + # DTEND is not always set on events, in particular it seems that + # events which have the same start and end time, don't provide + # DTEND. See #2021. + dt_end = extract_date_or_datetime(event_data['DTEND'].dt) + else: + dt_end = dt_start # Let's mark those occurrences as 'all-day'. all_day = ( diff --git a/events/models.py b/events/models.py index 3334ca326..b41d92b22 100644 --- a/events/models.py +++ b/events/models.py @@ -237,7 +237,7 @@ class OccurringRule(RuleMixin, models.Model): def __str__(self): strftime = settings.SHORT_DATETIME_FORMAT - return f'{self.event.title} {date(self.dt_start.strftime, strftime)} - {date(self.dt_end.strftime, strftime)}' + return f'{self.event.title} {date(self.dt_start, strftime)} - {date(self.dt_end, strftime)}' @property def begin(self): @@ -283,8 +283,8 @@ class RecurringRule(RuleMixin, models.Model): all_day = models.BooleanField(default=False) def __str__(self): - strftime = settings.SHORT_DATETIME_FORMAT - return f'{self.event.title} every {timedelta_nice_repr(self.interval)} since {date(self.dt_start.strftime, strftime)}' + return (f'{self.event.title} every {timedelta_nice_repr(self.freq_interval_as_timedelta)} since ' + f'{date(self.dt_start, settings.SHORT_DATETIME_FORMAT)}') def to_rrule(self): return rrule( diff --git a/fixtures/boxes.json b/fixtures/boxes.json index bc3816cc7..df66827b5 100644 --- a/fixtures/boxes.json +++ b/fixtures/boxes.json @@ -318,9 +318,9 @@ "created": "2014-02-13T17:37:50.862Z", "updated": "2014-02-16T23:01:04.762Z", "label": "widget-weneedyou", - "content": "

>>> Python Needs You

\r\n

Open source software is made better when users can easily contribute code and documentation to fix bugs and add features. Python strongly encourages community involvement in improving the software. Learn more about how to make Python better for everyone.

\r\n

\r\n Contribute to Python\r\n Bug Tracker\r\n

", + "content": "

>>> Python Needs You

\r\n

Open source software is made better when users can easily contribute code and documentation to fix bugs and add features. Python strongly encourages community involvement in improving the software. Learn more about how to make Python better for everyone.

\r\n

\r\n Contribute to Python\r\n Bug Tracker\r\n

", "content_markup_type": "html", - "_content_rendered": "

>>> Python Needs You

\r\n

Open source software is made better when users can easily contribute code and documentation to fix bugs and add features. Python strongly encourages community involvement in improving the software. Learn more about how to make Python better for everyone.

\r\n

\r\n Contribute to Python\r\n Bug Tracker\r\n

" + "_content_rendered": "

>>> Python Needs You

\r\n

Open source software is made better when users can easily contribute code and documentation to fix bugs and add features. Python strongly encourages community involvement in improving the software. Learn more about how to make Python better for everyone.

\r\n

\r\n Contribute to Python\r\n Bug Tracker\r\n

" } }, { diff --git a/jobs/tests/test_models.py b/jobs/tests/test_models.py index 310659165..5a9c5eb8d 100644 --- a/jobs/tests/test_models.py +++ b/jobs/tests/test_models.py @@ -76,7 +76,7 @@ def test_visible_manager(self): j3 = factories.ApprovedJobFactory(expires=past) visible = Job.objects.visible() - self.assertTrue(len(visible), 1) + self.assertEqual(len(visible), 1) self.assertIn(j1, visible) self.assertNotIn(j2, visible) self.assertNotIn(j3, visible) diff --git a/pydotorg/settings/base.py b/pydotorg/settings/base.py index 9697a6ea8..30dc8de4a 100644 --- a/pydotorg/settings/base.py +++ b/pydotorg/settings/base.py @@ -230,11 +230,6 @@ 'allauth', 'allauth.account', - 'allauth.socialaccount', - #'allauth.socialaccount.providers.facebook', - #'allauth.socialaccount.providers.github', - #'allauth.socialaccount.providers.openid', - #'allauth.socialaccount.providers.twitter', # Tastypie needs the `users` app to be already loaded. 'tastypie', diff --git a/runtime.txt b/runtime.txt deleted file mode 100644 index c9cbcea6f..000000000 --- a/runtime.txt +++ /dev/null @@ -1 +0,0 @@ -python-3.9.16 diff --git a/templates/base.html b/templates/base.html index b9f3df9c6..578dc1204 100644 --- a/templates/base.html +++ b/templates/base.html @@ -66,7 +66,7 @@ {# Tile icon for Win8 (144x144 + tile color) #} - +