Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
commit 1ac84d1bc13763d1dded51cc5d62fcbcb64ac2c7 Author: Valentin Gologuzov vgologuz@redhat.com Date: Fri Aug 21 15:57:59 2015 +0200
[frontend][api] removed bp_url_for; use hardcoded endpoints to avoid cyclic imports; use copr_id instead of user/project
.../coprs_frontend/coprs/logic/builds_logic.py | 8 ++ frontend/coprs_frontend/coprs/logic/coprs_logic.py | 4 + frontend/coprs_frontend/coprs/rest_api/__init__.py | 19 +++--- .../coprs/rest_api/resources/build.py | 55 +++++++++------ .../coprs/rest_api/resources/chroot.py | 43 ++++++------ .../coprs/rest_api/resources/copr.py | 77 +++++++++++--------- frontend/coprs_frontend/coprs/rest_api/schemas.py | 6 +- frontend/coprs_frontend/coprs/rest_api/util.py | 12 --- 8 files changed, 121 insertions(+), 103 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/logic/builds_logic.py b/frontend/coprs_frontend/coprs/logic/builds_logic.py index 45829fc..be28dbd 100644 --- a/frontend/coprs_frontend/coprs/logic/builds_logic.py +++ b/frontend/coprs_frontend/coprs/logic/builds_logic.py @@ -106,6 +106,14 @@ class BuildsLogic(object): return cls.get_multiple().filter(models.Build.copr == copr)
@classmethod + def get_multiple_by_owner(cls, user): + """ Get collection of builds in copr sorted by build_id descending + form the copr owned by `user` + """ + return cls.get_multiple().join(models.Build.copr).filter( + models.Copr.owner == user) + + @classmethod def get_multiple_by_name(cls, username, coprname): query = cls.get_multiple() return (query.join(models.Build.copr) diff --git a/frontend/coprs_frontend/coprs/logic/coprs_logic.py b/frontend/coprs_frontend/coprs/logic/coprs_logic.py index 4e53e37..7110ea9 100644 --- a/frontend/coprs_frontend/coprs/logic/coprs_logic.py +++ b/frontend/coprs_frontend/coprs/logic/coprs_logic.py @@ -32,6 +32,10 @@ class CoprsLogic(object): return query
@classmethod + def get_by_id(cls, copr_id): + return cls.get_all().filter(models.Copr.id == copr_id) + + @classmethod def get(cls, username, coprname, **kwargs): with_builds = kwargs.get("with_builds", False) with_mock_chroots = kwargs.get("with_mock_chroots", False) diff --git a/frontend/coprs_frontend/coprs/rest_api/__init__.py b/frontend/coprs_frontend/coprs/rest_api/__init__.py index 309ba44..d94ad8f 100644 --- a/frontend/coprs_frontend/coprs/rest_api/__init__.py +++ b/frontend/coprs_frontend/coprs/rest_api/__init__.py @@ -6,9 +6,8 @@ from flask_restful_swagger import swagger
from coprs.rest_api.exceptions import ApiError from coprs.rest_api.resources.build import BuildListR, BuildR -from coprs.rest_api.resources.chroot import ChrootListR, ChrootR +from coprs.rest_api.resources.chroot import MockChrootListR, MockChrootR from coprs.rest_api.resources.copr import CoprListR, CoprR -from coprs.rest_api.util import bp_url_for
URL_PREFIX = "/api_2.0" @@ -21,11 +20,11 @@ class RootR(Resource): ) def get(self): return { - "links": { - "self": bp_url_for(RootR.endpoint), - "coprs": bp_url_for(CoprListR.endpoint), - "chroots": bp_url_for(ChrootListR.endpoint), - "builds": bp_url_for(BuildListR.endpoint), + "_links": { + "self": {"href": url_for(".rootr")}, + "coprs": {"href": url_for(".coprlistr")}, + "copr_chroots": {"href": url_for(".mockchrootlistr")}, + "builds": {"href": url_for(".buildlistr")}, } }
@@ -77,10 +76,10 @@ api = MyApi(
api.add_resource(RootR, "/") api.add_resource(CoprListR, "/coprs") -api.add_resource(CoprR, "/coprs/<owner>/<project>") +api.add_resource(CoprR, "/coprs/int:copr_id")
-api.add_resource(ChrootListR, "/chroots") -api.add_resource(ChrootR, "/chroots/<name>") +api.add_resource(MockChrootListR, "/mock_chroots") +api.add_resource(MockChrootR, "/mock_chroots/<name>")
api.add_resource(BuildListR, "/builds") api.add_resource(BuildR, "/builds/int:build_id") diff --git a/frontend/coprs_frontend/coprs/rest_api/resources/build.py b/frontend/coprs_frontend/coprs/rest_api/resources/build.py index 1db3bf4..ca5f0c1 100644 --- a/frontend/coprs_frontend/coprs/rest_api/resources/build.py +++ b/frontend/coprs_frontend/coprs/rest_api/resources/build.py @@ -1,15 +1,17 @@ # coding: utf-8
import flask +from flask import url_for
# from flask_restful_swagger import swagger
from coprs.logic.coprs_logic import CoprsLogic from coprs.logic.builds_logic import BuildsLogic +from coprs.logic.users_logic import UsersLogic
from coprs.rest_api.schemas import BuildSchema
-from coprs.rest_api.util import get_one_safe, bp_url_for +from coprs.rest_api.util import get_one_safe
from flask_restful import Resource, reqparse
@@ -21,21 +23,26 @@ class BuildListR(Resource): parser = reqparse.RequestParser()
parser.add_argument('owner', type=str,) - parser.add_argument('project', type=str) + parser.add_argument('copr_id', type=int)
parser.add_argument('limit', type=int) parser.add_argument('offset', type=int)
req_args = parser.parse_args()
- if "owner" and "project" in req_args: - query = BuildsLogic.get_multiple_by_name( - req_args["owner"], req_args["project"]) + if req_args["copr_id"] is not None: + copr = get_one_safe(CoprsLogic.get_by_id(req_args["copr_id"])) + query = BuildsLogic.get_multiple_by_copr(copr) + elif req_args["owner" ] is not None: + user = get_one_safe(UsersLogic.get(req_args["owner"])) + query = BuildsLogic.get_multiple_by_owner(user) else: query = BuildsLogic.get_multiple()
if "limit" in req_args: limit = req_args["limit"] + if limit <= 0 or limit > 100: + limit = 100 else: limit = 100
@@ -50,21 +57,17 @@ class BuildListR(Resource): "builds": [ { "build": BuildSchema().dump(build)[0], - "link": bp_url_for(BuildR.endpoint, build_id=build.id), + "_links": { + "self": {"href": url_for(".buildr", build_id=build.id)}, + } } for build in builds ], - "links": { - "self": bp_url_for(BuildListR.endpoint, **req_args), + "_links": { + "self": {"href": url_for(".buildlistr", **req_args)}, }, }
-# @swagger.model -# class BuildItem(object): -# def __init__(self, build_id): -# pass - - class BuildR(Resource):
def get(self, build_id): @@ -73,17 +76,27 @@ class BuildR(Resource): """ build = get_one_safe(BuildsLogic.get(build_id), "Not found build with id: {}".format(build_id)) + return { "build": BuildSchema().dump(build)[0], - "links": { - "self": bp_url_for(BuildR.endpoint, build_id=build_id), - # TODO: can't do this due to circular imports - # "parent_copr": url_for(CoprR.endpoint, - # owner=build.copr.owner.name, - # project=build.copr.name), + "_links": { + "self": url_for(".buildr", build_id=build_id), + "parent_copr": url_for(".coprr", copr_id=build.id), } }
- +# to get build details and cancel individual build chroots +# class BuildChrootR(Resource): +# def get(self, owner, project, name): +# copr = get_one_safe(CoprsLogic.get(flask.g.user, owner, project), +# "Copr {}/{} not found".format(owner, project)) +# chroot = get_one_safe(CoprChrootsLogic.get(copr, name)) +# +# return { +# "chroot": chroot.to_dict(), +# "links": { +# "self": bp_url_for(BuildChrootR.endpoint, owner=owner, project=project, name=name) +# } +# }
diff --git a/frontend/coprs_frontend/coprs/rest_api/resources/chroot.py b/frontend/coprs_frontend/coprs/rest_api/resources/chroot.py index 61d6e5a..bc0ddcc 100644 --- a/frontend/coprs_frontend/coprs/rest_api/resources/chroot.py +++ b/frontend/coprs_frontend/coprs/rest_api/resources/chroot.py @@ -6,49 +6,48 @@ from flask import url_for from flask_restful import Resource, reqparse
from marshmallow import Schema, fields, pprint +from coprs.rest_api.schemas import MockChrootSchema
from coprs.views.misc import api_login_required from coprs.logic.coprs_logic import MockChrootsLogic, CoprChrootsLogic, CoprsLogic
-from ..util import get_one_safe, json_loads_safe, mm_deserialize, bp_url_for +from ..util import get_one_safe, json_loads_safe, mm_deserialize
-class ChrootListR(Resource): +class MockChrootListR(Resource): def get(self): - chroots = MockChrootsLogic.get_multiple(None).all() + # todo: add argument active_only + chroots = MockChrootsLogic.get_multiple(active_only=False).all() return { - "links": { - "self": bp_url_for(ChrootListR.endpoint), + "_links": { + "self": {"href": url_for(".mockchrootlistr")}, }, "chroots": [ { - "chroot": chroot.to_dict(), - "link": url_for(ChrootR.endpoint, name=chroot.name), + "chroot": MockChrootSchema().dump(chroot)[0], + "_links": { + "self": {"href": url_for(".mockchrootr", name=chroot.name)}, + } } for chroot in chroots ] }
-class ChrootR(Resource): +class MockChrootR(Resource): def get(self, name): chroot = get_one_safe(MockChrootsLogic.get_from_name(name)) return { - "chroot": chroot.to_dict(), - "links": { - "self": bp_url_for(ChrootR.endpoint, name=chroot.name) + "chroot": MockChrootSchema().dump(chroot)[0], + "_links": { + "self": {"href": url_for(".mockchrootr", name=chroot.name)}, + "all_chroots": {"href": url_for(".mockchrootlistr")} }, }
-class BuildChrootR(Resource): - def get(self, owner, project, name): - copr = get_one_safe(CoprsLogic.get(flask.g.user, owner, project), - "Copr {}/{} not found".format(owner, project)) - chroot = get_one_safe(CoprChrootsLogic.get(copr, name)) +class CoprChrootListR(Resource): + pass
- return { - "chroot": chroot.to_dict(), - "links": { - "self": bp_url_for(BuildChrootR.endpoint, owner=owner, project=project, name=name) - } - } + +class CoprChrootR(Resource): + pass diff --git a/frontend/coprs_frontend/coprs/rest_api/resources/copr.py b/frontend/coprs_frontend/coprs/rest_api/resources/copr.py index f1f5e48..26991c8 100644 --- a/frontend/coprs_frontend/coprs/rest_api/resources/copr.py +++ b/frontend/coprs_frontend/coprs/rest_api/resources/copr.py @@ -3,6 +3,7 @@ import datetime import functools
import flask +from flask import url_for from flask_restful import Resource, reqparse from marshmallow import pprint
@@ -13,9 +14,10 @@ from coprs.logic.users_logic import UsersLogic from coprs.logic.coprs_logic import CoprsLogic from coprs.exceptions import ActionInProgressException, InsufficientRightsException from .build import BuildListR +# from .chroot import CoprChrootListR, CoprChrootR from coprs.rest_api.schemas import CoprSchema from ..exceptions import ObjectAlreadyExists, AuthFailed -from ..util import get_one_safe, json_loads_safe, mm_deserialize, bp_url_for, render_allowed_method +from ..util import get_one_safe, json_loads_safe, mm_deserialize, render_allowed_method
def rest_api_auth_required(f): @@ -55,7 +57,6 @@ class CoprListR(Resource): Creates new copr """ owner = flask.g.user - # new_copr_dict = json_loads_safe(flask.request.data, "")
result = mm_deserialize(CoprSchema(), flask.request.data) # todo check that chroots are available @@ -77,6 +78,7 @@ class CoprListR(Resource): parser.add_argument('owner', dest='username', type=str) parser.add_argument('limit', type=int) parser.add_argument('offset', type=int) + # parser.add_argument('help', type=bool) req_args = parser.parse_args()
kwargs = {} @@ -92,7 +94,7 @@ class CoprListR(Resource): # todo: also could be optional query = CoprsLogic.join_builds(query)
- if req_args["offset"]: + if "limit" in req_args: query = query.offset(req_args["offset"])
# todo: add maximum allowed limit and also use as a default limit @@ -101,40 +103,46 @@ class CoprListR(Resource):
coprs_list = query.all()
- return { - "links": { - "self": bp_url_for(CoprListR.endpoint, **req_args) + result_dict = { + "_links": { + "self": {"href": url_for(".coprlistr", **req_args)} }, "coprs": [ { "copr": CoprSchema().dump(copr)[0], - "link": bp_url_for( - CoprR.endpoint, - owner=copr.owner.name, - project=copr.name - ), + "_links": { + "self": {"href": url_for(".coprr", copr_id=copr.id)} + }, } for copr in coprs_list ], - # TODO: show only if user provided ?help=true param - # "allowed_methods": [ - # render_allowed_method("GET", "Get list of coprs", require_auth=False, - # params=[ - # "username: filter coprs owned by user", - # "limit: show only the given number of coprs", - # "offset: skip given number of coprs", - # ]), - # render_allowed_method("POST", "Creates new copr, send dict with copr fields"), - # ] + }
+ # TODO: show only if user provided ?help=true param + # + # if req_args.get("help"): + # result_dict["allowed_methods"] = [ + # render_allowed_method("GET", "Get list of coprs", require_auth=False, + # params=[ + # "username: filter coprs owned by the user", + # "limit: show only the given number of coprs", + # "offset: skip given number of coprs", + # ]), + # render_allowed_method("POST", "Creates new copr, send dict with copr fields"), + # ] + + return result_dict +
class CoprR(Resource):
@rest_api_auth_required - def delete(self, owner, project): - copr = get_one_safe(CoprsLogic.get(flask.g.user, owner, project), - "Copr {}/{} not found".format(owner, project)) + def delete(self, copr_id): + copr = get_one_safe(CoprsLogic.get_by_id(int(copr_id))) + + raise NotImplementedError() + try: ComplexLogic.delete_copr(copr) except (ActionInProgressException, @@ -146,24 +154,21 @@ class CoprR(Resource):
return None, 204
- def get(self, owner, project): + def get(self, copr_id): # parser = reqparse.RequestParser() # parser.add_argument('show_builds', type=bool, default=True) # parser.add_argument('show_chroots', type=bool, default=True) # req_args = parser.parse_args()
- copr = get_one_safe(CoprsLogic.get(flask.g.user, owner, project), - "Copr {}/{} not found".format(owner, project)) + copr = get_one_safe(CoprsLogic.get_by_id(int(copr_id))) + return { "copr": CoprSchema().dump(copr)[0], - "links": { - "self": bp_url_for(CoprR.endpoint, - owner=owner, - project=project), - # "chroots": - "builds": bp_url_for(BuildListR.endpoint, - owner=copr.owner.name, - project=copr.name) + "_links": { + "self": {"href": url_for(".coprr", copr_id=copr.id)}, + #"chroots": bp_url_for(ChrootListR.endpoint, + # ) + "builds": {"href": url_for(".buildlistr", owner=copr.owner.name, project=copr.name)} }, # "allowed_methods": [ # render_allowed_method("GET", "Get single copr", require_auth=False), @@ -172,7 +177,7 @@ class CoprR(Resource): }
@rest_api_auth_required - def put(self, owner, project): + def put(self, copr_id): """ Modifies project by replacment of provided fields """ diff --git a/frontend/coprs_frontend/coprs/rest_api/schemas.py b/frontend/coprs_frontend/coprs/rest_api/schemas.py index 9c243a7..0b29b54 100644 --- a/frontend/coprs_frontend/coprs/rest_api/schemas.py +++ b/frontend/coprs_frontend/coprs/rest_api/schemas.py @@ -9,8 +9,10 @@ class AllowedMethodSchema(Schema): params = fields.List(fields.Str())
-class MockChroot(Schema): - pass +class MockChrootSchema(Schema): + class Meta: + fields = ("name", "os_release", "os_version", "arch", "is_active") + ordered = True
class CoprSchema(Schema): diff --git a/frontend/coprs_frontend/coprs/rest_api/util.py b/frontend/coprs_frontend/coprs/rest_api/util.py index ac9b0b6..0fec6c6 100644 --- a/frontend/coprs_frontend/coprs/rest_api/util.py +++ b/frontend/coprs_frontend/coprs/rest_api/util.py @@ -19,18 +19,6 @@ def render_allowed_method(method, doc, require_auth=True, params=None): return AllowedMethodSchema().dump(AllowedMethod(method, doc, require_auth, params))[0]
-def bp_url_for(endpoint, *args, **kwargs): - """ - Prepend endpoing with dot - :param endpoint: - :param args: - :param kwargs: - :return: - """ - - return url_for(".{}".format(endpoint), *args, **kwargs) - - def get_one_safe(query, data_on_error=None): try: return query.one()