JakeWharton / JakeWharton/plex-orphaned-files

Detecting but not showing the orphans.. I think

Open
#14 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Kotlin
Stars
123
Forks
6
Avg merge
1h 52m
Merged PRs (30d)
18

Description

At first I wasn't sure anything was happening, I had to do quite a bit of troubleshooting just to figure out what was intended and how to debug (you really should include debug instructions for such a new project, I had to dig through code to figure out how to enable debug mode :()

I had a lot of trouble with this tool mostly due to its lack of feedback on what's happening. So my first run I got this:
```
root@Nexus:~# docker run jakewharton/plex-orphaned-files:1 \
--token --base-url http://172.17.0.3:32400

MoviesException in thread "main" java.nio.file.NoSuchFileException: /media/homemovies
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileAttributeViews$Basic.readAttributes(UnixFileAttributeViews.java:55)
at sun.nio.fs.UnixFileSystemProvider.readAttributes(UnixFileSystemProvider.java:144)
at sun.nio.fs.LinuxFileSystemProvider.readAttributes(LinuxFileSystemProvider.java:99)
at java.nio.file.Files.readAttributes(Files.java:1737)
at java.nio.file.FileTreeWalker.getAttributes(FileTreeWalker.java:219)
at java.nio.file.FileTreeWalker.visit(FileTreeWalker.java:276)
at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:322)
at java.nio.file.FileTreeIterator.(FileTreeIterator.java:72)
at java.nio.file.Files.walk(Files.java:3574)
at java.nio.file.Files.walk(Files.java:3625)
at com.jakewharton.plex.OrphanedFiles.find(orphanedFiles.kt:50)
at com.jakewharton.plex.OrphanedFiles$find$1.invokeSuspend(orphanedFiles.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:84)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at com.jakewharton.plex.OrphanedFilesCommand.run(main.kt:109)
at com.github.ajalt.clikt.parsers.Parser.parse(Parser.kt:171)
at com.github.ajalt.clikt.parsers.Parser.parse(Parser.kt:16)
at com.github.ajalt.clikt.core.CliktCommand.parse(CliktCommand.kt:395)
at com.github.ajalt.clikt.core.CliktCommand.parse$default(CliktCommand.kt:392)
at com.github.ajalt.clikt.core.CliktCommand.main(CliktCommand.kt:410)
at com.github.ajalt.clikt.core.CliktCommand.main(CliktCommand.kt:435)
at com.jakewharton.plex.Main.main(main.kt:125)
```

Ok, maybe the file mapping needs to be done, after all my Plex server is also running in a docker container on this host:

```
root@Nexus:~# docker run jakewharton/plex-orphaned-files:1 \
--token --base-url http://172.17.0.3:32400 \
--folder-mapping /media:/mnt/user/Media

MoviesException in thread "main" java.nio.file.NoSuchFileException: /media/homemovies
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileAttributeViews$Basic.readAttributes(UnixFileAttributeViews.java:55)
at sun.nio.fs.UnixFileSystemProvider.readAttributes(UnixFileSystemProvider.java:144)
at sun.nio.fs.LinuxFileSystemProvider.readAttributes(LinuxFileSystemProvider.java:99)
at java.nio.file.Files.readAttributes(Files.java:1737)
at java.nio.file.FileTreeWalker.getAttributes(FileTreeWalker.java:219)
at java.nio.file.FileTreeWalker.visit(FileTreeWalker.java:276)
at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:322)
at java.nio.file.FileTreeIterator.(FileTreeIterator.java:72)
at java.nio.file.Files.walk(Files.java:3574)
at java.nio.file.Files.walk(Files.java:3625)
at com.jakewharton.plex.OrphanedFiles.find(orphanedFiles.kt:50)
at com.jakewharton.plex.OrphanedFiles$find$1.invokeSuspend(orphanedFiles.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:84)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at com.jakewharton.plex.OrphanedFilesCommand.run(main.kt:109)
at com.github.ajalt.clikt.parsers.Parser.parse(Parser.kt:171)
at com.github.ajalt.clikt.parsers.Parser.parse(Parser.kt:16)
at com.github.ajalt.clikt.core.CliktCommand.parse(CliktCommand.kt:395)
at com.github.ajalt.clikt.core.CliktCommand.parse$default(CliktCommand.kt:392)
at com.github.ajalt.clikt.core.CliktCommand.main(CliktCommand.kt:410)
at com.github.ajalt.clikt.core.CliktCommand.main(CliktCommand.kt:435)
at com.jakewharton.plex.Main.main(main.kt:125)
```

