Repository: beetbox/beets

Issue:
Extending REIMPORT_FRESH_FIELDS from plugins
@JOJ0 looks like there are still some issues with reimports. 

I am reimporting with [youtube](https://github.com/arsaboo/beets-youtube) and here are the relevant logs:

```
Reimported album 1. Preserving attribute ['added']. Path: /home/arsaboo/shared/music/Tu Jhoothi Main Makkaar (2023)
Reimported album 1. Preserving flexible attributes ['data_source']. Path: /home/arsaboo/shared/music/Tu Jhoothi Main Makkaar (2023)
Reimported item 1. Preserving attribute ['added']. Path: /home/arsaboo/shared/music/Tu Jhoothi Main Makkaar (2023)/Tu Jhoothi Main Makkaar (2023) - Jaadui.mp3
Reimported item 1. Preserving flexible attributes ['data_source', 'yt_album_id', 'yt_artist_id', 'yt_track_id', 'track_alt', 'cover_art_url', 'yt_updated', 'yt_views', 'spotify_album_id', 'spotify_artist_id', 'spotify_track_id', 'jiosaavn_album_id', 'jiosaavn_artist_id', 'jiosaavn_perma_url', 'jiosaavn_track_id', 'jiosaavn_updated', 'danceability', 'beats_count', 'average_loudness', 'danceable', 'gender', 'is_male', 'is_female', 'genre_rosamerica', 'voice_instrumental', 'is_voice', 'is_instrumental', 'mood_acoustic', 'mood_aggressive', 'mood_electronic', 'mood_happy', 'mood_sad', 'mood_party', 'mood_relaxed', 'mood_mirex', 'mood_mirex_cluster_1', 'mood_mirex_cluster_2', 'mood_mirex_cluster_3', 'mood_mirex_cluster_4', 'mood_mirex_cluster_5', 'spotify_track_popularity', 'spotify_danceability', 'spotify_energy', 'spotify_key', 'spotify_loudness', 'spotify_mode', 'spotify_speechiness', 'spotify_acousticness', 'spotify_instrumentalness', 'spotify_liveness', 'spotify_valence', 'spotify_tempo', 'spotify_time_signature', 'spotify_updated']. Path: /home/arsaboo/shared/music/Tu Jhoothi Main Makkaar (2023)/Tu Jhoothi Main Makkaar (2023) - Jaadui.mp3
Sending event: database_change
```

Some of the `yt_*` fields should not be preserved. Specially, `yt_album_id`, `yt_artist_id`, `yt_track_id`, `yt_updated`, `yt_views`, and (maybe even) `cover_art_url`. As a default, `cover_art_url` should be overwritten on reimport (plugins can add a config option to prevent overwriting `cover_art_url`).



Discussion:
Hmm I'd say this is a feature request. yt we could add to the REIMPORT_FRESH_... module level constants (importer.py). Not sure about cover_art_url. Will think about it but sounds like it would make sense too.
Sorry for being brief yesterday. Please add to these lists: https://github.com/beetbox/beets/blob/8fc3ddee2702d0612c5340700f876d78c3e06bbc/beets/importer.py#L53
Is this something a plugin can modify or will it require changes to the beets repo? 

As an approach, shouldn't reimports overwrite plugin-specific information?
not sure. for now requires edit of beets repo.
Looks tricky! The obvious solution here would be to introduce a new plugin hook to register these non-preserved fields. That would be a little clunky to use, but it would work. I wonder if there is some more elegant way to approach this, such as somehow using a special prefix on the field name…
This will definitely have to be resolved. I am seeing this with another (Tidal) plugin:

```bash
Reimported item 144. Preserving attribute ['added']. Path: /home/arsaboo/shared/music/XYZ (2021)/XYZ (2021) - Thode Kam Ajnabi.mp3
Reimported item 144. Preserving flexible attributes ['data_source', 'tidal_album_id', 'tidal_artist_id', 'tidal_alb_popularity', 'tidal_track_popularity', 'explicit', 'cover_art_url', 'tidal_updated', 'tidal_track_id', 'jiosaavn_album_id', 'jiosaavn_artist_id', 'jiosaavn_perma_url', 'jiosaavn_track_id', 'jiosaavn_updated', 'plex_guid', 'plex_ratingkey', 'plex_userrating', 'plex_skipcount', 'plex_viewcount', 'plex_lastviewedat', 'plex_lastratedat', 'plex_updated', 'spotify_updated']. Path: /home/arsaboo/shared/music/XYZ (2021)/XYZ (2021) - Thode Kam Ajnabi.mp3
```
I would even raise this issue to a critical level. 
> Please add to these lists:
> 
> https://github.com/beetbox/beets/blob/8fc3ddee2702d0612c5340700f876d78c3e06bbc/beets/importer.py#L53

@JOJ0 can we make this list configurable?
Actually, I am trying to now recall why should any field be preserved on reimport. 

Any plugin should be able to rewrite their respective fields. The only restriction should be preventing cross-plugin writes, i.e., the Spotify plugin should not overwrite MusicBrainz fields. 
> Looks tricky! The obvious solution here would be to introduce a new plugin hook to register these non-preserved fields. That would be a little clunky to use, but it would work. I wonder if there is some more elegant way to approach this, such as somehow using a special prefix on the field name…

This approach works. I just added the following function to my `tidal` plugin and it works:
```python
def extend_reimport_fresh_fields_item():
    """Extend the REIMPORT_FRESH_FIELDS_ITEM list from a plugin."""
    importer.REIMPORT_FRESH_FIELDS_ITEM.extend([
        'tidal_album_id', 'tidal_track_id', 'tidal_artist_id',
        'tidal_track_popularity', 'tidal_alb_popularity',
        'tidal_updated'])
```
Here are the logs now:

```bash
Reimported item 144. Preserving attribute ['added']. Path: /home/arsaboo/shared/music/XYZ (2021)/XYZ (2021) - Thode Kam Ajnabi.mp3
Reimported item 144. Not preserving flexible attributes ['tidal_updated', 'tidal_track_id']. Path: /home/arsaboo/shared/music/Pagglait (2021)/Pagglait (2021) - Thode Kam Ajnabi.mp3
Reimported item 144. Preserving flexible attributes ['data_source', 'tidal_album_id', 'tidal_artist_id', 'tidal_alb_popularity', 'tidal_track_popularity', 'explicit', 'cover_art_url', 'jiosaavn_album_id', 'jiosaavn_artist_id', 'jiosaavn_perma_url', 'jiosaavn_track_id', 'jiosaavn_updated', 'plex_guid', 'plex_ratingkey', 'plex_userrating', 'plex_skipcount', 'plex_viewcount', 'plex_lastviewedat', 'plex_lastratedat', 'plex_updated', 'spotify_updated']. Path: /home/arsaboo/shared/music/XYZ (2021)/XYZ (2021) - Thode Kam Ajnabi.mp3
```

Notice the new line: `Not preserving flexible attributes ['tidal_updated', 'tidal_track_id']`
Actually I think this approach is quite elegant already, at least for my taste. Thanks for the efforts @arsaboo  How could we make sure that knowledge is not buried in this thread? Maybe add a new chapter to the developer's docs? 

Or maybe bring in this feature into one source plugin that comes boxed with beets in a PR? 

I wanted to suggest Spotify but then realized that there is a reason it has to be in the core code haha :-)
Thanks @JOJ0. How about we update the comment here to add that information and maybe even update the spotify code to add an example?
https://github.com/beetbox/beets/blob/8fc3ddee2702d0612c5340700f876d78c3e06bbc/beets/importer.py#L53
> Thanks @JOJ0. How about we update the comment here to add that information and maybe even update the spotify code to add an example?
> 
> https://github.com/beetbox/beets/blob/8fc3ddee2702d0612c5340700f876d78c3e06bbc/beets/importer.py#L53

Yeah good idea to elaborate on that comment!

Dont forget that spotify_album_id can be updated from MusicBrainz and needs to stay in this list even though someone hasnt activated spotify plug.

Resolving patch:
diff --git a/beets/importer.py b/beets/importer.py
--- a/beets/importer.py
+++ b/beets/importer.py
@@ -50,7 +50,15 @@
 SINGLE_ARTIST_THRESH = 0.25
 PROGRESS_KEY = 'tagprogress'
 HISTORY_KEY = 'taghistory'
-# Album and item flexble attrbutes that should not be preserved on reimports.
+# Usually flexible attributes are preserved (i.e., not updated) during
+# reimports. The following two lists (globally) change this behaviour for
+# certain fields. To alter these lists only when a specific plugin is in use,
+# something like this can be used within that plugin's code:
+#
+# from beets import importer
+# def extend_reimport_fresh_fields_item():
+#     importer.REIMPORT_FRESH_FIELDS_ITEM.extend(['tidal_track_popularity']
+# )
 REIMPORT_FRESH_FIELDS_ALBUM = ['data_source']
 REIMPORT_FRESH_FIELDS_ITEM = ['data_source', 'bandcamp_album_id',
                               'spotify_album_id', 'deezer_album_id',


Test patch: