Beispiel #1
0
 def bootstrap_pass_one(cls, model_class, xml_tag, id_attr="id", name_attr="name", skip_without=None):
     # Pass one.
     template = u"{} (Pass 1) (idx:{}) (id:{}) [{:.8f}]: {}"
     xml_path = Bootstrapper.get_xml_path(xml_tag)
     print(xml_path)
     with gzip.GzipFile(xml_path, "r") as file_pointer:
         iterator = Bootstrapper.iterparse(file_pointer, xml_tag)
         for i, element in enumerate(iterator):
             data = None
             try:
                 with systemtools.Timer(verbose=False) as timer:
                     data = model_class.tags_to_fields(element)
                     if skip_without:
                         if any(not data.get(_) for _ in skip_without):
                             continue
                     if element.get("id"):
                         data["id"] = element.get("id")
                     data["random"] = random.random()
                     document = model_class.create(**data)
                 message = template.format(
                     model_class.__name__.upper(),
                     i,
                     getattr(document, id_attr),
                     timer.elapsed_time,
                     getattr(document, name_attr),
                 )
                 print(message)
             except peewee.DataError as e:
                 pprint.pprint(data)
                 traceback.print_exc()
                 raise (e)
    def test_01(self):
        iterator = Bootstrapper.get_iterator('label')
        label_element = next(iterator)
        label_element = next(iterator)
        label_element = next(iterator)
        actual = stringtools.normalize(Bootstrapper.prettify(label_element))
        expected = stringtools.normalize(u'''
            <?xml version="1.0" ?>
            <label>
                <id>3</id>
                <name>Seasons Recordings</name>
                <contactinfo>Seasons Recordings
            2236 Pacific Avenue
            Suite D
            Costa Mesa, CA 92627

            Jamie Thinnes

            Tel: 949-574-5255
            Fax: 949-574-0255

            [email protected]
            [email protected]
            </contactinfo>
                <profile>California Deep-House Label Founded By Jamie Thinnes.
            The First 10 Records Were Released on [l=Earthtones Recordings]
            </profile>
                <data_quality>Correct</data_quality>
                <sublabels>
                    <label>Seasons Classics</label>
                    <label>Seasons Limited</label>
                </sublabels>
            </label>
            ''')
        assert actual.splitlines() == expected.splitlines()
        label_document = library.Label.from_element(label_element)
        actual = format(label_document)
        expected = stringtools.normalize(u'''
            discograph.library.mongo.Label(
                discogs_id=3,
                name='Seasons Recordings',
                sublabels=[
                    discograph.library.mongo.LabelReference(
                        name='Seasons Classics',
                        ),
                    discograph.library.mongo.LabelReference(
                        name='Seasons Limited',
                        ),
                    ],
                )
            ''')
        assert actual == expected
Beispiel #3
0
 def bootstrap_pass_one(cls):
     # Pass one.
     labels_xml_path = Bootstrapper.labels_xml_path
     with gzip.GzipFile(labels_xml_path, 'r') as file_pointer:
         iterator = Bootstrapper.iterparse(file_pointer, 'label')
         iterator = Bootstrapper.clean_elements(iterator)
         for i, element in enumerate(iterator):
             try:
                 with systemtools.Timer(verbose=False) as timer:
                     document = cls.from_element(element)
                     cls.objects.insert(document, load_bulk=False)
                     #document.save()
                     #document.save(force_insert=True)
                 message = u'{} (Pass 1) {} [{}]: {}'.format(
                     cls.__name__.upper(),
                     document.discogs_id,
                     timer.elapsed_time,
                     document.name,
                     )
                 print(message)
             except mongoengine.errors.ValidationError:
                 traceback.print_exc()
