From d788a5477c3e24be0d04f556143ca2f38554608e Mon Sep 17 00:00:00 2001 From: Ryan Lerch Date: Nov 24 2017 06:39:10 +0000 Subject: [PATCH 1/2] Rename Subscriptions widget to 'My Hubs' --- diff --git a/hubs/default_config.py b/hubs/default_config.py index 3c0ef00..cb13489 100644 --- a/hubs/default_config.py +++ b/hubs/default_config.py @@ -65,10 +65,10 @@ WIDGETS = [ 'hubs.widgets.irc:IRC', 'hubs.widgets.meetings:Meetings', 'hubs.widgets.memberships:Memberships', + 'hubs.widgets.my_hubs:MyHubs', 'hubs.widgets.pagure_pr:PagurePRs', 'hubs.widgets.pagureissues:PagureIssues', 'hubs.widgets.rules:Rules', 'hubs.widgets.sticky:Sticky', - 'hubs.widgets.subscriptions:Subscriptions', 'hubs.widgets.workflow.updates2stable:Updates2Stable', ] diff --git a/hubs/widgets/my_hubs/__init__.py b/hubs/widgets/my_hubs/__init__.py new file mode 100644 index 0000000..c08f23d --- /dev/null +++ b/hubs/widgets/my_hubs/__init__.py @@ -0,0 +1,79 @@ +from __future__ import unicode_literals + +import flask +from fedmsg.meta import msg2usernames +from fedmsg.meta.base import BaseConglomerator as BC + +import hubs.models +from hubs.utils import get_fedmsg_config +from hubs.widgets import validators +from hubs.widgets.base import Widget +from hubs.widgets.view import RootWidgetView +from hubs.widgets.caching import CachedFunction + + +fedmsg_config = get_fedmsg_config() + + +class MyHubs(Widget): + + name = "my_hubs" + position = "right" + label = "My Hubs" + hidden_if_empty = True + parameters = [ + dict( + name="username", + label="Username", + default=None, + validator=validators.Username, + help="A FAS username.", + )] + hub_types = ['user'] + + +class BaseView(RootWidgetView): + + def get_context(self, instance, *args, **kwargs): + context = {} + get_subs = GetSubs(instance) + context.update(get_subs()) + return context + + +# function hyperlinks the hubs in the subscription widget +def manage_subscriptions(items): + return [ + '{item}'.format( + link=flask.url_for('hub', name=item), + item=item, + ) for index, item in enumerate(items[0:3]) + ] + + +class GetSubs(CachedFunction): + + def execute(self): + username = self.instance.config["username"] + user = hubs.models.User.by_username(username) + ownerships = [u.name for u in user.ownerships] + memberships = [u.name for u in user.memberships] + subscriptions = [u.name for u in user.subscriptions] + subscriptions_list = manage_subscriptions(subscriptions) + memberships_list = manage_subscriptions(memberships) + return dict( + associations=memberships + ownerships, + ownerships=ownerships, + memberships=memberships, + subscriptions=subscriptions, + ownerships_text=BC.list_to_series(ownerships), + memberships_text=BC.list_to_series(memberships_list), + subscriptions_text=BC.list_to_series(subscriptions_list), + ) + + def should_invalidate(self, message): + if not message['topic'].endswith('hubs.associate'): + return False + username = self.instance.config['username'] + users = msg2usernames(message, **fedmsg_config) + return username in users diff --git a/hubs/widgets/my_hubs/templates/root.html b/hubs/widgets/my_hubs/templates/root.html new file mode 100644 index 0000000..248d86f --- /dev/null +++ b/hubs/widgets/my_hubs/templates/root.html @@ -0,0 +1,15 @@ +{% if associations %} + + {% if memberships %} +

Belongs to: {{memberships_text}}

+ {% endif %} +
+ {% if subscriptions %} +

Subscribes to: + {% for subscription in subscriptions %} + + {{subscription}} + {% endfor %}

