From 51c5b5de88c607d8fdaf0c1c463a36c234489bf4 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Thu, 19 Sep 2024 16:04:40 -0500 Subject: [PATCH 01/10] fix: display active events, fix time not displaying for some events (#2556) * fix: display active events, fix time not displaying for some events * test: passing events view tests * style: different icon * Update views.py Co-authored-by: Ee Durbin --------- Co-authored-by: Ee Durbin --- events/models.py | 11 ++- events/tests/test_views.py | 61 +++++++++++++-- events/views.py | 23 ++++-- templates/events/event_list.html | 123 ++++++++++++++++++++----------- 4 files changed, 161 insertions(+), 57 deletions(-) diff --git a/events/models.py b/events/models.py index b41d92b22..1f2ab2cb0 100644 --- a/events/models.py +++ b/events/models.py @@ -211,8 +211,15 @@ def previous_time(self): return None @property - def next_or_previous_time(self): - return self.next_time or self.previous_time + def next_or_previous_time(self) -> models.Model: + """Return the next or previous time of the event OR the occurring rule.""" + if next_time := self.next_time: + return next_time + + if previous_time := self.previous_time: + return previous_time + + return self.occurring_rule if hasattr(self, "occurring_rule") else None @property def is_past(self): diff --git a/events/tests/test_views.py b/events/tests/test_views.py index 691817036..1291252a5 100644 --- a/events/tests/test_views.py +++ b/events/tests/test_views.py @@ -35,11 +35,50 @@ def setUpTestData(cls): finish=cls.now - datetime.timedelta(days=1), ) + # Future event + cls.future_event = Event.objects.create(title='Future Event', creator=cls.user, calendar=cls.calendar, featured=True) + RecurringRule.objects.create( + event=cls.future_event, + begin=cls.now + datetime.timedelta(days=1), + finish=cls.now + datetime.timedelta(days=2), + ) + + # Happening now event + cls.current_event = Event.objects.create(title='Current Event', creator=cls.user, calendar=cls.calendar) + RecurringRule.objects.create( + event=cls.current_event, + begin=cls.now - datetime.timedelta(hours=1), + finish=cls.now + datetime.timedelta(hours=1), + ) + + # Just missed event + cls.just_missed_event = Event.objects.create(title='Just Missed Event', creator=cls.user, calendar=cls.calendar) + RecurringRule.objects.create( + event=cls.just_missed_event, + begin=cls.now - datetime.timedelta(hours=3), + finish=cls.now - datetime.timedelta(hours=1), + ) + + # Past event + cls.past_event = Event.objects.create(title='Past Event', creator=cls.user, calendar=cls.calendar) + RecurringRule.objects.create( + event=cls.past_event, + begin=cls.now - datetime.timedelta(days=2), + finish=cls.now - datetime.timedelta(days=1), + ) + def test_events_homepage(self): url = reverse('events:events') response = self.client.get(url) + events = response.context['object_list'] + event_titles = [event.title for event in events] + self.assertEqual(response.status_code, 200) - self.assertEqual(len(response.context['object_list']), 1) + self.assertEqual(len(events), 6) + + self.assertIn('Future Event', event_titles) + self.assertIn('Current Event', event_titles) + self.assertIn('Past Event', event_titles) def test_calendar_list(self): calendars_count = Calendar.objects.count() @@ -54,7 +93,7 @@ def test_event_list(self): response = self.client.get(url) self.assertEqual(response.status_code, 200) - self.assertEqual(len(response.context['object_list']), 1) + self.assertEqual(len(response.context['object_list']), 3) url = reverse('events:event_list_past', kwargs={"calendar_slug": 'unexisting'}) response = self.client.get(url) @@ -66,7 +105,7 @@ def test_event_list_past(self): response = self.client.get(url) self.assertEqual(response.status_code, 200) - self.assertEqual(len(response.context['object_list']), 1) + self.assertEqual(len(response.context['object_list']), 4) def test_event_list_category(self): category = EventCategory.objects.create( @@ -114,7 +153,7 @@ def test_event_list_date(self): response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['object'], dt.date()) - self.assertEqual(len(response.context['object_list']), 2) + self.assertEqual(len(response.context['object_list']), 6) def test_eventlocation_list(self): venue = EventLocation.objects.create( @@ -150,12 +189,20 @@ def test_event_detail(self): self.assertEqual(self.event, response.context['object']) def test_upcoming_tag(self): - self.assertEqual(len(get_events_upcoming()), 1) - self.assertEqual(len(get_events_upcoming(only_featured=True)), 0) + self.assertEqual(len(get_events_upcoming()), 3) + self.assertEqual(len(get_events_upcoming(only_featured=True)), 1) self.rule.begin = self.now - datetime.timedelta(days=3) self.rule.finish = self.now - datetime.timedelta(days=2) self.rule.save() - self.assertEqual(len(get_events_upcoming()), 0) + self.assertEqual(len(get_events_upcoming()), 2) + + def test_context_data(self): + url = reverse("events:events") + response = self.client.get(url) + + self.assertIn("events_just_missed", response.context) + self.assertIn("upcoming_events", response.context) + self.assertIn("events_now", response.context) class EventSubmitTests(TestCase): diff --git a/events/views.py b/events/views.py index 2490626e3..56df88dcb 100644 --- a/events/views.py +++ b/events/views.py @@ -40,10 +40,21 @@ def get_context_data(self, **kwargs): class EventHomepage(ListView): """ Main Event Landing Page """ - template_name = 'events/event_list.html' + template_name = "events/event_list.html" - def get_queryset(self): - return Event.objects.for_datetime(timezone.now()).order_by('occurring_rule__dt_start') + def get_queryset(self) -> Event: + """Queryset to return all events, ordered by START date.""" + return Event.objects.all().order_by("-occurring_rule__dt_start") + + def get_context_data(self, **kwargs: dict) -> dict: + """Add more ctx, specifically events that are happening now, just missed, and upcoming.""" + context = super().get_context_data(**kwargs) + context["events_just_missed"] = Event.objects.until_datetime(timezone.now())[:2] + context["upcoming_events"] = Event.objects.for_datetime(timezone.now()) + context["events_now"] = Event.objects.filter( + occurring_rule__dt_start__lte=timezone.now(), + occurring_rule__dt_end__gte=timezone.now())[:2] + return context class EventDetail(DetailView): @@ -68,11 +79,13 @@ def get_context_data(self, **kwargs): class EventList(EventListBase): def get_queryset(self): - return Event.objects.for_datetime(timezone.now()).filter(calendar__slug=self.kwargs['calendar_slug']).order_by('occurring_rule__dt_start') + return Event.objects.for_datetime(timezone.now()).filter(calendar__slug=self.kwargs['calendar_slug']).order_by( + 'occurring_rule__dt_start') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['events_today'] = Event.objects.until_datetime(timezone.now()).filter(calendar__slug=self.kwargs['calendar_slug'])[:2] + context['events_today'] = Event.objects.until_datetime(timezone.now()).filter( + calendar__slug=self.kwargs['calendar_slug'])[:2] context['calendar'] = get_object_or_404(Calendar, slug=self.kwargs['calendar_slug']) return context diff --git a/templates/events/event_list.html b/templates/events/event_list.html index bbfb764d2..8d7b0d60f 100644 --- a/templates/events/event_list.html +++ b/templates/events/event_list.html @@ -8,73 +8,110 @@ {% block header_content %} {% if featured %} - {% endif %} {% endblock header_content %} - -{# Based on python/events.html #} - {% block content %} - {% if calendar %} + {% if calendar %}

from the {{ calendar.name }}

- {% endif %} + {% endif %} -
+
+ {% if events_now %}
-

Upcoming Events

- {% if page_obj.has_next %} -

More

- {% endif %} +

Happening Now

+
+ {% endif %} + +
+

Upcoming Events

+ {% if page_obj.has_next %} +

More

+ {% endif %} + -
- - {% if events_today %} -

You just missed...

- - {% endif %}
+ + {% if events_just_missed %} +
+

You just missed...

+ +
+ {% endif %} +
{% endblock content %} From 5fdcbb2ec277c52109f184f09569958e2e33c91c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 21:28:19 +0000 Subject: [PATCH 02/10] Bump django-admin-interface from 0.24.2 to 0.28.9 (#2589) Bumps [django-admin-interface](https://github.com/fabiocaccamo/django-admin-interface) from 0.24.2 to 0.28.9. - [Release notes](https://github.com/fabiocaccamo/django-admin-interface/releases) - [Changelog](https://github.com/fabiocaccamo/django-admin-interface/blob/main/CHANGELOG.md) - [Commits](https://github.com/fabiocaccamo/django-admin-interface/compare/0.24.2...0.28.9) --- updated-dependencies: - dependency-name: django-admin-interface dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jacob Coffee --- base-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base-requirements.txt b/base-requirements.txt index fc018561c..2b777de51 100644 --- a/base-requirements.txt +++ b/base-requirements.txt @@ -2,7 +2,7 @@ dj-database-url==0.5.0 django-pipeline==3.0.0 # 3.0.0 is first version that supports Django 4.2 django-sitetree==1.18.0 # >=1.17.1 is (?) first version that supports Django 4.2 django-apptemplates==1.5 -django-admin-interface==0.24.2 +django-admin-interface==0.28.9 django-translation-aliases==0.1.0 Django==4.2.16 docutils==0.21.2 From a13d00adabac7f817164455af11d26dbaffd5e7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 17:38:17 -0500 Subject: [PATCH 03/10] Bump django-pipeline from 3.0.0 to 3.1.0 (#2549) Bumps [django-pipeline](https://github.com/jazzband/django-pipeline) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/jazzband/django-pipeline/releases) - [Changelog](https://github.com/jazzband/django-pipeline/blob/master/HISTORY.rst) - [Commits](https://github.com/jazzband/django-pipeline/compare/3.0.0...3.1.0) --- updated-dependencies: - dependency-name: django-pipeline dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- base-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base-requirements.txt b/base-requirements.txt index 2b777de51..fc681bce5 100644 --- a/base-requirements.txt +++ b/base-requirements.txt @@ -1,5 +1,5 @@ dj-database-url==0.5.0 -django-pipeline==3.0.0 # 3.0.0 is first version that supports Django 4.2 +django-pipeline==3.1.0 # 3.0.0 is first version that supports Django 4.2 django-sitetree==1.18.0 # >=1.17.1 is (?) first version that supports Django 4.2 django-apptemplates==1.5 django-admin-interface==0.28.9 From fa18e78c393babc44f911e6c67516f6011f6463e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 09:05:36 -0500 Subject: [PATCH 04/10] Bump factory-boy from 3.2.1 to 3.3.1 (#2548) Bumps [factory-boy](https://github.com/FactoryBoy/factory_boy) from 3.2.1 to 3.3.1. - [Changelog](https://github.com/FactoryBoy/factory_boy/blob/master/docs/changelog.rst) - [Commits](https://github.com/FactoryBoy/factory_boy/compare/3.2.1...3.3.1) --- updated-dependencies: - dependency-name: factory-boy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 8d61d0f9d..1ee11a333 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -2,7 +2,7 @@ # Required for running tests -factory-boy==3.2.1 +factory-boy==3.3.1 Faker==0.8.1 tblib==1.7.0 responses==0.13.3 From 3fa351b168942274c48158cb370e2371e843c1a8 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Fri, 20 Sep 2024 10:02:09 -0500 Subject: [PATCH 05/10] fix(frontend): add help text to story form (#2594) * fix(frontend): add help text to story form Closes #2364 * chore: source migration * fix: use meta class overrides instead * feat: linkify --- successstories/forms.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/successstories/forms.py b/successstories/forms.py index f623001b0..45ec1dfd3 100644 --- a/successstories/forms.py +++ b/successstories/forms.py @@ -24,6 +24,10 @@ class Meta: labels = { 'name': 'Story name', } + help_texts = { + "content": "Note: Submissions in Markdown " + "are strongly preferred and can be processed faster.", + } def clean_name(self): name = self.cleaned_data.get('name') From f2e763cc62cb894c26b4bc39b328ac70752db96b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 12:49:37 -0500 Subject: [PATCH 06/10] Bump python-decouple from 3.4 to 3.8 (#2596) Bumps [python-decouple](https://github.com/henriquebastos/python-decouple) from 3.4 to 3.8. - [Release notes](https://github.com/henriquebastos/python-decouple/releases) - [Changelog](https://github.com/HBNetwork/python-decouple/blob/master/CHANGELOG.md) - [Commits](https://github.com/henriquebastos/python-decouple/compare/v3.4...v3.8) --- updated-dependencies: - dependency-name: python-decouple dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jacob Coffee --- base-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base-requirements.txt b/base-requirements.txt index fc681bce5..ed65c1acf 100644 --- a/base-requirements.txt +++ b/base-requirements.txt @@ -11,7 +11,7 @@ cmarkgfm==0.6.0 Pillow==10.4.0 psycopg2-binary==2.9.9 python3-openid==3.2.0 -python-decouple==3.4 +python-decouple==3.8 # lxml used by BeautifulSoup. lxml==5.2.2 cssselect==1.1.0 From ccbc9e42488f2bf6c12831c5e12d31f5eec4c2a7 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Mon, 23 Sep 2024 07:14:45 -0500 Subject: [PATCH 07/10] deps: no mo boto (#2598) --- .github/dependabot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 427010ca9..dbe4b843c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -16,6 +16,10 @@ updates: - 0.13.0 - 0.13.1 - 0.13.2 + - dependency-name: "boto3" + - dependency-name: "boto3-stubs" + - dependency-name: "botocore" + - dependency-name: "botocore-stubs" - dependency-name: lxml versions: - 4.6.2 From c8a87b747fb257fb16725c66641dcd694a116eac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 13:10:46 -0500 Subject: [PATCH 08/10] Bump django-tastypie from 0.14.6 to 0.14.7 (#2602) Bumps [django-tastypie](https://github.com/django-tastypie/django-tastypie) from 0.14.6 to 0.14.7. - [Release notes](https://github.com/django-tastypie/django-tastypie/releases) - [Commits](https://github.com/django-tastypie/django-tastypie/compare/v0.14.6...v0.14.7) --- updated-dependencies: - dependency-name: django-tastypie dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- base-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base-requirements.txt b/base-requirements.txt index ed65c1acf..d3400104f 100644 --- a/base-requirements.txt +++ b/base-requirements.txt @@ -26,7 +26,7 @@ django-imagekit==5.0 # 5.0 is first version that supports Django 4.2 django-haystack==3.2.1 elasticsearch>=7,<8 # TODO: 0.14.0 only supports Django 1.8 and 1.11. -django-tastypie==0.14.6 # 0.14.6 is first version that supports Django 4.2 +django-tastypie==0.14.7 # 0.14.6 is first version that supports Django 4.2 pytz==2021.1 python-dateutil==2.8.2 From a84a53a7fee93bd74f9db51179935c1d3e59103c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 09:20:01 -0500 Subject: [PATCH 09/10] Bump cssselect from 1.1.0 to 1.2.0 (#2606) Bumps [cssselect](https://github.com/scrapy/cssselect) from 1.1.0 to 1.2.0. - [Changelog](https://github.com/scrapy/cssselect/blob/master/CHANGES) - [Commits](https://github.com/scrapy/cssselect/compare/v1.1.0...v1.2.0) --- updated-dependencies: - dependency-name: cssselect dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- base-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base-requirements.txt b/base-requirements.txt index d3400104f..4877f78c3 100644 --- a/base-requirements.txt +++ b/base-requirements.txt @@ -14,7 +14,7 @@ python3-openid==3.2.0 python-decouple==3.8 # lxml used by BeautifulSoup. lxml==5.2.2 -cssselect==1.1.0 +cssselect==1.2.0 feedparser==6.0.11 beautifulsoup4==4.12.3 icalendar==4.0.7 From 70a7ef6b363f7621082d03901fc16951561a07f2 Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Tue, 24 Sep 2024 10:32:57 -0400 Subject: [PATCH 10/10] chores & docs: clean up some inaccuracies in getting started (#2600) * chore: remove obsolete version entry from compose Currently raises a warning: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion Signed-off-by: Mike Fiedler * docs: staging site does not exist Signed-off-by: Mike Fiedler * docs: format the link to be clickable Signed-off-by: Mike Fiedler * docs: use what's currently in docker-compose.yml Signed-off-by: Mike Fiedler * docs: remove version specificity Signed-off-by: Mike Fiedler --------- Signed-off-by: Mike Fiedler --- docker-compose.yml | 2 -- docs/source/index.rst | 1 - docs/source/install.md | 6 +++--- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 4406c0ff5..1f5ea36b4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3.9" - services: postgres: image: postgres:15.3-bullseye diff --git a/docs/source/index.rst b/docs/source/index.rst index 76a201828..cfde87586 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -10,7 +10,6 @@ General information :Issue tracker: https://github.com/python/pythondotorg/issues :Mailing list: pydotorg-www_ :IRC: ``#pydotorg`` on Freenode -:Staging site: https://staging.python.org/ (``main`` branch) :Production configuration: https://github.com/python/psf-salt :GitHub Actions: .. image:: https://github.com/python/pythondotorg/actions/workflows/ci.yml/badge.svg diff --git a/docs/source/install.md b/docs/source/install.md index d6c29d295..c91d1bd59 100644 --- a/docs/source/install.md +++ b/docs/source/install.md @@ -55,7 +55,7 @@ web_1 | Starting development server at http://0.0.0.0:8000/ web_1 | Quit the server with CONTROL-C. ``` -You can view these results in your local web browser at: `http://localhost:8000` +You can view these results in your local web browser at: To reset your local environment, run: @@ -88,7 +88,7 @@ This is a simple wrapper around running `python manage.py` in the container, all Manual setup ------------ -First, install [PostgreSQL](https://www.postgresql.org/download/) on your machine and run it. *pythondotorg* currently uses Postgres 10.21. +First, install [PostgreSQL](https://www.postgresql.org/download/) on your machine and run it. *pythondotorg* currently uses Postgres 15.x. Then clone the repository: @@ -99,7 +99,7 @@ $ git clone git://github.com/python/pythondotorg.git Then create a virtual environment: ``` -$ python3.9 -m venv venv +$ python3 -m venv venv ``` And then you'll need to install dependencies. You don't need to use `pip3` inside a Python 3 virtual environment: