Skip to content
This repository has been archived by the owner on Jan 21, 2025. It is now read-only.

Commit

Permalink
Initial. Name and Links metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
sharkusmanch committed Aug 14, 2021
0 parents commit 777dc60
Show file tree
Hide file tree
Showing 13 changed files with 498 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
bin/
dist/
obj/
tmp/
*.sln
87 changes: 87 additions & 0 deletions PCGWClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using Playnite.SDK;
using RestSharp;
using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;

namespace PCGamingWikiMetadata
{
public class PCGWClient
{
private readonly ILogger logger = LogManager.GetLogger();
private readonly string baseUrl = @"https://www.pcgamingwiki.com/w/api.php";
private RestClient client;

public PCGWClient()
{
client = new RestClient(baseUrl);
}

public JObject ExecuteRequest(RestRequest request)
{
request.AddParameter("format", "json", ParameterType.QueryString);
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
var fullUrl = client.BuildUri(request);
logger.Info(fullUrl.ToString());
var response = client.Execute(request);

if (response.ErrorException != null)
{
const string message = "Error retrieving response. Check inner details for more info.";
var e = new Exception(message, response.ErrorException);
throw e;
}
var content = response.Content;

logger.Debug(content);
return JObject.Parse(content);
}

private string NormalizeSearchString(string search)
{
string updated = search.Replace("-", " ");

return updated;
}

public List<GenericItemOption> SearchGames(string searchName)
{
List<GenericItemOption> gameResults = new List<GenericItemOption>();
logger.Info(searchName);

var request = new RestRequest("/", Method.GET);
request.AddParameter("action", "query", ParameterType.QueryString);
request.AddParameter("list", "search", ParameterType.QueryString);
request.AddParameter("srsearch", NormalizeSearchString(searchName), ParameterType.QueryString);

try
{
JObject searchResults = ExecuteRequest(request);
JToken error;

if (searchResults.TryGetValue("error", out error))
{
logger.Error($"Encountered API error: {error.ToString()}");
return gameResults;
}

logger.Debug($"SearchGames {searchResults["query"]["searchinfo"]["totalhits"]} results for {searchName}");

foreach (dynamic game in searchResults["query"]["search"])
{
if (!((string)game.snippet).Contains("#REDIRECT"))
{
PCGWGame g = new PCGWGame((string)game.title, (int)game.pageid);
gameResults.Add(g);
}
}
}
catch (Exception e)
{
logger.Error(e, "Error performing search");
}

return gameResults;
}
}
}
77 changes: 77 additions & 0 deletions PCGWGame.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System;
using Playnite.SDK;
using Playnite.SDK.Models;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;

namespace PCGamingWikiMetadata
{
public class PCGWGame : GenericItemOption
{

public int PageID {get; set; }

private List<Link> links;
public List<Link> Links { get { return links; } }
private IDictionary<string, IList<string>> data;
public IDictionary<string, IList<string>> Data { get { return data; } }

private IDictionary<string, IList<string>> sobj;
public IDictionary<string, IList<string>> Sobj { get {return sobj;} }

public PCGWGame()
{
this.links = new List<Link>();
}

public PCGWGame(string name, int pageid)
{
this.Name = name;
this.PageID = pageid;
this.links = new List<Link>();
this.links.Add(PCGamingWikiLink());
}
protected Link PCGamingWikiLink()
{
string escapedName = Uri.EscapeUriString(this.Name);
return new Link("PCGamingWiki", $"https://www.pcgamingwiki.com/wiki/{escapedName}");
}

public void Update(JObject gameData)
{
UpdateDynamic(gameData);
}

protected void UpdateDynamic(dynamic gameData)
{
this.data = DataToDictionary(gameData.query.data);

if (gameData.query.sobj.Count != 1)
{
Console.WriteLine($"Got sobj list of size: {gameData.query.sobj.Count}");
}

this.sobj = DataToDictionary(gameData.query.sobj[0].data);

this.Name = this.Sobj["_SKEY"][0];
}

private IDictionary<string, IList<string>> DataToDictionary(JArray data)
{
IDictionary<string, IList<string>> dataDict = new Dictionary<string, IList<string>>();

foreach (dynamic attribute in data)
{
IList<string> dataItems = new List<string>();
foreach (dynamic item in attribute.dataitem)
{
dataItems.Add((string)item.item);
}

dataDict.Add((string)attribute.property, dataItems);
}

return dataDict;
}
}
}
48 changes: 48 additions & 0 deletions PCGamingWikiMetadata.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Playnite.SDK;
using Playnite.SDK.Plugins;
using System;
using System.Collections.Generic;
using System.Windows.Controls;


