From 059d1dc7f252f933ba1c6a9b69116d3eb53c9771 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Mon, 8 Feb 2010 10:19:43 +0100
Subject: [PATCH] command: "listplaylist" dumps playlist files

Same for "listplaylistinfo".
---
 doc/protocol.xml     | 25 ++++++++++++++++++++-----
 src/command.c        |  6 ++++++
 src/playlist_print.c | 37 +++++++++++++++++++++++++++++++++++++
 src/playlist_print.h | 11 +++++++++++
 4 files changed, 74 insertions(+), 5 deletions(-)

diff --git a/doc/protocol.xml b/doc/protocol.xml
index 1f053acaa..4ed1878c8 100644
--- a/doc/protocol.xml
+++ b/doc/protocol.xml
@@ -960,6 +960,20 @@ OK
     <section>
       <title>Stored playlists</title>
 
+      <para>
+        Playlists are stored inside the configured playlist directory.
+        They are addressed with their file name (without the directory
+        and without the <filename>.m3u</filename> suffix).
+      </para>
+
+      <para>
+        Some of the commands described in this section can be used to
+        run playlist plugins instead of the hard-coded simple
+        <filename>m3u</filename> parser.  They can access playlists in
+        the music directory (relative path including the suffix) or
+        remote playlists (absolute URI with a supported scheme).
+      </para>
+
       <variablelist>
         <varlistentry id="command_listplaylist">
           <term>
@@ -970,8 +984,8 @@ OK
           </term>
           <listitem>
             <para>
-              Lists the files in the playlist
-              <filename>NAME.m3u</filename>.
+              Lists the songs in the playlist.  Playlist plugins are
+              supported.
             </para>
           </listitem>
         </varlistentry>
@@ -984,7 +998,8 @@ OK
           </term>
           <listitem>
             <para>
-              Lists songs in the playlist <filename>NAME.m3u</filename>.
+              Lists the songs with metadata in the playlist.  Playlist
+              plugins are supported.
             </para>
           </listitem>
         </varlistentry>
@@ -1016,8 +1031,8 @@ OK
           </term>
           <listitem>
             <para>
-              Loads the playlist <filename>NAME.m3u</filename> from
-              the playlist directory.
+              Loads the playlist into the current queue.  Playlist
+              plugins are supported.
             </para>
           </listitem>
         </varlistentry>
diff --git a/src/command.c b/src/command.c
index 5b94cbe7f..e591d06e3 100644
--- a/src/command.c
+++ b/src/command.c
@@ -733,6 +733,9 @@ handle_load(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
 static enum command_return
 handle_listplaylist(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
 {
+	if (playlist_file_print(client, argv[1], false))
+		return COMMAND_RETURN_OK;
+
 	bool ret;
 
 	ret = spl_print(client, argv[1], false);
@@ -748,6 +751,9 @@ static enum command_return
 handle_listplaylistinfo(struct client *client,
 			G_GNUC_UNUSED int argc, char *argv[])
 {
+	if (playlist_file_print(client, argv[1], true))
+		return COMMAND_RETURN_OK;
+
 	bool ret;
 
 	ret = spl_print(client, argv[1], true);
diff --git a/src/playlist_print.c b/src/playlist_print.c
index 97d0e2523..020b0fa87 100644
--- a/src/playlist_print.c
+++ b/src/playlist_print.c
@@ -19,6 +19,10 @@
 
 #include "config.h"
 #include "playlist_print.h"
+#include "playlist_list.h"
+#include "playlist_plugin.h"
+#include "playlist_mapper.h"
+#include "playlist_song.h"
 #include "queue_print.h"
 #include "stored_playlist.h"
 #include "song_print.h"
@@ -139,3 +143,36 @@ spl_print(struct client *client, const char *name_utf8, bool detail)
 	spl_free(list);
 	return true;
 }
+
+static void
+playlist_provider_print(struct client *client, const char *uri,
+			struct playlist_provider *playlist, bool detail)
+{
+	struct song *song;
+	char *base_uri = uri != NULL ? g_path_get_dirname(uri) : NULL;
+
+	while ((song = playlist_plugin_read(playlist)) != NULL) {
+		song = playlist_check_translate_song(song, base_uri);
+		if (song == NULL)
+			continue;
+
+		if (detail)
+			song_print_info(client, song);
+		else
+			song_print_uri(client, song);
+	}
+
+	g_free(base_uri);
+}
+
+bool
+playlist_file_print(struct client *client, const char *uri, bool detail)
+{
+	struct playlist_provider *playlist = playlist_mapper_open(uri);
+	if (playlist == NULL)
+		return false;
+
+	playlist_provider_print(client, uri, playlist, detail);
+	playlist_plugin_close(playlist);
+	return true;
+}
diff --git a/src/playlist_print.h b/src/playlist_print.h
index bbb2e8adc..b3a0446ed 100644
--- a/src/playlist_print.h
+++ b/src/playlist_print.h
@@ -101,4 +101,15 @@ playlist_print_changes_position(struct client *client,
 bool
 spl_print(struct client *client, const char *name_utf8, bool detail);
 
+/**
+ * Send the playlist file to the client.
+ *
+ * @param client the client which requested the playlist
+ * @param uri the URI of the playlist file in UTF-8 encoding
+ * @param detail true if all details should be printed
+ * @return true on success, false if the playlist does not exist
+ */
+bool
+playlist_file_print(struct client *client, const char *uri, bool detail);
+
 #endif