Ejemplo n.º 1
0
 def test_delta_none_end(self):
     end = datetime.datetime.utcnow() - datetime.timedelta(seconds=600)
     end = datetime.datetime.timestamp(end)
     start, end, delta = assemble_timerange(None, end, 5)
     eq_(1325375395.0, start)
     eq_(1325375400.0, end)
     eq_(5, delta)
Ejemplo n.º 2
0
 def test_delta_none_end(self):
     end = datetime.datetime.now() - datetime.timedelta(seconds=600)
     end = time.mktime(end.timetuple())
     start, end, delta = assemble_timerange(None, end, 5)
     eq_(1325375395.0, start)
     eq_(1325375400.0, end)
     eq_(5, delta)
Ejemplo n.º 3
0
 def test_none_none_end(self):
     end = datetime.datetime.now() - datetime.timedelta(seconds=600)
     end = time.mktime(end.timetuple())
     start, end, delta = assemble_timerange(None, end, None)
     eq_(1325374800.0, start)
     eq_(1325375400.0, end)
     eq_(600, delta)
Ejemplo n.º 4
0
 def test_delta_start_none(self):
     start = datetime.datetime.now() - datetime.timedelta(seconds=600)
     start = time.mktime(start.timetuple())
     start, end, delta = assemble_timerange(start, None, 5)
     eq_(1325375400.0, start)
     eq_(1325375405.0, end)
     eq_(5, delta)
Ejemplo n.º 5
0
 def test_none_start_none(self):
     start = datetime.datetime.now() - datetime.timedelta(seconds=700)
     start = time.mktime(start.timetuple())
     start, end, delta = assemble_timerange(start, None, None)
     eq_(1325375300.0, start)
     eq_(1325376000.0, end)
     eq_(700, delta)
Ejemplo n.º 6
0
 def test_delta_start_none(self):
     start = datetime.datetime.utcnow() - datetime.timedelta(seconds=600)
     start = datetime.datetime.timestamp(start)
     start, end, delta = assemble_timerange(start, None, 5)
     eq_(1325375400.0, start)
     eq_(1325375405.0, end)
     eq_(5, delta)
Ejemplo n.º 7
0
 def test_none_start_none(self):
     start = datetime.datetime.utcnow() - datetime.timedelta(seconds=700)
     start = datetime.datetime.timestamp(start)
     start, end, delta = assemble_timerange(start, None, None)
     eq_(1325375300.0, start)
     eq_(1325376000.0, end)
     eq_(700, delta)
Ejemplo n.º 8
0
 def test_delta_start_end(self):
     end = datetime.datetime.utcnow() - datetime.timedelta(seconds=600)
     end = datetime.datetime.timestamp(end)
     start = datetime.datetime.utcnow() - datetime.timedelta(seconds=800)
     start = datetime.datetime.timestamp(start)
     start, end, delta = assemble_timerange(start, end, 5)
     eq_(1325375200.0, start)
     eq_(1325375400.0, end)
     eq_(200, delta)
Ejemplo n.º 9
0
 def test_delta_start_end(self):
     end = datetime.datetime.now() - datetime.timedelta(seconds=600)
     end = time.mktime(end.timetuple())
     start = datetime.datetime.now() - datetime.timedelta(seconds=800)
     start = time.mktime(start.timetuple())
     start, end, delta = assemble_timerange(start, end, 5)
     eq_(1325375200.0, start)
     eq_(1325375400.0, end)
     eq_(200, delta)
Ejemplo n.º 10
0
 def test_delta_start_end(self):
     end = datetime.datetime.now() - datetime.timedelta(seconds=600)
     end = time.mktime(end.timetuple())
     start = datetime.datetime.now() - datetime.timedelta(seconds=800)
     start = time.mktime(start.timetuple())
     start, end, delta = assemble_timerange(start, end, 5)
     eq_(1325375200.0, start)
     eq_(1325375400.0, end)
     eq_(200, delta)
Ejemplo n.º 11
0
    def from_request_args(cls, request_args):
        obj = cls()
        opts = dict()

        for arg in OPTIONS:
            opts[arg] = request_args.get(arg, None)

        for arg in LIST_OPTIONS:
            opts[arg] = request_args.getlist(arg)

        opts['start'], opts['end'], opts['delta'] = \
            assemble_timerange(opts['start'], opts['end'], opts['delta'])

        obj.options = opts
        return obj
Ejemplo n.º 12
0
    def from_request_args(cls, request_args):
        obj = cls()
        opts = dict()

        for arg in OPTIONS:
            opts[arg] = request_args.get(arg, None)

        for arg in LIST_OPTIONS:
            opts[arg] = request_args.getlist(arg)

        opts['start'], opts['end'], opts['delta'] = \
            assemble_timerange(opts['start'], opts['end'], opts['delta'])

        obj.options = opts
        return obj
