예제 #1
0
파일: packages.py 프로젝트: sean-hayes/zoom
def requires(*package_names):
    """Inform framework of the packages required for rendering

    >>> request = zoom.request.Request(dict(PATH_INFO='/'))
    >>> zoom.system.site = zoom.site.Site(request)

    >>> requires('c3')
    >>> libs = zoom.component.composition.parts.parts['libs']
    >>> list(libs)[0]
    'https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js'

    >>> try:
    ...     requires('d4')
    ... except Exception as e:
    ...     'Missing required' in str(e) and 'raised!'
    'raised!'

    """

    parts = zoom.Component()

    registered_packages = get_registered_packages()

    for name in package_names:
        package = registered_packages.get(name)
        if package:
            parts += zoom.Component(**package)
        else:
            missing = set(package_names) - set(registered_packages)
            raise Exception('Missing required packages: {}'.format(missing))

    zoom.component.composition.parts += parts
예제 #2
0
파일: index.py 프로젝트: brettgoss/zoom
def side_menu(*items):
    css = """
    .side-nav ul li {
        height: 2em;
        line-height: 2em;
        padding: 0 0.5em;
        list-style-type: none;
    }
    .side-nav ul .active {
        background: #ddd;
    }
    .content ul {
        margin-left: 0;
    }
    """
    result = []
    for item in items:
        item_id = zoom.utils.id_for(item)
        route = zoom.system.request.route
        attr = route[1:][:1] == [item_id] and {'class': 'active'} or {}
        result.append(
            h.tag(
                'li',
                h.tag('a',
                      item,
                      href=zoom.helpers.url_for_page(item_id),
                      id=item_id), **attr))
    return zoom.Component(
        h.tag('ul', ''.join(result), classed='side-nav'),
        css=css,
    ) if result else ''
예제 #3
0
파일: index.py 프로젝트: robinsax/zoom
 def environment(self):
     return page(
         zoom.Component(
             h.h2('Python'),
             zoom.tags.table([
                 ('Version', sys.version),
                 ('PYTHONPATH', '<br>'.join(sys.path)),
                 ('PATH', '<br>'.join(os.environ.get('PATH').split(':')))
             ]),
             h.h2('Operating System'),
             zoom.tags.table([
                 ('Name', os.name),
                 ('PYTHONPATH', '<br>'.join(sys.path)),
                 ('PATH', '<br>'.join(os.environ.get('PATH').split(':')))
             ]),
             h.h2('Platform'),
             zoom.tags.table([
                 ('Node', platform.node()),
                 ('System', platform.system()),
                 ('Machine', platform.machine()),
                 ('Archtitecture', ' '.join(platform.architecture()))
             ]),
             h.h2('Variables'),
             zoom.tags.table(
                 list(os.environ.items())
             ),
             css = """
                 .content table { width: 100%; }
                 .content table td { vertical-align: top; }
             """
         ),
         title='Environment'
     )
예제 #4
0
파일: index.py 프로젝트: zodman/ZoomFoundry
 def environment(self):
     return page(zoom.Component(
         h.h2('Zoom'),
         zoom.html.table([
             ('Version', zoom.__version__ + ' Community Edition'),
             ('Installed Path', zoom.tools.zoompath()),
         ]),
         h.h2('Python'),
         zoom.html.table([
             ('sys.version', sys.version),
             ('sys.path', '<br>'.join(sys.path)),
         ]),
         h.h2('Operating System'),
         zoom.html.table([
             ('Name', os.name),
             ('PATH', '<br>'.join(os.environ.get('PATH').split(':')))
         ]),
         h.h2('Platform'),
         zoom.html.table([('Node', platform.node()),
                          ('System', platform.system()),
                          ('Machine', platform.machine()),
                          ('Archtitecture',
                           ' '.join(platform.architecture()))]),
         h.h2('Variables'),
         zoom.html.table(list(os.environ.items())),
         css="""
                 .content table { width: 100%; }
                 .content table td { vertical-align: top; width: 70%; }
                 .content table td:first-child { width: 25%; }
             """),
                 title='Environment')
