def piece_create(request, *args, **kwargs): form = validate_dynamic_piece_form(request, PieceForm(request.POST)) if not form.is_valid(): # Form errors are rendered for user on the front end. errors = {f: [e.get_json_data()[0]['message']] for f, e in form.errors.items()} errors = json.dumps({'errors': errors}) return HttpResponse(content=errors, content_type="application/json", status=status.HTTP_400_BAD_REQUEST) clean = Cleanup() clean_form = form.cleaned_data new_piece = Piece(title=clean_form['title'], creator=request.user, created=datetime.datetime.now(pytz.utc), updated=datetime.datetime.now(pytz.utc)) clean.list.append({"object": new_piece, "isNew": True}) try: new_piece.save(ignore_solr=True) except: clean.cleanup() raise object_list = [] for key in clean_form: object_list.append({'id': key, 'value': clean_form[key]}) handle_related_models(object_list, new_piece, clean, user=request.user, birth_date=clean_form['composer_birth_date'], death_date=clean_form['composer_death_date']) new_piece.save() handle_dynamic_file_table(request, new_piece, clean) rebuild_suggester_dicts.delay() data = json.dumps({'success': True, 'id': new_piece.id, 'url': "/piece/{0}".format(new_piece.id)}) return HttpResponse(data, content_type="application/json", status=status.HTTP_201_CREATED)
def create_piece(request): if request.method == 'POST': form = PieceForm(request.POST, request.FILES) if form.is_valid(): clean_form = form.cleaned_data # Hardcoded user for now uploader = User.objects.get(pk=40) # Handle tags tags = tag_handler(clean_form['tags']) # Handle composer and corpus composer = composer_handler(clean_form.get('composer')) corpus = object_handler(Corpus, clean_form.get('corpus')) date = date_handler(clean_form.get('date_of_composition')) # Create piece piece = Piece(title=clean_form['title'], composer=composer, corpus=corpus, date_of_composition=date, number_of_voices=clean_form.get('number_of_voices'), comment=clean_form.get('comment'), uploader=uploader ) piece.save() attachments = [] # Create movements associated with piece (if any) # Also return attachment associated with piece if possible attachments.extend(movement_files_handler(request.POST, request.FILES, piece)) # Add tags to piece for tag in tags: piece.tags.add(tag) piece.save() # Add attachments to piece for attachment in attachments: piece.attachments.add(attachment) piece.save() else: form = PieceForm(initial={'title':'Piece title', 'composer': 'Composer', 'corpus': 'Corpus', 'date_of_composition':'date of composition', 'comment': 'Add a comment...', 'tags': 'Comma-separated list of tags', 'description':'Description of piece file...'}) return render(request, 'forms/piece.html', {'form':form})
def setUp(self): self.setUp_user() self.c = Collection() self.c.title = "This is the collection title" self.c.save() self.p = Piece() self.p.creator = self.creator_user self.p.save() self.composer = Composer() self.composer.name = "Fake Composer" self.composer.save() self.m = Movement() self.m.creator = self.creator_user self.m.composer = self.composer self.m.save()
def setUp(self): self.setUp_user() self.p = Piece() self.p.creator = self.creator_user self.p.save() self.composer = Composer() self.composer.name = "Fake Composer" self.composer.save() self.m = Movement() self.m.creator = self.creator_user self.m.composer = self.composer self.m.title = "This is the movement title" self.m.save() self.source1 = Source() self.source1.title = "Source 1" self.source1.save() self.source2 = Source() self.source2.title = "Source 2" self.source2.save() self.genre1 = Genre() self.genre1.title = "Genre 1" self.genre1.save() self.genre2 = Genre() self.genre2.title = "Genre 2" self.genre2.save() self.attachment1 = Attachment() self.attachment1.description = "Attachment 1" self.attachment1.save() self.attachment2 = Attachment() self.attachment2.description = "Attachment 2" self.attachment2.save()
class CollectionTestCase(ElvisTestSetup, APITestCase): def setUp(self): self.setUp_user() self.c = Collection() self.c.title = "This is the collection title" self.c.save() self.p = Piece() self.p.creator = self.creator_user self.p.save() self.composer = Composer() self.composer.name = "Fake Composer" self.composer.save() self.m = Movement() self.m.creator = self.creator_user self.m.composer = self.composer self.m.save() def tearDown(self): self.c.delete() self.p.delete() self.m.delete() self.composer.delete() def test_unicode(self): self.assertEqual(str(self.c), "This is the collection title") def test_add_piece(self): self.assertTrue(self.p not in self.c) self.assertEqual(self.c.piece_count, 0) self.c.add(self.p) self.assertEqual(self.c.piece_count, 1) self.assertEqual(self.p, self.c.pieces.first()) self.assertTrue(self.p in self.c) def test_add_movement(self): self.assertTrue(self.m not in self.c) self.assertEqual(self.c.movement_count, 0) self.c.add(self.m) self.assertEqual(self.c.movement_count, 1) self.assertEqual(self.m, self.c.movements.first()) self.assertTrue(self.m in self.c) def test_remove_piece(self): self.assertTrue(self.p not in self.c) self.c.add(self.p) self.assertTrue(self.p in self.c) self.c.remove(self.p) self.assertTrue(self.p not in self.c) def test_remove_movement(self): self.assertTrue(self.m not in self.c) self.c.add(self.m) self.assertTrue(self.m in self.c) self.c.remove(self.m) self.assertTrue(self.m not in self.c) def test_get_free_movements(self): # First test with a free movement self.assertListEqual(list(self.c.free_movements), []) self.assertEqual(self.c.free_movements_count, 0) self.c.add(self.m) self.assertListEqual(list(self.c.free_movements), [self.m]) self.assertEqual(self.c.free_movements_count, 1) # Then, make self.m unfree and see that it responds self.m.piece = self.p self.p.movements.add(self.m) self.assertListEqual(list(self.c.free_movements), []) self.assertEqual(self.c.free_movements_count, 0) def test_container_contains_none(self): """ Test that checking "None in collection" does not crash the program. Instead, it returns false. :return: """ self.assertFalse(None in self.c) def test_invalid_contains_parameter(self): """ Test that calling the __contains__ interface on Collection with an unacceptable parameter throws an exception. :return: """ with self.assertRaises(Exception): 5 in self.c with self.assertRaises(Exception): "bad" in self.c def test_maintain_valid_collection(self): """ Test that a collection does not enter an invalid state when adding a movement or piece such that the movement is in the piece. An invalid state is when a collection contains both the movement and the piece even though the movement is contained within the piece. :return: """ # M is a movement in P self.m.piece = self.p self.p.movements.add(self.m) # Neither M or P is in C self.assertTrue(self.m not in self.c) self.assertTrue(self.p not in self.c) # Only M is in C self.c.add(self.m) self.assertTrue(self.m in self.c) self.assertTrue(self.p not in self.c) # Add P to C, thereby removing just M self.c.add(self.p) self.assertTrue(self.m not in self.c) self.assertTrue(self.p in self.c) # Try to add just M. M remains not in C and P remains in C self.c.add(self.m) self.assertTrue(self.m not in self.c) self.assertTrue(self.p in self.c)
class MovementTestCase(ElvisTestSetup, APITestCase): def setUp(self): self.setUp_user() self.p = Piece() self.p.creator = self.creator_user self.p.save() self.composer = Composer() self.composer.name = "Fake Composer" self.composer.save() self.m = Movement() self.m.creator = self.creator_user self.m.composer = self.composer self.m.title = "This is the movement title" self.m.save() self.source1 = Source() self.source1.title = "Source 1" self.source1.save() self.source2 = Source() self.source2.title = "Source 2" self.source2.save() self.genre1 = Genre() self.genre1.title = "Genre 1" self.genre1.save() self.genre2 = Genre() self.genre2.title = "Genre 2" self.genre2.save() self.attachment1 = Attachment() self.attachment1.description = "Attachment 1" self.attachment1.save() self.attachment2 = Attachment() self.attachment2.description = "Attachment 2" self.attachment2.save() def tearDown(self): self.p.delete() self.m.delete() self.composer.delete() self.source1.delete() self.source2.delete() self.genre1.delete() self.genre2.delete() self.attachment1.delete() def test_unicode(self): self.assertEqual(str(self.m), "This is the movement title") def test_get_parent_cart_id(self): # No piece self.assertEqual(self.m.get_parent_cart_id, "") # Add the piece self.m.piece = self.p # Assert that it matches the regex self.assertRegexpMatches(self.m.get_parent_cart_id, self.uuid_regexp) # Remove it self.m.piece = None self.assertEqual(self.m.get_parent_cart_id, "")
def get_pieces_movements(self, rettype): users = self.__get_ddmal_users() query = PIECE_MOVEMENT_QUERY.format(rettype) self.__connect() self.curs.execute(query) objects = self.curs.fetchall() print "Deleting {0}".format(rettype) if rettype == "piece": Piece.objects.all().delete() elif rettype == "movement": Movement.objects.all().delete() print "Adding {0}".format(rettype) for item in objects: # LM: composer may be none try: composer_obj = Composer.objects.get(old_id=item['composer_id']) except Composer.DoesNotExist: composer_obj = None for user in users: if item.get('uploader') == user.get('uid'): user_obj = User.objects.get(username=user.get('name')) break if rettype == "piece": collection_objs = Collection.objects.filter(old_id=item['book_id']) if not collection_objs.exists(): collection_objs = None else: collection_objs = collection_objs elif rettype == "movement": parent_obj = self.__resolve_movement_parent(item['old_id']) collection_objs = Collection.objects.filter(old_id=item['book_id']) if not collection_objs.exists(): collection_objs = None else: collection_objs = collection_objs p = { 'uploader': user_obj, 'composer': composer_obj, 'old_id': item.get('old_id', None), 'title': my_decoder(item.get('title', None)), 'date_of_composition': pytz.utc.localize(item.get('date_of_composition', None)), 'date_of_composition2': pytz.utc.localize(item.get('date_of_composition2', None)), 'number_of_voices': item.get('number_of_voices', None), 'comment': my_decoder(item.get('comment', None)), 'created': datetime.datetime.fromtimestamp(item.get('created')), 'updated': datetime.datetime.fromtimestamp(item.get('updated')) } #if not item.get('composition_start_date', None) == item.get('composition_end_date', None): if rettype == "piece": x = Piece(**p) elif rettype == "movement": p.update({'piece': parent_obj}) x = Movement(**p) x.save() if not (collection_objs is None or collection_objs is []): for collection_obj in collection_objs: x.collections.add(collection_obj) x.save() self.__disconnect() print "Tagging {0}".format(rettype) # filters out composers (tid 3) ITEM_TAG_QUERY = """SELECT ti.nid, ti.tid FROM taxonomy_index ti LEFT JOIN taxonomy_term_data td ON td.tid = ti.tid WHERE ti.nid = %s""" if rettype == "piece": objects = Piece.objects.all() elif rettype == "movement": objects = Movement.objects.all() for item in objects: self.__connect() self.curs.execute(ITEM_TAG_QUERY, [item.old_id]) tags = self.curs.fetchall() for tag in tags: tag_obj = Tag.objects.filter(old_id=tag.get('tid')) if not tag_obj.exists(): continue item.tags.add(tag_obj[0]) item.save() self.__disconnect() ITEM_ATTACHMENT_QUERY = """SELECT ff.field_files_description AS description, fm.timestamp AS created, fm.uid AS uploader, fm.filename AS filename, fm.uri AS uri FROM field_data_field_files ff LEFT JOIN file_managed fm ON ff.field_files_fid = fm.fid WHERE ff.entity_id = %s""" print "Attaching files to {0}".format(rettype) if rettype == "piece": objects = Piece.objects.all() # LM: Deletion of previous attachments should happen here, otherwise attaching movements will delete attachments to pieces print "Deleting attachments" #Attachment.objects.all().delete() attachment_set = Attachment.objects.all() for item in attachment_set: item.delete() elif rettype == "movement": objects = Movement.objects.all() print("Attaching for real - LM") self.__connect() failures = 0 for item in objects: self.curs.execute(ITEM_ATTACHMENT_QUERY, [item.old_id]) attachments = self.curs.fetchall() for attachment in attachments: for user in users: if attachment.get('uploader') == user.get('uid'): user_obj = User.objects.get(username=user.get('name')) break a = Attachment() a.save() # ensure we've got a PK before we try and attach a file. # LM filename from old attachment objects filename = attachment.get('filename') #filename = "test_file.mei" # for testing. # LM Catch IO Error when trying to find file try: filepath = os.path.join(DRUPAL_FILE_PATH, filename) f = open(filepath, 'rb') except IOError: # print('Failed to open: ' + filename) # Some files have _0 appended to name before extension.... try that try: filename_temp, extension_temp = os.path.splitext(filename) filename = filename_temp + '_0' + extension_temp filepath = os.path.join(DRUPAL_FILE_PATH, filename) f = open(filepath) # If that doesn't work then pass except IOError: print('Failure: ' + filename) failures = failures + 1 continue attached_file = os.path.join(a.attachment_path, filename) # LM Try to localise timezone #try: date_created = pytz.utc.localize(datetime.datetime.fromtimestamp(attachment.get('created'))) #except AttributeError: # date_created = datetime.datetime.fromtimestamp(attachment.get('created')) s = { 'uploader': user_obj, 'description': attachment.get('description', None), 'created': date_created, 'old_id': attachment.get('old_id', None) } a.__dict__.update(**s) a.save() a.attachment.save(filename, File(f)) a.save() f.close() #print('Attaching ' + a.attachment.attachment_path + ' to ' + item.title) item.attachments.add(a) self.__disconnect() print('failed attachments', failures)
def get_pieces_movements(self, rettype): users = self.__get_ddmal_users() query = PIECE_MOVEMENT_QUERY.format(rettype) self.__connect() self.curs.execute(query) objects = self.curs.fetchall() print "Deleting {0}".format(rettype) if rettype == "piece": Piece.objects.all().delete() elif rettype == "movement": Movement.objects.all().delete() print "Adding {0}".format(rettype) for item in objects: composer_obj = Composer.objects.get(old_id=item['composer_id']) for user in users: if item.get('uploader') == user.get('uid'): user_obj = User.objects.get(username=user.get('name')) break if rettype == "piece": parent_obj = Corpus.objects.filter(old_id=item['book_id']) if not parent_obj.exists(): parent_obj = None else: parent_obj = parent_obj[0] elif rettype == "movement": parent_obj = self.__resolve_movement_parent(item['old_id']) corpus_obj = Corpus.objects.filter(old_id=item['book_id']) if not corpus_obj.exists(): corpus_obj = None else: corpus_obj = corpus_obj[0] p = { 'uploader': user_obj, 'composer': composer_obj, 'old_id': item.get('old_id', None), 'title': item.get('title', None), 'date_of_composition': item.get('date_of_composition', None), 'number_of_voices': item.get('number_of_voices', None), 'comment': item.get('comment', None), 'created': datetime.datetime.fromtimestamp(item.get('created')), 'updated': datetime.datetime.fromtimestamp(item.get('updated')) } if rettype == "piece": p.update({'corpus': parent_obj}) x = Piece(**p) elif rettype == "movement": p.update({'piece': parent_obj, 'corpus': corpus_obj}) x = Movement(**p) x.save() self.__disconnect() print "Tagging {0}".format(rettype) # filters out composers (tid 3) ITEM_TAG_QUERY = """SELECT ti.nid, ti.tid FROM taxonomy_index ti LEFT JOIN taxonomy_term_data td ON td.tid = ti.tid WHERE ti.nid = %s""" if rettype == "piece": objects = Piece.objects.all() elif rettype == "movement": objects = Movement.objects.all() for item in objects: self.__connect() self.curs.execute(ITEM_TAG_QUERY, item.old_id) tags = self.curs.fetchall() for tag in tags: tag_obj = Tag.objects.filter(old_id=tag.get('tid')) if not tag_obj.exists(): continue item.tags.add(tag_obj[0]) item.save() self.__disconnect() ITEM_ATTACHMENT_QUERY = """SELECT ff.field_files_description AS description, fm.timestamp AS created, fm.uid AS uploader, fm.filename AS filename, fm.uri AS uri FROM field_data_field_files ff LEFT JOIN file_managed fm ON ff.field_files_fid = fm.fid WHERE ff.entity_id = %s""" print "Attaching files to {0}".format(rettype) if rettype == "piece": objects = Piece.objects.all() elif rettype == "movement": objects = Movement.objects.all() print "Deleting attachments" Attachment.objects.all().delete() self.__connect() for item in objects: self.curs.execute(ITEM_ATTACHMENT_QUERY, item.old_id) attachments = self.curs.fetchall() for attachment in attachments: for user in users: if attachment.get('uploader') == user.get('uid'): user_obj = User.objects.get(username=user.get('name')) break a = Attachment() a.save( ) # ensure we've got a PK before we try and attach a file. # filename = attachment.get('filename')[9:] # lop the 'public://' off. filename = "test_file.mei" # for testing. filepath = os.path.join(DRUPAL_FILE_PATH, filename) f = open(filepath, 'rb') # attached_file = os.path.join(a.attachment_path, filename) s = { 'uploader': user_obj, 'description': attachment.get('description', None), 'created': datetime.datetime.fromtimestamp(attachment.get('created')), 'old_id': attachment.get('old_id', None) } a.__dict__.update(**s) a.save() a.attachment.save(filename, File(f)) a.save() f.close() item.attachments.add(a) self.__disconnect()
def get_pieces_movements(self, rettype): users = self.__get_ddmal_users() query = PIECE_MOVEMENT_QUERY.format(rettype) self.__connect() self.curs.execute(query) objects = self.curs.fetchall() print "Deleting {0}".format(rettype) if rettype == "piece": Piece.objects.all().delete() elif rettype == "movement": Movement.objects.all().delete() print "Adding {0}".format(rettype) for item in objects: composer_obj = Composer.objects.get(old_id=item['composer_id']) for user in users: if item.get('uploader') == user.get('uid'): user_obj = User.objects.get(username=user.get('name')) break if rettype == "piece": parent_obj = Corpus.objects.filter(old_id=item['book_id']) if not parent_obj.exists(): parent_obj = None else: parent_obj = parent_obj[0] elif rettype == "movement": parent_obj = self.__resolve_movement_parent(item['old_id']) corpus_obj = Corpus.objects.filter(old_id=item['book_id']) if not corpus_obj.exists(): corpus_obj = None else: corpus_obj = corpus_obj[0] p = { 'uploader': user_obj, 'composer': composer_obj, 'old_id': item.get('old_id', None), 'title': item.get('title', None), 'date_of_composition': item.get('date_of_composition', None), 'number_of_voices': item.get('number_of_voices', None), 'comment': item.get('comment', None), 'created': datetime.datetime.fromtimestamp(item.get('created')), 'updated': datetime.datetime.fromtimestamp(item.get('updated')) } if rettype == "piece": p.update({'corpus': parent_obj}) x = Piece(**p) elif rettype == "movement": p.update({'piece': parent_obj, 'corpus': corpus_obj}) x = Movement(**p) x.save() self.__disconnect() print "Tagging {0}".format(rettype) # filters out composers (tid 3) ITEM_TAG_QUERY = """SELECT ti.nid, ti.tid FROM taxonomy_index ti LEFT JOIN taxonomy_term_data td ON td.tid = ti.tid WHERE ti.nid = %s""" if rettype == "piece": objects = Piece.objects.all() elif rettype == "movement": objects = Movement.objects.all() for item in objects: self.__connect() self.curs.execute(ITEM_TAG_QUERY, item.old_id) tags = self.curs.fetchall() for tag in tags: tag_obj = Tag.objects.filter(old_id=tag.get('tid')) if not tag_obj.exists(): continue item.tags.add(tag_obj[0]) item.save() self.__disconnect() ITEM_ATTACHMENT_QUERY = """SELECT ff.field_files_description AS description, fm.timestamp AS created, fm.uid AS uploader, fm.filename AS filename, fm.uri AS uri FROM field_data_field_files ff LEFT JOIN file_managed fm ON ff.field_files_fid = fm.fid WHERE ff.entity_id = %s""" print "Attaching files to {0}".format(rettype) if rettype == "piece": objects = Piece.objects.all() elif rettype == "movement": objects = Movement.objects.all() print "Deleting attachments" Attachment.objects.all().delete() self.__connect() for item in objects: self.curs.execute(ITEM_ATTACHMENT_QUERY, item.old_id) attachments = self.curs.fetchall() for attachment in attachments: for user in users: if attachment.get('uploader') == user.get('uid'): user_obj = User.objects.get(username=user.get('name')) break a = Attachment() a.save() # ensure we've got a PK before we try and attach a file. # filename = attachment.get('filename')[9:] # lop the 'public://' off. filename = "test_file.mei" # for testing. filepath = os.path.join(DRUPAL_FILE_PATH, filename) f = open(filepath, 'rb') # attached_file = os.path.join(a.attachment_path, filename) s = { 'uploader': user_obj, 'description': attachment.get('description', None), 'created': datetime.datetime.fromtimestamp(attachment.get('created')), 'old_id': attachment.get('old_id', None) } a.__dict__.update(**s) a.save() a.attachment.save(filename, File(f)) a.save() f.close() item.attachments.add(a) self.__disconnect()