+ {% endif %} + +{% endif %} diff --git a/hubs/widgets/subscriptions/__init__.py b/hubs/widgets/subscriptions/__init__.py deleted file mode 100644 index 6374b8a..0000000 --- a/hubs/widgets/subscriptions/__init__.py +++ /dev/null @@ -1,79 +0,0 @@ -from __future__ import unicode_literals - -import flask -from fedmsg.meta import msg2usernames -from fedmsg.meta.base import BaseConglomerator as BC - -import hubs.models -from hubs.utils import get_fedmsg_config -from hubs.widgets import validators -from hubs.widgets.base import Widget -from hubs.widgets.view import RootWidgetView -from hubs.widgets.caching import CachedFunction - - -fedmsg_config = get_fedmsg_config() - - -class Subscriptions(Widget): - - name = "subscriptions" - position = "right" - display_title = "Hubs" - hidden_if_empty = True - parameters = [ - dict( - name="username", - label="Username", - default=None, - validator=validators.Username, - help="A FAS username.", - )] - hub_types = ['user'] - - -class BaseView(RootWidgetView): - - def get_context(self, instance, *args, **kwargs): - context = {} - get_subs = GetSubs(instance) - context.update(get_subs()) - return context - - -# function hyperlinks the hubs in the subscription widget -def manage_subscriptions(items): - return [ - '{item}'.format( - link=flask.url_for('hub', name=item), - item=item, - ) for index, item in enumerate(items[0:3]) - ] - - -class GetSubs(CachedFunction): - - def execute(self): - username = self.instance.config["username"] - user = hubs.models.User.by_username(username) - ownerships = [u.name for u in user.ownerships] - memberships = [u.name for u in user.memberships] - subscriptions = [u.name for u in user.subscriptions] - subscriptions_list = manage_subscriptions(subscriptions) - memberships_list = manage_subscriptions(memberships) - return dict( - associations=memberships + ownerships, - ownerships=ownerships, - memberships=memberships, - subscriptions=subscriptions, - ownerships_text=BC.list_to_series(ownerships), - memberships_text=BC.list_to_series(memberships_list), - subscriptions_text=BC.list_to_series(subscriptions_list), - ) - - def should_invalidate(self, message): - if not message['topic'].endswith('hubs.associate'): - return False - username = self.instance.config['username'] - users = msg2usernames(message, **fedmsg_config) - return username in users diff --git a/hubs/widgets/subscriptions/templates/root.html b/hubs/widgets/subscriptions/templates/root.html deleted file mode 100644 index 248d86f..0000000 --- a/hubs/widgets/subscriptions/templates/root.html +++ /dev/null @@ -1,15 +0,0 @@ -{% if associations %} - - {% if memberships %} -

Belongs to: {{memberships_text}}

- {% endif %} -
- {% if subscriptions %} -

Subscribes to: - {% for subscription in subscriptions %} - - {{subscription}} - {% endfor %}

