airsonic-advanced / airsonic-advanced

GNU General Public License v3.0
1.25k stars 132 forks source link

Can't update podcast folder #790

Open Dikakus opened 2 years ago

Dikakus commented 2 years ago

Problem description

I want to change podcast folder from configuration menu, but I can't and log throws an exeception.

Steps to reproduce

  1. Go to configuration/folder media:

image

  1. Change podcast folder from /media/Euterpe/pi/Podcast to /media/Euterpe/Podcast and click on Save.

image

  1. Page reloads and the podcast folder remains the same. The log shows:
java.lang.IllegalArgumentException: Music folder with path /media/Euterpe/Podcast overlaps with existing music folder path(s) (SAME: [], ANCESTOR: [Euterpe], DESCENDANT: []) and can therefore not be updated.
    at org.airsonic.player.service.MediaFolderService.updateMusicFolder(MediaFolderService.java:133) ~[classes!/:11.0.0-SNAPSHOT]
    at org.airsonic.player.controller.MusicFolderSettingsController.onSubmit(MusicFolderSettingsController.java:160) ~[classes!/:11.0.0-SNAPSHOT]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
[...]
  1. Trying other folders with same results.

NOTE: Podcast folder exits in the path:

pi@raspberrypi:/var/airsonic $ ls -d /media/Euterpe/Podcast/
drwxrwxrwx 3 airsonic airsonic 4,0K 2021-07-22 11:01 /media/Euterpe/Podcast/

System information

randomnicode commented 2 years ago

Hi @Dikakus this issue is the effect of a deliberate design decision we made for relative paths. You can read some of the commentary and discussion in the PR (#659).

Let's first try examining what the system is doing, then expanding on why this restriction exists, and eliciting feedback for what ought to be done.

To mitigate the above scenarios, the following restrictions are placed:

As an example, let's take a scenario where the following hierarchy exists: /Music /Music/1.mp3 /Music/vi /Music/vi/Pod /Music/vi/Pod/P1 /Music/vi/Pod/P2 /Music/vi2 /Music/vi2/Pod2 /Music/vi2/Pod2/P3

And 2 folders exist in the system F1: /Music F2: /Music/vi/Pod

After a scan, these media files will exist: [F1, ''] <-- F1 root [F1, 1.mp3] [F1, vi] [F1, vi2] [F1, vi2/Pod2] [F1, vi2/Pod2/P3] [F2, ''] <--F2 root [F2, P1] [F2, P2]

Lets say we want to move /Music/vi/Pod to /Music/Pod We move over the folder on disk, after the scan the following media files exist in the DB [F1, ''] <-- F1 root [F1, 1.mp3] [F1, Pod] <-- New add [F1, Pod/P1] <-- New add [F1, Pod/P2] <--New add [F1, vi] [F1, vi2] [F1, vi2/Pod2] [F1, vi2/Pod2/P3] [F2, ''] <--F2 root [F2, P1] <-- X (doesn't exist) [F2, P2] <-- X (doesn't exist)

Now we edit F2 to point to /Music/Pod.

If we just edit and change the folder path, the issue is that multiple media files now point to the same file on disc: [F2, P1] points to /Music/Pod/P1 [F1, Pod/P1] also points to /Music/Pod/P1 Same for P2

This is bad, the same file can be referenced in the DB in multiple ways which is something we're trying to avoid.

So let's try and merge two, like we would if we added a new folder. Let's assign all the stuff that is under the F1 that might now belong to F2 to F2. [F1, Pod/P1] -> [F2, P1] This is an issue because [F2, P1] already exists. There is a uniqueness constraint.

The reason this works with adding new folder is because a new folder does not have existing files in the DB and therefore can be assigned files from the parent without any conflicts.

The fundamental difference between removing and adding a new folder, and just modifying an existing folder is that the former creates new files/new entries, whereas the latter carries over the existing entries and thus has potential for conflicts when merging files from the parent. Therefore we need to restrict the latter in terms of what you can edit it to.

None of this solves your problem. The point is feedback. What do you should we should do? A solution is to allow adding new PODCAST folders, but only have one active. When you add a new PODCAST folder, you would lose the statistics for the files under the old PODCAST folder

Dikakus commented 2 years ago

Hi @randomnicode. First, sorry for the dalay to reply and thank you for your great explanation. I undesrtood, there can't be two files referred twice.

I've tried to aply your solution: Disable the current podcast folder and add a new folder, but I think something went wrong. Maybe I'm a little bit clumsy. Now I have 2 podcast folder:

image

And when I try to remove the new folder, a exception is thrown:

2022-02-07 16:58:30.098 ERROR --- o.a.p.s.LoggingExceptionResolver         : 127.0.0.1: An exception occurred while loading http://127.0.0.1:8085/airso>
2777
2778 java.lang.NullPointerException: null
2779         at org.airsonic.player.service.MediaFolderService.getMusicFolderPathOverlaps(MediaFolderService.java:148) ~[classes!/:11.0.0-SNAPSHOT]
2780         at org.airsonic.player.service.MediaFolderService.deleteMusicFolder(MediaFolderService.java:117) ~[classes!/:11.0.0-SNAPSHOT]
2781         at org.airsonic.player.controller.MusicFolderSettingsController.onSubmit(MusicFolderSettingsController.java:155) ~[classes!/:11.0.0-SNAPSHOT]
2782         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
2783         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
2784         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
2785         at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]

Moreover, there isn't a checkbox to delete the older podcast folder (a red message "Not folder found" is displayed). So I think I'm trapped. :(

randomnicode commented 2 years ago

@Dikakus is this issue resolved now?

Dikakus commented 2 years ago

Hi @randomnicode. Thank you for your attention!

I'm running 11.0.0-SNAPSHOT.20220222093559 – 2022/02/22. I added a new podcast folder and it seems goes ok. The second one is enabled, so I tried to remove the first one:

Caused by: org.hsqldb.HsqlException: violación del restricción de integridad: violación de índice o clave única: IDX_MEDIA_FILE_FOLDER_PATH
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.index.IndexAVL.insert(Unknown Source)
    at org.hsqldb.persist.RowStoreAVL.indexRow(Unknown Source)
    at org.hsqldb.TransactionManagerMVCC.addInsertAction(Unknown Source)
    at org.hsqldb.Session.addInsertAction(Unknown Source)
    at org.hsqldb.Table.insertSingleRow(Unknown Source)
    at org.hsqldb.StatementDML.update(Unknown Source)
    at org.hsqldb.StatementDML.executeUpdateStatement(Unknown Source)
    at org.hsqldb.StatementDML.getResult(Unknown Source)
    at org.hsqldb.StatementDMQL.execute(Unknown Source)
    at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
    at org.hsqldb.Session.execute(Unknown Source)
    ... 156 more

I don't know if it is right, but I still have 2 podcast folders.

randomnicode commented 2 years ago

Ah, we think your db is in an inconsistent state. What likely happened was that a parent folder likely already has files that the child folder you're trying to delete does.

When a folder gets deleted, it assigns its children to its ancestors (unless no ancestor folders are present). But if an ancestor folder also has those children, the child cannot assign its contents to the parent and the db is in an inconsistent state. This would not normally happen, but you caught the bug at an awkward time before it was discovered.

your options are: delete manually things from your db or start anew with a new db