def get_schema_annotation_dict(announcement_email): """Utility to get schema annotation dict for this course.""" schema_dict = [ (['title'], 'Announcement'), (['properties', 'key', '_inputex'], { 'label': 'ID', '_type': 'uneditable' }), (['properties', 'date', '_inputex'], { 'label': 'Date', '_type': 'date', 'dateFormat': 'Y/m/d', 'valueFormat': 'Y/m/d' }), (['properties', 'title', '_inputex'], { 'label': 'Title' }), (['properties', 'html', '_inputex'], { 'label': 'Body', '_type': 'html', 'supportCustomTags': tags.CAN_USE_DYNAMIC_TAGS.value }), oeditor.create_bool_select_annotation(['properties', 'is_draft'], 'Status', 'Draft', 'Published'), (['properties', 'send_email', '_inputex'], { 'label': 'Send Email', '_type': 'boolean', 'description': AnnouncementsItemRESTHandler.get_send_email_description( announcement_email) }) ] return schema_dict
def create_status_annotation(): return oeditor.create_bool_select_annotation( ['properties', 'is_draft'], 'Status', DRAFT_TEXT, PUBLISHED_TEXT, class_name='split-from-main-group')
def get_schema_annotation_dict(announcement_email): """Utility to get schema annotation dict for this course.""" schema_dict = [ (['title'], 'Announcement'), (['properties', 'key', '_inputex'], { 'label': 'ID', '_type': 'uneditable'}), (['properties', 'date', '_inputex'], { 'label': 'Date', '_type': 'date', 'dateFormat': 'Y/m/d', 'valueFormat': 'Y/m/d'}), (['properties', 'title', '_inputex'], {'label': 'Title'}), (['properties', 'html', '_inputex'], { 'label': 'Body', '_type': 'html', 'supportCustomTags': tags.CAN_USE_DYNAMIC_TAGS.value}), oeditor.create_bool_select_annotation( ['properties', 'is_draft'], 'Status', 'Draft', 'Published'), (['properties', 'send_email', '_inputex'], { 'label': 'Send Email', '_type': 'boolean', 'description': AnnouncementsItemRESTHandler.get_send_email_description( announcement_email)})] return schema_dict
"properties": { "name" : {"type": "string"}, "value": {"optional": true, "type": "%s"}, "is_draft": {"type": "boolean"} } } """ # This is a template because the doc_string is not yet known. SCHEMA_ANNOTATIONS_TEMPLATE = [ (['title'], 'Configuration Property Override'), (['properties', 'name', '_inputex'], { 'label': 'Name', '_type': 'uneditable'}), oeditor.create_bool_select_annotation( ['properties', 'is_draft'], 'Status', 'Pending', 'Active', description='<strong>Active</strong>: This value is active and ' 'overrides all other defaults.<br/><strong>Pending</strong>: This ' 'value is not active yet, and the default settings still apply.')] class ConfigPropertyRights(object): """Manages view/edit rights for configuration properties.""" @classmethod def can_view(cls): return cls.can_edit() @classmethod def can_edit(cls): return roles.Roles.is_super_admin()
"is_draft": {"type": "boolean"} } } """ # This is a template because the doc_string is not yet known. SCHEMA_ANNOTATIONS_TEMPLATE = [ (['title'], 'Configuration Property Override'), (['properties', 'name', '_inputex'], { 'label': 'Name', '_type': 'uneditable' }), oeditor.create_bool_select_annotation( ['properties', 'is_draft'], 'Status', 'Pending', 'Active', description='<strong>Active</strong>: This value is active and ' 'overrides all other defaults.<br/><strong>Pending</strong>: This ' 'value is not active yet, and the default settings still apply.') ] class ConfigPropertyRights(object): """Manages view/edit rights for configuration properties.""" @classmethod def can_view(cls): return cls.can_edit() @classmethod def can_edit(cls): return roles.Roles.is_super_admin()
def create_status_annotation(): return oeditor.create_bool_select_annotation( ["properties", "is_draft"], "Status", DRAFT_TEXT, PUBLISHED_TEXT, class_name="split-from-main-group" )
} """ SCHEMA_DICT = json.loads(SCHEMA_JSON) # inputex specific schema annotations to control editor look and feel SCHEMA_ANNOTATIONS_DICT = [ (["title"], "Announcement"), (["properties", "key", "_inputex"], {"label": "ID", "_type": "uneditable"}), ( ["properties", "date", "_inputex"], {"label": "Date", "_type": "date", "dateFormat": "Y/m/d", "valueFormat": "Y/m/d"}, ), (["properties", "title", "_inputex"], {"label": "Title"}), (["properties", "html", "_inputex"], {"label": "Body", "_type": "text"}), oeditor.create_bool_select_annotation(["properties", "is_draft"], "Status", "Draft", "Published"), ] class AnnouncementsRights(object): """Manages view/edit rights for announcements.""" @classmethod def can_view(cls, unused_handler): return True @classmethod def can_edit(cls, handler): return roles.Roles.is_course_admin(handler.app_context) @classmethod
from models import courses from models import roles from models import transforms from models import vfs from modules.oeditor import oeditor from modules.dashboard import messages from tools import verify import yaml from modules.offline_assignments import base DRAFT_TEXT = 'Private' PUBLISHED_TEXT = 'Public' STATUS_ANNOTATION = oeditor.create_bool_select_annotation( ['properties', 'is_draft'], 'Status', DRAFT_TEXT, PUBLISHED_TEXT, class_name='split-from-main-group') def workflow_key(key): return 'workflow:%s' % key def content_key(key): return 'content:%s' % key def blob_key(key): return content_key('blob:%s' % key)
} """ SCHEMA_DICT = json.loads(SCHEMA_JSON) # inputex specific schema annotations to control editor look and feel SCHEMA_ANNOTATIONS_DICT = [ (['title'], 'Announcement'), (['properties', 'key', '_inputex'], { 'label': 'ID', '_type': 'uneditable'}), (['properties', 'title', '_inputex'], {'label': 'Title'}), (['properties', 'date', '_inputex'], { 'label': 'Date', '_type': 'date', 'dateFormat': 'Y/m/d', 'valueFormat': 'Y/m/d'}), oeditor.create_bool_select_annotation( ['properties', 'is_html'], 'Type', 'Html', 'WikiText'), (['properties', 'html', '_inputex'], {'label': 'Body', '_type': 'text'}), oeditor.create_bool_select_annotation( ['properties', 'is_draft'], 'Status', 'Draft', 'Published')] class AnnouncementsRights(object): """Manages view/edit rights for announcements.""" @classmethod def can_view(cls, unused_handler): return True @classmethod def can_edit(cls, handler):
# inputex specific schema annotations to control editor look and feel SCHEMA_ANNOTATIONS_DICT = [ (['title'], 'Announcement'), (['properties', 'key', '_inputex'], { 'label': 'ID', '_type': 'uneditable' }), (['properties', 'title', '_inputex'], { 'label': 'Title' }), (['properties', 'date', '_inputex'], { 'label': 'Date', '_type': 'date', 'dateFormat': 'Y/m/d', 'valueFormat': 'Y/m/d' }), oeditor.create_bool_select_annotation(['properties', 'is_html'], 'Type', 'Html', 'WikiText'), (['properties', 'html', '_inputex'], { 'label': 'Body', '_type': 'text' }), oeditor.create_bool_select_annotation(['properties', 'is_draft'], 'Status', 'Draft', 'Published') ] class AnnouncementsRights(object): """Manages view/edit rights for announcements.""" @classmethod def can_view(cls, unused_handler): return True
DRAFT_TEXT = 'Private' PUBLISHED_TEXT = 'Public' # The editor has severe limitations for editing nested lists of objects. First, # it does not allow one to move a lesson from one unit to another. We need a way # of doing that. Second, JSON schema specification does not seem to support a # type-safe array, which has objects of different types. We also want that # badly :). All in all - using generic schema-based object editor for editing # nested arrayable polymorphic attributes is a pain... STATUS_ANNOTATION = oeditor.create_bool_select_annotation( ['properties', 'is_draft'], 'Status', DRAFT_TEXT, PUBLISHED_TEXT, class_name='split-from-main-group') class CourseOutlineRights(object): """Manages view/edit rights for course outline.""" @classmethod def can_view(cls, handler): return cls.can_edit(handler) @classmethod def can_edit(cls, handler): return roles.Roles.is_course_admin(handler.app_context) @classmethod
"name" : {"type": "string"}, "value": {"optional": true, "type": "%s"}, "is_draft": {"type": "boolean"} } } """ # This is a template because the doc_string is not yet known. SCHEMA_ANNOTATIONS_TEMPLATE = [ (["title"], "Configuration Property Override"), (["properties", "name", "_inputex"], {"label": "Name", "_type": "uneditable"}), oeditor.create_bool_select_annotation( ["properties", "is_draft"], "Status", "Pending", "Active", description="<strong>Active</strong>: This value is active and " "overrides all other defaults.<br/><strong>Pending</strong>: This " "value is not active yet, and the default settings still apply.", ), ] class ConfigPropertyRights(object): """Manages view/edit rights for configuration properties.""" @classmethod def can_view(cls): return cls.can_edit() @classmethod
class AnnouncementsItemRESTHandler(BaseRESTHandler): """Provides REST API for an announcement.""" # TODO(psimakov): we should really use an ordered dictionary, not plain # text; it can't be just a normal dict because a dict iterates its items in # undefined order; thus when we render a dict to JSON an order of fields # will not match what we specify here; the final editor will also show the # fields in an undefined order; for now we use the raw JSON, rather than the # dict, but will move to an ordered dict late. SCHEMA_JSON = """ { "id": "Announcement Entity", "type": "object", "description": "Announcement", "properties": { "key" : {"type": "string"}, "title": {"optional": true, "type": "string"}, "date": {"optional": true, "type": "date"}, "html": {"optional": true, "type": "html"}, "is_draft": {"type": "boolean"} } } """ SCHEMA_DICT = transforms.loads(SCHEMA_JSON) # inputex specific schema annotations to control editor look and feel SCHEMA_ANNOTATIONS_DICT = [ (['title'], 'Announcement'), (['properties', 'key', '_inputex'], { 'label': 'ID', '_type': 'uneditable' }), (['properties', 'date', '_inputex'], { 'label': 'Date', '_type': 'date', 'dateFormat': 'Y/m/d', 'valueFormat': 'Y/m/d' }), (['properties', 'title', '_inputex'], { 'label': 'Title' }), (['properties', 'html', '_inputex'], { 'label': 'Body', '_type': 'html', 'editorType': 'simple' }), oeditor.create_bool_select_annotation(['properties', 'is_draft'], 'Status', 'Draft', 'Published') ] REQUIRED_MODULES = [ 'inputex-date', 'gcb-rte', 'inputex-select', 'inputex-string', 'inputex-uneditable' ] def get(self): """Handles REST GET verb and returns an object as JSON payload.""" key = self.request.get('key') try: entity = AnnouncementEntity.get(key) except db.BadKeyError: entity = None if not entity: transforms.send_json_response(self, 404, 'Object not found.', {'key': key}) return viewable = AnnouncementsRights.apply_rights(self, [entity]) if not viewable: transforms.send_json_response(self, 401, 'Access denied.', {'key': key}) return entity = viewable[0] json_payload = transforms.dict_to_json( transforms.entity_to_dict(entity), AnnouncementsItemRESTHandler.SCHEMA_DICT) transforms.send_json_response( self, 200, 'Success.', payload_dict=json_payload, xsrf_token=XsrfTokenManager.create_xsrf_token('announcement-put')) def put(self): """Handles REST PUT verb with JSON payload.""" request = transforms.loads(self.request.get('request')) key = request.get('key') if not self.assert_xsrf_token_or_fail(request, 'announcement-put', {'key': key}): return if not AnnouncementsRights.can_edit(self): transforms.send_json_response(self, 401, 'Access denied.', {'key': key}) return entity = AnnouncementEntity.get(key) if not entity: transforms.send_json_response(self, 404, 'Object not found.', {'key': key}) return payload = request.get('payload') transforms.dict_to_entity( entity, transforms.json_to_dict(transforms.loads(payload), AnnouncementsItemRESTHandler.SCHEMA_DICT)) entity.put() transforms.send_json_response(self, 200, 'Saved.')
def create_status_annotation(): return oeditor.create_bool_select_annotation( ['properties', 'is_draft'], 'Status', DRAFT_TEXT, PUBLISHED_TEXT, class_name='split-from-main-group')