From 4a9f6c215fb3fefc360ac0fc5d196e2064a4a3c4 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Feb 13 2017 11:23:17 +0000 Subject: [PATCH 1/9] Use the validators's return value for the widget conf The validators were returning a converted value (for example, to integer) but that value was ignored and the widgets had to do the conversion again themselves when they wanted to use that value. This changeset make use of the validators to convert to and from the string that was passed to the config form. --- diff --git a/hubs/templates/add_widget.html b/hubs/templates/add_widget.html index cb3f04d..38f0467 100644 --- a/hubs/templates/add_widget.html +++ b/hubs/templates/add_widget.html @@ -25,7 +25,7 @@
{{ param.label | capitalize }} {% if param.help %} {{ param.help }} diff --git a/hubs/templates/edit.html b/hubs/templates/edit.html index 928ea91..10c18d8 100644 --- a/hubs/templates/edit.html +++ b/hubs/templates/edit.html @@ -12,7 +12,7 @@
{{ param.label | capitalize }} {% if param.help %} {{ param.help }} diff --git a/hubs/validators.py b/hubs/validators.py index e065629..b59ca25 100644 --- a/hubs/validators.py +++ b/hubs/validators.py @@ -6,56 +6,101 @@ import hubs.models import requests -def required(session, value): - if bool(value): +class Validator(object): + + @classmethod + def from_string(cls, value): + if value is None: + return "" return value + @classmethod + def to_string(cls, value): + return value -def text(session, value): - return kitchen.text.converters.to_unicode(value) +class Required(Validator): -def integer(session, value): - return int(value) + @classmethod + def from_string(cls, value): + if not bool(value): + raise ValueError("the parameter is required") + return value -def link(session, value): - # TODO -- verify that this is actually a link - return value +class Text(Validator): + @classmethod + def from_string(cls, value): + return kitchen.text.converters.to_unicode(value) -def username(session, value): - if hubs.models.User.by_username(value) is not None: - return value - raise ValueError('Invalid username') +class Integer(Validator): -def github_organization(session, value): - # TODO -- implement this. - return value + @classmethod + def from_string(cls, value): + return int(value) -def github_repo(session, value): - # TODO -- implement this. - return value +class Link(Validator): -def fmn_context(session, value): - # TODO get this from the fedmsg config. - if value in [ - 'irc', 'email', 'android', 'desktop', 'hubs',]: + @classmethod + def from_string(cls, value): + # TODO -- verify that this is actually a link return value - raise ValueError('Invalid FMN context') -def pagure_repo(session, value): - response = requests.get("https://pagure.io/%s" % value, timeout=5) - if response.status_code == 200: +class Username(Validator): + + @classmethod + def from_string(cls, value): + if hubs.models.User.by_username(value) is not None: + return value + raise ValueError('Invalid username') + + +class GithubOrganization(Validator): + + @classmethod + def from_string(cls, value): + # TODO -- implement this. return value - raise ValueError('Invalid pagure repo') -def fedorahosted_project(session, value): - response = requests.get("https://fedorahosted.org/%s" % value, timeout=5) - if response.status_code == 200: +class GithubRepo(Validator): + + @classmethod + def from_string(cls, value): + # TODO -- implement this. return value - raise ValueError('Invalid fedorahosted project') + + +class FMNContext(Validator): + + @classmethod + def from_string(cls, value): + # TODO get this from the fedmsg config. + if value in [ + 'irc', 'email', 'android', 'desktop', 'hubs',]: + return value + raise ValueError('Invalid FMN context') + + +class PagureRepo(Validator): + + @classmethod + def from_string(cls, value): + response = requests.get("https://pagure.io/%s" % value, timeout=5) + if response.status_code == 200: + return value + raise ValueError('Invalid pagure repo') + + +class FedorahostedProject(Validator): + + @classmethod + def from_string(cls, value): + response = requests.get("https://fedorahosted.org/%s" % value, timeout=5) + if response.status_code == 200: + return value + raise ValueError('Invalid fedorahosted project') diff --git a/hubs/views/hub.py b/hubs/views/hub.py index 6641711..7b03d57 100644 --- a/hubs/views/hub.py +++ b/hubs/views/hub.py @@ -212,7 +212,7 @@ def hub_add_widget_post(name): error = True break try: - param.validator(flask.g.db, val) + val = param.validator.from_string(val) config[param.name] = val except Exception as err: flask.flash('Invalid data provided, error: %s' % err, 'error') diff --git a/hubs/views/widget.py b/hubs/views/widget.py index 192c44d..adc857a 100644 --- a/hubs/views/widget.py +++ b/hubs/views/widget.py @@ -48,7 +48,7 @@ def widget_edit_post(hub, idx): error = True break try: - val = param.validator(flask.g.db, val) + val = param.validator.from_string(val) config[param.name] = val except Exception as err: flask.flash('Invalid data provided, error: %s' % err, 'error') diff --git a/hubs/widgets/about/__init__.py b/hubs/widgets/about/__init__.py index bdb7e7b..5fe313c 100644 --- a/hubs/widgets/about/__init__.py +++ b/hubs/widgets/about/__init__.py @@ -13,7 +13,7 @@ class About(Widget): name="text", label="Text", default="I am a Fedora user, and this is my about", - validator=validators.text, + validator=validators.Text, help="Text about a user.", )] diff --git a/hubs/widgets/badges/__init__.py b/hubs/widgets/badges/__init__.py index 79315e1..1c102cb 100644 --- a/hubs/widgets/badges/__init__.py +++ b/hubs/widgets/badges/__init__.py @@ -16,7 +16,7 @@ class Badges(Widget): name="username", label="Username", default=None, - validator=validators.username, + validator=validators.Username, help="A FAS username.", )] diff --git a/hubs/widgets/bugzilla/__init__.py b/hubs/widgets/bugzilla/__init__.py index c63fa3c..5717e24 100644 --- a/hubs/widgets/bugzilla/__init__.py +++ b/hubs/widgets/bugzilla/__init__.py @@ -19,7 +19,7 @@ class Bugzilla(Widget): name="username", label="Username", default=None, - validator=validators.username, + validator=validators.Username, help="A FAS username.", )] diff --git a/hubs/widgets/dummy/__init__.py b/hubs/widgets/dummy/__init__.py index ca4bac8..daa0600 100644 --- a/hubs/widgets/dummy/__init__.py +++ b/hubs/widgets/dummy/__init__.py @@ -12,7 +12,7 @@ class Dummy(Widget): name="text", label="Text", default="Lorem ipsum dolor...", - validator=validators.text, + validator=validators.Text, help="Some dummy text to display.", )] diff --git a/hubs/widgets/fedmsgstats/__init__.py b/hubs/widgets/fedmsgstats/__init__.py index 142548f..4887af8 100644 --- a/hubs/widgets/fedmsgstats/__init__.py +++ b/hubs/widgets/fedmsgstats/__init__.py @@ -21,7 +21,7 @@ class FedmsgStats(Widget): name="username", label="Username", default=None, - validator=validators.username, + validator=validators.Username, help="A FAS username.", )] diff --git a/hubs/widgets/feed/__init__.py b/hubs/widgets/feed/__init__.py index b1f8299..9180637 100644 --- a/hubs/widgets/feed/__init__.py +++ b/hubs/widgets/feed/__init__.py @@ -17,13 +17,13 @@ class Feed(Widget): "name": "username", "label": "Username", "default": None, - "validator": validators.username, + "validator": validators.Username, "help": "A FAS username.", }, { "name": "message_limit", "label": "Message limit", "default": 20, - "validator": validators.integer, + "validator": validators.Integer, "help": "Max number of feed messages to display.", }] diff --git a/hubs/widgets/fhosted/__init__.py b/hubs/widgets/fhosted/__init__.py index 8f60efa..49a7955 100644 --- a/hubs/widgets/fhosted/__init__.py +++ b/hubs/widgets/fhosted/__init__.py @@ -16,13 +16,13 @@ class FedoraHosted(Widget): name="project", label="Project", default=None, - validator=validators.fedorahosted_project, + validator=validators.FedorahostedProject, help="Name of the trac instance on fedorahosted.org.", ), dict( name="n_tickets", label="Number of tickets", default=4, - validator=validators.integer, + validator=validators.Integer, help="The number of tickets to display.", )] @@ -48,7 +48,7 @@ class GetTickets(CachedFunction): Queries Fedorahosted via xmlrpc for tickets. ''' def execute(self): - n_tickets = int(self.instance.config["n_tickets"]) + n_tickets = self.instance.config["n_tickets"] url = 'https://fedorahosted.org/%s/rpc' \ % self.instance.config["project"] filters = 'status=accepted&status=assigned&status=new&status=reopened'\ diff --git a/hubs/widgets/github_pr/__init__.py b/hubs/widgets/github_pr/__init__.py index 6961d4a..d794c24 100644 --- a/hubs/widgets/github_pr/__init__.py +++ b/hubs/widgets/github_pr/__init__.py @@ -22,13 +22,13 @@ class GitHubPRs(Widget): name="organization", label="Organization", default=None, - validator=validators.github_organization, + validator=validators.GithubOrganization, help="Github Organization or username", ), dict( name="display_number", label="Number of tickets", default=6, - validator=validators.integer, + validator=validators.Integer, help="How many pull requests to display at max.", )] @@ -42,10 +42,9 @@ class BaseView(WidgetView): def get_context(self, instance, *args, **kwargs): get_prs = GetPRs(instance) org = instance.config["organization"] - display_number = int(instance.config["display_number"]) context = dict( organization=org, - display_number=display_number, + display_number=instance.config["display_number"], title="Github: Pull Requests", ) context.update(get_prs()) @@ -56,7 +55,7 @@ class GetPRs(CachedFunction): def execute(self): org = self.instance.config["organization"] - display_number = int(self.instance.config["display_number"]) + display_number = self.instance.config["display_number"] log.info("Getting GH prs for %r, (%r)" % (org, display_number)) token = fedmsg_config.get('github.oauth_token') pulls = [] diff --git a/hubs/widgets/githubissues/__init__.py b/hubs/widgets/githubissues/__init__.py index e29faa7..7172dbb 100644 --- a/hubs/widgets/githubissues/__init__.py +++ b/hubs/widgets/githubissues/__init__.py @@ -16,19 +16,19 @@ class GitHubIssues(Widget): name="org", label="Username", default=None, - validator=validators.github_organization, + validator=validators.GithubOrganization, help="Github Organization or username", ), dict( name="repo", label="Repository", default=None, - validator=validators.github_repo, + validator=validators.GithubRepo, help="Github repository", ), dict( name="display_number", label="Number of tickets", default=10, - validator=validators.integer, + validator=validators.Integer, help="The number of tickets to display.", )] @@ -44,7 +44,7 @@ class BaseView(WidgetView): return dict( org=instance.config["org"], repo=instance.config["repo"], - display_number=int(instance.config["display_number"]), + display_number=instance.config["display_number"], title="Github: Newest Open Tickets", all_issues=get_issues(), ) diff --git a/hubs/widgets/library/__init__.py b/hubs/widgets/library/__init__.py index 351ec4f..bab0ab4 100644 --- a/hubs/widgets/library/__init__.py +++ b/hubs/widgets/library/__init__.py @@ -13,7 +13,7 @@ class Library(Widget): name="urls", label="URLs", default=None, - validator=validators.text, + validator=validators.Text, help="A comma separated list of URLs to add to the library. " "External links must include the whole link " "(starting with http...)." diff --git a/hubs/widgets/linechart/__init__.py b/hubs/widgets/linechart/__init__.py index dfae632..0da1cb7 100644 --- a/hubs/widgets/linechart/__init__.py +++ b/hubs/widgets/linechart/__init__.py @@ -12,7 +12,7 @@ class Linechart(Widget): name="username", label="Username", default=None, - validator=validators.username, + validator=validators.Username, help="A FAS username.", )] diff --git a/hubs/widgets/meetings/__init__.py b/hubs/widgets/meetings/__init__.py index 01908ce..fbe712a 100644 --- a/hubs/widgets/meetings/__init__.py +++ b/hubs/widgets/meetings/__init__.py @@ -20,13 +20,13 @@ class Meetings(Widget): name="calendar", label="Calendar", default=None, - validator=validators.required, + validator=validators.Required, help="A fedocal calendar.", ), dict( name="n_meetings", label="Number of meetings", default=4, - validator=validators.integer, + validator=validators.Integer, help="The number of meetings to display.", )] @@ -56,7 +56,7 @@ class GetMeetings(CachedFunction): def execute(self): calendar = self.instance.config["calendar"] - n_meetings = int(self.instance.config.get("n_meetings", 4)) + n_meetings = self.instance.config.get("n_meetings", 4) base = ('https://apps.fedoraproject.org/calendar/api/meetings/' '?calendar=%s') url = base % calendar diff --git a/hubs/widgets/pagure_pr/__init__.py b/hubs/widgets/pagure_pr/__init__.py index 518d12d..1ace710 100644 --- a/hubs/widgets/pagure_pr/__init__.py +++ b/hubs/widgets/pagure_pr/__init__.py @@ -18,7 +18,7 @@ class PagurePRs(Widget): name="repo", label="Repository", default=None, - validator=validators.pagure_repo, + validator=validators.PagureRepo, help="Pagure repo name.", )] diff --git a/hubs/widgets/pagureissues/__init__.py b/hubs/widgets/pagureissues/__init__.py index 356d59f..f8df811 100644 --- a/hubs/widgets/pagureissues/__init__.py +++ b/hubs/widgets/pagureissues/__init__.py @@ -18,7 +18,7 @@ class PagureIssues(Widget): name="repo", label="Repository", default=None, - validator=validators.pagure_repo, + validator=validators.PagureRepo, help="Pagure repo name", )] diff --git a/hubs/widgets/rules/__init__.py b/hubs/widgets/rules/__init__.py index 498e3a8..5c207a3 100644 --- a/hubs/widgets/rules/__init__.py +++ b/hubs/widgets/rules/__init__.py @@ -19,25 +19,25 @@ class Rules(Widget): name="link", label="Link", default=None, - validator=validators.link, + validator=validators.Link, help="Link to the community rules and guidelines.", ), dict( name="schedule_text", label="Schedule text", default=None, - validator=validators.text, + validator=validators.Text, help="Some text about when meetings are.", ), dict( name="schedule_link", label="Schedule link", default=None, - validator=validators.link, + validator=validators.Link, help="Link to a schedule for IRC meetings, etc.", ), dict( name="minutes_link", label="Minutes link", default=None, - validator=validators.link, + validator=validators.Link, help="Link to meeting menutes from past meetings.", )] diff --git a/hubs/widgets/sticky/__init__.py b/hubs/widgets/sticky/__init__.py index 3f038ba..3fcccfc 100644 --- a/hubs/widgets/sticky/__init__.py +++ b/hubs/widgets/sticky/__init__.py @@ -13,7 +13,7 @@ class Sticky(Widget): name="text", label="Text", default="Lorem ipsum dolor...", - validator=validators.text, + validator=validators.Text, help="Some dummy text to display.", )] diff --git a/hubs/widgets/subscriptions/__init__.py b/hubs/widgets/subscriptions/__init__.py index 1641191..b427ad5 100644 --- a/hubs/widgets/subscriptions/__init__.py +++ b/hubs/widgets/subscriptions/__init__.py @@ -22,7 +22,7 @@ class Subscriptions(Widget): name="username", label="Username", default=None, - validator=validators.username, + validator=validators.Username, help="A FAS username.", )] diff --git a/hubs/widgets/workflow/pendingacls.py b/hubs/widgets/workflow/pendingacls.py index 07fd52b..1c926d5 100644 --- a/hubs/widgets/workflow/pendingacls.py +++ b/hubs/widgets/workflow/pendingacls.py @@ -17,7 +17,7 @@ class PendingACLs(Widget): name="username", label="Username", default=None, - validator=validators.username, + validator=validators.Username, help="A FAS username.", )] diff --git a/hubs/widgets/workflow/updates2stable.py b/hubs/widgets/workflow/updates2stable.py index 79fac1f..92a56dd 100644 --- a/hubs/widgets/workflow/updates2stable.py +++ b/hubs/widgets/workflow/updates2stable.py @@ -21,7 +21,7 @@ class Updates2Stable(Widget): name="username", label="Username", default=None, - validator=validators.username, + validator=validators.Username, help="A FAS username.", )] From 2b79f4b88ee5fb8c018c8baa3fea0db9bf893ed3 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Feb 13 2017 11:29:37 +0000 Subject: [PATCH 2/9] Move validators to the widgets module Validators are actually only used by widgets, it makes more sense to have them with the other widget-related modules. --- diff --git a/hubs/validators.py b/hubs/validators.py deleted file mode 100644 index b59ca25..0000000 --- a/hubs/validators.py +++ /dev/null @@ -1,106 +0,0 @@ -from __future__ import unicode_literals - -import kitchen.text.converters - -import hubs.models -import requests - - -class Validator(object): - - @classmethod - def from_string(cls, value): - if value is None: - return "" - return value - - @classmethod - def to_string(cls, value): - return value - - -class Required(Validator): - - @classmethod - def from_string(cls, value): - if not bool(value): - raise ValueError("the parameter is required") - return value - - -class Text(Validator): - - @classmethod - def from_string(cls, value): - return kitchen.text.converters.to_unicode(value) - - -class Integer(Validator): - - @classmethod - def from_string(cls, value): - return int(value) - - -class Link(Validator): - - @classmethod - def from_string(cls, value): - # TODO -- verify that this is actually a link - return value - - -class Username(Validator): - - @classmethod - def from_string(cls, value): - if hubs.models.User.by_username(value) is not None: - return value - raise ValueError('Invalid username') - - -class GithubOrganization(Validator): - - @classmethod - def from_string(cls, value): - # TODO -- implement this. - return value - - -class GithubRepo(Validator): - - @classmethod - def from_string(cls, value): - # TODO -- implement this. - return value - - -class FMNContext(Validator): - - @classmethod - def from_string(cls, value): - # TODO get this from the fedmsg config. - if value in [ - 'irc', 'email', 'android', 'desktop', 'hubs',]: - return value - raise ValueError('Invalid FMN context') - - -class PagureRepo(Validator): - - @classmethod - def from_string(cls, value): - response = requests.get("https://pagure.io/%s" % value, timeout=5) - if response.status_code == 200: - return value - raise ValueError('Invalid pagure repo') - - -class FedorahostedProject(Validator): - - @classmethod - def from_string(cls, value): - response = requests.get("https://fedorahosted.org/%s" % value, timeout=5) - if response.status_code == 200: - return value - raise ValueError('Invalid fedorahosted project') diff --git a/hubs/widgets/about/__init__.py b/hubs/widgets/about/__init__.py index 5fe313c..1de5e0c 100644 --- a/hubs/widgets/about/__init__.py +++ b/hubs/widgets/about/__init__.py @@ -1,9 +1,8 @@ from __future__ import unicode_literals +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView -from hubs import validators - class About(Widget): diff --git a/hubs/widgets/badges/__init__.py b/hubs/widgets/badges/__init__.py index 1c102cb..c609776 100644 --- a/hubs/widgets/badges/__init__.py +++ b/hubs/widgets/badges/__init__.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import operator import requests -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView from hubs.widgets.caching import CachedFunction diff --git a/hubs/widgets/bugzilla/__init__.py b/hubs/widgets/bugzilla/__init__.py index 5717e24..99d02f1 100644 --- a/hubs/widgets/bugzilla/__init__.py +++ b/hubs/widgets/bugzilla/__init__.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import requests import pkgwat.api -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView from hubs.widgets.caching import CachedFunction diff --git a/hubs/widgets/dummy/__init__.py b/hubs/widgets/dummy/__init__.py index daa0600..463e359 100644 --- a/hubs/widgets/dummy/__init__.py +++ b/hubs/widgets/dummy/__init__.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView diff --git a/hubs/widgets/fedmsgstats/__init__.py b/hubs/widgets/fedmsgstats/__init__.py index 4887af8..0b68bcb 100644 --- a/hubs/widgets/fedmsgstats/__init__.py +++ b/hubs/widgets/fedmsgstats/__init__.py @@ -5,8 +5,8 @@ import fedmsg.config import fedmsg.meta import requests -from hubs import validators from hubs.utils import commas +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView from hubs.widgets.caching import CachedFunction diff --git a/hubs/widgets/feed/__init__.py b/hubs/widgets/feed/__init__.py index 9180637..30b39eb 100644 --- a/hubs/widgets/feed/__init__.py +++ b/hubs/widgets/feed/__init__.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView import logging diff --git a/hubs/widgets/fhosted/__init__.py b/hubs/widgets/fhosted/__init__.py index 49a7955..7b83881 100644 --- a/hubs/widgets/fhosted/__init__.py +++ b/hubs/widgets/fhosted/__init__.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from six.moves.xmlrpc_client import ServerProxy -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView from hubs.widgets.caching import CachedFunction diff --git a/hubs/widgets/github_pr/__init__.py b/hubs/widgets/github_pr/__init__.py index d794c24..1d41502 100644 --- a/hubs/widgets/github_pr/__init__.py +++ b/hubs/widgets/github_pr/__init__.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import logging import hubs.utils -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView from hubs.widgets.caching import CachedFunction diff --git a/hubs/widgets/githubissues/__init__.py b/hubs/widgets/githubissues/__init__.py index 7172dbb..39d5aa0 100644 --- a/hubs/widgets/githubissues/__init__.py +++ b/hubs/widgets/githubissues/__init__.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import requests -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView from hubs.widgets.caching import CachedFunction diff --git a/hubs/widgets/library/__init__.py b/hubs/widgets/library/__init__.py index bab0ab4..e1d4511 100644 --- a/hubs/widgets/library/__init__.py +++ b/hubs/widgets/library/__init__.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals -from hubs import validators -from hubs.widgets import clean_input +from hubs.widgets import clean_input, validators from hubs.widgets.base import Widget, WidgetView diff --git a/hubs/widgets/linechart/__init__.py b/hubs/widgets/linechart/__init__.py index 0da1cb7..e9765ca 100644 --- a/hubs/widgets/linechart/__init__.py +++ b/hubs/widgets/linechart/__init__.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView diff --git a/hubs/widgets/meetings/__init__.py b/hubs/widgets/meetings/__init__.py index fbe712a..568a04b 100644 --- a/hubs/widgets/meetings/__init__.py +++ b/hubs/widgets/meetings/__init__.py @@ -5,8 +5,8 @@ import collections import datetime import requests -from hubs import validators from hubs import utils +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView from hubs.widgets.caching import CachedFunction diff --git a/hubs/widgets/pagure_pr/__init__.py b/hubs/widgets/pagure_pr/__init__.py index 1ace710..48c57a0 100644 --- a/hubs/widgets/pagure_pr/__init__.py +++ b/hubs/widgets/pagure_pr/__init__.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView from hubs.widgets.caching import CachedFunction diff --git a/hubs/widgets/pagureissues/__init__.py b/hubs/widgets/pagureissues/__init__.py index f8df811..7aa36c7 100644 --- a/hubs/widgets/pagureissues/__init__.py +++ b/hubs/widgets/pagureissues/__init__.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import requests -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView from hubs.widgets.caching import CachedFunction diff --git a/hubs/widgets/rules/__init__.py b/hubs/widgets/rules/__init__.py index 5c207a3..1ec9c09 100644 --- a/hubs/widgets/rules/__init__.py +++ b/hubs/widgets/rules/__init__.py @@ -2,8 +2,8 @@ from __future__ import unicode_literals from collections import OrderedDict as ordereddict -from hubs import validators from hubs.utils import username2avatar +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView diff --git a/hubs/widgets/sticky/__init__.py b/hubs/widgets/sticky/__init__.py index 3fcccfc..baec759 100644 --- a/hubs/widgets/sticky/__init__.py +++ b/hubs/widgets/sticky/__init__.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView diff --git a/hubs/widgets/subscriptions/__init__.py b/hubs/widgets/subscriptions/__init__.py index b427ad5..d6dd928 100644 --- a/hubs/widgets/subscriptions/__init__.py +++ b/hubs/widgets/subscriptions/__init__.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import flask import hubs.models -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView from hubs.widgets.caching import CachedFunction diff --git a/hubs/widgets/validators.py b/hubs/widgets/validators.py new file mode 100644 index 0000000..b59ca25 --- /dev/null +++ b/hubs/widgets/validators.py @@ -0,0 +1,106 @@ +from __future__ import unicode_literals + +import kitchen.text.converters + +import hubs.models +import requests + + +class Validator(object): + + @classmethod + def from_string(cls, value): + if value is None: + return "" + return value + + @classmethod + def to_string(cls, value): + return value + + +class Required(Validator): + + @classmethod + def from_string(cls, value): + if not bool(value): + raise ValueError("the parameter is required") + return value + + +class Text(Validator): + + @classmethod + def from_string(cls, value): + return kitchen.text.converters.to_unicode(value) + + +class Integer(Validator): + + @classmethod + def from_string(cls, value): + return int(value) + + +class Link(Validator): + + @classmethod + def from_string(cls, value): + # TODO -- verify that this is actually a link + return value + + +class Username(Validator): + + @classmethod + def from_string(cls, value): + if hubs.models.User.by_username(value) is not None: + return value + raise ValueError('Invalid username') + + +class GithubOrganization(Validator): + + @classmethod + def from_string(cls, value): + # TODO -- implement this. + return value + + +class GithubRepo(Validator): + + @classmethod + def from_string(cls, value): + # TODO -- implement this. + return value + + +class FMNContext(Validator): + + @classmethod + def from_string(cls, value): + # TODO get this from the fedmsg config. + if value in [ + 'irc', 'email', 'android', 'desktop', 'hubs',]: + return value + raise ValueError('Invalid FMN context') + + +class PagureRepo(Validator): + + @classmethod + def from_string(cls, value): + response = requests.get("https://pagure.io/%s" % value, timeout=5) + if response.status_code == 200: + return value + raise ValueError('Invalid pagure repo') + + +class FedorahostedProject(Validator): + + @classmethod + def from_string(cls, value): + response = requests.get("https://fedorahosted.org/%s" % value, timeout=5) + if response.status_code == 200: + return value + raise ValueError('Invalid fedorahosted project') diff --git a/hubs/widgets/workflow/pendingacls.py b/hubs/widgets/workflow/pendingacls.py index 1c926d5..40c19ec 100644 --- a/hubs/widgets/workflow/pendingacls.py +++ b/hubs/widgets/workflow/pendingacls.py @@ -2,8 +2,8 @@ from __future__ import unicode_literals import requests -from hubs import validators from hubs.utils import username2avatar +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView from hubs.widgets.caching import CachedFunction diff --git a/hubs/widgets/workflow/updates2stable.py b/hubs/widgets/workflow/updates2stable.py index 92a56dd..4f6f462 100644 --- a/hubs/widgets/workflow/updates2stable.py +++ b/hubs/widgets/workflow/updates2stable.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import requests -from hubs import validators +from hubs.widgets import validators from hubs.widgets.base import Widget, WidgetView from hubs.widgets.caching import CachedFunction From c0f410dff0895b4880782e06efd60109699b2697 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Feb 13 2017 11:59:22 +0000 Subject: [PATCH 3/9] Redirect when adding a widget succeeds --- diff --git a/hubs/tests/test_fedora_hubs_flask_api.py b/hubs/tests/test_fedora_hubs_flask_api.py index 9415590..61c909e 100644 --- a/hubs/tests/test_fedora_hubs_flask_api.py +++ b/hubs/tests/test_fedora_hubs_flask_api.py @@ -246,9 +246,10 @@ class HubsAPITest(hubs.tests.APPTest): user = tests.FakeAuthorization('ralph') with tests.auth_set(app, user): data = {'widget_name': 'about'} - result = self.app.post('/ralph/add', data=data, - follow_redirects=False) - self.assertEqual(result.status_code, 200) + result = self.app.post('/ralph/add', data=data) + self.assertEqual(result.status_code, 302) + self.assertEqual(urlparse(result.location).path, "/ralph/edit") + result = self.app.get('/ralph/edit') expected_str = '' self.assertIn(expected_str, result.get_data(as_text=True)) expected_str = 'Full Name: fullname: ralph' @@ -260,7 +261,9 @@ class HubsAPITest(hubs.tests.APPTest): data = {'widget_name': 'about', 'text': 'text of widget'} result = self.app.post('/ralph/add', data=data, follow_redirects=False) - self.assertEqual(result.status_code, 200) + self.assertEqual(result.status_code, 302) + self.assertEqual(urlparse(result.location).path, "/ralph/edit") + result = self.app.get('/ralph/edit') expected_str = '' self.assertIn(expected_str, result.get_data(as_text=True)) expected_str = 'Full Name: fullname: ralph' diff --git a/hubs/views/hub.py b/hubs/views/hub.py index 7b03d57..3da39d3 100644 --- a/hubs/views/hub.py +++ b/hubs/views/hub.py @@ -231,6 +231,4 @@ def hub_add_widget_post(name): 'Could not save the configuration to the database ' 'if the error persists, please warn an admin', 'error') - - return flask.render_template( - 'hubs.html', hub=hub, edit=True) + return flask.redirect(flask.url_for('hub_edit', name=hub.name)) From 6f743e24fe96e9f47fb008f1fccb4edf5ad2b7dd Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Feb 13 2017 11:59:22 +0000 Subject: [PATCH 4/9] Make the add and save buttons more visible --- diff --git a/hubs/templates/add_widget.html b/hubs/templates/add_widget.html index 38f0467..cf9d686 100644 --- a/hubs/templates/add_widget.html +++ b/hubs/templates/add_widget.html @@ -40,7 +40,7 @@ - diff --git a/hubs/templates/edit.html b/hubs/templates/edit.html index 10c18d8..de4613f 100644 --- a/hubs/templates/edit.html +++ b/hubs/templates/edit.html @@ -27,7 +27,7 @@ Close {% if widget.module.get_parameters() %} - {% endif %} From ace2200a6c1cd1b7c08ad16569a2333f8462bc1c Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Feb 14 2017 10:42:52 +0000 Subject: [PATCH 5/9] Add and fix documentation --- diff --git a/docs/api.rst b/docs/api.rst index 8cecb30..449b292 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -27,6 +27,13 @@ Widget class :members: :show-inheritance: +Widget parameter validators +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: hubs.widgets.validators + :members: + :show-inheritance: + Widget view ^^^^^^^^^^^ diff --git a/hubs/widgets/base.py b/hubs/widgets/base.py index ac50fd3..38da840 100644 --- a/hubs/widgets/base.py +++ b/hubs/widgets/base.py @@ -23,13 +23,19 @@ class WidgetParameter(object): :py:class:`WidgetParameter` objects returned by the widget's :py:meth:`~Widget.get_parameters` method. + The value of the parameter is stored in the database as the value returned + by the validator's :py:meth:`from_string` method. It can thus be a string, + an integer, a list, a dict, or any JSON-serializable value. + Attributes: name (str): The name of the parameter. label (str): A humanized name of the parameter, which will be shown in the UI. default: The default value if this parameter is not set. - validator (function): A validation function that will be called when - a user sets the parameter value. + validator (hubs.widgets.validators.Validator): A validator subclass + that will be used to convert the parameter value to and from + string, raising an exception if it is invalid. This attribute + points to the validator subclass, not an instance of the class. help (str): A help text that will be shown in the UI. """ diff --git a/hubs/widgets/validators.py b/hubs/widgets/validators.py index b59ca25..18b86fd 100644 --- a/hubs/widgets/validators.py +++ b/hubs/widgets/validators.py @@ -7,19 +7,42 @@ import requests class Validator(object): + """Convert widget parameters to and from string, and validate their value. + + Validators are used to convert + :py:class:`~hubs.widgets.base.WidgetParameter` values to and from string. + They will raise an exception if the value is invalid. + + A validator is a subclass of the :py:class:`Validator` class and implements + two class methods: :py:meth:`from_string` and :py:meth:`to_string`. + """ @classmethod def from_string(cls, value): + """Convert the value from a string to a JSON-serializable value. + + The result of this function will be stored in the database for widget + parameters. + + Raises: + ValueError: The value is invalid. + """ if value is None: return "" return value @classmethod def to_string(cls, value): + """Convert the value to a string. + + The result of this function will be used in the widget configuration + form fields. + """ return value class Required(Validator): + """Raises an error if the value is ``False``-like.""" @classmethod def from_string(cls, value): @@ -29,6 +52,7 @@ class Required(Validator): class Text(Validator): + """Raises an error if the value can't be converted to unicode.""" @classmethod def from_string(cls, value): @@ -36,6 +60,7 @@ class Text(Validator): class Integer(Validator): + """Raises an error if the value can't be converted to an integer.""" @classmethod def from_string(cls, value): @@ -43,6 +68,7 @@ class Integer(Validator): class Link(Validator): + """Raises an error if the value doesn't look like a link.""" @classmethod def from_string(cls, value): @@ -51,6 +77,13 @@ class Link(Validator): class Username(Validator): + """Raises an error if the value isn't an existing username. + + There must be a corresponding :py:class:`~hubs.models.User` record. + + This validator does not return the User instance because it is not + JSON-serializable, it returns the username unchanged. + """ @classmethod def from_string(cls, value): @@ -60,6 +93,7 @@ class Username(Validator): class GithubOrganization(Validator): + """Fails if the Github organization name does not exist.""" @classmethod def from_string(cls, value): @@ -68,6 +102,7 @@ class GithubOrganization(Validator): class GithubRepo(Validator): + """Fails if the Github repository name does not exist.""" @classmethod def from_string(cls, value): @@ -76,6 +111,7 @@ class GithubRepo(Validator): class FMNContext(Validator): + """Fails if the value is not a valid FMN context name.""" @classmethod def from_string(cls, value): @@ -87,6 +123,7 @@ class FMNContext(Validator): class PagureRepo(Validator): + """Fails if the Pagure repository name does not exist.""" @classmethod def from_string(cls, value): @@ -97,6 +134,7 @@ class PagureRepo(Validator): class FedorahostedProject(Validator): + """Fails if the FedoraHosted project name does not exist.""" @classmethod def from_string(cls, value): From a906b5984bcecdbc3725bf0d801545d3eba6f14a Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Feb 14 2017 10:42:52 +0000 Subject: [PATCH 6/9] Add two more assertions in the tests --- diff --git a/hubs/tests/test_fedora_hubs_flask_api.py b/hubs/tests/test_fedora_hubs_flask_api.py index 61c909e..2a53ba5 100644 --- a/hubs/tests/test_fedora_hubs_flask_api.py +++ b/hubs/tests/test_fedora_hubs_flask_api.py @@ -250,6 +250,7 @@ class HubsAPITest(hubs.tests.APPTest): self.assertEqual(result.status_code, 302) self.assertEqual(urlparse(result.location).path, "/ralph/edit") result = self.app.get('/ralph/edit') + self.assertEqual(result.status_code, 200) expected_str = '' self.assertIn(expected_str, result.get_data(as_text=True)) expected_str = 'Full Name: fullname: ralph' @@ -264,6 +265,7 @@ class HubsAPITest(hubs.tests.APPTest): self.assertEqual(result.status_code, 302) self.assertEqual(urlparse(result.location).path, "/ralph/edit") result = self.app.get('/ralph/edit') + self.assertEqual(result.status_code, 200) expected_str = '' self.assertIn(expected_str, result.get_data(as_text=True)) expected_str = 'Full Name: fullname: ralph' From 6e4ad75b5699756d886f0a1dd93dd4c47d2da2cc Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Feb 14 2017 11:01:53 +0000 Subject: [PATCH 7/9] Add unittests for validators --- diff --git a/hubs/tests/test_widget_validators.py b/hubs/tests/test_widget_validators.py new file mode 100644 index 0000000..567c60f --- /dev/null +++ b/hubs/tests/test_widget_validators.py @@ -0,0 +1,69 @@ +from __future__ import unicode_literals + +import six +import unittest + +from hubs.widgets import validators + +#from mock import Mock +from hubs.tests import APPTest +from hubs.models import User + + +class ValidatorsTest(APPTest): + + def test_required(self): + self.assertRaises(ValueError, validators.Required.from_string, "") + + def test_text(self): + self.assertEqual(validators.Text.from_string("\xe9"), "\xe9") + + def test_integer(self): + self.assertEqual(validators.Integer.from_string("1"), 1) + self.assertRaises(ValueError, validators.Integer.from_string, "text") + + @unittest.skip("Not implemented yet") + def test_link(self): + value = 'dummy' + self.assertEqual(validators.Link.from_string(value), value) + self.assertRaises(ValueError, validators.Link.from_string, "text") + + def test_username(self): + self.assertEqual(validators.Username.from_string("ralph"), "ralph") + self.assertRaises(ValueError, validators.Username.from_string, "nobody") + + @unittest.skip("Not implemented yet") + def test_github_organization(self): + self.assertEqual( + validators.GithubOrganization.from_string("fedora-infra"), + "fedora-infra") + self.assertRaises( + ValueError, + validators.GithubOrganization.from_string, + "something-that-does-not-exist") + + @unittest.skip("Not implemented yet") + def test_github_repo(self): + self.assertEqual( + validators.GithubRepo.from_string("fedmsg"), "fedmsg") + self.assertRaises(ValueError, validators.GithubRepo.from_string, + "something-that-does-not-exist") + + def test_fmncontext(self): + self.assertEqual(validators.FMNContext.from_string("email"), "email") + self.assertRaises( + ValueError, validators.FMNContext.from_string, "dummy") + + def test_pagure_repo(self): + self.assertEqual( + validators.PagureRepo.from_string("fedora-hubs"), "fedora-hubs") + self.assertRaises(ValueError, validators.PagureRepo.from_string, + "something-that-does-not-exist") + + def test_fedorahosted_project(self): + self.assertEqual( + validators.FedorahostedProject.from_string("about-fedora"), + "about-fedora") + self.assertRaises( + ValueError, validators.FedorahostedProject.from_string, + "something-that-does-not-exist") diff --git a/hubs/tests/vcr-request-data/hubs.tests.test_widget_validators.ValidatorsTest.test_fedorahosted_project b/hubs/tests/vcr-request-data/hubs.tests.test_widget_validators.ValidatorsTest.test_fedorahosted_project new file mode 100644 index 0000000..3d8315c --- /dev/null +++ b/hubs/tests/vcr-request-data/hubs.tests.test_widget_validators.ValidatorsTest.test_fedorahosted_project @@ -0,0 +1,186 @@ +interactions: +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + User-Agent: [python-requests/2.13.0] + method: GET + uri: https://fedorahosted.org/about-fedora/ + response: + body: {string: "\n\n \n \n\n \n\n\n \n \n about-fedora\n \n\ + \ \n \n \n \n \n \n \n \n \n \n \n \n\ + \ \n \n \n
\n
\n \"Fedora\n
\n
\n
\n \n \n \n
\n
\n \n
\n \n
\n \n
\n

