예제 #1
0
파일: page.py 프로젝트: zodman/ZoomFoundry
    def render(self, request):
        """render page"""

        logger = logging.getLogger(__name__)
        logger.debug('rendering page')

        self.content = render(self.header(), self.content, *self.args)

        app_theme = request.app.theme if hasattr(request, 'app') else None
        site_theme = request.site.theme
        self.theme = self.kwargs.get('theme', app_theme or site_theme
                                     or 'default')
        self.theme_uri = '/themes/' + self.theme

        zoom.render.add_helpers(
            zoom.forms.helpers(request),
            self.helpers(request),
        )

        template = zoom.tools.get_template(self.template, self.theme)

        if zoom.system.site.settings.site.cookie_consent:
            zoom.requires('cookieconsent')

        return HTMLResponse(template, status=self.status)
예제 #2
0
def spinner():
    """A progress spinner

    >>> isinstance(spinner(), str)
    True
    """
    zoom.requires('spin')
    return div(id='spinner')
예제 #3
0
파일: app.py 프로젝트: zodman/ZoomFoundry
def app(request):
    """Return a page containing a list of available apps"""

    zoom.requires('fontawesome4')

    css = """
        .app-icons ul {
            list-style-type: none;
            margin-top: 50px;
        }
        .app-icons li {
            display: inline;
        }
        .zoom-app-as-icon {
            width: 110px;
            height: 120px;
            text-align: center;
            float: left;
        }
        .zoom-app-as-icon:hover {
            background: #eee;
        }
        .zoom-app-icon {
            height: 50px;
            width: 50px;
            border-radius: 5px;
            margin-top: 16px;
            padding-top: 5px;
            line-height: 50px;
            text-align: center;
            box-shadow: inset 0px 49px 0px -24px #67828b;
            background-color: #5a7179;
            border: 1px solid #ffffff;
            display: inline-block;
            color: #ffffff;
            font-size: 15px;
            text-decoration: none;
        }
        .zoom-app-icon .fa {
            font-size: 2em;
        }
    """

    if len(request.route) > 1 or request.data:
        return zoom.home()

    skip = 'home', 'logout', 'login', 'settings'
    content = h.div(
        h.ul(
            a.as_icon for a in sorted(request.site.apps, key=lambda a: a.title.lower())
            if a.name not in skip and a.visible and request.user.can_run(a)
        ), classed='app-icons'
    ) + '<div style="clear:both"></div>'
    return zoom.page(content, css=css)
예제 #4
0
def app(request):

    zoom.requires('Morphext')

    content = ul(link_to(text, url) for text, url in [
        ('Info', '/info'),
    ])

    js = """
    $("#js-rotating").Morphext({
        animation: "bounceIn",
        separator: ",",
        speed: 2000,
    });
    """

    return page(
        '<span id="js-rotating">Hello, Howdy, Hola, Hi</span> World!<br>{}'.
        format(content),
        title='Hello',
        js=js,
    )
예제 #5
0
파일: flags.py 프로젝트: zodman/ZoomFoundry
    def render_in_state(self, state):
        zoom.requires('fontawesome')
        selector = '[data-flag-id="%s"]'%self.id

        # Maybe render styles. add_page_dependencies() doesn't work here in the
        # case that this is the result of a helper being used, since the head
        # of the document will already have been rendered.
        flag_style = '''
        <style>
            %s .icon-flag {
                cursor: pointer;
                color: %s;
            }
            %s .icon-flag[data-active="true"] {
                color: %s;
            }
        </style>
        '''%(
            selector,
            self.data.get('off_color') or 'gray',
            selector,
            self.data.get('on_color') or 'black'
        )
        fa_import = '''
            <link rel="stylesheet" href="//use.fontawesome.com/releases/v5.0.6/css/all.css"/>
        '''
        if getattr(context, '_flag_inc_fa', False):
            fa_import = str()
            context._flag_inc_fa = True

        return '''%s%s
            <i class="fa fa-%s icon-flag" title="%s" data-active="%s"></i>
        '''%(
            fa_import, flag_style,
            self.data.get('icon') or 'star',
            self.get_label_in_state(state),
            str(state).lower()
        )