Ejemplo n.º 13
0
def raw():
    """ Main API entry point. """

    # Perform our complicated datetime logic
    start = flask.request.args.get('start', None)
    end = flask.request.args.get('end', None)
    delta = flask.request.args.get('delta', None)
    start, end, delta = assemble_timerange(start, end, delta)

    # Further filters, all ANDed together in CNF style.
    users = flask.request.args.getlist('user')
    packages = flask.request.args.getlist('package')
    categories = flask.request.args.getlist('category')
    topics = flask.request.args.getlist('topic')

    # Paging arguments
    page = int(flask.request.args.get('page', 1))
    rows_per_page = int(flask.request.args.get('rows_per_page', 20))
    order = flask.request.args.get('order', 'asc')

    # Response formatting arguments
    callback = flask.request.args.get('callback', None)
    meta = flask.request.args.getlist('meta')

    arguments = dict(
        start=start,
        delta=delta,
        end=end,
        users=users,
        packages=packages,
        categories=categories,
        topics=topics,
        page=page,
        rows_per_page=rows_per_page,
        order=order,
        meta=meta,
    )

    if page < 1:
        raise ValueError("page must be > 0")

    if rows_per_page > 100:
        raise ValueError("rows_per_page must be <= 100")

    if order not in ['desc', 'asc']:
        raise ValueError("order must be either 'desc' or 'asc'")

    meta_expected = set(['title', 'subtitle', 'icon', 'secondary_icon',
                         'link', 'usernames', 'packages', 'objects'])
    if len(set(meta).intersection(meta_expected)) != len(set(meta)):
        raise ValueError("meta must be in %s"
                         % ','.join(list(meta_expected)))

    try:
        # This fancy classmethod does all of our search for us.
        total, pages, messages = dm.Message.grep(
            start=start and datetime.fromtimestamp(start),
            end=end and datetime.fromtimestamp(end),
            page=page,
            rows_per_page=rows_per_page,
            order=order,
            users=users,
            packages=packages,
            categories=categories,
            topics=topics,
        )

        # Convert our messages from sqlalchemy objects to json-like dicts
        messages = [msg.__json__() for msg in messages]

        if meta:
            for message in messages:
                metas = {}
                for metadata in meta:
                    cmd = 'msg2%s' % metadata
                    metas[metadata] = getattr(
                        fedmsg.meta, cmd)(message, **fedmsg_config)

                    # We have to do this because 'set' is not
                    # JSON-serializable.  In the next version of fedmsg, this
                    # will be handled automatically and we can just remove this
                    # statement https://github.com/fedora-infra/fedmsg/pull/139
                    if isinstance(metas[metadata], set):
                        metas[metadata] = list(metas[metadata])

                message['meta'] = metas

        output = dict(
            raw_messages=messages,
            total=total,
            pages=pages,
            count=len(messages),
            arguments=arguments,
        )
        status = 200
    except Exception as e:
        output = dict(
            error=str(e),
            arguments=arguments,
        )

        # :D
        if app.config.get('DEBUG', False):
            output['tb'] = traceback.format_exc().split('\n')

        status = 500

    body = fedmsg.encoding.dumps(output)

    mimetype = 'application/json'

    if callback:
        mimetype = 'application/javascript'
        body = "%s(%s);" % (callback, body)

    return flask.Response(
        response=body,
        status=status,
        mimetype=mimetype,
    )
