Package coprs :: Package views :: Package coprs_ns :: Module coprs_general
[hide private]
[frames] | no frames]

Source Code for Module coprs.views.coprs_ns.coprs_general

  1  import os 
  2  import time 
  3   
  4  import flask 
  5  import platform 
  6  import smtplib 
  7  import sqlalchemy 
  8  from email.mime.text import MIMEText 
  9   
 10  from coprs import app 
 11  from coprs import db 
 12  from coprs import exceptions 
 13  from coprs import forms 
 14  from coprs import helpers 
 15  from coprs import models 
 16   
 17  from coprs.views.misc import login_required, page_not_found 
 18   
 19  from coprs.views.coprs_ns import coprs_ns 
 20   
 21  from coprs.logic import builds_logic 
 22  from coprs.logic import coprs_logic 
 23  from coprs.helpers import parse_package_name, render_repo 
24 25 26 @coprs_ns.route('/', defaults = {'page': 1}) 27 @coprs_ns.route('/<int:page>/') 28 -def coprs_show(page=1):
29 query = coprs_logic.CoprsLogic.get_multiple(flask.g.user, with_mock_chroots=False) 30 paginator = helpers.Paginator(query, query.count(), page) 31 32 coprs = paginator.sliced_query 33 return flask.render_template('coprs/show.html', coprs=coprs, paginator=paginator)
34
35 36 @coprs_ns.route('/<username>/', defaults = {'page': 1}) 37 @coprs_ns.route('/<username>/<int:page>/') 38 -def coprs_by_owner(username=None, page=1):
39 query = coprs_logic.CoprsLogic.get_multiple(flask.g.user, 40 user_relation='owned', 41 username=username, 42 with_mock_chroots=False) 43 paginator = helpers.Paginator(query, query.count(), page) 44 45 coprs = paginator.sliced_query 46 return flask.render_template('coprs/show.html', coprs=coprs, paginator=paginator)
47
48 49 @coprs_ns.route('/<username>/allowed/', defaults = {'page': 1}) 50 @coprs_ns.route('/<username>/allowed/<int:page>/') 51 -def coprs_by_allowed(username=None, page=1):
52 query = coprs_logic.CoprsLogic.get_multiple(flask.g.user, 53 user_relation='allowed', 54 username=username, 55 with_mock_chroots=False) 56 paginator = helpers.Paginator(query, query.count(), page) 57 58 coprs = paginator.sliced_query 59 return flask.render_template('coprs/show.html', coprs=coprs, paginator=paginator)
60
61 62 @coprs_ns.route('/fulltext/', defaults = {'page': 1}) 63 @coprs_ns.route('/fulltext/<int:page>/') 64 -def coprs_fulltext_search(page=1):
65 fulltext = flask.request.args.get('fulltext', '') 66 try: 67 query = coprs_logic.CoprsLogic.get_multiple_fulltext(flask.g.user, fulltext) 68 except ValueError, e: 69 flask.flash(str(e)) 70 return flask.redirect(flask.request.referrer or flask.url_for('coprs_ns.coprs_show')) 71 paginator = helpers.Paginator(query, query.count(), page) 72 73 coprs = paginator.sliced_query 74 return flask.render_template('coprs/show.html', 75 coprs=coprs, 76 paginator=paginator, 77 fulltext=fulltext)
78
79 80 @coprs_ns.route('/<username>/add/') 81 @login_required 82 -def copr_add(username):
83 form = forms.CoprFormFactory.create_form_cls()() 84 85 return flask.render_template('coprs/add.html', form = form)
86
87 88 @coprs_ns.route('/<username>/new/', methods=['POST']) 89 @login_required 90 -def copr_new(username):
91 """ Receive information from the user on how to create its new copr 92 and create it accordingly. 93 """ 94 form = forms.CoprFormFactory.create_form_cls()() 95 if form.validate_on_submit(): 96 copr = coprs_logic.CoprsLogic.add(flask.g.user, 97 name=form.name.data, 98 repos=form.repos.data.replace('\n', ' '), 99 selected_chroots=form.selected_chroots, 100 description=form.description.data, 101 instructions=form.instructions.data) 102 db.session.commit() 103 flask.flash('New project was successfully created.') 104 105 if form.initial_pkgs.data: 106 builds_logic.BuildsLogic.add(flask.g.user, 107 pkgs=form.initial_pkgs.data.replace('\n', ' '), 108 copr=copr) 109 db.session.commit() 110 flask.flash('Initial packages were successfully submitted ' 111 'for building.') 112 113 return flask.redirect(flask.url_for('coprs_ns.copr_detail', username=flask.g.user.name, coprname=copr.name)) 114 else: 115 return flask.render_template('coprs/add.html', form = form)
116
117 118 @coprs_ns.route('/<username>/<coprname>/') 119 -def copr_detail(username, coprname):
120 query = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname, with_mock_chroots=True) 121 form = forms.CoprLegalFlagForm() 122 try: 123 copr = query.one() 124 except sqlalchemy.orm.exc.NoResultFound: 125 return page_not_found('Copr with name {0} does not exist.'.format(coprname)) 126 127 return flask.render_template('coprs/detail/overview.html', 128 copr=copr, 129 form=form)
130
131 132 @coprs_ns.route('/<username>/<coprname>/permissions/') 133 -def copr_permissions(username, coprname):
134 query = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname) 135 copr = query.first() 136 if not copr: 137 return page_not_found('Copr with name {0} does not exist.'.format(coprname)) 138 139 permissions = coprs_logic.CoprPermissionsLogic.get_for_copr(flask.g.user, copr).all() 140 if flask.g.user: 141 user_perm = flask.g.user.permissions_for_copr(copr) 142 else: 143 user_perm = None 144 145 permissions_applier_form = None 146 permissions_form = None 147 148 # generate a proper form for displaying 149 if flask.g.user: 150 if flask.g.user.can_edit(copr): 151 permissions_form = forms.PermissionsFormFactory.create_form_cls(permissions)() 152 else: 153 # https://github.com/ajford/flask-wtf/issues/58 154 permissions_applier_form = forms.PermissionsApplierFormFactory.create_form_cls(user_perm)(formdata=None) 155 156 return flask.render_template('coprs/detail/permissions.html', 157 copr = copr, 158 permissions_form = permissions_form, 159 permissions_applier_form = permissions_applier_form, 160 permissions = permissions, 161 current_user_permissions = user_perm)
162
163 164 @coprs_ns.route('/<username>/<coprname>/edit/') 165 @login_required 166 -def copr_edit(username, coprname, form=None):
167 query = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname) 168 copr = query.first() 169 170 if not copr: 171 return page_not_found('Copr with name {0} does not exist.'.format(coprname)) 172 if not form: 173 form = forms.CoprFormFactory.create_form_cls(copr.mock_chroots)(obj=copr) 174 175 return flask.render_template('coprs/detail/edit.html', 176 copr=copr, 177 form=form)
178
179 180 @coprs_ns.route('/<username>/<coprname>/update/', methods = ['POST']) 181 @login_required 182 -def copr_update(username, coprname):
183 form = forms.CoprFormFactory.create_form_cls()() 184 copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first() 185 186 if form.validate_on_submit(): 187 # we don't change owner (yet) 188 copr.name = form.name.data 189 copr.repos = form.repos.data.replace('\n', ' ') 190 copr.description = form.description.data 191 copr.instructions = form.instructions.data 192 coprs_logic.CoprChrootsLogic.update_from_names(flask.g.user, copr, form.selected_chroots) 193 194 try: 195 coprs_logic.CoprsLogic.update(flask.g.user, copr, check_for_duplicates = False) # form validation checks for duplicates 196 except (exceptions.ActionInProgressException, exceptions.InsufficientRightsException) as e: 197 flask.flash(str(e)) 198 db.session.rollback() 199 else: 200 flask.flash('Project was updated successfully.') 201 db.session.commit() 202 203 return flask.redirect(flask.url_for('coprs_ns.copr_detail', username = username, coprname = copr.name)) 204 else: 205 return copr_edit(username, coprname, form)
206
207 208 @coprs_ns.route('/<username>/<coprname>/permissions_applier_change/', methods = ['POST']) 209 @login_required 210 -def copr_permissions_applier_change(username, coprname):
211 copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first() 212 permission = coprs_logic.CoprPermissionsLogic.get(flask.g.user, copr, flask.g.user).first() 213 applier_permissions_form = forms.PermissionsApplierFormFactory.create_form_cls(permission)() 214 215 if not copr: 216 return page_not_found('Project with name {0} does not exist.'.format(coprname)) 217 if copr.owner == flask.g.user: 218 flask.flash('Owner cannot request permissions for his own project.') 219 elif applier_permissions_form.validate_on_submit(): 220 # we rely on these to be 0 or 1 from form. TODO: abstract from that 221 new_builder = applier_permissions_form.copr_builder.data 222 new_admin = applier_permissions_form.copr_admin.data 223 coprs_logic.CoprPermissionsLogic.update_permissions_by_applier(flask.g.user, copr, permission, new_builder, new_admin) 224 db.session.commit() 225 flask.flash('Successfuly updated permissions for project "{0}".'.format(copr.name)) 226 227 return flask.redirect(flask.url_for('coprs_ns.copr_detail', username = copr.owner.name, coprname = copr.name))
228
229 230 @coprs_ns.route('/<username>/<coprname>/update_permissions/', methods = ['POST']) 231 @login_required 232 -def copr_update_permissions(username, coprname):
233 query = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname) 234 copr = query.first() 235 permissions = copr.copr_permissions 236 permissions_form = forms.PermissionsFormFactory.create_form_cls(permissions)() 237 238 if permissions_form.validate_on_submit(): 239 # we don't change owner (yet) 240 try: 241 # if admin is changing his permissions, his must be changed last 242 # so that we don't get InsufficientRightsException 243 permissions.sort(cmp=lambda x, y: -1 if y.user_id == flask.g.user.id else 1) 244 for perm in permissions: 245 new_builder = permissions_form['copr_builder_{0}'.format(perm.user_id)].data 246 new_admin = permissions_form['copr_admin_{0}'.format(perm.user_id)].data 247 coprs_logic.CoprPermissionsLogic.update_permissions(flask.g.user, copr, perm, new_builder, new_admin) 248 # for now, we don't check for actions here, as permissions operation don't collide with any actions 249 except exceptions.InsufficientRightsException as e: 250 db.session.rollback() 251 flask.flash(str(e)) 252 else: 253 db.session.commit() 254 flask.flash('Project permissions were updated successfully.') 255 256 return flask.redirect(flask.url_for('coprs_ns.copr_detail', username = copr.owner.name, coprname = copr.name))
257
258 259 @coprs_ns.route('/<username>/<coprname>/delete/', methods=['GET', 'POST']) 260 @login_required 261 -def copr_delete(username, coprname):
262 form = forms.CoprDeleteForm() 263 copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first() 264 265 if form.validate_on_submit(): 266 try: 267 coprs_logic.CoprsLogic.delete(flask.g.user, copr) 268 except (exceptions.ActionInProgressException, exceptions.InsufficientRightsException) as e: 269 db.session.rollback() 270 flask.flash(str(e)) 271 return flask.redirect(flask.url_for('coprs_ns.copr_detail', username=username, coprname=coprname)) 272 else: 273 db.session.commit() 274 flask.flash('Project was deleted successfully.') 275 return flask.redirect(flask.url_for('coprs_ns.coprs_by_owner', username=username)) 276 else: 277 if copr: 278 return flask.render_template('coprs/detail/delete.html', form=form, copr=copr) 279 else: 280 return page_not_found('Project {0}/{1} does not exist'.format(username, coprname))
281 314
315 316 @coprs_ns.route('/<username>/<coprname>/repo/<chroot>/') 317 -def generate_repo_file(username, coprname, chroot):
318 ''' Generate repo file for a given repo name. 319 Reponame = username-coprname ''' 320 # This solution is used because flask splits off the last part after a 321 # dash, therefore user-re-po resolves to user-re/po instead of user/re-po 322 # FAS usernames may not contain dashes, so this construction is safe. 323 324 reponame = "%s-%s" % (username, coprname) 325 326 if '-' not in reponame: 327 return page_not_found('Bad repository name: {0}. Must be username-projectname'.format(reponame)) 328 329 copr = None 330 try: 331 # query.one() is used since it fetches all builds, unlike query.first(). 332 copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname, 333 with_builds=True).one() 334 except sqlalchemy.orm.exc.NoResultFound: 335 return page_not_found('Project {0}/{1} does not exist'.format(username, coprname)) 336 337 try: 338 mock_chroot = coprs_logic.MockChrootsLogic.get_from_name(chroot).one() 339 except sqlalchemy.orm.exc.NoResultFound: 340 return page_not_found('Chroot %s does not exist' % chroot) 341 except ValueError, e: 342 return page_not_found("%s" % e) 343 344 url = '' 345 for build in copr.builds: 346 if build.results: 347 url = build.results 348 break 349 350 if not url: 351 return page_not_found('Repository not initialized: No finished builds in {0}/{1}.'.format(username, coprname)) 352 353 response = flask.make_response(render_repo(copr, mock_chroot, url)) 354 response.mimetype='text/plain' 355 response.headers['Content-Disposition'] = 'filename=%s.repo' % reponame 356 return response
357
358 @coprs_ns.route('/<username>/<coprname>/monitor/') 359 -def copr_build_monitor(username, coprname):
360 query = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname, with_mock_chroots=True) 361 form = forms.CoprLegalFlagForm() 362 try: 363 copr = query.one() 364 except sqlalchemy.orm.exc.NoResultFound: 365 return page_not_found('Copr with name {0} does not exist.'.format(coprname)) 366 367 builds_query = builds_logic.BuildsLogic.get_multiple(flask.g.user, copr=copr) 368 builds = builds_query.order_by('-id').all() 369 370 # please don't waste time trying to decipher this 371 # the only reason why this is necessary is non-existent 372 # database design 373 # 374 # loop goes through builds trying to approximate 375 # per-package results based on previous builds 376 # - it can't determine build results if build contains 377 # more than one package as this data is not available 378 379 out = {} 380 build = None 381 chroots = set([chroot.name for chroot in copr.active_chroots]) 382 latest_build = None 383 384 if builds: 385 latest_build = builds[0] 386 chroots.union([chroot.name for chroot in latest_build.build_chroots]) 387 388 chroots = sorted(chroots) 389 390 for build in builds: 391 chroot_results = {chroot.name: chroot.state 392 for chroot in build.build_chroots} 393 394 build_results = [] 395 for chroot_name in chroots: 396 if chroot_name in chroot_results: 397 build_results.append((build.id, chroot_results[chroot_name])) 398 else: 399 build_results.append((build.id, None)) 400 401 for pkg_url in build.pkgs.split(): 402 pkg = os.path.basename(pkg_url) 403 pkg_name = parse_package_name(pkg) 404 405 if pkg_name in out: 406 continue 407 408 out[pkg_name] = build_results 409 410 return flask.render_template('coprs/detail/monitor.html', 411 copr=copr, 412 build=latest_build, 413 chroots=chroots, 414 packages=sorted(out.iteritems()), 415 form=form)
416