예제 #5
0
파일: database.py 프로젝트: brettgoss/zoom
    def index(self):
        engine = zoom.system.site.config.get('database', 'engine')
        if engine == 'mysql':

            db = zoom.system.site.db

            sections = [
                ('Settings', [
                    ('Connection', str(zoom.tools.websafe(zoom.system.site.db))),
                    ('Isolation Level', get_isolation_level(zoom.system.site.db))
                ]),
                ('Process List', zoom.system.site.db('show processlist')),
                ('Status', zoom.system.site.db('show status')),
            ]

            if db('show slave hosts'):
                sections.extend([
                    ('Replication Hosts', db('show slave hosts')),
                    ('Replication Status', db('show slave status'))
                ])

            content = zoom.Component(
                *((h.h2(title), h.table(code)) for title, code in sections),
                css="""
                .content table { width: 100%; }
                .content table td {width: 50%; }
                """
            )


        else:
            content = 'not available for {} database engine'.format(engine)
        return zoom.page(content, title='Database')
예제 #6
0
def delete_form(name, cancel=None):
    """produce a delete form"""
    css = """
    .delete-card {
        border: thin solid #ddd;
        margin: 10% auto;
        width: 50%;
        padding: 3em;
        background: white;
        box-shadow: 3px 3px 3px #ddd;
    }
    .delete-card p {
        font-size: 1.8rem;
    }
    @media (max-width: 600px) {
        .delete-card {
            padding: 1em;
            width: 100%;
        }
    }
    """
    return zoom.Component(html.div(Form(
        MarkdownText('Are you sure you want to delete **%s**?' % name),
        Hidden(name='confirm', value='no'),
        Button('Yes, I\'m sure.  Please delete.',
               name='delete_button',
               cancel=cancel or url_for('..'))).edit(),
                                   classed='delete-card'),
                          css=css)
예제 #7
0
 def setUp(self):
     bunch = zoom.utils.Bunch
     # db = zoom.database.setup_test()
     zoom.system.site = zoom.sites.Site()
     zoom.system.request = bunch(
         app=bunch(name='myapp', url='/myapp'),
         user=zoom.system.site.users.first(username='******'))
     zoom.system.parts = zoom.Component()
예제 #8
0
def requires(*package_names):
    """Inform framework of the packages required for rendering

    >>> import zoom.request
    >>> request = zoom.request.Request(dict(PATH_INFO='/'))
    >>> zoom.system.site = zoom.site.Site(request)
    >>> zoom.system.parts = zoom.Component()

    >>> requires('c3')
    >>> libs = zoom.system.parts.parts['libs']
    >>> print('\\n'.join(list(libs)))
    https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js
    https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.15/c3.min.js

    >>> zoom.system.parts = zoom.Component()
    >>> requires('jquery-ui')
    >>> libs = zoom.system.parts.parts['libs']
    >>> print('\\n'.join(list(libs)))
    //code.jquery.com/jquery-3.3.1.min.js
    //code.jquery.com/ui/1.12.1/jquery-ui.min.js

    >>> try:
    ...     requires('d4')
    ... except Exception as e:
    ...     'Missing required' in str(e) and 'raised!'
    'raised!'

    """
    parts = zoom.Component()

    registered_packages = get_registered_packages()

    for name in package_names:
        package = registered_packages.get(name)
        if package:
            requirements = package.get('requires')
            if requirements:
                requires(*requirements)
            parts += zoom.Component(**package)
        else:
            missing = set(package_names) - set(registered_packages)
            raise Exception('Missing required packages: {}'.format(missing))

    zoom.system.parts += parts
예제 #9
0
    def format(self, *content, title=None, footer=None):  # pylint: disable=arguments-differ
        """Card format

        Format content in the form of a Card.

        """

        header = html.div(title, classed='card-header') if title else ''
        footer = html.div(footer, classed='card-footer') if footer else ''

        card = zoom.Component(
            html.div(header,
                     html.div(zoom.Component(content).render(),
                              classed='card-body'),
                     footer,
                     classed='card'))

        return zoom.DynamicComponent(
            self,
            card,
        )
예제 #10
0
파일: index.py 프로젝트: zodman/ZoomFoundry
    def _index(self):
        self.model.site.logging = False
        db = self.model.site.db

        content = zoom.Component(
            views.index_metrics_view(db),
            views.IndexPageLayoutView(
                feed1=activity_panel(db),
                feed2=users_panel(db),
                feed3=error_panel(db),
                feed4=warning_panel(db),
            ),
        )
        return zoom.partial(content)