Ejemplo n.º 14
0
def raw():
    """ Main API entry point. """

    # Perform our complicated datetime logic
    start = flask.request.args.get('start', None)
    end = flask.request.args.get('end', None)
    delta = flask.request.args.get('delta', None)
    start, end, delta = assemble_timerange(start, end, delta)

    # Further filters, all ANDed together in CNF style.
    users = flask.request.args.getlist('user')
    packages = flask.request.args.getlist('package')
    categories = flask.request.args.getlist('category')
    topics = flask.request.args.getlist('topic')
    contains = flask.request.args.getlist('contains')

    # Still more filters.. negations of the previous ones.
    not_users = flask.request.args.getlist('not_user')
    not_packages = flask.request.args.getlist('not_package')
    not_categories = flask.request.args.getlist('not_category')
    not_topics = flask.request.args.getlist('not_topic')

    # Paging arguments
    page = int(flask.request.args.get('page', 1))
    rows_per_page = int(flask.request.args.get('rows_per_page', 20))
    order = flask.request.args.get('order', 'desc')
    # adding size as paging arguments
    size = flask.request.args.get('size', 'large')
    # adding chrome as paging arguments
    chrome = flask.request.args.get('chrome', 'true')

    # Response formatting arguments
    callback = flask.request.args.get('callback', None)
    meta = flask.request.args.getlist('meta')

    arguments = dict(
        start=start,
        delta=delta,
        end=end,
        users=users,
        packages=packages,
        categories=categories,
        topics=topics,
        contains=contains,
        not_users=not_users,
        not_packages=not_packages,
        not_categories=not_categories,
        not_topics=not_topics,
        page=page,
        rows_per_page=rows_per_page,
        order=order,
        meta=meta,
    )

    if page < 1:
        raise ValueError("page must be > 0")

    if rows_per_page > 100:
        raise ValueError("rows_per_page must be <= 100")

    if order not in ['desc', 'asc']:
        raise ValueError("order must be either 'desc' or 'asc'")

    # check size value
    possible_sizes = ['small', 'medium', 'large', 'extra-large']
    if size not in possible_sizes:
        raise ValueError("size must be in one of these %r" % possible_sizes)

    # checks chrome value
    if chrome not in ['true', 'false']:
        raise ValueError("chrome should be either 'true' or 'false'")

    try:
        # This fancy classmethod does all of our search for us.
        total, pages, messages = dm.Message.grep(
            start=start and datetime.fromtimestamp(start),
            end=end and datetime.fromtimestamp(end),
            page=page,
            rows_per_page=rows_per_page,
            order=order,
            users=users,
            packages=packages,
            categories=categories,
            topics=topics,
            contains=contains,
            not_users=not_users,
            not_packages=not_packages,
            not_categories=not_categories,
            not_topics=not_topics,
        )

        # Convert our messages from sqlalchemy objects to json-like dicts
        messages = [msg.__json__() for msg in messages]
        if meta:
            for message in messages:
                message = meta_argument(message, meta)

        output = dict(
            raw_messages=messages,
            total=total,
            pages=pages,
            count=len(messages),
            arguments=arguments,
        )
        status = 200
    except Exception as e:
        output = dict(
            error=str(e),
            arguments=arguments,
        )

        # :D
        if app.config.get('DEBUG', False):
            output['tb'] = traceback.format_exc().split('\n')

        status = 500

    body = fedmsg.encoding.dumps(output)

    mimetype = flask.request.headers.get('Accept')

    if callback:
        mimetype = 'application/javascript'
        body = "%s(%s);" % (callback, body)

    # return HTML content else json
    if not callback and request_wants_html():
        # convert string into python dictionary
        obj = json.loads(body)
        # extract the messages
        raw_message_list = obj["raw_messages"]

        final_message_list = []

        for msg in raw_message_list:
            # message_card module will handle size
            message = message_card(msg, size)
            # add msg_id to the message dictionary
            if (msg["msg_id"] is not None):
                message['msg_id'] = msg["msg_id"]
            final_message_list.append(message)

        # removes boilerlate codes if chrome value is false
        if chrome == 'true':
            return flask.render_template(
                "base.html",
                size=size,
                response=final_message_list,
                heading="Raw Messages",
            )
        else:
            return flask.render_template(
                "raw.html",
                size=size,
                response=final_message_list,
            )

    else:
        return flask.Response(
            response=body,
            status=status,
            mimetype=mimetype,
        )