Same result. Then I thought maybe docker needs to actually mount the local filesystem same as the Plex container so I went off road from your instructions and added a volume mount:

```
root@Nexus:~# docker run -v /media:/mnt/user/Media/ jakewharton/plex-orphaned-files:1 \
--token --base-url http://172.17.0.3:32400

Movies: /media/homemovies
```

And alas, success, or so I thought. On second glance I realized I wasn't sure if this was actually a success or not, after all it didn't say "no orphans" it just spit out the library name and it's path with nothing else. Since I started using this tool because I knew for a fact there was at least 1 file that wasn't indexing I thought something must be going on so I dug deeper. Without any kind of verbose mode or help output I was forced to start digging through the code to see if I could brain-compile the execution path and figure out what was going on. Having never seen kotlin before It was a bit of a challenge but I eventually found the HIDDEN debug option so I passed it and hoped it worked:

```
root@Nexus:~# docker run -v /media:/mnt/user/Media jakewharton/plex-orphaned-files:1 \
--token --base-url http://172.17.0.3:32400 --debug
Checking Movies...
Found 1 orphan(s)
Movies: /media/homemovies
```

Ah ha! Some additional output! But It seems as though it gave me more questions than answers. So it found an orphan? What was it? Where? No dice. I doubted that there was only 1 orphan but I'd have to tackle one problem at a time, let's find this one first. I re-read the Readme and best I could figure was that when an orphan is detected it should list the library and the file next to it ( `Library: /path/to/orphan.mp4`). I didn't see that. Unless it was telling me the whole directory was missing? But if that's the case that's a really weird way to say it. After all I got 2 long stack traces before when the directory didn't exist so I didn't think that was likely (why error before but show this output now if it's the same issue?)

Without any further recourse I went back to the code and continued scanning. I noticed in your http library you allow for multiple debug modes with multiple output verbosities and even though I have _never_ see the "use multiple --debug flags for additional debugging" (granted I'm not a java or kotlin dev so I might just be ignorant 🤷 ), I went with it and had some more success:

```
root@Nexus:~# docker run -v /media:/mnt/user/Media jakewharton/plex-orphaned-files:1 \
--token --base-url http://172.17.0.3:32400 --debug --debug

--> GET http://172.17.0.3:32400/library/sections?X-Plex-Token= http/1.1
<-- 200 OK http://172.17.0.3:32400/library/sections?X-Plex-Token= (9ms, 456-byte body)
Checking Movies...
--> GET http://172.17.0.3:32400/library/sections/4/all?X-Plex-Token= http/1.1
<-- 200 OK http://172.17.0.3:32400/library/sections/4/all?X-Plex-Token= (1018ms, 643650-byte body)
Found 1 orphan(s)
Movies: /media/homemovies
```

Ok, so I've go some http logging output, not helpful but maybe getting there. I then went for the coup-de-grace of THREE debug flags just for shits and giggles. I can't post that output because it's literally 4.5MB of text:
`-rw-rw-rw- 1 root root 4.5M May 9 10:30 logfile.txt`.

Looking at that file I can see it includes the entirety of the json output for my library. And the fact that I have 4000 video files in the library I suspect that json is gonna be pretty huge. Is this perhaps the reason it fails? It simply runs out of memory and pukes? Why no error message then? Very confusing.

I only post this here because I've run out of paths to debug externally and I feel I've done enough as a user to pass it on to the dev for further investigation.

In case it helps I'm running this on Unraid which is a linux NAS distribution 👍

Contributor guide

No contributing guide indexed for this repository

Research direction

Reproduce the Docker invocation and start with com.jakewharton.plex.OrphanedFiles.find in orphanedFiles.kt:50, then follow OrphanedFilesCommand.run in main.kt:109 and the README's output expectations. Check how missing paths, detected orphans, and debug output are reported; done means the command clearly identifies the orphan or failure and provides useful feedback without requiring hidden debug flags.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, kotlin
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.