namespace PCGamingWikiMetadata
{
public class PCGamingWikiMetadata : MetadataPlugin
{
private static readonly ILogger logger = LogManager.GetLogger();

private PCGamingWikiMetadataSettings settings { get; set; }

public override Guid Id { get; } = Guid.Parse("c038558e-427b-4551-be4c-be7009ce5a8d");

public override List<MetadataField> SupportedFields { get; } = new List<MetadataField>
{
MetadataField.Name,
MetadataField.Links
};

// Change to something more appropriate
public override string Name => "PCGamingWiki";

public PCGamingWikiMetadata(IPlayniteAPI api) : base(api)
{
settings = new PCGamingWikiMetadataSettings(this);
}

public override OnDemandMetadataProvider GetMetadataProvider(MetadataRequestOptions options)
{
return new PCGamingWikiMetadataProvider(options, this);
}

public override ISettings GetSettings(bool firstRunSettings)
{
return settings;
}

public override UserControl GetSettingsView(bool firstRunSettings)
{
return new PCGamingWikiMetadataSettingsView();
}

}
}
31 changes: 31 additions & 0 deletions PCGamingWikiMetadata.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

<PropertyGroup>
<TargetFramework>net462</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="RestSharp" Version="106.10.1" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="WindowsBase" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="PlayniteSDK" Version="5.5.0" />
</ItemGroup>

<ItemGroup>
<None Include="extension.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
<None Include="icon.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
128 changes: 128 additions & 0 deletions PCGamingWikiMetadataProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
using Playnite.SDK.Plugins;
using Playnite.SDK;
using Playnite.SDK.Models;
using System.Collections.Generic;
using System;

namespace PCGamingWikiMetadata
{
public class PCGamingWikiMetadataProvider : OnDemandMetadataProvider
{
private readonly MetadataRequestOptions options;
private readonly PCGamingWikiMetadata plugin;

private PCGWClient client;

private PCGWGame pcgwData;
private static readonly ILogger logger = LogManager.GetLogger();

private List<MetadataField> availableFields;
public override List<MetadataField> AvailableFields
{
get
{
if (availableFields == null)
{
availableFields = GetAvailableFields();
}

return availableFields;
}
}

private List<MetadataField> GetAvailableFields()
{
if (pcgwData == null)
{
GetPCGWMetadata();
}

var fields = new List<MetadataField> { MetadataField.Name };
return fields;
}

private void GetPCGWMetadata()
{
if (pcgwData != null)
{
return;
}

logger.Debug("GetPCGWMetadata");

if (!options.IsBackgroundDownload)
{
logger.Debug("Starting selection...");

var item = plugin.PlayniteApi.Dialogs.ChooseItemWithSearch(null, (a) =>
{
return client.SearchGames(a);
}, options.GameData.Name);

if (item != null)
{
var searchItem = item as PCGWGame;
logger.Debug($"GetPCGWMetadata for {searchItem.Name}");
this.pcgwData = (PCGWGame)item;
}
else
{
this.pcgwData = new PCGWGame();
logger.Warn($"Cancelled search");
}
}
else
{
try
{
List<GenericItemOption> results = client.SearchGames(options.GameData.Name);

if (results.Count == 0)
{
this.pcgwData = new PCGWGame();
return;
}

if (results.Count > 1)
{
logger.Warn($"More than one result for {options.GameData.Name}. Using first result.");
}

this.pcgwData = (PCGWGame)results[0];
}
catch (Exception e)
{
logger.Error(e, "Failed to get PCGW metadata.");
}
}
}

public PCGamingWikiMetadataProvider(MetadataRequestOptions options, PCGamingWikiMetadata plugin)
{
this.options = options;
this.plugin = plugin;
this.client = new PCGWClient();
}

public override string GetName()
{
if (AvailableFields.Contains(MetadataField.Name))
{
return this.pcgwData.Name;
}

return base.GetName();
}


public override List<Link> GetLinks()
{
if (AvailableFields.Contains(MetadataField.Links))
{
return this.pcgwData.Links;
}

return base.GetLinks();
}
}
}
Loading

0 comments on commit 777dc60

Please sign in to comment.