Ejemplo n.º 15
0
def make_charts(chart_type):
    """ Return SVGs graphing db content. """

    # Perform our complicated datetime logic
    start = flask.request.args.get('start', None)
    end = flask.request.args.get('end', None)
    delta = flask.request.args.get('delta', None)
    start, end, delta = assemble_timerange(start, end, delta)

    # Further filters, all ANDed together in CNF style.
    users = flask.request.args.getlist('user')
    packages = flask.request.args.getlist('package')
    categories = flask.request.args.getlist('category')
    topics = flask.request.args.getlist('topic')
    contains = flask.request.args.getlist('contains')

    # Still more filters.. negations of the previous ones.
    not_users = flask.request.args.getlist('not_user')
    not_packages = flask.request.args.getlist('not_package')
    not_categories = flask.request.args.getlist('not_category')
    not_topics = flask.request.args.getlist('not_topic')

    end = end and datetime.fromtimestamp(end)
    start = start and datetime.fromtimestamp(start)
    end = end or datetime.utcnow()
    start = start or end - timedelta(days=365)

    human_readable = flask.request.args.get('human_readable', True, asbool)
    logarithmic = flask.request.args.get('logarithmic', False, asbool)
    show_x_labels = flask.request.args.get('show_x_labels', True, asbool)
    show_y_labels = flask.request.args.get('show_y_labels', True, asbool)
    show_dots = flask.request.args.get('show_dots', True, asbool)
    fill = flask.request.args.get('fill', False, asbool)

    title = flask.request.args.get('title', 'fedmsg events')
    width = flask.request.args.get('width', 800, int)
    height = flask.request.args.get('height', 800, int)

    interpolation = flask.request.args.get('interpolation', None)
    interpolation_types = [
        None,
        'quadratic',
        'cubic',
    ]
    if interpolation not in interpolation_types:
        flask.abort(404, "%s not in %r" % (interpolation, interpolation_types))

    chart_types = {
        'line': 'Line',
        'stackedline': 'StackedLine',
        'xy': 'XY',
        'bar': 'Bar',
        'horizontalbar': 'HorizontalBar',
        'stackedbar': 'StackedBar',
        'horizontalstackedbar': 'HorizontalStackedBar',
        'funnel': 'Funnel',
        'pyramid': 'Pyramid',
        'verticalpyramid': 'VerticalPyramid',
        'dot': 'Dot',
        'gauge': 'Gauge',
    }
    if chart_type not in chart_types:
        flask.abort(404, "%s not in %r" % (chart_type, chart_types))

    style = flask.request.args.get('style', 'default')
    if style not in pygal.style.styles:
        flask.abort(404, "%s not in %r" % (style, pygal.style.styles))
    style = pygal.style.styles[style]

    chart = getattr(pygal, chart_types[chart_type])(
        human_readable=human_readable,
        logarithmic=logarithmic,
        show_x_labels=show_x_labels,
        show_y_labels=show_y_labels,
        show_dots=show_dots,
        fill=fill,
        title=title,
        width=width,
        height=height,
        interpolate=interpolation,
        x_label_rotation=45,
        style=style,
    )


    lookup = locals()
    factor_names = flask.request.args.getlist('split_on')
    factor_names = [name for name in factor_names if lookup[name]]
    factor_values = [lookup[name] for name in factor_names]
    factors = list(itertools.product(*factor_values))

    N = int(flask.request.args.get('N', 10))
    if N < 3:
        flask.abort(500, 'N must be greater than 3')
    if N > 15:
        flask.abort(500, 'N must be less than 15')

    try:
        labels = []

        kwargs = dict(
            users=users,
            packages=packages,
            categories=categories,
            topics=topics,
            contains=contains,
        )

        dates = [i for i, _ in daterange(start, end, N)]
        if human_readable:
            labels = [arrow.get(i).humanize() for i in dates]
        else:
            labels = [unicode(arrow.get(i).date()) for i in dates]

        for factor in factors:
            for i, name in enumerate(factor_names):
                kwargs[name] = [factor[i]]

            values = []

            for i, j in daterange(start, end, N):
                count, _, _ = dm.Message.grep(
                    start=i,
                    end=j,
                    rows_per_page=None,
                    defer=True,
                    not_users=not_users,
                    not_packages=not_packages,
                    not_categories=not_categories,
                    not_topics=not_topics,
                    **kwargs
                )
                values.append(count)
            tag = factor and " & ".join(factor) or "events"

            # Truncate things to make charts prettier
            if tag.startswith('org.fedoraproject.prod.'):
                tag = tag[len('org.fedoraproject.prod.'):]

            chart.add(tag, values)

        chart.x_labels = labels
        output = chart.render()
        status = 200
        mimetype = 'image/svg+xml'
    except Exception as e:
        import traceback
        traceback.print_exc()
        output = "Error, %r" % e
        status = 500
        mimetype = 'text/html'

    return flask.Response(
        response=output,
        status=status,
        mimetype=mimetype,
    )