예제 #11
0
def get_impersonation_notice():
    username = get_impersonated_username()
    if username is None:
        return ''
    return str(
        zoom.Component(
            h.div(
                'Impersonating {}'.format(username),
                zoom.link_to(
                    'Stop Impersonating',
                    '/stop-impersonation',
                    classed='action'
                ),
                id='impersonation-notice'
            )
        )
    )
예제 #12
0
파일: index.py 프로젝트: zodman/ZoomFoundry
def callback(method, url=None, timeout=5000):
    method_name = method.__name__
    path = url or '/<dz:app_name>/' + method_name
    js = """
        jQuery(function($){
          setInterval(function(){
            $.get('%(path)s', function( content ){
              if (content) {
                    $('#%(method_name)s').html( content );
                }
            });
          }, %(timeout)s);
        });
    """ % dict(path=path, method_name=method_name, timeout=timeout)
    content = '<div id="%(method_name)s">%(initial_value)s</div>' % dict(
        initial_value=method().content, method_name=method_name)
    return zoom.Component(content, js=js)
예제 #13
0
def view():

    hr = '<hr>\n'

    content = zoom.Component(
        'zoom.components.HeaderBar',
        c.HeaderBar(left=h.h2('HeaderBar Left'), right='HeaderBar right'),
        hr,
        'zoom.components.spinner',
        h.div(c.spinner(),
              classed="clearfix",
              style="margin: 40px auto; width: 0;"),
        hr,
        'zoom.components.dropzone',
        c.dropzone('/sample/components'),
        hr,
    )

    return zoom.page(content, title='Components')
예제 #14
0
파일: index.py 프로젝트: robinsax/zoom
    def index(self, q=''):

        content = callback(self._index)

        if q:
            request = zoom.system.request
            users_collection = users.get_users_collection(request)
            user_records = users_collection.search(q)

            groups_collection = groups.get_groups_collection(request)
            group_records = groups_collection.search(q)

            if user_records or group_records:
                content = zoom.Component()
                if group_records:
                    footer = '%d groups found' % len(group_records)
                    content += zoom.browse(
                        group_records,
                        columns=groups_collection.columns,
                        labels=groups_collection.labels,
                        title='Groups',
                        footer=footer,
                    )

                if user_records:
                    footer = '%d users found' % len(user_records)
                    content += zoom.browse(
                        user_records,
                        columns=users_collection.columns,
                        labels=users_collection.labels,
                        title='Users',
                        footer=footer,
                    )
            else:
                zoom.alerts.warning('no records found')

        return page(
            content,
            title='Overview',
            search=q
        )
예제 #15
0
def view():

    hr = '<hr>\n'

    data = [('String', 'Integer', 'Decimal'),
            ('One', 1, decimal.Decimal(1234)),
            ('Two', 2, decimal.Decimal(2345))]

    content = zoom.Component(
        'zoom.browse',
        zoom.browse(data, title='Sample Header',
                    footer='sample footer'), hr, 'zoom.components.HeaderBar',
        c.HeaderBar(left=h.h2('HeaderBar Left'),
                    right='HeaderBar right'), hr, 'zoom.components.spinner',
        h.div(c.spinner(),
              classed="clearfix",
              style="margin: 40px auto; width: 0;"), hr,
        'zoom.components.dropzone', c.dropzone('/sample/components'), hr,
        use_common_package('not updated yet'))

    return zoom.page(content, title='Components')
예제 #16
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)
예제 #17
0
파일: tools.py 프로젝트: zodman/ZoomFoundry
def partial(*args, **kwargs):
    """Return a partial HTML response."""
    content = zoom.Component(*args, **kwargs)
    return zoom.response.HTMLResponse(content.render())
예제 #18
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))
예제 #19
0
def use_common_package(message):
    zoom.requires('common_package_test')
    return zoom.Component(h.tag('div', message, id='common_package_test'))
