Exemple #1
0
class LiveFeedWidget(LiveWidget):
    """ A live streaming feed widget """

    url = twc.Param("The feed URL")
    topic = twc.Param("A topic or list of topics to subscribe to")
    feed = twc.Param("A moksha Feed object")
    d = twc.Param("The widget data")
    limit = twc.Param("The number of entries to display")

    template = "mako:mako:moksha.feeds.widgets.templates.live"
    onmessage = """
        $.each(json, function() {
            $("#${id} ul li:last").remove();
            $("<li/>").html(
                $("<a/>")
                  .attr("href", this.link)
                  .text(this.title))
              .prependTo($("#${id} ul"));
        });
    """
    feed = Feed()
    topic = None
    limit = 10

    def prepare(self):
        if not getattr(self, 'topic', None):
            self.topic = 'feed.%s' % d.get('url', self.url)
        super(LiveFeedWidget, self).prepare()
        self.d = self  # Wha?
class InputField(FormField):
    """A generic <input> field.
    
    Generally you won't use this one, but will rely
    on one of its specialised subclasses like :class:`.TextField`
    or :class:`Checkbox`.
    """
    type = twc.Variable('Type of input field',
                        default=twc.Required,
                        attribute=True)  #: Input type

    value = twc.Param(attribute=True)  #: Current value of the input

    required = twc.Param(
        'Input field is required', attribute=True,
        default=None)  #: Add required attributed to the input.

    autofocus = twc.Param(
        'Autofocus form field (HTML5 only)', attribute=True,
        default=None)  #: Add autofocus attributed to the input.

    template = "tw2.forms.templates.input_field"

    def prepare(self):
        super(InputField, self).prepare()
        self.safe_modify('attrs')
        self.attrs['required'] = 'required' if self.required in [
            True, 'required'
        ] else None
        self.required = None  # Needed because self.required would otherwise overwrite self.attrs['required'] again
class ReleaseFilter(twc.Widget):
    on_change = twc.Param(
        'The name of the javascript function to call upon change')
    package = twc.Param('The name of the package')
    template = 'mako:fedoracommunity.widgets.package.templates.release_filter'

    def prepare(self):
        super(ReleaseFilter, self).prepare()
        releases = []
        top_repo = os.path.join(config.get('git_repo_path'), self.package)
        pkgdb = get_connector('pkgdb')
        collections = pkgdb.get_collection_table(active_only=True)
        for id, collection in collections.iteritems():
            name = collection['name']
            ver = collection['version']
            label = "%s %s" % (name, ver)
            value = ""
            branchname = collection['gitbranchname']
            if branchname:
                repo_path = os.path.join(top_repo, branchname)
                if not os.path.isdir(repo_path):
                    continue
                value = branchname
            if label != 'Fedora devel' and name in ('Fedora', 'Fedora EPEL'):
                releases.append({
                    'label': label,
                    'value': value,
                    'version': ver,
                })
        self.releases_table = sorted(
            releases,
            reverse=True,
            cmp=lambda x, y: cmp(x['version'], y['version']))
        self.releases_table.insert(0, {'label': 'Rawhide', 'value': 'master'})
Exemple #4
0
class ButtonSetRadio(uibase.JQueryUIWidget):
    """
    Styles a group of radio buttons as a 'button set' by calling
    ``.buttonset()`` on a common container.
    
    See the wrapped library's documentation for more information:
        http://jqueryui.com/demos/button/#radio
    """
    template = 'tw2.jqplugins.ui.templates.buttonset_radio'

    items = twc.Param("a list of dicts - required keys are 'id' and 'label'",
                      default=[])
    checked_item = twc.Param(
        "a single button may be marked as 'checked' by " +
        "passing its 'id' [as a string] to this parameter",
        default=None)
    jqmethod = "buttonset"

    def prepare(self):
        super(ButtonSetRadio, self).prepare()

        if not isinstance(self.items, list):
            raise ValueError, "'items' must be of type list"

        ids = [i['id'] for i in self.items]
        if self.checked_item and self.checked_item not in ids:
            raise ValueError, "A 'checked_item' has been passed in but " + \
                              "the id to which it refers is not in the " + \
                              "'items' list"