Context Navigation

\n \n
\n
\n
\n
\n \n \n\ + \
\n Last modified\ + \ 8 years ago\n \ + \ Last modified on 02/09/09 03:57:48\n\ + \
\n

What is this site?

\n

\nThis is the source project for About Fedora.\ + \ It includes a git repo and a database for tracking how we develop\ + \ the source toolchain. \n

\n

\nIt's all part of the \u200B\ + Fedora Project. This site, in particular, is run by the \u200BFedora Documentation team.\n

\n

\nIf you want\ + \ to look at what we've created, use the \"Browse Source\" link above and\ + \ to the right.\n

\n

About\ + \ Fedora has something missing or wrong.

\n

\nIf you need to tell us\ + \ that something is wrong in About Fedora, visit \u200BBugzilla.\ + \ File a bug against the product \"Fedora Documentation,\" component \"about-fedora\"\ + .\n

\n

I want to help with the content.

\n\ +

\nIf you want to help update the content of About Fedora, first \u200Bintroduce yourself to the Docs Project.\ + \ When you've done that, \u200Bjoin our project group. Then visit\ + \ \u200Bthis page on the Fedora Project wiki\ + \ to find out how to get started using git. These instructions should\ + \ work for most people with access to this repository:\n

\n
cd ~/projects/\ngit clone ssh://<username>@git.fedorahosted.org/git/docs/about-fedora.git\n\
+        git clone git://git.fedorahosted.org/git/fedora-doc-utils docs-common\n

