Trees | Indices | Help |
---|
|
1 import os 2 import flask 3 from werkzeug.datastructures import MultiDict 4 from . import get_copr, file_upload, query_params, pagination, Paginator, json2form, GET, POST, PUT, DELETE 5 from .json2form import get_form_compatible_data, without_empty_fields 6 from werkzeug import secure_filename 7 from coprs import db, forms, models 8 from coprs.helpers import StatusEnum 9 from coprs.exceptions import (ApiError, InsufficientRightsException, ActionInProgressException, 10 BadRequest, AccessRestricted) 11 from coprs.views.misc import api_login_required 12 from coprs.views.apiv3_ns import apiv3_ns 13 from coprs.logic.complex_logic import ComplexLogic 14 from coprs.logic.builds_logic import BuildsLogic18 return { 19 "id": build.id, 20 "state": build.state, 21 "projectname": build.copr.name, 22 "ownername": build.copr.owner_name, 23 "repo_url": build.copr.repo_url, 24 "source_package": {"name": build.package_name, "version": build.pkg_version, "url": build.srpm_url}, 25 "submitted_on": build.submitted_on, 26 "started_on": build.min_started_on, 27 "ended_on": build.max_ended_on, 28 "submitter": build.user.name if build.user else None, 29 "chroots": [chroot.name for chroot in build.build_chroots], 30 }3134 return { 35 "state": StatusEnum(build.source_status), 36 "result_url": os.path.dirname(build.import_log_url_backend), 37 # @TODO Do we have such information stored? 38 # "started_on": None, 39 # "ended_on": None 40 }4144 return { 45 "source_type": build.source_type_text, 46 "source_dict": build.source_json_dict, 47 "memory_limit": build.memory_reqs, 48 "timeout": build.timeout, 49 "is_background": build.is_background, 50 }5154 replace = { 55 "source_build_method": "srpm_build_method", 56 } 57 output = input.copy() 58 for from_name, to_name in replace.items(): 59 if from_name not in output: 60 continue 61 output[to_name] = output.pop(from_name) 62 return output63 67 7374 75 @apiv3_ns.route("/build/list/", methods=GET) 76 @pagination() 77 @query_params() 78 -def get_build_list(ownername, projectname, packagename=None, status=None, **kwargs):79 copr = get_copr(ownername, projectname) 80 query = BuildsLogic.get_multiple_by_copr(copr) 81 if packagename: 82 query = BuildsLogic.filter_by_package_name(query, packagename) 83 84 # WORKAROUND 85 # We can't filter builds by status directly in the database, because we 86 # use a logic in Build.status property to determine a build status. 87 # Therefore if we want to filter by `status`, we need to query all builds 88 # and filter them in the application and then return the desired number. 89 limit = kwargs["limit"] 90 paginator_limit = None if status else kwargs["limit"] 91 del kwargs["limit"] 92 93 paginator = Paginator(query, models.Build, limit=paginator_limit, **kwargs) 94 builds = paginator.map(to_dict) 95 96 if status: 97 builds = [b for b in builds if b["state"] == status][:limit] 98 paginator.limit = limit 99 100 return flask.jsonify(items=builds, meta=paginator.meta)101102 103 @apiv3_ns.route("/build/source-chroot/<int:build_id>/", methods=GET) 104 -def get_source_chroot(build_id):107108 109 @apiv3_ns.route("/build/source-build-config/<int:build_id>/", methods=GET) 110 -def get_source_build_config(build_id):111 build = ComplexLogic.get_build_safe(build_id) 112 return flask.jsonify(to_source_build_config(build))113114 115 @apiv3_ns.route("/build/cancel/<int:build_id>", methods=PUT) 116 @api_login_required 117 -def cancel_build(build_id):118 build = ComplexLogic.get_build_safe(build_id) 119 BuildsLogic.cancel_build(flask.g.user, build) 120 db.session.commit() 121 return render_build(build)122123 124 @apiv3_ns.route("/build/create/url", methods=POST) 125 @api_login_required 126 -def create_from_url():127 copr = get_copr() 128 data = get_form_compatible_data() 129 form = forms.BuildFormUrlFactory(copr.active_chroots)(data, csrf_enabled=False) 130 131 def create_new_build(): 132 # create separate build for each package 133 pkgs = form.pkgs.data.split("\n") 134 return [BuildsLogic.create_new_from_url( 135 flask.g.user, copr, 136 url=pkg, 137 chroot_names=form.selected_chroots, 138 background=form.background.data, 139 ) for pkg in pkgs]140 return process_creating_new_build(copr, form, create_new_build) 141142 143 @apiv3_ns.route("/build/create/upload", methods=POST) 144 @api_login_required 145 @file_upload() 146 -def create_from_upload():147 copr = get_copr() 148 data = get_form_compatible_data() 149 form = forms.BuildFormUploadFactory(copr.active_chroots)(data, csrf_enabled=False) 150 151 def create_new_build(): 152 return BuildsLogic.create_new_from_upload( 153 flask.g.user, copr, 154 f_uploader=lambda path: form.pkgs.data.save(path), 155 orig_filename=secure_filename(form.pkgs.data.filename), 156 chroot_names=form.selected_chroots, 157 background=form.background.data, 158 )159 return process_creating_new_build(copr, form, create_new_build) 160161 162 @apiv3_ns.route("/build/create/scm", methods=POST) 163 @api_login_required 164 -def create_from_scm():165 copr = get_copr() 166 data = rename_fields(get_form_compatible_data()) 167 form = forms.BuildFormScmFactory(copr.active_chroots)(data, csrf_enabled=False) 168 169 def create_new_build(): 170 return BuildsLogic.create_new_from_scm( 171 flask.g.user, 172 copr, 173 scm_type=form.scm_type.data, 174 clone_url=form.clone_url.data, 175 committish=form.committish.data, 176 subdirectory=form.subdirectory.data, 177 spec=form.spec.data, 178 srpm_build_method=form.srpm_build_method.data, 179 chroot_names=form.selected_chroots, 180 background=form.background.data, 181 )182 return process_creating_new_build(copr, form, create_new_build) 183184 185 @apiv3_ns.route("/build/create/pypi", methods=POST) 186 @api_login_required 187 -def create_from_pypi():188 copr = get_copr() 189 data = MultiDict(json2form.without_empty_fields(json2form.get_input())) 190 form = forms.BuildFormPyPIFactory(copr.active_chroots)(data, csrf_enabled=False) 191 192 # TODO: automatically prepopulate all form fields with their defaults 193 if not form.python_versions.data: 194 form.python_versions.data = form.python_versions.default 195 196 def create_new_build(): 197 return BuildsLogic.create_new_from_pypi( 198 flask.g.user, 199 copr, 200 form.pypi_package_name.data, 201 form.pypi_package_version.data, 202 form.python_versions.data, 203 form.selected_chroots, 204 background=form.background.data, 205 )206 return process_creating_new_build(copr, form, create_new_build) 207208 209 @apiv3_ns.route("/build/create/rubygems", methods=POST) 210 @api_login_required 211 -def create_from_rubygems():212 copr = get_copr() 213 data = get_form_compatible_data() 214 form = forms.BuildFormRubyGemsFactory(copr.active_chroots)(data, csrf_enabled=False) 215 216 def create_new_build(): 217 return BuildsLogic.create_new_from_rubygems( 218 flask.g.user, 219 copr, 220 form.gem_name.data, 221 form.selected_chroots, 222 background=form.background.data, 223 )224 return process_creating_new_build(copr, form, create_new_build) 225226 227 @apiv3_ns.route("/build/create/custom", methods=POST) 228 @api_login_required 229 -def create_from_custom():230 copr = get_copr() 231 data = get_form_compatible_data() 232 form = forms.BuildFormCustomFactory(copr.active_chroots)(data, csrf_enabled=False) 233 234 def create_new_build(): 235 return BuildsLogic.create_new_from_custom( 236 flask.g.user, 237 copr, 238 form.script.data, 239 form.chroot.data, 240 form.builddeps.data, 241 form.resultdir.data, 242 chroot_names=form.selected_chroots, 243 background=form.background.data, 244 )245 return process_creating_new_build(copr, form, create_new_build) 246249 if not form.validate_on_submit(): 250 raise BadRequest("Bad request parameters: {0}".format(form.errors)) 251 252 if not flask.g.user.can_build_in(copr): 253 raise AccessRestricted("User {} is not allowed to build in the copr: {}" 254 .format(flask.g.user.username, copr.full_name)) 255 256 # From URLs it can be created multiple builds at once 257 # so it can return a list 258 build = create_new_build() 259 db.session.commit() 260 261 if type(build) == list: 262 builds = [build] if type(build) != list else build 263 return flask.jsonify(items=[to_dict(b) for b in builds], meta={}) 264 return flask.jsonify(to_dict(build))265266 267 @apiv3_ns.route("/build/delete/<int:build_id>", methods=DELETE) 268 @api_login_required 269 -def delete_build(build_id):270 build = ComplexLogic.get_build_safe(build_id) 271 build_dict = to_dict(build) 272 BuildsLogic.delete_build(flask.g.user, build) 273 db.session.commit() 274 return flask.jsonify(build_dict)275
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 | http://epydoc.sourceforge.net |