Ejemplo n.º 16
0
def raw():
    """ Main API entry point. """

    # Perform our complicated datetime logic
    start = flask.request.args.get('start', None)
    end = flask.request.args.get('end', None)
    default_delta = app.config['DEFAULT_QUERY_DELTA']
    delta = flask.request.args.get('delta')
    if not (start or end or delta):
        delta = default_delta
    start, end, delta = assemble_timerange(start, end, delta)

    # Further filters, all ANDed together in CNF style.
    users = flask.request.args.getlist('user')
    packages = flask.request.args.getlist('package')
    categories = flask.request.args.getlist('category')
    topics = flask.request.args.getlist('topic')
    contains = flask.request.args.getlist('contains')

    # Still more filters.. negations of the previous ones.
    not_users = flask.request.args.getlist('not_user')
    not_packages = flask.request.args.getlist('not_package')
    not_categories = flask.request.args.getlist('not_category')
    not_topics = flask.request.args.getlist('not_topic')

    # Paging arguments
    page = int(flask.request.args.get('page', 1))
    rows_per_page = int(flask.request.args.get('rows_per_page', 25))
    order = flask.request.args.get('order', 'desc')
    # adding size as paging arguments
    size = flask.request.args.get('size', 'large')
    # adding chrome as paging arguments
    chrome = flask.request.args.get('chrome', 'true')

    # Response formatting arguments
    callback = flask.request.args.get('callback', None)
    meta = flask.request.args.getlist('meta')
    grouped = flask.request.args.get('grouped', False, asbool)

    arguments = dict(
        start=start,
        delta=delta,
        end=end,
        users=users,
        packages=packages,
        categories=categories,
        topics=topics,
        contains=contains,
        not_users=not_users,
        not_packages=not_packages,
        not_categories=not_categories,
        not_topics=not_topics,
        page=page,
        rows_per_page=rows_per_page,
        order=order,
        meta=meta,
        grouped=grouped,
    )

    if page < 1:
        raise ValueError("page must be > 0")

    if rows_per_page > 100:
        raise ValueError("rows_per_page must be <= 100")

    if order not in ['desc', 'asc']:
        raise ValueError("order must be either 'desc' or 'asc'")

    # check size value
    possible_sizes = ['small', 'medium', 'large', 'extra-large']
    if size not in possible_sizes:
        raise ValueError("size must be in one of these %r" % possible_sizes)

    # checks chrome value
    if chrome not in ['true', 'false']:
        raise ValueError("chrome should be either 'true' or 'false'")

    if contains and datetime.fromtimestamp(
            start or 0) < (datetime.utcnow() - timedelta(weeks=4 * 8)):
        raise BadRequest('When using contains, specify a start at most '
                         'eight months into the past')

    if contains and not (categories or topics):
        raise BadRequest('When using contains, specify either a topic or'
                         ' a category as well')

    try:
        # This fancy classmethod does all of our search for us.
        total, pages, messages = dm.Message.grep(
            start=start and datetime.fromtimestamp(start),
            end=end and datetime.fromtimestamp(end),
            page=page,
            rows_per_page=rows_per_page,
            order=order,
            users=users,
            packages=packages,
            categories=categories,
            topics=topics,
            contains=contains,
            not_users=not_users,
            not_packages=not_packages,
            not_categories=not_categories,
            not_topics=not_topics,
        )

        # Convert our messages from sqlalchemy objects to json-like dicts
        messages = [msg.__json__() for msg in messages]
        if grouped:
            messages = fedmsg.meta.conglomerate(messages, **fedmsg_config)
            for message in messages:
                message['date'] = arrow.get(message['timestamp']).humanize()
        elif meta:
            for message in messages:
                message = meta_argument(message, meta)

        output = dict(
            raw_messages=messages,
            total=total,
            pages=pages,
            count=len(messages),
            arguments=arguments,
        )
        status = 200
    except Exception as e:
        traceback.print_exc()

        output = dict(
            error=str(e),
            arguments=arguments,
        )

        # :D
        if app.config.get('DEBUG', False):
            output['tb'] = traceback.format_exc().split('\n')

        status = 500

    body = fedmsg.encoding.dumps(output)

    mimetype = flask.request.headers.get('Accept')

    # Our default - http://da.gd/vIIV
    if mimetype == '*/*':
        mimetype = 'application/json'

    if callback:
        mimetype = 'application/javascript'
        body = "%s(%s);" % (callback, body)

    # return HTML content else json
    if not callback and request_wants_html():
        # convert string into python dictionary
        obj = json.loads(body)
        # extract the messages
        raw_message_list = obj.get("raw_messages", [])

        final_message_list = []

        for msg in raw_message_list:
            if not grouped:
                # message_card module will handle size
                message = message_card(msg, size)
                # add msg_id to the message dictionary
                if (msg['msg_id'] is not None):
                    message['msg_id'] = msg['msg_id']
            else:
                message = msg
                message['msg_id'] = None
                if len(message['msg_ids']) == 1:
                    message['msg_id'] = message['msg_ids'].keys()[0]
                message['date'] = arrow.get(message['timestamp'])

            final_message_list.append(message)

        # removes boilerlate codes if chrome value is false
        if chrome == 'true':
            return flask.render_template(
                "base.html",
                size=size,
                response=final_message_list,
                arguments=arguments,
                autoscroll=True,
            )
        else:
            return flask.render_template(
                "raw.html",
                size=size,
                response=final_message_list,
                arguments=arguments,
            )

    else:
        return flask.Response(
            response=body,
            status=status,
            mimetype=mimetype,
        )
Ejemplo n.º 17
0
 def test_delta_none_none(self):
     start, end, delta = assemble_timerange(None, None, 5)
     eq_(1325375995.0, start)
     eq_(1325376000.0, end)
     eq_(5, delta)
