mirror of
https://github.com/ZetaKebab/MpcNET.git
synced 2025-07-01 00:37:37 +00:00
Rewrote most of the library
This commit is contained in:
57
Sources/MpcNET.Test/LibMpcTest.cs
Normal file
57
Sources/MpcNET.Test/LibMpcTest.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace MpcNET.Test
|
||||
{
|
||||
[TestClass]
|
||||
public partial class LibMpcTest
|
||||
{
|
||||
private static MpdMock _mpdMock;
|
||||
|
||||
[ClassInitialize]
|
||||
public static void Init(TestContext context)
|
||||
{
|
||||
_mpdMock = new MpdMock();
|
||||
_mpdMock.Start();
|
||||
|
||||
Mpc = new MpcMock().Client;
|
||||
}
|
||||
|
||||
[ClassCleanup]
|
||||
public static void Cleanup()
|
||||
{
|
||||
_mpdMock.Dispose();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
26
Sources/MpcNET.Test/MpcMock.cs
Normal file
26
Sources/MpcNET.Test/MpcMock.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MpcNET.Test
|
||||
{
|
||||
public class MpcMock : IDisposable
|
||||
{
|
||||
public MpcMock()
|
||||
{
|
||||
var mpdEndpoint = new IPEndPoint(IPAddress.Loopback, 6600);
|
||||
Client = new Mpc(mpdEndpoint);
|
||||
|
||||
var connected = Task.Run(async () => await Client.ConnectAsync()).Result;
|
||||
TestOutput.WriteLine($"Connected to MPD : {connected}; Version: {Client.Version}");
|
||||
}
|
||||
|
||||
public Mpc Client { get; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Client?.DisconnectAsync().GetAwaiter().GetResult();
|
||||
TestOutput.WriteLine($"Disconnected from MPD.");
|
||||
}
|
||||
}
|
||||
}
|
40
Sources/MpcNET.Test/MpcNET.Test.csproj
Normal file
40
Sources/MpcNET.Test/MpcNET.Test.csproj
Normal file
@ -0,0 +1,40 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<AssemblyName>MpcNET.Test</AssemblyName>
|
||||
<PackageId>MpcNET.Test</PackageId>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||
<RootNamespace>MpcNET.Test</RootNamespace>
|
||||
<SignAssembly>False</SignAssembly>
|
||||
<DelaySign>True</DelaySign>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="MpcNET.Test.csproj.DotSettings" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Server\**\*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="1.2.0" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="1.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MpcNET\MpcNET.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
57
Sources/MpcNET.Test/MpdConf.cs
Normal file
57
Sources/MpcNET.Test/MpdConf.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace MpcNET.Test
|
||||
{
|
||||
public class MpdConf
|
||||
{
|
||||
private const string MPD_CONF_FILE = "mpd.conf";
|
||||
private const string MPD_LOG_FILE = "mpd_log.txt";
|
||||
private const string MPD_DB_FILE = "mpd.db";
|
||||
|
||||
public static void Create(string rootDirectory)
|
||||
{
|
||||
File.Create(Path.Combine(rootDirectory, MPD_LOG_FILE)).Dispose();
|
||||
|
||||
CreateConfFile(rootDirectory);
|
||||
}
|
||||
|
||||
private static void CreateConfFile(string rootDirectory)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.AppendLine($"log_file \"{Path.Combine(rootDirectory, MPD_LOG_FILE).Replace("\\", "\\\\")}\"");
|
||||
builder.AppendLine($"db_file \"{Path.Combine(rootDirectory, MPD_DB_FILE).Replace("\\", "\\\\")}\"");
|
||||
builder.AppendLine("bind_to_address \"any\"");
|
||||
builder.AppendLine($"music_directory \"{Path.Combine(rootDirectory, "Music").Replace("\\", "\\\\")}\"");
|
||||
builder.AppendLine($"playlist_directory \"{Path.Combine(rootDirectory, "Playlists").Replace("\\", "\\\\")}\"");
|
||||
builder.AppendLine("port \"6600\"");
|
||||
builder.AppendLine("audio_output {");
|
||||
builder.AppendLine("type \"null\"");
|
||||
builder.AppendLine("name \"Enabled output to be disabled\"");
|
||||
builder.AppendLine("enabled \"true\"");
|
||||
builder.AppendLine("mixer_type \"none\"");
|
||||
builder.AppendLine("}");
|
||||
builder.AppendLine("audio_output {");
|
||||
builder.AppendLine("type \"null\"");
|
||||
builder.AppendLine("name \"Disabled output to be enabled\"");
|
||||
builder.AppendLine("enabled \"false\"");
|
||||
builder.AppendLine("mixer_type \"none\"");
|
||||
builder.AppendLine("}");
|
||||
builder.AppendLine("audio_output {");
|
||||
builder.AppendLine("type \"null\"");
|
||||
builder.AppendLine("name \"Enabled output to be toggled\"");
|
||||
builder.AppendLine("enabled \"true\"");
|
||||
builder.AppendLine("mixer_type \"none\"");
|
||||
builder.AppendLine("}");
|
||||
|
||||
var mpdConfContent = builder.ToString();
|
||||
|
||||
using (var file = File.CreateText(Path.Combine(rootDirectory, MPD_CONF_FILE)))
|
||||
{
|
||||
file.Write(mpdConfContent);
|
||||
file.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
119
Sources/MpcNET.Test/MpdMock.cs
Normal file
119
Sources/MpcNET.Test/MpdMock.cs
Normal file
@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MpcNET.Test
|
||||
{
|
||||
public class MpdMock : IDisposable
|
||||
{
|
||||
public void Start()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
SendCommand("/usr/bin/pkill mpd");
|
||||
}
|
||||
|
||||
MpdConf.Create(Path.Combine(AppContext.BaseDirectory, "Server"));
|
||||
|
||||
var server = GetServer();
|
||||
|
||||
Process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = server.FileName,
|
||||
WorkingDirectory = server.WorkingDirectory,
|
||||
Arguments = server.Arguments,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true,
|
||||
}
|
||||
};
|
||||
|
||||
TestOutput.WriteLine($"Starting Server: {Process.StartInfo.FileName} {Process.StartInfo.Arguments}");
|
||||
|
||||
Process.Start();
|
||||
TestOutput.WriteLine($"Output: {Process.StandardOutput.ReadToEnd()}");
|
||||
TestOutput.WriteLine($"Error: {Process.StandardError.ReadToEnd()}");
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
SendCommand("/bin/netstat -ntpl");
|
||||
}
|
||||
}
|
||||
|
||||
public Process Process { get; private set; }
|
||||
|
||||
private Server GetServer()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
return Server.Linux;
|
||||
}
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return Server.Windows;
|
||||
}
|
||||
|
||||
throw new NotSupportedException("OS not supported");
|
||||
}
|
||||
|
||||
private void SendCommand(string command)
|
||||
{
|
||||
var netcat = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "/bin/bash",
|
||||
WorkingDirectory = "/bin/",
|
||||
Arguments = $"-c \"sudo {command}\"",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true,
|
||||
}
|
||||
};
|
||||
|
||||
netcat.Start();
|
||||
netcat.WaitForExit();
|
||||
|
||||
TestOutput.WriteLine(command);
|
||||
TestOutput.WriteLine($"Output: {netcat.StandardOutput.ReadToEnd()}");
|
||||
TestOutput.WriteLine($"Error: {netcat.StandardError.ReadToEnd()}");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Process?.Kill();
|
||||
Process?.Dispose();
|
||||
TestOutput.WriteLine("Server Stopped.");
|
||||
}
|
||||
|
||||
private class Server
|
||||
{
|
||||
public static Server Linux = new Server(
|
||||
fileName: "/bin/bash",
|
||||
workingDirectory: "/bin/",
|
||||
arguments: $"-c \"sudo /usr/bin/mpd {Path.Combine(AppContext.BaseDirectory, "Server", "mpd.conf")} -v\"");
|
||||
|
||||
public static Server Windows = new Server(
|
||||
fileName: Path.Combine(AppContext.BaseDirectory, "Server", "mpd.exe"),
|
||||
workingDirectory: Path.Combine(AppContext.BaseDirectory, "Server"),
|
||||
arguments: $"{Path.Combine(AppContext.BaseDirectory, "Server", "mpd.conf")} -v");
|
||||
|
||||
private Server(string fileName, string workingDirectory, string arguments)
|
||||
{
|
||||
FileName = fileName;
|
||||
WorkingDirectory = workingDirectory;
|
||||
Arguments = arguments;
|
||||
}
|
||||
|
||||
public string FileName { get; }
|
||||
public string WorkingDirectory { get; }
|
||||
public string Arguments { get; }
|
||||
}
|
||||
}
|
||||
}
|
18
Sources/MpcNET.Test/Properties/AssemblyInfo.cs
Normal file
18
Sources/MpcNET.Test/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("LibMpcTest")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("69f1d68f-9cd5-4ea6-9b47-2a7a9bf8ced9")]
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Sources/MpcNET.Test/Server/Music/Directory/2-Kids-Laughing.mp3
Normal file
BIN
Sources/MpcNET.Test/Server/Music/Directory/2-Kids-Laughing.mp3
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Sources/MpcNET.Test/Server/Music/whistle-kettle-boiling.mp3
Normal file
BIN
Sources/MpcNET.Test/Server/Music/whistle-kettle-boiling.mp3
Normal file
Binary file not shown.
Binary file not shown.
BIN
Sources/MpcNET.Test/Server/OpenAL32.dll
Normal file
BIN
Sources/MpcNET.Test/Server/OpenAL32.dll
Normal file
Binary file not shown.
5
Sources/MpcNET.Test/Server/Playlists/Playlist One.m3u
Normal file
5
Sources/MpcNET.Test/Server/Playlists/Playlist One.m3u
Normal file
@ -0,0 +1,5 @@
|
||||
teaspoon-stirring-mug-of-coffee.mp3
|
||||
whistle-kettle-boiling.mp3
|
||||
wine-glass-double-chink-clink-cheers.mp3
|
||||
Directory With Spaces/coin-spin-light.mp3
|
||||
Directory With Spaces/finger-snap-click.mp3
|
3
Sources/MpcNET.Test/Server/Playlists/Playlist Two.m3u
Normal file
3
Sources/MpcNET.Test/Server/Playlists/Playlist Two.m3u
Normal file
@ -0,0 +1,3 @@
|
||||
A long name directory with some spaces/pouring-water-into-mug-of-coffee.mp3
|
||||
A long name directory with some spaces/Sub Directory Two/short-trouser-pants-zip-closing.mp3
|
||||
Directory/2-Kids-Laughing.mp3
|
5
Sources/MpcNET.Test/Server/Playlists/_My Playlist.m3u
Normal file
5
Sources/MpcNET.Test/Server/Playlists/_My Playlist.m3u
Normal file
@ -0,0 +1,5 @@
|
||||
A long name directory with some spaces/Ghost-Sounds.mp3
|
||||
Directory/ambient-noise-server-room.mp3
|
||||
Directory With Spaces/SubDirectory One/central-locking-Ford-Mondeo-Mk-3.mp3
|
||||
_My Directory/gas-fire-lighting.mp3
|
||||
A long name directory with some spaces/Sub Directory Two/starting-engine-Ford-Mondeo-Mk-3-diesel.mp3
|
1
Sources/MpcNET.Test/Server/StartLocal.bat
Normal file
1
Sources/MpcNET.Test/Server/StartLocal.bat
Normal file
@ -0,0 +1 @@
|
||||
mpd.exe mpd.conf -v
|
30
Sources/MpcNET.Test/Server/mpd.conf
Normal file
30
Sources/MpcNET.Test/Server/mpd.conf
Normal 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"
|
||||
}
|
163
Sources/MpcNET.Test/Server/mpd.db
Normal file
163
Sources/MpcNET.Test/Server/mpd.db
Normal file
@ -0,0 +1,163 @@
|
||||
info_begin
|
||||
format: 1
|
||||
mpd_version: 0.17.4
|
||||
fs_charset: cp1252
|
||||
tag: Artist
|
||||
tag: ArtistSort
|
||||
tag: Album
|
||||
tag: AlbumArtist
|
||||
tag: AlbumArtistSort
|
||||
tag: Title
|
||||
tag: Track
|
||||
tag: Name
|
||||
tag: Genre
|
||||
tag: Date
|
||||
tag: Composer
|
||||
tag: Performer
|
||||
tag: Disc
|
||||
tag: MUSICBRAINZ_ARTISTID
|
||||
tag: MUSICBRAINZ_ALBUMID
|
||||
tag: MUSICBRAINZ_ALBUMARTISTID
|
||||
tag: MUSICBRAINZ_TRACKID
|
||||
info_end
|
||||
directory: A long name directory with some spaces
|
||||
mtime: 1482142041
|
||||
begin: A long name directory with some spaces
|
||||
directory: Sub Directory Two
|
||||
mtime: 1482142041
|
||||
begin: A long name directory with some spaces/Sub Directory Two
|
||||
song_begin: short-trouser-pants-zip-closing.mp3
|
||||
Time: 1
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: short trouser pants zip closing
|
||||
Date: 2013
|
||||
Date: 2013
|
||||
mtime: 1481623577
|
||||
song_end
|
||||
song_begin: starting-engine-Ford-Mondeo-Mk-3-diesel.mp3
|
||||
Time: 6
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: starting engine - Ford Mondeo Mk 3 diesel
|
||||
Album: Geek & Dummy Sound Library
|
||||
Date: 2014
|
||||
Genre: soundfx
|
||||
mtime: 1481623577
|
||||
song_end
|
||||
end: A long name directory with some spaces/Sub Directory Two
|
||||
song_begin: pouring-water-into-mug-of-coffee.mp3
|
||||
Time: 4
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: pouring water into mug of coffee
|
||||
Date: 2013
|
||||
Date: 2013
|
||||
mtime: 1481623577
|
||||
song_end
|
||||
song_begin: Ghost-Sounds.mp3
|
||||
Time: 95
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: ghostly haunted house (bells, ghostly laughs & knives sharpened)
|
||||
Album: Geek & Dummy Sound Library
|
||||
Date: 2014
|
||||
Date: 2014
|
||||
Genre: soundfx
|
||||
mtime: 1481623577
|
||||
song_end
|
||||
end: A long name directory with some spaces
|
||||
directory: Directory
|
||||
mtime: 1482142041
|
||||
begin: Directory
|
||||
song_begin: 2-Kids-Laughing.mp3
|
||||
Time: 30
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: two kids laughing
|
||||
Album: Geek & Dummy Sound Library
|
||||
Date: 2014
|
||||
Date: 2014
|
||||
Genre: soundfx
|
||||
mtime: 1481623577
|
||||
song_end
|
||||
song_begin: ambient-noise-server-room.mp3
|
||||
Time: 71
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: ambient noise - server room
|
||||
Album: Geek & Dummy Sound Library
|
||||
Date: 2014
|
||||
Date: 2014
|
||||
Genre: soundfx
|
||||
mtime: 1481623577
|
||||
song_end
|
||||
end: Directory
|
||||
directory: Directory With Spaces
|
||||
mtime: 1482142041
|
||||
begin: Directory With Spaces
|
||||
directory: SubDirectory One
|
||||
mtime: 1482142041
|
||||
begin: Directory With Spaces/SubDirectory One
|
||||
song_begin: central-locking-Ford-Mondeo-Mk-3.mp3
|
||||
Time: 5
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: central locking - Ford Mondeo Mk 3
|
||||
Album: Geek & Dummy Sound Library
|
||||
Date: 2014
|
||||
Date: 2014
|
||||
Genre: soundfx
|
||||
mtime: 1481623577
|
||||
song_end
|
||||
end: Directory With Spaces/SubDirectory One
|
||||
song_begin: coin-spin-light.mp3
|
||||
Time: 5
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: coin spin (light coin)
|
||||
Date: 2013
|
||||
Date: 2013
|
||||
mtime: 1481623577
|
||||
song_end
|
||||
song_begin: finger-snap-click.mp3
|
||||
Time: 0
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: finger snap/click
|
||||
Album: Geek & Dummy Sound Library
|
||||
Date: 2014
|
||||
Date: 2014
|
||||
Genre: soundfx
|
||||
mtime: 1481623577
|
||||
song_end
|
||||
end: Directory With Spaces
|
||||
directory: _My Directory
|
||||
mtime: 1482142041
|
||||
begin: _My Directory
|
||||
song_begin: gas-fire-lighting.mp3
|
||||
Time: 58
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: gas fire lighting and warming up
|
||||
Album: Geek & Dummy Sound Library
|
||||
Date: 2014
|
||||
Date: 2014
|
||||
Genre: soundfx
|
||||
mtime: 1481623577
|
||||
song_end
|
||||
end: _My Directory
|
||||
song_begin: teaspoon-stirring-mug-of-coffee.mp3
|
||||
Time: 4
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: teaspoon stirring mug of coffee
|
||||
Date: 2013
|
||||
Date: 2013
|
||||
mtime: 1481623577
|
||||
song_end
|
||||
song_begin: whistle-kettle-boiling.mp3
|
||||
Time: 36
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: whistle kettle boiling
|
||||
Date: 2013
|
||||
Date: 2013
|
||||
mtime: 1481623577
|
||||
song_end
|
||||
song_begin: wine-glass-double-chink-clink-cheers.mp3
|
||||
Time: 1
|
||||
Artist: Geek & Dummy
|
||||
Title: Sound effect: wine glass double chink/clink/cheers
|
||||
Date: 2013
|
||||
Date: 2013
|
||||
mtime: 1481623577
|
||||
song_end
|
BIN
Sources/MpcNET.Test/Server/mpd.exe
Normal file
BIN
Sources/MpcNET.Test/Server/mpd.exe
Normal file
Binary file not shown.
88
Sources/MpcNET.Test/Server/mpd_log.txt
Normal file
88
Sources/MpcNET.Test/Server/mpd_log.txt
Normal 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
|
BIN
Sources/MpcNET.Test/Server/openal-info.exe
Normal file
BIN
Sources/MpcNET.Test/Server/openal-info.exe
Normal file
Binary file not shown.
BIN
Sources/MpcNET.Test/Server/winmm-info.exe
Normal file
BIN
Sources/MpcNET.Test/Server/winmm-info.exe
Normal file
Binary file not shown.
18
Sources/MpcNET.Test/TestOutput.cs
Normal file
18
Sources/MpcNET.Test/TestOutput.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using MpcNET.Message;
|
||||
|
||||
namespace MpcNET.Test
|
||||
{
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
33
Sources/MpcNET.Test/Tests/DatabaseCommandsTest.cs
Normal file
33
Sources/MpcNET.Test/Tests/DatabaseCommandsTest.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MpcNET.Commands;
|
||||
using MpcNET.Tags;
|
||||
|
||||
namespace MpcNET.Test
|
||||
{
|
||||
public partial class LibMpcTest
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task ListAllTest()
|
||||
{
|
||||
var response = await Mpc.SendAsync(Command.Database.ListAll());
|
||||
|
||||
TestOutput.WriteLine("ListAllTest Result:");
|
||||
TestOutput.WriteLine(response);
|
||||
|
||||
Assert.IsTrue(response.Response.Body.Count().Equals(7));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task FindGenreTest()
|
||||
{
|
||||
var response = await Mpc.SendAsync(Command.Database.Find(MpdTags.Genre, "soundfx"));
|
||||
|
||||
TestOutput.WriteLine("FindGenreTest Result:");
|
||||
TestOutput.WriteLine(response);
|
||||
|
||||
Assert.IsTrue(response.Response.Body.Count().Equals(7));
|
||||
}
|
||||
}
|
||||
}
|
16
Sources/MpcNET.Test/Tests/MpdMessageExtension.cs
Normal file
16
Sources/MpcNET.Test/Tests/MpdMessageExtension.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
76
Sources/MpcNET.Test/Tests/OutputCommandsTest.cs
Normal file
76
Sources/MpcNET.Test/Tests/OutputCommandsTest.cs
Normal file
@ -0,0 +1,76 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MpcNET.Commands;
|
||||
|
||||
namespace MpcNET.Test
|
||||
{
|
||||
public partial class LibMpcTest
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task DisableOutputTest()
|
||||
{
|
||||
var responseOutputs = await Mpc.SendAsync(Command.Output.Outputs());
|
||||
Assert.IsTrue(responseOutputs.Response.Body.Single(output => output.Id.Equals(0)).IsEnabled);
|
||||
|
||||
var response = await Mpc.SendAsync(Command.Output.DisableOutput(0));
|
||||
|
||||
TestOutput.WriteLine("DisableOutputTest Result:");
|
||||
TestOutput.WriteLine(response);
|
||||
|
||||
Assert.IsTrue(response.Response.Body.Equals(string.Empty));
|
||||
Assert.IsTrue(response.Response.State.Status.Equals("OK"));
|
||||
|
||||
responseOutputs = await Mpc.SendAsync(Command.Output.Outputs());
|
||||
Assert.IsFalse(responseOutputs.Response.Body.Single(output => output.Id.Equals(0)).IsEnabled);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task EnableOutputTest()
|
||||
{
|
||||
var responseOutputs = await Mpc.SendAsync(Command.Output.Outputs());
|
||||
// By default should be disable from mpd.config
|
||||
Assert.IsFalse(responseOutputs.Response.Body.Single(output => output.Id.Equals(1)).IsEnabled);
|
||||
|
||||
var response = await Mpc.SendAsync(Command.Output.EnableOutput(1));
|
||||
|
||||
TestOutput.WriteLine("EnableOutputTest Result:");
|
||||
TestOutput.WriteLine(response);
|
||||
|
||||
Assert.IsTrue(response.Response.Body.Equals(string.Empty));
|
||||
Assert.IsTrue(response.Response.State.Status.Equals("OK"));
|
||||
|
||||
responseOutputs = await Mpc.SendAsync(Command.Output.Outputs());
|
||||
Assert.IsTrue(responseOutputs.Response.Body.Single(output => output.Id.Equals(1)).IsEnabled);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ToggleOutputTest()
|
||||
{
|
||||
var responseOutputs = await Mpc.SendAsync(Command.Output.Outputs());
|
||||
Assert.IsTrue(responseOutputs.Response.Body.Single(output => output.Id.Equals(2)).IsEnabled);
|
||||
|
||||
var response = await Mpc.SendAsync(Command.Output.ToggleOutput(2));
|
||||
|
||||
TestOutput.WriteLine("ToggleOutputTest Result:");
|
||||
TestOutput.WriteLine(response);
|
||||
|
||||
Assert.IsTrue(response.Response.Body.Equals(string.Empty));
|
||||
Assert.IsTrue(response.Response.State.Status.Equals("OK"));
|
||||
|
||||
responseOutputs = await Mpc.SendAsync(Command.Output.Outputs());
|
||||
Assert.IsFalse(responseOutputs.Response.Body.Single(output => output.Id.Equals(2)).IsEnabled);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task LisOutputsTest()
|
||||
{
|
||||
var response = await Mpc.SendAsync(Command.Output.Outputs());
|
||||
|
||||
TestOutput.WriteLine("LisOutputsTest Result:");
|
||||
TestOutput.WriteLine(response);
|
||||
|
||||
Assert.IsTrue(response.Response.Body.Count().Equals(3));
|
||||
}
|
||||
}
|
||||
}
|
174
Sources/MpcNET.Test/Tests/PlaylistsCommandsTest.cs
Normal file
174
Sources/MpcNET.Test/Tests/PlaylistsCommandsTest.cs
Normal file
@ -0,0 +1,174 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MpcNET.Commands;
|
||||
|
||||
namespace MpcNET.Test
|
||||
{
|
||||
public partial class LibMpcTest
|
||||
{
|
||||
[DataTestMethod]
|
||||
[DataRow("Playlist One", 5)]
|
||||
[DataRow("Playlist Two", 3)]
|
||||
[DataRow("_My Playlist", 5)]
|
||||
public async Task ListPlaylistTest(string playlistName, int numberOfFiles)
|
||||
{
|
||||
var response = await Mpc.SendAsync(Command.Playlists.Stored.GetContent(playlistName));
|
||||
|
||||
TestOutput.WriteLine($"ListPlaylistTest (playlistName: {playlistName}) Result:");
|
||||
TestOutput.WriteLine(response);
|
||||
|
||||
Assert.IsTrue(response.Response.Body.Count().Equals(numberOfFiles));
|
||||
}
|
||||
|
||||
[DataTestMethod]
|
||||
[DataRow("Playlist One", 5)]
|
||||
[DataRow("Playlist Two", 3)]
|
||||
[DataRow("_My Playlist", 5)]
|
||||
public async Task ListPlaylistInfoTest(string playlistName, int numberOfFiles)
|
||||
{
|
||||
var response = await Mpc.SendAsync(Command.Playlists.Stored.GetContentWithMetadata(playlistName));
|
||||
|
||||
TestOutput.WriteLine($"ListPlaylistTest (playlistName: {playlistName}) Result:");
|
||||
TestOutput.WriteLine(response);
|
||||
|
||||
Assert.IsTrue(response.Response.Body.Count().Equals(numberOfFiles));
|
||||
Assert.IsTrue(response.Response.Body.All(item => !string.IsNullOrEmpty(item.Artist)));
|
||||
Assert.IsTrue(response.Response.Body.All(item => !string.IsNullOrEmpty(item.Title)));
|
||||
Assert.IsTrue(response.Response.Body.All(item => !string.IsNullOrEmpty(item.Date)));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ListPlaylistsTest()
|
||||
{
|
||||
var response = await Mpc.SendAsync(Command.Playlists.Stored.GetAll());
|
||||
|
||||
TestOutput.WriteLine($"ListPlaylistsTest Result:");
|
||||
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(Command.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(Command.Playlists.Stored.Load(playlistName));
|
||||
Assert.IsTrue(message.HasSuccessResponse());
|
||||
}
|
||||
|
||||
private async Task Clear_Queue()
|
||||
{
|
||||
var message = await Mpc.SendAsync(Command.Playlists.Current.Clear());
|
||||
Assert.IsTrue(message.HasSuccessResponse());
|
||||
}
|
||||
|
||||
private async Task Check_Queue_HasSongs(int nrOfSongs)
|
||||
{
|
||||
var message = await Mpc.SendAsync(Command.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(Command.Playlists.Current.AddDirectory(directory));
|
||||
Assert.IsTrue(message.HasSuccessResponse());
|
||||
}
|
||||
|
||||
private async Task Add_File(string file)
|
||||
{
|
||||
var message = await Mpc.SendAsync(Command.Playlists.Current.AddSong(file));
|
||||
Assert.IsTrue(message.HasSuccessResponse());
|
||||
}
|
||||
|
||||
private async Task Remove_Position(int position)
|
||||
{
|
||||
var message = await Mpc.SendAsync(Command.Playlists.Current.RemoveSongByPosition(position));
|
||||
Assert.IsTrue(message.HasSuccessResponse());
|
||||
}
|
||||
|
||||
private async Task Remove_Id(int songId)
|
||||
{
|
||||
var message = await Mpc.SendAsync(Command.Playlists.Current.RemoveSongById(songId));
|
||||
Assert.IsTrue(message.HasSuccessResponse());
|
||||
}
|
||||
|
||||
private async Task<int> Get_Song_Id()
|
||||
{
|
||||
var message = await Mpc.SendAsync(Command.Playlists.Current.GetAllSongMetadata());
|
||||
return message.Response.Body.Single().Id;
|
||||
}
|
||||
}
|
||||
}
|
79
Sources/MpcNET.Test/Tests/ReflectionCommandsTest.cs
Normal file
79
Sources/MpcNET.Test/Tests/ReflectionCommandsTest.cs
Normal file
@ -0,0 +1,79 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MpcNET.Commands;
|
||||
|
||||
namespace MpcNET.Test
|
||||
{
|
||||
public partial class LibMpcTest
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task CommandsTest()
|
||||
{
|
||||
var response = await Mpc.SendAsync(Command.Reflection.Commands());
|
||||
|
||||
TestOutput.WriteLine($"CommandsTest (commands: {response.Response.Body.Count()}) Result:");
|
||||
TestOutput.WriteLine(response);
|
||||
|
||||
// Different answer from MPD on Windows and on Linux, beacuse of Version.
|
||||
// Check some of the commands.
|
||||
Assert.IsTrue(response.Response.Body.Any(command => command.Equals("listall")));
|
||||
Assert.IsTrue(response.Response.Body.Any(command => command.Equals("outputs")));
|
||||
Assert.IsTrue(response.Response.Body.Any(command => command.Equals("pause")));
|
||||
Assert.IsTrue(response.Response.Body.Any(command => command.Equals("play")));
|
||||
Assert.IsTrue(response.Response.Body.Any(command => command.Equals("setvol")));
|
||||
Assert.IsTrue(response.Response.Body.Any(command => command.Equals("stop")));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TagTypesTest()
|
||||
{
|
||||
var response = await Mpc.SendAsync(Command.Reflection.TagTypes());
|
||||
|
||||
TestOutput.WriteLine("TagTypesTest Result:");
|
||||
TestOutput.WriteLine(response);
|
||||
|
||||
Assert.IsTrue(response.Response.Body.Count().Equals(17));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task UrlHandlersTest()
|
||||
{
|
||||
var response = await Mpc.SendAsync(Command.Reflection.UrlHandlers());
|
||||
|
||||
TestOutput.WriteLine($"UrlHandlersTest (handlers: {response.Response.Body.Count()}) Result:");
|
||||
TestOutput.WriteLine(response);
|
||||
|
||||
// Different answer from MPD on Windows and on Linux.
|
||||
// Check some of the handlers.
|
||||
Assert.IsTrue(response.Response.Body.Any(handler => handler.Equals("http://")));
|
||||
Assert.IsTrue(response.Response.Body.Any(handler => handler.Equals("mms://")));
|
||||
Assert.IsTrue(response.Response.Body.Any(handler => handler.Equals("gopher://")));
|
||||
Assert.IsTrue(response.Response.Body.Any(handler => handler.Equals("rtp://")));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task DecodersTest()
|
||||
{
|
||||
var response = await Mpc.SendAsync(Command.Reflection.Decoders());
|
||||
|
||||
TestOutput.WriteLine($"DecodersTest (decoders: {response.Response.Body.Count()}) Result:");
|
||||
TestOutput.WriteLine(response);
|
||||
|
||||
// Different answer from MPD on Windows and on Linux.
|
||||
// Check some of the decoders.
|
||||
Assert.IsTrue(response.Response.Body.Any(decoder => decoder.Name.Equals("mad")));
|
||||
Assert.IsTrue(response.Response.Body.Any(decoder => decoder.Suffixes.Any(suffix => suffix.Equals("mp3"))));
|
||||
Assert.IsTrue(response.Response.Body.Any(decoder => decoder.MediaTypes.Any(mediaType => mediaType.Equals("audio/mpeg"))));
|
||||
Assert.IsTrue(response.Response.Body.Any(decoder => decoder.Name.Equals("flac")));
|
||||
Assert.IsTrue(response.Response.Body.Any(decoder => decoder.Suffixes.Any(suffix => suffix.Equals("flac"))));
|
||||
Assert.IsTrue(response.Response.Body.Any(decoder => decoder.MediaTypes.Any(mediaType => mediaType.Equals("audio/flac"))));
|
||||
Assert.IsTrue(response.Response.Body.Any(decoder => decoder.MediaTypes.Any(mediaType => mediaType.Equals("audio/x-flac"))));
|
||||
Assert.IsTrue(response.Response.Body.Any(decoder => decoder.Name.Equals("ffmpeg")));
|
||||
Assert.IsTrue(response.Response.Body.Any(decoder => decoder.Suffixes.Any(suffix => suffix.Equals("aac"))));
|
||||
Assert.IsTrue(response.Response.Body.Any(decoder => decoder.Suffixes.Any(suffix => suffix.Equals("mpeg"))));
|
||||
Assert.IsTrue(response.Response.Body.Any(decoder => decoder.MediaTypes.Any(mediaType => mediaType.Equals("audio/aac"))));
|
||||
Assert.IsTrue(response.Response.Body.Any(decoder => decoder.MediaTypes.Any(mediaType => mediaType.Equals("audio/mpeg"))));
|
||||
}
|
||||
}
|
||||
}
|
33
Sources/MpcNET.sln
Normal file
33
Sources/MpcNET.sln
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26403.3
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Utilities", "Solution Utilities", "{83D06F7C-1336-4AC3-82BB-FDE7940D3C10}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.travis.yml = .travis.yml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MpcNET", "MpcNET\MpcNET.csproj", "{8994C820-7BA9-4BB8-B9EA-C608B07C4A11}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MpcNET.Test", "MpcNET.Test\MpcNET.Test.csproj", "{69F1D68F-9CD5-4EA6-9B47-2A7A9BF8CED9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8994C820-7BA9-4BB8-B9EA-C608B07C4A11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8994C820-7BA9-4BB8-B9EA-C608B07C4A11}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8994C820-7BA9-4BB8-B9EA-C608B07C4A11}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8994C820-7BA9-4BB8-B9EA-C608B07C4A11}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{69F1D68F-9CD5-4EA6-9B47-2A7A9BF8CED9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{69F1D68F-9CD5-4EA6-9B47-2A7A9BF8CED9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{69F1D68F-9CD5-4EA6-9B47-2A7A9BF8CED9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{69F1D68F-9CD5-4EA6-9B47-2A7A9BF8CED9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
74
Sources/MpcNET/CommandFactory.cs
Normal file
74
Sources/MpcNET/CommandFactory.cs
Normal file
@ -0,0 +1,74 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace MpcNET
|
||||
{
|
||||
using MpcNET.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Provides MPD commands.
|
||||
/// </summary>
|
||||
/// <seealso cref="MpcNET.ICommandFactory" />
|
||||
public class CommandFactory : ICommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the status command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The status.
|
||||
/// </value>
|
||||
public IStatusCommandFactory Status { get; } = new StatusCommandFactory();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the database command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The database.
|
||||
/// </value>
|
||||
public IDatabaseCommandFactory Database { get; } = new DatabaseCommandFactory();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reflection command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The reflection.
|
||||
/// </value>
|
||||
public IReflectionCommandFactory Reflection { get; } = new ReflectionCommandFactory();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stored playlist command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The stored playlist.
|
||||
/// </value>
|
||||
public IStoredPlaylistCommandFactory StoredPlaylist { get; } = new StoredPlaylistCommandFactory();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current playlist command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current playlist.
|
||||
/// </value>
|
||||
public ICurrentPlaylistCommandFactory CurrentPlaylist { get; } = new CurrentPlaylistCommandFactory();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the playback command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The playback.
|
||||
/// </value>
|
||||
public IPlaybackCommandFactory Playback { get; } = new PlaybackCommandFactory();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the output command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The output.
|
||||
/// </value>
|
||||
public IOutputCommandFactory Output { get; } = new OutputCommandFactory();
|
||||
}
|
||||
}
|
95
Sources/MpcNET/Commands/CurrentPlaylistCommandFactory.cs
Normal file
95
Sources/MpcNET/Commands/CurrentPlaylistCommandFactory.cs
Normal file
@ -0,0 +1,95 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CurrentPlaylistCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Commands.Playlist;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.musicpd.org/doc/protocol/queue.html
|
||||
/// </summary>
|
||||
public class CurrentPlaylistCommandFactory : ICurrentPlaylistCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Command: add
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory.</param>
|
||||
/// <returns>An <see cref="AddCommand"/>.</returns>
|
||||
public IMpcCommand<string> AddDirectory(string directory)
|
||||
{
|
||||
return new AddCommand(directory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command: addid
|
||||
/// </summary>
|
||||
/// <param name="songPath">The song path.</param>
|
||||
/// <returns>An <see cref="AddIdCommand"/>.</returns>
|
||||
public IMpcCommand<string> AddSong(string songPath)
|
||||
{
|
||||
return new AddIdCommand(songPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command: clear
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="ClearCommand"/>.</returns>
|
||||
public IMpcCommand<string> Clear()
|
||||
{
|
||||
return new ClearCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command: playlist
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="PlaylistCommand"/>.</returns>
|
||||
public IMpcCommand<IEnumerable<IMpdFile>> GetAllSongsInfo()
|
||||
{
|
||||
return new PlaylistCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command: delete
|
||||
/// </summary>
|
||||
/// <param name="position">The position.</param>
|
||||
/// <returns>A <see cref="DeleteCommand" />.</returns>
|
||||
public IMpcCommand<string> RemoveSongByPosition(int position)
|
||||
{
|
||||
return new DeleteCommand(position);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command: deleteid
|
||||
/// </summary>
|
||||
/// <param name="songId">The song identifier.</param>
|
||||
/// <returns>A <see cref="DeleteIdCommand"/>.</returns>
|
||||
public IMpcCommand<string> RemoveSongById(int songId)
|
||||
{
|
||||
return new DeleteIdCommand(songId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command: playlistid
|
||||
/// </summary>
|
||||
/// <param name="songId">The song identifier.</param>
|
||||
/// <returns>A <see cref="PlaylistIdCommand" />.</returns>
|
||||
public IMpcCommand<IEnumerable<IMpdFile>> GetSongMetadata(int songId)
|
||||
{
|
||||
return new PlaylistIdCommand(songId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command: playlistinfo
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="PlaylistInfoCommand" />.</returns>
|
||||
public IMpcCommand<IEnumerable<IMpdFile>> GetAllSongMetadata()
|
||||
{
|
||||
return new PlaylistInfoCommand();
|
||||
}
|
||||
}
|
||||
}
|
36
Sources/MpcNET/Commands/Database/FindCommand.cs
Normal file
36
Sources/MpcNET/Commands/Database/FindCommand.cs
Normal file
@ -0,0 +1,36 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="FindCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Database
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Tags;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Finds songs in the database that is exactly "searchText".
|
||||
/// </summary>
|
||||
internal class FindCommand : IMpcCommand<IEnumerable<IMpdFile>>
|
||||
{
|
||||
private readonly ITag tag;
|
||||
private readonly string searchText;
|
||||
|
||||
public FindCommand(ITag tag, string searchText)
|
||||
{
|
||||
this.tag = tag;
|
||||
this.searchText = searchText;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", "find", this.tag.Value, this.searchText);
|
||||
|
||||
public IEnumerable<IMpdFile> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return MpdFile.CreateList(response);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: rescan
|
||||
}
|
46
Sources/MpcNET/Commands/Database/ListAllCommand.cs
Normal file
46
Sources/MpcNET/Commands/Database/ListAllCommand.cs
Normal file
@ -0,0 +1,46 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ListAllCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Database
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Lists all songs and directories in URI.
|
||||
/// </summary>
|
||||
internal class ListAllCommand : IMpcCommand<IEnumerable<MpdDirectory>>
|
||||
{
|
||||
public string Serialize() => "listall";
|
||||
|
||||
public IEnumerable<MpdDirectory> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
var rootDirectory = new List<MpdDirectory>
|
||||
{
|
||||
new MpdDirectory("/") // Add by default the root directory
|
||||
};
|
||||
|
||||
foreach (var line in response)
|
||||
{
|
||||
if (line.Key.Equals("file"))
|
||||
{
|
||||
rootDirectory.Last().AddFile(line.Value);
|
||||
}
|
||||
|
||||
if (line.Key.Equals("directory"))
|
||||
{
|
||||
rootDirectory.Add(new MpdDirectory(line.Value));
|
||||
}
|
||||
}
|
||||
|
||||
return rootDirectory;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: findadd
|
||||
// TODO: rescan
|
||||
}
|
31
Sources/MpcNET/Commands/Database/ListCommand.cs
Normal file
31
Sources/MpcNET/Commands/Database/ListCommand.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ListCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Database
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Tags;
|
||||
|
||||
internal class ListCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly ITag tag;
|
||||
|
||||
public ListCommand(ITag tag)
|
||||
{
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", "list", this.tag);
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
// TODO:
|
||||
return response.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: rescan
|
||||
}
|
46
Sources/MpcNET/Commands/Database/UpdateCommand.cs
Normal file
46
Sources/MpcNET/Commands/Database/UpdateCommand.cs
Normal file
@ -0,0 +1,46 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UpdateCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Database
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
internal class UpdateCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly string uri;
|
||||
|
||||
public UpdateCommand(string uri)
|
||||
{
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public string Serialize()
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.uri))
|
||||
{
|
||||
return "update";
|
||||
}
|
||||
|
||||
var newUri = this.uri;
|
||||
if (this.uri.StartsWith(@""""))
|
||||
{
|
||||
newUri = @"""" + this.uri;
|
||||
}
|
||||
|
||||
if (this.uri.EndsWith(@""""))
|
||||
{
|
||||
newUri = this.uri + @"""";
|
||||
}
|
||||
|
||||
return string.Join(" ", "update", newUri);
|
||||
}
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
52
Sources/MpcNET/Commands/DatabaseCommandFactory.cs
Normal file
52
Sources/MpcNET/Commands/DatabaseCommandFactory.cs
Normal file
@ -0,0 +1,52 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="DatabaseCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Commands.Database;
|
||||
using MpcNET.Tags;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.musicpd.org/doc/protocol/database.html
|
||||
/// </summary>
|
||||
public class DatabaseCommandFactory : IDatabaseCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Finds the specified tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <param name="searchText">The search text.</param>
|
||||
/// <returns>An <see cref="FindCommand"/>.</returns>
|
||||
public IMpcCommand<IEnumerable<IMpdFile>> Find(ITag tag, string searchText)
|
||||
{
|
||||
return new FindCommand(tag, searchText);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified URI.
|
||||
/// </summary>
|
||||
/// <param name="uri">The URI.</param>
|
||||
/// <returns>An <see cref="UpdateCommand"/>.</returns>
|
||||
public IMpcCommand<string> Update(string uri = null)
|
||||
{
|
||||
return new UpdateCommand(uri);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lists all.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="ListAllCommand"/>.</returns>
|
||||
public IMpcCommand<IEnumerable<MpdDirectory>> ListAll()
|
||||
{
|
||||
return new ListAllCommand();
|
||||
}
|
||||
|
||||
// TODO: count
|
||||
// TODO: rescan
|
||||
}
|
||||
}
|
71
Sources/MpcNET/Commands/ICurrentPlaylistCommandFactory.cs
Normal file
71
Sources/MpcNET/Commands/ICurrentPlaylistCommandFactory.cs
Normal file
@ -0,0 +1,71 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ICurrentPlaylistCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Commands.Playlist;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Provides current playlist commands.
|
||||
/// </summary>
|
||||
public interface ICurrentPlaylistCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Command: add
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory.</param>
|
||||
/// <returns>An <see cref="AddCommand"/>.</returns>
|
||||
IMpcCommand<string> AddDirectory(string directory);
|
||||
|
||||
/// <summary>
|
||||
/// Command: addid
|
||||
/// </summary>
|
||||
/// <param name="songPath">The song path.</param>
|
||||
/// <returns>An <see cref="AddIdCommand"/>.</returns>
|
||||
IMpcCommand<string> AddSong(string songPath);
|
||||
|
||||
/// <summary>
|
||||
/// Command: clear
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="ClearCommand"/>.</returns>
|
||||
IMpcCommand<string> Clear();
|
||||
|
||||
/// <summary>
|
||||
/// Command: playlist
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="PlaylistCommand"/>.</returns>
|
||||
IMpcCommand<IEnumerable<IMpdFile>> GetAllSongsInfo();
|
||||
|
||||
/// <summary>
|
||||
/// Command: delete
|
||||
/// </summary>
|
||||
/// <param name="position">The position.</param>
|
||||
/// <returns>A <see cref="DeleteCommand" />.</returns>
|
||||
IMpcCommand<string> RemoveSongByPosition(int position);
|
||||
|
||||
/// <summary>
|
||||
/// Command: deleteid
|
||||
/// </summary>
|
||||
/// <param name="songId">The song identifier.</param>
|
||||
/// <returns>A <see cref="DeleteIdCommand"/>.</returns>
|
||||
IMpcCommand<string> RemoveSongById(int songId);
|
||||
|
||||
/// <summary>
|
||||
/// Command: playlistid
|
||||
/// </summary>
|
||||
/// <param name="songId">The song identifier.</param>
|
||||
/// <returns>A <see cref="PlaylistIdCommand" />.</returns>
|
||||
IMpcCommand<IEnumerable<IMpdFile>> GetSongMetadata(int songId);
|
||||
|
||||
/// <summary>
|
||||
/// Command: playlistinfo
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="PlaylistInfoCommand" />.</returns>
|
||||
IMpcCommand<IEnumerable<IMpdFile>> GetAllSongMetadata();
|
||||
}
|
||||
}
|
40
Sources/MpcNET/Commands/IDatabaseCommandFactory.cs
Normal file
40
Sources/MpcNET/Commands/IDatabaseCommandFactory.cs
Normal file
@ -0,0 +1,40 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IDatabaseCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Commands.Database;
|
||||
using MpcNET.Tags;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Provides database commands.
|
||||
/// </summary>
|
||||
public interface IDatabaseCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Finds the specified tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <param name="searchText">The search text.</param>
|
||||
/// <returns>An <see cref="FindCommand"/>.</returns>
|
||||
IMpcCommand<IEnumerable<IMpdFile>> Find(ITag tag, string searchText);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified URI.
|
||||
/// </summary>
|
||||
/// <param name="uri">The URI.</param>
|
||||
/// <returns>An <see cref="UpdateCommand"/>.</returns>
|
||||
IMpcCommand<string> Update(string uri = null);
|
||||
|
||||
/// <summary>
|
||||
/// Lists all.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="ListAllCommand"/>.</returns>
|
||||
IMpcCommand<IEnumerable<MpdDirectory>> ListAll();
|
||||
}
|
||||
}
|
45
Sources/MpcNET/Commands/IOutputCommandFactory.cs
Normal file
45
Sources/MpcNET/Commands/IOutputCommandFactory.cs
Normal file
@ -0,0 +1,45 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IOutputCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Commands.Output;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Provides output commands.
|
||||
/// </summary>
|
||||
public interface IOutputCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Outputses this instance.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="OutputsCommand"/>.</returns>
|
||||
IMpcCommand<IEnumerable<MpdOutput>> Outputs();
|
||||
|
||||
/// <summary>
|
||||
/// Disables the output.
|
||||
/// </summary>
|
||||
/// <param name="outputId">The output identifier.</param>
|
||||
/// <returns>A <see cref="DisableOutputCommand"/>.</returns>
|
||||
IMpcCommand<string> DisableOutput(int outputId);
|
||||
|
||||
/// <summary>
|
||||
/// Enables the output.
|
||||
/// </summary>
|
||||
/// <param name="outputId">The output identifier.</param>
|
||||
/// <returns>A <see cref="EnableOutputCommand"/>.</returns>
|
||||
IMpcCommand<string> EnableOutput(int outputId);
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the output.
|
||||
/// </summary>
|
||||
/// <param name="outputId">The output identifier.</param>
|
||||
/// <returns>A <see cref="ToggleOutputCommand"/>.</returns>
|
||||
IMpcCommand<string> ToggleOutput(int outputId);
|
||||
}
|
||||
}
|
71
Sources/MpcNET/Commands/IPlaybackCommandFactory.cs
Normal file
71
Sources/MpcNET/Commands/IPlaybackCommandFactory.cs
Normal file
@ -0,0 +1,71 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IPlaybackCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using MpcNET.Commands.Playback;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Provides playback commands.
|
||||
/// </summary>
|
||||
public interface IPlaybackCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Get a next command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="NextCommand"/>.</returns>
|
||||
IMpcCommand<string> Next();
|
||||
|
||||
/// <summary>
|
||||
/// Get a previous command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="StopCommand"/>.</returns>
|
||||
IMpcCommand<string> Previous();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a play-pause command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="PlayPauseCommand"/>.</returns>
|
||||
IMpcCommand<string> PlayPause();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a play command.
|
||||
/// </summary>
|
||||
/// <param name="mpdFile">The MPD file.</param>
|
||||
/// <returns>A <see cref="PlayCommand"/>.</returns>
|
||||
IMpcCommand<string> Play(IMpdFile mpdFile);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a play command.
|
||||
/// </summary>
|
||||
/// <param name="position">The position.</param>
|
||||
/// <returns>A <see cref="PlayCommand"/>.</returns>
|
||||
IMpcCommand<string> Play(int position);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a play command.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>A <see cref="PlayCommand"/>.</returns>
|
||||
IMpcCommand<string> PlayId(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a stop command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="StopCommand"/>.</returns>
|
||||
IMpcCommand<string> Stop();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the volume.
|
||||
/// </summary>
|
||||
/// <param name="volume">The volume.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="SetVolumeCommand" />.
|
||||
/// </returns>
|
||||
IMpcCommand<string> SetVolume(byte volume);
|
||||
}
|
||||
}
|
42
Sources/MpcNET/Commands/IReflectionCommandFactory.cs
Normal file
42
Sources/MpcNET/Commands/IReflectionCommandFactory.cs
Normal file
@ -0,0 +1,42 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IReflectionCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Commands.Reflection;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Provides reflection commands.
|
||||
/// </summary>
|
||||
public interface IReflectionCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a commands command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="CommandsCommand"/>.</returns>
|
||||
IMpcCommand<IEnumerable<string>> Commands();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a tag types command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="TagTypesCommand"/>.</returns>
|
||||
IMpcCommand<IEnumerable<string>> TagTypes();
|
||||
|
||||
/// <summary>
|
||||
/// Gets URL handlers command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="UrlHandlersCommand"/>.</returns>
|
||||
IMpcCommand<IEnumerable<string>> UrlHandlers();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a decoders command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="DecodersCommand"/>.</returns>
|
||||
IMpcCommand<IEnumerable<MpdDecoderPlugin>> Decoders();
|
||||
}
|
||||
}
|
29
Sources/MpcNET/Commands/IStatusCommandFactory.cs
Normal file
29
Sources/MpcNET/Commands/IStatusCommandFactory.cs
Normal file
@ -0,0 +1,29 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IStatusCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using MpcNET.Commands.Status;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Provides status commands.
|
||||
/// </summary>
|
||||
public interface IStatusCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a status command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="StatusCommand"/>.</returns>
|
||||
IMpcCommand<MpdStatus> GetStatus();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a current song command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="CurrentSongCommand"/>.</returns>
|
||||
IMpcCommand<IMpdFile> GetCurrentSong();
|
||||
}
|
||||
}
|
45
Sources/MpcNET/Commands/IStoredPlaylistCommandFactory.cs
Normal file
45
Sources/MpcNET/Commands/IStoredPlaylistCommandFactory.cs
Normal file
@ -0,0 +1,45 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IStoredPlaylistCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Commands.Playlist;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Provides stored playlist commands.
|
||||
/// </summary>
|
||||
public interface IStoredPlaylistCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Command: load
|
||||
/// </summary>
|
||||
/// <param name="playlistName">Name of the playlist.</param>
|
||||
/// <returns>A <see cref="LoadCommand" />.</returns>
|
||||
IMpcCommand<string> Load(string playlistName);
|
||||
|
||||
/// <summary>
|
||||
/// Command: listplaylist
|
||||
/// </summary>
|
||||
/// <param name="playlistName">Name of the playlist.</param>
|
||||
/// <returns>A <see cref="ListPlaylistCommand" />.</returns>
|
||||
IMpcCommand<IEnumerable<IMpdFilePath>> GetContent(string playlistName);
|
||||
|
||||
/// <summary>
|
||||
/// Command: listplaylistinfo
|
||||
/// </summary>
|
||||
/// <param name="playlistName">Name of the playlist.</param>
|
||||
/// <returns>A <see cref="ListPlaylistInfoCommand" />.</returns>
|
||||
IMpcCommand<IEnumerable<IMpdFile>> GetContentWithMetadata(string playlistName);
|
||||
|
||||
/// <summary>
|
||||
/// Command: listplaylists
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="ListPlaylistsCommand" />.</returns>
|
||||
IMpcCommand<IEnumerable<MpdPlaylist>> GetAll();
|
||||
}
|
||||
}
|
31
Sources/MpcNET/Commands/Output/DisableOutputCommand.cs
Normal file
31
Sources/MpcNET/Commands/Output/DisableOutputCommand.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="DisableOutputCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Output
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Turns an output off.
|
||||
/// </summary>
|
||||
internal class DisableOutputCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly int outputId;
|
||||
|
||||
public DisableOutputCommand(int outputId)
|
||||
{
|
||||
this.outputId = outputId;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", "disableoutput", this.outputId);
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
// Response should be empty.
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
31
Sources/MpcNET/Commands/Output/EnableOutputCommand.cs
Normal file
31
Sources/MpcNET/Commands/Output/EnableOutputCommand.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="EnableOutputCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Output
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Turns an output on.
|
||||
/// </summary>
|
||||
internal class EnableOutputCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly int outputId;
|
||||
|
||||
public EnableOutputCommand(int outputId)
|
||||
{
|
||||
this.outputId = outputId;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", "enableoutput", this.outputId);
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
// Response should be empty.
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
35
Sources/MpcNET/Commands/Output/OutputsCommand.cs
Normal file
35
Sources/MpcNET/Commands/Output/OutputsCommand.cs
Normal file
@ -0,0 +1,35 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="OutputsCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Output
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Shows information about all outputs.
|
||||
/// </summary>
|
||||
internal class OutputsCommand : IMpcCommand<IEnumerable<MpdOutput>>
|
||||
{
|
||||
public string Serialize() => "outputs";
|
||||
|
||||
public IEnumerable<MpdOutput> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
var result = new List<MpdOutput>();
|
||||
|
||||
for (var i = 0; i < response.Count; i += 3)
|
||||
{
|
||||
var outputId = int.Parse(response[i].Value);
|
||||
var outputName = response[i + 1].Value;
|
||||
var outputEnabled = response[i + 2].Value == "1";
|
||||
|
||||
result.Add(new MpdOutput(outputId, outputName, outputEnabled));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
30
Sources/MpcNET/Commands/Output/ToggleOutputCommand.cs
Normal file
30
Sources/MpcNET/Commands/Output/ToggleOutputCommand.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ToggleOutputCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Output
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Turns an output on or off, depending on the current state.
|
||||
/// </summary>
|
||||
internal class ToggleOutputCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly int outputId;
|
||||
|
||||
public ToggleOutputCommand(int outputId)
|
||||
{
|
||||
this.outputId = outputId;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", "toggleoutput", this.outputId);
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
57
Sources/MpcNET/Commands/OutputCommandFactory.cs
Normal file
57
Sources/MpcNET/Commands/OutputCommandFactory.cs
Normal file
@ -0,0 +1,57 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="OutputCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Commands.Output;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.musicpd.org/doc/protocol/output_commands.html
|
||||
/// </summary>
|
||||
public class OutputCommandFactory : IOutputCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Outputses this instance.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="OutputsCommand"/>.</returns>
|
||||
public IMpcCommand<IEnumerable<MpdOutput>> Outputs()
|
||||
{
|
||||
return new OutputsCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the output.
|
||||
/// </summary>
|
||||
/// <param name="outputId">The output identifier.</param>
|
||||
/// <returns>A <see cref="DisableOutputCommand"/>.</returns>
|
||||
public IMpcCommand<string> DisableOutput(int outputId)
|
||||
{
|
||||
return new DisableOutputCommand(outputId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the output.
|
||||
/// </summary>
|
||||
/// <param name="outputId">The output identifier.</param>
|
||||
/// <returns>A <see cref="EnableOutputCommand"/>.</returns>
|
||||
public IMpcCommand<string> EnableOutput(int outputId)
|
||||
{
|
||||
return new EnableOutputCommand(outputId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the output.
|
||||
/// </summary>
|
||||
/// <param name="outputId">The output identifier.</param>
|
||||
/// <returns>A <see cref="ToggleOutputCommand"/>.</returns>
|
||||
public IMpcCommand<string> ToggleOutput(int outputId)
|
||||
{
|
||||
return new ToggleOutputCommand(outputId);
|
||||
}
|
||||
}
|
||||
}
|
20
Sources/MpcNET/Commands/Playback/NextCommand.cs
Normal file
20
Sources/MpcNET/Commands/Playback/NextCommand.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="NextCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playback
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
internal class NextCommand : IMpcCommand<string>
|
||||
{
|
||||
public string Serialize() => string.Join(" ", "next");
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
43
Sources/MpcNET/Commands/Playback/PlayCommand.cs
Normal file
43
Sources/MpcNET/Commands/Playback/PlayCommand.cs
Normal file
@ -0,0 +1,43 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PlayCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playback
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Types;
|
||||
|
||||
internal class PlayCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly int position;
|
||||
private readonly int id;
|
||||
|
||||
public PlayCommand(int position, int id)
|
||||
{
|
||||
this.position = position;
|
||||
this.id = id;
|
||||
if (this.position == MpdFile.NoPos && this.id == MpdFile.NoId)
|
||||
{
|
||||
throw new ArgumentException("PlayCommand requires Id or Position");
|
||||
}
|
||||
}
|
||||
|
||||
public string Serialize()
|
||||
{
|
||||
if (this.id != MpdFile.NoId)
|
||||
{
|
||||
return string.Join(" ", "playid", this.id);
|
||||
}
|
||||
|
||||
return string.Join(" ", "play", this.position);
|
||||
}
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
20
Sources/MpcNET/Commands/Playback/PlayPauseCommand.cs
Normal file
20
Sources/MpcNET/Commands/Playback/PlayPauseCommand.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PlayPauseCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playback
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
internal class PlayPauseCommand : IMpcCommand<string>
|
||||
{
|
||||
public string Serialize() => string.Join(" ", "pause");
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
20
Sources/MpcNET/Commands/Playback/PreviousCommand.cs
Normal file
20
Sources/MpcNET/Commands/Playback/PreviousCommand.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PreviousCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playback
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
internal class PreviousCommand : IMpcCommand<string>
|
||||
{
|
||||
public string Serialize() => string.Join(" ", "previous");
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
31
Sources/MpcNET/Commands/Playback/SetVolumeCommand.cs
Normal file
31
Sources/MpcNET/Commands/Playback/SetVolumeCommand.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="SetVolumeCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace MpcNET.Commands.Playback
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
internal class SetVolumeCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly byte volume;
|
||||
|
||||
public SetVolumeCommand(byte volume)
|
||||
{
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
public string Serialize()
|
||||
{
|
||||
return string.Join(" ", "setvol", this.volume);
|
||||
}
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
20
Sources/MpcNET/Commands/Playback/StopCommand.cs
Normal file
20
Sources/MpcNET/Commands/Playback/StopCommand.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="StopCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playback
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
internal class StopCommand : IMpcCommand<string>
|
||||
{
|
||||
public string Serialize() => string.Join(" ", "stop");
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
95
Sources/MpcNET/Commands/PlaybackCommandFactory.cs
Normal file
95
Sources/MpcNET/Commands/PlaybackCommandFactory.cs
Normal file
@ -0,0 +1,95 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PlaybackCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using MpcNET.Commands.Playback;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.musicpd.org/doc/protocol/playback_commands.html
|
||||
/// </summary>
|
||||
public class PlaybackCommandFactory : IPlaybackCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Get a next command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="NextCommand"/>.</returns>
|
||||
public IMpcCommand<string> Next()
|
||||
{
|
||||
return new NextCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a previous command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="StopCommand"/>.</returns>
|
||||
public IMpcCommand<string> Previous()
|
||||
{
|
||||
return new PreviousCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a play-pause command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="PlayPauseCommand"/>.</returns>
|
||||
public IMpcCommand<string> PlayPause()
|
||||
{
|
||||
return new PlayPauseCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a play command.
|
||||
/// </summary>
|
||||
/// <param name="mpdFile">The MPD file.</param>
|
||||
/// <returns>A <see cref="PlayCommand"/>.</returns>
|
||||
public IMpcCommand<string> Play(IMpdFile mpdFile)
|
||||
{
|
||||
return new PlayCommand(mpdFile.Id, mpdFile.Position);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a play command.
|
||||
/// </summary>
|
||||
/// <param name="position">The position.</param>
|
||||
/// <returns>A <see cref="PlayCommand"/>.</returns>
|
||||
public IMpcCommand<string> Play(int position)
|
||||
{
|
||||
return new PlayCommand(position, MpdFile.NoId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a play command.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>A <see cref="PlayCommand"/>.</returns>
|
||||
public IMpcCommand<string> PlayId(int id)
|
||||
{
|
||||
return new PlayCommand(MpdFile.NoPos, id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a stop command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="StopCommand"/>.</returns>
|
||||
public IMpcCommand<string> Stop()
|
||||
{
|
||||
return new StopCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the volume.
|
||||
/// </summary>
|
||||
/// <param name="volume">The volume.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="T:MpcNET.Commands.Playback.SetVolumeCommand" />.
|
||||
/// </returns>
|
||||
public IMpcCommand<string> SetVolume(byte volume)
|
||||
{
|
||||
return new SetVolumeCommand(volume);
|
||||
}
|
||||
}
|
||||
}
|
30
Sources/MpcNET/Commands/Playlist/AddCommand.cs
Normal file
30
Sources/MpcNET/Commands/Playlist/AddCommand.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="AddCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playlist
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Adds the file URI to the playlist (directories add recursively). URI can also be a single file.
|
||||
/// </summary>
|
||||
internal class AddCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly string uri;
|
||||
|
||||
public AddCommand(string uri)
|
||||
{
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", "add", $"\"{this.uri}\"");
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
30
Sources/MpcNET/Commands/Playlist/AddIdCommand.cs
Normal file
30
Sources/MpcNET/Commands/Playlist/AddIdCommand.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="AddIdCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playlist
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Adds a song to the playlist (non-recursive) and returns the song id.
|
||||
/// </summary>
|
||||
internal class AddIdCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly string uri;
|
||||
|
||||
public AddIdCommand(string uri)
|
||||
{
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", "addid", $"\"{this.uri}\"");
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
23
Sources/MpcNET/Commands/Playlist/ClearCommand.cs
Normal file
23
Sources/MpcNET/Commands/Playlist/ClearCommand.cs
Normal file
@ -0,0 +1,23 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ClearCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playlist
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current playlist.
|
||||
/// </summary>
|
||||
internal class ClearCommand : IMpcCommand<string>
|
||||
{
|
||||
public string Serialize() => "clear";
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
30
Sources/MpcNET/Commands/Playlist/DeleteCommand.cs
Normal file
30
Sources/MpcNET/Commands/Playlist/DeleteCommand.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="DeleteCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playlist
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a song from the playlist.
|
||||
/// </summary>
|
||||
internal class DeleteCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly int position;
|
||||
|
||||
public DeleteCommand(int position)
|
||||
{
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", "delete", this.position);
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
30
Sources/MpcNET/Commands/Playlist/DeleteIdCommand.cs
Normal file
30
Sources/MpcNET/Commands/Playlist/DeleteIdCommand.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="DeleteIdCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playlist
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the song SONGID from the playlist
|
||||
/// </summary>
|
||||
internal class DeleteIdCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly int songId;
|
||||
|
||||
public DeleteIdCommand(int songId)
|
||||
{
|
||||
this.songId = songId;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", "deleteid", this.songId);
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
34
Sources/MpcNET/Commands/Playlist/ListPlaylistCommand.cs
Normal file
34
Sources/MpcNET/Commands/Playlist/ListPlaylistCommand.cs
Normal file
@ -0,0 +1,34 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ListPlaylistCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playlist
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Lists the songs in the playlist.
|
||||
/// </summary>
|
||||
internal class ListPlaylistCommand : IMpcCommand<IEnumerable<IMpdFilePath>>
|
||||
{
|
||||
private readonly string playlistName;
|
||||
|
||||
public ListPlaylistCommand(string playlistName)
|
||||
{
|
||||
this.playlistName = playlistName;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", "listplaylist", $"\"{this.playlistName}\"");
|
||||
|
||||
public IEnumerable<IMpdFilePath> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
var results = response.Where(line => line.Key.Equals("file")).Select(line => new MpdFile(line.Value));
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
31
Sources/MpcNET/Commands/Playlist/ListPlaylistInfoCommand.cs
Normal file
31
Sources/MpcNET/Commands/Playlist/ListPlaylistInfoCommand.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ListPlaylistInfoCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playlist
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Lists the songs with metadata in the playlist.
|
||||
/// </summary>
|
||||
internal class ListPlaylistInfoCommand : IMpcCommand<IEnumerable<IMpdFile>>
|
||||
{
|
||||
private readonly string playlistName;
|
||||
|
||||
public ListPlaylistInfoCommand(string playlistName)
|
||||
{
|
||||
this.playlistName = playlistName;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", "listplaylistinfo", $"\"{this.playlistName}\"");
|
||||
|
||||
public IEnumerable<IMpdFile> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return MpdFile.CreateList(response);
|
||||
}
|
||||
}
|
||||
}
|
39
Sources/MpcNET/Commands/Playlist/ListPlaylistsCommand.cs
Normal file
39
Sources/MpcNET/Commands/Playlist/ListPlaylistsCommand.cs
Normal file
@ -0,0 +1,39 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ListPlaylistsCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playlist
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Prints a list of the playlist directory.
|
||||
/// </summary>
|
||||
internal class ListPlaylistsCommand : IMpcCommand<IEnumerable<MpdPlaylist>>
|
||||
{
|
||||
public string Serialize() => "listplaylists";
|
||||
|
||||
public IEnumerable<MpdPlaylist> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
var result = new List<MpdPlaylist>();
|
||||
|
||||
foreach (var line in response)
|
||||
{
|
||||
if (line.Key.Equals("playlist"))
|
||||
{
|
||||
result.Add(new MpdPlaylist(line.Value));
|
||||
}
|
||||
else if (line.Key.Equals("Last-Modified"))
|
||||
{
|
||||
result.Last().AddLastModified(line.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
30
Sources/MpcNET/Commands/Playlist/LoadCommand.cs
Normal file
30
Sources/MpcNET/Commands/Playlist/LoadCommand.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="LoadCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playlist
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Loads the playlist into the current queue.
|
||||
/// </summary>
|
||||
internal class LoadCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly string playlistName;
|
||||
|
||||
public LoadCommand(string playlistName)
|
||||
{
|
||||
this.playlistName = playlistName;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", "load", $"\"{this.playlistName}\"");
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
27
Sources/MpcNET/Commands/Playlist/PlaylistCommand.cs
Normal file
27
Sources/MpcNET/Commands/Playlist/PlaylistCommand.cs
Normal file
@ -0,0 +1,27 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PlaylistCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playlist
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Displays the current playlist.
|
||||
/// </summary>
|
||||
internal class PlaylistCommand : IMpcCommand<IEnumerable<IMpdFile>>
|
||||
{
|
||||
public string Serialize() => "playlist";
|
||||
|
||||
public IEnumerable<IMpdFile> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
var results = response.Select(line => MpdFile.Create(line.Value, int.Parse(line.Key)));
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
31
Sources/MpcNET/Commands/Playlist/PlaylistIdCommand.cs
Normal file
31
Sources/MpcNET/Commands/Playlist/PlaylistIdCommand.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PlaylistIdCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playlist
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Displays song ID in the playlist.
|
||||
/// </summary>
|
||||
internal class PlaylistIdCommand : IMpcCommand<IEnumerable<IMpdFile>>
|
||||
{
|
||||
private readonly int songId;
|
||||
|
||||
public PlaylistIdCommand(int songId)
|
||||
{
|
||||
this.songId = songId;
|
||||
}
|
||||
|
||||
public string Serialize() => string.Join(" ", new[] { "playlistid" }, this.songId);
|
||||
|
||||
public IEnumerable<IMpdFile> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return MpdFile.CreateList(response);
|
||||
}
|
||||
}
|
||||
}
|
24
Sources/MpcNET/Commands/Playlist/PlaylistInfoCommand.cs
Normal file
24
Sources/MpcNET/Commands/Playlist/PlaylistInfoCommand.cs
Normal file
@ -0,0 +1,24 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PlaylistInfoCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Playlist
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Displays a list of all songs in the playlist,
|
||||
/// </summary>
|
||||
internal class PlaylistInfoCommand : IMpcCommand<IEnumerable<IMpdFile>>
|
||||
{
|
||||
public string Serialize() => "playlistinfo";
|
||||
|
||||
public IEnumerable<IMpdFile> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return MpdFile.CreateList(response);
|
||||
}
|
||||
}
|
||||
}
|
27
Sources/MpcNET/Commands/Reflection/CommandsCommand.cs
Normal file
27
Sources/MpcNET/Commands/Reflection/CommandsCommand.cs
Normal file
@ -0,0 +1,27 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CommandsCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Reflection
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
/// <summary>
|
||||
/// Shows which commands the current user has access to.
|
||||
/// config : This command is only permitted to "local" clients (connected via UNIX domain socket).
|
||||
/// </summary>
|
||||
internal class CommandsCommand : IMpcCommand<IEnumerable<string>>
|
||||
{
|
||||
public string Serialize() => "commands";
|
||||
|
||||
public IEnumerable<string> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
var result = response.Where(item => item.Key.Equals("command")).Select(item => item.Value);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
50
Sources/MpcNET/Commands/Reflection/DecodersCommand.cs
Normal file
50
Sources/MpcNET/Commands/Reflection/DecodersCommand.cs
Normal file
@ -0,0 +1,50 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="DecodersCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Reflection
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Print a list of decoder plugins, followed by their supported suffixes and MIME types.
|
||||
/// </summary>
|
||||
internal class DecodersCommand : IMpcCommand<IEnumerable<MpdDecoderPlugin>>
|
||||
{
|
||||
public string Serialize() => "decoders";
|
||||
|
||||
public IEnumerable<MpdDecoderPlugin> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
var result = new List<MpdDecoderPlugin>();
|
||||
|
||||
var mpdDecoderPlugin = MpdDecoderPlugin.Empty;
|
||||
foreach (var line in response)
|
||||
{
|
||||
if (line.Key.Equals("plugin"))
|
||||
{
|
||||
if (mpdDecoderPlugin.IsInitialized)
|
||||
{
|
||||
result.Add(mpdDecoderPlugin);
|
||||
}
|
||||
|
||||
mpdDecoderPlugin = new MpdDecoderPlugin(line.Value);
|
||||
}
|
||||
|
||||
if (line.Key.Equals("suffix") && mpdDecoderPlugin.IsInitialized)
|
||||
{
|
||||
mpdDecoderPlugin.AddSuffix(line.Value);
|
||||
}
|
||||
|
||||
if (line.Key.Equals("mime_type") && mpdDecoderPlugin.IsInitialized)
|
||||
{
|
||||
mpdDecoderPlugin.AddMediaType(line.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
28
Sources/MpcNET/Commands/Reflection/TagTypesCommand.cs
Normal file
28
Sources/MpcNET/Commands/Reflection/TagTypesCommand.cs
Normal file
@ -0,0 +1,28 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="TagTypesCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Reflection
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
// TODO: notcommands : Shows which commands the current user does not have access to.
|
||||
|
||||
/// <summary>
|
||||
/// Shows a list of available song metadata.
|
||||
/// </summary>
|
||||
internal class TagTypesCommand : IMpcCommand<IEnumerable<string>>
|
||||
{
|
||||
public string Serialize() => "tagtypes";
|
||||
|
||||
public IEnumerable<string> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
var result = response.Where(item => item.Key.Equals("tagtype")).Select(item => item.Value);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
26
Sources/MpcNET/Commands/Reflection/UrlHandlersCommand.cs
Normal file
26
Sources/MpcNET/Commands/Reflection/UrlHandlersCommand.cs
Normal file
@ -0,0 +1,26 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UrlHandlersCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Reflection
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of available URL handlers.
|
||||
/// </summary>
|
||||
internal class UrlHandlersCommand : IMpcCommand<IEnumerable<string>>
|
||||
{
|
||||
public string Serialize() => "urlhandlers";
|
||||
|
||||
public IEnumerable<string> Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
var result = response.Where(item => item.Key.Equals("handler")).Select(item => item.Value);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
54
Sources/MpcNET/Commands/ReflectionCommandFactory.cs
Normal file
54
Sources/MpcNET/Commands/ReflectionCommandFactory.cs
Normal file
@ -0,0 +1,54 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ReflectionCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Commands.Reflection;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.musicpd.org/doc/protocol/reflection_commands.html
|
||||
/// </summary>
|
||||
public class ReflectionCommandFactory : IReflectionCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a commands command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="CommandsCommand"/>.</returns>
|
||||
public IMpcCommand<IEnumerable<string>> Commands()
|
||||
{
|
||||
return new CommandsCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a tag types command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="TagTypesCommand"/>.</returns>
|
||||
public IMpcCommand<IEnumerable<string>> TagTypes()
|
||||
{
|
||||
return new TagTypesCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets URL handlers command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="UrlHandlersCommand"/>.</returns>
|
||||
public IMpcCommand<IEnumerable<string>> UrlHandlers()
|
||||
{
|
||||
return new UrlHandlersCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a decoders command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="DecodersCommand"/>.</returns>
|
||||
public IMpcCommand<IEnumerable<MpdDecoderPlugin>> Decoders()
|
||||
{
|
||||
return new DecodersCommand();
|
||||
}
|
||||
}
|
||||
}
|
21
Sources/MpcNET/Commands/Status/CurrentSongCommand.cs
Normal file
21
Sources/MpcNET/Commands/Status/CurrentSongCommand.cs
Normal file
@ -0,0 +1,21 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CurrentSongCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Status
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Types;
|
||||
|
||||
internal class CurrentSongCommand : IMpcCommand<IMpdFile>
|
||||
{
|
||||
public string Serialize() => "currentsong";
|
||||
|
||||
public IMpdFile Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return MpdFile.Create(response, 0).mpdFile;
|
||||
}
|
||||
}
|
||||
}
|
35
Sources/MpcNET/Commands/Status/IdleCommand.cs
Normal file
35
Sources/MpcNET/Commands/Status/IdleCommand.cs
Normal file
@ -0,0 +1,35 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IdleCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Status
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
internal class IdleCommand : IMpcCommand<string>
|
||||
{
|
||||
private readonly string subSystem;
|
||||
|
||||
public IdleCommand(string subSystem)
|
||||
{
|
||||
this.subSystem = subSystem;
|
||||
}
|
||||
|
||||
public string Serialize()
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.subSystem))
|
||||
{
|
||||
return "idle";
|
||||
}
|
||||
|
||||
return "idle " + this.subSystem;
|
||||
}
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
20
Sources/MpcNET/Commands/Status/NoIdleCommand.cs
Normal file
20
Sources/MpcNET/Commands/Status/NoIdleCommand.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="NoIdleCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Status
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
internal class NoIdleCommand : IMpcCommand<string>
|
||||
{
|
||||
public string Serialize() => "noidle";
|
||||
|
||||
public string Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
return string.Join(", ", response);
|
||||
}
|
||||
}
|
||||
}
|
167
Sources/MpcNET/Commands/Status/StatusCommand.cs
Normal file
167
Sources/MpcNET/Commands/Status/StatusCommand.cs
Normal file
@ -0,0 +1,167 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="StatusCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands.Status
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
internal class StatusCommand : IMpcCommand<MpdStatus>
|
||||
{
|
||||
private const string VolumeText = "volume";
|
||||
private const string RepeatText = "repeat";
|
||||
private const string RandomText = "random";
|
||||
private const string SingleText = "single";
|
||||
private const string ConsumeText = "consume";
|
||||
private const string PlaylistText = "playlist";
|
||||
private const string PlaylistlengthText = "playlistlength";
|
||||
private const string SongText = "song";
|
||||
private const string SongidText = "songid";
|
||||
private const string NextsongText = "nextsong";
|
||||
private const string NextsongidText = "nextsongid";
|
||||
private const string BitrateText = "bitrate";
|
||||
private const string AudioText = "audio";
|
||||
private const string XfadeText = "xfade";
|
||||
private const string StateText = "state";
|
||||
private const string TimeText = "time";
|
||||
private const string ElapsedText = "elapsed";
|
||||
private const string DurationText = "duration";
|
||||
private const string MixrampDbText = "mixrampdb";
|
||||
private const string UpdatingDbText = "updating_db";
|
||||
|
||||
public string Serialize() => "status";
|
||||
|
||||
public MpdStatus Deserialize(IReadOnlyList<KeyValuePair<string, string>> response)
|
||||
{
|
||||
int volume = -1;
|
||||
bool repeat = false;
|
||||
bool random = false;
|
||||
bool single = false;
|
||||
bool consume = false;
|
||||
int playlist = -1;
|
||||
int playlistLength = 0;
|
||||
int playlistSong = -1;
|
||||
int playlistSongId = -1;
|
||||
int playlistNextSong = -1;
|
||||
int playlistNextSongId = -1;
|
||||
int bitrate = 0;
|
||||
int audioSampleRate = -1;
|
||||
int audioBits = -1;
|
||||
int audioChannels = -1;
|
||||
int crossfade = -1;
|
||||
MpdState mpdState = MpdState.Unknown;
|
||||
TimeSpan elapsed;
|
||||
TimeSpan duration;
|
||||
double mixrampDb = -1;
|
||||
int updatingDb = -1;
|
||||
string error = string.Empty;
|
||||
foreach (var keyValuePair in response)
|
||||
{
|
||||
var value = keyValuePair.Value;
|
||||
switch (keyValuePair.Key)
|
||||
{
|
||||
case VolumeText:
|
||||
int.TryParse(value, out volume);
|
||||
break;
|
||||
case RepeatText:
|
||||
repeat = value == "1";
|
||||
break;
|
||||
case RandomText:
|
||||
random = value == "1";
|
||||
break;
|
||||
case SingleText:
|
||||
single = value == "1";
|
||||
break;
|
||||
case ConsumeText:
|
||||
consume = value == "1";
|
||||
break;
|
||||
case PlaylistText:
|
||||
int.TryParse(value, out playlist);
|
||||
break;
|
||||
case PlaylistlengthText:
|
||||
int.TryParse(value, out playlistLength);
|
||||
break;
|
||||
case SongText:
|
||||
int.TryParse(value, out playlistSong);
|
||||
break;
|
||||
case SongidText:
|
||||
int.TryParse(value, out playlistSongId);
|
||||
break;
|
||||
case NextsongText:
|
||||
int.TryParse(value, out playlistNextSong);
|
||||
break;
|
||||
case NextsongidText:
|
||||
int.TryParse(value, out playlistNextSongId);
|
||||
break;
|
||||
case BitrateText:
|
||||
int.TryParse(value, out bitrate);
|
||||
break;
|
||||
case AudioText:
|
||||
var audioFormat = value.Split(':');
|
||||
int.TryParse(audioFormat[0], out audioSampleRate);
|
||||
int.TryParse(audioFormat[1], out audioBits);
|
||||
int.TryParse(audioFormat[2], out audioChannels);
|
||||
break;
|
||||
case XfadeText:
|
||||
int.TryParse(value, out crossfade);
|
||||
break;
|
||||
case StateText:
|
||||
Enum.TryParse(value, true, out mpdState);
|
||||
break;
|
||||
case ElapsedText:
|
||||
elapsed = ParseTime(value);
|
||||
break;
|
||||
case TimeText:
|
||||
break;
|
||||
case DurationText:
|
||||
duration = ParseTime(value);
|
||||
break;
|
||||
case MixrampDbText:
|
||||
double.TryParse(value, out mixrampDb);
|
||||
break;
|
||||
case UpdatingDbText:
|
||||
int.TryParse(value, out updatingDb);
|
||||
break;
|
||||
default:
|
||||
Debug.WriteLine($"Unprocessed status: {keyValuePair.Key} - {keyValuePair.Value}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new MpdStatus(
|
||||
volume,
|
||||
repeat,
|
||||
random,
|
||||
consume,
|
||||
single,
|
||||
playlist,
|
||||
playlistLength,
|
||||
crossfade,
|
||||
mpdState,
|
||||
playlistSong,
|
||||
playlistSongId,
|
||||
playlistNextSong,
|
||||
playlistNextSongId,
|
||||
elapsed,
|
||||
duration,
|
||||
bitrate,
|
||||
audioSampleRate,
|
||||
audioBits,
|
||||
audioChannels,
|
||||
updatingDb,
|
||||
error);
|
||||
}
|
||||
|
||||
private static TimeSpan ParseTime(string value)
|
||||
{
|
||||
var timeParts = value.Split(new[] { '.' }, 2);
|
||||
int.TryParse(timeParts[0], out var seconds);
|
||||
int.TryParse(timeParts[1], out var milliseconds);
|
||||
return TimeSpan.FromSeconds(seconds) + TimeSpan.FromMilliseconds(milliseconds);
|
||||
}
|
||||
}
|
||||
}
|
35
Sources/MpcNET/Commands/StatusCommandFactory.cs
Normal file
35
Sources/MpcNET/Commands/StatusCommandFactory.cs
Normal file
@ -0,0 +1,35 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="StatusCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using MpcNET.Commands.Status;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.musicpd.org/doc/protocol/command_reference.html#status_commands
|
||||
/// </summary>
|
||||
public class StatusCommandFactory : IStatusCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a status command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="StatusCommand"/>.</returns>
|
||||
public IMpcCommand<MpdStatus> GetStatus()
|
||||
{
|
||||
return new StatusCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a current song command.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="CurrentSongCommand"/>.</returns>
|
||||
public IMpcCommand<IMpdFile> GetCurrentSong()
|
||||
{
|
||||
return new CurrentSongCommand();
|
||||
}
|
||||
}
|
||||
}
|
57
Sources/MpcNET/Commands/StoredPlaylistCommandFactory.cs
Normal file
57
Sources/MpcNET/Commands/StoredPlaylistCommandFactory.cs
Normal file
@ -0,0 +1,57 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="StoredPlaylistCommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Commands
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using MpcNET.Commands.Playlist;
|
||||
using MpcNET.Types;
|
||||
|
||||
/// <summary>
|
||||
/// https://www.musicpd.org/doc/protocol/playlist_files.html
|
||||
/// </summary>
|
||||
public class StoredPlaylistCommandFactory : IStoredPlaylistCommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Command: load
|
||||
/// </summary>
|
||||
/// <param name="playlistName">Name of the playlist.</param>
|
||||
/// <returns>A <see cref="LoadCommand" />.</returns>
|
||||
public IMpcCommand<string> Load(string playlistName)
|
||||
{
|
||||
return new LoadCommand(playlistName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command: listplaylist
|
||||
/// </summary>
|
||||
/// <param name="playlistName">Name of the playlist.</param>
|
||||
/// <returns>A <see cref="ListPlaylistCommand" />.</returns>
|
||||
public IMpcCommand<IEnumerable<IMpdFilePath>> GetContent(string playlistName)
|
||||
{
|
||||
return new ListPlaylistCommand(playlistName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command: listplaylistinfo
|
||||
/// </summary>
|
||||
/// <param name="playlistName">Name of the playlist.</param>
|
||||
/// <returns>A <see cref="ListPlaylistInfoCommand" />.</returns>
|
||||
public IMpcCommand<IEnumerable<IMpdFile>> GetContentWithMetadata(string playlistName)
|
||||
{
|
||||
return new ListPlaylistInfoCommand(playlistName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command: listplaylists
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="ListPlaylistsCommand" />.</returns>
|
||||
public IMpcCommand<IEnumerable<MpdPlaylist>> GetAll()
|
||||
{
|
||||
return new ListPlaylistsCommand();
|
||||
}
|
||||
}
|
||||
}
|
17
Sources/MpcNET/Constants.cs
Normal file
17
Sources/MpcNET/Constants.cs
Normal file
@ -0,0 +1,17 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="Constants.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET
|
||||
{
|
||||
internal class Constants
|
||||
{
|
||||
public static readonly string Ok = "OK";
|
||||
|
||||
public static readonly string Ack = "ACK";
|
||||
|
||||
public static readonly string FirstLinePrefix = "OK MPD ";
|
||||
}
|
||||
}
|
20
Sources/MpcNET/Exceptions/CommandNullException.cs
Normal file
20
Sources/MpcNET/Exceptions/CommandNullException.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CommandNullException.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Thrown by <see cref="MpcConnection"/> when the command is null.
|
||||
/// </summary>
|
||||
/// <seealso cref="System.Exception" />
|
||||
public class CommandNullException : MpcException
|
||||
{
|
||||
internal CommandNullException()
|
||||
: base("No command was specified")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
26
Sources/MpcNET/Exceptions/EmptyResponseException.cs
Normal file
26
Sources/MpcNET/Exceptions/EmptyResponseException.cs
Normal file
@ -0,0 +1,26 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="EmptyResponseException.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Exceptions
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Exception throw when an empty response is received.
|
||||
/// </summary>
|
||||
/// <seealso cref="Exception" />
|
||||
public class EmptyResponseException : MpcException
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EmptyResponseException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="command">The command.</param>
|
||||
public EmptyResponseException(string command)
|
||||
: base($"The command: {command} returned no response")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
26
Sources/MpcNET/Exceptions/MpcConnectException.cs
Normal file
26
Sources/MpcNET/Exceptions/MpcConnectException.cs
Normal file
@ -0,0 +1,26 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="MpcConnectException.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Exceptions
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Exception thrown when there are problems with the <see cref="MpcConnection"/>.
|
||||
/// </summary>
|
||||
/// <seealso cref="Exception" />
|
||||
public class MpcConnectException : MpcException
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MpcConnectException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The message that describes the error.</param>
|
||||
public MpcConnectException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
26
Sources/MpcNET/Exceptions/MpcException.cs
Normal file
26
Sources/MpcNET/Exceptions/MpcException.cs
Normal file
@ -0,0 +1,26 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="MpcException.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Exceptions
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for all exceptions.
|
||||
/// </summary>
|
||||
/// <seealso cref="System.Exception" />
|
||||
public class MpcException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MpcException" /> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The message.</param>
|
||||
public MpcException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
72
Sources/MpcNET/ICommandFactory.cs
Normal file
72
Sources/MpcNET/ICommandFactory.cs
Normal file
@ -0,0 +1,72 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ICommandFactory.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET
|
||||
{
|
||||
using MpcNET.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Interface for providing specific command factories.
|
||||
/// </summary>
|
||||
public interface ICommandFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the status command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The status.
|
||||
/// </value>
|
||||
IStatusCommandFactory Status { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the database command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The database.
|
||||
/// </value>
|
||||
IDatabaseCommandFactory Database { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reflection command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The reflection.
|
||||
/// </value>
|
||||
IReflectionCommandFactory Reflection { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stored playlist command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The stored playlist.
|
||||
/// </value>
|
||||
IStoredPlaylistCommandFactory StoredPlaylist { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current playlist command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current playlist.
|
||||
/// </value>
|
||||
ICurrentPlaylistCommandFactory CurrentPlaylist { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the playback command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The playback.
|
||||
/// </value>
|
||||
IPlaybackCommandFactory Playback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the output command factory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The output.
|
||||
/// </value>
|
||||
IOutputCommandFactory Output { get; }
|
||||
}
|
||||
}
|
30
Sources/MpcNET/IMpcCommand.cs
Normal file
30
Sources/MpcNET/IMpcCommand.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IMpcCommand.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Interface for implementing a MPD command.
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue">The type of the value.</typeparam>
|
||||
public interface IMpcCommand<out TValue>
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializes the command.
|
||||
/// </summary>
|
||||
/// <returns>The serialize command.</returns>
|
||||
string Serialize();
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the specified response text pairs.
|
||||
/// </summary>
|
||||
/// <param name="response">The response.</param>
|
||||
/// <returns>The deserialized response.</returns>
|
||||
TValue Deserialize(IReadOnlyList<KeyValuePair<string, string>> response);
|
||||
}
|
||||
}
|
45
Sources/MpcNET/IMpcConnection.cs
Normal file
45
Sources/MpcNET/IMpcConnection.cs
Normal file
@ -0,0 +1,45 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IMpcConnection.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace MpcNET
|
||||
{
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using MpcNET.Message;
|
||||
|
||||
/// <summary>
|
||||
/// Interface for implementing an MPD connection.
|
||||
/// </summary>
|
||||
/// <seealso cref="System.IDisposable" />
|
||||
public interface IMpcConnection : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the version.
|
||||
/// </summary>
|
||||
string Version { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Connects asynchronously.
|
||||
/// </summary>
|
||||
/// <returns>The connect task.</returns>
|
||||
Task ConnectAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Disconnects asynchronously.
|
||||
/// </summary>
|
||||
/// <returns>The disconnect task.</returns>
|
||||
Task DisconnectAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Sends the command asynchronously.
|
||||
/// </summary>
|
||||
/// <typeparam name="TResponse">The response type.</typeparam>
|
||||
/// <param name="commandSelector">The command selector.</param>
|
||||
/// <returns>The send task.</returns>
|
||||
Task<IMpdMessage<TResponse>> SendAsync<TResponse>(Func<ICommandFactory, IMpcCommand<TResponse>> commandSelector);
|
||||
}
|
||||
}
|
77
Sources/MpcNET/IMpcConnectionObserver.cs
Normal file
77
Sources/MpcNET/IMpcConnectionObserver.cs
Normal file
@ -0,0 +1,77 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IMpcConnectionObserver.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Interface for implementing an observer for <see cref="MpcConnection"/>.
|
||||
/// </summary>
|
||||
public interface IMpcConnectionObserver
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when connecting.
|
||||
/// </summary>
|
||||
/// <param name="isReconnect">if set to <c>true</c> [is reconnect].</param>
|
||||
/// <param name="connectAttempt">The connect attempt.</param>
|
||||
void Connecting(bool isReconnect, int connectAttempt);
|
||||
|
||||
/// <summary>
|
||||
/// Called when connection is accepted.
|
||||
/// </summary>
|
||||
/// <param name="isReconnect">if set to <c>true</c> [is reconnect].</param>
|
||||
/// <param name="connectAttempt">The connect attempt.</param>
|
||||
void ConnectionAccepted(bool isReconnect, int connectAttempt);
|
||||
|
||||
/// <summary>
|
||||
/// Called when connected.
|
||||
/// </summary>
|
||||
/// <param name="isReconnect">if set to <c>true</c> [is reconnect].</param>
|
||||
/// <param name="connectAttempt">The connect attempt.</param>
|
||||
/// <param name="connectionInfo">The connection information.</param>
|
||||
void Connected(bool isReconnect, int connectAttempt, string connectionInfo);
|
||||
|
||||
/// <summary>
|
||||
/// Called when sending command.
|
||||
/// </summary>
|
||||
/// <param name="command">The command.</param>
|
||||
void Sending(string command);
|
||||
|
||||
/// <summary>
|
||||
/// Called when send exception occured.
|
||||
/// </summary>
|
||||
/// <param name="commandText">The command text.</param>
|
||||
/// <param name="sendAttempt">The send attempt.</param>
|
||||
/// <param name="exception">The exception.</param>
|
||||
void SendException(string commandText, int sendAttempt, Exception exception);
|
||||
|
||||
/// <summary>
|
||||
/// Called when send is retried.
|
||||
/// </summary>
|
||||
/// <param name="command">The command.</param>
|
||||
/// <param name="sendAttempt">The send attempt.</param>
|
||||
void RetrySend(string command, int sendAttempt);
|
||||
|
||||
/// <summary>
|
||||
/// Called when response is read.
|
||||
/// </summary>
|
||||
/// <param name="responseLine">The response line.</param>
|
||||
void ReadResponse(string responseLine);
|
||||
|
||||
/// <summary>
|
||||
/// Called when disconnecting.
|
||||
/// </summary>
|
||||
/// <param name="isExplicitDisconnect">if set to <c>true</c> the disconnect was explicitly called.</param>
|
||||
void Disconnecting(bool isExplicitDisconnect);
|
||||
|
||||
/// <summary>
|
||||
/// Called when disconnected.
|
||||
/// </summary>
|
||||
/// <param name="isExplicitDisconnect">if set to <c>true</c> the disconnect was explicitly called.</param>
|
||||
void Disconnected(bool isExplicitDisconnect);
|
||||
}
|
||||
}
|
23
Sources/MpcNET/Message/ErrorMpdMessage.cs
Normal file
23
Sources/MpcNET/Message/ErrorMpdMessage.cs
Normal file
@ -0,0 +1,23 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ErrorMpdMessage.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Message
|
||||
{
|
||||
internal class ErrorMpdMessage<T> : IMpdMessage<T>
|
||||
{
|
||||
public ErrorMpdMessage(IMpcCommand<T> command, ErrorMpdResponse<T> errorResponse)
|
||||
{
|
||||
this.Request = new MpdRequest<T>(command);
|
||||
this.Response = errorResponse;
|
||||
}
|
||||
|
||||
public IMpdRequest<T> Request { get; }
|
||||
|
||||
public IMpdResponse<T> Response { get; }
|
||||
|
||||
public bool IsResponseValid => false;
|
||||
}
|
||||
}
|
44
Sources/MpcNET/Message/ErrorMpdResponse.cs
Normal file
44
Sources/MpcNET/Message/ErrorMpdResponse.cs
Normal file
@ -0,0 +1,44 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ErrorMpdResponse.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Message
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of <see cref="IMpdResponse{TContent}"/> in case of an error.
|
||||
/// </summary>
|
||||
/// <typeparam name="TContent">The content type.</typeparam>
|
||||
/// <seealso cref="MpcNET.Message.IMpdResponse{T}" />
|
||||
public class ErrorMpdResponse<TContent> : IMpdResponse<TContent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ErrorMpdResponse{TContent}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception.</param>
|
||||
public ErrorMpdResponse(Exception exception)
|
||||
{
|
||||
this.Result = new MpdResponseResult(null, false, exception);
|
||||
this.Content = default(TContent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the state.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The state.
|
||||
/// </value>
|
||||
public IMpdResponseResult Result { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The content.
|
||||
/// </value>
|
||||
public TContent Content { get; }
|
||||
}
|
||||
}
|
39
Sources/MpcNET/Message/IMpdMessage.cs
Normal file
39
Sources/MpcNET/Message/IMpdMessage.cs
Normal file
@ -0,0 +1,39 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IMpdMessage.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Message
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for implementing MPD message.
|
||||
/// </summary>
|
||||
/// <typeparam name="TContent">The type of the content.</typeparam>
|
||||
public interface IMpdMessage<TContent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the request.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The request.
|
||||
/// </value>
|
||||
IMpdRequest<TContent> Request { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the response.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The response.
|
||||
/// </value>
|
||||
IMpdResponse<TContent> Response { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is response valid.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is response valid; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsResponseValid { get; }
|
||||
}
|
||||
}
|
23
Sources/MpcNET/Message/IMpdRequest.cs
Normal file
23
Sources/MpcNET/Message/IMpdRequest.cs
Normal file
@ -0,0 +1,23 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IMpdRequest.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Message
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for implementing a MPD request.
|
||||
/// </summary>
|
||||
/// <typeparam name="TContent">The response content.</typeparam>
|
||||
public interface IMpdRequest<out TContent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the command.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The command.
|
||||
/// </value>
|
||||
IMpcCommand<TContent> Command { get; }
|
||||
}
|
||||
}
|
31
Sources/MpcNET/Message/IMpdResponse.cs
Normal file
31
Sources/MpcNET/Message/IMpdResponse.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IMpdResponse.cs" company="Hukano">
|
||||
// Copyright (c) Hukano. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace MpcNET.Message
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents response to a <see cref="IMpcCommand{TValue}"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TContent">The type of the content.</typeparam>
|
||||
public interface IMpdResponse<TContent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the state.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The state.
|
||||
/// </value>
|
||||
IMpdResponseResult Result { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The content.
|
||||
/// </value>
|
||||
TContent Content { get; }
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user