Package coprs :: Package views :: Package apiv3_ns :: Module apiv3_projects
[hide private]
[frames] | no frames]

Source Code for Module coprs.views.apiv3_ns.apiv3_projects

  1  import flask 
  2  from . import query_params, get_copr, pagination, Paginator, GET, POST, PUT, DELETE 
  3  from .json2form import get_form_compatible_data, get_input_dict 
  4  from coprs import db, models, forms 
  5  from coprs.views.misc import api_login_required 
  6  from coprs.views.apiv3_ns import apiv3_ns 
  7  from coprs.logic.coprs_logic import CoprsLogic, CoprChrootsLogic, MockChrootsLogic 
  8  from coprs.logic.complex_logic import ComplexLogic 
  9  from coprs.exceptions import (DuplicateException, NonAdminCannotCreatePersistentProject, 
 10                                NonAdminCannotDisableAutoPrunning, ActionInProgressException, 
 11                                InsufficientRightsException, BadRequest, ObjectNotFound) 
12 13 14 -def to_dict(copr):
15 return { 16 "id": copr.id, 17 "name": copr.name, 18 "ownername": copr.owner_name, 19 "full_name": copr.full_name, 20 "homepage": copr.homepage, 21 "contact": copr.contact, 22 "description": copr.description, 23 "instructions": copr.instructions, 24 "devel_mode": copr.devel_mode, 25 "persistent": copr.persistent, 26 "unlisted_on_hp": copr.unlisted_on_hp, 27 "auto_prune": copr.auto_prune, 28 "chroot_repos": CoprsLogic.get_yum_repos(copr, empty=True), 29 "additional_repos": copr.repos_list, 30 "enable_net": copr.build_enable_net, 31 "use_bootstrap_container": copr.use_bootstrap_container, 32 "module_hotfixes": copr.module_hotfixes, 33 }
34
35 36 -def rename_fields(input):
37 replace = { 38 "devel_mode": "disable_createrepo", 39 "additional_repos": "repos", 40 } 41 output = input.copy() 42 for from_name, to_name in replace.items(): 43 if from_name not in output: 44 continue 45 output[to_name] = output.pop(from_name) 46 return output
47
48 49 -def validate_chroots(input, allowed_chroots):
50 inserted = set(input["chroots"] or []) 51 allowed = {x.name for x in allowed_chroots} 52 unexpected = inserted - allowed 53 if unexpected: 54 raise BadRequest("Unexpected chroot: {}".format(", ".join(unexpected)))
55
56 57 @apiv3_ns.route("/project", methods=GET) 58 @query_params() 59 -def get_project(ownername, projectname):
60 copr = get_copr(ownername, projectname) 61 return flask.jsonify(to_dict(copr))
62
63 64 @apiv3_ns.route("/project/list", methods=GET) 65 @pagination() 66 @query_params() 67 -def get_project_list(ownername=None, **kwargs):
68 if not ownername: 69 query = CoprsLogic.get_multiple() 70 elif ownername.startswith("@"): 71 group_name = ownername[1:] 72 query = CoprsLogic.get_multiple() 73 query = CoprsLogic.filter_by_group_name(query, group_name) 74 else: 75 query = CoprsLogic.get_multiple_owned_by_username(ownername) 76 query = CoprsLogic.filter_without_group_projects(query) 77 78 # @TODO ordering doesn't work correctly - try order by models.Copr.name DESC 79 paginator = Paginator(query, models.Copr, **kwargs) 80 projects = paginator.map(to_dict) 81 return flask.jsonify(items=projects, meta=paginator.meta)
82
83 84 @apiv3_ns.route("/project/search", methods=GET) 85 @pagination() 86 @query_params() 87 # @TODO should the param be query or projectname? 88 -def search_projects(query, **kwargs):
89 try: 90 search_query = CoprsLogic.get_multiple_fulltext(query) 91 paginator = Paginator(search_query, models.Copr, **kwargs) 92 projects = paginator.map(to_dict) 93 except ValueError as ex: 94 raise BadRequest(str(ex)) 95 return flask.jsonify(items=projects, meta=paginator.meta)
96
97 98 @apiv3_ns.route("/project/add/<ownername>", methods=POST) 99 @api_login_required 100 -def add_project(ownername):
101 data = rename_fields(get_form_compatible_data()) 102 form = forms.CoprFormFactory.create_form_cls()(data, meta={'csrf': False}) 103 104 if not form.validate_on_submit(): 105 raise BadRequest(form.errors) 106 validate_chroots(get_input_dict(), MockChrootsLogic.get_multiple()) 107 108 group = None 109 if ownername[0] == "@": 110 group = ComplexLogic.get_group_by_name_safe(ownername[1:]) 111 112 try: 113 copr = CoprsLogic.add( 114 name=form.name.data.strip(), 115 repos=" ".join(form.repos.data.split()), 116 user=flask.g.user, 117 selected_chroots=form.selected_chroots, 118 description=form.description.data, 119 instructions=form.instructions.data, 120 check_for_duplicates=True, 121 unlisted_on_hp=form.unlisted_on_hp.data, 122 build_enable_net=form.enable_net.data, 123 group=group, 124 persistent=form.persistent.data, 125 auto_prune=form.auto_prune.data, 126 use_bootstrap_container=form.use_bootstrap_container.data, 127 homepage=form.homepage.data, 128 contact=form.contact.data, 129 disable_createrepo=form.disable_createrepo.data, 130 delete_after_days=form.delete_after_days.data, 131 multilib=form.multilib.data, 132 module_hotfixes=form.module_hotfixes.data, 133 ) 134 db.session.commit() 135 except (DuplicateException, 136 NonAdminCannotCreatePersistentProject, 137 NonAdminCannotDisableAutoPrunning) as err: 138 db.session.rollback() 139 raise err 140 return flask.jsonify(to_dict(copr))
141
142 143 @apiv3_ns.route("/project/edit/<ownername>/<projectname>", methods=PUT) 144 @api_login_required 145 -def edit_project(ownername, projectname):
146 copr = get_copr(ownername, projectname) 147 data = rename_fields(get_form_compatible_data()) 148 form = forms.CoprModifyForm(data, meta={'csrf': False}) 149 150 if not form.validate_on_submit(): 151 raise BadRequest(form.errors) 152 validate_chroots(get_input_dict(), MockChrootsLogic.get_multiple()) 153 154 for field in form: 155 if field.data is None or field.name in ["csrf_token", "chroots"]: 156 continue 157 if field.name not in data.keys(): 158 continue 159 setattr(copr, field.name, field.data) 160 161 if form.chroots.data: 162 CoprChrootsLogic.update_from_names( 163 flask.g.user, copr, form.chroots.data) 164 165 try: 166 CoprsLogic.update(flask.g.user, copr) 167 if copr.group: # load group.id 168 _ = copr.group.id 169 db.session.commit() 170 except (ActionInProgressException, 171 InsufficientRightsException, 172 NonAdminCannotDisableAutoPrunning) as ex: 173 db.session.rollback() 174 raise ex 175 176 return flask.jsonify(to_dict(copr))
177
178 179 @apiv3_ns.route("/project/fork/<ownername>/<projectname>", methods=PUT) 180 @api_login_required 181 -def fork_project(ownername, projectname):
182 copr = get_copr(ownername, projectname) 183 184 # @FIXME we want "ownername" from the outside, but our internal Form expects "owner" instead 185 data = get_form_compatible_data() 186 data["owner"] = data.get("ownername") 187 188 form = forms.CoprForkFormFactory \ 189 .create_form_cls(copr=copr, user=flask.g.user, groups=flask.g.user.user_groups)(data, meta={'csrf': False}) 190 191 if form.validate_on_submit() and copr: 192 try: 193 dstgroup = ([g for g in flask.g.user.user_groups if g.at_name == form.owner.data] or [None])[0] 194 if flask.g.user.name != form.owner.data and not dstgroup: 195 return ObjectNotFound("There is no such group: {}".format(form.owner.data)) 196 197 fcopr, created = ComplexLogic.fork_copr(copr, flask.g.user, dstname=form.name.data, dstgroup=dstgroup) 198 if not created and form.confirm.data != True: 199 raise BadRequest("You are about to fork into existing project: {}\n" 200 "Please use --confirm if you really want to do this".format(fcopr.full_name)) 201 db.session.commit() 202 203 except (ActionInProgressException, InsufficientRightsException) as err: 204 db.session.rollback() 205 raise err 206 else: 207 raise BadRequest(form.errors) 208 209 return flask.jsonify(to_dict(fcopr))
210
211 212 @apiv3_ns.route("/project/delete/<ownername>/<projectname>", methods=DELETE) 213 @api_login_required 214 -def delete_project(ownername, projectname):
215 copr = get_copr(ownername, projectname) 216 copr_dict = to_dict(copr) 217 form = forms.APICoprDeleteForm(meta={'csrf': False}) 218 219 if form.validate_on_submit() and copr: 220 try: 221 ComplexLogic.delete_copr(copr) 222 except (ActionInProgressException, 223 InsufficientRightsException) as err: 224 db.session.rollback() 225 raise err 226 else: 227 db.session.commit() 228 else: 229 raise BadRequest(form.errors) 230 return flask.jsonify(copr_dict)
231