\n\ + If you don't have access to this repo, use git:// instead of ssh://\ + \ above.\n

\n

I want\ + \ to translate the content to my language.

\n

\nCheck the \u200Bstatistics page to get details about\ + \ your language and join the \u200BFedora Translation team if your language\ + \ is not available.\n

\n

I'm confused.\ + \ What is this site for?

\n

\nIf you have questions, come visit the\ + \ Docs Project on IRC. IRC is a way to communicate in real time with other\ + \ Fedora Project members. You can find more information \u200Bhere.\n

\n
\n \n \n
\n\ + \ \n\n
\n
\n

Download in other\ + \ formats:

\n \n
\n
\n

\n \"Trac\n

Powered by Trac 0.12.5\n By Edgewall Software.Libravatar support by Tracvatar 1.9

\n

Visit the Trac open source\ + \ project at
http://trac.edgewall.org/

\n\ + \
\n \n \n\ + \ \n \n \n"} + headers: + cache-control: [must-revalidate] + connection: [Keep-Alive] + content-length: ['9437'] + content-type: [text/html;charset=utf-8] + date: ['Tue, 14 Feb 2017 10:57:38 GMT'] + expires: ['Fri, 01 Jan 1999 00:00:00 GMT'] + keep-alive: ['timeout=5, max=500'] + server: [Apache/2.2.15 (Red Hat)] + set-cookie: [trac_form_token=8344c426dbc2cc320d5e431d; Path=/about-fedora, 'trac_session=808a3fc5547b36ddaca5f057; + expires=Mon, 15-May-2017 10:57:39 GMT; Path=/about-fedora'] + strict-transport-security: [max-age=15768000; includeSubDomains; preload] + status: {code: 200, message: Ok} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + User-Agent: [python-requests/2.13.0] + method: GET + uri: https://fedorahosted.org/something-that-does-not-exist/ + response: + body: {string: !!python/unicode ' + + + + 302 Found + + + +

