1
0
mirror of https://github.com/ZetaKebab/MpcNET.git synced 2024-09-16 05:30:09 +00:00

Command for Current Queue implemented + tests.

This commit is contained in:
glucaci 2017-04-13 11:25:19 +02:00
parent 6cfbb61ca4
commit 6426d98fc5
19 changed files with 584 additions and 39 deletions

View File

@ -1,4 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MpcNET.Test
{
@ -23,5 +26,32 @@ namespace MpcNET.Test
}
internal static Mpc Mpc { get; private set; }
private static async Task SendCommand(string command)
{
var response = await Mpc.SendAsync(new PassthroughCommand(command));
TestOutput.WriteLine(response);
}
private static async Task SendCommand<T>(IMpcCommand<T> command)
{
var response = await Mpc.SendAsync(command);
TestOutput.WriteLine(response);
}
private class PassthroughCommand : IMpcCommand<IList<string>>
{
public PassthroughCommand(string command)
{
Value = command;
}
public string Value { get; }
public IList<string> FormatResponse(IList<KeyValuePair<string, string>> response)
{
var result = response.Select(atrb => $"{atrb.Key}: {atrb.Value}").ToList();
return result;
}
}
}
}

View File

@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following

View File

@ -0,0 +1 @@
mpd.exe mpd.conf -v

View File

@ -0,0 +1,30 @@
log_file "mpd_log.txt"
db_file "mpd.db"
bind_to_address "any"
music_directory "Music"
playlist_directory "Playlists"
port "6600"
audio_output {
type "null"
name "Enabled output to be disabled"
enabled "true"
mixer_type "none"
}
audio_output {
type "null"
name "Disabled output to be enabled"
enabled "false"
mixer_type "none"
}
audio_output {
type "null"
name "Enabled output to be toggled"
enabled "true"
mixer_type "none"
}

View File

