Skip to content

Commit

Permalink
merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
PKBeam committed Feb 10, 2024
2 parents b168eeb + 6e732b8 commit eeff6e8
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 24 deletions.
13 changes: 5 additions & 8 deletions AMWin-RichPresence/AppleMusicClientScraper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
using System.Text.RegularExpressions;
using FlaUI.UIA3;
using FlaUI.Core.Conditions;
using DiscordRPC.Logging;
using FlaUI.Core.AutomationElements;
using System.Xml.Linq;

namespace AMWin_RichPresence {

Expand Down Expand Up @@ -50,6 +48,7 @@ public void Print() {
}

internal class AppleMusicClientScraper {
private static readonly Regex ComposerPerformerRegex = new Regex(@"By\s.*?\s\u2014", RegexOptions.Compiled);

public delegate void RefreshHandler(AppleMusicInfo? newInfo);
string? lastFmApiKey;
Expand Down Expand Up @@ -140,8 +139,7 @@ public void Refresh(object? source, ElapsedEventArgs? e) {
// some classical songs add "By " before the composer's name
string? songComposer = null;
string? songPerformer = null;
var composerPerformerRegex = new Regex(@"By\s.*?\s\u2014");
var songComposerPerformer = composerPerformerRegex.Matches(songAlbumArtist);
//var songComposerPerformer = ComposerPerformerRegex.Matches(songAlbumArtist);
try {
var songInfo = ParseSongAlbumArtist(songAlbumArtist, composerAsArtist);
songArtist = songInfo.Item1;
Expand Down Expand Up @@ -256,10 +254,9 @@ private static Tuple<string, string> ParseSongAlbumArtist(string songAlbumArtist
string songAlbum;

// some classical songs add "By " before the composer's name
string? songComposer;
string? songPerformer;
var composerPerformerRegex = new Regex(@"By\s.*?\s\u2014");
var songComposerPerformer = composerPerformerRegex.Matches(songAlbumArtist);
string? songComposer = null;
string? songPerformer = null;
var songComposerPerformer = ComposerPerformerRegex.Matches(songAlbumArtist);
if (songComposerPerformer.Count > 0) {
songComposer = songAlbumArtist.Split(" \u2014 ")[0].Remove(0, 3);
songPerformer = songAlbumArtist.Split(" \u2014 ")[1];
Expand Down
12 changes: 5 additions & 7 deletions AMWin-RichPresence/AppleMusicScrobbler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ public struct ListenBrainzCredentials : IScrobblerCredentials {

internal class AlbumCleaner {

private static readonly Regex AlbumCleanerRegex = new Regex(@"\s-\s((Single)|(EP))$", RegexOptions.Compiled);

public static string CleanAlbumName(string songName) {
// Remove " - Single" and " - EP"
var re = new Regex(@"\s-\s((Single)|(EP))$");
return re.Replace(songName, new MatchEvaluator((m) => { return ""; }));
return AlbumCleanerRegex.Replace(songName, new MatchEvaluator((m) => { return ""; }));
}

}
Expand Down Expand Up @@ -124,7 +125,6 @@ internal class AppleMusicLastFmScrobbler : AppleMusicScrobbler<LastFmCredentials
private LastAuth? lastfmAuth;
private IScrobbler? lastFmScrobbler;
private ITrackApi? trackApi;
private HttpClient? httpClient;

public AppleMusicLastFmScrobbler(Logger? logger = null) : base("Last.FM", logger) { }

Expand All @@ -135,12 +135,11 @@ public async override Task<bool> init(LastFmCredentials credentials) {
return false;
}
// Use the four pieces of information (API Key, API Secret, Username, Password) to log into Last.FM for Scrobbling
httpClient = new HttpClient();
lastfmAuth = new LastAuth(credentials.apiKey, credentials.apiSecret);
await lastfmAuth.GetSessionTokenAsync(credentials.username, credentials.password);

lastFmScrobbler = new MemoryScrobbler(lastfmAuth, httpClient);
trackApi = new TrackApi(lastfmAuth, httpClient);
lastFmScrobbler = new MemoryScrobbler(lastfmAuth, Constants.HttpClient);
trackApi = new TrackApi(lastfmAuth, Constants.HttpClient);

if (lastfmAuth.Authenticated) {
logger?.Log("Last.FM authentication succeeded");
Expand All @@ -153,7 +152,6 @@ public async override Task<bool> init(LastFmCredentials credentials) {

public async override Task<bool> UpdateCredsAsync(LastFmCredentials credentials) {
logger?.Log("[Last.FM scrobbler] Updating credentials");
httpClient = null;
lastfmAuth = null;
lastFmScrobbler = null;
trackApi = null;
Expand Down
20 changes: 12 additions & 8 deletions AMWin-RichPresence/AppleMusicWebScraper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
using System;

namespace AMWin_RichPresence {
internal class AppleMusicWebScraper {
internal class AppleMusicWebScraper
{
private static readonly Regex SongTitleRegex = new Regex(@"(?<=Listen to ).*(?= by)", RegexOptions.Compiled);
private static readonly Regex DurationRegex = new Regex(@"(?<=Duration: )\S*$", RegexOptions.Compiled);
private static readonly Regex ImageUrlRegex = new Regex(@"http\S*?(?= \d{2,3}w)", RegexOptions.Compiled);
Logger? logger;
string? lastFmApiKey;
string songName;
Expand Down Expand Up @@ -39,23 +43,21 @@ public AppleMusicWebScraper(string songName, string songAlbum, string songArtist
this.songArtist = songArtist;
}
private async Task<HtmlDocument> GetURL(string url, string? callingFunction = null) {
var client = new HttpClient();
// Apple Music web search doesn't like ampersands... even if they're HTML-escaped?
var cleanUrl = HttpUtility.HtmlEncode(url.Replace("&", " "));
logger?.Log($"[{callingFunction ?? "GetURL"}] HTTP GET for {cleanUrl}");
var stopwatch = Stopwatch.StartNew();
var res = await client.GetStringAsync(cleanUrl);
var res = await Constants.HttpClient.GetStringAsync(cleanUrl);
stopwatch.Stop();
logger?.Log($"[{callingFunction ?? "GetURL"}] HTTP GET for {cleanUrl} took {stopwatch.ElapsedMilliseconds}ms");
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(res);
return doc;
}
private async Task<JsonDocument> GetURLJson(string url, string? callingFunction = null) {
var client = new HttpClient();
logger?.Log($"[{callingFunction ?? "GetURL"}] HTTP GET for {url}");
var stopwatch = Stopwatch.StartNew();
var res = await client.GetStringAsync(url);
var res = await Constants.HttpClient.GetStringAsync(url);
stopwatch.Stop();
logger?.Log($"[{callingFunction ?? "GetURL"}] HTTP GET for {url} took {stopwatch.ElapsedMilliseconds}ms");
return JsonDocument.Parse(res);
Expand Down Expand Up @@ -166,13 +168,15 @@ public List<string> GetArtistList() {
try {
var result = SearchSongs();
if (result != null) {
/*
var searchResultUrl = result
.Descendants("li")
.First(x => x.Attributes["class"].Value.Contains("track-lockup__title"))
.Descendants("a")
.First()
.Attributes["href"]
.Value;
*/

var searchResultSubtitles = result
.Descendants("span")
Expand Down Expand Up @@ -248,7 +252,7 @@ private string GetLargestImageUrl(HtmlNode nodeWithSource) {

var imgUrls = imgSources[0].Attributes["srcset"].Value;

return new Regex(@"http\S*?(?= \d{2,3}w)").Matches(imgUrls).Last().Value;
return ImageUrlRegex.Matches(imgUrls).Last().Value;
}

// Get song duration
Expand Down Expand Up @@ -306,8 +310,8 @@ private string GetLargestImageUrl(HtmlNode nodeWithSource) {
.First(x => x.Attributes.Contains("name") && x.Attributes["name"].Value == "description");

var str = desc.Attributes["content"].Value;
var songTitle = new Regex(@"(?<=Listen to ).*(?= by)").Matches(str).First().Value;
var duration = new Regex(@"(?<=Duration: )\S*$").Matches(str).First().Value;
var songTitle = SongTitleRegex.Matches(str).First().Value;
var duration = DurationRegex.Matches(str).First().Value;

// check that the result actually is the song
if (HttpUtility.HtmlDecode(songTitle) == songName) {
Expand Down
5 changes: 4 additions & 1 deletion AMWin-RichPresence/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Http;

namespace AMWin_RichPresence {
internal static class Constants {
Expand Down Expand Up @@ -38,6 +39,8 @@ private static string ProgramVersionBase {
public static string WindowsAppDataFolder => Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
public static string AppDataFolder => Path.Combine(WindowsAppDataFolder, AppDataFolderName);
public static string AppShortcutPath => Path.Join(WindowsStartupFolder, "AMWin-RP.lnk");
public static string? ExePath => Process.GetCurrentProcess().MainModule?.FileName;
public static string? ExePath => Process.GetCurrentProcess().MainModule?.FileName;

public static readonly HttpClient HttpClient = new HttpClient();
}
}

0 comments on commit eeff6e8

Please sign in to comment.