Exemple #5
0
class WebSocketWidget(AbstractMokshaSocket):
    __shorthand__ = 'WebSocket'

    ws_host = twc.Param(default=twc.Required)
    ws_port = twc.Param(default=twc.Required)

    template = "mako:moksha.wsgi.widgets.api.websocket.templates.websocket"
Exemple #6
0
class CustomisedForm(twf.Form):
    """A form that allows specification of several useful client-side behaviours."""
    blank_deleted = twc.Param(
        'Blank out any invisible form fields before submitting. This is needed for GrowingGrid.',
        default=True)
    disable_enter = twc.Param(
        'Disable the enter button (except with textarea fields). This reduces the chance of users accidentally submitting the form.',
        default=True)
    prevent_multi_submit = twc.Param(
        'When the user clicks the submit button, disable it, to prevent the user causing multiple submissions.',
        default=True)

    resources = [twc.JSLink(modname=__name__, filename="static/dynforms.js")]

    def prepare(self):
        super(CustomisedForm, self).prepare()
        if self.blank_deleted:
            self.safe_modify('attrs')
            self.attrs['onsubmit'] = 'twd_blank_deleted()'
        if self.disable_enter:
            self.safe_modify('resources')
            self.resources.append(
                twc.JSSource(src='document.onkeypress = twd_suppress_enter;'))
        if self.prevent_multi_submit:
            self.submit.safe_modify('attrs')
            self.submit.attrs['onclick'] = 'return twd_no_multi_submit(this);'
Exemple #7
0
class JQueryUIWidget(twc.Widget):
    """ Base JQueryUIWidget """
    _hide_docs = False
    resources = [jquery_ui_js, jquery_ui_css]

    jqmethod = twc.Variable("(str) Name of this widget's jQuery init method")
    selector = twc.Variable("(str) Escaped id.  jQuery selector.")

    options = twc.Param('(dict) A dict of options to pass to the widget',
                        default={})

    # TODO -- add all the events http://api.jquery.com/category/events/
    # TODO -- try to automatically generate IDs if not specified
    # TODO -- TBD, figure out if this actually makes sense for all ui things.

    events = twc.Param('(dict) (BETA) javascript callbacks for events',
                       default={})

    def prepare(self):
        if self.events is not None and not isinstance(self.events, dict):
            raise ValueError, 'Events parameter must be a dict'

        self.resources.append(jquery_ui_css(name=get_ui_theme_name()))

        if self.options is not None and not isinstance(self.options, dict):
            raise ValueError, 'Options parameter must be a dict'

        self.options = encoder.encode(self.options)
        super(JQueryUIWidget, self).prepare()
        if not hasattr(self, 'id') or 'id' not in self.attrs:
            raise ValueError, 'JQueryWidget must be supplied an id'
        self.selector = self.attrs['id'].replace(':', '\\\\:')
class Details(twc.Widget):
    template = 'mako:fedoracommunity.widgets.package.templates.details'
    kwds = twc.Param('Data passed in from the tabs')
    package_info = twc.Param('A dict containing package details from xapian')
    active_releases_widget = ActiveReleasesGrid

    def prepare(self):
        super(Details, self).prepare()
        package_name = self.kwds['package_name']
        xapian_conn = get_connector('xapian')
        result = xapian_conn.get_package_info(package_name)

        if result['name'] == package_name:
            self.summary = result['summary']
            self.description = result['description']
        else:
            for subpkg in result['sub_pkgs']:
                if subpkg['name'] == package_name:
                    self.summary = subpkg['summary']
                    self.description = subpkg['description']
                    break

        self.package_info = result

    def __repr__(self):
        return "<Details %s>" % self.kwds
Exemple #9
0
class TextArea(FormField):
    rows = twc.Param('Number of rows', default=None, attribute=True)
    cols = twc.Param('Number of columns', default=None, attribute=True)
    placeholder = twc.Param('Placeholder text (HTML5 Only)',
                            attribute=True,
                            default=None)
    template = "tw2.forms.templates.textarea"