Found

+ +

The document has moved here.

+ +
+ +
Apache/2.2.15 (Red Hat) Server at fedorahosted.org Port 443
+ + + + '} + headers: + connection: [Keep-Alive] + content-length: ['300'] + content-type: [text/html; charset=iso-8859-1] + date: ['Tue, 14 Feb 2017 10:57:40 GMT'] + keep-alive: ['timeout=5, max=500'] + location: ['https://fedorahosted.org/web/410'] + server: [Apache/2.2.15 (Red Hat)] + strict-transport-security: [max-age=15768000; includeSubDomains; preload] + status: {code: 302, message: Found} +version: 1 diff --git a/hubs/tests/vcr-request-data/hubs.tests.test_widget_validators.ValidatorsTest.test_pagure_repo b/hubs/tests/vcr-request-data/hubs.tests.test_widget_validators.ValidatorsTest.test_pagure_repo new file mode 100644 index 0000000..03a168e --- /dev/null +++ b/hubs/tests/vcr-request-data/hubs.tests.test_widget_validators.ValidatorsTest.test_pagure_repo @@ -0,0 +1,351 @@ +interactions: +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + User-Agent: [python-requests/2.13.0] + method: GET + uri: https://pagure.io/fedora-hubs + response: + body: {string: "\n\n\n \n Overview\ + \ - fedora-hubs - Pagure\n \n \n \n \n \n \n \n \n \n \n
\n
\n
\n\ + \ \n \ + \
\n
\n\n \n
\n \n
\n \n\n\ + \
\n
\n
\n
\n
\n\n
\n\n\n
\n
\n
\n \n \nfedora-hubs\n\ + \ \n
\nFedora Hubs\ + \  |  https://hubs-dev.fedorainfracloud.org/
\n\n
\n\ + \ \n
\n\ +
\n\n
\n
\n \ + \
\n
\n \ + \
\n

