Merge branch 'replace_page_edit_form' into dev

This commit is contained in:
Dannon Baker
2017-09-28 12:57:20 -04:00
12 changed files with 170 additions and 181 deletions
+10
View File
@@ -46,6 +46,8 @@ window.app = function app( options, bootstrapped ){
'(/)user(/)(:form_id)' : 'show_user_form',
'(/)workflow(/)' : 'show_workflows',
'(/)workflow/run(/)' : 'show_run',
'(/)pages(/)create(/)' : 'show_pages_create',
'(/)pages(/)edit(/)' : 'show_pages_edit',
'(/)pages(/)(:action_id)' : 'show_pages',
'(/)visualizations(/)edit(/)' : 'show_visualizations_edit',
'(/)visualizations/(:action_id)' : 'show_visualizations',
@@ -114,6 +116,14 @@ window.app = function app( options, bootstrapped ){
this.page.display( new GridShared.View( { action_id: action_id, plural: 'Pages', item: 'page' } ) );
},
show_pages_create : function() {
this.page.display( new FormWrapper.View ( { url : 'page/create', redirect: 'pages/list' } ) );
},
show_pages_edit : function() {
this.page.display( new FormWrapper.View ( { url : 'page/edit?id=' + QueryStringParsing.get( 'id' ), redirect: 'pages/list' } ) );
},
show_workflows : function(){
this.page.display( new Workflows.View() );
},
+4 -1
View File
@@ -183,13 +183,16 @@ class BaseUIController(BaseController):
try:
return BaseController.get_object(self, trans, id, class_name,
check_ownership=check_ownership, check_accessible=check_accessible, deleted=deleted)
except exceptions.MessageException:
raise # handled in the caller
except:
log.exception("Exception in get_object check for %s %s:", class_name, str(id))
raise Exception('Server error retrieving %s id ( %s ).' % (class_name, str(id)))
def message_exception(self, trans, message):
trans.response.status = 400
return {'err_msg': util.sanitize_text(message)}
class BaseAPIController(BaseController):
+2
View File
@@ -121,6 +121,8 @@ def paste_app_factory(global_conf, **kwargs):
webapp.add_client_route('/visualizations/edit')
webapp.add_client_route('/pages/list')
webapp.add_client_route('/pages/list_published')
webapp.add_client_route('/pages/create')
webapp.add_client_route('/pages/edit')
webapp.add_client_route('/histories/list')
webapp.add_client_route('/histories/list_published')
webapp.add_client_route('/histories/list_shared')
+35 -40
View File
@@ -547,13 +547,13 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
if 'operation' in kwargs:
id = kwargs.get('id')
if not id:
return message_exception(trans, 'Invalid quota id (%s) received.' % str(id))
return self.message_exception(trans, 'Invalid quota id (%s) received.' % str(id))
quotas = []
for quota_id in util.listify(id):
try:
quotas.append(get_quota(trans, quota_id))
except MessageException as e:
return message_exception(trans, str(e))
return self.message_exception(trans, str(e))
operation = kwargs.pop('operation').lower()
try:
if operation == 'delete':
@@ -618,14 +618,14 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
quota, message = self._create_quota(util.Params(payload), decode_id=trans.security.decode_id)
return {'message': message}
except ActionInputError as e:
return message_exception(trans, e.err_msg)
return self.message_exception(trans, e.err_msg)
@web.expose_api
@web.require_admin
def rename_quota(self, trans, payload=None, **kwd):
id = kwd.get('id')
if not id:
return message_exception(trans, 'No quota id received for renaming.')
return self.message_exception(trans, 'No quota id received for renaming.')
quota = get_quota(trans, id)
if trans.request.method == 'GET':
return {
@@ -644,14 +644,14 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
try:
return {'message': self._rename_quota(quota, util.Params(payload))}
except ActionInputError as e:
return message_exception(trans, e.err_msg)
return self.message_exception(trans, e.err_msg)
@web.expose_api
@web.require_admin
def manage_users_and_groups_for_quota(self, trans, payload=None, **kwd):
quota_id = kwd.get('id')
if not quota_id:
return message_exception(trans, 'Invalid quota id (%s) received' % str(quota_id))
return self.message_exception(trans, 'Invalid quota id (%s) received' % str(quota_id))
quota = get_quota(trans, quota_id)
if trans.request.method == 'GET':
in_users = []
@@ -680,14 +680,14 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
try:
return {'message': self._manage_users_and_groups_for_quota(quota, util.Params(payload), decode_id=trans.security.decode_id)}
except ActionInputError as e:
return message_exception(trans, e.err_msg)
return self.message_exception(trans, e.err_msg)
@web.expose_api
@web.require_admin
def edit_quota(self, trans, payload=None, **kwd):
id = kwd.get('id')
if not id:
return message_exception(trans, 'No quota id received for renaming.')
return self.message_exception(trans, 'No quota id received for renaming.')
quota = get_quota(trans, id)
if trans.request.method == 'GET':
return {
@@ -708,14 +708,14 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
try:
return {'message': self._edit_quota(quota, util.Params(payload))}
except ActionInputError as e:
return message_exception(trans, e.err_msg)
return self.message_exception(trans, e.err_msg)
@web.expose_api
@web.require_admin
def set_quota_default(self, trans, payload=None, **kwd):
id = kwd.get('id')
if not id:
return message_exception(trans, 'No quota id received for renaming.')
return self.message_exception(trans, 'No quota id received for renaming.')
quota = get_quota(trans, id)
if trans.request.method == 'GET':
default_value = quota.default[0].type if quota.default else 'no'
@@ -736,7 +736,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
try:
return {'message': self._set_quota_default(quota, util.Params(payload))}
except ActionInputError as e:
return message_exception(trans, e.err_msg)
return self.message_exception(trans, e.err_msg)
@web.expose
@web.require_admin
@@ -984,11 +984,11 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
in_users = [trans.sa_session.query(trans.app.model.User).get(trans.security.decode_id(x)) for x in util.listify(payload.get('in_users'))]
in_groups = [trans.sa_session.query(trans.app.model.Group).get(trans.security.decode_id(x)) for x in util.listify(payload.get('in_groups'))]
if not name or not description:
return message_exception(trans, 'Enter a valid name and a description.')
return self.message_exception(trans, 'Enter a valid name and a description.')
elif trans.sa_session.query(trans.app.model.Role).filter(trans.app.model.Role.table.c.name == name).first():
return message_exception(trans, 'Role names must be unique and a role with that name already exists, so choose another name.')
return self.message_exception(trans, 'Role names must be unique and a role with that name already exists, so choose another name.')
elif None in in_users or None in in_groups:
return message_exception(trans, 'One or more invalid user/group id has been provided.')
return self.message_exception(trans, 'One or more invalid user/group id has been provided.')
else:
# Create the role
role = trans.app.model.Role(name=name, description=description, type=trans.app.model.Role.types.ADMIN)
@@ -1004,7 +1004,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
if auto_create_checked:
# Check if role with same name already exists
if trans.sa_session.query(trans.app.model.Group).filter(trans.app.model.Group.table.c.name == name).first():
return message_exception(trans, 'A group with that name already exists, so choose another name or disable group creation.')
return self.message_exception(trans, 'A group with that name already exists, so choose another name or disable group creation.')
# Create the group
group = trans.app.model.Group(name=name)
trans.sa_session.add(group)
@@ -1025,7 +1025,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
def rename_role(self, trans, payload=None, **kwd):
id = kwd.get('id')
if not id:
return message_exception(trans, 'No role id received for renaming.')
return self.message_exception(trans, 'No role id received for renaming.')
role = get_role(trans, id)
if trans.request.method == 'GET':
return {
@@ -1045,11 +1045,11 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
new_name = util.restore_text(payload.get('name'))
new_description = util.restore_text(payload.get('description'))
if not new_name:
return message_exception(trans, 'Enter a valid role name.')
return self.message_exception(trans, 'Enter a valid role name.')
else:
existing_role = trans.sa_session.query(trans.app.model.Role).filter(trans.app.model.Role.table.c.name == new_name).first()
if existing_role and existing_role.id != role.id:
return message_exception(trans, 'A role with that name already exists.')
return self.message_exception(trans, 'A role with that name already exists.')
else:
if not (role.name == new_name and role.description == new_description):
role.name = new_name
@@ -1063,7 +1063,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
def manage_users_and_groups_for_role(self, trans, payload=None, **kwd):
role_id = kwd.get('id')
if not role_id:
return message_exception(trans, 'Invalid role id (%s) received' % str(role_id))
return self.message_exception(trans, 'Invalid role id (%s) received' % str(role_id))
role = get_role(trans, role_id)
if trans.request.method == 'GET':
in_users = []
@@ -1092,7 +1092,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
in_users = [trans.sa_session.query(trans.app.model.User).get(trans.security.decode_id(x)) for x in util.listify(payload.get('in_users'))]
in_groups = [trans.sa_session.query(trans.app.model.Group).get(trans.security.decode_id(x)) for x in util.listify(payload.get('in_groups'))]
if None in in_users or None in in_groups:
return message_exception(trans, 'One or more invalid user/group id has been provided.')
return self.message_exception(trans, 'One or more invalid user/group id has been provided.')
for ura in role.users:
user = trans.sa_session.query(trans.app.model.User).get(ura.user_id)
if user not in in_users:
@@ -1178,7 +1178,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
if 'operation' in kwargs:
id = kwargs.get('id')
if not id:
return message_exception(trans, 'Invalid group id (%s) received.' % str(id))
return self.message_exception(trans, 'Invalid group id (%s) received.' % str(id))
ids = util.listify(id)
operation = kwargs['operation'].lower().replace('+', ' ')
if operation == 'delete':
@@ -1198,7 +1198,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
def rename_group(self, trans, payload=None, **kwd):
id = kwd.get('id')
if not id:
return message_exception(trans, 'No group id received for renaming.')
return self.message_exception(trans, 'No group id received for renaming.')
group = get_group(trans, id)
if trans.request.method == 'GET':
return {
@@ -1213,11 +1213,11 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
old_name = group.name
new_name = util.restore_text(payload.get('name'))
if not new_name:
return message_exception(trans, 'Enter a valid group name.')
return self.message_exception(trans, 'Enter a valid group name.')
else:
existing_group = trans.sa_session.query(trans.app.model.Group).filter(trans.app.model.Group.table.c.name == new_name).first()
if existing_group and existing_group.id != group.id:
return message_exception(trans, 'A group with that name already exists.')
return self.message_exception(trans, 'A group with that name already exists.')
else:
if not (group.name == new_name):
group.name = new_name
@@ -1230,7 +1230,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
def manage_users_and_roles_for_group(self, trans, payload=None, **kwd):
group_id = kwd.get('id')
if not group_id:
return message_exception(trans, 'Invalid group id (%s) received' % str(group_id))
return self.message_exception(trans, 'Invalid group id (%s) received' % str(group_id))
group = get_group(trans, group_id)
if trans.request.method == 'GET':
in_users = []
@@ -1259,7 +1259,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
in_users = [trans.sa_session.query(trans.app.model.User).get(trans.security.decode_id(x)) for x in util.listify(payload.get('in_users'))]
in_roles = [trans.sa_session.query(trans.app.model.Role).get(trans.security.decode_id(x)) for x in util.listify(payload.get('in_roles'))]
if None in in_users or None in in_roles:
return message_exception(trans, 'One or more invalid user/role id has been provided.')
return self.message_exception(trans, 'One or more invalid user/role id has been provided.')
trans.app.security_agent.set_entity_group_associations(groups=[group], users=in_users, roles=in_roles)
trans.sa_session.refresh(group)
return {'message' : 'Group \'%s\' has been updated with %d associated users and %d associated roles.' % (group.name, len(in_users), len(in_roles))}
@@ -1297,11 +1297,11 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
in_users = [trans.sa_session.query(trans.app.model.User).get(trans.security.decode_id(x)) for x in util.listify(payload.get('in_users'))]
in_roles = [trans.sa_session.query(trans.app.model.Role).get(trans.security.decode_id(x)) for x in util.listify(payload.get('in_roles'))]
if not name:
return message_exception(trans, 'Enter a valid name.')
return self.message_exception(trans, 'Enter a valid name.')
elif trans.sa_session.query(trans.app.model.Group).filter(trans.app.model.Group.table.c.name == name).first():
return message_exception(trans, 'Group names must be unique and a group with that name already exists, so choose another name.')
return self.message_exception(trans, 'Group names must be unique and a group with that name already exists, so choose another name.')
elif None in in_users or None in in_roles:
return message_exception(trans, 'One or more invalid user/role id has been provided.')
return self.message_exception(trans, 'One or more invalid user/role id has been provided.')
else:
# Create the role
group = trans.app.model.Group(name=name)
@@ -1317,7 +1317,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
if auto_create_checked:
# Check if role with same name already exists
if trans.sa_session.query(trans.app.model.Role).filter(trans.app.model.Role.table.c.name == name).first():
return message_exception(trans, 'A role with that name already exists, so choose another name or disable role creation.')
return self.message_exception(trans, 'A role with that name already exists, so choose another name or disable role creation.')
# Create the role
role = trans.app.model.Role(name=name, description='Role for group %s' % name)
trans.sa_session.add(role)
@@ -1396,16 +1396,16 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
password = payload.get('password')
confirm = payload.get('confirm')
if len(password) < 6:
return message_exception(trans, 'Use a password of at least 6 characters.')
return self.message_exception(trans, 'Use a password of at least 6 characters.')
elif password != confirm:
return message_exception(trans, 'Passwords do not match.')
return self.message_exception(trans, 'Passwords do not match.')
for user in users.itervalues():
user.set_password_cleartext(password)
trans.sa_session.add(user)
trans.sa_session.flush()
return {'message': 'Passwords reset for %d user(s).' % len(users)}
else:
return message_exception(trans, 'Please specify user ids.')
return self.message_exception(trans, 'Please specify user ids.')
def _delete_user(self, trans, ids):
message = 'Deleted %d users: ' % len(ids)
@@ -1510,7 +1510,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
def manage_roles_and_groups_for_user(self, trans, payload=None, **kwd):
user_id = kwd.get('id')
if not user_id:
return message_exception(trans, 'Invalid user id (%s) received' % str(user_id))
return self.message_exception(trans, 'Invalid user id (%s) received' % str(user_id))
user = get_user(trans, user_id)
if trans.request.method == 'GET':
in_roles = []
@@ -1542,7 +1542,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
in_roles = [trans.sa_session.query(trans.app.model.Role).get(trans.security.decode_id(x)) for x in util.listify(payload.get('in_roles'))]
in_groups = [trans.sa_session.query(trans.app.model.Group).get(trans.security.decode_id(x)) for x in util.listify(payload.get('in_groups'))]
if None in in_groups or None in in_roles:
return message_exception(trans, 'One or more invalid role/group id has been provided.')
return self.message_exception(trans, 'One or more invalid role/group id has been provided.')
# make sure the user is not dis-associating himself from his private role
private_role = trans.app.security_agent.get_private_user_role(user)
@@ -1715,11 +1715,6 @@ def build_select_input(name, label, options, value):
'value' : value}
def message_exception(trans, message):
trans.response.status = 400
return {'err_msg': sanitize_text(message)}
def get_user(trans, user_id):
"""Get a User from the database by id."""
user = trans.sa_session.query(trans.model.User).get(trans.security.decode_id(user_id))
@@ -87,7 +87,7 @@ class Forms(BaseUIController):
if 'operation' in kwd:
id = kwd.get('id')
if not id:
return message_exception(trans, 'Invalid form id (%s) received.' % str(id))
return self.message_exception(trans, 'Invalid form id (%s) received.' % str(id))
ids = util.listify(id)
operation = kwd['operation'].lower()
if operation == 'delete':
@@ -147,7 +147,7 @@ class Forms(BaseUIController):
index = index + 1
new_form, message = self.save_form_definition(trans, None, payload)
if new_form is None:
return message_exception(trans, message)
return self.message_exception(trans, message)
imported = (' with %i imported fields' % index) if index > 0 else ''
message = 'The form \'%s\' has been created%s.' % (payload.get('name'), imported)
return {'message': util.sanitize_text(message)}
@@ -157,7 +157,7 @@ class Forms(BaseUIController):
def edit_form(self, trans, payload=None, **kwd):
id = kwd.get('id')
if not id:
return message_exception(trans, 'No form id received for editing.')
return self.message_exception(trans, 'No form id received for editing.')
form = get_form(trans, id)
latest_form = form.latest_form
if trans.request.method == 'GET':
@@ -232,7 +232,7 @@ class Forms(BaseUIController):
else:
new_form, message = self.save_form_definition(trans, id, payload)
if new_form is None:
return message_exception(trans, message)
return self.message_exception(trans, message)
message = 'The form \'%s\' has been updated.' % payload.get('name')
return {'message': util.sanitize_text(message)}
@@ -331,11 +331,6 @@ class Forms(BaseUIController):
# ---- Utility methods -------------------------------------------------------
def message_exception(trans, message):
trans.response.status = 400
return {'err_msg': util.sanitize_text(message)}
def get_form(trans, form_id):
"""Get a FormDefinition from the database by id."""
form = trans.sa_session.query(trans.app.model.FormDefinitionCurrent).get(trans.security.decode_id(form_id))
@@ -1245,7 +1245,7 @@ class HistoryController(BaseUIController, SharableMixin, UsesAnnotations, UsesIt
def rename(self, trans, payload=None, **kwd):
id = kwd.get('id')
if not id:
return message_exception(trans, 'No history id received for renaming.')
return self.message_exception(trans, 'No history id received for renaming.')
user = trans.get_user()
id = listify(id)
histories = []
@@ -1330,8 +1330,3 @@ class HistoryController(BaseUIController, SharableMixin, UsesAnnotations, UsesIt
new_history = trans.new_history(name)
return self.history_data(trans, new_history)
# TODO: /history/current to do all of the above: if ajax, return json; if post, read id and set to current
def message_exception(trans, message):
trans.response.status = 400
return {'err_msg': sanitize_text(message)}
+101 -93
View File
@@ -32,7 +32,7 @@ class PageListGrid(grids.Grid):
default_filter = {"published": "All", "tags": "All", "title": "All", "sharing": "All"}
default_sort_key = "-update_time"
columns = [
grids.TextColumn("Title", key="title", attach_popup=True, filterable="advanced"),
grids.TextColumn("Title", key="title", attach_popup=True, filterable="advanced", link=(lambda item: dict(action="display_by_username_and_slug", username=item.user.username, slug=item.slug))),
URLColumn("Public URL"),
grids.OwnerAnnotationColumn("Annotation", key="annotation", model_annotation_association_class=model.PageAnnotationAssociation, filterable="advanced"),
grids.IndividualTagsColumn("Tags", key="tags", model_tag_association_class=model.PageTagAssociation, filterable="advanced", grid_name="PageListGrid"),
@@ -45,13 +45,13 @@ class PageListGrid(grids.Grid):
cols_to_filter=[columns[0], columns[2]],
key="free-text-search", visible=False, filterable="standard"))
global_actions = [
grids.GridAction("Add new page", dict(action='create'), target="inbound")
grids.GridAction("Add new page", dict(controller="", action="pages/create"))
]
operations = [
grids.DisplayByUsernameAndSlugGridOperation("View", allow_multiple=False),
grids.GridOperation("Edit content", allow_multiple=False, url_args=dict(action='edit_content')),
grids.GridOperation("Edit attributes", allow_multiple=False, url_args=dict(action='edit')),
grids.GridOperation("Share or Publish", allow_multiple=False, condition=(lambda item: not item.deleted), url_args=dict(action='sharing')),
grids.GridOperation("Edit content", allow_multiple=False, url_args=dict(action="edit_content")),
grids.GridOperation("Edit attributes", allow_multiple=False, url_args=dict(controller="", action="pages/edit")),
grids.GridOperation("Share or Publish", allow_multiple=False, condition=(lambda item: not item.deleted), url_args=dict(action="sharing")),
grids.GridOperation("Delete", confirm="Are you sure you want to delete this page?"),
]
@@ -348,107 +348,115 @@ class PageController(BaseUIController, SharableMixin,
'slug' : p.page.slug,
'title' : p.page.title} for p in shared_by_others]
@web.expose
@web.expose_api
@web.require_login("create pages")
def create(self, trans, page_title="", page_slug="", page_annotation=""):
def create(self, trans, payload=None, **kwd):
"""
Create a new page
Create a new page.
"""
user = trans.get_user()
page_title_err = page_slug_err = page_annotation_err = ""
if trans.request.method == "POST":
if not page_title:
page_title_err = "Page name is required"
elif not page_slug:
page_slug_err = "Page id is required"
elif not self._is_valid_slug(page_slug):
page_slug_err = "Page identifier must consist of only lowercase letters, numbers, and the '-' character"
elif trans.sa_session.query(model.Page).filter_by(user=user, slug=page_slug, deleted=False).first():
page_slug_err = "Page id must be unique"
if trans.request.method == 'GET':
return {
'title' : 'Create a new page',
'inputs' : [{
'name' : 'title',
'label' : 'Name'
}, {
'name' : 'slug',
'label' : 'Identifier',
'help' : 'A unique identifier that will be used for public links to this page. This field can only contain lowercase letters, numbers, and dashes (-).'
}, {
'name' : 'annotation',
'label' : 'Annotation',
'help' : 'A description of the page. The annotation is shown alongside published pages.'
}]
}
else:
user = trans.get_user()
p_title = payload.get('title')
p_slug = payload.get('slug')
p_annotation = payload.get('annotation')
if not p_title:
return self.message_exception(trans, 'Please provide a page name is required.')
elif not p_slug:
return self.message_exception(trans, 'Please provide a unique identifier.')
elif not self._is_valid_slug(p_slug):
return self.message_exception(trans, 'Page identifier can only contain lowercase letters, numbers, and dashes (-).')
elif trans.sa_session.query(model.Page).filter_by(user=user, slug=p_slug, deleted=False).first():
return self.message_exception(trans, 'Page id must be unique.')
else:
# Create the new stored page
page = model.Page()
page.title = page_title
page.slug = page_slug
page_annotation = sanitize_html(page_annotation, 'utf-8', 'text/html')
self.add_item_annotation(trans.sa_session, trans.get_user(), page, page_annotation)
page.user = user
p = model.Page()
p.title = p_title
p.slug = p_slug
p.user = user
if p_annotation:
p_annotation = sanitize_html(p_annotation, 'utf-8', 'text/html')
self.add_item_annotation(trans.sa_session, user, p, p_annotation)
# And the first (empty) page revision
page_revision = model.PageRevision()
page_revision.title = page_title
page_revision.page = page
page.latest_revision = page_revision
page_revision.content = ""
p_revision = model.PageRevision()
p_revision.title = p_title
p_revision.page = p
p.latest_revision = p_revision
p_revision.content = ""
# Persist
session = trans.sa_session
session.add(page)
session.flush()
# Display the management page
# trans.set_message( "Page '%s' created" % page.title )
return trans.response.send_redirect(web.url_for(controller='pages', action='list'))
return trans.show_form(
web.FormBuilder(web.url_for(controller='page', action='create'), "Create new page", submit_text="Submit")
.add_text("page_title", "Page title", value=page_title, error=page_title_err)
.add_text("page_slug", "Page identifier", value=page_slug, error=page_slug_err,
help="""A unique identifier that will be used for
public links to this page. A default is generated
from the page title, but can be edited. This field
must contain only lowercase letters, numbers, and
the '-' character.""")
.add_text("page_annotation", "Page annotation", value=page_annotation, error=page_annotation_err,
help="A description of the page; annotation is shown alongside published pages."),
template="page/create.mako")
trans.sa_session.add(p)
trans.sa_session.flush()
return {'message': 'Page \'%s\' successfully created.' % p.title, 'status': 'success'}
@web.expose
@web.expose_api
@web.require_login("edit pages")
def edit(self, trans, id, page_title="", page_slug="", page_annotation=""):
def edit(self, trans, payload=None, **kwd):
"""
Edit a page's attributes.
"""
encoded_id = id
id = self.decode_id(id)
session = trans.sa_session
page = session.query(model.Page).get(id)
user = trans.user
assert page.user == user
page_title_err = page_slug_err = page_annotation_err = ""
if trans.request.method == "POST":
if not page_title:
page_title_err = "Page name is required"
elif not page_slug:
page_slug_err = "Page id is required"
elif not self._is_valid_slug(page_slug):
page_slug_err = "Page identifier must consist of only lowercase letters, numbers, and the '-' character"
elif page_slug != page.slug and trans.sa_session.query(model.Page).filter_by(user=user, slug=page_slug, deleted=False).first():
page_slug_err = "Page id must be unique"
elif not page_annotation:
page_annotation_err = "Page annotation is required"
else:
page.title = page_title
page.slug = page_slug
page_annotation = sanitize_html(page_annotation, 'utf-8', 'text/html')
self.add_item_annotation(trans.sa_session, trans.get_user(), page, page_annotation)
session.flush()
# Redirect to page list.
return trans.response.send_redirect(web.url_for(controller='pages', action='list'))
id = kwd.get('id')
if not id:
return self.message_exception(trans, 'No page id received for editing.')
decoded_id = self.decode_id(id)
user = trans.get_user()
p = trans.sa_session.query(model.Page).get(decoded_id)
if trans.request.method == 'GET':
if p.slug is None:
self.create_item_slug(trans.sa_session, p)
return {
'title' : 'Edit page attributes',
'inputs' : [{
'name' : 'title',
'label' : 'Name',
'value' : p.title
}, {
'name' : 'slug',
'label' : 'Identifier',
'value' : p.slug,
'help' : 'A unique identifier that will be used for public links to this page. This field can only contain lowercase letters, numbers, and dashes (-).'
}, {
'name' : 'annotation',
'label' : 'Annotation',
'value' : self.get_item_annotation_str(trans.sa_session, user, p),
'help' : 'A description of the page. The annotation is shown alongside published pages.'
}]
}
else:
page_title = page.title
page_slug = page.slug
page_annotation = self.get_item_annotation_str(trans.sa_session, trans.user, page)
if not page_annotation:
page_annotation = ""
return trans.show_form(
web.FormBuilder(web.url_for(controller='page', action='edit', id=encoded_id), "Edit page attributes", submit_text="Submit")
.add_text("page_title", "Page title", value=page_title, error=page_title_err)
.add_text("page_slug", "Page identifier", value=page_slug, error=page_slug_err,
help="""A unique identifier that will be used for
public links to this page. A default is generated
from the page title, but can be edited. This field
must contain only lowercase letters, numbers, and
the '-' character.""")
.add_text("page_annotation", "Page annotation", value=page_annotation, error=page_annotation_err,
help="A description of the page; annotation is shown alongside published pages."),
template="page/create.mako")
p_title = payload.get('title')
p_slug = payload.get('slug')
p_annotation = payload.get('annotation')
if not p_title:
return self.message_exception(trans, 'Please provide a page name is required.')
elif not p_slug:
return self.message_exception(trans, 'Please provide a unique identifier.')
elif not self._is_valid_slug(p_slug):
return self.message_exception(trans, 'Page identifier can only contain lowercase letters, numbers, and dashes (-).')
elif p_slug != p.slug and trans.sa_session.query(model.Page).filter_by(user=p.user, slug=p_slug, deleted=False).first():
return self.message_exception(trans, 'Page id must be unique.')
else:
p.title = p_title
p.slug = p_slug
if p_annotation:
p_annotation = sanitize_html(p_annotation, 'utf-8', 'text/html')
self.add_item_annotation(trans.sa_session, user, p, p_annotation)
trans.sa_session.add(p)
trans.sa_session.flush()
return {'message': 'Attributes of \'%s\' successfully saved.' % p.title, 'status': 'success'}
@web.expose
@web.require_login("edit pages")
@@ -570,7 +570,7 @@ class VisualizationController(BaseUIController, SharableMixin, UsesVisualization
"""
id = kwd.get('id')
if not id:
return message_exception(trans, 'No visualization id received for editing.')
return self.message_exception(trans, 'No visualization id received for editing.')
v = self.get_visualization(trans, id, check_ownership=True)
if trans.request.method == 'GET':
if v.slug is None:
@@ -585,7 +585,7 @@ class VisualizationController(BaseUIController, SharableMixin, UsesVisualization
'name' : 'slug',
'label' : 'Identifier',
'value' : v.slug,
'help' : 'A unique identifier that will be used for public links to this visualization. A default is generated from the visualization title, but can be edited. This field must contain only lowercase letters, numbers, and the \'-\' character.'
'help' : 'A unique identifier that will be used for public links to this visualization. This field can only contain lowercase letters, numbers, and dashes (-).'
}, {
'name' : 'dbkey',
'label' : 'Build',
@@ -607,13 +607,13 @@ class VisualizationController(BaseUIController, SharableMixin, UsesVisualization
v_dbkey = payload.get('dbkey')
v_annotation = payload.get('annotation')
if not v_title:
return message_exception(trans, 'Please provide a visualization name is required.')
return self.message_exception(trans, 'Please provide a visualization name is required.')
elif not v_slug:
return message_exception(trans, 'Please provide a unique identifier.')
return self.message_exception(trans, 'Please provide a unique identifier.')
elif not self._is_valid_slug(v_slug):
return message_exception(trans, 'Visualization identifier must consist of only lowercase letters, numbers, and the \'-\' character.')
return self.message_exception(trans, 'Visualization identifier can only contain lowercase letters, numbers, and dashes (-).')
elif v_slug != v.slug and trans.sa_session.query(model.Visualization).filter_by(user=v.user, slug=v_slug, deleted=False).first():
return message_exception(trans, 'Visualization id must be unique.')
return self.message_exception(trans, 'Visualization id must be unique.')
else:
v.title = v_title
v.slug = v_slug
@@ -967,8 +967,3 @@ class VisualizationController(BaseUIController, SharableMixin, UsesVisualization
name = fields[4]
rows.append([location, name])
return {'data': rows}
def message_exception(trans, message):
trans.response.status = 400
return {'err_msg': sanitize_text(message)}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-14
View File
@@ -1,14 +0,0 @@
<%inherit file="/form.mako"/>
<%def name="javascripts()">
${parent.javascripts()}
<script type="text/javascript">
$(function(){
var page_name = $("input[name=page_title]");
var page_slug = $("input[name=page_slug]");
page_name.keyup(function(){
page_slug.val( $(this).val().replace(/\s+/g,'-').replace(/[^a-zA-Z0-9\-]/g,'').toLowerCase() )
});
})
</script>
</%def>