mirror of
https://github.com/ZetaKebab/MpcNET.git
synced 2026-10-17 20:16:21 +00:00
Rewrote most of the library
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")]
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
mpd.exe mpd.conf -v
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
Binary file not shown.
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 ";
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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