Skip to content

Commit

Permalink
Download covers from url with a permanent redirect (308)
Browse files Browse the repository at this point in the history
  • Loading branch information
keifufu committed Mar 5, 2023
1 parent 2388a7c commit 786cdd7
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 79 deletions.
132 changes: 59 additions & 73 deletions WebNowPlaying.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
using System.Runtime.InteropServices;
using Rainmeter;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.IO;
using WNPReduxAdapterLibrary;
using System.Net;

namespace WebNowPlaying {
internal class Measure {
Expand All @@ -31,70 +32,56 @@ enum PlayerTypes {
private string CoverDefaultLocation = "";
private static string LastDownloadedCoverUrl = "";
private static string LastFailedCoverUrl = "";

private static string rainmeterFileSettingsLocation = "";

private PlayerTypes playerType = PlayerTypes.Status;

public static void DownloadCoverImage() {
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
string CoverUrl = WNPRedux.mediaInfo.CoverUrl;
if (CoverUrl.Length == 0 || LastFailedCoverUrl == CoverUrl || LastDownloadedCoverUrl == CoverUrl || !Uri.IsWellFormedUriString(CoverUrl, UriKind.RelativeOrAbsolute)) return;

try {
HttpWebRequest httpWebRequest = (HttpWebRequest) HttpWebRequest.Create(CoverUrl);
using (HttpWebResponse httpWebResponse = (HttpWebResponse) httpWebRequest.GetResponse()) {
using (Stream stream = httpWebResponse.GetResponseStream()) {
Byte[] image = ReadStream(stream);
WriteStream(image);
LastDownloadedCoverUrl = CoverUrl;
}
}
} catch (Exception e) {
API.Log(API.LogType.Error, $"WebNowPlaying.dll - Unable to get album art from: {CoverUrl}");
API.Log(API.LogType.Debug, $"WebNowPlaying Trace: {e}");
LastFailedCoverUrl = CoverUrl;
}
}
private static byte[] ReadStream(Stream input) {
byte[] buffer = new byte[1024];
using (MemoryStream ms = new MemoryStream()) {
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0) {
ms.Write(buffer, 0, read);
}
return ms.ToArray();
if (CoverOutputLocation == Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Temp/Rainmeter/WebNowPlaying/cover.png") {
// Make sure the path folder exists if using it
Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Temp/Rainmeter/WebNowPlaying");
}
}

private static void WriteStream(Byte[] image) {
try {
if (CoverOutputLocation == Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Temp/Rainmeter/WebNowPlaying/cover.png") {
// Make sure the path folder exists if using it
Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Temp/Rainmeter/WebNowPlaying");
}
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;

FileStream fs = new FileStream(CoverOutputLocation, FileMode.Create, FileAccess.Write, FileShare.Read);
BinaryWriter bw = new BinaryWriter(fs);
try {
bw.Write(image);
} catch (Exception e) {
bw.Close();
fs.Close();
throw e;
} finally {
bw.Close();
fs.Close();
// This is a mess, but it works for now :)
using (var httpClientHandler = new HttpClientHandler()) {
httpClientHandler.AllowAutoRedirect = true;
httpClientHandler.MaxAutomaticRedirections = 3;
using (var httpClient = new HttpClient(httpClientHandler)) {
HttpResponseMessage response = httpClient.GetAsync(CoverUrl).Result;

if (response.StatusCode == HttpStatusCode.OK) {
using (Stream inputStream = response.Content.ReadAsStreamAsync().Result)
using (Stream outputStream = File.OpenWrite(CoverOutputLocation)) {
inputStream.CopyTo(outputStream);
}
LastDownloadedCoverUrl = CoverUrl;
} else if (response.StatusCode == (HttpStatusCode)308) {
string redirectUrl = response.Headers.Location.ToString();
response = httpClient.GetAsync(redirectUrl).Result;

if (response.StatusCode == HttpStatusCode.OK) {
using (Stream inputStream = response.Content.ReadAsStreamAsync().Result)
using (Stream outputStream = File.OpenWrite(CoverOutputLocation)) {
inputStream.CopyTo(outputStream);
}
LastDownloadedCoverUrl = CoverUrl;
} else {
LastFailedCoverUrl = CoverUrl;
}
} else {
LastFailedCoverUrl = CoverUrl;
WNPRedux.Log(WNPRedux.LogType.Error, $"WebNowPlaying.dll - Unable to get album art from: {CoverUrl}. Response status code: {response.StatusCode}");
}
}

} catch (Exception e) {
API.Log(API.LogType.Error, $"WebNowPlaying.dll - Unable to download album art to: {CoverOutputLocation}");
API.Log(API.LogType.Debug, $"WebNowPlaying Trace: {e}");
}
}

static int MeasureCount = 0;

internal Measure(API api) {
++MeasureCount;
try {
Expand All @@ -107,19 +94,19 @@ internal Measure(API api) {

void logger(WNPRedux.LogType type, string message) {
switch (type) {
case WNPRedux.LogType.DEBUG:
case WNPRedux.LogType.Debug:
API.Log(API.LogType.Debug, message); break;
case WNPRedux.LogType.WARNING:
case WNPRedux.LogType.Warning:
API.Log(API.LogType.Warning, message); break;
case WNPRedux.LogType.ERROR:
case WNPRedux.LogType.Error:
API.Log(API.LogType.Error, message); break;
}
}

WNPRedux.Initialize(8974, adapterVersion, logger, true);
} catch (Exception e) {
API.Log(API.LogType.Error, "WebNowPlaying.dll - Error initializing WNPRedux");
API.Log(API.LogType.Debug, $"WebNowPlaying Trace: {e}");
WNPRedux.Log(WNPRedux.LogType.Error, "WebNowPlaying.dll - Error initializing WNPRedux");
WNPRedux.Log(WNPRedux.LogType.Debug, $"WebNowPlaying Trace: {e}");
}
}

Expand All @@ -145,8 +132,8 @@ internal virtual void Reload(API api, ref double maxValue) {
maxValue = 100;
}
} catch (Exception e) {
API.Log(API.LogType.Error, "WebNowPlaying.dll - Unknown PlayerType:" + playerTypeString);
API.Log(API.LogType.Debug, $"WebNowPlaying Trace: {e}");
WNPRedux.Log(WNPRedux.LogType.Error, "WebNowPlaying.dll - Unknown PlayerType:" + playerTypeString);
WNPRedux.Log(WNPRedux.LogType.Debug, $"WebNowPlaying Trace: {e}");
playerType = PlayerTypes.Status;
}
}
Expand All @@ -166,8 +153,8 @@ internal void ExecuteBang(string args) {
try {
WNPRedux.mediaEvents.SetRating(Convert.ToInt16(bang.Substring(bang.LastIndexOf(" ") + 1)));
} catch (Exception e) {
API.Log(API.LogType.Error, "WebNowPlaying.dll - Failed to parse rating number, assuming 0");
API.Log(API.LogType.Debug, $"WebNowPlaying Trace: {e}");
WNPRedux.Log(WNPRedux.LogType.Error, "WebNowPlaying.dll - Failed to parse rating number, assuming 0");
WNPRedux.Log(WNPRedux.LogType.Debug, $"WebNowPlaying Trace: {e}");
WNPRedux.mediaEvents.SetRating(0);
}
} else if (bang.Contains("setposition ")) {
Expand All @@ -183,8 +170,8 @@ internal void ExecuteBang(string args) {
WNPRedux.mediaEvents.SetPositionPercent(percent);
}
} catch (Exception e) {
API.Log(API.LogType.Error, $"WebNowPlaying.dll - SetPosition argument could not be converted to a double: {args}");
API.Log(API.LogType.Debug, $"WebNowPlaying Trace: {e}");
WNPRedux.Log(WNPRedux.LogType.Error, $"WebNowPlaying.dll - SetPosition argument could not be converted to a double: {args}");
WNPRedux.Log(WNPRedux.LogType.Debug, $"WebNowPlaying Trace: {e}");
}
} else if (bang.Contains("setvolume ")) {
try {
Expand All @@ -199,21 +186,20 @@ internal void ExecuteBang(string args) {
WNPRedux.mediaEvents.SetVolume(volume);
}
} catch (Exception e) {
API.Log(API.LogType.Error, $"WebNowPlaying.dll - SetVolume argument could not be converted to a double: {args}");
API.Log(API.LogType.Debug, $"WebNowPlaying Trace: {e}");
WNPRedux.Log(WNPRedux.LogType.Error, $"WebNowPlaying.dll - SetVolume argument could not be converted to a double: {args}");
WNPRedux.Log(WNPRedux.LogType.Debug, $"WebNowPlaying Trace: {e}");
}
} else {
API.Log(API.LogType.Warning, $"WebNowPlaying.dll - Unknown bang: {args}");
WNPRedux.Log(WNPRedux.LogType.Warning, $"WebNowPlaying.dll - Unknown bang: {args}");
}
} catch (Exception e) {
API.Log(API.LogType.Error, $"WebNowPlaying.dll - Error using bang: {args}");
API.Log(API.LogType.Debug, $"WebNowPlaying Trace: {e}");
WNPRedux.Log(WNPRedux.LogType.Error, $"WebNowPlaying.dll - Error using bang: {args}");
WNPRedux.Log(WNPRedux.LogType.Debug, $"WebNowPlaying Trace: {e}");
}
}

internal virtual double Update() {
if (WNPRedux.mediaInfo.CoverUrl.Length > 0 && LastFailedCoverUrl != WNPRedux.mediaInfo.CoverUrl && LastDownloadedCoverUrl != WNPRedux.mediaInfo.CoverUrl && Uri.IsWellFormedUriString(WNPRedux.mediaInfo.CoverUrl, UriKind.RelativeOrAbsolute))
DownloadCoverImage();
DownloadCoverImage();

try {
switch (playerType) {
Expand Down Expand Up @@ -247,8 +233,8 @@ internal virtual double Update() {
return WNPRedux.mediaInfo.DurationSeconds;
}
} catch (Exception e) {
API.Log(API.LogType.Error, "WebNowPlaying.dll - Error doing update cycle");
API.Log(API.LogType.Debug, $"WebNowPlaying Trace: {e}");
WNPRedux.Log(WNPRedux.LogType.Error, "WebNowPlaying.dll - Error doing update cycle");
WNPRedux.Log(WNPRedux.LogType.Debug, $"WebNowPlaying Trace: {e}");
}

return 0.0;
Expand Down Expand Up @@ -279,8 +265,8 @@ internal string GetString() {
return WNPRedux.mediaInfo.Duration;
}
} catch (Exception e) {
API.Log(API.LogType.Error, "WebNowPlaying.dll - Error doing getString cycle");
API.Log(API.LogType.Debug, $"WebNowPlaying Trace: {e}");
WNPRedux.Log(WNPRedux.LogType.Error, "WebNowPlaying.dll - Error doing getString cycle");
WNPRedux.Log(WNPRedux.LogType.Debug, $"WebNowPlaying Trace: {e}");
}

return null;
Expand Down
17 changes: 12 additions & 5 deletions WebNowPlaying.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,17 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="websocket-sharp, Version=1.0.2.59611, Culture=neutral, PublicKeyToken=5660b08a1845a91e, processorArchitecture=MSIL">
<HintPath>packages\WebSocketSharp.1.0.3-rc11\lib\websocket-sharp.dll</HintPath>
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
</Reference>
<Reference Include="WNPRedux-Adapter-Library, Version=1.0.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\WNPRedux-Adapter-Library.1.0.3\lib\net48\WNPRedux-Adapter-Library.dll</HintPath>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Xml" />
<Reference Include="WNPRedux-Adapter-Library, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\WNPRedux-Adapter-Library.1.0.4\lib\net48\WNPRedux-Adapter-Library.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
Expand Down Expand Up @@ -127,6 +132,8 @@ xcopy "$(TargetDir)$(TargetFileName)" "%25appdata%25\Rainmeter\Plugins" /Y</Pos
<Error Condition="!Exists('packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.props'))" />
<Error Condition="!Exists('packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.targets'))" />
<Error Condition="!Exists('packages\ILMerge.3.0.41\build\ILMerge.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\ILMerge.3.0.41\build\ILMerge.props'))" />
<Error Condition="!Exists('packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<Import Project="packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.targets" Condition="Exists('packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.targets')" />
<Import Project="packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
</Project>
5 changes: 4 additions & 1 deletion packages.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ILMerge" version="3.0.41" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net48" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net48" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net48" />
<package id="MSBuild.ILMerge.Task" version="1.1.3" targetFramework="net45" />
<package id="WNPRedux-Adapter-Library" version="1.0.3" targetFramework="net48" />
<package id="WNPRedux-Adapter-Library" version="1.0.4" targetFramework="net48" />
</packages>

0 comments on commit 786cdd7

Please sign in to comment.