@ -0,0 +1,88 @@
Apr 12 14:17 : client: [0] opened from 127.0.0.1:65192
Apr 12 14:17 : client: [0] expired
Apr 12 14:17 : client: [0] closed
Apr 12 14:17 : client: [1] opened from 127.0.0.1:65193
Apr 12 14:17 : client: [1] expired
Apr 12 14:17 : client: [1] closed
Apr 12 14:17 : client: [2] opened from 127.0.0.1:65194
Apr 12 14:17 : client: [2] expired
Apr 12 14:17 : client: [2] closed
Apr 12 14:17 : client: [3] opened from 127.0.0.1:65195
Apr 12 14:17 : client: [3] expired
Apr 12 14:17 : client: [3] closed
Apr 12 14:18 : client: [4] opened from 127.0.0.1:65196
Apr 12 14:18 : client: [4] expired
Apr 12 14:18 : client: [4] closed
Apr 12 14:18 : client: [5] opened from 127.0.0.1:65203
Apr 12 14:18 : client: [5] expired
Apr 12 14:18 : client: [5] closed
Apr 12 14:19 : client: [6] opened from 127.0.0.1:65204
Apr 12 14:19 : client: [6] process command "stats"
Apr 12 14:19 : client: [6] command returned 0
Apr 12 14:19 : client: [6] expired
Apr 12 14:19 : client: [6] closed
Apr 12 14:20 : client: [7] opened from 127.0.0.1:65220
Apr 12 14:20 : client: [7] process command "stats"
Apr 12 14:20 : client: [7] command returned 0
Apr 12 14:20 : client: [7] expired
Apr 12 14:20 : client: [7] closed
Apr 12 14:20 : client: [8] opened from 127.0.0.1:65221
Apr 12 14:20 : client: [8] process command "status"
Apr 12 14:20 : client: [8] command returned 0
Apr 12 14:20 : client: [8] expired
Apr 12 14:20 : client: [8] closed
Apr 12 14:23 : client: [9] opened from 127.0.0.1:65226
Apr 12 14:23 : client: [9] process command "stats"
Apr 12 14:23 : client: [9] command returned 0
Apr 12 14:23 : client: [9] expired
Apr 12 14:23 : client: [9] closed
Apr 12 14:23 : client: [10] opened from 127.0.0.1:65227
Apr 12 14:23 : client: [10] process command "stats"
Apr 12 14:23 : client: [10] command returned 0
Apr 12 14:23 : client: [10] expired
Apr 12 14:23 : client: [10] closed
Apr 12 14:23 : client: [11] opened from 127.0.0.1:65228
Apr 12 14:23 : client: [11] process command "stats"
Apr 12 14:23 : client: [11] command returned 0
Apr 12 14:23 : client: [11] expired
Apr 12 14:23 : client: [11] closed
Apr 12 14:23 : client: [12] opened from 127.0.0.1:65229
Apr 12 14:23 : client: [12] process command "status"
Apr 12 14:23 : client: [12] command returned 0
Apr 12 14:23 : client: [12] expired
Apr 12 14:23 : client: [12] closed
Apr 12 14:23 : client: [13] opened from 127.0.0.1:65230
Apr 12 14:23 : client: [13] process command "stats"
Apr 12 14:23 : client: [13] command returned 0
Apr 12 14:23 : client: [13] expired
Apr 12 14:23 : client: [13] closed
Apr 12 14:25 : client: [14] opened from 127.0.0.1:65236
Apr 12 14:25 : client: [14] process command "listplaylists"
Apr 12 14:25 : client: [14] command returned 0
Apr 12 14:25 : client: [14] expired
Apr 12 14:25 : client: [14] closed
Apr 12 14:28 : client: [15] opened from 127.0.0.1:65383
Apr 12 14:28 : client: [15] process command "listplaylists"
Apr 12 14:28 : client: [15] command returned 0
Apr 12 14:28 : client: [15] expired
Apr 12 14:28 : client: [15] closed
Apr 12 14:29 : client: [16] opened from 127.0.0.1:65385
Apr 12 14:29 : client: [16] process command "listplaylistinfo Playlist One"
Apr 12 14:29 : client: [16] command returned -1
Apr 12 14:29 : client: [16] expired
Apr 12 14:29 : client: [16] closed
Apr 12 14:29 : client: [17] opened from 127.0.0.1:65386
Apr 12 14:29 : client: [17] process command "listplaylistinfo "Playlist One""
Apr 12 14:29 : database: get song: teaspoon-stirring-mug-of-coffee.mp3
Apr 12 14:29 : database: get song: whistle-kettle-boiling.mp3
Apr 12 14:29 : database: get song: wine-glass-double-chink-clink-cheers.mp3
Apr 12 14:29 : database: get song: Directory With Spaces/coin-spin-light.mp3
Apr 12 14:29 : database: get song: Directory With Spaces/finger-snap-click.mp3
Apr 12 14:29 : client: [17] command returned 0
Apr 12 14:29 : client: [17] expired
Apr 12 14:29 : client: [17] closed
Apr 12 14:32 : client: [18] opened from 127.0.0.1:65446
Apr 12 14:32 : client: [18] process command "statstastats"
Apr 12 14:32 : client: [18] command returned -1
Apr 12 14:32 : client: [18] process command "stats"
Apr 12 14:3

View File

@ -1,12 +1,18 @@
using System;
using MpcNET.Message;
namespace MpcNET.Test
{
internal class TestOutput
internal static class TestOutput
{
internal static void WriteLine(string value)
{
Console.Out.WriteLine(value);
}
internal static void WriteLine<T>(IMpdMessage<T> message)
{
Console.Out.WriteLine(message.ToString());
}
}
}

View File