예제 #6
0
def dropzone(url, **kwargs):
    """Dropzone component

    A basic dropzone component that supports drag and drop uploading
    of files which are posted to the URL provided.

    >>> zoom.system.site = zoom.sites.Site()
    >>> zoom.system.site.packages = {}
    >>> zoom.system.request = zoom.utils.Bunch(app=zoom.utils.Bunch(name='hello', packages={}, common_packages={}))
    >>> c = dropzone('/app/files')
    >>> isinstance(c, zoom.Component)
    True
    """
    zoom.requires('dropzone')

    id = 'dropzone_' + uuid.uuid4().hex

    js = """
    var %(id)s = new Dropzone("#%(id)s", {url: "%(url)s"});
    """ % dict(id=id, url=url)

    html = div(classed='dropzone', id=id, **kwargs)
    return zoom.Component(html)#, js=js)
예제 #7
0
    def index(self):
        """Show all images"""

        actions = 'Edit',

        tpl = """
        <a href="{image.access_url}" class="image-item-container">
          <img class="images-thumbnail" title="{image.image_name}" src="/content/images/{image.image_id}">
          <div class="images-linker-container">
            {image.markdown_linker}
          </div>
        </a>
        """

        content = ''.join(
            tpl.format(image=image) for image in zoom.store_of(Image))

        zoom.requires('fontawesome4')
        return zoom.page(content,
                         title='Images',
                         actions=actions,
                         css=css,
                         libs=('/content/static/markdown-linker.js', ))
예제 #8
0
 def format(self, chart):
     """Format a Chart"""
     zoom.requires('chartjs')
     return zoom.DynamicComponent.format(self, chart=chart)