Ejemplo n.º 18
0
def raw():
    """ Main API entry point. """

    # Perform our complicated datetime logic
    start = flask.request.args.get('start', None)
    end = flask.request.args.get('end', None)
    delta = flask.request.args.get('delta', None)
    start, end, delta = assemble_timerange(start, end, delta)

    start_id = flask.request.args.get('start_id', None)
    end_id = flask.request.args.get('end_id', None)

    # Further filters, all ANDed together in CNF style.
    users = flask.request.args.getlist('user')
    packages = flask.request.args.getlist('package')
    categories = flask.request.args.getlist('category')
    topics = flask.request.args.getlist('topic')
    contains = flask.request.args.getlist('contains')

    # Still more filters.. negations of the previous ones.
    not_users = flask.request.args.getlist('not_user')
    not_packages = flask.request.args.getlist('not_package')
    not_categories = flask.request.args.getlist('not_category')
    not_topics = flask.request.args.getlist('not_topic')

    # Paging arguments
    page = int(flask.request.args.get('page', 1))
    rows_per_page = int(flask.request.args.get('rows_per_page', 25))
    order = flask.request.args.get('order', 'desc')
    # adding size as paging arguments
    size = flask.request.args.get('size', 'large')
    # adding chrome as paging arguments
    chrome = flask.request.args.get('chrome', 'true')

    # Response formatting arguments
    callback = flask.request.args.get('callback', None)
    meta = flask.request.args.getlist('meta')
    grouped = flask.request.args.get('grouped', False, asbool)

    arguments = dict(
        start=start,
        delta=delta,
        end=end,
        start_id=start_id,
        end_id=end_id,
        users=users,
        packages=packages,
        categories=categories,
        topics=topics,
        contains=contains,
        not_users=not_users,
        not_packages=not_packages,
        not_categories=not_categories,
        not_topics=not_topics,
        page=page,
        rows_per_page=rows_per_page,
        order=order,
        meta=meta,
        grouped=grouped,
    )

    if page < 1:
        raise ValueError("page must be > 0")

    if rows_per_page > 100:
        raise ValueError("rows_per_page must be <= 100")

    if order not in ['desc', 'asc']:
        raise ValueError("order must be either 'desc' or 'asc'")

    # check size value
    possible_sizes = ['small', 'medium', 'large', 'extra-large']
    if size not in possible_sizes:
        raise ValueError("size must be in one of these %r" % possible_sizes)

    # checks chrome value
    if chrome not in ['true', 'false']:
        raise ValueError("chrome should be either 'true' or 'false'")

    if start or end or delta:
        start_id = None
        end_id = None
    else:
        if start_id:
            start_msg = dm.Message.query.filter_by(msg_id=start_id).first()
            start = start_msg.timestamp.strftime('%s')
        if end_id:
            end_msg = dm.Message.query.filter_by(msg_id=end_id).first()
            end = end_msg.timestamp.strftime('%s')

        start, end, delta = assemble_timerange(start, end, delta)

    if contains and datetime.fromtimestamp(start or 0) < (datetime.utcnow() - timedelta(weeks=4*8)):
        raise BadRequest('When using contains, specify a start at most '
                         'eight months into the past')

    if contains and not (categories or topics):
        raise BadRequest('When using contains, specify either a topic or'
                         ' a category as well')

    try:
        # This fancy classmethod does all of our search for us.
        total, pages, messages = dm.Message.grep(
            start=start and datetime.fromtimestamp(start),
            end=end and datetime.fromtimestamp(end),
            page=page,
            rows_per_page=rows_per_page,
            order=order,
            users=users,
            packages=packages,
            categories=categories,
            topics=topics,
            contains=contains,
            not_users=not_users,
            not_packages=not_packages,
            not_categories=not_categories,
            not_topics=not_topics,
        )

        # Convert our messages from sqlalchemy objects to json-like dicts
        messages = [msg.__json__() for msg in messages]
        if grouped:
            messages = fedmsg.meta.conglomerate(messages, **fedmsg_config)
            for message in messages:
                message['date'] = arrow.get(message['timestamp']).humanize()
        elif meta:
            for message in messages:
                message = meta_argument(message, meta)

        output = dict(
            raw_messages=messages,
            total=total,
            pages=pages,
            count=len(messages),
            arguments=arguments,
        )
        status = 200
    except Exception as e:
        traceback.print_exc()

        output = dict(
            error=str(e),
            arguments=arguments,
        )

        # :D
        if app.config.get('DEBUG', False):
            output['tb'] = traceback.format_exc().split('\n')

        status = 500

    body = fedmsg.encoding.dumps(output)

    mimetype = flask.request.headers.get('Accept')

    # Our default - http://da.gd/vIIV
    if mimetype == '*/*':
        mimetype = 'application/json'

    if callback:
        mimetype = 'application/javascript'
        body = "%s(%s);" % (callback, body)

    # return HTML content else json
    if not callback and request_wants_html():
        # convert string into python dictionary
        obj = json.loads(body)
        # extract the messages
        raw_message_list = obj.get("raw_messages", [])

        final_message_list = []

        for msg in raw_message_list:
            if not grouped:
                # message_card module will handle size
                message = message_card(msg, size)
                # add msg_id to the message dictionary
                if (msg['msg_id'] is not None):
                    message['msg_id'] = msg['msg_id']
            else:
                message = msg
                message['msg_id'] = None
                if len(message['msg_ids']) == 1:
                    message['msg_id'] = message['msg_ids'].keys()[0]
                message['date'] = arrow.get(message['timestamp'])

            final_message_list.append(message)

        # removes boilerlate codes if chrome value is false
        if chrome == 'true':
            return flask.render_template(
                "base.html",
                size=size,
                response=final_message_list,
                arguments=arguments,
                autoscroll=True,
            )
        else:
            return flask.render_template(
                "raw.html",
                size=size,
                response=final_message_list,
                arguments=arguments,
            )

    else:
        return flask.Response(
            response=body,
            status=status,
            mimetype=mimetype,
        )
Ejemplo n.º 19
0
 def test_none_none_none(self):
     start, end, delta = assemble_timerange(None, None, None)
     eq_(None, start)
     eq_(None, end)
     eq_(None, delta)