Exemple #10
0
class AttributeDetails(twc.Widget):
    """
    Widget to present the details of the given Attribute
    """
    template = 'rnms.templates.widgets.attribute_details'
    attribute = twc.Param('The attribute record out of the DB query')
    extra = twc.Param('Additional data outside the DB query', default=None)
Exemple #11
0
class Column(twc.Widget):
    """A column in a DataTable. The TW id becomes the YUI key, and the TW key becomes the YUI field."""
    options = twc.Param(
        'Configuration options for the widget. See the YUI docs for available options.',
        default={})
    sortable = twc.Param('Is the column sortable?', default=True)
    resizeable = twc.Param('Is the column resizeable?', default=True)
    label = twc.Param('Label for the field. Auto generates this from the id',
                      default=twc.Auto)
    formatter = twc.Param(
        'Formatter function. Use a string like "currency" for a YUI built-in, or JSSymbol for a custom function.',
        default=None)

    def prepare(self):
        super(Column, self).prepare()
        self.safe_modify('options')

        self.options['sortable'] = self.sortable
        self.options['resizeable'] = self.resizeable
        if self.label is twc.Auto:
            self.label = twc.util.name2label(self.id)
        self.options['label'] = self.label
        self.options['key'] = self.id
        self.options['field'] = self.key
        if self.formatter:
            self.options['formatter'] = self.formatter
Exemple #12
0
class HTML5MinMaxMixin(twc.Widget):
    '''HTML5 mixin for input field value limits

    TODO: Configure server-side validator
    '''
    min = twc.Param('Minimum value for field', attribute=True, default=None)
    max = twc.Param('Maximum value for field', attribute=True, default=None)
Exemple #13
0
class PostlabeledInputField(InputField):
    """ Inherits InputField, but with a text
    label that follows the input field """
    text = twc.Param('Text to display after the field.')
    text_attrs = twc.Param('Dict of attributes to inject into the label.',
                           default={})
    template = "tw2.forms.templates.postlabeled_input_field"
Exemple #14
0
class LinkField(twc.Widget):
    """
    A dynamic link based on the value of a field. If either *link* or *text*
    contain a $, it is replaced with the field value. If the value is None,
    and there is no default, the entire link is hidden.
    """
    template = "tw2.forms.templates.link_field"
    link = twc.Param('Link target', default='')
    text = twc.Param('Link text', default='')
    value = twc.Param("Value to replace $ with in the link/text")
    escape = twc.Param('Whether text shall be html-escaped or not',
                       default=True)
    validator = twc.BlankValidator

    def prepare(self):
        super(LinkField, self).prepare()
        self.safe_modify('attrs')
        self.attrs['href'] = self.link.replace('$',
                                               six.text_type(self.value or ''))

        if '$' in self.text:
            self.text = \
                    self.value and \
                    self.text.replace('$', six.text_type(self.value)) or \
                    ''
Exemple #15
0
class FlatRRDProtoBarChart(tw2.protovis.conventional.BarChart, RRDFlatMixin):
    series_sorter = twc.Param("function to compare to data points for sorting",
                              default=None)
    prune_zeroes = twc.Param("hide zero-valued series?", default=False)
    p_data = twc.Variable("Internally produced")
    p_labels = twc.Variable("Internally produced")
    method = twc.Param(
        "Method for consolidating values.  Either 'sum' or 'average'",
        default='average')

    def prepare(self):
        data = self.flat_fetch()

        if self.series_sorter:
            data.sort(self.series_sorter)

        if not self.method in ['sum', 'average']:
            raise ValueError, "Illegal value '%s' for method" % self.method

        self.p_labels = [series['label'] for series in data]

        if self.method == 'sum':
            self.p_data = [
                sum([d[1] for d in series['data']]) for series in data
            ]
        elif self.method == 'average':
            self.p_data = [
                sum([d[1] for d in series['data']]) / len(series['data'])
                for series in data
            ]

        super(FlatRRDProtoBarChart, self).prepare()
