def update_collection_by_deletion_of_referenced_form(collection, referenced_form): """Update a collection based on the deletion of a form it references. This function is called in the :class:`FormsController` when a form is deleted. It is called on each collection that references the deleted form and the changes to each of those collections are propagated through all of the collections that reference them, and so on. :param collection: a collection model object. :param referenced_form: a form model object. :returns: ``None``. """ collection_dict = collection.get_full_dict() collection.contents = remove_references_to_this_form( collection.contents, referenced_form.id) collections_referenced = get_collections_referenced(collection.contents) collection.contents_unpacked = generate_contents_unpacked( collection.contents, collections_referenced) collection.html = h.get_HTML_from_contents(collection.contents_unpacked, collection.markup_language) collection.datetime_modified = datetime.datetime.utcnow() backup_collection(collection_dict) update_collections_that_reference_this_collection( collection, OldcollectionsController.query_builder, contents_changed=True) Session.add(collection) Session.commit()
def update_collection_by_deletion_of_referenced_form(collection, referenced_form): """Update a collection based on the deletion of a form it references. This function is called in the :class:`FormsController` when a form is deleted. It is called on each collection that references the deleted form and the changes to each of those collections are propagated through all of the collections that reference them, and so on. :param collection: a collection model object. :param referenced_form: a form model object. :returns: ``None``. """ collection_dict = collection.get_full_dict() collection.contents = remove_references_to_this_form(collection.contents, referenced_form.id) collections_referenced = get_collections_referenced(collection.contents) collection.contents_unpacked = generate_contents_unpacked( collection.contents, collections_referenced) collection.html = h.get_HTML_from_contents(collection.contents_unpacked, collection.markup_language) collection.datetime_modified = datetime.datetime.utcnow() backup_collection(collection_dict) update_collections_that_reference_this_collection( collection, OldcollectionsController.query_builder, contents_changed=True) Session.add(collection) Session.commit()
def update_speaker(speaker, data): """Update a speaker. :param speaker: the speaker model to be updated. :param dict data: representation of the updated speaker. :returns: the updated speaker model or, if ``changed`` has not been set to ``True``, ``False``. """ changed = False # Unicode Data changed = speaker.set_attr('first_name', h.normalize(data['first_name']), changed) changed = speaker.set_attr('last_name', h.normalize(data['last_name']), changed) changed = speaker.set_attr('dialect', h.normalize(data['dialect']), changed) changed = speaker.set_attr('page_content', h.normalize(data['page_content']), changed) changed = speaker.set_attr('markup_language', h.normalize(data['markup_language']), changed) changed = speaker.set_attr('html', h.get_HTML_from_contents(speaker.page_content, speaker.markup_language), changed) if changed: speaker.datetime_modified = datetime.datetime.utcnow() return speaker return changed
def create_new_user(data): """Create a new user. :param dict data: the data for the user to be created. :returns: an SQLAlchemy model object representing the user. """ user = User() user.salt = h.generate_salt() user.password = unicode(h.encrypt_password(data['password'], str(user.salt))) user.username = h.normalize(data['username']) user.first_name = h.normalize(data['first_name']) user.last_name = h.normalize(data['last_name']) user.email = h.normalize(data['email']) user.affiliation = h.normalize(data['affiliation']) user.role = h.normalize(data['role']) user.markup_language = h.normalize(data['markup_language']) user.page_content = h.normalize(data['page_content']) user.html = h.get_HTML_from_contents(user.page_content, user.markup_language) # Many-to-One Data: input and output orthographies if data['input_orthography']: user.input_orthography= data['input_orthography'] if data['output_orthography']: user.output_orthography = data['output_orthography'] # OLD-generated Data user.datetime_modified = datetime.datetime.utcnow() # Create the user's directory h.create_user_directory(user) return user
def create_new_user(data): """Create a new user. :param dict data: the data for the user to be created. :returns: an SQLAlchemy model object representing the user. """ user = User() user.salt = h.generate_salt() user.password = unicode( h.encrypt_password(data['password'], str(user.salt))) user.username = h.normalize(data['username']) user.first_name = h.normalize(data['first_name']) user.last_name = h.normalize(data['last_name']) user.email = h.normalize(data['email']) user.affiliation = h.normalize(data['affiliation']) user.role = h.normalize(data['role']) user.markup_language = h.normalize(data['markup_language']) user.page_content = h.normalize(data['page_content']) user.html = h.get_HTML_from_contents(user.page_content, user.markup_language) # Many-to-One Data: input and output orthographies if data['input_orthography']: user.input_orthography = data['input_orthography'] if data['output_orthography']: user.output_orthography = data['output_orthography'] # OLD-generated Data user.datetime_modified = datetime.datetime.utcnow() # Create the user's directory h.create_user_directory(user) return user
def create_new_collection(data, collections_referenced): """Create a new collection. :param dict data: the collection to be created. :param dict collections_referenced: the collection models recursively referenced in ``data['contents']``. :returns: an SQLAlchemy model object representing the collection. """ collection = Collection() collection.UUID = unicode(uuid4()) # User-inputted string data collection.title = h.normalize(data['title']) collection.type = h.normalize(data['type']) collection.url = h.normalize(data['url']) collection.description = h.normalize(data['description']) collection.markup_language = h.normalize(data['markup_language']) collection.contents = h.normalize(data['contents']) collection.contents_unpacked = h.normalize(data['contents_unpacked']) collection.html = h.get_HTML_from_contents(collection.contents_unpacked, collection.markup_language) # User-inputted date: date_elicited collection.date_elicited = data['date_elicited'] # Many-to-One if data['elicitor']: collection.elicitor = data['elicitor'] if data['speaker']: collection.speaker = data['speaker'] if data['source']: collection.source = data['source'] # Many-to-Many: tags, files & forms collection.tags = [t for t in data['tags'] if t] collection.files = [f for f in data['files'] if f] collection.forms = [f for f in data['forms'] if f] # Restrict the entire collection if it is associated to restricted forms or # files or if it references a restricted collection in its contents field. immediately_referenced_collections = get_collections_referenced_in_contents( collection, collections_referenced) tags = [f.tags for f in collection.files + collection.forms + immediately_referenced_collections] tags = [tag for tag_list in tags for tag in tag_list] restricted_tags = [tag for tag in tags if tag.name == u'restricted'] if restricted_tags: restricted_tag = restricted_tags[0] if restricted_tag not in collection.tags: collection.tags.append(restricted_tag) # OLD-generated Data now = datetime.datetime.utcnow() collection.datetime_entered = now collection.datetime_modified = now collection.enterer = collection.modifier = session['user'] return collection
def update_contents_unpacked_etc(collection, **kwargs): deleted = kwargs.get('deleted', False) collection_id = kwargs.get('collection_id') if deleted: collection.contents = remove_references_to_this_collection(collection.contents, collection_id) collections_referenced = get_collections_referenced(collection.contents) collection.contents_unpacked = generate_contents_unpacked( collection.contents, collections_referenced) collection.html = h.get_HTML_from_contents(collection.contents_unpacked, collection.markup_language) collection.forms = [Session.query(Form).get(int(id)) for id in h.form_reference_pattern.findall(collection.contents_unpacked)]
def update_user(user, data): """Update a user. :param user: the user model to be updated. :param dict data: representation of the updated user. :returns: the updated user model or, if ``changed`` has not been set to ``True``, ``False``. """ changed = False # Unicode Data changed = user.set_attr('first_name', h.normalize(data['first_name']), changed) changed = user.set_attr('last_name', h.normalize(data['last_name']), changed) changed = user.set_attr('email', h.normalize(data['email']), changed) changed = user.set_attr('affiliation', h.normalize(data['affiliation']), changed) changed = user.set_attr('role', h.normalize(data['role']), changed) changed = user.set_attr('page_content', h.normalize(data['page_content']), changed) changed = user.set_attr('markup_language', h.normalize(data['markup_language']), changed) changed = user.set_attr( 'html', h.get_HTML_from_contents(user.page_content, user.markup_language), changed) # username and password need special treatment: a value of None means that # these should not be updated. if data['password'] is not None: changed = user.set_attr( 'password', unicode(h.encrypt_password(data['password'], str(user.salt))), changed) if data['username'] is not None: username = h.normalize(data['username']) if username != user.username: h.rename_user_directory(user.username, username) changed = user.set_attr('username', username, changed) # Many-to-One Data changed = user.set_attr('input_orthography', data['input_orthography'], changed) changed = user.set_attr('output_orthography', data['output_orthography'], changed) if changed: user.datetime_modified = datetime.datetime.utcnow() return user return changed
def test_create(self): """Tests that POST /pages creates a new page or returns an appropriate error if the input is invalid. """ original_page_count = Session.query(Page).count() # Create a valid one params = self.page_create_params.copy() params.update({ 'name': u'page', 'markup_language': u'Markdown', 'content': self.md_contents }) params = json.dumps(params) response = self.app.post(url('pages'), params, self.json_headers, self.extra_environ_admin) resp = json.loads(response.body) new_page_count = Session.query(Page).count() assert new_page_count == original_page_count + 1 assert resp['name'] == u'page' assert resp['content'] == self.md_contents assert resp['html'] == h.get_HTML_from_contents(self.md_contents, 'Markdown') assert response.content_type == 'application/json' # Invalid because name is empty and markup language is invalid params = self.page_create_params.copy() params.update({ 'name': u'', 'markup_language': u'markdownable', 'content': self.md_contents }) params = json.dumps(params) response = self.app.post(url('pages'), params, self.json_headers, self.extra_environ_admin, status=400) resp = json.loads(response.body) assert resp['errors']['name'] == u'Please enter a value' assert resp['errors']['markup_language'] == \ u"Value must be one of: Markdown; reStructuredText (not u'markdownable')" assert response.content_type == 'application/json' # Invalid because name is too long params = self.page_create_params.copy() params.update({ 'name': u'name' * 200, 'markup_language': u'Markdown', 'content': self.md_contents }) params = json.dumps(params) response = self.app.post(url('pages'), params, self.json_headers, self.extra_environ_admin, status=400) resp = json.loads(response.body) assert resp['errors']['name'] == u'Enter a value not more than 255 characters long' assert response.content_type == 'application/json'
def create_new_page(data): """Create a new page. :param dict data: the data for the page to be created. :returns: an SQLAlchemy model object representing the page. """ page = Page() page.name = h.normalize(data['name']) page.heading = h.normalize(data['heading']) page.markup_language = data['markup_language'] page.content = h.normalize(data['content']) page.html = h.get_HTML_from_contents(page.content, page.markup_language) page.datetime_modified = datetime.datetime.utcnow() return page
def update_contents_unpacked_etc(collection, **kwargs): deleted = kwargs.get('deleted', False) collection_id = kwargs.get('collection_id') if deleted: collection.contents = remove_references_to_this_collection( collection.contents, collection_id) collections_referenced = get_collections_referenced( collection.contents) collection.contents_unpacked = generate_contents_unpacked( collection.contents, collections_referenced) collection.html = h.get_HTML_from_contents( collection.contents_unpacked, collection.markup_language) collection.forms = [ Session.query(Form).get(int(id)) for id in h.form_reference_pattern.findall(collection.contents_unpacked) ]
def create_new_speaker(data): """Create a new speaker. :param dict data: the data for the speaker to be created. :returns: an SQLAlchemy model object representing the speaker. """ speaker = Speaker() speaker.first_name = h.normalize(data['first_name']) speaker.last_name = h.normalize(data['last_name']) speaker.dialect = h.normalize(data['dialect']) speaker.page_content = h.normalize(data['page_content']) speaker.datetime_modified = datetime.datetime.utcnow() speaker.markup_language = h.normalize(data['markup_language']) speaker.html = h.get_HTML_from_contents(speaker.page_content, speaker.markup_language) return speaker
def update_page(page, data): """Update a page. :param page: the page model to be updated. :param dict data: representation of the updated page. :returns: the updated page model or, if ``changed`` has not been set to ``True``, ``False``. """ changed = False # Unicode Data changed = page.set_attr('name', h.normalize(data['name']), changed) changed = page.set_attr('heading', h.normalize(data['heading']), changed) changed = page.set_attr('markup_language', data['markup_language'], changed) changed = page.set_attr('content', h.normalize(data['content']), changed) changed = page.set_attr('html', h.get_HTML_from_contents(page.content, page.markup_language), changed) if changed: page.datetime_modified = datetime.datetime.utcnow() return page return changed
def update_user(user, data): """Update a user. :param user: the user model to be updated. :param dict data: representation of the updated user. :returns: the updated user model or, if ``changed`` has not been set to ``True``, ``False``. """ changed = False # Unicode Data changed = user.set_attr('first_name', h.normalize(data['first_name']), changed) changed = user.set_attr('last_name', h.normalize(data['last_name']), changed) changed = user.set_attr('email', h.normalize(data['email']), changed) changed = user.set_attr('affiliation', h.normalize(data['affiliation']), changed) changed = user.set_attr('role', h.normalize(data['role']), changed) changed = user.set_attr('page_content', h.normalize(data['page_content']), changed) changed = user.set_attr('markup_language', h.normalize(data['markup_language']), changed) changed = user.set_attr('html', h.get_HTML_from_contents(user.page_content, user.markup_language), changed) # username and password need special treatment: a value of None means that # these should not be updated. if data['password'] is not None: changed = user.set_attr('password', unicode(h.encrypt_password(data['password'], str(user.salt))), changed) if data['username'] is not None: username = h.normalize(data['username']) if username != user.username: h.rename_user_directory(user.username, username) changed = user.set_attr('username', username, changed) # Many-to-One Data changed = user.set_attr('input_orthography', data['input_orthography'], changed) changed = user.set_attr('output_orthography', data['output_orthography'], changed) if changed: user.datetime_modified = datetime.datetime.utcnow() return user return changed
def update_page(page, data): """Update a page. :param page: the page model to be updated. :param dict data: representation of the updated page. :returns: the updated page model or, if ``changed`` has not been set to ``True``, ``False``. """ changed = False # Unicode Data changed = page.set_attr('name', h.normalize(data['name']), changed) changed = page.set_attr('heading', h.normalize(data['heading']), changed) changed = page.set_attr('markup_language', data['markup_language'], changed) changed = page.set_attr('content', h.normalize(data['content']), changed) changed = page.set_attr( 'html', h.get_HTML_from_contents(page.content, page.markup_language), changed) if changed: page.datetime_modified = datetime.datetime.utcnow() return page return changed
def test_create(self): """Tests that POST /pages creates a new page or returns an appropriate error if the input is invalid. """ original_page_count = Session.query(Page).count() # Create a valid one params = self.page_create_params.copy() params.update({ 'name': u'page', 'markup_language': u'Markdown', 'content': self.md_contents }) params = json.dumps(params) response = self.app.post(url('pages'), params, self.json_headers, self.extra_environ_admin) resp = json.loads(response.body) new_page_count = Session.query(Page).count() assert new_page_count == original_page_count + 1 assert resp['name'] == u'page' assert resp['content'] == self.md_contents assert resp['html'] == h.get_HTML_from_contents( self.md_contents, 'Markdown') assert response.content_type == 'application/json' # Invalid because name is empty and markup language is invalid params = self.page_create_params.copy() params.update({ 'name': u'', 'markup_language': u'markdownable', 'content': self.md_contents }) params = json.dumps(params) response = self.app.post(url('pages'), params, self.json_headers, self.extra_environ_admin, status=400) resp = json.loads(response.body) assert resp['errors']['name'] == u'Please enter a value' assert resp['errors']['markup_language'] == \ u"Value must be one of: Markdown; reStructuredText (not u'markdownable')" assert response.content_type == 'application/json' # Invalid because name is too long params = self.page_create_params.copy() params.update({ 'name': u'name' * 200, 'markup_language': u'Markdown', 'content': self.md_contents }) params = json.dumps(params) response = self.app.post(url('pages'), params, self.json_headers, self.extra_environ_admin, status=400) resp = json.loads(response.body) assert resp['errors'][ 'name'] == u'Enter a value not more than 255 characters long' assert response.content_type == 'application/json'
def update_collection(collection, data, collections_referenced): """Update a collection model. :param collection: the collection model to be updated. :param dict data: representation of the updated collection. :param dict collections_referenced: the collection models recursively referenced in ``data['contents']``. :returns: a 3-tuple where the second and third elements are invariable booleans indicating whether the collection has become restricted or has had its ``contents`` value changed as a result of the update, respectively. The first element is the updated collection or ``False`` of the no update has occurred. """ changed = False restricted = False contents_changed = False # Unicode Data changed = collection.set_attr('title', h.normalize(data['title']), changed) changed = collection.set_attr('type', h.normalize(data['type']), changed) changed = collection.set_attr('url', h.normalize(data['url']), changed) changed = collection.set_attr('description', h.normalize(data['description']), changed) changed = collection.set_attr('markup_language', h.normalize(data['markup_language']), changed) submitted_contents = h.normalize(data['contents']) if collection.contents != submitted_contents: collection.contents = submitted_contents contents_changed = changed = True changed = collection.set_attr('contents_unpacked', h.normalize(data['contents_unpacked']), changed) changed = collection.set_attr( 'html', h.get_HTML_from_contents(collection.contents_unpacked, collection.markup_language), changed) # User-entered date: date_elicited changed = collection.set_attr('date_elicited', data['date_elicited'], changed) # Many-to-One Data changed = collection.set_attr('elicitor', data['elicitor'], changed) changed = collection.set_attr('speaker', data['speaker'], changed) changed = collection.set_attr('source', data['source'], changed) # Many-to-Many Data: files, forms & tags # Update only if the user has made changes. files_to_add = [f for f in data['files'] if f] forms_to_add = [f for f in data['forms'] if f] tags_to_add = [t for t in data['tags'] if t] if set(files_to_add) != set(collection.files): collection.files = files_to_add changed = True if set(forms_to_add) != set(collection.forms): collection.forms = forms_to_add changed = True # Restrict the entire collection if it is associated to restricted forms or # files or if it references a restricted collection. tags = [ f.tags for f in collection.files + collection.forms + collections_referenced.values() ] tags = [tag for tag_list in tags for tag in tag_list] restricted_tags = [tag for tag in tags if tag.name == u'restricted'] if restricted_tags: restricted_tag = restricted_tags[0] if restricted_tag not in tags_to_add: tags_to_add.append(restricted_tag) if set(tags_to_add) != set(collection.tags): if u'restricted' in [t.name for t in tags_to_add] and \ u'restricted' not in [t.name for t in collection.tags]: restricted = True collection.tags = tags_to_add changed = True if changed: collection.datetime_modified = datetime.datetime.utcnow() session['user'] = Session.merge(session['user']) collection.modifier = session['user'] return collection, restricted, contents_changed return changed, restricted, contents_changed
def create_new_collection(data, collections_referenced): """Create a new collection. :param dict data: the collection to be created. :param dict collections_referenced: the collection models recursively referenced in ``data['contents']``. :returns: an SQLAlchemy model object representing the collection. """ collection = Collection() collection.UUID = unicode(uuid4()) # User-inputted string data collection.title = h.normalize(data['title']) collection.type = h.normalize(data['type']) collection.url = h.normalize(data['url']) collection.description = h.normalize(data['description']) collection.markup_language = h.normalize(data['markup_language']) collection.contents = h.normalize(data['contents']) collection.contents_unpacked = h.normalize(data['contents_unpacked']) collection.html = h.get_HTML_from_contents(collection.contents_unpacked, collection.markup_language) # User-inputted date: date_elicited collection.date_elicited = data['date_elicited'] # Many-to-One if data['elicitor']: collection.elicitor = data['elicitor'] if data['speaker']: collection.speaker = data['speaker'] if data['source']: collection.source = data['source'] # Many-to-Many: tags, files & forms collection.tags = [t for t in data['tags'] if t] collection.files = [f for f in data['files'] if f] collection.forms = [f for f in data['forms'] if f] # Restrict the entire collection if it is associated to restricted forms or # files or if it references a restricted collection in its contents field. immediately_referenced_collections = get_collections_referenced_in_contents( collection, collections_referenced) tags = [ f.tags for f in collection.files + collection.forms + immediately_referenced_collections ] tags = [tag for tag_list in tags for tag in tag_list] restricted_tags = [tag for tag in tags if tag.name == u'restricted'] if restricted_tags: restricted_tag = restricted_tags[0] if restricted_tag not in collection.tags: collection.tags.append(restricted_tag) # OLD-generated Data now = datetime.datetime.utcnow() collection.datetime_entered = now collection.datetime_modified = now # Because of SQLAlchemy's uniqueness constraints, we may need to set the # enterer to the elicitor. if data['elicitor'] and (data['elicitor'].id == session['user'].id): collection.enterer = data['elicitor'] else: collection.enterer = session['user'] return collection
def update_collection(collection, data, collections_referenced): """Update a collection model. :param collection: the collection model to be updated. :param dict data: representation of the updated collection. :param dict collections_referenced: the collection models recursively referenced in ``data['contents']``. :returns: a 3-tuple where the second and third elements are invariable booleans indicating whether the collection has become restricted or has had its ``contents`` value changed as a result of the update, respectively. The first element is the updated collection or ``False`` of the no update has occurred. """ changed = False restricted = False contents_changed = False # Unicode Data changed = collection.set_attr('title', h.normalize(data['title']), changed) changed = collection.set_attr('type', h.normalize(data['type']), changed) changed = collection.set_attr('url', h.normalize(data['url']), changed) changed = collection.set_attr('description', h.normalize(data['description']), changed) changed = collection.set_attr('markup_language', h.normalize(data['markup_language']), changed) submitted_contents = h.normalize(data['contents']) if collection.contents != submitted_contents: collection.contents = submitted_contents contents_changed = changed = True changed = collection.set_attr('contents_unpacked', h.normalize(data['contents_unpacked']), changed) changed = collection.set_attr('html', h.get_HTML_from_contents(collection.contents_unpacked, collection.markup_language), changed) # User-entered date: date_elicited changed = collection.set_attr('date_elicited', data['date_elicited'], changed) # Many-to-One Data changed = collection.set_attr('elicitor', data['elicitor'], changed) changed = collection.set_attr('speaker', data['speaker'], changed) changed = collection.set_attr('source', data['source'], changed) # Many-to-Many Data: files, forms & tags # Update only if the user has made changes. files_to_add = [f for f in data['files'] if f] forms_to_add = [f for f in data['forms'] if f] tags_to_add = [t for t in data['tags'] if t] if set(files_to_add) != set(collection.files): collection.files = files_to_add changed = True if set(forms_to_add) != set(collection.forms): collection.forms = forms_to_add changed = True # Restrict the entire collection if it is associated to restricted forms or # files or if it references a restricted collection. tags = [f.tags for f in collection.files + collection.forms + collections_referenced.values()] tags = [tag for tag_list in tags for tag in tag_list] restricted_tags = [tag for tag in tags if tag.name == u'restricted'] if restricted_tags: restricted_tag = restricted_tags[0] if restricted_tag not in tags_to_add: tags_to_add.append(restricted_tag) if set(tags_to_add) != set(collection.tags): if u'restricted' in [t.name for t in tags_to_add] and \ u'restricted' not in [t.name for t in collection.tags]: restricted = True collection.tags = tags_to_add changed = True if changed: collection.datetime_modified = datetime.datetime.utcnow() session['user'] = Session.merge(session['user']) collection.modifier = session['user'] return collection, restricted, contents_changed return changed, restricted, contents_changed