- {% endif %} - -{% endif %} From e766f5329fc4cfa7a54eed55e99a84879d8a7b24 Mon Sep 17 00:00:00 2001 From: Ryan Lerch Date: Nov 24 2017 06:39:10 +0000 Subject: [PATCH 2/2] implement my hubs widget as per the mockup a rework of the hubs widget to match the mockup, including a rename from "subscriptions" to "my_hubs" fixes #436 Signed-off-by: Ryan Lerch --- diff --git a/hubs/defaults.py b/hubs/defaults.py index c4e3539..5f8f22d 100644 --- a/hubs/defaults.py +++ b/hubs/defaults.py @@ -40,7 +40,7 @@ def add_user_widgets(session, hub, username, fullname): })) hub.widgets.append(widget) widget = hubs.models.Widget( - plugin='subscriptions', index=3, + plugin='my_hubs', index=3, _config=json.dumps({ 'username': username, })) diff --git a/hubs/static/css/style.css b/hubs/static/css/style.css index f821195..90fd4df 100644 --- a/hubs/static/css/style.css +++ b/hubs/static/css/style.css @@ -390,3 +390,25 @@ header h5.m-b-1 { .small { font-size: small; } + +.monogram-avatar{ + width:64px; + height:64px; + font-size:54px; + line-height: 64px; + font-weight: 700; + text-align: center; +} + +/*Move these color defs into fedora-bootstrap*/ +.bg-fedora-blue{background-color:#3c6eb4;} +.bg-fedora-magenta{background-color: #db3279;} +.bg-fedora-orange{background-color: #e59728;} +.bg-fedora-green{background-color: #79db32;} +.bg-fedora-purple{background-color: #a07cbc;} +.text-fedora-blue-dark{color: #294a7a;} +.text-fedora-magenta-dark{color: #9a1b51;} +.text-fedora-orange-dark{color: #9a6213;} +.text-fedora-green-dark{color: #488b18;} +.text-fedora-purple-dark{color: #70488f;} + diff --git a/hubs/tests/widgets/test_my_hubs.py b/hubs/tests/widgets/test_my_hubs.py new file mode 100644 index 0000000..d5c0e44 --- /dev/null +++ b/hubs/tests/widgets/test_my_hubs.py @@ -0,0 +1,35 @@ +from __future__ import unicode_literals + +from . import WidgetTest +import hubs.models # noqa: E402 + + +class MyHubsTest(WidgetTest): + + plugin = "my_hubs" + + def populate(self): + super(MyHubsTest, self).populate() + self._add_widget_under_test() + hub = hubs.models.Hub.by_name('infra') + hub.subscribe(hubs.models.User.by_username('ralph'), 'owner') + + hub = hubs.models.Hub.by_name('i18n') + hub.subscribe(hubs.models.User.by_username('ralph'), 'subscriber') + + self.session.add(hubs.models.Hub(name="designteam")) + hub = hubs.models.Hub.by_name('designteam') + hub.subscribe(hubs.models.User.by_username('ralph'), 'member') + + def test_myhubs_output(self): + self._update_widget_config({ + "username": "ralph" + }) + func = self.widget.module.get_cached_functions()['GetSubs'] + result = func(self.widget).execute() + self.assertEquals(len(result['memberships']), 1) + self.assertEquals(len(result['ownerships']), 1) + self.assertEquals(len(result['subscriptions']), 1) + self.assertEquals(result['memberships'][0].name, "designteam") + self.assertEquals(result['ownerships'][0].name, "infra") + self.assertEquals(result['subscriptions'][0].name, "i18n") diff --git a/hubs/widgets/my_hubs/__init__.py b/hubs/widgets/my_hubs/__init__.py index c08f23d..eb0ef39 100644 --- a/hubs/widgets/my_hubs/__init__.py +++ b/hubs/widgets/my_hubs/__init__.py @@ -1,16 +1,11 @@ from __future__ import unicode_literals -import flask -from fedmsg.meta import msg2usernames -from fedmsg.meta.base import BaseConglomerator as BC +import hashlib import hubs.models from hubs.utils import get_fedmsg_config -from hubs.widgets import validators from hubs.widgets.base import Widget from hubs.widgets.view import RootWidgetView -from hubs.widgets.caching import CachedFunction - fedmsg_config = get_fedmsg_config() @@ -21,59 +16,50 @@ class MyHubs(Widget): position = "right" label = "My Hubs" hidden_if_empty = True - parameters = [ - dict( - name="username", - label="Username", - default=None, - validator=validators.Username, - help="A FAS username.", - )] hub_types = ['user'] class BaseView(RootWidgetView): def get_context(self, instance, *args, **kwargs): - context = {} - get_subs = GetSubs(instance) - context.update(get_subs()) - return context - - -# function hyperlinks the hubs in the subscription widget -def manage_subscriptions(items): - return [ - '{item}'.format( - link=flask.url_for('hub', name=item), - item=item, - ) for index, item in enumerate(items[0:3]) - ] + # since this widget only shows on user hubs, we assume + # hub.name == the username + username = instance.hub.name - -class GetSubs(CachedFunction): - - def execute(self): - username = self.instance.config["username"] user = hubs.models.User.by_username(username) - ownerships = [u.name for u in user.ownerships] - memberships = [u.name for u in user.memberships] - subscriptions = [u.name for u in user.subscriptions] - subscriptions_list = manage_subscriptions(subscriptions) - memberships_list = manage_subscriptions(memberships) + monograms = {} + ownerships = [] + assoc = [] + for hub in user.ownerships: + if not hub.user_hub: + ownerships.append(hub) + assoc.append(hub.name) + monograms[hub.name] = generate_monogram(hub.name) + memberships = [] + for hub in user.memberships: + if not hub.user_hub: + if hub.name not in assoc: + memberships.append(hub) + assoc.append(hub.name) + monograms[hub.name] = generate_monogram(hub.name) + subscriptions = [] + for hub in user.subscriptions: + if not hub.user_hub: + if hub.name not in assoc: + subscriptions.append(hub) + monograms[hub.name] = generate_monogram(hub.name) return dict( - associations=memberships + ownerships, ownerships=ownerships, memberships=memberships, subscriptions=subscriptions, - ownerships_text=BC.list_to_series(ownerships), - memberships_text=BC.list_to_series(memberships_list), - subscriptions_text=BC.list_to_series(subscriptions_list), + monograms=monograms, ) - def should_invalidate(self, message): - if not message['topic'].endswith('hubs.associate'): - return False - username = self.instance.config['username'] - users = msg2usernames(message, **fedmsg_config) - return username in users + +def generate_monogram(hubname): + colours = ["blue", "green", "magenta", "orange", "purple"] + colour_index = int(hashlib.md5(hubname.encode('utf8')).hexdigest(), 16) % 5 + return ("
" + "%s
") % (colours[colour_index], + colours[colour_index], + hubname[0].upper()) diff --git a/hubs/widgets/my_hubs/templates/root.html b/hubs/widgets/my_hubs/templates/root.html index 248d86f..a1f4311 100644 --- a/hubs/widgets/my_hubs/templates/root.html +++ b/hubs/widgets/my_hubs/templates/root.html @@ -1,15 +1,42 @@ -{% if associations %} - - {% if memberships %} -

Belongs to: {{memberships_text}}

- {% endif %} -
- {% if subscriptions %} -

Subscribes to: - {% for subscription in subscriptions %} - - {{subscription}} - {% endfor %}

- {% endif %} - -{% endif %} +
+
    + {% for ownership in ownerships %} +
  • +
    + {{monograms[ownership.name]}} +
    +
    + + Group Administrator +
    +
  • + {% endfor %} + {% for membership in memberships %} +
  • +
    + {{monograms[membership.name]}} +
    +
    + + Member +
    +
  • + {% endfor %} + {% for subscription in subscriptions %} +
  • +
    + {{monograms[subscription.name]}} +
    +
    + + Subscribed +
    +
  • + {% endfor %} +