From 9a5ef1558e3da4b99a2a7bf3bd293143821d2819 Mon Sep 17 00:00:00 2001 From: niclastimle Date: Mon, 26 May 2025 23:45:29 +0200 Subject: [PATCH 1/6] WikiData --- Controller/ArtistController.cs | 38 ++++++++++++++++++++++++++++++---- Endpoints/ArtistEndPoint.cs | 7 +++++++ Endpoints/IArtistEndPoint.cs | 2 ++ Handler/ArtistHandler.cs | 10 +++++++-- Models/ApiSettings.cs | 1 + Models/ArtistDto.cs | 7 ++++++- Models/WikiDataDto.cs | 20 ++++++++++++++++++ Models/WikipediaSummaryDto.cs | 9 ++++++++ Querys/ArtistQuery.cs | 2 ++ appsettings.json | 3 ++- 10 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 Models/WikiDataDto.cs create mode 100644 Models/WikipediaSummaryDto.cs diff --git a/Controller/ArtistController.cs b/Controller/ArtistController.cs index 963ffaa..274239d 100644 --- a/Controller/ArtistController.cs +++ b/Controller/ArtistController.cs @@ -12,20 +12,50 @@ namespace HollyJukeBox.Controller; public class ArtistController(IMediator mediator) : ControllerBase { - [HttpGet] - public async Task Get([FromQuery] string? id, [FromQuery] string? name) + [HttpGet("{id}")] + public async Task GetById([FromQuery] string? id) { if (!string.IsNullOrWhiteSpace(id)) { var result = await mediator.Send(new ArtistQuery.GetById(id)); return result is null ? NotFound() : Ok(result); } - + return BadRequest("Provide either id for the artist"); + } + + [HttpGet("{name}")] + + public async Task GetByName([FromQuery] string? name) + { if (!string.IsNullOrWhiteSpace(name)) { var result = await mediator.Send(new ArtistQuery.GetByName(name)); return result is null ? NotFound() : Ok(result); } - return BadRequest("Provide either id or name for the artist"); + return BadRequest("Provide either name for the artist"); + } + + [HttpGet("wikidata/{id}")] + public async Task GetWikidataById(string? id) + { + if (!string.IsNullOrWhiteSpace(id)) + { + var result = await mediator.Send(new ArtistQuery.GetWikiData(id)); + return result is null ? NotFound() : Ok(result); + } + + return BadRequest("Provide id for the wikidata"); + } + + [HttpGet("summery/{artist}")] + public async Task GetWikiDataSummery(string? artist) + { + if (!string.IsNullOrWhiteSpace(artist)) + { + var result = await mediator.Send(new ArtistQuery.GetWikipediaSummary(artist)); + return result is null ? NotFound() : Ok(result); + } + + return BadRequest("Provide id for the wikidata"); } } \ No newline at end of file diff --git a/Endpoints/ArtistEndPoint.cs b/Endpoints/ArtistEndPoint.cs index 9e27b37..7085f2e 100644 --- a/Endpoints/ArtistEndPoint.cs +++ b/Endpoints/ArtistEndPoint.cs @@ -8,6 +8,13 @@ public class ArtistEndPoint(IOptions options, HttpClient client) : { public async Task GetById(string id) => await client.GetFromJsonAsync( options.Value.MusicBrainzUrl + $"artist/{id}?inc=release-groups&fmt=json"); + public async Task GetByName(string name) => await client.GetFromJsonAsync( options.Value.MusicBrainzUrl + $"artist?query={name}&fmt=json"); + + public async Task GetWikiData(string id) => await client.GetFromJsonAsync( + options.Value.WikiDataUrl + $"?action=wbgetentities&ids={id}&format=json&props=sitelinks"); + + public async Task GetWikipediaSummary(string artist) => await client.GetFromJsonAsync( + options.Value.WikipediaSummery + $"{artist}"); } \ No newline at end of file diff --git a/Endpoints/IArtistEndPoint.cs b/Endpoints/IArtistEndPoint.cs index fd8283e..e3fb6ff 100644 --- a/Endpoints/IArtistEndPoint.cs +++ b/Endpoints/IArtistEndPoint.cs @@ -6,4 +6,6 @@ public interface IArtistEndPoint { public Task GetById(string id); public Task GetByName(string name); + public Task GetWikiData(string id); + public Task GetWikipediaSummary(string artist); } \ No newline at end of file diff --git a/Handler/ArtistHandler.cs b/Handler/ArtistHandler.cs index 3797b90..c00da5b 100644 --- a/Handler/ArtistHandler.cs +++ b/Handler/ArtistHandler.cs @@ -7,7 +7,9 @@ namespace HollyJukeBox.Handler; public class ArtistHandler(IArtistEndPoint artistEndPoint) : IRequestHandler, - IRequestHandler + IRequestHandler, + IRequestHandler, + IRequestHandler { public async Task Handle(ArtistQuery.GetById query, CancellationToken cancellationToken) => await artistEndPoint.GetById(query.Id); @@ -19,5 +21,9 @@ public async Task Handle(ArtistQuery.GetByName query, CancellationTok artist = await artistEndPoint.GetById(artist.Id); return artist; } - + + public async Task Handle(ArtistQuery.GetWikiData request, CancellationToken cancellationToken) + => await artistEndPoint.GetWikiData(request.id); + public async Task Handle(ArtistQuery.GetWikipediaSummary request, CancellationToken cancellationToken) + => await artistEndPoint.GetWikipediaSummary(request.artist); } \ No newline at end of file diff --git a/Models/ApiSettings.cs b/Models/ApiSettings.cs index 4a40992..712dc05 100644 --- a/Models/ApiSettings.cs +++ b/Models/ApiSettings.cs @@ -5,4 +5,5 @@ public class ApiSettings public string MusicBrainzUrl { get; set; } public string CoverArtArchiveUrl { get; set; } public string WikiDataUrl { get; set; } + public string WikipediaSummery { get; set; } } \ No newline at end of file diff --git a/Models/ArtistDto.cs b/Models/ArtistDto.cs index 1958edf..5091b67 100644 --- a/Models/ArtistDto.cs +++ b/Models/ArtistDto.cs @@ -11,10 +11,15 @@ public class ArtistDto [JsonPropertyName("release-groups")] public List ReleasesGroups { get; set; } + [JsonPropertyName("relations")] + public List Relations { get; set; } } public record ReleasesGroups( [property: JsonPropertyName("id")] string Id, [property: JsonPropertyName("title")] string Title, [property: JsonPropertyName("first-release-date")] string FirstReleaseDate -); \ No newline at end of file +); + +public record Relations(List url); +public record Url(string id, string resource); \ No newline at end of file diff --git a/Models/WikiDataDto.cs b/Models/WikiDataDto.cs new file mode 100644 index 0000000..94195e7 --- /dev/null +++ b/Models/WikiDataDto.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace HollyJukeBox.Models; + +public class WikiDataDto +{ + [JsonPropertyName("entities")] + public Dictionary Entities { get; set; } +} +public record Entity( + [property: JsonPropertyName("id")] string Id, + [property: JsonPropertyName("sitelinks")] List SiteLinks +); +public record SiteLink( + [property: JsonPropertyName("enwiki")] Enwiki Enwiki +); + +public record Enwiki( + [property: JsonPropertyName("site")] string enwiki +); \ No newline at end of file diff --git a/Models/WikipediaSummaryDto.cs b/Models/WikipediaSummaryDto.cs new file mode 100644 index 0000000..4c715f7 --- /dev/null +++ b/Models/WikipediaSummaryDto.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace HollyJukeBox.Models; + +public class WikipediaSummaryDto +{ + [JsonPropertyName("extract")] + public string Extract { get; set; } +} \ No newline at end of file diff --git a/Querys/ArtistQuery.cs b/Querys/ArtistQuery.cs index 9109648..eda1809 100644 --- a/Querys/ArtistQuery.cs +++ b/Querys/ArtistQuery.cs @@ -7,4 +7,6 @@ public class ArtistQuery : IRequest { public record GetById(string Id) : IRequest; public record GetByName(string Name) : IRequest; + public record GetWikiData(string id) : IRequest; + public record GetWikipediaSummary(string artist) : IRequest; } \ No newline at end of file diff --git a/appsettings.json b/appsettings.json index ff0c4ef..0bde613 100644 --- a/appsettings.json +++ b/appsettings.json @@ -8,7 +8,8 @@ "ApiSettings": { "MusicBrainzUrl": "https://musicbrainz.org/ws/2/", "CoverArtArchiveUrl": "http://coverartarchive.org/", - "WikiDataUrl" : "https://www.wikidata.org/w/api.php" + "WikiDataUrl" : "https://www.wikidata.org/w/api.php", + "WikipediaSummery" : "https://en.wikipedia.org/api/rest_v1/page/summary/" }, "AllowedHosts": "*" } From df8dd4d78b20637e3c3c786249e1dd0e2e39edfc Mon Sep 17 00:00:00 2001 From: Niclas Timle Date: Mon, 26 May 2025 23:50:21 +0200 Subject: [PATCH 2/6] Delete .DS_Store --- .DS_Store | Bin 10244 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 9fe1057c8f10c6c2ade9481937e5beab410f4c91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10244 zcmeHMOOG2x5U#fOF`EQrwBZ0s&`3yRC02_!L9AAR$Z;GAkPrkTIE1j+YirlZc-rzK zo3N~8apQH*0de66a7Ku0PMi=gaY91k9*GMF0$+8v5So+|(8Tat^Om!87&&N+&e3V&qs$ zr3#yR_aKa_Fk1|v)lnZZ9I|5MSWB%=LaUQ7Eeo?l5vq0Qg$hohqNTrk4|orxJ#Zec z=4p*O)S|Ytf9HwBwQGN?qEszpw6k8{mffCuPvthGRoj)dnmGpuZrnQg*DrT&CtB*t z)**=AuHAxa=ma&WhtB|g9pclWn0D}OjcRyv9alsW^<6y0s9&S2sFf63=Mv28OI$Xu zQm)-heQ`3OU!*4Y#cf4=oQ-lkcka0_fHL~F*H%wFG4a~H+NsCVwT`#W{R*RWgf1|5 z_@NIO;nSvmqK|(9_qi3}OdY4kRP5*3w)_9im5oc^>!@eiwBvsm*5RfXh$XrRW-Y{8 zs!=ecfy<0zEFQL)WoWp(=AQyqC6Tvv~ZoZ;$_=StRV(QOQTSz2^x<$IyE{#%|KfG@@%5YgN3t;YNjd zI8n*fa~Un4n$?EQ?bh9|KQh@S*S5{_e()~ekohj>@kP$rM$YM}Id|1%FL<`udFPQC zR(4f}>$w)xIIu00W>^?tBqef^%INkuS_YrtD)OlMsl#*JVF%^>GWWbH(R)XHG{$Do{k7VpTZ zzTLx>`uig@_KcoA($cj~ujW;+j?imrSOnDqSNF2j`(#T6WLI$ zMThD%_Xa()YJb)2MV-O0T>eoMigWV|i@{=WG`LdVm3#GJV>lXA8~w}t?F}iT=H$82 ze6!Qu+bSKuAmd@96SwcCxkTjd>+mY z=%=?|*f0Ujv}uR;Fsu`7y@+Mnyk76ek&HRvGsgwGgz3qFy_pIs(n(@!Sy-2Ef%i#{ zEt}`c?;qU#ZZfqj8#cc@jLR!TGj2NxK7mRyef(JKAmwBZREJXv@A48KqP-Nx=63lv zxwxshW#Fc%V;0Wks1`it>5KP(_kj1n1L}dI?sv%N{}=QB|9?Q)`EGj;cn{o<2gF>h zUaJB*`AwZv;)czogG_!V4?Ewki;=ZcYIE%65BU;i_} YI(zi{f4~1Xd)~>(u)R Date: Mon, 26 May 2025 23:50:31 +0200 Subject: [PATCH 3/6] Delete obj directory --- obj/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 obj/.DS_Store diff --git a/obj/.DS_Store b/obj/.DS_Store deleted file mode 100644 index 25a115b42df7608190b2b3815bf788ae43b2d42a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~J5B>J5Qb;SBCSM|lG0a5MQb8cQ{)0@2?|A`O_PqoSD@xT9DtHra0C8%fH15? z7a=qw*}oq%-rY}H+e1XWJggT)b0X?dL|GaWCc~3cC+^%qS=ZQXH;dKnxZ6)G^EZd& z-A}2|9SwA#_WftqFYWAZEM?e^14jF&hsTT8x97|69_wE`_V-^1bs6DdK_CbOfglhB zj!FP$wpf2=8g&o|0zu%Dfb0(mMKrrsQ{6gHX$k<9YqT2Ll1oTTa?P&Q6f-ckP^g8n zrxo%(`VxGSrFtr`s4HDtW794C}QGQr2#{`xdfmi`^dRY+I*5W{IY8`l~rV1!=Z5z MP#{qSfg=!j2c6F>h5!Hn From f953212616cfaab1d4e3875f0c27191418291b6c Mon Sep 17 00:00:00 2001 From: Niclas Timle Date: Mon, 26 May 2025 23:50:43 +0200 Subject: [PATCH 4/6] Delete bin directory --- bin/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 bin/.DS_Store diff --git a/bin/.DS_Store b/bin/.DS_Store deleted file mode 100644 index 450547d063f61a613b42881c8f33e27c6ad2fcbe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~J5B>J5Qb+UNGs8#q(Z(zD!Rx-<^;I_T7p86XwyV#eFaXyRj4=wx8Mf+^8jI3 zi7rBDMzViDX1u$fw6=$cc(Gs2h^9o;p@_0HMoflBr%v2?0%cuey;;wecf)o!vdrHc zl6OC&Lig0up4#`HUp}?7+o6f!O~_3h>QyT|GmkKMx;Li1;YhXsKk5Cnoi z5I8CUoY`XCxoOlvAP5A3PXe+(Boxu?T1|E9K&2@FRIbr#XiF|3G08Q%R#VKt*g~Ne z%AR7dg=0LqUv{mg7EbKR2m6yhk{8yeWBsJ=#Mw0JAP@vv0;krU%K3kTUuHDPZ$qLN z1cJanBfyigEDL;;pRGSWPtMwea*HA+epMPUw3|x+I Date: Mon, 26 May 2025 23:50:57 +0200 Subject: [PATCH 5/6] Delete .idea directory --- .idea/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .idea/.DS_Store diff --git a/.idea/.DS_Store b/.idea/.DS_Store deleted file mode 100644 index 378b2ee0f59ce0397818c9ea866426bf4c6b7895..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5dPNo5b#oZ>T#by=*jCEB8VrUFJNm#iz(@)ptro0Z{S1t7JUQ1*%_hH z9Et})nF+h!?EGwYKS*{5Kqzi6PIi#2K#8qT%y5MAkm# zs@JG-kHhu9;2JwT(OPmx&&|Vpao29Px~NwQ6dySQ&cHuoAdIU;RdQ2ywtm~5oVAhdmQ6(BI#DRpdzSzXZ&cH7)@Bt*OK5PI0 From b35005449704f344e362efc434540c5a936655bb Mon Sep 17 00:00:00 2001 From: niclastimle Date: Tue, 27 May 2025 21:54:32 +0200 Subject: [PATCH 6/6] wikidata and wikisummery added to swagger --- Controller/ArtistController.cs | 17 ++++++++--------- Endpoints/ArtistEndPoint.cs | 10 +++++----- Endpoints/IArtistEndPoint.cs | 2 +- Handler/ArtistHandler.cs | 4 ++-- Models/ArtistDto.cs | 2 +- Models/WikiDataDto.cs | 5 +++-- Querys/ArtistQuery.cs | 2 +- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Controller/ArtistController.cs b/Controller/ArtistController.cs index 274239d..28e7db7 100644 --- a/Controller/ArtistController.cs +++ b/Controller/ArtistController.cs @@ -12,7 +12,7 @@ namespace HollyJukeBox.Controller; public class ArtistController(IMediator mediator) : ControllerBase { - [HttpGet("{id}")] + [HttpGet("id")] public async Task GetById([FromQuery] string? id) { if (!string.IsNullOrWhiteSpace(id)) @@ -23,8 +23,7 @@ public async Task GetById([FromQuery] string? id) return BadRequest("Provide either id for the artist"); } - [HttpGet("{name}")] - + [HttpGet("name")] public async Task GetByName([FromQuery] string? name) { if (!string.IsNullOrWhiteSpace(name)) @@ -35,8 +34,8 @@ public async Task GetByName([FromQuery] string? name) return BadRequest("Provide either name for the artist"); } - [HttpGet("wikidata/{id}")] - public async Task GetWikidataById(string? id) + [HttpGet("wikidata")] + public async Task GetWikidataById([FromQuery] string? id) { if (!string.IsNullOrWhiteSpace(id)) { @@ -47,12 +46,12 @@ public async Task GetWikidataById(string? id) return BadRequest("Provide id for the wikidata"); } - [HttpGet("summery/{artist}")] - public async Task GetWikiDataSummery(string? artist) + [HttpGet("summery")] + public async Task GetWikiDataSummery([FromQuery] string? enwikiTitle) { - if (!string.IsNullOrWhiteSpace(artist)) + if (!string.IsNullOrWhiteSpace(enwikiTitle)) { - var result = await mediator.Send(new ArtistQuery.GetWikipediaSummary(artist)); + var result = await mediator.Send(new ArtistQuery.GetWikipediaSummary(enwikiTitle)); return result is null ? NotFound() : Ok(result); } diff --git a/Endpoints/ArtistEndPoint.cs b/Endpoints/ArtistEndPoint.cs index 7085f2e..00e3da6 100644 --- a/Endpoints/ArtistEndPoint.cs +++ b/Endpoints/ArtistEndPoint.cs @@ -7,14 +7,14 @@ namespace HollyJukeBox.Endpoints; public class ArtistEndPoint(IOptions options, HttpClient client) : IArtistEndPoint { public async Task GetById(string id) => await client.GetFromJsonAsync( - options.Value.MusicBrainzUrl + $"artist/{id}?inc=release-groups&fmt=json"); + options.Value.MusicBrainzUrl + $"artist/{id}?inc=release-groups+url-rels&fmt=json"); public async Task GetByName(string name) => await client.GetFromJsonAsync( options.Value.MusicBrainzUrl + $"artist?query={name}&fmt=json"); - - public async Task GetWikiData(string id) => await client.GetFromJsonAsync( - options.Value.WikiDataUrl + $"?action=wbgetentities&ids={id}&format=json&props=sitelinks"); - + + public async Task GetWikiData(string id) => await client.GetFromJsonAsync( + options.Value.WikiDataUrl + $"?action=wbgetentities&ids={id}&format=json&props=sitelinks"); + public async Task GetWikipediaSummary(string artist) => await client.GetFromJsonAsync( options.Value.WikipediaSummery + $"{artist}"); } \ No newline at end of file diff --git a/Endpoints/IArtistEndPoint.cs b/Endpoints/IArtistEndPoint.cs index e3fb6ff..7d3e1bb 100644 --- a/Endpoints/IArtistEndPoint.cs +++ b/Endpoints/IArtistEndPoint.cs @@ -7,5 +7,5 @@ public interface IArtistEndPoint public Task GetById(string id); public Task GetByName(string name); public Task GetWikiData(string id); - public Task GetWikipediaSummary(string artist); + public Task GetWikipediaSummary(string enwikiTitle); } \ No newline at end of file diff --git a/Handler/ArtistHandler.cs b/Handler/ArtistHandler.cs index c00da5b..3018e61 100644 --- a/Handler/ArtistHandler.cs +++ b/Handler/ArtistHandler.cs @@ -15,7 +15,7 @@ public async Task Handle(ArtistQuery.GetById query, CancellationToken => await artistEndPoint.GetById(query.Id); public async Task Handle(ArtistQuery.GetByName query, CancellationToken cancellationToken) - { + { var result = await artistEndPoint.GetByName(query.Name); var artist = result.Artists.First(x => string.Equals(x.Name, query.Name, StringComparison.OrdinalIgnoreCase)); artist = await artistEndPoint.GetById(artist.Id); @@ -25,5 +25,5 @@ public async Task Handle(ArtistQuery.GetByName query, CancellationTok public async Task Handle(ArtistQuery.GetWikiData request, CancellationToken cancellationToken) => await artistEndPoint.GetWikiData(request.id); public async Task Handle(ArtistQuery.GetWikipediaSummary request, CancellationToken cancellationToken) - => await artistEndPoint.GetWikipediaSummary(request.artist); + => await artistEndPoint.GetWikipediaSummary(request.enwikiTitle); } \ No newline at end of file diff --git a/Models/ArtistDto.cs b/Models/ArtistDto.cs index 5091b67..ff6ba09 100644 --- a/Models/ArtistDto.cs +++ b/Models/ArtistDto.cs @@ -21,5 +21,5 @@ public record ReleasesGroups( [property: JsonPropertyName("first-release-date")] string FirstReleaseDate ); -public record Relations(List url); +public record Relations(string type, Url url); public record Url(string id, string resource); \ No newline at end of file diff --git a/Models/WikiDataDto.cs b/Models/WikiDataDto.cs index 94195e7..c1bfbc5 100644 --- a/Models/WikiDataDto.cs +++ b/Models/WikiDataDto.cs @@ -9,10 +9,11 @@ public class WikiDataDto } public record Entity( [property: JsonPropertyName("id")] string Id, - [property: JsonPropertyName("sitelinks")] List SiteLinks + [property: JsonPropertyName("sitelinks")] Dictionary Sitelinks ); public record SiteLink( - [property: JsonPropertyName("enwiki")] Enwiki Enwiki + [property: JsonPropertyName("site")] string site, + [property: JsonPropertyName("title")] string title ); public record Enwiki( diff --git a/Querys/ArtistQuery.cs b/Querys/ArtistQuery.cs index eda1809..1de5680 100644 --- a/Querys/ArtistQuery.cs +++ b/Querys/ArtistQuery.cs @@ -8,5 +8,5 @@ public class ArtistQuery : IRequest public record GetById(string Id) : IRequest; public record GetByName(string Name) : IRequest; public record GetWikiData(string id) : IRequest; - public record GetWikipediaSummary(string artist) : IRequest; + public record GetWikipediaSummary(string enwikiTitle) : IRequest; } \ No newline at end of file