Beispiel #4
0
 def bootstrap_pass_one(
     cls,
     model_class,
     xml_tag,
     id_attr='id',
     name_attr='name',
     skip_without=None,
     ):
     # Pass one.
     template = u'{} (Pass 1) (idx:{}) (id:{}) [{:.8f}]: {}'
     xml_path = Bootstrapper.get_xml_path(xml_tag)
     print(xml_path)
     with gzip.GzipFile(xml_path, 'r') as file_pointer:
         iterator = Bootstrapper.iterparse(file_pointer, xml_tag)
         for i, element in enumerate(iterator):
             data = None
             try:
                 with systemtools.Timer(verbose=False) as timer:
                     data = model_class.tags_to_fields(element)
                     if skip_without:
                         if any(not data.get(_) for _ in skip_without):
                             continue
                     if element.get('id'):
                         data['id'] = element.get('id')
                     data['random'] = random.random()
                     document = model_class.create(**data)
                 message = template.format(
                     model_class.__name__.upper(),
                     i,
                     getattr(document, id_attr),
                     timer.elapsed_time,
                     getattr(document, name_attr),
                     )
                 print(message)
             except peewee.DataError as e:
                 pprint.pprint(data)
                 traceback.print_exc()
                 raise(e)
Beispiel #5
0
 def element_to_formats(cls, element):
     result = []
     if element is None or not len(element):
         return result
     for subelement in element:
         document = {
             'name': subelement.get('name'),
             'quantity': subelement.get('qty'),
             }
         if subelement.get('text'):
             document['text'] = subelement.get('text')
         if len(subelement):
             subelement = subelement[0]
             descriptions = Bootstrapper.element_to_strings(subelement)
             document['descriptions'] = descriptions
         result.append(document)
     return result
 def test_01(self):
     iterator = Bootstrapper.get_iterator('release')
     release_element = next(iterator)
     release_document = library.Release.from_element(release_element)
     release_document.resolve_references(spuriously=True)
     relations = library.Relation.from_release(release_document)
     actual = '\n'.join(format(_) for _ in relations)
     expected = stringtools.normalize(r'''
         discograph.library.mongo.Relation(
             category=discograph.library.mongo.CreditRole.Category.RELATION,
             country='Sweden',
             entity_one_id=1,
             entity_one_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             entity_two_id=-3,
             entity_two_type=discograph.library.mongo.Relation.EntityType.LABEL,
             genres=['Electronic'],
             release_id=1,
             role_name='Released On',
             styles=['Deep House'],
             year=1999,
             )
         discograph.library.mongo.Relation(
             category=discograph.library.mongo.CreditRole.Category.WRITING_AND_ARRANGEMENT,
             country='Sweden',
             entity_one_id=239,
             entity_one_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             entity_two_id=1,
             entity_two_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             genres=['Electronic'],
             release_id=1,
             role_name='Music By',
             styles=['Deep House'],
             year=1999,
             )
         ''')
     assert actual == expected
 def test_01(self):
     iterator = Bootstrapper.get_iterator('artist')
     artist_element = next(iterator)
     artist_element = next(iterator)
     artist_document = library.Artist.from_element(artist_element)
     for discogs_id, member in enumerate(artist_document.members, 200000000):
         name = member.name
         library.Artist(discogs_id=discogs_id, name=name).save()
     for discogs_id, alias in enumerate(artist_document.aliases, 100000000):
         name = alias.name
         library.Artist(discogs_id=discogs_id, name=name).save()
     artist_document.resolve_references()
     artist_document.save()
     artist_document.reload()
     relations = library.Relation.from_artist(artist_document)
     actual = '\n'.join(format(_) for _ in relations)
     expected = stringtools.normalize(r'''
         discograph.library.mongo.Relation(
             category=discograph.library.mongo.CreditRole.Category.RELATION,
             entity_one_id=2,
             entity_one_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             entity_two_id=100000000,
             entity_two_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             role_name='Alias',
             )
         discograph.library.mongo.Relation(
             category=discograph.library.mongo.CreditRole.Category.RELATION,
             entity_one_id=2,
             entity_one_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             entity_two_id=100000001,
             entity_two_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             role_name='Alias',
             )
         discograph.library.mongo.Relation(
             category=discograph.library.mongo.CreditRole.Category.RELATION,
             entity_one_id=2,
             entity_one_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             entity_two_id=100000002,
             entity_two_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             role_name='Alias',
             )
         discograph.library.mongo.Relation(
             category=discograph.library.mongo.CreditRole.Category.RELATION,
             entity_one_id=2,
             entity_one_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             entity_two_id=100000003,
             entity_two_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             role_name='Alias',
             )
         discograph.library.mongo.Relation(
             category=discograph.library.mongo.CreditRole.Category.RELATION,
             entity_one_id=2,
             entity_one_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             entity_two_id=100000004,
             entity_two_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             role_name='Alias',
             )
         discograph.library.mongo.Relation(
             category=discograph.library.mongo.CreditRole.Category.RELATION,
             entity_one_id=200000000,
             entity_one_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             entity_two_id=2,
             entity_two_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             role_name='Member Of',
             )
         discograph.library.mongo.Relation(
             category=discograph.library.mongo.CreditRole.Category.RELATION,
             entity_one_id=200000001,
             entity_one_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             entity_two_id=2,
             entity_two_type=discograph.library.mongo.Relation.EntityType.ARTIST,
             role_name='Member Of',
             )
         ''')
     assert actual == expected