@ -2,7 +2,6 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MpcNET.Tags;
using Newtonsoft.Json;
namespace MpcNET.Test
{
@ -14,7 +13,7 @@ namespace MpcNET.Test
var response = await Mpc.SendAsync(new Commands.Database.ListAll());
TestOutput.WriteLine("ListAllTest Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
Assert.IsTrue(response.Response.Body.Count().Equals(7));
}
@ -22,10 +21,10 @@ namespace MpcNET.Test
[TestMethod]
public async Task FindGenreTest()
{
var response = await Test.LibMpcTest.Mpc.SendAsync(new Commands.Database.Find(MpdTags.Genre, "soundfx"));
var response = await Mpc.SendAsync(new Commands.Database.Find(MpdTags.Genre, "soundfx"));
TestOutput.WriteLine("FindGenreTest Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
Assert.IsTrue(response.Response.Body.Count().Equals(7));
}

View File

@ -0,0 +1,16 @@
using MpcNET.Message;
namespace MpcNET.Test
{
public static class MpdMessageExtension
{
public static bool HasSuccessResponse<T>(this IMpdMessage<T> message)
{
return message.Response.State.Connected &&
message.Response.State.Status == "OK" &&
!message.Response.State.Error &&
message.Response.State.ErrorMessage == string.Empty &&
message.Response.State.MpdError == string.Empty;
}
}
}

View File

@ -1,7 +1,6 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
namespace MpcNET.Test
{
@ -16,7 +15,7 @@ namespace MpcNET.Test
var response = await Mpc.SendAsync(new Commands.Output.DisableOutput(0));
TestOutput.WriteLine("DisableOutputTest Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
Assert.IsTrue(response.Response.Body.Equals(string.Empty));
Assert.IsTrue(response.Response.State.Status.Equals("OK"));
@ -35,7 +34,7 @@ namespace MpcNET.Test
var response = await Mpc.SendAsync(new Commands.Output.EnableOutput(1));
TestOutput.WriteLine("EnableOutputTest Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
Assert.IsTrue(response.Response.Body.Equals(string.Empty));
Assert.IsTrue(response.Response.State.Status.Equals("OK"));
@ -53,7 +52,7 @@ namespace MpcNET.Test
var response = await Mpc.SendAsync(new Commands.Output.ToggleOutput(2));
TestOutput.WriteLine("ToggleOutputTest Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
Assert.IsTrue(response.Response.Body.Equals(string.Empty));
Assert.IsTrue(response.Response.State.Status.Equals("OK"));
@ -68,7 +67,7 @@ namespace MpcNET.Test
var response = await Mpc.SendAsync(new Commands.Output.Outputs());
TestOutput.WriteLine("LisOutputsTest Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
Assert.IsTrue(response.Response.Body.Count().Equals(3));
}

View File

@ -1,7 +1,6 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
namespace MpcNET.Test
{
@ -13,10 +12,10 @@ namespace MpcNET.Test
[DataRow("_My Playlist", 5)]
public async Task ListPlaylistTest(string playlistName, int numberOfFiles)
{
var response = await Mpc.SendAsync(new Commands.Playlists.Stored.ListPlaylist(playlistName));
var response = await Mpc.SendAsync(Commands.Playlists.Stored.GetContent(playlistName));
TestOutput.WriteLine($"ListPlaylistTest (playlistName: {playlistName}) Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
Assert.IsTrue(response.Response.Body.Count().Equals(numberOfFiles));
}
@ -27,10 +26,10 @@ namespace MpcNET.Test
[DataRow("_My Playlist", 5)]
public async Task ListPlaylistInfoTest(string playlistName, int numberOfFiles)
{
var response = await Mpc.SendAsync(new Commands.Playlists.Stored.ListPlaylistInfo(playlistName));
var response = await Mpc.SendAsync(Commands.Playlists.Stored.GetContentWithMetadata(playlistName));
TestOutput.WriteLine($"ListPlaylistTest (playlistName: {playlistName}) Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
Assert.IsTrue(response.Response.Body.Count().Equals(numberOfFiles));
Assert.IsTrue(response.Response.Body.All(item => !string.IsNullOrEmpty(item.Artist)));
@ -41,12 +40,134 @@ namespace MpcNET.Test
[TestMethod]
public async Task ListPlaylistsTest()
{
var response = await Mpc.SendAsync(new Commands.Playlists.Stored.ListPlaylists());
var response = await Mpc.SendAsync(Commands.Playlists.Stored.GetAll());
TestOutput.WriteLine($"ListPlaylistsTest Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
Assert.IsTrue(response.Response.Body.Count().Equals(3));
}
/// <summary>
/// These tests must run sequential because we have only one "Current Queue"
/// </summary>
[TestMethod]
public async Task QueueTests()
{
await LoadPlaylistTest();
await ClearPlaylistTest();
await AddDirectoryTest();
await AddFileTest();
await RemovePositionTest();
await RemoveIdTest();
}
public async Task LoadPlaylistTest()
{
await Clear_Queue();
await Check_Empty_Queue();
await Load_Playlist("Playlist One");
await Check_Queue_HasSongs(5);
}
public async Task ClearPlaylistTest()
{
await Clear_Queue();
await Check_Empty_Queue();
await Load_Playlist("Playlist One");
await Clear_Queue();
await Check_Queue_HasSongs(0);
}
public async Task AddDirectoryTest()
{
await Clear_Queue();
await Check_Empty_Queue();
await Add_Directory("Directory With Spaces");
await Check_Queue_HasSongs(3);
}
public async Task AddFileTest()
{
await Clear_Queue();
await Check_Empty_Queue();
await Add_File("teaspoon-stirring-mug-of-coffee.mp3");
await Check_Queue_HasSongs(1);
}
public async Task RemovePositionTest()
{
await Clear_Queue();
await Check_Empty_Queue();
await Add_File("teaspoon-stirring-mug-of-coffee.mp3");
await Remove_Position(0);
await Check_Queue_HasSongs(0);
}
public async Task RemoveIdTest()
{
await Clear_Queue();
await Check_Empty_Queue();
await Add_File("teaspoon-stirring-mug-of-coffee.mp3");
var id = await Get_Song_Id();
await Remove_Id(id);
await Check_Queue_HasSongs(0);
}
private async Task Check_Empty_Queue()
{
var message = await Mpc.SendAsync(Commands.Playlists.Current.GetAllSongsInfo());
Assert.IsTrue(message.HasSuccessResponse());
Assert.IsFalse(message.Response.Body.Any());
}
private async Task Load_Playlist(string playlistName)
{
var message = await Mpc.SendAsync(Commands.Playlists.Stored.Load(playlistName));
Assert.IsTrue(message.HasSuccessResponse());
}
private async Task Clear_Queue()
{
var message = await Mpc.SendAsync(Commands.Playlists.Current.Clear());
Assert.IsTrue(message.HasSuccessResponse());
}
private async Task Check_Queue_HasSongs(int nrOfSongs)
{
var message = await Mpc.SendAsync(Commands.Playlists.Current.GetAllSongsInfo());
Assert.IsTrue(message.HasSuccessResponse());
Assert.IsTrue(message.Response.Body.Count() == nrOfSongs);
}
private async Task Add_Directory(string directory)
{
var message = await Mpc.SendAsync(Commands.Playlists.Current.AddDirectory(directory));
Assert.IsTrue(message.HasSuccessResponse());
}
private async Task Add_File(string file)
{
var message = await Mpc.SendAsync(Commands.Playlists.Current.AddSong(file));
Assert.IsTrue(message.HasSuccessResponse());
}
private async Task Remove_Position(int position)
{
var message = await Mpc.SendAsync(Commands.Playlists.Current.RemoveSongByPosition(position));
Assert.IsTrue(message.HasSuccessResponse());
}
private async Task Remove_Id(int songId)
{
var message = await Mpc.SendAsync(Commands.Playlists.Current.RemoveSongById(songId));
Assert.IsTrue(message.HasSuccessResponse());
}
private async Task<int> Get_Song_Id()
{
var message = await Mpc.SendAsync(Commands.Playlists.Current.GetAllSongMetadata());
return message.Response.Body.Single().Id;
}
}
}

View File

@ -1,7 +1,6 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
namespace MpcNET.Test
{
@ -13,7 +12,7 @@ namespace MpcNET.Test
var response = await Mpc.SendAsync(new Commands.Reflection.Commands());
TestOutput.WriteLine($"CommandsTest (commands: {response.Response.Body.Count()}) Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
// Different answer from MPD on Windows and on Linux, beacuse of Version.
// Check some of the commands.
@ -31,7 +30,7 @@ namespace MpcNET.Test
var response = await Mpc.SendAsync(new Commands.Reflection.TagTypes());
TestOutput.WriteLine("TagTypesTest Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
Assert.IsTrue(response.Response.Body.Count().Equals(17));
}
@ -42,7 +41,7 @@ namespace MpcNET.Test
var response = await Mpc.SendAsync(new Commands.Reflection.UrlHandlers());
TestOutput.WriteLine($"UrlHandlersTest (handlers: {response.Response.Body.Count()}) Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
// Different answer from MPD on Windows and on Linux.
// Check some of the handlers.
@ -58,7 +57,7 @@ namespace MpcNET.Test
var response = await Mpc.SendAsync(new Commands.Reflection.Decoders());
TestOutput.WriteLine($"DecodersTest (decoders: {response.Response.Body.Count()}) Result:");
TestOutput.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
TestOutput.WriteLine(response);
// Different answer from MPD on Windows and on Linux.
// Check some of the decoders.

View File

@ -5,7 +5,7 @@ using MpcNET.Types;
namespace MpcNET
{
public partial class Commands
public static partial class Commands
{
/// <summary>
/// https://www.musicpd.org/doc/protocol/database.html

View File

@ -3,7 +3,7 @@ using MpcNET.Types;
namespace MpcNET
{
public partial class Commands
public static partial class Commands
{
/// <summary>
/// https://www.musicpd.org/doc/protocol/output_commands.html

View File

@ -4,7 +4,7 @@ using MpcNET.Types;
namespace MpcNET
{
public partial class Commands
public static partial class Commands
{
public static class Playlists
{
@ -13,7 +13,214 @@ namespace MpcNET
/// </summary>
public static class Current
{
/// <summary>
/// Adds the file URI to the playlist (directories add recursively). URI can also be a single file.
/// </summary>
private class AddImpl : IMpcCommand<string>
{
private readonly string _uri;
public AddImpl(string uri)
{
_uri = uri;
}
public string Value => string.Join(" ", "add", $"\"{_uri}\"");
public string FormatResponse(IList<KeyValuePair<string, string>> response)
{
return string.Join(", ", response);
}
}
/// <summary>
/// Command: add
/// </summary>
public static IMpcCommand<string> AddDirectory(string directory) { return new AddImpl(directory); }
/// <summary>
/// Adds a song to the playlist (non-recursive) and returns the song id.
/// </summary>
private class AddIdImpl : IMpcCommand<string>
{
private readonly string _uri;
public AddIdImpl(string uri)
{
_uri = uri;
}
public string Value => string.Join(" ", "addid", $"\"{_uri}\"");
public string FormatResponse(IList<KeyValuePair<string, string>> response)
{
return string.Join(", ", response);
}
}
/// <summary>
/// Command: addid
/// </summary>
public static IMpcCommand<string> AddSong(string songPath) { return new AddIdImpl(songPath); }
/// <summary>
/// Clears the current playlist.
/// </summary>
private class ClearImpl : IMpcCommand<string>
{
public string Value => "clear";
public string FormatResponse(IList<KeyValuePair<string, string>> response)
{
return string.Join(", ", response);
}
}
/// <summary>
/// Command: clear
/// </summary>
public static IMpcCommand<string> Clear() { return new ClearImpl(); }
/// <summary>
/// Displays the current playlist.
/// </summary>
private class PlaylistImpl : IMpcCommand<IEnumerable<IMpdFile>>
{
public string Value => "playlist";
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
{
var results = response.Select(line => new MpdFile(line.Value) { Pos = int.Parse(line.Key) });
return results;
}
}
/// <summary>
/// Command: playlist
/// </summary>
public static IMpcCommand<IEnumerable<IMpdFile>> GetAllSongsInfo() { return new PlaylistImpl(); }
/// <summary>
/// Deletes a song from the playlist.
/// </summary>
private class DeleteImpl : IMpcCommand<string>
{
private readonly int _position;
public DeleteImpl(int position)
{
_position = position;
}
public string Value => string.Join(" ", "delete", _position);
public string FormatResponse(IList<KeyValuePair<string, string>> response)
{
return string.Join(", ", response);
}
}
/// <summary>
/// Command: delete
/// </summary>
public static IMpcCommand<string> RemoveSongByPosition(int position) { return new DeleteImpl(position); }
/// <summary>
/// Deletes the song SONGID from the playlist
/// </summary>
private class DeleteIdImpl : IMpcCommand<string>
{
private readonly int _songId;
public DeleteIdImpl(int songId)
{
_songId = songId;
}
public string Value => string.Join(" ", "deleteid", _songId);
public string FormatResponse(IList<KeyValuePair<string, string>> response)
{
return string.Join(", ", response);
}
}
/// <summary>
/// Command: deleteid
/// </summary>
public static IMpcCommand<string> RemoveSongById(int songId) { return new DeleteIdImpl(songId); }
/// <summary>
/// Displays song ID in the playlist.
/// </summary>
private class PlaylistIdImpl : IMpcCommand<IEnumerable<IMpdFile>>
{
private readonly int _songId;
public PlaylistIdImpl(int songId)
{
_songId = songId;
}
public string Value => string.Join(" ", "playlistid", _songId);
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
{
var results = new List<MpdFile>();
foreach (var line in response)
{
if (line.Key.Equals("file"))
{
results.Add(new MpdFile(line.Value));
}
else
{
results.Last().AddTag(line.Key, line.Value);
}
}
return results;
}
}
/// <summary>
/// Command: playlistid
/// </summary>
public static IMpcCommand<IEnumerable<IMpdFile>> GetSongMetadata(int songId) { return new PlaylistIdImpl(songId); }
/// <summary>
/// Displays a list of all songs in the playlist,
/// </summary>
private class PlaylistInfoImpl : IMpcCommand<IEnumerable<IMpdFile>>
{
public string Value => "playlistinfo";
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
{
var results = new List<MpdFile>();
foreach (var line in response)
{
if (line.Key.Equals("file"))
{
results.Add(new MpdFile(line.Value));
}
else
{
results.Last().AddTag(line.Key, line.Value);
}
}
return results;
}
}
/// <summary>
/// Command: playlistinfo
/// </summary>
public static IMpcCommand<IEnumerable<IMpdFile>> GetAllSongMetadata() { return new PlaylistInfoImpl(); }
}
/// <summary>
@ -21,11 +228,39 @@ namespace MpcNET
/// </summary>
public static class Stored
{
public class ListPlaylist : IMpcCommand<IEnumerable<IMpdFilePath>>
/// <summary>
/// Loads the playlist into the current queue.
/// </summary>
private class LoadImpl : IMpcCommand<string>
{
private readonly string _playlistName;
public ListPlaylist(string playlistName)
public LoadImpl(string playlistName)
{
_playlistName = playlistName;
}
public string Value => string.Join(" ", "load", $"\"{_playlistName}\"");
public string FormatResponse(IList<KeyValuePair<string, string>> response)
{
return string.Join(", ", response);
}
}
/// <summary>
/// Command: load
/// </summary>
public static IMpcCommand<string> Load(string playlistName) { return new LoadImpl(playlistName); }
/// <summary>
/// Lists the songs in the playlist.
/// </summary>
private class ListPlaylistImpl : IMpcCommand<IEnumerable<IMpdFilePath>>
{
private readonly string _playlistName;
public ListPlaylistImpl(string playlistName)
{
_playlistName = playlistName;
}
@ -40,11 +275,19 @@ namespace MpcNET
}
}
public class ListPlaylistInfo : IMpcCommand<IEnumerable<IMpdFile>>
/// <summary>
/// Command: listplaylist
/// </summary>
public static IMpcCommand<IEnumerable<IMpdFilePath>> GetContent(string playlistName) { return new ListPlaylistImpl(playlistName); }
/// <summary>
/// Lists the songs with metadata in the playlist.
/// </summary>
private class ListPlaylistInfoImpl : IMpcCommand<IEnumerable<IMpdFile>>
{
private readonly string _playlistName;
public ListPlaylistInfo(string playlistName)
public ListPlaylistInfoImpl(string playlistName)
{
_playlistName = playlistName;
}
@ -71,10 +314,15 @@ namespace MpcNET
}
}
/// <summary>
/// Command: listplaylistinfo
/// </summary>
public static IMpcCommand<IEnumerable<IMpdFile>> GetContentWithMetadata(string playlistName) { return new ListPlaylistInfoImpl(playlistName); }
/// <summary>
/// Prints a list of the playlist directory.
/// </summary>
public class ListPlaylists : IMpcCommand<IEnumerable<MpdPlaylist>>
private class ListPlaylistsImpl : IMpcCommand<IEnumerable<MpdPlaylist>>
{
public string Value => "listplaylists";
@ -97,6 +345,11 @@ namespace MpcNET
return result;
}
}
/// <summary>
/// Command: listplaylists
/// </summary>
public static IMpcCommand<IEnumerable<MpdPlaylist>> GetAll() { return new ListPlaylistsImpl(); }
}
}
}

View File

@ -4,7 +4,7 @@ using MpcNET.Types;
namespace MpcNET
{
public partial class Commands
public static partial class Commands
{
/// <summary>
/// https://www.musicpd.org/doc/protocol/reflection_commands.html

View File

@ -15,7 +15,7 @@ namespace MpcNET.Message
[DebuggerDisplay("Request: {Request.Command.Value} | Response Status: {Response.State.Status}")]
public class MpdMessage<T> : IMpdMessage<T>
{
private readonly Regex _linePattern = new Regex("^(?<key>[A-Za-z_-]*):[ ]{0,1}(?<value>.*)$");
private readonly Regex _linePattern = new Regex(@"^(?<key>[\w-]*):[ ]{0,1}(?<value>.*)$");
private readonly IList<string> _rawResponse;
public MpdMessage(IMpcCommand<T> command, bool connected, IReadOnlyCollection<string> response)

View File

@ -12,6 +12,10 @@
<RootNamespace>MpcNET</RootNamespace>
</PropertyGroup>
<ItemGroup>
<None Remove="MpcNET.csproj.DotSettings" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>

View File

@ -4,7 +4,7 @@ namespace MpcNET.Types
{
public interface IMpdFilePath
{
string File { get; }
string Path { get; }
}
public interface IMpdFile : IMpdFilePath

View File

@ -29,10 +29,10 @@ namespace MpcNET.Types
{
file.CheckNotNull();
File = file;
Path = file;
}
public string File { get; }
public string Path { get; }
public int Time { get; private set; } = -1;
public string Album { get; private set; } = string.Empty;
public string Artist { get; private set; } = string.Empty;
@ -45,7 +45,7 @@ namespace MpcNET.Types
public string Performer { get; private set; } = string.Empty;
public string Comment { get; private set; } = string.Empty;
public int Disc { get; private set; } = -1;
public int Pos { get; private set; } = -1;
public int Pos { get; set; } = -1;
public int Id { get; private set; } = -1;
public IDictionary<string, string> UnknownMetadata => _unknownMetadata;