From baee8b5649d47f5785235ecd7f87affb83143d77 Mon Sep 17 00:00:00 2001 From: Ryan Lerch Date: Jan 15 2018 04:29:47 +0000 Subject: update calendar widget for streams This Changes the calendar (aka the meetings) widget so it only shows on streams or teams. Additionally on the stream page, it shows the meetings upcoming for all the hubs that a user is a member of. fixes #489 --- diff --git a/hubs/widgets/meetings/__init__.py b/hubs/widgets/meetings/__init__.py index 12b9041..52ba6eb 100644 --- a/hubs/widgets/meetings/__init__.py +++ b/hubs/widgets/meetings/__init__.py @@ -4,7 +4,9 @@ import arrow 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 @@ class Meetings(Widget): 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,14 +40,18 @@ class BaseView(RootWidgetView): 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, ) @@ -53,33 +60,66 @@ class GetMeetings(CachedFunction): TOPIC = ".fedocal.calendar." invalidate_on_hub_config_change = True + def __init__(self, instance): + self.instance = instance + # there is no way to invalidate the cache if a + # different hub config changes. Since streams + # calendar pulls from the hubs the user is a member + # of, we just invalidate the cache for streams. + self.invalidate() + if self.instance.hub.hub_type == "stream": + self.invalidate() + def execute(self): calendar = self.instance.hub.config.get("calendar") + calendars = [] 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) - + if self.instance.hub.hub_type == "stream": + username = self.instance.hub.name + user = hubs.models.User.by_username(username) + for hub in user.memberships: + if hub.name != username: + c = hub.config.get("calendar") + # if a hub admin adds a calendar, then removes it + # the calendar value is '' rather than null. This + # works around that. + if c != '': + calendars.append(hub.config.get("calendar")) + if calendars is []: + calendars = None + else: + calendars = None + else: + # if a hub admin adds a calendar, then removes it + # the calendar value is '' rather than null. This + # works around that. + if calendar != '': + calendars.append(calendar) 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 + if calendars: + 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): if self.TOPIC not in message["topic"]: diff --git a/hubs/widgets/meetings/templates/root.html b/hubs/widgets/meetings/templates/root.html index 2596d32..ea10b92 100644 --- a/hubs/widgets/meetings/templates/root.html +++ b/hubs/widgets/meetings/templates/root.html @@ -1,7 +1,13 @@ -{% if not calendar %} +{% if not calendars %} + {% if hub_type == 'team' %}

You must configure a calendar in the hub configuration in order to use this widget.

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

+ The hubs you are subscribed to are not using calendars +

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