Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: 2
build:
os: ubuntu-22.04
tools:
python: "3.11"
python: "3.14"

python:
install:
Expand Down
22 changes: 14 additions & 8 deletions docs/community/monthly-meeting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@ Documentation Community Monthly Meetings

Monthly meetings are held on the first Tuesday of the month
on the `Discord server <https://discord.gg/sMWqvzXvde>`_ and last one hour.
Check the agenda or Discourse announcement to verify the start time.
Upcoming meeting dates and times:

+-----------------+--------------+--------------+
| Period | Even months | Odd months |
+=================+==============+==============+
| April-October | 19:00 UTC | 16:00 UTC |
+-----------------+--------------+--------------+
| November-March | 20:00 UTC | 17:00 UTC |
+-----------------+--------------+--------------+
.. meeting-dates::

`Download iCalendar file </docs-community-meetings.ics>`_

The agenda and later the meeting minutes are written in the `HackMD <https://hackmd.io/@encukou/pydocswg1>`_.
To edit notes, click the “pencil” or “split view” button on the `HackMD Document <https://hackmd.io/@encukou/pydocswg1>`_.
Expand All @@ -27,6 +23,16 @@ By participating in meetings, you are agreeing to abide by and uphold the
`PSF Code of Conduct <https://policies.python.org/python.org/code-of-conduct/>`_.
Please take a second to read through it!

Meetings follow the pattern:

+-----------------+--------------+--------------+
| Period | Even months | Odd months |
+=================+==============+==============+
| April-October | 19:00 UTC | 16:00 UTC |
+-----------------+--------------+--------------+
| November-March | 20:00 UTC | 17:00 UTC |
+-----------------+--------------+--------------+


Minutes template
----------------
Expand Down
10 changes: 10 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

# A list of strings that are module names of Sphinx extensions
import os
import sys

sys.path.append(os.path.abspath("tools/"))

extensions = [
"sphinx_copybutton",
"sphinx.ext.intersphinx",
"myst_parser",
"meeting_dates",
]

myst_enable_extensions = ["linkify"]
Expand Down Expand Up @@ -68,6 +74,10 @@
r"https://plausible.io/docs.python.org",
r"https://plausible.io/packaging.python.org",
r"https://us.pycon.org/2024/registration/category/4",
# Have redirects:
r"https://arewemeetingyet.com/.*",
# Generated at build time:
r"/docs-community-meetings.ics",
]

# A list of document names to exclude from linkcheck
Expand Down
109 changes: 109 additions & 0 deletions docs/tools/meeting_dates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"""Sphinx extension to generate a list of upcoming meeting dates."""

import datetime as dt
import os

from docutils import nodes
from sphinx.util.docutils import SphinxDirective


def utc_hour(date):
if 4 <= date.month <= 10:
# Daylight saving time in Europe and the US
return 19 if date.month % 2 == 0 else 16
else:
# Winter time in Europe and the US
return 20 if date.month % 2 == 0 else 17


def first_tuesday(year, month):
first = dt.date(year, month, 1)
days_ahead = (1 - first.weekday()) % 7
return first + dt.timedelta(days=days_ahead)


def upcoming_meetings(today, count):
meetings = []
year, month = today.year, today.month
while len(meetings) < count:
meeting_date = first_tuesday(year, month)
if meeting_date >= today:
meetings.append((meeting_date, utc_hour(meeting_date)))
month += 1
if month > 12:
month = 1
year += 1
return meetings


def past_meetings(today, count):
meetings = []
year, month = today.year, today.month
while len(meetings) < count:
meeting_date = first_tuesday(year, month)
if meeting_date < today:
meetings.append((meeting_date, utc_hour(meeting_date)))
month -= 1
if month < 1:
month = 12
year -= 1
meetings.reverse()
return meetings


class MeetingDatesDirective(SphinxDirective):
has_content = False

def run(self):
bullets = nodes.bullet_list()
for date, hour in upcoming_meetings(dt.date.today(), 6):
item = nodes.list_item()
text = f"{date.strftime('%B %d, %Y')} - {hour:02d}:00 UTC"
url = f"https://arewemeetingyet.com/UTC/{date.isoformat()}/{hour}:00/Docs Community Meeting"

paragraph = nodes.paragraph()
ref = nodes.reference("", text, refuri=url)
paragraph += ref
item += paragraph
bullets += item

return [bullets]


def generate_ics(app, exception):
if exception:
return

lines = [
"BEGIN:VCALENDAR",
"VERSION:2.0",
"PRODID:-//Python Docs WG//Meeting dates//EN",
"X-WR-CALDESC:Python Docs WG meetings from https://docs-community.readthedocs.io/",
"X-WR-CALNAME:Python Docs WG meetings",
]
today = dt.date.today()
meetings = past_meetings(today, 12) + upcoming_meetings(today, 12)
for date, hour in meetings:
start = dt.datetime(date.year, date.month, date.day, hour, 0, 0)
end = start + dt.timedelta(hours=1)
lines += [
"BEGIN:VEVENT",
f"UID:{start.strftime('%Y%m%dT%H%M%SZ')}@python-docs-community",
f"DTSTAMP:{dt.datetime.now(dt.timezone.utc).strftime('%Y%m%dT%H%M%SZ')}",
f"DTSTART:{start.strftime('%Y%m%dT%H%M%SZ')}",
f"DTEND:{end.strftime('%Y%m%dT%H%M%SZ')}",
"SUMMARY:Python Docs WG",
f"URL:https://arewemeetingyet.com/UTC/{date.isoformat()}/{hour}:00/Python Docs WG meeting",
"END:VEVENT",
]
lines += ["END:VCALENDAR"]
ics = "\r\n".join(lines) + "\r\n"

with open(os.path.join(app.outdir, "docs-community-meetings.ics"), "w") as f:
f.write(ics)


def setup(app):
app.add_directive("meeting-dates", MeetingDatesDirective)
app.connect("build-finished", generate_ics)
return {"version": "1.0", "parallel_read_safe": True}
Loading