Skip to content

Commit

Permalink
Merge pull request DSPaul#2 from DSPAUL/dev
Browse files Browse the repository at this point in the history
Update to 0.2.0
  • Loading branch information
DSPaul authored Jun 14, 2022
2 parents 8db92eb + d5b4c7e commit 8049f15
Show file tree
Hide file tree
Showing 13 changed files with 223 additions and 144 deletions.
18 changes: 16 additions & 2 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
# Changelog

## 0.1.0 (10/06/22)
Release of 0.1.0
## COMPASS v0.2.0 (14 Jun 2022)

### Fixes

- Importing a homebrewery file would sometimes fail
- Metadata fields of homebrewery were cut short if they contained a comma

### New Features

- Google drive import has been added, supported metadate is:
- Cover
- Title
- Automatic update checking and installing

## COMPASS 0.1.0 (10 Jun 2022)
- Release of 0.1.0
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ If you are an RPG fan like me, you probably have lots of pdf's both homebrew and
## Features
- **Unify** your digital tabletop RPG sourcebook library so everything is in one place.
- **Import** any pdf or link a URL for online sources. You can also manually add books to include your physical collection.
- **Automatic metadata** such as Author, Publisher, Release date from pdf's and supported sites that can be used to sort and filter your books. Supported sites at the moment are Homebrewery and GM Binder.
- **Automatic metadata** such as Author, Publisher, Release date from pdf's and supported sites that can be used to sort and filter your books. Supported sites at the moment are Homebrewery, GM Binder and Google Drive.
- **Categorize** all your books using Tags. You can add Tags for anything you like, some examples:
- The type of content like *Adventure*, *Monster Stats* or *Setting/Lore*.
- The edition or ruleset such as *DnD 5e* or *Pathfinder 2e*.
Expand Down
10 changes: 4 additions & 6 deletions src/COMPASS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@
<ApplicationIcon>COMPASS.ico</ApplicationIcon>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<StartupObject>COMPASS.App</StartupObject>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>

<ItemGroup>
<None Remove="faviconv4.ico" />
<None Remove="JadeCompass.ico" />
</ItemGroup>

<ItemGroup>

<Content Include="COMPASS.ico" />
Expand All @@ -29,6 +25,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Autoupdater.NET.Official" Version="1.7.3" />
<PackageReference Include="gong-wpf-dragdrop" Version="3.1.1" />
<PackageReference Include="HtmlAgilityPack">
<Version>1.11.43</Version>
Expand All @@ -48,7 +45,8 @@
<PackageReference Include="MaterialDesignThemes">
<Version>4.5.0</Version>
</PackageReference>
<PackageReference Include="NetSparkleUpdater.SparkleUpdater" Version="2.1.1" />
<PackageReference Include="NetSparkleUpdater.UI.WPF" Version="2.1.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="ScrapySharp">
<Version>3.0.0</Version>
</PackageReference>
Expand Down
2 changes: 0 additions & 2 deletions src/Models/PreferableFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ public PreferableFunction(string name, Func<T,bool> func, int id = -1)
}

public Func<T,bool> Function { get; private set; }

public int ID { get; set; }
}

