Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(playlists): POST endpoint for importing m3u playlists - #2078 #2273

Merged
merged 15 commits into from
Nov 1, 2023

Conversation

spwats
Copy link
Contributor

@spwats spwats commented Mar 22, 2023

Closes 2078

Description:
adds an HTTP post endpoint at api/playlist for uploading m3u playlists

Changes:

  • Route POST requests to api/playlist based on content-type. Requests with audio-xmpegurl content type are parsed as a m3u playlist and imported.
  • Minor refactor to core playlist parsing logic and interface to support parsing m3u playlists from an io.Reader. Previous code assumed a local file.
  • Minor fix (workaround?) for locally failing test. I don't have much context here so my workaround may not be optimal, but it was blocking me.

Example POST request:

curl -X POST \
-H "Content-Type: audio/x-mpegurl" \
-H "X-ND-Authorization: Bearer redacted" \
--data "`cat myplaylist.m3u`" \
localhost:4533/api/playlist

@github-actions
Copy link

Download the artifacts for this pull request:

@deluan
Copy link
Member

deluan commented Mar 26, 2023

Thanks @SwatsonCodes! I'll review as soon as I can (the backlog of PRs to review is huge ATM)

Copy link
Member

@deluan deluan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. See my comments below. Also, we could add some tests here, specially to the ImportM3U method

core/playlists.go Show resolved Hide resolved
core/playlists.go Outdated Show resolved Hide resolved
server/nativeapi/playlists.go Show resolved Hide resolved
core/playlists.go Outdated Show resolved Hide resolved
server/nativeapi/playlists.go Outdated Show resolved Hide resolved
server/nativeapi/playlists.go Outdated Show resolved Hide resolved
server/nativeapi/playlists.go Outdated Show resolved Hide resolved
@caiocotts
Copy link
Contributor

Hey @spwats, are you planning in addressing these changes? If not, would it be ok if I work on them?

@spwats
Copy link
Contributor Author

spwats commented Aug 16, 2023

Hi @caiocotts! Yes please, I'd be happy for you to pick up this PR. I feel bad for abandoning it, but I got a new job and no longer have time to work on open source stuff.

@caiocotts
Copy link
Contributor

It's all good man. Thanks for the fast response!

@caiocotts
Copy link
Contributor

Hey @deluan, I made the changes you requested, but I still have to write the tests. Let me know if there's anything else I'm missing.

@caiocotts caiocotts requested a review from deluan October 29, 2023 21:31
@deluan
Copy link
Member

deluan commented Oct 30, 2023

Looks good, thanks! Let me know if you need help with the tests.

Copy link
Member

@deluan deluan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the tests! Just a small change and we are ready to merge!

core/playlists_test.go Outdated Show resolved Hide resolved
@deluan
Copy link
Member

deluan commented Nov 1, 2023

Thanks @spwats and @caiocotts!

@deluan deluan merged commit 26472f4 into navidrome:master Nov 1, 2023
5 checks passed
@spwats
Copy link
Contributor Author

spwats commented Nov 1, 2023

Very happy to see this get completed! Thanks for picking up where I left off @caiocotts.

@spwats spwats deleted the upload-playlist-from-m3u branch November 1, 2023 20:21
@samcro1967
Copy link

I tried this out this morning using the develop docker image. I get the following response when I try to do an import:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    57  100    39  100    18    647    298 --:--:-- --:--:-- --:--:--   950
#EXTM3U
#PLAYLIST:2023-11-02T14:02:11Z

A playlist is created with a generic name based on timestamp and the test song is not added. I do not see a way to set the playlist name. Thinking it should come from the playlist filename??? Here is my script I am testing:

#!/bin/sh

# User credentials and server URL
USERNAME="<redacted>"
PASSWORD="<redacted>"
NAVIDROME_URL="<redacted>"

# Get Bearer token
TOKEN_RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" -d "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}" "$NAVIDROME_URL/navidrome/auth/login")
BEARER_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r .token)

# Check if token was successfully retrieved
if [ "$BEARER_TOKEN" = "null" ] || [ -z "$BEARER_TOKEN" ]; then
  echo "Failed to retrieve Bearer token"
  exit 1
fi

# echo "Bearer Token: $BEARER_TOKEN"

# Playlist information
PLAYLIST_FILE="playlist.m3u"

# Import playlist
RESPONSE=$(curl -X POST \
  -H "Content-Type: audio/x-mpegurl" \
  -H "X-ND-Authorization: Bearer $BEARER_TOKEN" \
  --data "'cat $PLAYLIST_FILE'" \
  "$NAVIDROME_URL/navidrome/api/playlist")