Fedora Hubs

\n

Fedora Hubs\ + \ will provide a communication and collaboration center for Fedora\ncontributors\ + \ of all types. The idea is that contributors will be able to visit\nHubs\ + \ to check on their involvements across Fedora, discover new places that they\n\ + can contribute, and more.

\n

Hubs is currently under development, and\ + \ you can see the progress on the\nDevelopment instance here: https://hubs-dev.fedorainfracloud.org/

\n
\n\ +

Get Involved

\n

Visit our mailing list\nand join us in the #fedora-hubs\ + \ IRC channel on irc.freenode.net. Meetings are held\nweekly in #fedora-hubs at 14:00UTC and the minutes for\ + \ every meeting are\narchived.\nIn the meetings we review our statuses from the preceding\ + \ week and do ticket triage, too.

\n

For a more detailed overview of\ + \ what Fedora Hubs is, see the\ndocumentation.

\n

To set up a development environment and start\ + \ contributing, check out\nthe development guide.

\n
\n
\n\n
\n \ + \
\n
\n
\n
\n
Owners
\n\ + \ \n
Branches
\n\ + \
\n
\n
\n \n \ + \ develop\n
\n
\n \n \ + \
\n
\n\n
\n \n\ + \
\n
\n\ + \
\n
\n
\n \n\ + \ fix_fedmsgstats\n\ + \ \n\n
\n
\n
\n
\n \ + \
\n
\n \ + \ \n \ + \ jenkins\n \ + \ \n\n
\n
\n
\n
\n \ + \
\n \ + \
\n \n \ + \ master\n \n\ + \n
\n
\n
\n
\n
\n \ + \
\n \n unittest\n \n\n \ + \
\n
\n \ + \
\n
\n
\n
Source\ + \ GIT URLs more
\n\ + \
\n
\n \ + \
\n
SSH
\n \n\ + \
\n
\n
\n
\n\ + \
GIT
\n \ + \ \n
\n
\n \n
Docs\ + \ GIT URLs
\n
\n \ + \
\n \ + \
GIT
\n \ + \ \n
\n
\n \ + \
\n
\n
\n
\n created 2\ + \ years ago\n
\n
\n\n \n
\n \ + \
\n
\n\n\n\n \n\n
\n
\n