Beispiel #8
0
 def test_01(self):
     iterator = Bootstrapper.get_iterator('release')
     release_element = next(iterator)
     release = discograph.PostgresRelease.from_element(release_element)
     actual = format(release)
     expected = stringtools.normalize(u"""
         discograph.library.PostgresRelease(
             artists=[
                 {
                     'id': 1,
                     'join': ',',
                     'name': 'The Persuader',
                     },
                 ],
             companies=[
                 {
                     'entity_type': 23,
                     'entity_type_name': 'Recorded At',
                     'id': 271046,
                     'name': 'The Globe Studios',
                     },
                 {
                     'entity_type': 17,
                     'entity_type_name': 'Pressed By',
                     'id': 56025,
                     'name': 'MPO',
                     },
                 ],
             country='Sweden',
             extra_artists=[
                 {
                     'id': 239,
                     'name': 'Jesper Dahlbäck',
                     'roles': [
                         {
                             'detail': 'All Tracks By',
                             'name': 'Music By',
                             },
                         ],
                     },
                 ],
             formats=[
                 {
                     'descriptions': ['12"', '33 ⅓ RPM'],
                     'name': 'Vinyl',
                     'quantity': '2',
                     },
                 ],
             genres=['Electronic'],
             id=1,
             identifiers=[
                 {
                     'description': 'A-Side',
                     'type': 'Matrix / Runout',
                     'value': 'MPO SK 032 A1 G PHRUPMASTERGENERAL T27 LONDON',
                     },
                 {
                     'description': 'B-Side',
                     'type': 'Matrix / Runout',
                     'value': 'MPO SK 032 B1',
                     },
                 {
                     'description': 'C-Side',
                     'type': 'Matrix / Runout',
                     'value': 'MPO SK 032 C1',
                     },
                 {
                     'description': 'D-Side',
                     'type': 'Matrix / Runout',
                     'value': 'MPO SK 032 D1',
                     },
                 ],
             labels=[
                 {
                     'catalog_number': 'SK032',
                     'name': 'Svek',
                     },
                 ],
             release_date=datetime.datetime(1999, 3, 1, 0, 0),
             styles=['Deep House'],
             title='Stockholm',
             tracklist=[
                 {
                     'duration': '4:45',
                     'position': 'A',
                     'title': 'Östermalm',
                     },
                 {
                     'duration': '6:11',
                     'position': 'B1',
                     'title': 'Vasastaden',
                     },
                 {
                     'duration': '2:49',
                     'position': 'B2',
                     'title': 'Kungsholmen',
                     },
                 {
                     'duration': '5:38',
                     'position': 'C1',
                     'title': 'Södermalm',
                     },
                 {
                     'duration': '4:52',
                     'position': 'C2',
                     'title': 'Norrmalm',
                     },
                 {
                     'duration': '5:16',
                     'position': 'D',
                     'title': 'Gamla Stan',
                     },
                 ],
             )
         """)
     assert actual == expected