예제 #20
0
파일: index.py 프로젝트: zodman/ZoomFoundry
    def configuration(self):
        """Return the configuration page"""
        get = zoom.system.site.config.get
        site = zoom.system.site
        request = zoom.system.request
        app = zoom.system.request.app
        system_apps = get('apps', 'system',
                          ','.join(zoom.apps.DEFAULT_SYSTEM_APPS))
        main_apps = get('apps', 'main', ','.join(zoom.apps.DEFAULT_MAIN_APPS))

        items = zoom.packages.get_registered_packages()
        packages = ((key, '<br>'.join(
            '{resources}'.format(resources='<br>'.join(resources))
            for resource_type, resources in sorted(
                parts.items(),
                key=lambda a: ['requires', 'styles', 'libs'].index(a[0]))))
                    for key, parts in sorted(items.items()))

        return page(zoom.Component(
            h.h2('Site'),
            zoom.html.table([(k, getattr(site, k)) for k in (
                'name',
                'path',
                'owner_name',
                'owner_email',
                'owner_url',
                'admin_email',
                'csrf_validation',
            )]),
            h.h2('Users'),
            zoom.html.table([(k, getattr(site, k)) for k in (
                'guest',
                'administrators_group',
                'developers_group',
            )]),
            h.h2('Apps'),
            zoom.html.table([(k, getattr(site, k)) for k in (
                'index_app_name',
                'home_app_name',
                'login_app_name',
                'auth_app_name',
                'locate_app_name',
            )] + [
                ('app.path', app.path),
                ('apps_paths', '<br>'.join(site.apps_paths)),
                ('main_apps', main_apps),
                ('system_apps', system_apps),
            ]),
            h.h2('Theme'),
            zoom.html.table([
                ('name', site.theme),
                ('path', site.theme_path),
                ('comments', site.theme_comments),
            ]),
            h.h2('Sessions'),
            zoom.html.table([(k, getattr(site, k))
                             for k in ('secure_cookies', )]),
            h.h2('Monitoring'),
            zoom.html.table([
                ('logging', site.logging),
                ('profiling', site.profiling),
                ('app_database', site.monitor_app_database),
                ('system_database', site.monitor_system_database),
            ]),
            h.h2('Errors'),
            zoom.html.table([
                ('users', get('errors', 'users', False)),
            ]),
            h.h2('Packages'),
            zoom.html.table(packages, ),
            css="""
                    .content table { width: 100%; }
                    .content table td { vertical-align: top; width: 70%; }
                    .content table td:first-child { width: 25%; }
                """),
                    title='Environment')
예제 #21
0
 def component(self):
     return zoom.Component(
         '<h1>Component</h1>This is a <code>Component</code> response.')
예제 #22
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
예제 #23
0
def view():

    layout = WidgetsLayout()

    card = Card()

    cards = Cards().format(cards=zoom.Component(
        card.format('basic card'),
        card.format('card with title', title='Title'),
        card.format('Card with footer', footer='Footer'),
        card.format('Card with title and footer',
                    title='Title',
                    footer='Footer'),
    ), )

    metric = MetricWidget()
    metrics = zoom.Component(
        h.h2('Metrics'),
        zoom.html.div(
            layout.format(
                card(metric(title='Queries', value=100, hint='numeric value')),
                card(metric(title='Items', value='1,123', hint='string')),
                card(metric(title='Revenue', value='$1,323',
                            hint='formatted')),
                card(
                    metric(title='Date',
                           value=zoom.tools.today(),
                           hint='other types')),
            ),
            classed='metrics-layout',
        ),
        css='.metrics-layout .widgets-layout { min-height: auto; }')

    progress_widgets = (card(ProgressWidget().format(
        10 + n * 20,
        title='Metric %s' % n,
        hint='Metric %s hint' % n if n in [1, 3] else '',
    )) for n in range(4))
    progress = zoom.Component(
        h.h2('Progress'),
        layout.format(*progress_widgets),
    )

    charts = [
        Chart(
            title='Pipeline',
            format='${:,.2f}',
        ),
        Chart(
            title='Inventory',
            classed='bg-gradient-info',
            smooth=False,
        ),
        Chart(
            title='Expenses',
            classed='bg-gradient-warning',
            data=[100, 200, 700, 400],
            labels=['January', 'February', 'March', 'April'],
            type='bar',
        ),
        Chart(
            title='Errors',
            classed='bg-gradient-danger',
            fill_color='#fff',
        ),
    ]
    chart_widget = ChartWidget()
    chart_widgets = (card(chart_widget.format(chart)) for chart in charts)
    charts_section = zoom.Component(h.h2('Charts'),
                                    layout.format(*chart_widgets))

    return zoom.page(cards, metrics, progress, charts_section, title='Widgets')
예제 #24
0
파일: test_apps.py 프로젝트: brettgoss/zoom
 def test_respond_component(self):
     response = zoom.apps.respond(zoom.Component('my html', css='my css'),
                                  self.request)
     self.assertEqual(type(response), zoom.response.HTMLResponse)