//Default generic is of type object, to match relayfunctions
Expand Down
3 changes: 1 addition & 2 deletions src/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,5 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyVersion("0.2.0")]
//[assembly: AssemblyFileVersion("1.0.0")]
2 changes: 1 addition & 1 deletion src/Properties/PublishProfiles/FolderProfile.pubxml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\net6.0-windows\publish\win-x64\</PublishDir>
<PublishDir>bin\Publish\win-x64\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<TargetFramework>net6.0-windows</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
Expand Down
175 changes: 98 additions & 77 deletions src/Tools/CoverFetcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace COMPASS
Expand Down Expand Up @@ -88,6 +88,7 @@ public static bool GetCoverFromURL(Codex c)
if (URL.Contains("dndbeyond.com")) source = Enums.Sources.DnDBeyond;
else if (URL.Contains("gmbinder.com")) source = Enums.Sources.GmBinder;
else if (URL.Contains("homebrewery.naturalcrit.com")) source = Enums.Sources.Homebrewery;
else if (URL.Contains("drive.google.com")) source = Enums.Sources.GoogleDrive;
//if none of above, unsupported site
else
{
Expand All @@ -99,109 +100,129 @@ public static bool GetCoverFromURL(Codex c)

return GetCoverFromURL(c, source);
}
public static bool GetCoverFromURL(Codex destfile, Enums.Sources? source)
public static bool GetCoverFromURL(Codex destfile, Enums.Sources source)
{
string URL = destfile.SourceURL;

if (String.IsNullOrEmpty(URL)) return false;

if (source == Enums.Sources.DnDBeyond)
//sites that store cover as image that can be downloaded
if(source.HasFlag(Enums.Sources.DnDBeyond) || source.HasFlag(Enums.Sources.GoogleDrive))
{
try
{
HtmlWeb web = new HtmlWeb();
//cover art is on store page, redirect there by going to /credits which every book has
HtmlDocument doc = web.Load(string.Concat(URL, "/credits"));
HtmlNode src = doc.DocumentNode;
HtmlDocument doc;
HtmlNode src;
string imgURL = "";

string imgURL = src.SelectSingleNode("//img[@class='product-hero-avatar__image']").GetAttributeValue("content", String.Empty);

using (WebClient client = new WebClient())
switch (source)
{
client.DownloadFile(new Uri(imgURL), destfile.CoverArt);
case Enums.Sources.DnDBeyond:
//cover art is on store page, redirect there by going to /credits which every book has
doc = web.Load(string.Concat(URL, "/credits"));
src = doc.DocumentNode;

imgURL = src.SelectSingleNode("//img[@class='product-hero-avatar__image']").GetAttributeValue("content", String.Empty);
break;

case Enums.Sources.GoogleDrive:
doc = web.Load(URL);
src = doc.DocumentNode;

imgURL = src.SelectSingleNode("//meta[@property='og:image']").GetAttributeValue("content", String.Empty);
//cut of "=W***-h***-p" from URL that crops the image if it is present
if (imgURL.Contains("=")) imgURL = imgURL.Split('=')[0];
break;
}
//download the file
var imgBytes = Task.Run(async () => await Utils.DownloadFileAsync(imgURL)).Result;
File.WriteAllBytes(destfile.CoverArt, imgBytes);
}
catch
{
return false;
}
}

//Use Selenium for screenshotting pages
DriverService driverService;
WebDriver driver;
switch (Properties.Settings.Default.SeleniumBrowser)
{
case (int)Enums.Browser.Chrome:
driverService = ChromeDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
ChromeOptions CO = new ChromeOptions();
CO.AddArgument("--window-size=2500,2000");
CO.AddArgument("--headless");
driver = new ChromeDriver((ChromeDriverService)driverService, CO);
break;

case (int)Enums.Browser.Firefox:
driverService = FirefoxDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
FirefoxOptions FO = new FirefoxOptions();
FO.AddArgument("--window-size=2500,2000");
FO.AddArgument("--headless");
driver = new FirefoxDriver((FirefoxDriverService)driverService, FO);
break;

default:
driverService = EdgeDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
EdgeOptions EO = new EdgeOptions();
EO.AddArgument("--window-size=2500,2000");
EO.AddArgument("--headless");
driver = new EdgeDriver((EdgeDriverService)driverService, EO);
break;
}

IWebElement Coverpage;
MagickImage image = null;
try

//sites do not store cover as img, Use Selenium for screenshotting pages
else if (source.HasFlag(Enums.Sources.GmBinder) || source.HasFlag(Enums.Sources.Homebrewery))
{
driver.Navigate().GoToUrl(URL);

switch (source)
DriverService driverService;
WebDriver driver;
switch (Properties.Settings.Default.SeleniumBrowser)
{
case Enums.Sources.GmBinder:
Coverpage = driver.FindElement(By.Id("p1"));
//screenshot and download the image
image = GetCroppedScreenShot(driver, Coverpage.Location, Coverpage.Size);
case (int)Enums.Browser.Chrome:
driverService = ChromeDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
ChromeOptions CO = new ChromeOptions();
CO.AddArgument("--window-size=2500,2000");
CO.AddArgument("--headless");
driver = new ChromeDriver((ChromeDriverService)driverService, CO);
break;

case (int)Enums.Browser.Firefox:
driverService = FirefoxDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
FirefoxOptions FO = new FirefoxOptions();
FO.AddArgument("--window-size=2500,2000");
FO.AddArgument("--headless");
driver = new FirefoxDriver((FirefoxDriverService)driverService, FO);
break;

case Enums.Sources.Homebrewery:
//get nav height because scraper doesn't see nav anymore after it switched to frame
var nav = driver.FindElement(By.XPath("//nav"));
string navhstr = nav.GetCssValue("height");
float navheight = float.Parse(navhstr.Substring(0, navhstr.Length - 2), CultureInfo.InvariantCulture);

//switch to iframe
var iframe = driver.FindElement(By.XPath("//iframe"));
driver.SwitchTo().Frame(iframe);
Coverpage = driver.FindElement(By.Id("p1"));
//shift page down by nav height because element location is relative to frame, but coords on screenshot is reletaive to page
int newY = (int)Math.Round(Coverpage.Location.Y + navheight, 0);

//screenshot and download the image
image = GetCroppedScreenShot(driver, new System.Drawing.Point(Coverpage.Location.X, newY), Coverpage.Size);
default:
driverService = EdgeDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
EdgeOptions EO = new EdgeOptions();
EO.AddArgument("--window-size=2500,2000");
EO.AddArgument("--headless");
driver = new EdgeDriver((EdgeDriverService)driverService, EO);
break;
}

if (image.Width > 850) image.Resize(850, 0);
image.Write(destfile.CoverArt);
}
catch
{
IWebElement Coverpage;
MagickImage image = null;
try
{
driver.Navigate().GoToUrl(URL);

switch (source)
{
case Enums.Sources.GmBinder:
Coverpage = driver.FindElement(By.Id("p1"));
//screenshot and download the image
image = GetCroppedScreenShot(driver, Coverpage.Location, Coverpage.Size);
break;

case Enums.Sources.Homebrewery:
//get nav height because scraper doesn't see nav anymore after it switched to frame
var nav = driver.FindElement(By.XPath("//nav"));
string navhstr = nav.GetCssValue("height");
float navheight = float.Parse(navhstr.Substring(0, navhstr.Length - 2), CultureInfo.InvariantCulture);

//switch to iframe
var iframe = driver.FindElement(By.XPath("//iframe"));
driver.SwitchTo().Frame(iframe);
Coverpage = driver.FindElement(By.Id("p1"));
//shift page down by nav height because element location is relative to frame, but coords on screenshot is reletaive to page
int newY = (int)Math.Round(Coverpage.Location.Y + navheight, 0);

//screenshot and download the image
image = GetCroppedScreenShot(driver, new System.Drawing.Point(Coverpage.Location.X, newY), Coverpage.Size);
break;
}

if (image.Width > 850) image.Resize(850, 0);
image.Write(destfile.CoverArt);
}
catch
{
driver.Quit();
return false;
}
driver.Quit();
return false;
}

driver.Quit();

CreateThumbnail(destfile);
return true;
}
Expand Down
3 changes: 2 additions & 1 deletion src/Tools/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ public enum Sources
Pdf = 2,
GmBinder = 4,
Homebrewery = 8,
DnDBeyond = 16
DnDBeyond = 16,
GoogleDrive = 32
}