class ReleaseFilter(twc.Widget):
    on_change = twc.Param('The name of the javascript function to call upon change')
    package = twc.Param('The name of the package')
    template = 'mako:fedoracommunity.widgets.package.templates.release_filter'

    def prepare(self):
        super(ReleaseFilter, self).prepare()
        releases = []
        top_repo = os.path.join(config.get('git_repo_path'), self.package)
        bodhi = get_connector('bodhi')

        for collection in bodhi.get_all_releases():
            if collection['state'] != 'current':
                continue
            name = collection['id_prefix']
            ver = collection['version']
            label = collection['long_name']
            value = ""
            branchname = collection['branch']
            if branchname:
                repo_path = os.path.join(top_repo, branchname)
                if not os.path.isdir(repo_path):
                    continue
                value = branchname
            if label != 'Fedora devel' and name in ('FEDORA', 'FEDORA-EPEL'):
                releases.append({
                    'label': label,
                    'value': value,
                    'version': ver,
                    })
        self.releases_table = sorted(releases, reverse=True,
                cmp=lambda x, y: cmp(x['version'], y['version']))
        self.releases_table.insert(0, {'label': 'Rawhide', 'value': 'master'})
Exemple #17
0
class Wysihtml5(twbf.TextArea):
    resources = [bootstrap_wysihtml5_js, bootstrap_wysihtml5_css]

    parser = twc.Param(
        'The set of parser rules to use. '
        'The simple parser contains only basic html5 tags, while the '
        'advanced parser contains more html5 tags and preserves some '
        'css classes. If you use the simple parser, the editor css is '
        'not strictly needed. '
        'If you set the parser to False, you completely disable parsing, '
        'which is potentially unsafe, but a lot more convenient.',
        default=True)

    # TODO: Color support
    # Explicitly disable stylesheets, because wysiwyg-color.css is fetched otherwise
    stylesheets = twc.Param(default=list())
    wysihtml5_args = twc.Param(default=dict())

    def prepare(self):
        super(Wysihtml5, self).prepare()
        wysihtml5_args = self.wysihtml5_args.copy()
        wysihtml5_args.update(stylesheets=self.stylesheets)
        if self.parser and self.parser in parsers:
            self.safe_modify('resources')
            self.resources.append(parsers[self.parser])
            wysihtml5_args.update(
                parserRules=twc.js_symbol('wysihtml5ParserRules'))
        if self.parser is False:
            wysihtml5_args.update(parser=twc.js_symbol(
                'function(elementOrHtml, rules, context, cleanUp) { return elementOrHtml; }'
            ))
        self.add_call(twj.jQuery(self.selector).wysihtml5(wysihtml5_args))
class MenuWidget(tw2.jqplugins.ui.base.JQueryUIWidget, twc.DisplayOnlyWidget):
    """ Slidey menu that I made just for you!

    This is *quite* alpha still.  Please play with it and enhance it if you
    like.

    options::

        - width:  -- the width of the menu.

    """

    resources = [
        tw2.jquery.jquery_js,
        tw2.jqplugins.ui.jquery_ui_js,
        tw2.jqplugins.ui.jquery_ui_css,
        base.slidey_js,
        base.slidey_css,
    ]

    template = "mako:tw2.slideymenu.templates.menu"

    items = twc.Param('A recursive dictionary of menu entries', default=[])
    label = twc.Param('Label for the menu-show button', default='Menu')
    options = twc.Param('Options.', default={})

    def prepare(self):
        super(MenuWidget, self).prepare()
        self._options = encoder.encode(self.options)
Exemple #19
0
class ChosenMixin(twc.Widget):
    '''Mixin for Chosen SelectFields'''
    resources = [chosen_js, chosen_css]

    selector = twc.Variable("Escaped id.  jQuery selector.")
    opts = twc.Variable(
        'Arguments for the javascript init function. '
        'See http://harvesthq.github.io/chosen/options.html',
        default=dict())

    placeholder = twc.Param('Placeholder text, prompting user for selection',
                            default='')
    no_results_text = twc.Param(
        'Text shown when the search term returned no results', default='')

    search_contains = twc.Param(
        'Allow matches starting from anywhere within a word.', default=False)

    def prepare(self):
        super(ChosenMixin, self).prepare()
        # put code here to run just before the widget is displayed
        if 'id' in self.attrs:
            self.selector = "#" + self.attrs['id'].replace(':', '\\:')

        if self.placeholder:
            self.attrs['data-placeholder'] = self.placeholder
        if self.no_results_text:
            self.opts['no_results_text'] = self.no_results_text
        if self.search_contains:
            self.opts['search_contains'] = True

        self.add_call(twj.jQuery(self.selector).chosen(self.opts))
