diff --git a/critiquebrainz/frontend/external/bookbrainz_db/author.py b/critiquebrainz/frontend/external/bookbrainz_db/author.py index fc3afcd47..41e9e1138 100644 --- a/critiquebrainz/frontend/external/bookbrainz_db/author.py +++ b/critiquebrainz/frontend/external/bookbrainz_db/author.py @@ -2,10 +2,10 @@ from brainzutils import cache from typing import List import sqlalchemy -import critiquebrainz.frontend.external.bookbrainz_db as db +import critiquebrainz.frontend.external.bookbrainz_db as db from critiquebrainz.frontend.external.bookbrainz_db import DEFAULT_CACHE_EXPIRATION -from critiquebrainz.frontend.external.bookbrainz_db.identifiers import fetch_bb_external_identifiers -from critiquebrainz.frontend.external.bookbrainz_db.relationships import fetch_relationships, AUTHOR_WORK_AUTHOR_REL_ID +from critiquebrainz.frontend.external.bookbrainz_db.identifiers import process_bb_identifiers + def get_author_by_bbid(bbid: str) -> dict: """ @@ -50,65 +50,111 @@ def fetch_multiple_authors(bbids: List[str]) -> dict: if not results: with db.bb_engine.connect() as connection: result = connection.execute(sqlalchemy.text(""" - SELECT - bbid::text, - author.name, - sort_name, - author_type, - disambiguation, - identifier_set_id, - relationship_set_id, - area_id, - begin_year, - begin_month, - begin_day, - begin_area_id, - end_year, - end_month, - end_day, - end_area_id, - author.ended, - gender.name as gender, - COALESCE (json_agg(area) - FILTER (WHERE area IS NOT NULL), + SELECT + bbid::text, + author.name, + sort_name, + author_type, + disambiguation, + identifier_set_id, + relationship_set_id, + area_id, + begin_year, + begin_month, + begin_day, + begin_area_id, + end_year, + end_month, + end_day, + end_area_id, + author.ended, + gender.name as gender, + COALESCE (json_agg(area) + FILTER (WHERE area.name IS NOT NULL), + '[]' + ) as area_info, + COALESCE (json_agg(DISTINCT relationships) + FILTER (WHERE relationships IS NOT NULL), + '[]' + ) as rels, + COALESCE (json_agg(DISTINCT identifiers) + FILTER (WHERE identifiers IS NOT NULL), '[]' - ) as area_info - FROM author - LEFT JOIN musicbrainz.area area - ON begin_area_id = area.id - OR end_area_id = area.id - OR area_id = area.id + ) as identifiers + FROM author + LEFT JOIN musicbrainz.area area + ON begin_area_id = area.id + OR end_area_id = area.id + OR area_id = area.id LEFT JOIN musicbrainz.gender ON gender_id = gender.id - WHERE bbid IN :bbids - AND master = 't' - GROUP BY bbid, - author.name, - sort_name, - author_type, - disambiguation, - identifier_set_id, - relationship_set_id, - area_id, - begin_year, - begin_month, - begin_day, - begin_area_id, - end_year, - end_month, - end_day, - end_area_id, - author.ended, - gender.name - """), {'bbids': tuple(bbids)}) + LEFT JOIN LATERAL ( + SELECT rel.id as id, + reltype.id as relationship_type_id, + reltype.label as label, + rel.source_bbid::text as source_bbid, + rel.target_bbid::text as target_bbid, + reltype.target_entity_type as target_entity_type, + reltype.source_entity_type as source_entity_type, + COALESCE( + jsonb_object_agg(relatttype.name, relatttext.text_value) + FILTER (WHERE relatts IS NOT NULL), + '[]' + ) as attributes + FROM relationship_set__relationship rels + LEFT JOIN relationship rel ON rels.relationship_id = rel.id + LEFT JOIN relationship_type reltype ON rel.type_id = reltype.id + LEFT JOIN relationship_attribute_set__relationship_attribute relatts ON rel.attribute_set_id = relatts.set_id + LEFT JOIN relationship_attribute relatt ON relatts.attribute_id = relatt.id + LEFT JOIN relationship_attribute_type relatttype ON relatt.attribute_type = relatttype.id + LEFT JOIN relationship_attribute_text_value relatttext ON relatts.attribute_id = relatttext.attribute_id + WHERE rels.set_id = author.relationship_set_id + GROUP BY rel.id, + reltype.id, + reltype.label, + rel.source_bbid, + rel.target_bbid, + reltype.target_entity_type, + reltype.source_entity_type + ) AS relationships ON TRUE + LEFT JOIN LATERAL ( + SELECT iden.type_id as type_id, + idtype.label as label, + idtype.display_template as url_template, + iden.value as value + FROM identifier_set__identifier idens + LEFT JOIN identifier iden on idens.identifier_id = iden.id + LEFT JOIN identifier_type idtype on iden.type_id = idtype.id + WHERE idens.set_id = author.identifier_set_id + ) AS identifiers ON TRUE + WHERE bbid IN :bbids + AND master = 't' + GROUP BY bbid, + author.name, + sort_name, + author_type, + disambiguation, + identifier_set_id, + relationship_set_id, + area_id, + begin_year, + begin_month, + begin_day, + begin_area_id, + end_year, + end_month, + end_day, + end_area_id, + author.ended, + gender.name + """), {'bbids': tuple(bbids)}) authors = result.mappings() results = {} for author in authors: author = dict(author) author['bbid'] = str(author['bbid']) - author['identifiers'] = fetch_bb_external_identifiers(author['identifier_set_id']) - author['rels'] = fetch_relationships( author['relationship_set_id'], [AUTHOR_WORK_AUTHOR_REL_ID]) + author['identifiers'] = process_bb_identifiers(author['identifiers']) results[author['bbid']] = author cache.set(bb_author_key, results, DEFAULT_CACHE_EXPIRATION) diff --git a/critiquebrainz/frontend/external/bookbrainz_db/edition_group.py b/critiquebrainz/frontend/external/bookbrainz_db/edition_group.py index a9aba36be..9b242caa7 100644 --- a/critiquebrainz/frontend/external/bookbrainz_db/edition_group.py +++ b/critiquebrainz/frontend/external/bookbrainz_db/edition_group.py @@ -4,8 +4,8 @@ import sqlalchemy import critiquebrainz.frontend.external.bookbrainz_db as db from critiquebrainz.frontend.external.bookbrainz_db import DEFAULT_CACHE_EXPIRATION -from critiquebrainz.frontend.external.bookbrainz_db.identifiers import fetch_bb_external_identifiers -from critiquebrainz.frontend.external.bookbrainz_db.relationships import fetch_relationships, EDITION_EDITION_GROUP_EDITION_REL_ID, EDITION_WORK_CONTAINS_REL_ID +from critiquebrainz.frontend.external.bookbrainz_db.identifiers import process_bb_identifiers +from critiquebrainz.frontend.external.bookbrainz_db.relationships import EDITION_WORK_CONTAINS_REL_ID def get_edition_group_by_bbid(bbid: str) -> dict: @@ -63,9 +63,56 @@ def fetch_multiple_edition_groups(bbids: List[str]) -> dict: COALESCE( json_agg( acn ORDER BY "position" ASC ) FILTER (WHERE acn IS NOT NULL), '[]' - ) as author_credits + ) as author_credits, + COALESCE (json_agg(DISTINCT relationships) + FILTER (WHERE relationships IS NOT NULL), + '[]' + ) as rels, + COALESCE (json_agg(DISTINCT identifiers) + FILTER (WHERE identifiers IS NOT NULL), + '[]' + ) as identifiers FROM edition_group LEFT JOIN author_credit_name acn ON acn.author_credit_id = edition_group.author_credit_id + LEFT JOIN LATERAL ( + SELECT rel.id as id, + reltype.id as relationship_type_id, + reltype.label as label, + rel.source_bbid::text as source_bbid, + rel.target_bbid::text as target_bbid, + reltype.target_entity_type as target_entity_type, + reltype.source_entity_type as source_entity_type, + COALESCE( + jsonb_object_agg(relatttype.name, relatttext.text_value) + FILTER (WHERE relatts IS NOT NULL), + '[]' + ) as attributes + FROM relationship_set__relationship rels + LEFT JOIN relationship rel ON rels.relationship_id = rel.id + LEFT JOIN relationship_type reltype ON rel.type_id = reltype.id + LEFT JOIN relationship_attribute_set__relationship_attribute relatts ON rel.attribute_set_id = relatts.set_id + LEFT JOIN relationship_attribute relatt ON relatts.attribute_id = relatt.id + LEFT JOIN relationship_attribute_type relatttype ON relatt.attribute_type = relatttype.id + LEFT JOIN relationship_attribute_text_value relatttext ON relatts.attribute_id = relatttext.attribute_id + WHERE rels.set_id = edition_group.relationship_set_id + GROUP BY rel.id, + reltype.id, + reltype.label, + rel.source_bbid, + rel.target_bbid, + reltype.target_entity_type, + reltype.source_entity_type + ) AS relationships ON TRUE + LEFT JOIN LATERAL ( + SELECT iden.type_id as type_id, + idtype.label as label, + idtype.display_template as url_template, + iden.value as value + FROM identifier_set__identifier idens + LEFT JOIN identifier iden on idens.identifier_id = iden.id + LEFT JOIN identifier_type idtype on iden.type_id = idtype.id + WHERE idens.set_id = edition_group.identifier_set_id + ) AS identifiers ON TRUE WHERE bbid in :bbids AND master = 't' AND data_id IS NOT NULL @@ -82,8 +129,7 @@ def fetch_multiple_edition_groups(bbids: List[str]) -> dict: results = {} for edition_group in edition_groups: edition_group = dict(edition_group) - edition_group['identifiers'] = fetch_bb_external_identifiers(edition_group['identifier_set_id']) - edition_group['rels'] = fetch_relationships( edition_group['relationship_set_id'], [EDITION_EDITION_GROUP_EDITION_REL_ID]) + edition_group['identifiers'] = process_bb_identifiers(edition_group['identifiers']) results[edition_group['bbid']] = edition_group edition_groups = results diff --git a/critiquebrainz/frontend/external/bookbrainz_db/identifiers.py b/critiquebrainz/frontend/external/bookbrainz_db/identifiers.py index b44460257..2b4cd38e7 100644 --- a/critiquebrainz/frontend/external/bookbrainz_db/identifiers.py +++ b/critiquebrainz/frontend/external/bookbrainz_db/identifiers.py @@ -1,46 +1,4 @@ from typing import List -from brainzutils import cache -import sqlalchemy -import critiquebrainz.frontend.external.bookbrainz_db as db -from critiquebrainz.frontend.external.bookbrainz_db import DEFAULT_CACHE_EXPIRATION - -def fetch_bb_external_identifiers(identifier_set_id: int) -> List: - """ - Fetch identifiers from the database. - Args: - identifier_set_id (int): Identifier set ID. - Returns: - List of identifiers containing the following fields: - - name (str): Identifier name. - - url (str): Identifier URL. - - value (str): Identifier value. - - icon (str): Identifier icon. - """ - if not identifier_set_id: - return [] - - bb_identifiers_key = cache.gen_key('identifier', identifier_set_id) - identifiers = cache.get(bb_identifiers_key) - if not identifiers: - with db.bb_engine.connect() as connection: - result = connection.execute(sqlalchemy.text(""" - SELECT iden.type_id as type_id, - idtype.label as label, - idtype.display_template as url_template, - iden.value as value - FROM identifier_set__identifier idens - LEFT JOIN identifier iden on idens.identifier_id = iden.id - LEFT JOIN identifier_type idtype on iden.type_id = idtype.id - WHERE idens.set_id = :identifier_set_id - """), {'identifier_set_id': identifier_set_id}) - identifiers = result.mappings() - identifiers = [dict(identifier) for identifier in identifiers] - identifiers = process_bb_identifiers(identifiers) - cache.set(bb_identifiers_key, identifiers, DEFAULT_CACHE_EXPIRATION) - - if not identifiers: - return [] - return identifiers def process_bb_identifiers(identifiers: List) -> List: diff --git a/critiquebrainz/frontend/external/bookbrainz_db/literary_work.py b/critiquebrainz/frontend/external/bookbrainz_db/literary_work.py index 5a3cf10c5..63988d23d 100644 --- a/critiquebrainz/frontend/external/bookbrainz_db/literary_work.py +++ b/critiquebrainz/frontend/external/bookbrainz_db/literary_work.py @@ -4,8 +4,8 @@ import sqlalchemy import critiquebrainz.frontend.external.bookbrainz_db as db from critiquebrainz.frontend.external.bookbrainz_db import DEFAULT_CACHE_EXPIRATION -from critiquebrainz.frontend.external.bookbrainz_db.identifiers import fetch_bb_external_identifiers -from critiquebrainz.frontend.external.bookbrainz_db.relationships import fetch_relationships, WORK_WORK_TRANSLATION_REL_ID, EDITION_WORK_CONTAINS_REL_ID +from critiquebrainz.frontend.external.bookbrainz_db.identifiers import process_bb_identifiers +from critiquebrainz.frontend.external.bookbrainz_db.relationships import EDITION_WORK_CONTAINS_REL_ID WORK_TYPE_FILTER_OPTIONS = ('Novel', 'Short Story', 'Poem') @@ -80,13 +80,60 @@ def fetch_multiple_literary_works(bbids: List[str], work_type=None, limit=None, disambiguation, identifier_set_id, relationship_set_id, - COALESCE (json_agg(mbl.name) + COALESCE (json_agg(DISTINCT mbl.name) FILTER (WHERE mbl IS NOT NULL), '[]' - ) as languages + ) as languages, + COALESCE (json_agg(DISTINCT relationships) + FILTER (WHERE relationships IS NOT NULL), + '[]' + ) as rels, + COALESCE (json_agg(DISTINCT identifiers) + FILTER (WHERE identifiers IS NOT NULL), + '[]' + ) as identifiers FROM work LEFT JOIN bookbrainz.language_set__language lsl ON lsl.set_id = work.language_set_id LEFT JOIN musicbrainz.language mbl on mbl.id = lsl.language_id + LEFT JOIN LATERAL ( + SELECT rel.id as id, + reltype.id as relationship_type_id, + reltype.label as label, + rel.source_bbid::text as source_bbid, + rel.target_bbid::text as target_bbid, + reltype.target_entity_type as target_entity_type, + reltype.source_entity_type as source_entity_type, + COALESCE( + jsonb_object_agg(relatttype.name, relatttext.text_value) + FILTER (WHERE relatts IS NOT NULL), + '[]' + ) as attributes + FROM relationship_set__relationship rels + LEFT JOIN relationship rel ON rels.relationship_id = rel.id + LEFT JOIN relationship_type reltype ON rel.type_id = reltype.id + LEFT JOIN relationship_attribute_set__relationship_attribute relatts ON rel.attribute_set_id = relatts.set_id + LEFT JOIN relationship_attribute relatt ON relatts.attribute_id = relatt.id + LEFT JOIN relationship_attribute_type relatttype ON relatt.attribute_type = relatttype.id + LEFT JOIN relationship_attribute_text_value relatttext ON relatts.attribute_id = relatttext.attribute_id + WHERE rels.set_id = work.relationship_set_id + GROUP BY rel.id, + reltype.id, + reltype.label, + rel.source_bbid, + rel.target_bbid, + reltype.target_entity_type, + reltype.source_entity_type + ) AS relationships ON TRUE + LEFT JOIN LATERAL ( + SELECT iden.type_id as type_id, + idtype.label as label, + idtype.display_template as url_template, + iden.value as value + FROM identifier_set__identifier idens + LEFT JOIN identifier iden on idens.identifier_id = iden.id + LEFT JOIN identifier_type idtype on iden.type_id = idtype.id + WHERE idens.set_id = work.identifier_set_id + ) AS identifiers ON TRUE WHERE bbid IN :bbids AND master = 't' AND data_id IS NOT NULL @@ -107,8 +154,7 @@ def fetch_multiple_literary_works(bbids: List[str], work_type=None, limit=None, results = {} for literary_work in literary_works: literary_work = dict(literary_work) - literary_work['identifiers'] = fetch_bb_external_identifiers(literary_work['identifier_set_id']) - literary_work['rels'] = fetch_relationships(literary_work['relationship_set_id'], [WORK_WORK_TRANSLATION_REL_ID]) + literary_work['identifiers'] = process_bb_identifiers(literary_work['identifiers']) results[literary_work['bbid']] = literary_work cache.set(bb_literary_work_key, results, DEFAULT_CACHE_EXPIRATION) diff --git a/critiquebrainz/frontend/external/bookbrainz_db/publisher.py b/critiquebrainz/frontend/external/bookbrainz_db/publisher.py index 29589f303..05f94a2de 100644 --- a/critiquebrainz/frontend/external/bookbrainz_db/publisher.py +++ b/critiquebrainz/frontend/external/bookbrainz_db/publisher.py @@ -46,29 +46,29 @@ def fetch_multiple_publishers(bbids: List[str]) -> dict: if not results: with db.bb_engine.connect() as connection: result = connection.execute(sqlalchemy.text(""" - SELECT - bbid::text, - publisher.name, - sort_name, - publisher_type, - disambiguation, - identifier_set_id, - relationship_set_id, - area.gid::text as area_mbid, + SELECT + bbid::text, + publisher.name, + sort_name, + publisher_type, + disambiguation, + identifier_set_id, + relationship_set_id, + area.gid::text as area_mbid, area.name as area_name, - begin_year, - begin_month, - begin_day, - end_year, - end_month, - end_day, - publisher.ended - FROM publisher - LEFT JOIN musicbrainz.area - ON publisher.area_id = area.id - WHERE bbid IN :bbids - AND master = 't' - """), {'bbids': tuple(bbids)}) + begin_year, + begin_month, + begin_day, + end_year, + end_month, + end_day, + publisher.ended + FROM publisher + LEFT JOIN musicbrainz.area + ON publisher.area_id = area.id + WHERE bbid IN :bbids + AND master = 't' + """), {'bbids': tuple(bbids)}) publishers = result.mappings() results = {} diff --git a/critiquebrainz/frontend/external/bookbrainz_db/relationships.py b/critiquebrainz/frontend/external/bookbrainz_db/relationships.py index 9f9595a86..b6775b6cf 100644 --- a/critiquebrainz/frontend/external/bookbrainz_db/relationships.py +++ b/critiquebrainz/frontend/external/bookbrainz_db/relationships.py @@ -1,9 +1,3 @@ -from typing import List -from brainzutils import cache -import sqlalchemy -import critiquebrainz.frontend.external.bookbrainz_db as db -from critiquebrainz.frontend.external.bookbrainz_db import DEFAULT_CACHE_EXPIRATION - AUTHOR_WORK_AUTHOR_REL_ID = 8 EDITION_EDITION_GROUP_EDITION_REL_ID = 3 EDITION_WORK_CONTAINS_REL_ID = 10 @@ -16,36 +10,3 @@ 'Publisher': 74, 'Work': 71, } - -def fetch_relationships(relationship_set_id: int, relation_types_id: List) -> List: - """ - Fetch relationships from the database. - """ - if not relationship_set_id: - return [] - - key = cache.gen_key('bb_relationship', relationship_set_id, relation_types_id) - relationships = cache.get(key) - if not relationships: - with db.bb_engine.connect() as connection: - result = connection.execute(sqlalchemy.text(""" - SELECT rel.id as id, - reltype.id as relation_type_id, - reltype.label as label, - rel.source_bbid::text as source_bbid, - rel.target_bbid::text as target_bbid, - reltype.target_entity_type as target_entity_type, - reltype.source_entity_type as source_entity_type - FROM relationship_set__relationship rels - LEFT JOIN relationship rel on rels.relationship_id = rel.id - LEFT JOIN relationship_type reltype on rel.type_id = reltype.id - WHERE rels.set_id = :relationship_set_id - AND reltype.id in :relation_types_id - """), {'relationship_set_id': relationship_set_id, 'relation_types_id': tuple(relation_types_id)}) - relationships = result.mappings() - relationships = [dict(relationship) for relationship in relationships] - cache.set(key, relationships, DEFAULT_CACHE_EXPIRATION) - - if not relationships: - return [] - return relationships diff --git a/critiquebrainz/frontend/external/bookbrainz_db/series.py b/critiquebrainz/frontend/external/bookbrainz_db/series.py index 79806d2a6..1eb33eff0 100644 --- a/critiquebrainz/frontend/external/bookbrainz_db/series.py +++ b/critiquebrainz/frontend/external/bookbrainz_db/series.py @@ -4,8 +4,8 @@ import sqlalchemy import critiquebrainz.frontend.external.bookbrainz_db as db from critiquebrainz.frontend.external.bookbrainz_db import DEFAULT_CACHE_EXPIRATION -from critiquebrainz.frontend.external.bookbrainz_db.identifiers import fetch_bb_external_identifiers -from critiquebrainz.frontend.external.bookbrainz_db.relationships import fetch_relationships, SERIES_REL_MAP +from critiquebrainz.frontend.external.bookbrainz_db.identifiers import process_bb_identifiers +from critiquebrainz.frontend.external.bookbrainz_db.relationships import SERIES_REL_MAP from critiquebrainz.frontend.external.bookbrainz_db.author import fetch_multiple_authors from critiquebrainz.frontend.external.bookbrainz_db.edition import fetch_multiple_editions from critiquebrainz.frontend.external.bookbrainz_db.edition_group import fetch_multiple_edition_groups @@ -65,13 +65,70 @@ def fetch_multiple_series(bbids: List[str]) -> dict: disambiguation, identifier_set_id, relationship_set_id, - series_ordering_type.label as series_ordering_type + series_ordering_type.label as series_ordering_type, + series_ordering_type.id as series_ordering_type_id, + COALESCE (json_agg(DISTINCT relationships) + FILTER (WHERE relationships IS NOT NULL), + '[]' + ) as rels, + COALESCE (json_agg(DISTINCT identifiers) + FILTER (WHERE identifiers IS NOT NULL), + '[]' + ) as identifiers FROM series LEFT JOIN series_ordering_type ON series.ordering_type_id = series_ordering_type.id + LEFT JOIN LATERAL ( + SELECT rel.id as id, + reltype.id as relationship_type_id, + reltype.label as label, + rel.source_bbid::text as source_bbid, + rel.target_bbid::text as target_bbid, + reltype.target_entity_type as target_entity_type, + reltype.source_entity_type as source_entity_type, + COALESCE( + jsonb_object_agg(relatttype.name, relatttext.text_value) + FILTER (WHERE relatts IS NOT NULL), + '[]' + ) as attributes + FROM relationship_set__relationship rels + LEFT JOIN relationship rel ON rels.relationship_id = rel.id + LEFT JOIN relationship_type reltype ON rel.type_id = reltype.id + LEFT JOIN relationship_attribute_set__relationship_attribute relatts ON rel.attribute_set_id = relatts.set_id + LEFT JOIN relationship_attribute relatt ON relatts.attribute_id = relatt.id + LEFT JOIN relationship_attribute_type relatttype ON relatt.attribute_type = relatttype.id + LEFT JOIN relationship_attribute_text_value relatttext ON relatts.attribute_id = relatttext.attribute_id + WHERE rels.set_id = series.relationship_set_id + GROUP BY rel.id, + reltype.id, + reltype.label, + rel.source_bbid, + rel.target_bbid, + reltype.target_entity_type, + reltype.source_entity_type + ) AS relationships ON TRUE + LEFT JOIN LATERAL ( + SELECT iden.type_id as type_id, + idtype.label as label, + idtype.display_template as url_template, + iden.value as value + FROM identifier_set__identifier idens + LEFT JOIN identifier iden on idens.identifier_id = iden.id + LEFT JOIN identifier_type idtype on iden.type_id = idtype.id + WHERE idens.set_id = series.identifier_set_id + ) AS identifiers ON TRUE WHERE bbid IN :bbids AND master = 't' AND entity_type IS NOT NULL + GROUP BY bbid, + series.name, + sort_name, + entity_type, + disambiguation, + identifier_set_id, + relationship_set_id, + series_ordering_type.label, + series_ordering_type.id """), {'bbids': tuple(bbids)}) data = result.mappings() @@ -79,8 +136,20 @@ def fetch_multiple_series(bbids: List[str]) -> dict: for series in data: series = dict(series) series['bbid'] = str(series['bbid']) - series['identifiers'] = fetch_bb_external_identifiers(series['identifier_set_id']) - series['rels'] = fetch_relationships(series['relationship_set_id'], [SERIES_REL_MAP[series['series_type']]]) + series['identifiers'] = process_bb_identifiers(series['identifiers']) + + series_rels = [] + for rel in series['rels']: + if rel['relationship_type_id'] == SERIES_REL_MAP[series['series_type']]: + series_rels.append(rel) + + if series['series_ordering_type_id'] == 2: + series['rels'] = sorted(series_rels, key=lambda i: ( + i['attributes']['position'] is None, i['attributes']['position'])) + else: + series['rels'] = sorted(series_rels, key=lambda i: ( + i['attributes']['number'] is None, i['attributes']['number'])) + results[series['bbid']] = series cache.set(bb_series_key, results, DEFAULT_CACHE_EXPIRATION) diff --git a/critiquebrainz/frontend/external/bookbrainz_db/test/bb_relationship_test.py b/critiquebrainz/frontend/external/bookbrainz_db/test/bb_relationship_test.py deleted file mode 100644 index 949f4bf80..000000000 --- a/critiquebrainz/frontend/external/bookbrainz_db/test/bb_relationship_test.py +++ /dev/null @@ -1,15 +0,0 @@ -from critiquebrainz.frontend.external.bookbrainz_db import relationships -from critiquebrainz.data.testing import DataTestCase - -class BBRelationshipTestCase(DataTestCase): - def setUP(self): - super(BBRelationshipTestCase, self).setUp() - - def test_bb_relationship(self): - relationship = relationships.fetch_relationships(99999999, [relationships.AUTHOR_WORK_AUTHOR_REL_ID]) - self.assertEqual(relationship[0]["label"], "Author") - self.assertEqual(relationship[0]["source_bbid"], "e5c4e68b-bfce-4c77-9ca2-0f0a2d4d09f0") - self.assertEqual(relationship[0]["target_bbid"], "9f49df73-8ee5-4c5f-8803-427c9b216d8f") - - relationship = relationships.fetch_relationships(99999999, [relationships.EDITION_EDITION_GROUP_EDITION_REL_ID]) - self.assertEqual(relationship, []) diff --git a/critiquebrainz/frontend/templates/bb_series/entity.html b/critiquebrainz/frontend/templates/bb_series/entity.html index a2f0bd3db..b86743e23 100644 --- a/critiquebrainz/frontend/templates/bb_series/entity.html +++ b/critiquebrainz/frontend/templates/bb_series/entity.html @@ -77,7 +77,13 @@