\n Copyright © 2014-2017 Red Hat\n \ + \ pagure —\n 2.12.1\ + \ — Documentation\n\ + \

\n

SSH Hostkey/Fingerprint

\n\ + \
\n
\n\n \n \n \n \n\n\n\n\ + \n\n\n\n"} + headers: + connection: [Keep-Alive] + content-length: ['21185'] + content-type: [text/html; charset=utf-8] + date: ['Tue, 14 Feb 2017 10:48:02 GMT'] + keep-alive: ['timeout=5, max=100'] + server: [Apache/2.4.6 (Red Hat Enterprise Linux) OpenSSL/1.0.1e-fips mod_wsgi/3.4 + Python/2.7.5] + set-cookie: ['pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmIjp7IiBiIjoiTTJSallqTmlaak16T1ROaE4yWTNOekZpWkdNeFptRTVZek13Wm1FM01ETTBaV1E0WlRFMU1BPT0ifX0.C4Rx4g.oLbGmDy2SdBOneLnLMwKWvCQ5WY; + Expires=Fri, 17-Mar-2017 10:48:02 GMT; Secure; HttpOnly; Path=/'] + strict-transport-security: [max-age=15768000; includeSubDomains; preload] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + User-Agent: [python-requests/2.13.0] + method: GET + uri: https://pagure.io/something-that-does-not-exist + response: + body: {string: !!python/unicode "\n\n\n \ + \ \n Page not found :'( - Pagure\n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n \n \"pagure\n \n
\n
\n
\n\n \n\ + \n
\n
\n
\n
\n \ + \ \n\n
\n\n\ + \n
\n
\n
\n