Ejemplo n.º 20
0
def raw():
    """ Main API entry point. """

    # Perform our complicated datetime logic
    start = flask.request.args.get('start', None)
    end = flask.request.args.get('end', None)
    delta = flask.request.args.get('delta', None)
    start, end, delta = assemble_timerange(start, end, delta)

    # Further filters, all ANDed together in CNF style.
    users = flask.request.args.getlist('user')
    packages = flask.request.args.getlist('package')
    categories = flask.request.args.getlist('category')
    topics = flask.request.args.getlist('topic')
    contains = flask.request.args.getlist('contains')

    # Still more filters.. negations of the previous ones.
    not_users = flask.request.args.getlist('not_user')
    not_packages = flask.request.args.getlist('not_package')
    not_categories = flask.request.args.getlist('not_category')
    not_topics = flask.request.args.getlist('not_topic')

    # Paging arguments
    page = int(flask.request.args.get('page', 1))
    rows_per_page = int(flask.request.args.get('rows_per_page', 20))
    order = flask.request.args.get('order', 'desc')
    # adding size as paging arguments
    size = flask.request.args.get('size', 'large')
    # adding chrome as paging arguments
    chrome = flask.request.args.get('chrome', 'true')

    # Response formatting arguments
    callback = flask.request.args.get('callback', None)
    meta = flask.request.args.getlist('meta')

    arguments = dict(
        start=start,
        delta=delta,
        end=end,
        users=users,
        packages=packages,
        categories=categories,
        topics=topics,
        contains=contains,
        not_users=not_users,
        not_packages=not_packages,
        not_categories=not_categories,
        not_topics=not_topics,
        page=page,
        rows_per_page=rows_per_page,
        order=order,
        meta=meta,
    )

    if page < 1:
        raise ValueError("page must be > 0")

    if rows_per_page > 100:
        raise ValueError("rows_per_page must be <= 100")

    if order not in ['desc', 'asc']:
        raise ValueError("order must be either 'desc' or 'asc'")

    # check size value
    possible_sizes = ['small', 'medium', 'large', 'extra-large']
    if size not in possible_sizes:
        raise ValueError("size must be in one of these %r" % possible_sizes)

    # checks chrome value
    if chrome not in ['true', 'false']:
        raise ValueError("chrome should be either 'true' or 'false'")

    try:
        # This fancy classmethod does all of our search for us.
        total, pages, messages = dm.Message.grep(
            start=start and datetime.fromtimestamp(start),
            end=end and datetime.fromtimestamp(end),
            page=page,
            rows_per_page=rows_per_page,
            order=order,
            users=users,
            packages=packages,
            categories=categories,
            topics=topics,
            contains=contains,
            not_users=not_users,
            not_packages=not_packages,
            not_categories=not_categories,
            not_topics=not_topics,
        )

        # Convert our messages from sqlalchemy objects to json-like dicts
        messages = [msg.__json__() for msg in messages]
        if meta:
            for message in messages:
                message = meta_argument(message, meta)

        output = dict(
            raw_messages=messages,
            total=total,
            pages=pages,
            count=len(messages),
            arguments=arguments,
        )
        status = 200
    except Exception as e:
        output = dict(
            error=str(e),
            arguments=arguments,
        )

        # :D
        if app.config.get('DEBUG', False):
            output['tb'] = traceback.format_exc().split('\n')

        status = 500

    body = fedmsg.encoding.dumps(output)

    mimetype = flask.request.headers.get('Accept')

    if callback:
        mimetype = 'application/javascript'
        body = "%s(%s);" % (callback, body)

    # return HTML content else json
    if not callback and request_wants_html():
        # convert string into python dictionary
        obj = json.loads(body)
        # extract the messages
        raw_message_list = obj["raw_messages"]

        final_message_list = []

        for msg in raw_message_list:
            # message_card module will handle size
            message = message_card(msg, size)
            # add msg_id to the message dictionary
            if (msg["msg_id"] is not None):
                message['msg_id'] = msg["msg_id"]
            final_message_list.append(message)

        # removes boilerlate codes if chrome value is false
        if chrome == 'true':
            return flask.render_template(
                "base.html",
                size=size,
                response=final_message_list,
                heading="Raw Messages",
            )
        else:
            return flask.render_template(
                "raw.html",
                size=size,
                response=final_message_list,
            )

    else:
        return flask.Response(
            response=body,
            status=status,
            mimetype=mimetype,
        )
Ejemplo n.º 21
0
 def test_delta_none_none(self):
     start, end, delta = assemble_timerange(None, None, 5)
     eq_(1325375995.0, start)
     eq_(1325376000.0, end)
     eq_(5, delta)
