Package coprs :: Package views :: Package api_ns :: Module api_general
[hide private]
[frames] | no frames]

Source Code for Module coprs.views.api_ns.api_general

  1  import base64 
  2  import datetime 
  3  import urlparse 
  4   
  5  import flask 
  6   
  7  from coprs import db 
  8  from coprs import exceptions 
  9  from coprs import forms 
 10  from coprs import helpers 
 11   
 12  from coprs.views.misc import login_required, api_login_required 
 13   
 14  from coprs.views.api_ns import api_ns 
 15   
 16  from coprs.logic import builds_logic 
 17  from coprs.logic import coprs_logic 
18 19 20 @api_ns.route("/") 21 -def api_home():
22 """ 23 Render the home page of the api. 24 This page provides information on how to call/use the API. 25 """ 26 27 return flask.render_template("api.html")
28
29 30 @api_ns.route("/new/", methods=["GET", "POST"]) 31 @login_required 32 -def api_new_token():
33 """ 34 Generate a new API token for the current user. 35 """ 36 37 user = flask.g.user 38 copr64 = base64.b64encode("copr") + "##" 39 api_login = helpers.generate_api_token( 40 flask.current_app.config["API_TOKEN_LENGTH"] - len(copr64)) 41 user.api_login = api_login 42 user.api_token = helpers.generate_api_token( 43 flask.current_app.config["API_TOKEN_LENGTH"]) 44 user.api_token_expiration = datetime.date.today() + \ 45 datetime.timedelta( 46 days=flask.current_app.config["API_TOKEN_EXPIRATION"]) 47 48 db.session.add(user) 49 db.session.commit() 50 return flask.redirect(flask.url_for("api_ns.api_home"))
51
52 53 @api_ns.route("/coprs/<username>/new/", methods=["POST"]) 54 @api_login_required 55 -def api_new_copr(username):
56 """ 57 Receive information from the user on how to create its new copr, 58 check their validity and create the corresponding copr. 59 60 :arg name: the name of the copr to add 61 :arg chroots: a comma separated list of chroots to use 62 :kwarg repos: a comma separated list of repository that this copr 63 can use. 64 :kwarg initial_pkgs: a comma separated list of initial packages to 65 build in this new copr 66 67 """ 68 69 form = forms.CoprFormFactory.create_form_cls()(csrf_enabled=False) 70 httpcode = 200 71 72 # are there any arguments in POST which our form doesn't know? 73 if sum([1 for post_key in flask.request.form.keys() \ 74 if post_key not in form.__dict__.keys()]): 75 output = {"output": "notok", "error": 76 "Unknown arguments passed (non-existing chroot probably)"} 77 httpcode = 500 78 79 elif form.validate_on_submit(): 80 infos = [] 81 try: 82 copr = coprs_logic.CoprsLogic.add( 83 name=form.name.data.strip(), 84 repos=" ".join(form.repos.data.split()), 85 user=flask.g.user, 86 selected_chroots=form.selected_chroots, 87 description=form.description.data, 88 instructions=form.instructions.data, 89 check_for_duplicates=True) 90 infos.append("New project was successfully created.") 91 92 if form.initial_pkgs.data: 93 pkgs = form.initial_pkgs.data.split() 94 for pkg in pkgs: 95 builds_logic.BuildsLogic.add( 96 user=flask.g.user, 97 pkgs=pkg, 98 copr=copr) 99 100 infos.append("Initial packages were successfully " 101 "submitted for building.") 102 103 output = {"output": "ok", "message": "\n".join(infos)} 104 db.session.commit() 105 except exceptions.DuplicateException as err: 106 output = {"output": "notok", "error": err} 107 httpcode = 500 108 db.session.rollback() 109 110 else: 111 errormsg = "Validation error\n" 112 if form.errors: 113 for field, emsgs in form.errors.items(): 114 errormsg += "- {0}: {1}\n".format(field, "\n".join(emsgs)) 115 116 errormsg = errormsg.replace('"', "'") 117 output = {"output": "notok", "error": errormsg} 118 httpcode = 500 119 120 jsonout = flask.jsonify(output) 121 jsonout.status_code = httpcode 122 return jsonout
123
124 125 @api_ns.route("/coprs/<username>/<coprname>/delete/", methods=["POST"]) 126 @api_login_required 127 -def api_copr_delete(username, coprname):
128 """ Deletes selected user's project 129 """ 130 form = forms.CoprDeleteForm(csrf_enabled=False) 131 copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first() 132 httpcode = 200 133 134 if form.validate_on_submit() and copr: 135 builds_query = builds_logic.BuildsLogic.get_multiple( 136 flask.g.user, copr=copr) 137 try: 138 for build in builds_query: 139 builds_logic.BuildsLogic.delete_build(flask.g.user, build) 140 coprs_logic.CoprsLogic.delete(flask.g.user, copr) 141 except (exceptions.ActionInProgressException, 142 exceptions.InsufficientRightsException) as err: 143 output = {"output": "notok", "error": err} 144 httpcode = 500 145 db.session.rollback() 146 else: 147 message = "Project {0} has been deleted.".format(coprname) 148 output = {"output": "ok", "message": message} 149 db.session.commit() 150 else: 151 output = {"output": "notok", "error": "Invalid request"} 152 httpcode = 500 153 154 jsonout = flask.jsonify(output) 155 jsonout.status_code = httpcode 156 return jsonout
157
158 159 @api_ns.route("/coprs/") 160 @api_ns.route("/coprs/<username>/") 161 -def api_coprs_by_owner(username=None):
162 """ Return the list of coprs owned by the given user. 163 username is taken either from GET params or from the URL itself 164 (in this order). 165 166 :arg username: the username of the person one would like to the 167 coprs of. 168 169 """ 170 username = flask.request.args.get("username", None) or username 171 release_tmpl = "{chroot.os_release}-{chroot.os_version}-{chroot.arch}" 172 httpcode = 200 173 if username: 174 query = coprs_logic.CoprsLogic.get_multiple( 175 flask.g.user, user_relation="owned", 176 username=username, with_builds=True) 177 178 repos = query.all() 179 output = {"output": "ok", "repos": []} 180 for repo in repos: 181 yum_repos = {} 182 for build in repo.builds: 183 if build.results: 184 for chroot in repo.active_chroots: 185 release = release_tmpl.format(chroot=chroot) 186 yum_repos[release] = urlparse.urljoin( 187 build.results, release + '/') 188 break 189 190 output["repos"].append({"name": repo.name, 191 "additional_repos": repo.repos, 192 "yum_repos": yum_repos, 193 "description": repo.description, 194 "instructions": repo.instructions}) 195 else: 196 output = {"output": "notok", "error": "Invalid request"} 197 httpcode = 500 198 199 jsonout = flask.jsonify(output) 200 jsonout.status_code = httpcode 201 return jsonout
202
203 @api_ns.route("/coprs/<username>/<coprname>/detail/") 204 -def api_coprs_by_owner_detail(username, coprname):
205 """ Return detail of one project. 206 207 :arg username: the username of the person one would like to the 208 coprs of. 209 :arg coprname: the name of project. 210 211 """ 212 copr = coprs_logic.CoprsLogic.get(flask.g.user, username, 213 coprname).first() 214 release_tmpl = "{chroot.os_release}-{chroot.os_version}-{chroot.arch}" 215 httpcode = 200 216 if username and copr: 217 output = {"output": "ok", "detail": {}} 218 yum_repos = {} 219 for build in copr.builds: 220 if build.results: 221 for chroot in copr.active_chroots: 222 release = release_tmpl.format(chroot=chroot) 223 yum_repos[release] = urlparse.urljoin( 224 build.results, release + '/') 225 break 226 output["detail"] = {"name": copr.name, 227 "additional_repos": copr.repos, 228 "yum_repos": yum_repos, 229 "description": copr.description, 230 "instructions": copr.instructions, 231 "last_modified": builds_logic.BuildsLogic.last_modified(copr)} 232 else: 233 output = {"output": "notok", "error": "Copr with name {0} does not exist.".format(coprname)} 234 httpcode = 500 235 236 jsonout = flask.jsonify(output) 237 jsonout.status_code = httpcode 238 return jsonout
239
240 @api_ns.route("/coprs/<username>/<coprname>/new_build/", methods=["POST"]) 241 @api_login_required 242 -def copr_new_build(username, coprname):
243 copr = coprs_logic.CoprsLogic.get(flask.g.user, username, 244 coprname).first() 245 httpcode = 200 246 if not copr: 247 output = {"output": "notok", "error": 248 "Copr with name {0} does not exist.".format(coprname)} 249 httpcode = 500 250 251 else: 252 form = forms.BuildFormFactory.create_form_cls( 253 copr.active_chroots)(csrf_enabled=False) 254 255 # are there any arguments in POST which our form doesn't know? 256 if sum([1 for post_key in flask.request.form.keys() \ 257 if post_key not in form.__dict__.keys()]): 258 output = {"output": "notok", "error": 259 "Unknown arguments passed (non-existing chroot probably)"} 260 httpcode = 500 261 262 elif form.validate_on_submit() and flask.g.user.can_build_in(copr): 263 # we're checking authorization above for now 264 # and also creating separate build for each package 265 pkgs = form.pkgs.data.replace('\n', ' ').split(" ") 266 ids = [] 267 chroots = [] 268 for chroot in copr.active_chroots: 269 if chroot.name in form.selected_chroots: 270 chroots.append(chroot) 271 272 for pkg in pkgs: 273 build = builds_logic.BuildsLogic.add( 274 user=flask.g.user, 275 pkgs=pkg, 276 copr=copr, 277 chroots=chroots) 278 279 if flask.g.user.proven: 280 build.memory_reqs = form.memory_reqs.data 281 build.timeout = form.timeout.data 282 283 db.session.commit() 284 ids.append(build.id) 285 286 287 output = {"output": "ok", 288 "ids": ids, 289 "message": "Build was added to {0}.".format(coprname)} 290 else: 291 output = {"output": "notok", "error": "Invalid request"} 292 httpcode = 500 293 294 jsonout = flask.jsonify(output) 295 jsonout.status_code = httpcode 296 return jsonout
297
298 299 @api_ns.route("/coprs/build_status/<build_id>/", methods=["GET"]) 300 @api_login_required 301 -def build_status(build_id):
302 if build_id.isdigit(): 303 build = builds_logic.BuildsLogic.get(build_id).first() 304 else: 305 build = None 306 307 if build: 308 httpcode = 200 309 output = {"output": "ok", 310 "status": build.state} 311 else: 312 output = {"output": "notok", "error": "Invalid build"} 313 httpcode = 404 314 315 jsonout = flask.jsonify(output) 316 jsonout.status_code = httpcode 317 return jsonout
318
319 @api_ns.route("/coprs/build_detail/<build_id>/", methods=["GET"]) 320 @api_ns.route("/coprs/build/<build_id>/", methods=["GET"]) 321 -def build_detail(build_id):
322 if build_id.isdigit(): 323 build = builds_logic.BuildsLogic.get(build_id).first() 324 else: 325 build = None 326 327 if build: 328 httpcode = 200 329 chroots = {} 330 for chroot in build.build_chroots: 331 chroots[chroot.name] = chroot.state 332 333 built_packages = None 334 if build.built_packages: 335 built_packages = build.built_packages.split("\n") 336 337 output = {"output": "ok", 338 "status": build.state, 339 "project": build.copr.name, 340 "owner": build.copr.owner.name, 341 "results": build.results, 342 "built_pkgs": built_packages, 343 "src_version": build.pkg_version, 344 "chroots": chroots, 345 "submitted_on": build.submitted_on, 346 "started_on": build.started_on, 347 "ended_on": build.ended_on, 348 "src_pkg": build.pkgs, 349 "submitted_by": build.user.name} 350 else: 351 output = {"output": "notok", "error": "Invalid build"} 352 httpcode = 404 353 354 jsonout = flask.jsonify(output) 355 jsonout.status_code = httpcode 356 return jsonout
357
358 @api_ns.route("/coprs/cancel_build/<build_id>/", methods=["POST"]) 359 @api_login_required 360 -def cancel_build(build_id):
361 if build_id.isdigit(): 362 build = builds_logic.BuildsLogic.get(build_id).first() 363 else: 364 build = None 365 366 if build: 367 try: 368 builds_logic.BuildsLogic.cancel_build(flask.g.user, build) 369 except exceptions.InsufficientRightsException as e: 370 output = {'output': 'notok', 'error': str(e)} 371 httpcode = 500 372 else: 373 db.session.commit() 374 httpcode = 200 375 output = {'output': 'ok', 'status': "Build canceled"} 376 else: 377 output = {"output": "notok", "error": "Invalid build"} 378 httpcode = 404 379 jsonout = flask.jsonify(output) 380 jsonout.status_code = httpcode 381 return jsonout
382
383 @api_ns.route('/coprs/<username>/<coprname>/modify/', methods=["POST"]) 384 @api_login_required 385 -def copr_modify(username, coprname):
386 form = forms.CoprModifyForm(csrf_enabled=False) 387 copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first() 388 389 if copr is None: 390 output = {'output': 'notok', 'error': 'Invalid copr name or username'} 391 httpcode = 500 392 elif not form.validate_on_submit(): 393 output = {'output': 'notok', 'error': 'Invalid request'} 394 httpcode = 500 395 else: 396 # .raw_data needs to be inspected to figure out whether the field 397 # was not sent or was sent empty 398 if form.description.raw_data and len(form.description.raw_data): 399 copr.description = form.description.data 400 if form.instructions.raw_data and len(form.instructions.raw_data): 401 copr.instructions = form.instructions.data 402 if form.repos.raw_data and len(form.repos.raw_data): 403 copr.repos = form.repos.data 404 405 try: 406 coprs_logic.CoprsLogic.update(flask.g.user, copr) 407 except (exceptions.ActionInProgressException, exceptions.InsufficientRightsException) as e: 408 db.session.rollback() 409 410 output = {'output': 'notok', 'error': str(e)} 411 httpcode = 500 412 else: 413 db.session.commit() 414 415 output = {'output': 'ok', 416 'description': copr.description, 417 'instructions': copr.instructions, 418 'repos': copr.repos} 419 httpcode = 200 420 421 jsonout = flask.jsonify(output) 422 jsonout.status_code = httpcode 423 return jsonout
424
425 @api_ns.route('/coprs/<username>/<coprname>/modify/<chrootname>/', methods=["POST"]) 426 @api_login_required 427 -def copr_modify_chroot(username, coprname, chrootname):
428 form = forms.ModifyChrootForm(csrf_enabled=False) 429 copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first() 430 chroot = coprs_logic.MockChrootsLogic.get_from_name(chrootname, active_only=True).first() 431 432 if copr is None: 433 output = {'output': 'notok', 'error': 'Invalid copr name or username'} 434 httpcode = 500 435 elif chroot is None: 436 output = {'output': 'notok', 'error': 'Invalid chroot name'} 437 httpcode = 500 438 elif not form.validate_on_submit(): 439 output = {'output': 'notok', 'error': 'Invalid request'} 440 httpcode = 500 441 else: 442 coprs_logic.CoprChrootsLogic.update_buildroot_pkgs(copr, chroot, form.buildroot_pkgs.data) 443 db.session.commit() 444 445 ch = copr.check_copr_chroot(chroot) 446 output = {'output': 'ok', 'buildroot_pkgs': ch.buildroot_pkgs} 447 httpcode = 200 448 449 jsonout = flask.jsonify(output) 450 jsonout.status_code = httpcode 451 return jsonout
452
453 @api_ns.route('/coprs/<username>/<coprname>/detail/<chrootname>/', methods=["GET"]) 454 -def copr_chroot_details(username, coprname, chrootname):
455 copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first() 456 chroot = coprs_logic.MockChrootsLogic.get_from_name(chrootname, active_only=True).first() 457 458 if copr is None: 459 output = {'output': 'notok', 'error': 'Invalid copr name or username'} 460 httpcode = 500 461 elif chroot is None: 462 output = {'output': 'notok', 'error': 'Invalid chroot name'} 463 httpcode = 500 464 else: 465 ch = copr.check_copr_chroot(chroot) 466 if ch: 467 output = {'output': 'ok', 'buildroot_pkgs': ch.buildroot_pkgs} 468 httpcode = 200 469 else: 470 output = {"output": "notok", "error": "Invalid chroot for this project."} 471 httpcode = 404 472 473 474 jsonout = flask.jsonify(output) 475 jsonout.status_code = httpcode 476 return jsonout
477
478 @api_ns.route("/coprs/search/") 479 @api_ns.route("/coprs/search/<project>/") 480 -def api_coprs_search_by_project(project=None):
481 """ Return the list of coprs found in search by the given text. 482 project is taken either from GET params or from the URL itself 483 (in this order). 484 485 :arg project: the text one would like find for coprs. 486 487 """ 488 project = flask.request.args.get("project", None) or project 489 httpcode = 200 490 if project: 491 try: 492 query = coprs_logic.CoprsLogic.get_multiple_fulltext( 493 flask.g.user, project) 494 495 repos = query.all() 496 output = {"output": "ok", "repos": []} 497 for repo in repos: 498 output["repos"].append({"username": repo.owner.name, 499 "coprname": repo.name, 500 "description": repo.description}) 501 except ValueError as e: 502 output = {"output": "nook", "error": str(e)} 503 504 else: 505 output = {"output": "notok", "error": "Invalid request"} 506 httpcode = 500 507 508 jsonout = flask.jsonify(output) 509 jsonout.status_code = httpcode 510 return jsonout
511
512 @api_ns.route("/playground/list/") 513 -def playground_list():
514 """ Return list of coprs which are part of playground """ 515 query = coprs_logic.CoprsLogic.get_playground() 516 repos = query.all() 517 output = {"output": "ok", "repos": []} 518 for repo in repos: 519 output["repos"].append({"username": repo.owner.name, 520 "coprname": repo.name, 521 "chroots": [chroot.name for chroot in repo.active_chroots]}) 522 523 jsonout = flask.jsonify(output) 524 jsonout.status_code = 200 525 return jsonout
526