def view(request, form=None): project_name = request.matchdict['project_name'] try: issue_ref = int(request.matchdict['issue_ref']) except ValueError: # 'issue_ref' is not an integer. The route connected to this # view matched because no other route matched. This could be a # typo, for example: '/p/project-foo/confgure'. raise HTTPNotFound() session = DBSession() try: project = session.query(Project).filter_by(name=project_name).one() except NoResultFound: raise HTTPNotFound() if not has_permission(request, PERM_VIEW_PROJECT, project): raise HTTPForbidden() try: issue = session.query(Issue).filter_by( project_id=project.id, ref=issue_ref).one() except NoResultFound: raise HTTPNotFound() if form is None: data = {'assignee': issue.assignee, 'deadline': issue.deadline, 'kind': issue.kind, 'priority': issue.priority, 'status': issue.status, 'time_estimated': issue.time_estimated, 'time_billed': issue.time_billed, 'title': issue.title} form = make_add_change_form(project, session, **data) can_see_priv = has_permission( request, PERM_SEE_PRIVATE_TIMING_INFO, project) can_participate = has_permission( request, PERM_PARTICIPATE_IN_PROJECT, project) can_manage_project = has_permission(request, PERM_MANAGE_PROJECT, project) time_info = issue.get_time_info(include_private_info=can_see_priv) return {'api': TemplateAPI(request, issue.title), 'project': project, 'issue': issue, 'time_info': time_info, 'form': form, 'can_participate': can_participate, 'can_manage_project': can_manage_project, 'can_see_private_time_info': can_see_priv}
def update(request): project_name = request.matchdict['project_name'] issue_ref = int(request.matchdict['issue_ref']) session = DBSession() try: project = session.query(Project).filter_by(name=project_name).one() except NoResultFound: raise HTTPNotFound() if not has_permission(request, PERM_PARTICIPATE_IN_PROJECT, project): raise HTTPForbidden() try: issue = session.query(Issue).filter_by( project_id=project.id, ref=issue_ref).one() except NoResultFound: raise HTTPNotFound() # FIXME: move logic outside so that it can be more easily tested. form = make_add_change_form(project, session, request.POST) if not form.validate(): return view(request, form) now = datetime.utcnow() userid = request.user.id changes = {} for attr in ( 'title', 'status', 'assignee', 'deadline', 'priority', 'kind', 'time_estimated', 'time_billed'): old_v = getattr(issue, attr) new_v = getattr(form, attr).data if old_v != new_v: changes[attr] = (old_v, new_v) setattr(issue, attr, new_v) if form.time_spent_real.data and \ has_permission(request, PERM_SEE_PRIVATE_TIMING_INFO, project): changes['time_spent_real'] = (None, form.time_spent_real.data) if form.time_spent_public.data: changes['time_spent_public'] = (None, form.time_spent_public.data) if not changes and not form.text.data: error = _(u'You did not provide any comment or update.') form.errors['form'] = [error] return view(request, form) if form.status.data == ISSUE_STATUS_OPEN and \ issue.status != ISSUE_STATUS_OPEN: change_type = CHANGE_TYPE_REOPENING elif form.status.data == ISSUE_STATUS_CLOSED: change_type = CHANGE_TYPE_CLOSING else: change_type = CHANGE_TYPE_UPDATE change = Change(project_id=project.id, issue_id=issue.id, type=change_type, author=userid, date=now, text=form.text.data, text_renderer=form.text_renderer.data, changes=changes) if 'time_spent_real' in changes: change.time_spent_real = form.time_spent_real.data if 'time_spent_public' in changes: change.time_spent_public = form.time_spent_public.data session.add(change) route_args = {'project_name': project_name, 'issue_ref': issue.ref, '_query': {'issue_updated': 1}, '_anchor': 'issue_updated'} url = request.route_url('issue_view', **route_args) return HTTPSeeOther(location=url)