예제 #9
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     zoom.requires('fontawesome4')
예제 #10
0
def browse(data, **kwargs):
    """browse data"""

    def getcol(item, index):
        if isinstance(item, dict):
            return item.get(index, None)
        elif isinstance(item, (tuple, list)):
            return item[index]
        else:
            return getattr(item, index)

    labels = kwargs.get('labels')
    fields = kwargs.get('fields')
    columns = kwargs.get('columns')
    title = kwargs.get('title')
    actions = kwargs.get('actions', [])
    header = kwargs.get('header')
    footer = kwargs.get('footer', '')
    sortable = kwargs.get('sortable', False)
    table_id = kwargs.get('table_id', uuid.uuid4().hex)

    items = list(data)

    if labels:
        if not columns:
            if len(items) and hasattr(items[0], 'get'):
                columns = [name_for(label).lower() for label in labels]

            elif len(items) and hasattr(items[0], '__len__') and len(items[0]):
                columns = range(len(labels))

            else:
                columns = [name_for(label).lower() for label in labels]

    else:
        if columns:
            labels = columns
        else:
            if len(items) and isinstance(items[0], Record):
                labels = columns = sorted_column_names(set([
                    a for item in items
                    for a in item.attributes()
                    if not a.startswith('__')
                ]))

            elif (len(items) and hasattr(items[0], 'keys') and
                  callable(getattr(items[0], 'keys'))):
                # list of dicts
                labels = columns = [
                    a for a in sorted_column_names(items[0].keys())
                    if not a.startswith('__')
                ]

            elif len(items) and hasattr(items[0], '__dict__'):
                # list of objects
                labels = columns = [items[0].__dict__.keys()]

            elif hasattr(data, 'cursor'):
                # Result object
                labels = [c[0] for c in data.cursor.description]
                columns = range(len(labels))

            elif len(items) and hasattr(items[0], '__len__') and len(items[0]):
                # list of lists?
                labels = items[0]
                columns = range(len(items[0]))
                items = items[1:]

            else:
                if len(items):
                    raise Exception('%s' % hasattr(items[0],'__len__'))
                return '<div class="baselist"><table><tbody><tr><td>None</td></th></tbody></table></div>'

    columns = list(columns)
    labels = list(labels)
    invisible = []
    formatters = []
    alignments = []

    if fields:
        invisible_labels = []
        lookup = fields.as_dict()

        for n, col in enumerate(columns):

            if col in lookup:
                field = lookup[col]
                better_label = field.label
                visible = field.visible and field.browse
                if visible:
                    alignments.append(field.alignment)
                    formatters.append(str)
            else:
                better_label = None
                visible = True
                values = [getcol(row, col) for row in items]
                formatter, alignment = get_format(col, values)
                alignments.append(alignment)
                formatters.append(formatter)

            if better_label:
                if n > len(labels):
                    labels.append(better_label)
                else:
                    labels[n] = better_label

            if not visible:
                invisible.append(col)
                invisible_labels.append(n)

        for n in reversed(invisible_labels):
            del labels[n]

        alist = []
        for item in items:
            fields.initialize(item)
            flookup = fields.display_value()
            row = [
                flookup.get(col, getcol(item, col))
                for col in columns
                if col not in invisible
            ]
            alist.append(row)
    else:
        alist = [[getcol(item, col) for col in columns] for item in items]
        styling = calculate_styling(columns, labels, alist)
        formatters = [s[0] for s in styling]
        alignments = [s[1] for s in styling]

    column_alignments = """
        #%s tbody>tr>td:nth-child(%s) {
            text-align: right;
            padding-right: 20px;
        }
        #%s thead>tr>th:nth-child(%s) {
            text-align: right;
            padding-right: 20px;
        }
    """

    alignment_css = ''.join(
        column_alignments % (table_id, n+1, table_id, n+1)
        for n, alignment in enumerate(alignments)
        if alignment == 'right'
    )

    css = alignment_css

    t = []
    if labels:
        t.append('<thead><tr>')

        colnum = 0
        for label in labels:
            colnum += 1
            t.append('<th>%s</th>' % label)

        t.append('</tr></thead>')

    t.append('<tbody>')

    count = 0
    for row in alist:
        count += 1
        t.append('<tr id="row-%s">' % (count))

        for n, item in enumerate(row):
            try:
                value = formatters[n].format(item)
            except BaseException:
                value = repr(item)
            wrapping = len(value) < 80 and ' nowrap' or ''
            cell_tpl = '<td{}>%s</td>'.format(wrapping)
            t.append(cell_tpl % value)

        t.append('</tr>')

    t.append('</tbody>')

    if not count:
        t.append('<tr><td colspan=%s>None</td></tr>' % len(labels))

    if not header:
        if title:
            header = '<div class="title">%s</div>' % title
        if actions:
            header += as_actions(actions)

    header_body = header and ('<div class="header">%s</div>' % header) or ''
    footer_body = footer and ('<div class="footer">%s</div>' % footer) or ''

    if sortable:
        zoom.requires('datatables')
        js = """
            $('#{}').DataTable( {{
            "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],
            "dom": '<if>rt<lp><"clear">',
            paging: false,
            "oLanguage": {{
            "sSearch": "Filter"
            }}
        }} );
        """.format(table_id)
        css += """
        .dataTables_filter label {
            font-weight: normal;
        }
        """
        zoom.Component(css=css, js=js).render()
    else:
        zoom.Component(css=css).render()

    table_tag = '<table id="{}">'.format(table_id)

    result = '\n'.join(
        ['<div class="baselist">'] +
        [header_body] +
        [table_tag] + t + ['</table>'] +
        [footer_body] +
        ['</div>']
    )

    return result
예제 #11
0
파일: helpers.py 프로젝트: robinsax/zoom
def standard_zoom_head_tags():
    zoom.requires('standard-zoom-assets')
    tags = 'styles', 'css', 'head', 'tracker'
    return ''.join('{{%s}}' % tag for tag in tags)
예제 #12
0
파일: helpers.py 프로젝트: robinsax/zoom
def requires(*packages):
    zoom.requires(*packages)
    return ''
예제 #13
0
파일: index.py 프로젝트: robinsax/zoom
 def index(self):
     """Index page"""
     zoom.requires('fontawesome4')
     content = zoom.tools.load('icons.html')
     subtitle = 'Icons available as part of FontAwesome 4<br><br>'
     return zoom.page(content, title='Icons', subtitle=subtitle)
예제 #14
0
def use_common_package(message):
    zoom.requires('common_package_test')
    return zoom.Component(h.tag('div', message, id='common_package_test'))
예제 #15
0
 def format(self, chart):
     """Format a Chart"""
     zoom.requires('pivot-table')
     return (zoom.Component(
         "<div class='pivot-table' id='%s'></div>" % chart.selector) +
             zoom.DynamicComponent.format(self, chart=chart))