Exemple #20
0
class HostDetails(twc.Widget):
    """
    Widget to present the details of the given host
    """
    template = 'rnms.templates.widgets.host_details'
    host = twc.Param('The host record out of the DB query')
    extra = twc.Param('Additional data outside the DB query', default=None)
Exemple #21
0
class OrbitedWidget(twc.Widget):
    onopen = twc.Param("A javascript callback for when the connection opens",
                       default=twc.js_callback('function(){}'))
    onread = twc.Param("A javascript callback for when new data is read",
                       default=twc.js_callback('function(){}'))
    onclose = twc.Param("A javascript callback for when the connection closes",
                        default=twc.js_callback('function(){}'))
    resources = [orbited_js]
    template = """
        <script type="text/javascript">
            Orbited.settings.port = %(port)s
            Orbited.settings.hostname = '%(host)s'
            document.domain = document.domain
            TCPSocket = Orbited.TCPSocket
            connect = function() {
                conn = new TCPSocket()
                conn.onread = ${onread}
                conn.onopen = ${onopen}
                conn.onclose = ${onclose}
                conn.open('%(host)s', %(port)s)
            }
            $(document).ready(function() {
                connect()
            })
        </script>
    """ % {
        'port': orbited_port,
        'host': orbited_host
    }
Exemple #22
0
class TextFieldMixin(twc.Widget):
    '''Misc mixin class with attributes for textual input fields'''
    maxlength = twc.Param('Maximum length of field',
                          attribute=True,
                          default=None)  #: Maximum length of the field
    placeholder = twc.Param(
        'Placeholder text (HTML5 only)', attribute=True,
        default=None)  #: Placeholder text, until user writes something.
Exemple #23
0
class TextFieldMixin(twc.Widget):
    '''Misc mixin class with attributes for textual input fields'''
    maxlength = twc.Param('Maximum length of field',
                          attribute=True,
                          default=None)
    placeholder = twc.Param('Placeholder text (HTML5 only)',
                            attribute=True,
                            default=None)
Exemple #24
0
class Form(twc.DisplayOnlyWidget):
    """
    A form, with a submit button. It's common to pass a
    TableLayout or ListLayout widget as the child.
    """
    template = "tw2.forms.templates.form"
    help_msg = twc.Param('This message displays as a div inside the form',
                         default=None)
    action = twc.Param(
        'URL to submit form data to. If this is None, the form ' +
        'submits to the same URL it was displayed on.',
        default=None,
        attribute=True)
    method = twc.Param('HTTP method used for form submission.',
                       default='post',
                       attribute=True)
    submit = twc.Param('Submit button widget. If this is None, no submit ' +
                       'button is generated.',
                       default=SubmitButton(value='Save'))
    buttons = twc.Param('List of additional buttons to be placed at the ' +
                        'bottom of the form',
                        default=[])

    attrs = {'enctype': 'multipart/form-data'}
    id_suffix = 'form'

    @classmethod
    def post_define(cls):
        if not cls.buttons:
            cls.buttons = []
        else:
            for b in range(0, len(cls.buttons)):
                if callable(cls.buttons[b]):
                    cls.buttons[b] = cls.buttons[b](parent=cls)

        if cls.submit:
            cls.submit = cls.submit(parent=cls)

    def __init__(self, **kw):
        super(Form, self).__init__(**kw)
        if self.buttons:
            for b in range(0, len(self.buttons)):
                self.buttons[b] = self.buttons[b].req()

        if self.submit:
            self.submit = self.submit.req()

    def prepare(self):
        super(Form, self).prepare()
        if self.buttons and not isinstance(self.buttons, list):
            raise AttributeError("buttons parameter must be a list or None")

        if self.submit and not \
        ['SubmitButton' in repr(b) for b in self.buttons]:
            self.buttons.append(self.submit)

        for b in self.buttons:
            b.prepare()