{{ _('Author') }}

{% for rel in series_rels_info %} - {{ loop.index }} + + {% if rel['number'] is defined and rel['number'] %} + {{ rel['number'] }} + {% else %} + - + {% endif %} + {{ rel.name }} @@ -117,7 +123,13 @@

{{ _('Edition') }}

{% for rel in series_rels_info %} - {{ loop.index }} + + {% if rel['number'] is defined and rel['number'] %} + {{ rel['number'] }} + {% else %} + - + {% endif %} +
{{ rel.name }} @@ -161,7 +173,13 @@

{{ _('Edition Groups') }}

{% for rel in series_rels_info %} - {{ loop.index }} + + {% if rel['number'] is defined and rel['number'] %} + {{ rel['number'] }} + {% else %} + - + {% endif %} +
{{ rel.name }} @@ -209,7 +227,13 @@

{{ _('Publisher') }}

{% for rel in series_rels_info %} - {{ loop.index }} + + {% if rel['number'] is defined and rel['number'] %} + {{ rel['number'] }} + {% else %} + - + {% endif %} +
{{ rel.name }} @@ -249,7 +273,13 @@

{{ _('Literary Works') }}

{% for rel in series_rels_info %} - {{ loop.index }} + + {% if rel['number'] is defined and rel['number'] %} + {{ rel['number'] }} + {% else %} + - + {% endif %} +
{{ rel.name }} diff --git a/critiquebrainz/frontend/views/bb_author.py b/critiquebrainz/frontend/views/bb_author.py index e24f8166e..54e0609f5 100644 --- a/critiquebrainz/frontend/views/bb_author.py +++ b/critiquebrainz/frontend/views/bb_author.py @@ -13,6 +13,7 @@ bb_author_bp = Blueprint('bb_author', __name__) +AUTHOR_WORK_AUTHOR_REL_ID = 8 LITERARY_WORK_TYPE_NOVEL = 'Novel' LITERARY_WORK_TYPE_SHORT_STORY = 'Short Story' LITERARY_WORK_TYPE_POEM = 'Poem' @@ -61,12 +62,14 @@ def entity(id): raise BadRequest("Unsupported literary_work type.") if author['rels']: - literary_work_bbid = [rel['target_bbid'] for rel in author['rels']] + literary_work_bbid = [] + for rel in author['rels']: + if rel['relationship_type_id'] == AUTHOR_WORK_AUTHOR_REL_ID: + literary_work_bbid.append(rel['target_bbid']) else: literary_work_bbid = [] literary_works = bb_literary_work.fetch_multiple_literary_works(literary_work_bbid, literary_work_type) - try: reviews_limit = int(request.args.get('limit', default=AUTHOR_REVIEWS_LIMIT)) except ValueError: diff --git a/critiquebrainz/frontend/views/bb_literary_work.py b/critiquebrainz/frontend/views/bb_literary_work.py index 4e3ec937a..0aefd2c42 100644 --- a/critiquebrainz/frontend/views/bb_literary_work.py +++ b/critiquebrainz/frontend/views/bb_literary_work.py @@ -5,6 +5,7 @@ import critiquebrainz.db.review as db_review import critiquebrainz.frontend.external.bookbrainz_db.literary_work as bb_literary_work import critiquebrainz.frontend.external.bookbrainz_db.edition_group as bb_edition_group +from critiquebrainz.frontend.external.bookbrainz_db.relationships import WORK_WORK_TRANSLATION_REL_ID import critiquebrainz.frontend.external.bookbrainz_db.redirects as bb_redirects from critiquebrainz.frontend.forms.rate import RatingEditForm from critiquebrainz.frontend.views import get_avg_rating, LITERARY_WORK_REVIEWS_LIMIT, BROWSE_LITERARY_WORK_LIMIT @@ -91,7 +92,11 @@ def entity(id): return redirect(url_for('bb_literary_work.entity', id=id)) if literary_work['rels']: - work_rels_bbid = [rel['source_bbid'] for rel in literary_work['rels']] + work_rels_bbid = [] + for rel in literary_work['rels']: + if rel['relationship_type_id'] == WORK_WORK_TRANSLATION_REL_ID: + work_rels_bbid.append(rel['source_bbid']) + work_rels_count = len(work_rels_bbid) work_rels_info = bb_literary_work.fetch_multiple_literary_works( bbids=work_rels_bbid, diff --git a/critiquebrainz/frontend/views/bb_series.py b/critiquebrainz/frontend/views/bb_series.py index 536f80851..d190dc851 100644 --- a/critiquebrainz/frontend/views/bb_series.py +++ b/critiquebrainz/frontend/views/bb_series.py @@ -54,14 +54,28 @@ def entity(id): rating_form = RatingEditForm(entity_id=id, entity_type='bb_series') rating_form.rating.data = my_review['rating'] if my_review else None - rels_bbid = [rel['source_bbid'] for rel in series['rels']] + rels_bbid = [] + rels_order_number = [] + for rel in series['rels']: + rels_bbid.append(rel['source_bbid']) + if 'number' in rel['attributes']: + rels_order_number.append(rel['attributes']['number']) + else: + rels_order_number.append(None) + series_rels_info = bb_series.fetch_series_rels_info(series['series_type'], rels_bbid) - series_rels_info = series_rels_info.values() + + series_items = [] + for index, bbid in enumerate(rels_bbid): + item = series_rels_info[bbid] + number = rels_order_number[index] + item['number'] = number + series_items.append(item) return render_template('bb_series/entity.html', id=series['bbid'], series=series, - series_rels_info=series_rels_info, + series_rels_info=series_items, reviews=reviews, my_review=my_review, count=count,