Allowed superuser to edit posts in threads.

Catch IntegrityError in TryCatchDecorator
Check for duplicate title in threads
This commit is contained in:
Tanshu 2013-06-20 14:28:35 +05:30
parent c6c091bdcb
commit b9845a2dc1
7 changed files with 49 additions and 27 deletions

View File

@ -73,6 +73,10 @@ class Thread(Base):
def by_id(cls, id):
return DBSession.query(cls).filter(cls.id == id).first()
@classmethod
def by_title(cls, title):
return DBSession.query(cls).filter(cls.title == title).first()
@classmethod
def list(cls):
return DBSession.query(cls).all()
@ -102,6 +106,8 @@ class Post(Base):
@classmethod
def by_id(cls, id):
if not isinstance(id, uuid.UUID):
id = uuid.UUID(id)
return DBSession.query(cls).filter(cls.id == id).first()
@classmethod

View File

@ -1,5 +1,5 @@
from pyramid.response import Response
from sqlalchemy.exc import OperationalError
from sqlalchemy.exc import OperationalError, IntegrityError
import transaction
class ValidationError(Exception):
@ -18,7 +18,7 @@ def TryCatchFunction(f):
def _decorator(self, *args, **kwargs):
try:
return f(self, *args, **kwargs)
except (ValidationError, ValueError, KeyError, AttributeError, TypeError, OperationalError) as ex:
except (ValidationError, ValueError, KeyError, AttributeError, TypeError, OperationalError, IntegrityError) as ex:
transaction.abort()
response = Response("Failed validation: {0}".format(str(ex)))
response.status_int = 500

View File

@ -1,6 +1,6 @@
CACHE MANIFEST
# version 2013-06-07.1
# version 2013-06-19.1
CACHE:
/partial/404.html

View File

@ -44,14 +44,14 @@
</div>
<ul class="media-list">
<li class="media" ng-repeat="post in message.Posts" ng-disabled="post.PostID">
<div ng-switch="!$last" class="media-body">
<div ng-switch="post.Readonly" class="media-body">
<div ng-switch-when="true" class="media">
<div class="controls widget-box">
<div class="widget-title">
<h5>Created on {{post.CreationDate | localTime}} by {{post.User}} (Dated: {{post.Date}})</h5>
<ul class="nav nav-tabs pull-right">
<li>
<a href="#" ng-hide="!perms['Messages']"><b class="icon-edit"></b></a>
<a href ng-click="edit(post)" ng-hide="!perms['Messages']"><b class="icon-edit"></b></a>
</li>
</ul>

View File

@ -250,26 +250,22 @@ overlord_directive.directive('aceEditor', ['$parse', function ($parse) {
if (!ngModel) return; // do nothing if no ngModel
var originalValue = '';
ngModel.$render = function () {
var value = ngModel.$viewValue || '';
editor.getSession().setValue(value);
originalValue = value;
};
var getter = $parse(attrs['ngModel']);
var setter = getter.assign;
editor.getSession().setValue(getter(scope));
scope.$watch(attrs['ngModel'], function (newValue) {
if (editor.getValue() !== newValue) {
editor.getSession().setValue(newValue);
}
})
editor.getSession().on('change', function () {
if (valid(editor)) {
scope.$apply(read);
setter(scope, editor.getValue());
scope.$apply();
}
});
editor.getSession().setValue(originalValue);
read();
function read() {
ngModel.$setViewValue(editor.getValue());
}
}
};
}]);

View File

@ -6,12 +6,17 @@ var MessageCtrl = ['$scope', '$location', 'message', 'tags', 'users', 'prioritie
$scope.tags = tags;
$scope.users = users;
message.Posts.push({});
message.Posts.push({Readonly: false});
$scope.addTag = function (tag) {
tags.push(tag);
message.Tags.push(tag);
};
$scope.edit = function (post) {
post.Readonly = false;
};
$scope.save = function () {
if (!$scope.message.Title.length) {
$scope.toasts.push({Type: 'Error', Message: 'Message Title Blank'});
@ -45,7 +50,7 @@ MessageCtrl.resolve = {
var len = result.length;
var i = 0;
var list = []
for (i=0; i<len; i++){
for (i = 0; i < len; i++) {
list.push(result[i].Name);
}
deferred.resolve(list);
@ -59,7 +64,7 @@ MessageCtrl.resolve = {
var len = result.length;
var i = 0;
var list = []
for (i=0; i<len; i++){
for (i = 0; i < len; i++) {
list.push(result[i].Name);
}
deferred.resolve(list);

View File

@ -11,7 +11,7 @@ from brewman.models.auth import User
from brewman.models.messaging import Thread, Post, Tag, Subscriber
from brewman.models.tzinfoutc import get_age
from brewman.models.validation_exception import TryCatchFunction
from brewman.models.validation_exception import TryCatchFunction, ValidationError
@view_config(request_method='GET', route_name='message_id', renderer='brewman:templates/angular_base.mako')
@ -25,7 +25,10 @@ def html(request):
def save(request):
user_id = uuid.UUID(authenticated_userid(request))
user_name = User.by_id(user_id).name
thread = Thread(title=request.json_body['Title'], priority=request.json_body['Priority'], user_id=user_id)
title = request.json_body['Title'].strip()
if Thread.by_title(title) is None:
raise ValidationError('Message with same title already exists')
thread = Thread(title=title, priority=request.json_body['Priority'], user_id=user_id)
DBSession.add(thread)
for item in request.json_body['Posts']:
if 'Content' in item and item['Content'].strip() != '':
@ -79,9 +82,20 @@ def update(request):
DBSession.add(tag)
thread.tags.append(tag)
posts = [p for p in request.json_body['Posts'] if 'PostID' not in p]
if super_user:
posts = [p for p in request.json_body['Posts'] if p['Readonly'] == False or 'PostID' not in p]
else:
posts = [p for p in request.json_body['Posts'] if 'PostID' not in p]
posts = [p for p in posts if 'Content' in p and p['Content'].strip() != '']
for item in posts:
if 'Content' in item and item['Content'].strip() != '':
if 'PostID' in item:
post = Post.by_id(item['PostID'])
post.content = item['Content'].strip()
if 'Date' in item:
post.date = datetime.datetime.strptime(item['Date'], '%d-%b-%Y')
post.user_id = user_id
post.creation_date = datetime.datetime.utcnow()
else:
dt = datetime.datetime.strptime(item['Date'], '%d-%b-%Y') if 'Date' in item else None
post = Post(content=item['Content'].strip(), date=dt, user_id=user_id)
thread.posts.append(post)
@ -158,7 +172,8 @@ def thread_info(id):
for post in item.posts:
thread['Posts'].append({'PostID': post.id, 'Content': post.content, 'User': post.user.name,
'Date': post.date.strftime('%d-%b-%Y'),
'CreationDate': post.creation_date.strftime('%d-%b-%Y %H:%M')})
'CreationDate': post.creation_date.strftime('%d-%b-%Y %H:%M'),
'Readonly': True})
return thread