"""Add a new record to the database."""
assert item.provider_mappings, "Item is missing provider mapping(s)"
assert item.artists, f"Album {item.name} is missing artists"
- async with self._db_add_lock:
- cur_item = None
- # always try to grab existing item by musicbrainz_id
- if item.musicbrainz_id:
- match = {"musicbrainz_id": item.musicbrainz_id}
- cur_item = await self.mass.music.database.get_row(self.db_table, match)
- # try barcode/upc
- if not cur_item and item.barcode:
- for barcode in item.barcode:
- if search_result := await self.mass.music.database.search(
- self.db_table, barcode, "barcode"
- ):
- cur_item = Album.from_db_row(search_result[0])
- break
- if not cur_item:
- # fallback to search and match
- for row in await self.mass.music.database.search(self.db_table, item.name):
- row_album = Album.from_db_row(row)
- if compare_album(row_album, item):
- cur_item = row_album
- break
- if cur_item:
- # update existing
- return await self._update_db_item(cur_item.item_id, item)
+ cur_item = None
+ # always try to grab existing item by musicbrainz_id
+ if item.musicbrainz_id:
+ match = {"musicbrainz_id": item.musicbrainz_id}
+ cur_item = await self.mass.music.database.get_row(self.db_table, match)
+ # try barcode/upc
+ if not cur_item and item.barcode:
+ for barcode in item.barcode:
+ if search_result := await self.mass.music.database.search(
+ self.db_table, barcode, "barcode"
+ ):
+ cur_item = Album.from_db_row(search_result[0])
+ break
+ if not cur_item:
+ # fallback to search and match
+ for row in await self.mass.music.database.search(self.db_table, item.name):
+ row_album = Album.from_db_row(row)
+ if compare_album(row_album, item):
+ cur_item = row_album
+ break
+ if cur_item:
+ # update existing
+ return await self._update_db_item(cur_item.item_id, item)
- # insert new item
- album_artists = await self._get_artist_mappings(item, cur_item)
- sort_artist = album_artists[0].sort_name if album_artists else ""
+ # insert new item
+ album_artists = await self._get_artist_mappings(item, cur_item)
+ sort_artist = album_artists[0].sort_name if album_artists else ""
+ async with self._db_add_lock:
new_item = await self.mass.music.database.insert(
self.db_table,
{
},
)
item_id = new_item["item_id"]
- # update/set provider_mappings table
- await self._set_provider_mappings(item_id, item.provider_mappings)
- self.logger.debug("added %s to database", item.name)
- # return created object
- return await self.get_db_item(item_id)
+ # update/set provider_mappings table
+ await self._set_provider_mappings(item_id, item.provider_mappings)
+ self.logger.debug("added %s to database", item.name)
+ # return created object
+ return await self.get_db_item(item_id)
async def _update_db_item(
self, item_id: int, item: Album | ItemMapping, overwrite: bool = False
if item.musicbrainz_id == VARIOUS_ARTISTS_ID:
item.name = VARIOUS_ARTISTS
- async with self._db_add_lock:
- # always try to grab existing item by musicbrainz_id
- cur_item = None
- if musicbrainz_id := getattr(item, "musicbrainz_id", None):
- match = {"musicbrainz_id": musicbrainz_id}
- cur_item = await self.mass.music.database.get_row(self.db_table, match)
- if not cur_item:
- # fallback to exact name match
- # NOTE: we match an artist by name which could theoretically lead to collisions
- # but the chance is so small it is not worth the additional overhead of grabbing
- # the musicbrainz id upfront
- match = {"sort_name": item.sort_name}
- for row in await self.mass.music.database.get_rows(self.db_table, match):
- row_artist = Artist.from_db_row(row)
- if row_artist.sort_name == item.sort_name:
- cur_item = row_artist
- break
- if cur_item:
- # update existing
- return await self._update_db_item(cur_item.item_id, item)
+ # always try to grab existing item by musicbrainz_id
+ cur_item = None
+ if musicbrainz_id := getattr(item, "musicbrainz_id", None):
+ match = {"musicbrainz_id": musicbrainz_id}
+ cur_item = await self.mass.music.database.get_row(self.db_table, match)
+ if not cur_item:
+ # fallback to exact name match
+ # NOTE: we match an artist by name which could theoretically lead to collisions
+ # but the chance is so small it is not worth the additional overhead of grabbing
+ # the musicbrainz id upfront
+ match = {"sort_name": item.sort_name}
+ for row in await self.mass.music.database.get_rows(self.db_table, match):
+ row_artist = Artist.from_db_row(row)
+ if row_artist.sort_name == item.sort_name:
+ cur_item = row_artist
+ break
+ if cur_item:
+ # update existing
+ return await self._update_db_item(cur_item.item_id, item)
- # insert item
- item.timestamp_added = int(utc_timestamp())
- item.timestamp_modified = int(utc_timestamp())
- # edge case: item is an ItemMapping,
- # try to construct (a half baken) Artist object from it
- if isinstance(item, ItemMapping):
- item = Artist.from_dict(item.to_dict())
+ # insert item
+ item.timestamp_added = int(utc_timestamp())
+ item.timestamp_modified = int(utc_timestamp())
+ # edge case: item is an ItemMapping,
+ # try to construct (a half baken) Artist object from it
+ if isinstance(item, ItemMapping):
+ item = Artist.from_dict(item.to_dict())
+ async with self._db_add_lock:
new_item = await self.mass.music.database.insert(self.db_table, item.to_db_row())
item_id = new_item["item_id"]
- # update/set provider_mappings table
- await self._set_provider_mappings(item_id, item.provider_mappings)
- self.logger.debug("added %s to database", item.name)
- # return created object
- return await self.get_db_item(item_id)
+ # update/set provider_mappings table
+ await self._set_provider_mappings(item_id, item.provider_mappings)
+ self.logger.debug("added %s to database", item.name)
+ # return created object
+ return await self.get_db_item(item_id)
async def _update_db_item(
self, item_id: int, item: Artist | ItemMapping, overwrite: bool = False
async def _add_db_item(self, item: Playlist) -> Playlist:
"""Add a new record to the database."""
assert item.provider_mappings, "Item is missing provider mapping(s)"
+ match = {"name": item.name, "owner": item.owner}
+ if cur_item := await self.mass.music.database.get_row(self.db_table, match):
+ # update existing
+ return await self._update_db_item(cur_item["item_id"], item)
+ # insert new item
+ item.timestamp_added = int(utc_timestamp())
+ item.timestamp_modified = int(utc_timestamp())
async with self._db_add_lock:
- match = {"name": item.name, "owner": item.owner}
- if cur_item := await self.mass.music.database.get_row(self.db_table, match):
- # update existing
- return await self._update_db_item(cur_item["item_id"], item)
- # insert new item
- item.timestamp_added = int(utc_timestamp())
- item.timestamp_modified = int(utc_timestamp())
new_item = await self.mass.music.database.insert(self.db_table, item.to_db_row())
item_id = new_item["item_id"]
- # update/set provider_mappings table
- await self._set_provider_mappings(item_id, item.provider_mappings)
- self.logger.debug("added %s to database", item.name)
- # return created object
- return await self.get_db_item(item_id)
+ # update/set provider_mappings table
+ await self._set_provider_mappings(item_id, item.provider_mappings)
+ self.logger.debug("added %s to database", item.name)
+ # return created object
+ return await self.get_db_item(item_id)
async def _update_db_item(
self, item_id: int, item: Playlist, overwrite: bool = True
async def _add_db_item(self, item: Radio) -> Radio:
"""Add a new item record to the database."""
assert item.provider_mappings, "Item is missing provider mapping(s)"
+ match = {"name": item.name}
+ if cur_item := await self.mass.music.database.get_row(self.db_table, match):
+ # update existing
+ return await self._update_db_item(cur_item["item_id"], item)
+ # insert new item
+ item.timestamp_added = int(utc_timestamp())
+ item.timestamp_modified = int(utc_timestamp())
async with self._db_add_lock:
- match = {"name": item.name}
- if cur_item := await self.mass.music.database.get_row(self.db_table, match):
- # update existing
- return await self._update_db_item(cur_item["item_id"], item)
- # insert new item
- item.timestamp_added = int(utc_timestamp())
- item.timestamp_modified = int(utc_timestamp())
new_item = await self.mass.music.database.insert(self.db_table, item.to_db_row())
item_id = new_item["item_id"]
- # update/set provider_mappings table
- await self._set_provider_mappings(item_id, item.provider_mappings)
- self.logger.debug("added %s to database", item.name)
- # return created object
- return await self.get_db_item(item_id)
+ # update/set provider_mappings table
+ await self._set_provider_mappings(item_id, item.provider_mappings)
+ self.logger.debug("added %s to database", item.name)
+ # return created object
+ return await self.get_db_item(item_id)
async def _update_db_item(self, item_id: int, item: Radio, overwrite: bool = True) -> Radio:
"""Update Radio record in the database."""
assert isinstance(item, Track), "Not a full Track object"
assert item.artists, "Track is missing artist(s)"
assert item.provider_mappings, "Track is missing provider mapping(s)"
- async with self._db_add_lock:
- cur_item = None
+ cur_item = None
- # always try to grab existing item by external_id
- if item.musicbrainz_id:
- match = {"musicbrainz_id": item.musicbrainz_id}
- cur_item = await self.mass.music.database.get_row(self.db_table, match)
- for isrc in item.isrc:
- if search_result := await self.mass.music.database.search(
- self.db_table, isrc, "isrc"
- ):
- cur_item = Track.from_db_row(search_result[0])
+ # always try to grab existing item by external_id
+ if item.musicbrainz_id:
+ match = {"musicbrainz_id": item.musicbrainz_id}
+ cur_item = await self.mass.music.database.get_row(self.db_table, match)
+ for isrc in item.isrc:
+ if search_result := await self.mass.music.database.search(self.db_table, isrc, "isrc"):
+ cur_item = Track.from_db_row(search_result[0])
+ break
+ if not cur_item:
+ # fallback to matching
+ match = {"sort_name": item.sort_name}
+ for row in await self.mass.music.database.get_rows(self.db_table, match):
+ row_track = Track.from_db_row(row)
+ if compare_track(row_track, item):
+ cur_item = row_track
break
- if not cur_item:
- # fallback to matching
- match = {"sort_name": item.sort_name}
- for row in await self.mass.music.database.get_rows(self.db_table, match):
- row_track = Track.from_db_row(row)
- if compare_track(row_track, item):
- cur_item = row_track
- break
- if cur_item:
- # update existing
- return await self._update_db_item(cur_item.item_id, item)
+ if cur_item:
+ # update existing
+ return await self._update_db_item(cur_item.item_id, item)
- # no existing match found: insert new item
- track_artists = await self._get_artist_mappings(item)
- track_albums = await self._get_track_albums(item)
- sort_artist = track_artists[0].sort_name if track_artists else ""
- sort_album = track_albums[0].sort_name if track_albums else ""
+ # no existing match found: insert new item
+ track_artists = await self._get_artist_mappings(item)
+ track_albums = await self._get_track_albums(item)
+ sort_artist = track_artists[0].sort_name if track_artists else ""
+ sort_album = track_albums[0].sort_name if track_albums else ""
+ async with self._db_add_lock:
new_item = await self.mass.music.database.insert(
self.db_table,
{
},
)
item_id = new_item["item_id"]
- # update/set provider_mappings table
- await self._set_provider_mappings(item_id, item.provider_mappings)
- # return created object
- self.logger.debug("added %s to database: %s", item.name, item_id)
- return await self.get_db_item(item_id)
+ # update/set provider_mappings table
+ await self._set_provider_mappings(item_id, item.provider_mappings)
+ # return created object
+ self.logger.debug("added %s to database: %s", item.name, item_id)
+ return await self.get_db_item(item_id)
async def _update_db_item(
self, item_id: int, item: Track | ItemMapping, overwrite: bool = False