def delete(self, id): """Delete an existing orthography and return it. :URL: ``DELETE /orthographies/id`` :param str id: the ``id`` value of the orthography to be deleted. :returns: the deleted orthography model. .. note:: Contributors can only delete orthographies that are not used in the active application settings. """ orthography = Session.query(Orthography).get(id) if orthography: app_set = h.get_application_settings() if session['user'].role == u'administrator' or orthography not in ( app_set.storage_orthography, app_set.input_orthography, app_set.output_orthography): Session.delete(orthography) Session.commit() return orthography else: response.status = 403 return {'error': u'Only administrators are permitted to delete orthographies that are used in the active application settings.'} else: response.status_int = 404 return {'error': 'There is no orthography with id %s' % id}
def createForm(i, commit=False): f = model.Form() f.transcription = u'transcription' g1 = model.Gloss() g1.gloss = u'gloss' f.glosses.append(g1) if i % 2 == 0: g2 = model.Gloss() g2.gloss = u'gloss' f.glosses.append(g2) u = model.User() u.name = u'name' f.elicitor = u if i % 3 == 0: f1 = model.File() f1.filename = u'file%s-1.wav' % str(i) f2 = model.File() f2.filename = u'file%s-2.wav' % str(i) f3 = model.File() f3.filename = u'file%s-3.wav' % str(i) f.files = [f1, f2, f3] Session.add(f) if commit: Session.commit() return f
def _create_test_form_searches(n=100): """Create n form searches with various properties. A testing ground for searches! """ users = h.get_users() contributor = [u for u in users if u.role == u'contributor'][0] for i in range(1, n + 1): fs = model.FormSearch() fs.enterer_id = contributor.id fs.search = unicode(json.dumps( {'query': {'filter': ['Form', 'transcription', 'regex', '%d' % i]}})) if i % 2 == 0: fs.name = u'Form Search %d' % i else: fs.name = u'form search %d' % i if i > 50: fs.description = u'I really like this search and my favourite number is %d' % i if i > 20: fs.datetime_modified = today_timestamp else: fs.datetime_modified = yesterday_timestamp Session.add(fs) Session.commit()
def test_create(self): """Tests that POST /elicitationmethods creates a new elicitation method or returns an appropriate error if the input is invalid. """ original_EM_count = Session.query(ElicitationMethod).count() # Create a valid one params = json.dumps({'name': u'em', 'description': u'Described.'}) response = self.app.post(url('elicitationmethods'), params, self.json_headers, self.extra_environ_admin) resp = json.loads(response.body) new_EM_count = Session.query(ElicitationMethod).count() assert new_EM_count == original_EM_count + 1 assert resp['name'] == u'em' assert resp['description'] == u'Described.' assert response.content_type == 'application/json' # Invalid because name is not unique params = json.dumps({'name': u'em', 'description': u'Described.'}) response = self.app.post(url('elicitationmethods'), params, self.json_headers, self.extra_environ_admin, status=400) resp = json.loads(response.body) assert resp['errors']['name'] == u'The submitted value for ElicitationMethod.name is not unique.' assert response.content_type == 'application/json' # Invalid because name is empty params = json.dumps({'name': u'', 'description': u'Described.'}) response = self.app.post(url('elicitationmethods'), params, self.json_headers, self.extra_environ_admin, status=400) resp = json.loads(response.body) assert resp['errors']['name'] == u'Please enter a value' # Invalid because name is too long params = json.dumps({'name': u'name' * 400, 'description': u'Described.'}) response = self.app.post(url('elicitationmethods'), 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'
def delete(self, id): """Delete an existing orthography and return it. :URL: ``DELETE /orthographies/id`` :param str id: the ``id`` value of the orthography to be deleted. :returns: the deleted orthography model. .. note:: Contributors can only delete orthographies that are not used in the active application settings. """ orthography = Session.query(Orthography).get(id) if orthography: app_set = h.get_application_settings() if session['user'].role == u'administrator' or orthography not in ( app_set.storage_orthography, app_set.input_orthography, app_set.output_orthography): Session.delete(orthography) Session.commit() return orthography else: response.status = 403 return { 'error': u'Only administrators are permitted to delete orthographies that are used in the active application settings.' } else: response.status_int = 404 return {'error': 'There is no orthography with id %s' % id}
def show(self, id): """Return a user's remembered forms. :URL: ``GET /rememberedforms/id`` with optional query string parameters for ordering and pagination. :param str id: the ``id`` value of a user model. :returns: a list form models. .. note:: Any authenticated user is authorized to access this resource. Restricted forms are filtered from the array on a per-user basis. .. note:: See :func:`utils.add_order_by` and :func:`utils.add_pagination` for the query string parameters that effect ordering and pagination. """ user = Session.query(User).get(id) if user: try: query = h.eagerload_form(Session.query(Form))\ .filter(Form.memorizers.contains(user)) query = h.add_order_by(query, dict(request.GET), self.query_builder) query = h.filter_restricted_models('Form', query) return h.add_pagination(query, dict(request.GET)) except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def update(self, id): """Update a keyboard and return it. :URL: ``PUT /keyboards/id`` :Request body: JSON object representing the keyboard with updated attribute values. :param str id: the ``id`` value of the keyboard to be updated. :returns: the updated keyboard model. """ keyboard = Session.query(Keyboard).get(int(id)) if keyboard: try: schema = KeyboardSchema() values = json.loads(unicode(request.body, request.charset)) state = h.get_state_object(values) state.id = id data = schema.to_python(values, state) keyboard = update_keyboard(keyboard, data) # keyboard will be False if there are no changes (cf. # update_keyboard). if keyboard: Session.add(keyboard) Session.commit() return keyboard else: response.status_int = 400 return {'error': (u'The update request failed because the' u' submitted data were not new.')} except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
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(self, id): """Update a morpheme language model and return it. :URL: ``PUT /morphemelanguagemodels/id`` :Request body: JSON object representing the morpheme language model with updated attribute values. :param str id: the ``id`` value of the morpheme language model to be updated. :returns: the updated morpheme language model model. """ morpheme_language_model = h.eagerload_morpheme_language_model(Session.query(MorphemeLanguageModel)).get(int(id)) if morpheme_language_model: try: schema = MorphemeLanguageModelSchema() values = json.loads(unicode(request.body, request.charset)) state = h.get_state_object(values) state.id = id data = schema.to_python(values, state) morpheme_language_model_dict = morpheme_language_model.get_dict() morpheme_language_model = update_morpheme_language_model(morpheme_language_model, data) # morpheme_language_model will be False if there are no changes (cf. update_morpheme_language_model). if morpheme_language_model: backup_morpheme_language_model(morpheme_language_model_dict) Session.add(morpheme_language_model) Session.commit() return morpheme_language_model else: response.status_int = 400 return {'error': u'The update request failed because the submitted data were not new.'} except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def update(self, id): """Update a tag and return it. :URL: ``PUT /tags/id`` :Request body: JSON object representing the tag with updated attribute values. :param str id: the ``id`` value of the tag to be updated. :returns: the updated tag model. """ tag = Session.query(Tag).get(int(id)) if tag: try: schema = TagSchema() values = json.loads(unicode(request.body, request.charset)) state = h.get_state_object(values) state.id = id data = schema.to_python(values, state) tag = update_tag(tag, data) # tag will be False if there are no changes (cf. update_tag). if tag: Session.add(tag) Session.commit() return tag else: response.status_int = 400 return {'error': u'The update request failed because the submitted data were not new.'} except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def update(self, id): """Update an elicitation method and return it. :URL: ``PUT /elicitationmethods/id`` :Request body: JSON object representing the elicitation method with updated attribute values. :param str id: the ``id`` value of the elicitation method to be updated. :returns: the updated elicitation method model. """ elicitation_method = Session.query(ElicitationMethod).get(int(id)) if elicitation_method: try: schema = ElicitationMethodSchema() values = json.loads(unicode(request.body, request.charset)) state = h.get_state_object(values) state.id = id data = schema.to_python(values, state) elicitation_method = update_elicitation_method(elicitation_method, data) # elicitation_method will be False if there are no changes (cf. update_elicitation_method). if elicitation_method: Session.add(elicitation_method) Session.commit() return elicitation_method else: response.status_int = 400 return {'error': u'The update request failed because the submitted data were not new.'} except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def update(self, id): """Update a form search and return it. :URL: ``PUT /formsearches/id`` :Request body: JSON object representing the form search with updated attribute values. :param str id: the ``id`` value of the form search to be updated. :returns: the updated form search model. """ form_search = h.eagerload_form_search(Session.query(FormSearch)).get(int(id)) if form_search: try: schema = FormSearchSchema() values = json.loads(unicode(request.body, request.charset)) state = h.get_state_object(values) state.id = id state.config = config data = schema.to_python(values, state) form_search = update_form_search(form_search, data) # form_search will be False if there are no changes (cf. update_form_search). if form_search: Session.add(form_search) Session.commit() return form_search else: response.status_int = 400 return {'error': u'The update request failed because the submitted data were not new.'} except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def create(self): """Create a new user resource and return it. :URL: ``POST /users`` :request body: JSON object representing the user to create. :returns: the newly created user. .. note:: Only administrators are authorized to create users. """ try: schema = UserSchema() values = json.loads(unicode(request.body, request.charset)) data = schema.to_python(values) user = create_new_user(data) Session.add(user) Session.commit() return user.get_full_dict() except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def test_new(self): """Tests that GET /applicationsettings/new returns an appropriate JSON object for creating a new application settings object. The properties of the JSON object are 'languages', 'users' and 'orthographies' and their values are arrays/lists. """ # Add some orthographies. orthography1 = h.generate_default_orthography1() orthography2 = h.generate_default_orthography2() Session.add_all([orthography1, orthography2]) Session.commit() # Get the data currently in the db (see websetup.py for the test data). data = { 'languages': h.get_languages(), 'users': h.get_mini_dicts_getter('User')(), 'orthographies': h.get_mini_dicts_getter('Orthography')() } # JSON.stringify and then re-Python-ify the data. This is what the data # should look like in the response to a simulated GET request. data = json.loads(json.dumps(data, cls=h.JSONOLDEncoder)) # GET /applicationsettings/new without params. Expect a JSON array for # every store. response = self.app.get(url('new_applicationsetting'), extra_environ=self.extra_environ_admin) resp = json.loads(response.body) assert response.content_type == 'application/json' assert resp['languages'] == data['languages'] assert resp['users'] == data['users'] assert resp['orthographies'] == data['orthographies'] assert response.content_type == 'application/json' # GET /applicationsettings/new with params. Param values are treated as # strings, not JSON. If any params are specified, the default is to # return a JSON array corresponding to store for the param. There are # three cases that will result in an empty JSON array being returned: # 1. the param is not specified # 2. the value of the specified param is an empty string # 3. the value of the specified param is an ISO 8601 UTC datetime # string that matches the most recent datetime_modified value of the # store in question. params = { # Value is empty string: 'languages' will not be in response. 'languages': '', # Value is any string: 'users' will be in response. 'users': 'anything can go here!', # Value is ISO 8601 UTC datetime string that does not match the most # recent Orthography.datetime_modified value: 'orthographies' *will* # be in the response. 'orthographies': datetime.datetime.utcnow().isoformat(), } response = self.app.get(url('new_applicationsetting'), params, extra_environ=self.extra_environ_admin) resp = json.loads(response.body) assert resp['languages'] == [] assert resp['users'] == data['users'] assert resp['orthographies'] == data['orthographies']
def update(self, id): """Update a speaker and return it. :URL: ``PUT /speakers/id`` :Request body: JSON object representing the speaker with updated attribute values. :param str id: the ``id`` value of the speaker to be updated. :returns: the updated speaker model. """ speaker = Session.query(Speaker).get(int(id)) if speaker: try: schema = SpeakerSchema() values = json.loads(unicode(request.body, request.charset)) data = schema.to_python(values) speaker = update_speaker(speaker, data) # speaker will be False if there are no changes (cf. update_speaker). if speaker: Session.add(speaker) Session.commit() return speaker else: response.status_int = 400 return {'error': u'The update request failed because the submitted data were not new.'} except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
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(self, id): """Update a page and return it. :URL: ``PUT /pages/id`` :Request body: JSON object representing the page with updated attribute values. :param str id: the ``id`` value of the page to be updated. :returns: the updated page model. """ page = Session.query(Page).get(int(id)) if page: try: schema = PageSchema() values = json.loads(unicode(request.body, request.charset)) data = schema.to_python(values) page = update_page(page, data) # page will be False if there are no changes (cf. update_page). if page: Session.add(page) Session.commit() return page else: response.status_int = 400 return {'error': u'The update request failed because the submitted data were not new.'} except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def create(self): """Create a new corpus resource and return it. :URL: ``POST /corpora`` :request body: JSON object representing the corpus to create. :returns: the newly created corpus. """ try: schema = CorpusSchema() values = json.loads(unicode(request.body, request.charset)) state = h.get_state_object(values) state.config = config data = schema.to_python(values, state) corpus = create_new_corpus(data) Session.add(corpus) Session.commit() create_corpus_dir(corpus) return corpus except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def update(self, id): """Update an application settings and return it. :URL: ``PUT /applicationsettings/id`` :Request body: JSON object representing the application settings with updated attribute values. :param str id: the ``id`` value of the application settings to be updated. :returns: the updated application settings model. """ application_settings = h.eagerload_application_settings( Session.query(ApplicationSettings)).get(int(id)) if application_settings: try: schema = ApplicationSettingsSchema() values = json.loads(unicode(request.body, request.charset)) data = schema.to_python(values) # Try to create an updated ApplicationSetting object. application_settings = update_application_settings(application_settings, data) # application_settings will be False if there are no changes if application_settings: Session.add(application_settings) Session.commit() app_globals.application_settings = h.ApplicationSettings() return application_settings else: response.status_int = 400 return {'error': 'The update request failed because the submitted data were not new.'} except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def update(self, id): """Update a source and return it. :URL: ``PUT /sources/id`` :Request body: JSON object representing the source with updated attribute values. :param str id: the ``id`` value of the source to be updated. :returns: the updated source model. """ source = Session.query(Source).get(int(id)) if source: try: schema = SourceSchema() values = json.loads(unicode(request.body, request.charset)) state = h.get_state_object(values) state.id = id data = schema.to_python(values, state) source = update_source(source, data) # source will be False if there are no changes (cf. update_source). if source: Session.add(source) Session.commit() return source else: response.status_int = 400 return {'error': u'The update request failed because the submitted data were not new.'} except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def update(self, id): """Update a syntactic category and return it. :URL: ``PUT /syntacticcategorys/id`` :Request body: JSON object representing the syntactic category with updated attribute values. :param str id: the ``id`` value of the syntactic category to be updated. :returns: the updated syntactic category model. """ syntactic_category = Session.query(SyntacticCategory).get(int(id)) if syntactic_category: try: old_name = syntactic_category.name schema = SyntacticCategorySchema() values = json.loads(unicode(request.body, request.charset)) state = h.get_state_object(values) state.id = id data = schema.to_python(values, state) syntactic_category = update_syntactic_category(syntactic_category, data) # syntactic_category will be False if there are no changes (cf. update_syntactic_category). if syntactic_category: Session.add(syntactic_category) Session.commit() if syntactic_category.name != old_name: update_forms_referencing_this_category(syntactic_category) return syntactic_category else: response.status_int = 400 return {"error": u"The update request failed because the submitted data were not new."} except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {"errors": e.unpack_errors()}
def update(self, id): """Update a user and return it. :URL: ``PUT /users/id`` :Request body: JSON object representing the user with updated attribute values. :param str id: the ``id`` value of the user to be updated. :returns: the updated user model. """ user = Session.query(User).get(int(id)) if user: try: schema = UserSchema() values = json.loads(unicode(request.body, request.charset)) state = h.get_state_object(values) state.user_to_update = user.get_full_dict() state.user = session['user'].get_full_dict() data = schema.to_python(values, state) user = update_user(user, data) # user will be False if there are no changes (cf. update_user). if user: Session.add(user) Session.commit() return user.get_full_dict() else: response.status_int = 400 return {'error': u'The update request failed because the submitted data were not new.'} except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def tearDown(self, **kwargs): clear_all_tables = kwargs.get('clear_all_tables', False) dirs_to_clear = kwargs.get('dirs_to_clear', []) del_global_app_set = kwargs.get('del_global_app_set', False) dirs_to_destroy = kwargs.get('dirs_to_destroy', []) if clear_all_tables: h.clear_all_tables(['language']) else: h.clear_all_models() administrator = h.generate_default_administrator() contributor = h.generate_default_contributor() viewer = h.generate_default_viewer() Session.add_all([administrator, contributor, viewer]) Session.commit() for dir_path in dirs_to_clear: h.clear_directory_of_files(getattr(self, dir_path)) for dir_name in dirs_to_destroy: { 'user': lambda: h.destroy_all_directories('users', 'test.ini'), 'corpus': lambda: h.destroy_all_directories('corpora', 'test.ini'), 'phonology': lambda: h.destroy_all_directories('phonologies', 'test.ini'), 'morphology': lambda: h.destroy_all_directories('morphologies', 'test.ini'), 'morphological_parser': lambda: h.destroy_all_directories('morphological_parsers', 'test.ini'), 'morpheme_language_model': lambda: h.destroy_all_directories('morpheme_language_models', 'test.ini') }.get(dir_name, lambda: None)() if del_global_app_set: # Perform a vacuous GET just to delete app_globals.application_settings # to clean up for subsequent tests. self.app.get(url('new_form'), extra_environ=self.extra_environ_admin_appset)
def create(self): """Create a new collection resource and return it. :URL: ``POST /collections`` :request body: JSON object representing the collection to create. :returns: the newly created collection. """ try: unrestricted_users = h.get_unrestricted_users() user = session['user'] schema = CollectionSchema() values = json.loads(unicode(request.body, request.charset)) collections_referenced = get_collections_referenced(values['contents'], user, unrestricted_users) values = add_contents_unpacked_to_values(values, collections_referenced) values = add_form_ids_list_to_values(values) state = h.get_state_object(values) data = schema.to_python(values, state) collection = create_new_collection(data, collections_referenced) Session.add(collection) Session.commit() return collection.get_full_dict() except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except InvalidCollectionReferenceError, e: response.status_int = 400 return {'error': u'Invalid collection reference error: there is no collection with id %d' % e.args[0]}
def create(self): """Create a new collection resource and return it. :URL: ``POST /collections`` :request body: JSON object representing the collection to create. :returns: the newly created collection. """ try: unrestricted_users = h.get_unrestricted_users() user = session['user'] schema = CollectionSchema() values = json.loads(unicode(request.body, request.charset)) collections_referenced = get_collections_referenced( values['contents'], user, unrestricted_users) values = add_contents_unpacked_to_values(values, collections_referenced) values = add_form_ids_list_to_values(values) state = h.get_state_object(values) data = schema.to_python(values, state) collection = create_new_collection(data, collections_referenced) Session.add(collection) Session.commit() return collection.get_full_dict() except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except InvalidCollectionReferenceError, e: response.status_int = 400 return { 'error': u'Invalid collection reference error: there is no collection with id %d' % e.args[0] }
def _create_test_form_searches(n=100): """Create n form searches with various properties. A testing ground for searches! """ users = h.get_users() contributor = [u for u in users if u.role == u'contributor'][0] for i in range(1, n + 1): fs = model.FormSearch() fs.enterer_id = contributor.id fs.search = unicode( json.dumps({ 'query': { 'filter': ['Form', 'transcription', 'regex', '%d' % i] } })) if i % 2 == 0: fs.name = u'Form Search %d' % i else: fs.name = u'form search %d' % i if i > 50: fs.description = u'I really like this search and my favourite number is %d' % i if i > 20: fs.datetime_modified = today_timestamp else: fs.datetime_modified = yesterday_timestamp Session.add(fs) Session.commit()
def test_update(self): """Tests that PUT /speakers/id updates the speaker with id=id.""" # Create a speaker to update. params = self.speaker_create_params.copy() params.update({ 'first_name': u'first_name', 'last_name': u'last_name', 'page_content': u'page_content', 'dialect': u'dialect' }) params = json.dumps(params) response = self.app.post(url('speakers'), params, self.json_headers, self.extra_environ_admin) resp = json.loads(response.body) speaker_count = Session.query(Speaker).count() speaker_id = resp['id'] original_datetime_modified = resp['datetime_modified'] # Update the speaker sleep( 1 ) # sleep for a second to ensure that MySQL registers a different datetime_modified for the update params = self.speaker_create_params.copy() params.update({ 'first_name': u'first_name', 'last_name': u'last_name', 'page_content': u'page_content', 'dialect': u'updated dialect.' }) params = json.dumps(params) response = self.app.put(url('speaker', id=speaker_id), params, self.json_headers, self.extra_environ_admin) resp = json.loads(response.body) datetime_modified = resp['datetime_modified'] new_speaker_count = Session.query(Speaker).count() assert speaker_count == new_speaker_count assert datetime_modified != original_datetime_modified assert response.content_type == 'application/json' # Attempt an update with no new input and expect to fail sleep( 1 ) # sleep for a second to ensure that MySQL could register a different datetime_modified for the update response = self.app.put(url('speaker', id=speaker_id), params, self.json_headers, self.extra_environ_admin, status=400) resp = json.loads(response.body) speaker_count = new_speaker_count new_speaker_count = Session.query(Speaker).count() our_speaker_datetime_modified = Session.query(Speaker).get( speaker_id).datetime_modified assert our_speaker_datetime_modified.isoformat() == datetime_modified assert speaker_count == new_speaker_count assert resp[ 'error'] == u'The update request failed because the submitted data were not new.' assert response.content_type == 'application/json'
def compile_phonology(**kwargs): """Compile the foma script of a phonology and save it to the db with values that indicating compilation success. """ phonology = Session.query(model.Phonology).get(kwargs['phonology_id']) phonology.compile(kwargs['timeout']) phonology.datetime_modified = h.now() phonology.modifier_id = kwargs['user_id'] Session.commit()
def test_update(self): """Tests that PUT /pages/id updates the page with id=id.""" # Create a page to update. 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) page_count = Session.query(Page).count() page_id = resp['id'] original_datetime_modified = resp['datetime_modified'] # Update the page sleep( 1 ) # sleep for a second to ensure that MySQL registers a different datetime_modified for the update params = self.page_create_params.copy() params.update({ 'name': u'Awesome Page', 'markup_language': u'Markdown', 'content': self.md_contents }) params = json.dumps(params) response = self.app.put(url('page', id=page_id), params, self.json_headers, self.extra_environ_admin) resp = json.loads(response.body) datetime_modified = resp['datetime_modified'] new_page_count = Session.query(Page).count() assert page_count == new_page_count assert datetime_modified != original_datetime_modified assert resp['name'] == u'Awesome Page' assert response.content_type == 'application/json' # Attempt an update with no new input and expect to fail sleep( 1 ) # sleep for a second to ensure that MySQL could register a different datetime_modified for the update response = self.app.put(url('page', id=page_id), params, self.json_headers, self.extra_environ_admin, status=400) resp = json.loads(response.body) page_count = new_page_count new_page_count = Session.query(Page).count() our_page_datetime_modified = Session.query(Page).get( page_id).datetime_modified assert our_page_datetime_modified.isoformat() == datetime_modified assert page_count == new_page_count assert resp[ 'error'] == u'The update request failed because the submitted data were not new.' assert response.content_type == 'application/json'
def add_default_application_settings(): """Add the default application settings to the database.""" orthography1 = h.generate_default_orthography1() orthography2 = h.generate_default_orthography2() contributor = Session.query(User).filter(User.role==u'contributor').first() application_settings = h.generate_default_application_settings([orthography1, orthography2], [contributor]) Session.add(application_settings) Session.commit() return application_settings
def __call__(self, environ, start_response): """Invoke the Controller""" # WSGIController.__call__ dispatches to the Controller method # the request is routed to. This routing information is # available in environ['pylons.routes_dict'] # environ['paste.content_type'] = 'application/json' try: return WSGIController.__call__(self, environ, start_response) finally: Session.remove()
def backup_phonology(phonology_dict): """Backup a phonology. :param dict phonology_dict: a representation of a phonology model. :returns: ``None`` """ phonology_backup = PhonologyBackup() phonology_backup.vivify(phonology_dict) Session.add(phonology_backup)
def backup_morpheme_language_model(morpheme_language_model_dict): """Backup a morpheme language model. :param dict morpheme_language_model_dict: a representation of a morpheme language model model. :returns: ``None`` """ morpheme_language_model_backup = MorphemeLanguageModelBackup() morpheme_language_model_backup.vivify(morpheme_language_model_dict) Session.add(morpheme_language_model_backup)
def backup_morphological_parser(morphological_parser_dict): """Backup a morphological parser. :param dict morphological_parser_dict: a representation of a morphological parser model. :returns: ``None`` """ morphological_parser_backup = MorphologicalParserBackup() morphological_parser_backup.vivify(morphological_parser_dict) Session.add(morphological_parser_backup)
def backup_corpus(corpus_dict): """Backup a corpus. :param dict corpus_dict: a representation of a corpus model. :returns: ``None`` """ corpus_backup = CorpusBackup() corpus_backup.vivify(corpus_dict) Session.add(corpus_backup)
def backup_morphology(morphology_dict): """Backup a morphology. :param dict morphology_dict: a representation of a morphology model. :returns: ``None`` """ morphology_backup = MorphologyBackup() morphology_backup.vivify(morphology_dict) Session.add(morphology_backup)
def backup_collection(collection_dict): """Backup a collection. :param dict form_dict: a representation of a collection model. :returns: ``None`` """ collection_backup = CollectionBackup() collection_backup.vivify(collection_dict) Session.add(collection_backup)
def test_create(self): """Tests that POST /tags creates a new tag or returns an appropriate error if the input is invalid. """ original_tag_count = Session.query(Tag).count() # Create a valid one params = json.dumps({'name': u'tag', 'description': u'Described.'}) response = self.app.post(url('tags'), params, self.json_headers, self.extra_environ_admin) resp = json.loads(response.body) new_tag_count = Session.query(Tag).count() assert new_tag_count == original_tag_count + 1 assert resp['name'] == u'tag' assert resp['description'] == u'Described.' assert response.content_type == 'application/json' # Invalid because name is not unique params = json.dumps({'name': u'tag', 'description': u'Described.'}) response = self.app.post(url('tags'), params, self.json_headers, self.extra_environ_admin, status=400) resp = json.loads(response.body) assert resp['errors'][ 'name'] == u'The submitted value for Tag.name is not unique.' # Invalid because name is empty params = json.dumps({'name': u'', 'description': u'Described.'}) response = self.app.post(url('tags'), 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 response.content_type == 'application/json' # Invalid because name is too long params = json.dumps({ 'name': u'name' * 400, 'description': u'Described.' }) response = self.app.post(url('tags'), 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_test_models(n=100): _add_test_models_to_session('Tag', n, ['name']) _add_test_models_to_session('Speaker', n, ['first_name', 'last_name', 'dialect']) _add_test_models_to_session('Source', n, ['author_first_name', 'author_last_name', 'title']) _add_test_models_to_session('ElicitationMethod', n, ['name']) _add_test_models_to_session('SyntacticCategory', n, ['name']) _add_test_models_to_session('File', n, ['name']) restricted_tag = h.generate_restricted_tag() Session.add(restricted_tag) Session.commit()
def _create_test_models(n=100): _add_test_models_to_session('Tag', n, ['name']) _add_test_models_to_session('Speaker', n, ['first_name', 'last_name', 'dialect']) _add_test_models_to_session( 'Source', n, ['author_first_name', 'author_last_name', 'title']) _add_test_models_to_session('ElicitationMethod', n, ['name']) _add_test_models_to_session('SyntacticCategory', n, ['name']) _add_test_models_to_session('File', n, ['name']) restricted_tag = h.generate_restricted_tag() Session.add(restricted_tag) Session.commit()
def authenticate(self): """Session-based authentication. :URL: ``POST /login/authenticate`` :request body: A JSON object with ``"username"`` and ``"password"`` string values :returns: ``{"authenticated": True}`` on success, an error dictionary on failure. """ try: schema = LoginSchema() values = json.loads(unicode(request.body, request.charset)) result = schema.to_python(values) username = result['username'] user_from_username = Session.query(User).filter( User.username == username).first() if user_from_username: salt = user_from_username.salt password = unicode( h.encrypt_password(result['password'], str(salt))) user = Session.query(User).filter( User.username == username).filter( User.password == password).first() if user: session['user'] = user session.save() home_page = Session.query(Page).filter( Page.name == u'home').first() return { 'authenticated': True, 'user': user, 'homepage': home_page } else: response.status_int = 401 return { 'error': u'The username and password provided are not valid.' } else: response.status_int = 401 return { 'error': u'The username and password provided are not valid.' } except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def test_delete(self): """Tests that DELETE /formsearches/id deletes the form search with id=id.""" # Create a form search to delete. query = {'filter': ['Form', 'transcription', 'regex', u'[a-g]{3,}']} params = self.form_search_create_params.copy() params.update({ 'name': u'form search', 'description': u'This one\'s worth saving!', 'search': query }) params = json.dumps(params) response = self.app.post(url('formsearches'), params, self.json_headers, self.extra_environ_admin) resp = json.loads(response.body) form_search_count = Session.query(FormSearch).count() form_search_id = resp['id'] assert resp['name'] == u'form search' assert resp['description'] == u"This one's worth saving!" assert resp['search'] == query # Now delete the form_search response = self.app.delete(url('formsearch', id=form_search_id), headers=self.json_headers, extra_environ=self.extra_environ_admin) resp = json.loads(response.body) new_form_search_count = Session.query(FormSearch).count() assert new_form_search_count == form_search_count - 1 assert resp['id'] == form_search_id assert response.content_type == 'application/json' # Trying to get the deleted form_search from the db should return None deleted_form_search = Session.query(FormSearch).get(form_search_id) assert deleted_form_search == None # Delete with an invalid id id = 9999999999999 response = self.app.delete(url('formsearch', id=id), headers=self.json_headers, extra_environ=self.extra_environ_admin, status=404) assert u'There is no form search with id %s' % id in json.loads( response.body)['error'] assert response.content_type == 'application/json' # Delete without an id response = self.app.delete(url('formsearch', id=''), status=404, headers=self.json_headers, extra_environ=self.extra_environ_admin) assert json.loads( response.body)['error'] == 'The resource could not be found.'
def createCollection(i, forms=None, commit=False): c = model.Collection() c.title = u'title' if i % 3 == 0: c.forms = forms elif i % 2 == 0: c.forms = forms[::3] else: c.forms = forms[:10] Session.add(c) if commit: Session.commit() return c
def add_loremipsum_to_db(loremipsum_path, via_request=False): """Add the contents of the file at ``loremipsum_path`` to the database.""" categories = {} with open(loremipsum_path, 'r') as f: i = 0 for l in f: if i % 100 == 0: if not via_request: Session.commit() log.debug('%d lines processed' % i) i = i + 1 categories = create_model(l.replace('\n', ''), categories, via_request) Session.commit()
def update(self, id): """Update an orthography and return it. :URL: ``PUT /orthographies/id`` :Request body: JSON object representing the orthography with updated attribute values. :param str id: the ``id`` value of the orthography to be updated. :returns: the updated orthography model. .. note:: Contributors can only update orthographies that are not used in the active application settings. """ orthography = Session.query(Orthography).get(int(id)) user = session['user'] if orthography: app_set = h.get_application_settings() if user.role == u'administrator' or orthography not in ( app_set.storage_orthography, app_set.input_orthography, app_set.output_orthography): try: schema = OrthographySchema() values = json.loads(unicode(request.body, request.charset)) state = h.get_state_object(values) state.id = id result = schema.to_python(values, state) orthography = update_orthography(orthography, result) # orthography will be False if there are no changes (cf. update_orthography). if orthography: Session.add(orthography) Session.commit() return orthography else: response.status_int = 400 return { 'error': u'The update request failed because the submitted data were not new.' } except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()} else: response.status = 403 return { 'error': u'Only administrators are permitted to update orthographies that are used in the active application settings.' }
def test_delete(self): """Tests that DELETE /speakers/id deletes the speaker with id=id.""" # Create a speaker to delete. params = self.speaker_create_params.copy() params.update({ 'first_name': u'first_name', 'last_name': u'last_name', 'page_content': u'page_content', 'dialect': u'dialect' }) params = json.dumps(params) response = self.app.post(url('speakers'), params, self.json_headers, self.extra_environ_admin) resp = json.loads(response.body) speaker_count = Session.query(Speaker).count() speaker_id = resp['id'] # Now delete the speaker response = self.app.delete(url('speaker', id=speaker_id), headers=self.json_headers, extra_environ=self.extra_environ_admin) resp = json.loads(response.body) new_speaker_count = Session.query(Speaker).count() assert new_speaker_count == speaker_count - 1 assert resp['id'] == speaker_id assert response.content_type == 'application/json' # Trying to get the deleted speaker from the db should return None deleted_speaker = Session.query(Speaker).get(speaker_id) assert deleted_speaker == None assert response.content_type == 'application/json' # Delete with an invalid id id = 9999999999999 response = self.app.delete(url('speaker', id=id), headers=self.json_headers, extra_environ=self.extra_environ_admin, status=404) assert u'There is no speaker with id %s' % id in json.loads( response.body)['error'] assert response.content_type == 'application/json' # Delete without an id response = self.app.delete(url('speaker', id=''), status=404, headers=self.json_headers, extra_environ=self.extra_environ_admin) assert json.loads( response.body)['error'] == 'The resource could not be found.' assert response.content_type == 'application/json'
def test_update(self): """Tests that PUT /elicitationmethods/id updates the elicitationmethod with id=id.""" # Create an elicitation method to update. params = json.dumps({'name': u'name', 'description': u'description'}) response = self.app.post(url('elicitationmethods'), params, self.json_headers, self.extra_environ_admin) resp = json.loads(response.body) elicitation_method_count = Session.query(ElicitationMethod).count() elicitation_method_id = resp['id'] original_datetime_modified = resp['datetime_modified'] # Update the elicitation method sleep( 1 ) # sleep for a second to ensure that MySQL registers a different datetime_modified for the update params = json.dumps({ 'name': u'name', 'description': u'More content-ful description.' }) response = self.app.put( url('elicitationmethod', id=elicitation_method_id), params, self.json_headers, self.extra_environ_admin) resp = json.loads(response.body) datetime_modified = resp['datetime_modified'] new_elicitation_method_count = Session.query(ElicitationMethod).count() assert elicitation_method_count == new_elicitation_method_count assert datetime_modified != original_datetime_modified assert response.content_type == 'application/json' # Attempt an update with no new input and expect to fail sleep( 1 ) # sleep for a second to ensure that MySQL could register a different datetime_modified for the update response = self.app.put(url('elicitationmethod', id=elicitation_method_id), params, self.json_headers, self.extra_environ_admin, status=400) resp = json.loads(response.body) elicitation_method_count = new_elicitation_method_count new_elicitation_method_count = Session.query(ElicitationMethod).count() our_EM_datetime_modified = Session.query(ElicitationMethod).get( elicitation_method_id).datetime_modified assert our_EM_datetime_modified.isoformat() == datetime_modified assert elicitation_method_count == new_elicitation_method_count assert resp[ 'error'] == u'The update request failed because the submitted data were not new.' assert response.content_type == 'application/json'
def test_delete(self): """Tests that DELETE /pages/id deletes the page with id=id.""" # Create a page to delete. 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) page_count = Session.query(Page).count() page_id = resp['id'] # Now delete the page response = self.app.delete(url('page', id=page_id), headers=self.json_headers, extra_environ=self.extra_environ_admin) resp = json.loads(response.body) new_page_count = Session.query(Page).count() assert new_page_count == page_count - 1 assert resp['id'] == page_id assert response.content_type == 'application/json' # Trying to get the deleted page from the db should return None deleted_page = Session.query(Page).get(page_id) assert deleted_page == None assert response.content_type == 'application/json' # Delete with an invalid id id = 9999999999999 response = self.app.delete(url('page', id=id), headers=self.json_headers, extra_environ=self.extra_environ_admin, status=404) assert u'There is no page with id %s' % id in json.loads( response.body)['error'] assert response.content_type == 'application/json' # Delete without an id response = self.app.delete(url('page', id=''), status=404, headers=self.json_headers, extra_environ=self.extra_environ_admin) assert json.loads( response.body)['error'] == 'The resource could not be found.'