#520 Extend PR #511 to use the fedmsg publishing infra in #518
Merged 6 years ago by abompard. Opened 6 years ago by abompard.
abompard/fedora-hubs reviews/511/1  into  develop

@@ -4,7 +4,9 @@ 

  import collections

  import datetime

  import requests

+ from collections import OrderedDict as ordereddict

  

+ import hubs.models

  from hubs.utils import validators

  from hubs.utils.text import markup

  from hubs.widgets.base import Widget
@@ -24,6 +26,7 @@ 

              validator=validators.Integer,

              help="The number of meetings to display.",

          )]

+     hub_types = ["team", "stream"]

  

      def get_template_environment(self):

          env = super(Meetings, self).get_template_environment()
@@ -37,63 +40,102 @@ 

      def get_context(self, instance, *args, **kwargs):

          get_meetings = GetMeetings(instance)

          now = datetime.datetime.utcnow()

+         results = get_meetings()

          meetings = {

              title: meeting

-             for title, meeting in get_meetings().items()

+             for title, meeting in results["meetings"].items()

              if meeting['start_dt'] > now

              }

+         meetings = ordereddict(sorted(meetings.items(),

+                                       key=lambda x: x[1]["start_dt"]))

          return dict(

-             calendar=instance.hub.config.get("calendar"),

+             calendars=results["calendars"],

              meetings=meetings,

+             hub_type=instance.hub.hub_type,

              )

  

  

  class GetMeetings(CachedFunction):

  

-     TOPIC = ".fedocal.calendar."

- 

-     def execute(self):

+     def get_calendars(self):

          calendar = self.instance.hub.config.get("calendar")

-         if calendar is None:

-             return {}

-         n_meetings = self.instance.config.get("n_meetings", 4)

-         base = ('https://apps.fedoraproject.org/calendar/api/meetings/'

-                 '?calendar=%s')

-         url = base % calendar

-         response = requests.get(url).json()

- 

-         tmp = collections.defaultdict(list)

-         for meeting in response['meetings']:

-             if meeting.get('meeting_information_html'):

-                 meeting['meeting_information_html'] = markup(

-                     meeting['meeting_information'])

-             tmp[meeting['meeting_name']].append(meeting)

+         calendars = [calendar]

+         if self.instance.hub.hub_type == "stream":

+             username = self.instance.hub.name

+             user = hubs.models.User.query.get(username)

+             for hub in user.subscriptions:

+                 if hub.name != username:

+                     calendars.append(hub.config.get("calendar"))

+         # Filter out None or empty strings

+         return [c for c in calendars if c]

  

+     def execute(self):

+         calendars = self.get_calendars()

          meetings = {}

-         for title, items in tmp.items():

-             selected = next_meeting(items)

-             if not selected:

-                 continue

-             meetings[title] = selected

-             if len(meetings) >= n_meetings:

-                 break

- 

-         return meetings

+         for c in calendars:

+             n_meetings = self.instance.config.get("n_meetings", 4)

+             base = ('https://apps.fedoraproject.org/calendar/api/meetings/'

+                     '?calendar=%s')

+             url = base % c

+             response = requests.get(url).json()

+ 

+             tmp = collections.defaultdict(list)

+             for meeting in response['meetings']:

+                 if meeting.get('meeting_information_html'):

+                     meeting['meeting_information_html'] = markup(

+                         meeting['meeting_information'])

+                 tmp[meeting['meeting_name']].append(meeting)

+ 

+             for title, items in tmp.items():

+                 selected = next_meeting(items)

+                 if not selected:

+                     continue

+                 meetings[title] = selected

+                 if len(meetings) >= n_meetings:

+                     break

+ 

+         return {"meetings": meetings, "calendars": calendars}

  

      def should_invalidate(self, message):

+         # Invalidate when:

+         # - a subscribed hub changes its calendar

+         # - the user subscribes to a new hub that has a calendar

+         # - the user unsubscribes from a hub that has a calendar

+         # - one of the subscribed calendars has an update

+ 

          # Hub update

          if message["topic"].endswith('.hubs.hub.updated'):

              if "calendar" not in message["msg"]["changed_keys"]:

                  return False

-             return message["msg"]["hub_id"] == self.instance.hub.id

-         # Calendar update

-         if self.TOPIC not in message["topic"]:

+             hub_id = message["msg"]["hub_id"]

+             if hub_id == self.instance.hub.id:

+                 return True

+             if self.instance.hub.hub_type == "stream":

+                 user = hubs.models.User.query.get(self.instance.hub.name)

+                 if hub_id in [h.id for h in user.subscriptions]:

+                     return True

              return False

-         try:

-             calendar = message["msg"]["calendar"]["calendar_name"]

-         except KeyError:

-             return False

-         return (calendar == self.instance.hub.config.get("calendar"))

+ 

+         # User subscription

+         if ".hubs.user.role." in message["topic"]:

+             if message["msg"]["username"] != self.instance.hub.name:

+                 return False

+             if message["msg"]["role"] != "subscriber":

+                 return False

+             hub = hubs.models.Hub.query.get(message["msg"]["hub_id"])

+             if not hub:

+                 return False

+             return bool(hub.config.get("calendar"))

+ 

+         # Calendar update

+         if ".fedocal.calendar." in message["topic"]:

+             try:

+                 calendar = message["msg"]["calendar"]["calendar_name"]

+             except KeyError:

+                 return False

+             return calendar in self.get_calendars()

+ 

+         return False

  

  

  def next_meeting(meetings):

@@ -1,7 +1,13 @@ 

- {% if not calendar %}

+ {% if not calendars %}

+   {% if hub_type == 'team' %}

    <p class="text-warning mb-0">

      <em>You must configure a calendar in the hub configuration in order to use this widget.</em>

    </p>

+   {% elif hub_type == 'stream'%}

+   <p class="text-warning mb-0">

+     <em>The hubs you are subscribed to are not using calendars</em>

+   </p>

+   {% endif %}

  {% else %}

    {% for title, next in meetings.items() %}

    <div class="meeting">

The additional commit allows calendars to be refreshed in the following cases:

  • a subscribed hub changes its calendar
  • the user subscribes to a new hub that has a calendar
  • the user unsubscribes from a hub that has a calendar
  • one of the subscribed calendars has an update

It contains commits from PR #518 (fedmsg) and PR #511 by @ryanlerch .

rebased onto 5f1e0d2

6 years ago

Pull-Request has been merged by abompard

6 years ago