queue/PlaylistEdit: throw PlaylistError on error
This commit is contained in:
		@@ -66,7 +66,7 @@ handle_save(Client &client, Request args, gcc_unused Response &r)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CommandResult
 | 
					CommandResult
 | 
				
			||||||
handle_load(Client &client, Request args, Response &r)
 | 
					handle_load(Client &client, Request args, gcc_unused Response &r)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	RangeArg range = args.ParseOptional(1, RangeArg::All());
 | 
						RangeArg range = args.ParseOptional(1, RangeArg::All());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -74,12 +74,10 @@ handle_load(Client &client, Request args, Response &r)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	Error error;
 | 
						Error error;
 | 
				
			||||||
	const SongLoader loader(client);
 | 
						const SongLoader loader(client);
 | 
				
			||||||
	if (!playlist_open_into_queue(args.front(),
 | 
						playlist_open_into_queue(args.front(),
 | 
				
			||||||
				      range.start, range.end,
 | 
									 range.start, range.end,
 | 
				
			||||||
				      client.playlist,
 | 
									 client.playlist,
 | 
				
			||||||
				      client.player_control, loader, error))
 | 
									 client.player_control, loader);
 | 
				
			||||||
		return print_error(r, error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return CommandResult::OK;
 | 
						return CommandResult::OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,11 +54,7 @@ AddUri(Client &client, const LocatedUri &uri, Response &r)
 | 
				
			|||||||
		return print_error(r, error);
 | 
							return print_error(r, error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto &partition = client.partition;
 | 
						auto &partition = client.partition;
 | 
				
			||||||
	unsigned id = partition.playlist.AppendSong(partition.pc,
 | 
						partition.playlist.AppendSong(partition.pc, std::move(*song));
 | 
				
			||||||
						    std::move(*song), error);
 | 
					 | 
				
			||||||
	if (id == 0)
 | 
					 | 
				
			||||||
		return print_error(r, error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return CommandResult::OK;
 | 
						return CommandResult::OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -186,12 +182,8 @@ handle_rangeid(Client &client, Request args, Response &r)
 | 
				
			|||||||
		return CommandResult::ERROR;
 | 
							return CommandResult::ERROR;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Error error;
 | 
						client.partition.playlist.SetSongIdRange(client.partition.pc,
 | 
				
			||||||
	if (!client.partition.playlist.SetSongIdRange(client.partition.pc,
 | 
											 id, start, end);
 | 
				
			||||||
						      id, start, end,
 | 
					 | 
				
			||||||
						      error))
 | 
					 | 
				
			||||||
		return print_error(r, error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return CommandResult::OK;
 | 
						return CommandResult::OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,15 +28,13 @@
 | 
				
			|||||||
#include <functional>
 | 
					#include <functional>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool
 | 
					static bool
 | 
				
			||||||
AddToQueue(Partition &partition, const LightSong &song, Error &error)
 | 
					AddToQueue(Partition &partition, const LightSong &song)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const Storage &storage = *partition.instance.storage;
 | 
						const Storage &storage = *partition.instance.storage;
 | 
				
			||||||
	unsigned id =
 | 
						partition.playlist.AppendSong(partition.pc,
 | 
				
			||||||
		partition.playlist.AppendSong(partition.pc,
 | 
									      DatabaseDetachSong(storage,
 | 
				
			||||||
					      DatabaseDetachSong(storage,
 | 
												 song));
 | 
				
			||||||
								 song),
 | 
						return true;
 | 
				
			||||||
					      error);
 | 
					 | 
				
			||||||
	return id != 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool
 | 
					bool
 | 
				
			||||||
@@ -48,6 +46,6 @@ AddFromDatabase(Partition &partition, const DatabaseSelection &selection,
 | 
				
			|||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	using namespace std::placeholders;
 | 
						using namespace std::placeholders;
 | 
				
			||||||
	const auto f = std::bind(AddToQueue, std::ref(partition), _1, _2);
 | 
						const auto f = std::bind(AddToQueue, std::ref(partition), _1);
 | 
				
			||||||
	return db->Visit(selection, f, error);
 | 
						return db->Visit(selection, f, error);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,12 +35,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <memory>
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool
 | 
					void
 | 
				
			||||||
playlist_load_into_queue(const char *uri, SongEnumerator &e,
 | 
					playlist_load_into_queue(const char *uri, SongEnumerator &e,
 | 
				
			||||||
			 unsigned start_index, unsigned end_index,
 | 
								 unsigned start_index, unsigned end_index,
 | 
				
			||||||
			 playlist &dest, PlayerControl &pc,
 | 
								 playlist &dest, PlayerControl &pc,
 | 
				
			||||||
			 const SongLoader &loader,
 | 
								 const SongLoader &loader)
 | 
				
			||||||
			 Error &error)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const std::string base_uri = uri != nullptr
 | 
						const std::string base_uri = uri != nullptr
 | 
				
			||||||
		? PathTraitsUTF8::GetParent(uri)
 | 
							? PathTraitsUTF8::GetParent(uri)
 | 
				
			||||||
@@ -60,20 +59,15 @@ playlist_load_into_queue(const char *uri, SongEnumerator &e,
 | 
				
			|||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		unsigned id = dest.AppendSong(pc, std::move(*song), error);
 | 
							dest.AppendSong(pc, std::move(*song));
 | 
				
			||||||
		if (id == 0)
 | 
					 | 
				
			||||||
			return false;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return true;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool
 | 
					void
 | 
				
			||||||
playlist_open_into_queue(const char *uri,
 | 
					playlist_open_into_queue(const char *uri,
 | 
				
			||||||
			 unsigned start_index, unsigned end_index,
 | 
								 unsigned start_index, unsigned end_index,
 | 
				
			||||||
			 playlist &dest, PlayerControl &pc,
 | 
								 playlist &dest, PlayerControl &pc,
 | 
				
			||||||
			 const SongLoader &loader,
 | 
								 const SongLoader &loader)
 | 
				
			||||||
			 Error &error)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Mutex mutex;
 | 
						Mutex mutex;
 | 
				
			||||||
	Cond cond;
 | 
						Cond cond;
 | 
				
			||||||
@@ -83,13 +77,10 @@ playlist_open_into_queue(const char *uri,
 | 
				
			|||||||
								   loader.GetStorage(),
 | 
													   loader.GetStorage(),
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
								   mutex, cond));
 | 
													   mutex, cond));
 | 
				
			||||||
	if (playlist == nullptr) {
 | 
						if (playlist == nullptr)
 | 
				
			||||||
		error.Set(playlist_domain, int(PlaylistResult::NO_SUCH_LIST),
 | 
							throw PlaylistError::NoSuchList();
 | 
				
			||||||
			  "No such playlist");
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return playlist_load_into_queue(uri, *playlist,
 | 
						playlist_load_into_queue(uri, *playlist,
 | 
				
			||||||
					start_index, end_index,
 | 
									 start_index, end_index,
 | 
				
			||||||
					dest, pc, loader, error);
 | 
									 dest, pc, loader);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,22 +41,21 @@ struct PlayerControl;
 | 
				
			|||||||
 * @param start_index the index of the first song
 | 
					 * @param start_index the index of the first song
 | 
				
			||||||
 * @param end_index the index of the last song (excluding)
 | 
					 * @param end_index the index of the last song (excluding)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool
 | 
					void
 | 
				
			||||||
playlist_load_into_queue(const char *uri, SongEnumerator &e,
 | 
					playlist_load_into_queue(const char *uri, SongEnumerator &e,
 | 
				
			||||||
			 unsigned start_index, unsigned end_index,
 | 
								 unsigned start_index, unsigned end_index,
 | 
				
			||||||
			 playlist &dest, PlayerControl &pc,
 | 
								 playlist &dest, PlayerControl &pc,
 | 
				
			||||||
			 const SongLoader &loader,
 | 
								 const SongLoader &loader);
 | 
				
			||||||
			 Error &error);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Opens a playlist with a playlist plugin and append to the specified
 | 
					 * Opens a playlist with a playlist plugin and append to the specified
 | 
				
			||||||
 * play queue.
 | 
					 * play queue.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool
 | 
					void
 | 
				
			||||||
playlist_open_into_queue(const char *uri,
 | 
					playlist_open_into_queue(const char *uri,
 | 
				
			||||||
			 unsigned start_index, unsigned end_index,
 | 
								 unsigned start_index, unsigned end_index,
 | 
				
			||||||
			 playlist &dest, PlayerControl &pc,
 | 
								 playlist &dest, PlayerControl &pc,
 | 
				
			||||||
			 const SongLoader &loader, Error &error);
 | 
								 const SongLoader &loader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -195,11 +195,11 @@ public:
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return the new song id or 0 on error
 | 
						 * Throws PlaylistError if the queue would be too large.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @return the new song id
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	unsigned AppendSong(PlayerControl &pc,
 | 
						unsigned AppendSong(PlayerControl &pc, DetachedSong &&song);
 | 
				
			||||||
			    DetachedSong &&song,
 | 
					 | 
				
			||||||
			    Error &error);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return the new song id or 0 on error
 | 
						 * @return the new song id or 0 on error
 | 
				
			||||||
@@ -254,9 +254,8 @@ public:
 | 
				
			|||||||
	 * Sets the start_time and end_time attributes on the song
 | 
						 * Sets the start_time and end_time attributes on the song
 | 
				
			||||||
	 * with the specified id.
 | 
						 * with the specified id.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	bool SetSongIdRange(PlayerControl &pc, unsigned id,
 | 
						void SetSongIdRange(PlayerControl &pc, unsigned id,
 | 
				
			||||||
			    SongTime start, SongTime end,
 | 
								    SongTime start, SongTime end);
 | 
				
			||||||
			    Error &error);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void AddSongIdTag(unsigned id, TagType tag_type, const char *value);
 | 
						void AddSongIdTag(unsigned id, TagType tag_type, const char *value);
 | 
				
			||||||
	void ClearSongIdTag(unsigned id, TagType tag_type);
 | 
						void ClearSongIdTag(unsigned id, TagType tag_type);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -92,15 +92,13 @@ playlist::CommitBulk(PlayerControl &pc)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned
 | 
					unsigned
 | 
				
			||||||
playlist::AppendSong(PlayerControl &pc, DetachedSong &&song, Error &error)
 | 
					playlist::AppendSong(PlayerControl &pc, DetachedSong &&song)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned id;
 | 
						unsigned id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (queue.IsFull()) {
 | 
						if (queue.IsFull())
 | 
				
			||||||
		error.Set(playlist_domain, int(PlaylistResult::TOO_LARGE),
 | 
							throw PlaylistError(PlaylistResult::TOO_LARGE,
 | 
				
			||||||
			  "Playlist is too large");
 | 
									    "Playlist is too large");
 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const DetachedSong *const queued_song = GetQueuedSong();
 | 
						const DetachedSong *const queued_song = GetQueuedSong();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -134,7 +132,7 @@ playlist::AppendURI(PlayerControl &pc, const SongLoader &loader,
 | 
				
			|||||||
	if (song == nullptr)
 | 
						if (song == nullptr)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return AppendSong(pc, std::move(*song), error);
 | 
						return AppendSong(pc, std::move(*song));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
@@ -419,26 +417,20 @@ playlist::Shuffle(PlayerControl &pc, unsigned start, unsigned end)
 | 
				
			|||||||
	OnModified();
 | 
						OnModified();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool
 | 
					void
 | 
				
			||||||
playlist::SetSongIdRange(PlayerControl &pc, unsigned id,
 | 
					playlist::SetSongIdRange(PlayerControl &pc, unsigned id,
 | 
				
			||||||
			 SongTime start, SongTime end,
 | 
								 SongTime start, SongTime end)
 | 
				
			||||||
			 Error &error)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	assert(end.IsZero() || start < end);
 | 
						assert(end.IsZero() || start < end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int position = queue.IdToPosition(id);
 | 
						int position = queue.IdToPosition(id);
 | 
				
			||||||
	if (position < 0) {
 | 
						if (position < 0)
 | 
				
			||||||
		error.Set(playlist_domain, int(PlaylistResult::NO_SUCH_SONG),
 | 
							throw PlaylistError::NoSuchSong();
 | 
				
			||||||
			  "No such song");
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (playing) {
 | 
						if (playing) {
 | 
				
			||||||
		if (position == current) {
 | 
							if (position == current)
 | 
				
			||||||
			error.Set(playlist_domain, int(PlaylistResult::DENIED),
 | 
								throw PlaylistError(PlaylistResult::DENIED,
 | 
				
			||||||
				  "Cannot edit the current song");
 | 
										    "Cannot edit the current song");
 | 
				
			||||||
			return false;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (position == queued) {
 | 
							if (position == queued) {
 | 
				
			||||||
			/* if we're manipulating the "queued" song,
 | 
								/* if we're manipulating the "queued" song,
 | 
				
			||||||
@@ -455,12 +447,9 @@ playlist::SetSongIdRange(PlayerControl &pc, unsigned id,
 | 
				
			|||||||
	if (!duration.IsNegative()) {
 | 
						if (!duration.IsNegative()) {
 | 
				
			||||||
		/* validate the offsets */
 | 
							/* validate the offsets */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (start > duration) {
 | 
							if (start > duration)
 | 
				
			||||||
			error.Set(playlist_domain,
 | 
								throw PlaylistError(PlaylistResult::BAD_RANGE,
 | 
				
			||||||
				  int(PlaylistResult::BAD_RANGE),
 | 
										    "Invalid start offset");
 | 
				
			||||||
				  "Invalid start offset");
 | 
					 | 
				
			||||||
			return false;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (end >= duration)
 | 
							if (end >= duration)
 | 
				
			||||||
			end = SongTime::zero();
 | 
								end = SongTime::zero();
 | 
				
			||||||
@@ -474,5 +463,4 @@ playlist::SetSongIdRange(PlayerControl &pc, unsigned id,
 | 
				
			|||||||
	UpdateQueuedSong(pc, nullptr);
 | 
						UpdateQueuedSong(pc, nullptr);
 | 
				
			||||||
	queue.ModifyAtPosition(position);
 | 
						queue.ModifyAtPosition(position);
 | 
				
			||||||
	OnModified();
 | 
						OnModified();
 | 
				
			||||||
	return true;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user