mirror of
https://pagure.io/fm-orchestrator.git
synced 2026-04-14 14:39:43 +08:00
Add filtering to the module-builds route
This commit is contained in:
committed by
Nils Philippsen
parent
c79139b82c
commit
361de94693
25
rida/errors.py
Normal file
25
rida/errors.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# Copyright (c) 2016 Red Hat, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# Written by Matt Prahl <mprahl@redhat.com>
|
||||
""" Defines custom exceptions and error handling functions """
|
||||
|
||||
class ValidationError(ValueError):
|
||||
pass
|
||||
@@ -22,9 +22,12 @@
|
||||
# Matt Prahl <mprahl@redhat.com>
|
||||
""" Utility functions for rida. """
|
||||
from flask import request, url_for
|
||||
from datetime import datetime
|
||||
import re
|
||||
import functools
|
||||
import time
|
||||
from rida import log, models
|
||||
from errors import ValidationError
|
||||
|
||||
|
||||
def retry(timeout=120, interval=30, wait_on=Exception):
|
||||
@@ -96,3 +99,61 @@ def pagination_metadata(p_query):
|
||||
per_page=p_query.per_page, _external=True)
|
||||
|
||||
return pagination_data
|
||||
|
||||
|
||||
def filter_module_builds(flask_request):
|
||||
"""
|
||||
Returns a flask_sqlalchemy.Pagination object based on the request parameters
|
||||
:param request: Flask request object
|
||||
:return: flask_sqlalchemy.Pagination
|
||||
"""
|
||||
search_query = dict()
|
||||
state = flask_request.args.get('state', None)
|
||||
|
||||
if state:
|
||||
if state.isdigit():
|
||||
search_query['state'] = state
|
||||
else:
|
||||
if state in models.BUILD_STATES:
|
||||
search_query['state'] = models.BUILD_STATES[state]
|
||||
else:
|
||||
raise ValidationError('An invalid state was supplied')
|
||||
|
||||
for key in ['name', 'owner']:
|
||||
if flask_request.args.get(key, None):
|
||||
search_query[key] = flask_request.args[key]
|
||||
|
||||
query = models.ModuleBuild.query
|
||||
|
||||
if search_query:
|
||||
query = query.filter_by(**search_query)
|
||||
|
||||
# This is used when filtering the date request parameters, but it is here to avoid recompiling
|
||||
utc_iso_datetime_regex = re.compile(r'^(?P<datetime>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.\d+)?'
|
||||
r'(?:Z|[-+]00(?::00)?)?$')
|
||||
|
||||
# Filter the query based on date request parameters
|
||||
for item in ('submitted', 'modified', 'completed'):
|
||||
for context in ('before', 'after'):
|
||||
request_arg = '%s_%s' % (item, context) # i.e. submitted_before
|
||||
iso_datetime_arg = request.args.get(request_arg, None)
|
||||
|
||||
if iso_datetime_arg:
|
||||
iso_datetime_matches = re.match(utc_iso_datetime_regex, iso_datetime_arg)
|
||||
|
||||
if not iso_datetime_matches or not iso_datetime_matches.group('datetime'):
|
||||
raise ValidationError('An invalid Zulu ISO 8601 timestamp was provided for the "%s" parameter'
|
||||
% request_arg)
|
||||
# Converts the ISO 8601 string to a datetime object for SQLAlchemy to use to filter
|
||||
item_datetime = datetime.strptime(iso_datetime_matches.group('datetime'), '%Y-%m-%dT%H:%M:%S')
|
||||
# Get the database column to filter against
|
||||
column = getattr(models.ModuleBuild, 'time_' + item)
|
||||
|
||||
if context == 'after':
|
||||
query = query.filter(column >= item_datetime)
|
||||
elif context == 'before':
|
||||
query = query.filter(column <= item_datetime)
|
||||
|
||||
page = flask_request.args.get('page', 1, type=int)
|
||||
per_page = flask_request.args.get('per_page', 10, type=int)
|
||||
return query.paginate(page, per_page, False)
|
||||
|
||||
@@ -39,13 +39,13 @@ import shutil
|
||||
import tempfile
|
||||
from rida import app, conf, db, log
|
||||
from rida import models
|
||||
from rida.utils import pagination_metadata
|
||||
from rida.utils import pagination_metadata, filter_module_builds
|
||||
from errors import ValidationError
|
||||
|
||||
|
||||
@app.route("/rida/module-builds/", methods=["POST"])
|
||||
def submit_build():
|
||||
"""Handles new module build submissions."""
|
||||
# Get the time from when the build was submitted
|
||||
username = rida.auth.is_packager(conf.pkgdb_api_url)
|
||||
if not username:
|
||||
return "You must use your Fedora certificate when submitting a new build", 403
|
||||
@@ -165,15 +165,17 @@ def submit_build():
|
||||
@app.route("/rida/module-builds/", methods=["GET"])
|
||||
def query_builds():
|
||||
"""Lists all tracked module builds."""
|
||||
page = request.args.get('page', 1, type=int)
|
||||
per_page = request.args.get('per_page', 10, type=int)
|
||||
p_query = models.ModuleBuild.query.paginate(page, per_page, False)
|
||||
verbose_flag = request.args.get('verbose', 'false')
|
||||
try:
|
||||
p_query = filter_module_builds(request)
|
||||
except ValidationError as e:
|
||||
return e.message, 400
|
||||
|
||||
json_data = {
|
||||
'meta': pagination_metadata(p_query)
|
||||
}
|
||||
|
||||
verbose_flag = request.args.get('verbose', 'false')
|
||||
|
||||
if verbose_flag.lower() == 'true' or verbose_flag == '1':
|
||||
json_data['items'] = [item.api_json() for item in p_query.items]
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user