echo "$RESPONSE"

Here is what the playlist I am testing with looks like. I have copied the line from another playlist that was exported so I know the path is correct.

/music/Unmanaged/Singles/Dustin Lynch - Chevrolet (feat. Jelly Roll).mp3

The token is properly obtained. I am able to export playlists so I think I have all of the URL's correct. Guessing I am missing something, but not quite sure what.

@caiocotts
Copy link
Contributor

Hey @samcro1967.
The playlist name is set from the #PLAYLIST directive inside the M3U file. If it's not present, then a timestamp is used.

As for the song not getting added. Is the path /music/ the volume you mounted on your navidrome instance, or is that path from your host machine?

As a reference, this is the M3U I was using to test the endpoint, my navidrome was running directly on my machine without docker:

#EXTM3U
#PLAYLIST:Neat Sounds
#EXTINF:243,Kraftwerk - Morgenspaziergang
/home/caio/Music/Kraftwerk/Autobahn/01-05 Morgenspazisergang.mp3
#EXTINF:269,TOBACCO - Enough to Calm You Down
/home/caio/Music/TOBACCO/The Allegheny White Fish Tapes/01-06 Enough to Calm You Down.flac
#EXTINF:96,TOBACCO - Metal Ball Moon
/home/caio/Music/TOBACCO/The Allegheny White Fish Tapes/01-07 Metal Ball Moon.flac
#EXTINF:161,TOBACCO - The Love Song
/home/caio/Music/TOBACCO/The Allegheny White Fish Tapes/01-12 The Love Song.flac
#EXTINF:253,Morcheeba - Bullet Proof
/home/caio/Music/Morcheeba/Big Calm/01-06 Bullet Proof.flac

@samcro1967
Copy link

Yes, /music/ is what is mounted to the docker container. I have validated that the path is correct.

~/Documents/Docker/navidrome$ docker exec -it navidrome /bin/sh
/app $ ls -al '/music/Unmanaged/Singles/Dustin Lynch - Chevrolet (feat. Jelly Roll).mp3'
-rwxrwx---    1 1000     users      6265272 Oct 31 16:49 /music/Unmanaged/Singles/Dustin Lynch - Chevrolet (feat. Jelly Roll).mp3
/app $

I get the same results with the following playlist.m3u:

#EXTM3U
#PLAYLIST:TEST
#EXTINF:184,Dustin Lynch - Chevrolet (Feat. Jelly Roll)
/music/Unmanaged/Singles/Dustin Lynch - Chevrolet (feat. Jelly Roll).mp3

@JOJ0
Copy link

JOJ0 commented Nov 3, 2023

Does this endpoint require EXTM3U formatted lists? If so, which EXTM3U lines exactly are required to be contained in the source m3u files?

@samcro1967
Copy link

I was able to get the import to work with the updated script below.

#!/bin/sh

# User credentials and server URL
USERNAME="<redacted>"
PASSWORD="<redacted>"
NAVIDROME_URL="<redacted>"
BASEURL=navidrome

# Get Bearer token
TOKEN_RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" -d "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}" "$NAVIDROME_URL/$BASEURL/auth/login")
BEARER_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r .token)

# Check if token was successfully retrieved
if [ "$BEARER_TOKEN" = "null" ] || [ -z "$BEARER_TOKEN" ]; then
  echo "Failed to retrieve Bearer token"
  exit 1
fi

# echo "Bearer Token: $BEARER_TOKEN"

# Playlist information
PLAYLIST_FILE="playlist.m3u"

echo "---------------------------------------------------------------------------------------"
echo "PlaylistFile:  $PLAYLIST_FILE"
echo "-----------------------------"
cat $PLAYLIST_FILE
echo "\n---------------------------------------------------------------------------------------\n"

# Import playlist
RESPONSE=$(curl -X POST \
  -H "Content-Type: audio/x-mpegurl" \
  -H "X-ND-Authorization: Bearer $BEARER_TOKEN" \
  --data-binary @$PLAYLIST_FILE \
  "$NAVIDROME_URL/$BASEURL/api/playlist")

echo "\n---------------------------------------------------------------------------------------"
echo "Response:"
echo "$RESPONSE"
echo "---------------------------------------------------------------------------------------"

Copy link

github-actions bot commented Mar 3, 2024

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 3, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

API endpoint for importing m3u/m3u8 playlists
6 participants