playlist/*: move to playlist/plugins/
This commit is contained in:
32
src/playlist/MemorySongEnumerator.cxx
Normal file
32
src/playlist/MemorySongEnumerator.cxx
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "MemorySongEnumerator.hxx"
|
||||
|
||||
DetachedSong *
|
||||
MemorySongEnumerator::NextSong()
|
||||
{
|
||||
if (songs.empty())
|
||||
return nullptr;
|
||||
|
||||
auto result = new DetachedSong(std::move(songs.front()));
|
||||
songs.pop_front();
|
||||
return result;
|
||||
}
|
38
src/playlist/MemorySongEnumerator.hxx
Normal file
38
src/playlist/MemorySongEnumerator.hxx
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPD_MEMORY_PLAYLIST_PROVIDER_HXX
|
||||
#define MPD_MEMORY_PLAYLIST_PROVIDER_HXX
|
||||
|
||||
#include "SongEnumerator.hxx"
|
||||
#include "DetachedSong.hxx"
|
||||
|
||||
#include <forward_list>
|
||||
|
||||
class MemorySongEnumerator final : public SongEnumerator {
|
||||
std::forward_list<DetachedSong> songs;
|
||||
|
||||
public:
|
||||
MemorySongEnumerator(std::forward_list<DetachedSong> &&_songs)
|
||||
:songs(std::move(_songs)) {}
|
||||
|
||||
virtual DetachedSong *NextSong() override;
|
||||
};
|
||||
|
||||
#endif
|
69
src/playlist/PlaylistAny.cxx
Normal file
69
src/playlist/PlaylistAny.cxx
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "PlaylistAny.hxx"
|
||||
#include "PlaylistMapper.hxx"
|
||||
#include "PlaylistRegistry.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
static SongEnumerator *
|
||||
playlist_open_remote(const char *uri, Mutex &mutex, Cond &cond,
|
||||
InputStream **is_r)
|
||||
{
|
||||
assert(uri_has_scheme(uri));
|
||||
|
||||
SongEnumerator *playlist = playlist_list_open_uri(uri, mutex, cond);
|
||||
if (playlist != nullptr) {
|
||||
*is_r = nullptr;
|
||||
return playlist;
|
||||
}
|
||||
|
||||
Error error;
|
||||
InputStream *is = InputStream::OpenReady(uri, mutex, cond, error);
|
||||
if (is == nullptr) {
|
||||
if (error.IsDefined())
|
||||
FormatError(error, "Failed to open %s", uri);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
playlist = playlist_list_open_stream(*is, uri);
|
||||
if (playlist == nullptr) {
|
||||
is->Close();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
*is_r = is;
|
||||
return playlist;
|
||||
}
|
||||
|
||||
SongEnumerator *
|
||||
playlist_open_any(const char *uri, Mutex &mutex, Cond &cond,
|
||||
InputStream **is_r)
|
||||
{
|
||||
return uri_has_scheme(uri)
|
||||
? playlist_open_remote(uri, mutex, cond, is_r)
|
||||
: playlist_mapper_open(uri, mutex, cond, is_r);
|
||||
}
|
41
src/playlist/PlaylistAny.hxx
Normal file
41
src/playlist/PlaylistAny.hxx
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPD_PLAYLIST_ANY_HXX
|
||||
#define MPD_PLAYLIST_ANY_HXX
|
||||
|
||||
class Mutex;
|
||||
class Cond;
|
||||
class SongEnumerator;
|
||||
struct InputStream;
|
||||
|
||||
/**
|
||||
* Opens a playlist from the specified URI, which can be either an
|
||||
* absolute remote URI (with a scheme) or a relative path to the
|
||||
* music orplaylist directory.
|
||||
*
|
||||
* @param is_r on success, an input_stream object may be returned
|
||||
* here, which must be closed after the playlist_provider object is
|
||||
* freed
|
||||
*/
|
||||
SongEnumerator *
|
||||
playlist_open_any(const char *uri, Mutex &mutex, Cond &cond,
|
||||
InputStream **is_r);
|
||||
|
||||
#endif
|
102
src/playlist/PlaylistMapper.cxx
Normal file
102
src/playlist/PlaylistMapper.cxx
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "PlaylistMapper.hxx"
|
||||
#include "PlaylistFile.hxx"
|
||||
#include "PlaylistRegistry.hxx"
|
||||
#include "Mapper.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
static SongEnumerator *
|
||||
playlist_open_path(const char *path_fs, Mutex &mutex, Cond &cond,
|
||||
InputStream **is_r)
|
||||
{
|
||||
auto playlist = playlist_list_open_uri(path_fs, mutex, cond);
|
||||
if (playlist != nullptr)
|
||||
*is_r = nullptr;
|
||||
else
|
||||
playlist = playlist_list_open_path(path_fs, mutex, cond, is_r);
|
||||
|
||||
return playlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a playlist from the configured playlist directory.
|
||||
*/
|
||||
static SongEnumerator *
|
||||
playlist_open_in_playlist_dir(const char *uri, Mutex &mutex, Cond &cond,
|
||||
InputStream **is_r)
|
||||
{
|
||||
assert(spl_valid_name(uri));
|
||||
|
||||
const auto &playlist_directory_fs = map_spl_path();
|
||||
if (playlist_directory_fs.IsNull())
|
||||
return nullptr;
|
||||
|
||||
const auto uri_fs = AllocatedPath::FromUTF8(uri);
|
||||
if (uri_fs.IsNull())
|
||||
return nullptr;
|
||||
|
||||
const auto path_fs =
|
||||
AllocatedPath::Build(playlist_directory_fs, uri_fs);
|
||||
assert(!path_fs.IsNull());
|
||||
|
||||
return playlist_open_path(path_fs.c_str(), mutex, cond, is_r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a playlist from the configured music directory.
|
||||
*/
|
||||
static SongEnumerator *
|
||||
playlist_open_in_music_dir(const char *uri, Mutex &mutex, Cond &cond,
|
||||
InputStream **is_r)
|
||||
{
|
||||
assert(uri_safe_local(uri));
|
||||
|
||||
const auto path = map_uri_fs(uri);
|
||||
if (path.IsNull())
|
||||
return nullptr;
|
||||
|
||||
return playlist_open_path(path.c_str(), mutex, cond, is_r);
|
||||
}
|
||||
|
||||
SongEnumerator *
|
||||
playlist_mapper_open(const char *uri, Mutex &mutex, Cond &cond,
|
||||
InputStream **is_r)
|
||||
{
|
||||
if (spl_valid_name(uri)) {
|
||||
auto playlist = playlist_open_in_playlist_dir(uri, mutex, cond,
|
||||
is_r);
|
||||
if (playlist != nullptr)
|
||||
return playlist;
|
||||
}
|
||||
|
||||
if (uri_safe_local(uri)) {
|
||||
auto playlist = playlist_open_in_music_dir(uri, mutex, cond,
|
||||
is_r);
|
||||
if (playlist != nullptr)
|
||||
return playlist;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
40
src/playlist/PlaylistMapper.hxx
Normal file
40
src/playlist/PlaylistMapper.hxx
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPD_PLAYLIST_MAPPER_HXX
|
||||
#define MPD_PLAYLIST_MAPPER_HXX
|
||||
|
||||
class Mutex;
|
||||
class Cond;
|
||||
class SongEnumerator;
|
||||
struct InputStream;
|
||||
|
||||
/**
|
||||
* Opens a playlist from an URI relative to the playlist or music
|
||||
* directory.
|
||||
*
|
||||
* @param is_r on success, an input_stream object may be returned
|
||||
* here, which must be closed after the playlist_provider object is
|
||||
* freed
|
||||
*/
|
||||
SongEnumerator *
|
||||
playlist_mapper_open(const char *uri, Mutex &mutex, Cond &cond,
|
||||
InputStream **is_r);
|
||||
|
||||
#endif
|
109
src/playlist/PlaylistPlugin.hxx
Normal file
109
src/playlist/PlaylistPlugin.hxx
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPD_PLAYLIST_PLUGIN_HXX
|
||||
#define MPD_PLAYLIST_PLUGIN_HXX
|
||||
|
||||
struct config_param;
|
||||
struct InputStream;
|
||||
struct Tag;
|
||||
class Mutex;
|
||||
class Cond;
|
||||
class SongEnumerator;
|
||||
|
||||
struct playlist_plugin {
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* Initialize the plugin. Optional method.
|
||||
*
|
||||
* @param param a configuration block for this plugin, or nullptr
|
||||
* if none is configured
|
||||
* @return true if the plugin was initialized successfully,
|
||||
* false if the plugin is not available
|
||||
*/
|
||||
bool (*init)(const config_param ¶m);
|
||||
|
||||
/**
|
||||
* Deinitialize a plugin which was initialized successfully.
|
||||
* Optional method.
|
||||
*/
|
||||
void (*finish)(void);
|
||||
|
||||
/**
|
||||
* Opens the playlist on the specified URI. This URI has
|
||||
* either matched one of the schemes or one of the suffixes.
|
||||
*/
|
||||
SongEnumerator *(*open_uri)(const char *uri,
|
||||
Mutex &mutex, Cond &cond);
|
||||
|
||||
/**
|
||||
* Opens the playlist in the specified input stream. It has
|
||||
* either matched one of the suffixes or one of the MIME
|
||||
* types.
|
||||
*/
|
||||
SongEnumerator *(*open_stream)(InputStream &is);
|
||||
|
||||
const char *const*schemes;
|
||||
const char *const*suffixes;
|
||||
const char *const*mime_types;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize a plugin.
|
||||
*
|
||||
* @param param a configuration block for this plugin, or nullptr if none
|
||||
* is configured
|
||||
* @return true if the plugin was initialized successfully, false if
|
||||
* the plugin is not available
|
||||
*/
|
||||
static inline bool
|
||||
playlist_plugin_init(const struct playlist_plugin *plugin,
|
||||
const config_param ¶m)
|
||||
{
|
||||
return plugin->init != nullptr
|
||||
? plugin->init(param)
|
||||
: true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deinitialize a plugin which was initialized successfully.
|
||||
*/
|
||||
static inline void
|
||||
playlist_plugin_finish(const struct playlist_plugin *plugin)
|
||||
{
|
||||
if (plugin->finish != nullptr)
|
||||
plugin->finish();
|
||||
}
|
||||
|
||||
static inline SongEnumerator *
|
||||
playlist_plugin_open_uri(const struct playlist_plugin *plugin, const char *uri,
|
||||
Mutex &mutex, Cond &cond)
|
||||
{
|
||||
return plugin->open_uri(uri, mutex, cond);
|
||||
}
|
||||
|
||||
static inline SongEnumerator *
|
||||
playlist_plugin_open_stream(const struct playlist_plugin *plugin,
|
||||
InputStream &is)
|
||||
{
|
||||
return plugin->open_stream(is);
|
||||
}
|
||||
|
||||
#endif
|
90
src/playlist/PlaylistQueue.cxx
Normal file
90
src/playlist/PlaylistQueue.cxx
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "PlaylistQueue.hxx"
|
||||
#include "PlaylistAny.hxx"
|
||||
#include "PlaylistSong.hxx"
|
||||
#include "Playlist.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "SongEnumerator.hxx"
|
||||
#include "DetachedSong.hxx"
|
||||
#include "thread/Cond.hxx"
|
||||
#include "fs/Traits.hxx"
|
||||
|
||||
PlaylistResult
|
||||
playlist_load_into_queue(const char *uri, SongEnumerator &e,
|
||||
unsigned start_index, unsigned end_index,
|
||||
playlist &dest, PlayerControl &pc,
|
||||
bool secure)
|
||||
{
|
||||
const std::string base_uri = uri != nullptr
|
||||
? PathTraitsUTF8::GetParent(uri)
|
||||
: std::string(".");
|
||||
|
||||
DetachedSong *song;
|
||||
for (unsigned i = 0;
|
||||
i < end_index && (song = e.NextSong()) != nullptr;
|
||||
++i) {
|
||||
if (i < start_index) {
|
||||
/* skip songs before the start index */
|
||||
delete song;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!playlist_check_translate_song(*song, base_uri.c_str(),
|
||||
secure)) {
|
||||
delete song;
|
||||
continue;
|
||||
}
|
||||
|
||||
PlaylistResult result = dest.AppendSong(pc, std::move(*song));
|
||||
delete song;
|
||||
if (result != PlaylistResult::SUCCESS)
|
||||
return result;
|
||||
}
|
||||
|
||||
return PlaylistResult::SUCCESS;
|
||||
}
|
||||
|
||||
PlaylistResult
|
||||
playlist_open_into_queue(const char *uri,
|
||||
unsigned start_index, unsigned end_index,
|
||||
playlist &dest, PlayerControl &pc,
|
||||
bool secure)
|
||||
{
|
||||
Mutex mutex;
|
||||
Cond cond;
|
||||
|
||||
InputStream *is;
|
||||
auto playlist = playlist_open_any(uri, mutex, cond, &is);
|
||||
if (playlist == nullptr)
|
||||
return PlaylistResult::NO_SUCH_LIST;
|
||||
|
||||
PlaylistResult result =
|
||||
playlist_load_into_queue(uri, *playlist,
|
||||
start_index, end_index,
|
||||
dest, pc, secure);
|
||||
delete playlist;
|
||||
|
||||
if (is != nullptr)
|
||||
is->Close();
|
||||
|
||||
return result;
|
||||
}
|
59
src/playlist/PlaylistQueue.hxx
Normal file
59
src/playlist/PlaylistQueue.hxx
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
* \brief Glue between playlist plugin and the play queue
|
||||
*/
|
||||
|
||||
#ifndef MPD_PLAYLIST_QUEUE_HXX
|
||||
#define MPD_PLAYLIST_QUEUE_HXX
|
||||
|
||||
#include "PlaylistError.hxx"
|
||||
|
||||
class SongEnumerator;
|
||||
struct playlist;
|
||||
struct PlayerControl;
|
||||
|
||||
/**
|
||||
* Loads the contents of a playlist and append it to the specified
|
||||
* play queue.
|
||||
*
|
||||
* @param uri the URI of the playlist, used to resolve relative song
|
||||
* URIs
|
||||
* @param start_index the index of the first song
|
||||
* @param end_index the index of the last song (excluding)
|
||||
*/
|
||||
PlaylistResult
|
||||
playlist_load_into_queue(const char *uri, SongEnumerator &e,
|
||||
unsigned start_index, unsigned end_index,
|
||||
playlist &dest, PlayerControl &pc,
|
||||
bool secure);
|
||||
|
||||
/**
|
||||
* Opens a playlist with a playlist plugin and append to the specified
|
||||
* play queue.
|
||||
*/
|
||||
PlaylistResult
|
||||
playlist_open_into_queue(const char *uri,
|
||||
unsigned start_index, unsigned end_index,
|
||||
playlist &dest, PlayerControl &pc,
|
||||
bool secure);
|
||||
|
||||
#endif
|
||||
|
335
src/playlist/PlaylistRegistry.cxx
Normal file
335
src/playlist/PlaylistRegistry.cxx
Normal file
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "PlaylistRegistry.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "plugins/ExtM3uPlaylistPlugin.hxx"
|
||||
#include "plugins/M3uPlaylistPlugin.hxx"
|
||||
#include "plugins/XspfPlaylistPlugin.hxx"
|
||||
#include "plugins/DespotifyPlaylistPlugin.hxx"
|
||||
#include "plugins/SoundCloudPlaylistPlugin.hxx"
|
||||
#include "plugins/PlsPlaylistPlugin.hxx"
|
||||
#include "plugins/AsxPlaylistPlugin.hxx"
|
||||
#include "plugins/RssPlaylistPlugin.hxx"
|
||||
#include "plugins/CuePlaylistPlugin.hxx"
|
||||
#include "plugins/EmbeddedCuePlaylistPlugin.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/StringUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/Macros.hxx"
|
||||
#include "ConfigGlobal.hxx"
|
||||
#include "ConfigData.hxx"
|
||||
#include "system/FatalError.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
const struct playlist_plugin *const playlist_plugins[] = {
|
||||
&extm3u_playlist_plugin,
|
||||
&m3u_playlist_plugin,
|
||||
&pls_playlist_plugin,
|
||||
#ifdef HAVE_EXPAT
|
||||
&xspf_playlist_plugin,
|
||||
&asx_playlist_plugin,
|
||||
&rss_playlist_plugin,
|
||||
#endif
|
||||
#ifdef ENABLE_DESPOTIFY
|
||||
&despotify_playlist_plugin,
|
||||
#endif
|
||||
#ifdef ENABLE_SOUNDCLOUD
|
||||
&soundcloud_playlist_plugin,
|
||||
#endif
|
||||
&cue_playlist_plugin,
|
||||
&embcue_playlist_plugin,
|
||||
nullptr
|
||||
};
|
||||
|
||||
static constexpr unsigned n_playlist_plugins =
|
||||
ARRAY_SIZE(playlist_plugins) - 1;
|
||||
|
||||
/** which plugins have been initialized successfully? */
|
||||
static bool playlist_plugins_enabled[n_playlist_plugins];
|
||||
|
||||
#define playlist_plugins_for_each_enabled(plugin) \
|
||||
playlist_plugins_for_each(plugin) \
|
||||
if (playlist_plugins_enabled[playlist_plugin_iterator - playlist_plugins])
|
||||
|
||||
/**
|
||||
* Find the "playlist" configuration block for the specified plugin.
|
||||
*
|
||||
* @param plugin_name the name of the playlist plugin
|
||||
* @return the configuration block, or nullptr if none was configured
|
||||
*/
|
||||
static const struct config_param *
|
||||
playlist_plugin_config(const char *plugin_name)
|
||||
{
|
||||
const struct config_param *param = nullptr;
|
||||
|
||||
assert(plugin_name != nullptr);
|
||||
|
||||
while ((param = config_get_next_param(CONF_PLAYLIST_PLUGIN, param)) != nullptr) {
|
||||
const char *name = param->GetBlockValue("name");
|
||||
if (name == nullptr)
|
||||
FormatFatalError("playlist configuration without 'plugin' name in line %d",
|
||||
param->line);
|
||||
|
||||
if (strcmp(name, plugin_name) == 0)
|
||||
return param;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
playlist_list_global_init(void)
|
||||
{
|
||||
const config_param empty;
|
||||
|
||||
for (unsigned i = 0; playlist_plugins[i] != nullptr; ++i) {
|
||||
const struct playlist_plugin *plugin = playlist_plugins[i];
|
||||
const struct config_param *param =
|
||||
playlist_plugin_config(plugin->name);
|
||||
if (param == nullptr)
|
||||
param = ∅
|
||||
else if (!param->GetBlockValue("enabled", true))
|
||||
/* the plugin is disabled in mpd.conf */
|
||||
continue;
|
||||
|
||||
playlist_plugins_enabled[i] =
|
||||
playlist_plugin_init(playlist_plugins[i], *param);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
playlist_list_global_finish(void)
|
||||
{
|
||||
playlist_plugins_for_each_enabled(plugin)
|
||||
playlist_plugin_finish(plugin);
|
||||
}
|
||||
|
||||
static SongEnumerator *
|
||||
playlist_list_open_uri_scheme(const char *uri, Mutex &mutex, Cond &cond,
|
||||
bool *tried)
|
||||
{
|
||||
SongEnumerator *playlist = nullptr;
|
||||
|
||||
assert(uri != nullptr);
|
||||
|
||||
const auto scheme = uri_get_scheme(uri);
|
||||
if (scheme.empty())
|
||||
return nullptr;
|
||||
|
||||
for (unsigned i = 0; playlist_plugins[i] != nullptr; ++i) {
|
||||
const struct playlist_plugin *plugin = playlist_plugins[i];
|
||||
|
||||
assert(!tried[i]);
|
||||
|
||||
if (playlist_plugins_enabled[i] && plugin->open_uri != nullptr &&
|
||||
plugin->schemes != nullptr &&
|
||||
string_array_contains(plugin->schemes, scheme.c_str())) {
|
||||
playlist = playlist_plugin_open_uri(plugin, uri,
|
||||
mutex, cond);
|
||||
if (playlist != nullptr)
|
||||
break;
|
||||
|
||||
tried[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return playlist;
|
||||
}
|
||||
|
||||
static SongEnumerator *
|
||||
playlist_list_open_uri_suffix(const char *uri, Mutex &mutex, Cond &cond,
|
||||
const bool *tried)
|
||||
{
|
||||
const char *suffix;
|
||||
SongEnumerator *playlist = nullptr;
|
||||
|
||||
assert(uri != nullptr);
|
||||
|
||||
suffix = uri_get_suffix(uri);
|
||||
if (suffix == nullptr)
|
||||
return nullptr;
|
||||
|
||||
for (unsigned i = 0; playlist_plugins[i] != nullptr; ++i) {
|
||||
const struct playlist_plugin *plugin = playlist_plugins[i];
|
||||
|
||||
if (playlist_plugins_enabled[i] && !tried[i] &&
|
||||
plugin->open_uri != nullptr && plugin->suffixes != nullptr &&
|
||||
string_array_contains(plugin->suffixes, suffix)) {
|
||||
playlist = playlist_plugin_open_uri(plugin, uri,
|
||||
mutex, cond);
|
||||
if (playlist != nullptr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return playlist;
|
||||
}
|
||||
|
||||
SongEnumerator *
|
||||
playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond)
|
||||
{
|
||||
/** this array tracks which plugins have already been tried by
|
||||
playlist_list_open_uri_scheme() */
|
||||
bool tried[n_playlist_plugins];
|
||||
|
||||
assert(uri != nullptr);
|
||||
|
||||
memset(tried, false, sizeof(tried));
|
||||
|
||||
auto playlist = playlist_list_open_uri_scheme(uri, mutex, cond, tried);
|
||||
if (playlist == nullptr)
|
||||
playlist = playlist_list_open_uri_suffix(uri, mutex, cond,
|
||||
tried);
|
||||
|
||||
return playlist;
|
||||
}
|
||||
|
||||
static SongEnumerator *
|
||||
playlist_list_open_stream_mime2(InputStream &is, const char *mime)
|
||||
{
|
||||
assert(mime != nullptr);
|
||||
|
||||
playlist_plugins_for_each_enabled(plugin) {
|
||||
if (plugin->open_stream != nullptr &&
|
||||
plugin->mime_types != nullptr &&
|
||||
string_array_contains(plugin->mime_types, mime)) {
|
||||
/* rewind the stream, so each plugin gets a
|
||||
fresh start */
|
||||
is.Rewind(IgnoreError());
|
||||
|
||||
auto playlist = playlist_plugin_open_stream(plugin,
|
||||
is);
|
||||
if (playlist != nullptr)
|
||||
return playlist;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static SongEnumerator *
|
||||
playlist_list_open_stream_mime(InputStream &is, const char *full_mime)
|
||||
{
|
||||
assert(full_mime != nullptr);
|
||||
|
||||
const char *semicolon = strchr(full_mime, ';');
|
||||
if (semicolon == nullptr)
|
||||
return playlist_list_open_stream_mime2(is, full_mime);
|
||||
|
||||
if (semicolon == full_mime)
|
||||
return nullptr;
|
||||
|
||||
/* probe only the portion before the semicolon*/
|
||||
const std::string mime(full_mime, semicolon);
|
||||
return playlist_list_open_stream_mime2(is, mime.c_str());
|
||||
}
|
||||
|
||||
static SongEnumerator *
|
||||
playlist_list_open_stream_suffix(InputStream &is, const char *suffix)
|
||||
{
|
||||
assert(suffix != nullptr);
|
||||
|
||||
playlist_plugins_for_each_enabled(plugin) {
|
||||
if (plugin->open_stream != nullptr &&
|
||||
plugin->suffixes != nullptr &&
|
||||
string_array_contains(plugin->suffixes, suffix)) {
|
||||
/* rewind the stream, so each plugin gets a
|
||||
fresh start */
|
||||
is.Rewind(IgnoreError());
|
||||
|
||||
auto playlist = playlist_plugin_open_stream(plugin, is);
|
||||
if (playlist != nullptr)
|
||||
return playlist;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SongEnumerator *
|
||||
playlist_list_open_stream(InputStream &is, const char *uri)
|
||||
{
|
||||
assert(is.ready);
|
||||
|
||||
const char *const mime = is.GetMimeType();
|
||||
if (mime != nullptr) {
|
||||
auto playlist = playlist_list_open_stream_mime(is, mime);
|
||||
if (playlist != nullptr)
|
||||
return playlist;
|
||||
}
|
||||
|
||||
const char *suffix = uri != nullptr ? uri_get_suffix(uri) : nullptr;
|
||||
if (suffix != nullptr) {
|
||||
auto playlist = playlist_list_open_stream_suffix(is, suffix);
|
||||
if (playlist != nullptr)
|
||||
return playlist;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
playlist_suffix_supported(const char *suffix)
|
||||
{
|
||||
assert(suffix != nullptr);
|
||||
|
||||
playlist_plugins_for_each_enabled(plugin) {
|
||||
if (plugin->suffixes != nullptr &&
|
||||
string_array_contains(plugin->suffixes, suffix))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SongEnumerator *
|
||||
playlist_list_open_path(const char *path_fs, Mutex &mutex, Cond &cond,
|
||||
InputStream **is_r)
|
||||
{
|
||||
const char *suffix;
|
||||
|
||||
assert(path_fs != nullptr);
|
||||
|
||||
suffix = uri_get_suffix(path_fs);
|
||||
if (suffix == nullptr || !playlist_suffix_supported(suffix))
|
||||
return nullptr;
|
||||
|
||||
Error error;
|
||||
InputStream *is = InputStream::OpenReady(path_fs, mutex, cond, error);
|
||||
if (is == nullptr) {
|
||||
if (error.IsDefined())
|
||||
LogError(error);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto playlist = playlist_list_open_stream_suffix(*is, suffix);
|
||||
if (playlist != nullptr)
|
||||
*is_r = is;
|
||||
else
|
||||
is->Close();
|
||||
|
||||
return playlist;
|
||||
}
|
83
src/playlist/PlaylistRegistry.hxx
Normal file
83
src/playlist/PlaylistRegistry.hxx
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPD_PLAYLIST_REGISTRY_HXX
|
||||
#define MPD_PLAYLIST_REGISTRY_HXX
|
||||
|
||||
class Mutex;
|
||||
class Cond;
|
||||
class SongEnumerator;
|
||||
struct InputStream;
|
||||
|
||||
extern const struct playlist_plugin *const playlist_plugins[];
|
||||
|
||||
#define playlist_plugins_for_each(plugin) \
|
||||
for (const struct playlist_plugin *plugin, \
|
||||
*const*playlist_plugin_iterator = &playlist_plugins[0]; \
|
||||
(plugin = *playlist_plugin_iterator) != nullptr; \
|
||||
++playlist_plugin_iterator)
|
||||
|
||||
/**
|
||||
* Initializes all playlist plugins.
|
||||
*/
|
||||
void
|
||||
playlist_list_global_init(void);
|
||||
|
||||
/**
|
||||
* Deinitializes all playlist plugins.
|
||||
*/
|
||||
void
|
||||
playlist_list_global_finish(void);
|
||||
|
||||
/**
|
||||
* Opens a playlist by its URI.
|
||||
*/
|
||||
SongEnumerator *
|
||||
playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond);
|
||||
|
||||
/**
|
||||
* Opens a playlist from an input stream.
|
||||
*
|
||||
* @param is an #input_stream object which is open and ready
|
||||
* @param uri optional URI which was used to open the stream; may be
|
||||
* used to select the appropriate playlist plugin
|
||||
*/
|
||||
SongEnumerator *
|
||||
playlist_list_open_stream(InputStream &is, const char *uri);
|
||||
|
||||
/**
|
||||
* Determines if there is a playlist plugin which can handle the
|
||||
* specified file name suffix.
|
||||
*/
|
||||
bool
|
||||
playlist_suffix_supported(const char *suffix);
|
||||
|
||||
/**
|
||||
* Opens a playlist from a local file.
|
||||
*
|
||||
* @param path_fs the path of the playlist file
|
||||
* @param is_r on success, an input_stream object is returned here,
|
||||
* which must be closed after the playlist_provider object is freed
|
||||
* @return a playlist, or nullptr on error
|
||||
*/
|
||||
SongEnumerator *
|
||||
playlist_list_open_path(const char *path_fs, Mutex &mutex, Cond &cond,
|
||||
InputStream **is_r);
|
||||
|
||||
#endif
|
131
src/playlist/PlaylistSong.cxx
Normal file
131
src/playlist/PlaylistSong.cxx
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "PlaylistSong.hxx"
|
||||
#include "Mapper.hxx"
|
||||
#include "DatabaseSong.hxx"
|
||||
#include "ls.hxx"
|
||||
#include "tag/Tag.hxx"
|
||||
#include "tag/TagBuilder.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "fs/Traits.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "DetachedSong.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
static void
|
||||
merge_song_metadata(DetachedSong &add, const DetachedSong &base)
|
||||
{
|
||||
{
|
||||
TagBuilder builder(add.GetTag());
|
||||
builder.Complement(base.GetTag());
|
||||
add.SetTag(builder.Commit());
|
||||
}
|
||||
|
||||
add.SetLastModified(base.GetLastModified());
|
||||
}
|
||||
|
||||
static void
|
||||
apply_song_metadata(DetachedSong &dest, const DetachedSong &src)
|
||||
{
|
||||
if (!src.GetTag().IsDefined() &&
|
||||
src.GetStartMS() == 0 && src.GetEndMS() == 0)
|
||||
return;
|
||||
|
||||
merge_song_metadata(dest, src);
|
||||
|
||||
if (dest.GetTag().IsDefined() && dest.GetTag().time > 0 &&
|
||||
src.GetStartMS() > 0 && src.GetEndMS() == 0 &&
|
||||
src.GetStartMS() / 1000 < (unsigned)dest.GetTag().time)
|
||||
/* the range is open-ended, and the playlist plugin
|
||||
did not know the total length of the song file
|
||||
(e.g. last track on a CUE file); fix it up here */
|
||||
dest.WritableTag().time =
|
||||
dest.GetTag().time - src.GetStartMS() / 1000;
|
||||
}
|
||||
|
||||
static bool
|
||||
playlist_check_load_song(DetachedSong &song)
|
||||
{
|
||||
const char *const uri = song.GetURI();
|
||||
|
||||
if (uri_has_scheme(uri)) {
|
||||
return true;
|
||||
} else if (PathTraitsUTF8::IsAbsolute(uri)) {
|
||||
DetachedSong tmp(uri);
|
||||
if (!tmp.Update())
|
||||
return false;
|
||||
|
||||
apply_song_metadata(song, tmp);
|
||||
return true;
|
||||
} else {
|
||||
DetachedSong *tmp = DatabaseDetachSong(uri, IgnoreError());
|
||||
if (tmp == nullptr)
|
||||
return false;
|
||||
|
||||
apply_song_metadata(song, *tmp);
|
||||
delete tmp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
playlist_check_translate_song(DetachedSong &song, const char *base_uri,
|
||||
bool secure)
|
||||
{
|
||||
const char *const uri = song.GetURI();
|
||||
|
||||
if (uri_has_scheme(uri))
|
||||
/* valid remote song? */
|
||||
return uri_supported_scheme(uri);
|
||||
|
||||
if (base_uri != nullptr && strcmp(base_uri, ".") == 0)
|
||||
/* PathTraitsUTF8::GetParent() returns "." when there
|
||||
is no directory name in the given path; clear that
|
||||
now, because it would break the database lookup
|
||||
functions */
|
||||
base_uri = nullptr;
|
||||
|
||||
if (PathTraitsUTF8::IsAbsolute(uri)) {
|
||||
/* XXX fs_charset vs utf8? */
|
||||
const char *suffix = map_to_relative_path(uri);
|
||||
assert(suffix != nullptr);
|
||||
|
||||
if (suffix != uri)
|
||||
song.SetURI(std::string(suffix));
|
||||
else if (!secure)
|
||||
/* local files must be relative to the music
|
||||
directory when "secure" is enabled */
|
||||
return false;
|
||||
|
||||
base_uri = nullptr;
|
||||
}
|
||||
|
||||
if (base_uri != nullptr) {
|
||||
song.SetURI(PathTraitsUTF8::Build(base_uri, uri));
|
||||
/* repeat the above checks */
|
||||
return playlist_check_translate_song(song, nullptr, secure);
|
||||
}
|
||||
|
||||
return playlist_check_load_song(song);
|
||||
}
|
37
src/playlist/PlaylistSong.hxx
Normal file
37
src/playlist/PlaylistSong.hxx
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPD_PLAYLIST_SONG_HXX
|
||||
#define MPD_PLAYLIST_SONG_HXX
|
||||
|
||||
class DetachedSong;
|
||||
|
||||
/**
|
||||
* Verifies the song, returns false if it is unsafe. Translate the
|
||||
* song to a song within the database, if it is a local file.
|
||||
*
|
||||
* @param secure if true, then local files are only allowed if they
|
||||
* are relative to base_uri
|
||||
* @return true on success, false if the song should not be used
|
||||
*/
|
||||
bool
|
||||
playlist_check_translate_song(DetachedSong &song, const char *base_uri,
|
||||
bool secure);
|
||||
|
||||
#endif
|
71
src/playlist/Print.cxx
Normal file
71
src/playlist/Print.cxx
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "Print.hxx"
|
||||
#include "PlaylistAny.hxx"
|
||||
#include "PlaylistSong.hxx"
|
||||
#include "SongEnumerator.hxx"
|
||||
#include "SongPrint.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "DetachedSong.hxx"
|
||||
#include "fs/Traits.hxx"
|
||||
#include "thread/Cond.hxx"
|
||||
|
||||
static void
|
||||
playlist_provider_print(Client &client, const char *uri,
|
||||
SongEnumerator &e, bool detail)
|
||||
{
|
||||
const std::string base_uri = uri != nullptr
|
||||
? PathTraitsUTF8::GetParent(uri)
|
||||
: std::string(".");
|
||||
|
||||
DetachedSong *song;
|
||||
while ((song = e.NextSong()) != nullptr) {
|
||||
if (playlist_check_translate_song(*song, base_uri.c_str(),
|
||||
false)) {
|
||||
if (detail)
|
||||
song_print_info(client, *song);
|
||||
else
|
||||
song_print_uri(client, *song);
|
||||
}
|
||||
|
||||
delete song;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
playlist_file_print(Client &client, const char *uri, bool detail)
|
||||
{
|
||||
Mutex mutex;
|
||||
Cond cond;
|
||||
|
||||
InputStream *is;
|
||||
SongEnumerator *playlist = playlist_open_any(uri, mutex, cond, &is);
|
||||
if (playlist == nullptr)
|
||||
return false;
|
||||
|
||||
playlist_provider_print(client, uri, *playlist, detail);
|
||||
delete playlist;
|
||||
|
||||
if (is != nullptr)
|
||||
is->Close();
|
||||
|
||||
return true;
|
||||
}
|
36
src/playlist/Print.hxx
Normal file
36
src/playlist/Print.hxx
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPD_PLAYLIST__PRINT_HXX
|
||||
#define MPD_PLAYLIST__PRINT_HXX
|
||||
|
||||
class Client;
|
||||
|
||||
/**
|
||||
* 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(Client &client, const char *uri, bool detail);
|
||||
|
||||
#endif
|
41
src/playlist/SongEnumerator.hxx
Normal file
41
src/playlist/SongEnumerator.hxx
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPD_SONG_ENUMERATOR_HXX
|
||||
#define MPD_SONG_ENUMERATOR_HXX
|
||||
|
||||
class DetachedSong;
|
||||
|
||||
/**
|
||||
* An object which provides serial access to a number of #Song
|
||||
* objects. It is used to enumerate the contents of a playlist file.
|
||||
*/
|
||||
class SongEnumerator {
|
||||
public:
|
||||
virtual ~SongEnumerator() {}
|
||||
|
||||
/**
|
||||
* Obtain the next song. The caller is responsible for
|
||||
* freeing the returned #Song object. Returns nullptr if
|
||||
* there are no more songs.
|
||||
*/
|
||||
virtual DetachedSong *NextSong() = 0;
|
||||
};
|
||||
|
||||
#endif
|
@@ -19,8 +19,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "AsxPlaylistPlugin.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "MemorySongEnumerator.hxx"
|
||||
#include "../PlaylistPlugin.hxx"
|
||||
#include "../MemorySongEnumerator.hxx"
|
||||
#include "tag/TagBuilder.hxx"
|
||||
#include "util/ASCII.hxx"
|
||||
#include "util/Error.hxx"
|
@@ -19,8 +19,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "CuePlaylistPlugin.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "SongEnumerator.hxx"
|
||||
#include "../PlaylistPlugin.hxx"
|
||||
#include "../SongEnumerator.hxx"
|
||||
#include "cue/CueParser.hxx"
|
||||
#include "TextInputStream.hxx"
|
||||
|
@@ -20,8 +20,8 @@
|
||||
#include "config.h"
|
||||
#include "DespotifyPlaylistPlugin.hxx"
|
||||
#include "DespotifyUtils.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "MemorySongEnumerator.hxx"
|
||||
#include "../PlaylistPlugin.hxx"
|
||||
#include "../MemorySongEnumerator.hxx"
|
||||
#include "tag/Tag.hxx"
|
||||
#include "DetachedSong.hxx"
|
||||
#include "Log.hxx"
|
@@ -25,8 +25,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "EmbeddedCuePlaylistPlugin.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "SongEnumerator.hxx"
|
||||
#include "../PlaylistPlugin.hxx"
|
||||
#include "../SongEnumerator.hxx"
|
||||
#include "tag/TagHandler.hxx"
|
||||
#include "tag/TagId3.hxx"
|
||||
#include "tag/ApeTag.hxx"
|
@@ -19,8 +19,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "ExtM3uPlaylistPlugin.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "SongEnumerator.hxx"
|
||||
#include "../PlaylistPlugin.hxx"
|
||||
#include "../SongEnumerator.hxx"
|
||||
#include "DetachedSong.hxx"
|
||||
#include "tag/Tag.hxx"
|
||||
#include "tag/TagBuilder.hxx"
|
@@ -19,8 +19,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "M3uPlaylistPlugin.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "SongEnumerator.hxx"
|
||||
#include "../PlaylistPlugin.hxx"
|
||||
#include "../SongEnumerator.hxx"
|
||||
#include "DetachedSong.hxx"
|
||||
#include "util/StringUtil.hxx"
|
||||
#include "TextInputStream.hxx"
|
@@ -19,8 +19,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "PlsPlaylistPlugin.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "MemorySongEnumerator.hxx"
|
||||
#include "../PlaylistPlugin.hxx"
|
||||
#include "../MemorySongEnumerator.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "DetachedSong.hxx"
|
||||
#include "tag/TagBuilder.hxx"
|
@@ -19,8 +19,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "RssPlaylistPlugin.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "MemorySongEnumerator.hxx"
|
||||
#include "../PlaylistPlugin.hxx"
|
||||
#include "../MemorySongEnumerator.hxx"
|
||||
#include "tag/TagBuilder.hxx"
|
||||
#include "util/ASCII.hxx"
|
||||
#include "util/Error.hxx"
|
@@ -19,8 +19,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "SoundCloudPlaylistPlugin.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "MemorySongEnumerator.hxx"
|
||||
#include "../PlaylistPlugin.hxx"
|
||||
#include "../MemorySongEnumerator.hxx"
|
||||
#include "ConfigData.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "tag/TagBuilder.hxx"
|
@@ -19,8 +19,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "XspfPlaylistPlugin.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "MemorySongEnumerator.hxx"
|
||||
#include "../PlaylistPlugin.hxx"
|
||||
#include "../MemorySongEnumerator.hxx"
|
||||
#include "DetachedSong.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "tag/TagBuilder.hxx"
|
Reference in New Issue
Block a user