xref: /aosp_15_r20/external/pigweed/pw_docgen/py/pw_docgen/sphinx/pigweed_live.py (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1# Copyright 2023 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""Docs widget that provides up-to-date info about the next Pigweed Live."""
15
16
17import datetime
18import sys
19
20from docutils import nodes
21from docutils.parsers.rst import Directive
22from sphinx.application import Sphinx
23
24try:
25    import pytz  # type: ignore
26
27    PYTZ_AVAILABLE = True
28except ImportError:
29    PYTZ_AVAILABLE = False
30
31
32class PigweedLiveDirective(Directive):
33    """Generates the up-to-date Pigweed Live info."""
34
35    datetime_format = '%Y-%m-%d %H:%M:%S'
36    # TODO: b/303859828 - Update this data sometime between 2025-09-22
37    # and 2025-10-20.
38    meetings = [
39        '2024-07-01 13:00:00',
40        '2024-07-29 13:00:00',
41        '2024-08-26 13:00:00',
42        '2024-09-23 13:00:00',
43        '2024-10-21 13:00:00',
44        '2024-12-16 13:00:00',
45        '2025-01-13 13:00:00',
46        '2025-02-10 13:00:00',
47        '2025-03-10 13:00:00',
48        '2025-04-07 13:00:00',
49        '2025-05-05 13:00:00',
50        '2025-06-02 13:00:00',
51        '2025-06-30 13:00:00',
52        '2025-07-28 13:00:00',
53        '2025-08-25 13:00:00',
54        '2025-09-22 13:00:00',
55        '2025-10-20 13:00:00',
56        '2025-11-17 13:00:00',
57        '2025-12-15 13:00:00',
58    ]
59    timezone = pytz.timezone('US/Pacific')
60
61    def run(self) -> list[nodes.Node]:
62        return [self._make_paragraph()]
63
64    def _make_paragraph(self) -> nodes.Node:
65        next_meeting = self._find_next_meeting()
66        paragraph = nodes.paragraph()
67        paragraph += nodes.Text('Our next Pigweed Live is ')
68        meeting_text = nodes.strong()
69        meeting_text += nodes.Text(next_meeting)
70        paragraph += meeting_text
71        paragraph += nodes.Text(
72            (
73                ". Please join us to discuss what's new in Pigweed and "
74                "anything else Pigweed-related that's on your mind. "
75            )
76        )
77        refuri = 'https://groups.google.com/g/pigweed'
78        link = nodes.reference(refuri=refuri)
79        link += nodes.Text('Join our mailing list')
80        paragraph += link
81        paragraph += nodes.Text(" to receive an invite to the next meeting.")
82        return paragraph
83
84    def _find_next_meeting(self) -> str:
85        current_datetime = self.timezone.localize(datetime.datetime.now())
86        next_meeting = None
87        for meeting in self.meetings:
88            unlocalized_datetime = datetime.datetime.strptime(
89                meeting, self.datetime_format
90            )
91            meeting_datetime = self.timezone.localize(unlocalized_datetime)
92            if current_datetime > meeting_datetime:
93                continue
94            next_meeting = meeting_datetime
95            break
96        if next_meeting is None:
97            sys.exit(
98                'ERROR: Pigweed Live meeting data needs to be updated. '
99                'Update the `meetings` list in `PigweedLiveDirective`. '
100                'See b/303859828.'
101            )
102        else:
103            date = next_meeting.strftime('%a %b %d, %Y')
104            hour = next_meeting.strftime('%I%p').lstrip('0')
105            timezone = 'PDT' if next_meeting.dst() else 'PST'
106            return f'{date} {hour} ({timezone})'
107
108
109def setup(app: Sphinx) -> dict[str, bool]:
110    """Initialize the directive."""
111    if PYTZ_AVAILABLE:
112        app.add_directive('pigweed-live', PigweedLiveDirective)
113    return {
114        'parallel_read_safe': True,
115        'parallel_write_safe': True,
116    }
117