public enum FilterType
Expand Down
33 changes: 33 additions & 0 deletions src/Tools/Utils.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using COMPASS.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Threading.Tasks;

namespace COMPASS.Tools
{
Expand Down Expand Up @@ -60,5 +64,34 @@ public static bool tryFunctions<T>(ObservableCollection<PreferableFunction<T>> t
{
return tryFunctions<T>(toTry.ToList(), arg);
}

//Download data and put it in a byte[]
public static async Task<byte[]> DownloadFileAsync(string uri)
{
using (HttpClient client = new HttpClient())
{
Uri uriResult;

if (!Uri.TryCreate(uri, UriKind.Absolute, out uriResult)) throw new InvalidOperationException("URI is invalid.");

return await client.GetByteArrayAsync(uri);
}
}

//helper function for InitWebdriver to check if certain browsers are installed
public static bool IsInstalled(string name)
{
string currentUserRegistryPathPattern = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\App Paths\";
string localMachineRegistryPathPattern = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\";

var currentUserPath = Microsoft.Win32.Registry.GetValue(currentUserRegistryPathPattern + name, "", null);
var localMachinePath = Microsoft.Win32.Registry.GetValue(localMachineRegistryPathPattern + name, "", null);

if (currentUserPath != null | localMachinePath != null)
{
return true;
}
return false;
}
}
}
Loading

0 comments on commit 8049f15

Please sign in to comment.