Beispiel #9
0
 def test_02(self):
     iterator = Bootstrapper.get_iterator('release')
     release_element = next(iterator)
     release_element = next(iterator)
     release_element = next(iterator)
     release = discograph.PostgresRelease.from_element(release_element)
     actual = format(release)
     expected = stringtools.normalize(r'''
         discograph.library.PostgresRelease(
             artists=[
                 {
                     'id': 3,
                     'name': 'Josh Wink',
                     },
                 ],
             companies=[
                 {
                     'entity_type': 10,
                     'entity_type_name': 'Manufactured By',
                     'id': 93330,
                     'name': 'Columbia Records',
                     },
                 {
                     'entity_type': 9,
                     'entity_type_name': 'Distributed By',
                     'id': 93330,
                     'name': 'Columbia Records',
                     },
                 ],
             country='US',
             extra_artists=[
                 {
                     'id': 3,
                     'name': 'Josh Wink',
                     'roles': [
                         {
                             'name': 'DJ Mix',
                             },
                         ],
                     },
                 ],
             formats=[
                 {
                     'descriptions': ['Compilation', 'Mixed'],
                     'name': 'CD',
                     'quantity': '1',
                     },
                 ],
             genres=['Electronic'],
             id=3,
             identifiers=[
                 {
                     'description': None,
                     'type': 'Barcode',
                     'value': '074646362822',
                     },
                 ],
             labels=[
                 {
                     'catalog_number': 'CK 63628',
                     'name': 'Ruffhouse Records',
                     },
                 ],
             master_id=66526,
             release_date=datetime.datetime(1999, 7, 13, 0, 0),
             styles=['Techno', 'Tech House'],
             title='Profound Sounds Vol. 1',
             tracklist=[
                 {
                     'artists': [
                         {
                             'id': 5,
                             'join': '&',
                             'name': 'Heiko Laux',
                             },
                         {
                             'id': 4,
                             'join': ',',
                             'name': 'Johannes Heil',
                             },
                         ],
                     'duration': '7:00',
                     'position': '1',
                     'title': 'Untitled 8',
                     },
                 {
                     'artists': [
                         {
                             'anv': 'K.A.B.',
                             'id': 15525,
                             'join': ',',
                             'name': 'Karl Axel Bissler',
                             },
                         ],
                     'duration': '5:28',
                     'position': '2',
                     'title': 'Anjua (Sneaky 3)',
                     },
                 {
                     'artists': [
                         {
                             'id': 7,
                             'join': ',',
                             'name': 'Sylk 130',
                             },
                         ],
                     'duration': '5:25',
                     'extra_artists': [
                         {
                             'id': 8,
                             'name': 'Mood II Swing',
                             'roles': [
                                 {
                                     'name': 'Remix',
                                     },
                                 ],
                             },
                         ],
                     'position': '3',
                     'title': 'When The Funk Hits The Fan (Mood II Swing When The Dub Hits The Fan)',
                     },
                 {
                     'artists': [
                         {
                             'id': 1,
                             'join': ',',
                             'name': 'The Persuader',
                             },
                         ],
                     'duration': '4:27',
                     'position': '4',
                     'title': "What's The Time, Mr. Templar",
                     },
                 {
                     'artists': [
                         {
                             'id': 267132,
                             'join': ',',
                             'name': 'Care Company (2)',
                             },
                         ],
                     'duration': '5:36',
                     'position': '5',
                     'title': 'Vol. 2',
                     },
                 {
                     'artists': [
                         {
                             'id': 6981,
                             'join': ',',
                             'name': 'Gez Varley',
                             },
                         ],
                     'duration': '3:37',
                     'position': '6',
                     'title': 'Political Prisoner',
                     },
                 {
                     'artists': [
                         {
                             'id': 11,
                             'join': ',',
                             'name': 'DJ Dozia',
                             },
                         ],
                     'duration': '5:03',
                     'position': '7',
                     'title': 'Pop Kulture',
                     },
                 {
                     'artists': [
                         {
                             'id': 10702,
                             'join': 'Meets',
                             'name': "Nerio's Dubwork",
                             },
                         {
                             'id': 233190,
                             'join': ',',
                             'name': 'Kathy Lee',
                             },
                         ],
                     'duration': '5:42',
                     'extra_artists': [
                         {
                             'id': 23,
                             'name': 'Alex Hi-Fi',
                             'roles': [
                                 {
                                     'name': 'Remix',
                                     },
                                 ],
                             },
                         ],
                     'position': '8',
                     'title': 'K-Mart Shopping (Hi-Fi Mix)',
                     },
                 {
                     'artists': [
                         {
                             'id': 13,
                             'join': ',',
                             'name': 'Blaze',
                             },
                         ],
                     'duration': '5:47',
                     'extra_artists': [
                         {
                             'id': 14,
                             'name': 'Eight Miles High',
                             'roles': [
                                 {
                                     'name': 'Remix',
                                     },
                                 ],
                             },
                         ],
                     'position': '9',
                     'title': 'Lovelee Dae (Eight Miles High Mix)',
                     },
                 {
                     'artists': [
                         {
                             'id': 67226,
                             'join': 'Presents',
                             'name': 'Stacey Pullen',
                             },
                         {
                             'id': 7554,
                             'join': ',',
                             'name': 'Black Odyssey',
                             },
                         ],
                     'duration': '6:06',
                     'extra_artists': [
                         {
                             'id': 67226,
                             'name': 'Stacey Pullen',
                             'roles': [
                                 {
                                     'name': 'Presenter',
                                     },
                                 ],
                             },
                         ],
                     'position': '10',
                     'title': 'Sweat',
                     },
                 {
                     'artists': [
                         {
                             'id': 3906,
                             'join': ',',
                             'name': 'Christian Smith & John Selway',
                             },
                         ],
                     'duration': '3:16',
                     'position': '11',
                     'title': 'Silver',
                     },
                 {
                     'artists': [
                         {
                             'id': 3,
                             'join': ',',
                             'name': 'Josh Wink',
                             },
                         ],
                     'duration': '2:46',
                     'position': '12',
                     'title': 'Untitled',
                     },
                 {
                     'artists': [
                         {
                             'id': 19,
                             'join': ',',
                             'name': 'Sound Associates',
                             },
                         ],
                     'duration': '3:41',
                     'position': '13',
                     'title': 'Boom Box',
                     },
                 {
                     'artists': [
                         {
                             'id': 20,
                             'join': ',',
                             'name': 'Percy X',
                             },
                         ],
                     'duration': '3:39',
                     'position': '14',
                     'title': 'Track 2',
                     },
                 ],
             )
         ''')
     assert actual == expected
 def test_01(self):
     iterator = Bootstrapper.get_iterator('release')
     release_element = next(iterator)
     release = discograph.PostgresRelease.from_element(release_element)
     actual = format(release)
     expected = stringtools.normalize(u"""
         discograph.library.PostgresRelease(
             artists=[
                 {
                     'id': 1,
                     'join': ',',
                     'name': 'The Persuader',
                     },
                 ],
             companies=[
                 {
                     'entity_type': 23,
                     'entity_type_name': 'Recorded At',
                     'id': 271046,
                     'name': 'The Globe Studios',
                     },
                 {
                     'entity_type': 17,
                     'entity_type_name': 'Pressed By',
                     'id': 56025,
                     'name': 'MPO',
                     },
                 ],
             country='Sweden',
             extra_artists=[
                 {
                     'id': 239,
                     'name': 'Jesper Dahlbäck',
                     'roles': [
                         {
                             'detail': 'All Tracks By',
                             'name': 'Music By',
                             },
                         ],
                     },
                 ],
             formats=[
                 {
                     'descriptions': ['12"', '33 ⅓ RPM'],
                     'name': 'Vinyl',
                     'quantity': '2',
                     },
                 ],
             genres=['Electronic'],
             id=1,
             identifiers=[
                 {
                     'description': 'A-Side',
                     'type': 'Matrix / Runout',
                     'value': 'MPO SK 032 A1 G PHRUPMASTERGENERAL T27 LONDON',
                     },
                 {
                     'description': 'B-Side',
                     'type': 'Matrix / Runout',
                     'value': 'MPO SK 032 B1',
                     },
                 {
                     'description': 'C-Side',
                     'type': 'Matrix / Runout',
                     'value': 'MPO SK 032 C1',
                     },
                 {
                     'description': 'D-Side',
                     'type': 'Matrix / Runout',
                     'value': 'MPO SK 032 D1',
                     },
                 ],
             labels=[
                 {
                     'catalog_number': 'SK032',
                     'name': 'Svek',
                     },
                 ],
             release_date=datetime.datetime(1999, 3, 1, 0, 0),
             styles=['Deep House'],
             title='Stockholm',
             tracklist=[
                 {
                     'duration': '4:45',
                     'position': 'A',
                     'title': 'Östermalm',
                     },
                 {
                     'duration': '6:11',
                     'position': 'B1',
                     'title': 'Vasastaden',
                     },
                 {
                     'duration': '2:49',
                     'position': 'B2',
                     'title': 'Kungsholmen',
                     },
                 {
                     'duration': '5:38',
                     'position': 'C1',
                     'title': 'Södermalm',
                     },
                 {
                     'duration': '4:52',
                     'position': 'C2',
                     'title': 'Norrmalm',
                     },
                 {
                     'duration': '5:16',
                     'position': 'D',
                     'title': 'Gamla Stan',
                     },
                 ],
             )
         """)
     assert actual == expected
 def test_02(self):
     iterator = Bootstrapper.get_iterator('release')
     release_element = next(iterator)
     release_element = next(iterator)
     release_element = next(iterator)
     release = discograph.PostgresRelease.from_element(release_element)
     actual = format(release)
     expected = stringtools.normalize(r'''
         discograph.library.PostgresRelease(
             artists=[
                 {
                     'id': 3,
                     'name': 'Josh Wink',
                     },
                 ],
             companies=[
                 {
                     'entity_type': 10,
                     'entity_type_name': 'Manufactured By',
                     'id': 93330,
                     'name': 'Columbia Records',
                     },
                 {
                     'entity_type': 9,
                     'entity_type_name': 'Distributed By',
                     'id': 93330,
                     'name': 'Columbia Records',
                     },
                 ],
             country='US',
             extra_artists=[
                 {
                     'id': 3,
                     'name': 'Josh Wink',
                     'roles': [
                         {
                             'name': 'DJ Mix',
                             },
                         ],
                     },
                 ],
             formats=[
                 {
                     'descriptions': ['Compilation', 'Mixed'],
                     'name': 'CD',
                     'quantity': '1',
                     },
                 ],
             genres=['Electronic'],
             id=3,
             identifiers=[
                 {
                     'description': None,
                     'type': 'Barcode',
                     'value': '074646362822',
                     },
                 ],
             labels=[
                 {
                     'catalog_number': 'CK 63628',
                     'name': 'Ruffhouse Records',
                     },
                 ],
             master_id=66526,
             release_date=datetime.datetime(1999, 7, 13, 0, 0),
             styles=['Techno', 'Tech House'],
             title='Profound Sounds Vol. 1',
             tracklist=[
                 {
                     'artists': [
                         {
                             'id': 5,
                             'join': '&',
                             'name': 'Heiko Laux',
                             },
                         {
                             'id': 4,
                             'join': ',',
                             'name': 'Johannes Heil',
                             },
                         ],
                     'duration': '7:00',
                     'position': '1',
                     'title': 'Untitled 8',
                     },
                 {
                     'artists': [
                         {
                             'anv': 'K.A.B.',
                             'id': 15525,
                             'join': ',',
                             'name': 'Karl Axel Bissler',
                             },
                         ],
                     'duration': '5:28',
                     'position': '2',
                     'title': 'Anjua (Sneaky 3)',
                     },
                 {
                     'artists': [
                         {
                             'id': 7,
                             'join': ',',
                             'name': 'Sylk 130',
                             },
                         ],
                     'duration': '5:25',
                     'extra_artists': [
                         {
                             'id': 8,
                             'name': 'Mood II Swing',
                             'roles': [
                                 {
                                     'name': 'Remix',
                                     },
                                 ],
                             },
                         ],
                     'position': '3',
                     'title': 'When The Funk Hits The Fan (Mood II Swing When The Dub Hits The Fan)',
                     },
                 {
                     'artists': [
                         {
                             'id': 1,
                             'join': ',',
                             'name': 'The Persuader',
                             },
                         ],
                     'duration': '4:27',
                     'position': '4',
                     'title': "What's The Time, Mr. Templar",
                     },
                 {
                     'artists': [
                         {
                             'id': 267132,
                             'join': ',',
                             'name': 'Care Company (2)',
                             },
                         ],
                     'duration': '5:36',
                     'position': '5',
                     'title': 'Vol. 2',
                     },
                 {
                     'artists': [
                         {
                             'id': 6981,
                             'join': ',',
                             'name': 'Gez Varley',
                             },
                         ],
                     'duration': '3:37',
                     'position': '6',
                     'title': 'Political Prisoner',
                     },
                 {
                     'artists': [
                         {
                             'id': 11,
                             'join': ',',
                             'name': 'DJ Dozia',
                             },
                         ],
                     'duration': '5:03',
                     'position': '7',
                     'title': 'Pop Kulture',
                     },
                 {
                     'artists': [
                         {
                             'id': 10702,
                             'join': 'Meets',
                             'name': "Nerio's Dubwork",
                             },
                         {
                             'id': 233190,
                             'join': ',',
                             'name': 'Kathy Lee',
                             },
                         ],
                     'duration': '5:42',
                     'extra_artists': [
                         {
                             'id': 23,
                             'name': 'Alex Hi-Fi',
                             'roles': [
                                 {
                                     'name': 'Remix',
                                     },
                                 ],
                             },
                         ],
                     'position': '8',
                     'title': 'K-Mart Shopping (Hi-Fi Mix)',
                     },
                 {
                     'artists': [
                         {
                             'id': 13,
                             'join': ',',
                             'name': 'Blaze',
                             },
                         ],
                     'duration': '5:47',
                     'extra_artists': [
                         {
                             'id': 14,
                             'name': 'Eight Miles High',
                             'roles': [
                                 {
                                     'name': 'Remix',
                                     },
                                 ],
                             },
                         ],
                     'position': '9',
                     'title': 'Lovelee Dae (Eight Miles High Mix)',
                     },
                 {
                     'artists': [
                         {
                             'id': 67226,
                             'join': 'Presents',
                             'name': 'Stacey Pullen',
                             },
                         {
                             'id': 7554,
                             'join': ',',
                             'name': 'Black Odyssey',
                             },
                         ],
                     'duration': '6:06',
                     'extra_artists': [
                         {
                             'id': 67226,
                             'name': 'Stacey Pullen',
                             'roles': [
                                 {
                                     'name': 'Presenter',
                                     },
                                 ],
                             },
                         ],
                     'position': '10',
                     'title': 'Sweat',
                     },
                 {
                     'artists': [
                         {
                             'id': 3906,
                             'join': ',',
                             'name': 'Christian Smith & John Selway',
                             },
                         ],
                     'duration': '3:16',
                     'position': '11',
                     'title': 'Silver',
                     },
                 {
                     'artists': [
                         {
                             'id': 3,
                             'join': ',',
                             'name': 'Josh Wink',
                             },
                         ],
                     'duration': '2:46',
                     'position': '12',
                     'title': 'Untitled',
                     },
                 {
                     'artists': [
                         {
                             'id': 19,
                             'join': ',',
                             'name': 'Sound Associates',
                             },
                         ],
                     'duration': '3:41',
                     'position': '13',
                     'title': 'Boom Box',
                     },
                 {
                     'artists': [
                         {
                             'id': 20,
                             'join': ',',
                             'name': 'Percy X',
                             },
                         ],
                     'duration': '3:39',
                     'position': '14',
                     'title': 'Track 2',
                     },
                 ],
             )
         ''')
     assert actual == expected
 def test_01(self):
     iterator = Bootstrapper.get_iterator('artist')
     artist_element = next(iterator)
     artist_element = next(iterator)
     actual = Bootstrapper.prettify(artist_element)
     expected = stringtools.normalize('''
         <?xml version="1.0" ?>
         <artist>
             <id>2</id>
             <name>Mr. James Barth &amp; A.D.</name>
             <realname>Cari Lekebusch &amp; Alexi Delano</realname>
             <profile/>
             <data_quality>Correct</data_quality>
             <namevariations>
                 <name>Mr Barth &amp; A.D.</name>
                 <name>MR JAMES BARTH &amp; A. D.</name>
                 <name>Mr. Barth &amp; A.D.</name>
                 <name>Mr. James Barth &amp; A. D.</name>
             </namevariations>
             <aliases>
                 <name>ADCL</name>
                 <name>Alexi Delano &amp; Cari Lekebusch</name>
                 <name>Crushed Insect &amp; The Sick Puppy</name>
                 <name>Puente Latino</name>
                 <name>Yakari &amp; Delano</name>
             </aliases>
             <members>
                 <id>26</id>
                 <name>Alexi Delano</name>
                 <id>27</id>
                 <name>Cari Lekebusch</name>
             </members>
         </artist>
         ''')
     assert actual.splitlines() == expected.splitlines()
     artist_document = library.Artist.from_element(artist_element)
     actual = format(artist_document)
     expected = stringtools.normalize('''
         discograph.library.mongo.Artist(
             aliases=[
                 discograph.library.mongo.ArtistReference(
                     name='ADCL',
                     ),
                 discograph.library.mongo.ArtistReference(
                     name='Alexi Delano & Cari Lekebusch',
                     ),
                 discograph.library.mongo.ArtistReference(
                     name='Crushed Insect & The Sick Puppy',
                     ),
                 discograph.library.mongo.ArtistReference(
                     name='Puente Latino',
                     ),
                 discograph.library.mongo.ArtistReference(
                     name='Yakari & Delano',
                     ),
                 ],
             discogs_id=2,
             members=[
                 discograph.library.mongo.ArtistReference(
                     discogs_id=26,
                     name='Alexi Delano',
                     ),
                 discograph.library.mongo.ArtistReference(
                     discogs_id=27,
                     name='Cari Lekebusch',
                     ),
                 ],
             name='Mr. James Barth & A.D.',
             name_variations=[
                 'Mr Barth & A.D.',
                 'MR JAMES BARTH & A. D.',
                 'Mr. Barth & A.D.',
                 'Mr. James Barth & A. D.',
                 ],
             real_name='Cari Lekebusch & Alexi Delano',
             )
         ''')
     assert actual == expected