Page not found (404)

\n

With the message:

\n\ + \
\n

Project not found

\n
\n\ + \

You have either entered a bad URL or the page has moved, removed,\ + \ or otherwise rendered unavailable.
\n Please use the main navigation\ + \ menu to get (re)started.

\n
\n
\n
\n
\n\ + \n
\n
\n

\n Copyright ©\ + \ 2014-2017 Red Hat\n pagure\ + \ —\n 2.12.1 — Documentation\n

\n

SSH Hostkey/Fingerprint

\n
\n
\n\n \n \n\ + \ \n \n \n\n\n\n\ + "} + headers: + connection: [Keep-Alive] + content-length: ['3009'] + content-type: [text/html; charset=utf-8] + date: ['Tue, 14 Feb 2017 10:48:03 GMT'] + keep-alive: ['timeout=5, max=100'] + server: [Apache/2.4.6 (Red Hat Enterprise Linux) OpenSSL/1.0.1e-fips mod_wsgi/3.4 + Python/2.7.5] + set-cookie: ['pagure=eyJfcGVybWFuZW50Ijp0cnVlfQ.C4Rx4w.okkFK2vKErtBTg2N2mPN4XPMTVc; + Expires=Fri, 17-Mar-2017 10:48:03 GMT; Secure; HttpOnly; Path=/'] + strict-transport-security: [max-age=15768000; includeSubDomains; preload] + status: {code: 404, message: NOT FOUND} +version: 1 diff --git a/hubs/widgets/validators.py b/hubs/widgets/validators.py index 18b86fd..349fdb9 100644 --- a/hubs/widgets/validators.py +++ b/hubs/widgets/validators.py @@ -138,7 +138,8 @@ class FedorahostedProject(Validator): @classmethod def from_string(cls, value): - response = requests.get("https://fedorahosted.org/%s" % value, timeout=5) + response = requests.get("https://fedorahosted.org/%s/" % value, + timeout=5, allow_redirects=False) if response.status_code == 200: return value raise ValueError('Invalid fedorahosted project') From 7a1d24830fa3dfbf2327553cf6b128798a6a752e Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Feb 16 2017 14:08:54 +0000 Subject: [PATCH 8/9] Cleanup blank spaces --- diff --git a/hubs/widgets/validators.py b/hubs/widgets/validators.py index 349fdb9..99290b3 100644 --- a/hubs/widgets/validators.py +++ b/hubs/widgets/validators.py @@ -23,9 +23,9 @@ class Validator(object): The result of this function will be stored in the database for widget parameters. - + Raises: - ValueError: The value is invalid. + ValueError: The value is invalid. """ if value is None: return "" From 7e5de7c42ac5aa506fa0a8eebda42e52af39c739 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Feb 16 2017 14:08:54 +0000 Subject: [PATCH 9/9] Provide a sensible default for the Username validator --- diff --git a/hubs/widgets/validators.py b/hubs/widgets/validators.py index 99290b3..9c96320 100644 --- a/hubs/widgets/validators.py +++ b/hubs/widgets/validators.py @@ -1,8 +1,8 @@ from __future__ import unicode_literals -import kitchen.text.converters - +import flask import hubs.models +import kitchen.text.converters import requests @@ -91,6 +91,12 @@ class Username(Validator): return value raise ValueError('Invalid username') + @classmethod + def to_string(cls, value): + if value is None and flask.g.auth.logged_in: + return flask.g.auth.user.username + return value + class GithubOrganization(Validator): """Fails if the Github organization name does not exist."""