Exemple #25
0
class HBarGraph(twc.Widget):
    """
    Small Horizontal Bar Graph Chart
    graph_data should be a list of 3 item list
    (label, percent, value label)
     """
    template = 'rnms.templates.widgets.hbargraph'
    title = twc.Param('Title of the Chart', default='')
    graph_data = twc.Param('List of (label,pct,val)')
Exemple #26
0
class TextArea(TextFieldMixin, FormField):
    """A multiline text area"""
    rows = twc.Param(
        'Number of rows', default=None,
        attribute=True)  #: Add a rows= attribute to the HTML textarea
    cols = twc.Param(
        'Number of columns', default=None,
        attribute=True)  #: Add a cols= attribute to the HTML textarea
    template = "tw2.forms.templates.textarea"
Exemple #27
0
class PanelTile(twc.CompoundWidget):
    """
    Compound Widget that creates a panel tile that holds other widgets
    """
    template = 'rnms.templates.widgets.panel_tile'
    title = twc.Param('Title for this panel tile', default='Title')
    subtitle = twc.Param('Subtitle for this panel tile', default=None)
    fullwidth = twc.Param('Full width? True/False', default=False)
    fillrow = twc.Param('3/4 to fill row True/False', default=False)
    fullheight = twc.Param('Full height? True/False', default=False)
Exemple #28
0
class LineChart(twc.Widget):
    """
    Line Charts
     """
    template = 'rnms.templates.widgets.line_chart'
    data_url = twc.Param('URL for fetching the JSON data for graph')
    show_legend = twc.Param('Boolean: show the legend or not', default=False)

    def prepare(self):
        self.resources.append(chart_min_js)
        self.resources.append(jquery_js)
Exemple #29
0
class IFrameWidget(twc.Widget):
    template = "tw2.etc.templates.iframe"
    title = twc.Param("Title (optional)", default=None)
    height = twc.Param(default='100%', attribute=True)
    width = twc.Param(default='100%', attribute=True)
    src = twc.Param("Source for the iframe", attribute=True)
    url = twc.Param("Synonym for src", default=None)

    def prepare(self):
        if self.url:
            self.src = self.url
        super(IFrameWidget, self).prepare()
class TabWidget(twc.Widget):
    template = "mako:fedoracommunity.widgets.package.templates.tabs"
    base_url = twc.Param(default='/')
    args = twc.Param(default=None)
    kwds = twc.Param(default=None)
    tabs = twc.Variable(default=None)
    _uuid = twc.Param(default=None)
    widget = twc.Variable(default=None)
    active_tab = twc.Variable(default=None)
    tabs = twc.Variable(default=None)

    default_tab = None

    def __init__(self, *args, **kw):
        super(TabWidget, self).__init__(*args, **kw)
        self._uuid = str(uuid.uuid4())
        self._expanded_tabs = OrderedDict()
        for key, widget_key in self.tabs.items():
            display_name = key
            key = key.lower().replace(' ', '_')
            self._expanded_tabs[key] = {
                'display_name': display_name,
                'widget_key': widget_key
            }

    def prepare(self):
        super(TabWidget, self).prepare()
        if not self.args:
            self.args = []
        if not self.kwds:
            self.kwds = {}

        if isinstance(self.args, mako.runtime.Undefined):
            self.args = []
        if isinstance(self.kwds, mako.runtime.Undefined):
            self.kwds = {}

        if len(self.args) > 0:
            active_tab = self.args.pop(0).lower()
        else:
            active_tab = self.default_tab.lower()

        try:
            self.widget = moksha.common.utils.get_widget(
                self._expanded_tabs[active_tab]['widget_key'])
        except KeyError:
            self.widget = None

        self.tabs = self._expanded_tabs
        self.active_tab = active_tab

        if isinstance(self.base_url, Template):
            self.base_url = tg.url(self.base_url.render(**self.__dict__))