Ejemplo n.º 22
0
def make_charts(chart_type):
    """ Return SVGs graphing db content. """

    # Perform our complicated datetime logic
    start = flask.request.args.get('start', None)
    end = flask.request.args.get('end', None)
    delta = flask.request.args.get('delta', None)
    start, end, delta = assemble_timerange(start, end, delta)

    # Further filters, all ANDed together in CNF style.
    users = flask.request.args.getlist('user')
    packages = flask.request.args.getlist('package')
    categories = flask.request.args.getlist('category')
    topics = flask.request.args.getlist('topic')
    contains = flask.request.args.getlist('contains')

    # Still more filters.. negations of the previous ones.
    not_users = flask.request.args.getlist('not_user')
    not_packages = flask.request.args.getlist('not_package')
    not_categories = flask.request.args.getlist('not_category')
    not_topics = flask.request.args.getlist('not_topic')

    end = end and datetime.fromtimestamp(end)
    start = start and datetime.fromtimestamp(start)
    end = end or datetime.utcnow()
    start = start or end - timedelta(days=365)

    human_readable = flask.request.args.get('human_readable', True, asbool)
    logarithmic = flask.request.args.get('logarithmic', False, asbool)
    show_x_labels = flask.request.args.get('show_x_labels', True, asbool)
    show_y_labels = flask.request.args.get('show_y_labels', True, asbool)
    show_dots = flask.request.args.get('show_dots', True, asbool)
    fill = flask.request.args.get('fill', False, asbool)

    title = flask.request.args.get('title', 'fedmsg events')
    width = flask.request.args.get('width', 800, int)
    height = flask.request.args.get('height', 800, int)

    interpolation = flask.request.args.get('interpolation', None)
    interpolation_types = [
        None,
        'quadratic',
        'cubic',
    ]
    if interpolation not in interpolation_types:
        flask.abort(404, "%s not in %r" % (interpolation, interpolation_types))

    chart_types = {
        'line': 'Line',
        'stackedline': 'StackedLine',
        'xy': 'XY',
        'bar': 'Bar',
        'horizontalbar': 'HorizontalBar',
        'stackedbar': 'StackedBar',
        'horizontalstackedbar': 'HorizontalStackedBar',
        'funnel': 'Funnel',
        'pyramid': 'Pyramid',
        'verticalpyramid': 'VerticalPyramid',
        'dot': 'Dot',
        'gauge': 'Gauge',
    }
    if chart_type not in chart_types:
        flask.abort(404, "%s not in %r" % (chart_type, chart_types))

    style = flask.request.args.get('style', 'default')
    if style not in pygal.style.styles:
        flask.abort(404, "%s not in %r" % (style, pygal.style.styles))
    style = pygal.style.styles[style]

    chart = getattr(pygal, chart_types[chart_type])(
        human_readable=human_readable,
        logarithmic=logarithmic,
        show_x_labels=show_x_labels,
        show_y_labels=show_y_labels,
        show_dots=show_dots,
        fill=fill,
        title=title,
        width=width,
        height=height,
        interpolate=interpolation,
        x_label_rotation=45,
        style=style,
    )

    lookup = locals()
    factor_names = flask.request.args.getlist('split_on')
    factor_names = [name for name in factor_names if lookup[name]]
    factor_values = [lookup[name] for name in factor_names]
    factors = list(itertools.product(*factor_values))

    N = int(flask.request.args.get('N', 10))
    if N < 3:
        flask.abort(500, 'N must be greater than 3')
    if N > 15:
        flask.abort(500, 'N must be less than 15')

    try:
        labels = []

        kwargs = dict(
            users=users,
            packages=packages,
            categories=categories,
            topics=topics,
            contains=contains,
        )

        dates = [i for i, _ in daterange(start, end, N)]
        if human_readable:
            labels = [arrow.get(i).humanize() for i in dates]
        else:
            labels = [unicode(arrow.get(i).date()) for i in dates]

        for factor in factors:
            for i, name in enumerate(factor_names):
                kwargs[name] = [factor[i]]

            values = []

            for i, j in daterange(start, end, N):
                count, _, _ = dm.Message.grep(start=i,
                                              end=j,
                                              rows_per_page=None,
                                              defer=True,
                                              not_users=not_users,
                                              not_packages=not_packages,
                                              not_categories=not_categories,
                                              not_topics=not_topics,
                                              **kwargs)
                values.append(count)
            tag = factor and " & ".join(factor) or "events"

            # Truncate things to make charts prettier
            if tag.startswith('org.fedoraproject.prod.'):
                tag = tag[len('org.fedoraproject.prod.'):]

            chart.add(tag, values)

        chart.x_labels = labels
        output = chart.render()
        status = 200
        mimetype = 'image/svg+xml'
    except Exception as e:
        import traceback
        traceback.print_exc()
        output = "Error, %r" % e
        status = 500
        mimetype = 'text/html'

    return flask.Response(
        response=output,
        status=status,
        mimetype=mimetype,
    )
Ejemplo n.º 23
0
 def test_none_none_none(self):
     start, end, delta = assemble_timerange(None, None, None)
     eq_(None, start)
     eq_(None, end)
     eq_(None, delta)