public int Parent; // 0 if none public AppInfo( int id, string name = null, AppTypes type = AppTypes.Unknown, AppPlatforms platforms = AppPlatforms.All ) { this.Id = id; this.Name = name; this.AppType = type; this.Platforms = platforms; }
public int Parent; // 0 if none public AppInfo(int id, string name = null, AppTypes type = AppTypes.Unknown, AppPlatforms platforms = AppPlatforms.All) { this.Id = id; this.Name = name; this.AppType = type; this.Platforms = platforms; }
public AppInfo(int id, string name = null, AppTypes type = AppTypes.Unknown, AppPlatforms platforms = AppPlatforms.All) { Id = id; Name = name; AppType = type; Platforms = platforms; }
public void DifferentLanguagesShouldHaveSamePlatforms() { const AppPlatforms supportedPlatforms = AppPlatforms.All; _entry1.Platforms.Should().Be(supportedPlatforms); _entry2.Platforms.Should().Be(supportedPlatforms); _entry3.Platforms.Should().Be(supportedPlatforms); }
public void AppPlatformsTest() { // get test Assert.That(AppPlatforms.Ios.ToString(), Is.EqualTo("ios")); Assert.That(AppPlatforms.Android.ToString(), Is.EqualTo("android")); Assert.That(AppPlatforms.WinPhone.ToString(), Is.EqualTo("winphone")); Assert.That(AppPlatforms.Web.ToString(), Is.EqualTo("web")); // parse test Assert.That(AppPlatforms.FromJsonString("ios"), Is.EqualTo(AppPlatforms.Ios)); Assert.That(AppPlatforms.FromJsonString("android"), Is.EqualTo(AppPlatforms.Android)); Assert.That(AppPlatforms.FromJsonString("winphone"), Is.EqualTo(AppPlatforms.WinPhone)); Assert.That(AppPlatforms.FromJsonString("web"), Is.EqualTo(AppPlatforms.Web)); }
public void AppPlatformsTest() { // get test Assert.That(actual: AppPlatforms.Ios.ToString(), expression: Is.EqualTo(expected: "ios")); Assert.That(actual: AppPlatforms.Android.ToString(), expression: Is.EqualTo(expected: "android")); Assert.That(actual: AppPlatforms.WinPhone.ToString(), expression: Is.EqualTo(expected: "winphone")); Assert.That(actual: AppPlatforms.Web.ToString(), expression: Is.EqualTo(expected: "web")); // parse test Assert.That(actual: AppPlatforms.FromJsonString(response: "ios"), expression: Is.EqualTo(expected: AppPlatforms.Ios)); Assert.That(actual: AppPlatforms.FromJsonString(response: "android"), expression: Is.EqualTo(expected: AppPlatforms.Android)); Assert.That(actual: AppPlatforms.FromJsonString(response: "winphone"), expression: Is.EqualTo(expected: AppPlatforms.WinPhone)); Assert.That(actual: AppPlatforms.FromJsonString(response: "web"), expression: Is.EqualTo(expected: AppPlatforms.Web)); }
public override AutoCatResult CategorizeGame(GameInfo game, Filter filter) { if (games == null) { Logger.Error(GlobalStrings.Log_AutoCat_GamelistNull); throw new ApplicationException(GlobalStrings.AutoCatGenre_Exception_NoGameList); } if (game == null) { Logger.Error(GlobalStrings.Log_AutoCat_GameNull); return(AutoCatResult.Failure); } if (!game.IncludeGame(filter)) { return(AutoCatResult.Filtered); } if (!db.Contains(game.Id) || (db.Games[game.Id].LastStoreScrape == 0)) { return(AutoCatResult.NotInDatabase); } AppPlatforms platforms = db.Games[game.Id].Platforms; if (Windows && ((platforms & AppPlatforms.Windows) != 0)) { game.AddCategory(games.GetCategory(GetProcessedString("Windows"))); } if (Windows && ((platforms & AppPlatforms.Mac) != 0)) { game.AddCategory(games.GetCategory(GetProcessedString("Mac"))); } if (Windows && ((platforms & AppPlatforms.Linux) != 0)) { game.AddCategory(games.GetCategory(GetProcessedString("Linux"))); } if (Windows && ((platforms & AppPlatforms.Linux) != 0)) { game.AddCategory(games.GetCategory(GetProcessedString("SteamOS"))); } return(AutoCatResult.Success); }
/// <inheritdoc /> public override AutoCatResult CategorizeGame(GameInfo game, Filter filter) { if (games == null) { Logger.Error(GlobalStrings.Log_AutoCat_GamelistNull); throw new ApplicationException(GlobalStrings.AutoCatGenre_Exception_NoGameList); } if (game == null) { Logger.Error(GlobalStrings.Log_AutoCat_GameNull); return(AutoCatResult.Failure); } if (!game.IncludeGame(filter)) { return(AutoCatResult.Filtered); } if (!db.Contains(game.Id, out DatabaseEntry entry) || entry.LastStoreScrape == 0) { return(AutoCatResult.NotInDatabase); } AppPlatforms platforms = entry.Platforms; if (Windows && platforms.HasFlag(AppPlatforms.Windows)) { game.AddCategory(games.GetCategory(GetCategoryName("Windows"))); } if (Mac && platforms.HasFlag(AppPlatforms.Mac)) { game.AddCategory(games.GetCategory(GetCategoryName("Mac"))); } if (Linux && platforms.HasFlag(AppPlatforms.Linux)) { game.AddCategory(games.GetCategory(GetCategoryName("Linux"))); } if (Linux && platforms.HasFlag(AppPlatforms.Linux)) { game.AddCategory(games.GetCategory(GetCategoryName("SteamOS"))); } return(AutoCatResult.Success); }
/// <summary> /// Merges in data from another entry. Useful for merging scrape results, but could also merge data from a different database. /// Uses newer data when there is a conflict. /// Does NOT perform deep copies of list fields. /// </summary> /// <param name="other">GameDBEntry containing info to be merged into this entry.</param> public void MergeIn(GameDBEntry other) { bool useAppInfoFields = other.LastAppInfoUpdate > this.LastAppInfoUpdate || (this.LastAppInfoUpdate == 0 && other.LastStoreScrape >= this.LastStoreScrape); bool useScrapeOnlyFields = other.LastStoreScrape >= this.LastStoreScrape; if (other.AppType != AppTypes.Unknown && (this.AppType == AppTypes.Unknown || useAppInfoFields)) { this.AppType = other.AppType; } if (other.LastAppInfoUpdate >= this.LastAppInfoUpdate) { this.Platforms = other.Platforms; } if (useAppInfoFields) { if (!string.IsNullOrEmpty(other.Name)) { Name = other.Name; } if (other.ParentId > 0) { ParentId = other.ParentId; } } if (useScrapeOnlyFields) { if (other.Genres != null && other.Genres.Count > 0) { Genres = other.Genres; } if (other.Flags != null && other.Flags.Count > 0) { Flags = other.Flags; } if (other.Tags != null && other.Tags.Count > 0) { Tags = other.Tags; } if (other.Developers != null && other.Developers.Count > 0) { Developers = other.Developers; } if (other.Publishers != null && other.Publishers.Count > 0) { Publishers = other.Publishers; } if (!string.IsNullOrEmpty(other.SteamReleaseDate)) { SteamReleaseDate = other.SteamReleaseDate; } if (other.ReviewTotal != 0) { this.ReviewTotal = other.ReviewTotal; this.ReviewPositivePercentage = other.ReviewPositivePercentage; } if (!string.IsNullOrEmpty(other.MC_Url)) { MC_Url = other.MC_Url; } } if (other.LastStoreScrape > this.LastStoreScrape) { this.LastStoreScrape = other.LastStoreScrape; } if (other.LastAppInfoUpdate > this.LastAppInfoUpdate) { this.LastAppInfoUpdate = other.LastAppInfoUpdate; } }
public static AppInfo FromVdfNode(VdfFileNode commonNode) { if (commonNode == null || commonNode.NodeType != ValueType.Array) { return(null); } AppInfo result = null; VdfFileNode idNode = commonNode.GetNodeAt(new string[] { "gameid" }, false); int id = -1; if (idNode != null) { if (idNode.NodeType == ValueType.Int) { id = idNode.NodeInt; } else if (idNode.NodeType == ValueType.String) { if (!int.TryParse(idNode.NodeString, out id)) { id = -1; } } } if (id >= 0) { // Get name string name = null; VdfFileNode nameNode = commonNode.GetNodeAt(new string[] { "name" }, false); if (nameNode != null) { name = nameNode.NodeData.ToString(); } // Get type string typeStr = null; AppTypes type = AppTypes.Unknown; VdfFileNode typeNode = commonNode.GetNodeAt(new string[] { "type" }, false); if (typeNode != null) { typeStr = typeNode.NodeData.ToString(); } if (typeStr != null) { if (!Enum.TryParse <AppTypes>(typeStr, true, out type)) { type = AppTypes.Other; } } // Get platforms string oslist = null; AppPlatforms platforms = AppPlatforms.None; VdfFileNode oslistNode = commonNode.GetNodeAt(new string[] { "oslist" }, false); if (oslistNode != null) { oslist = oslistNode.NodeData.ToString(); if (oslist.IndexOf("windows", StringComparison.OrdinalIgnoreCase) != -1) { platforms |= AppPlatforms.Windows; } if (oslist.IndexOf("mac", StringComparison.OrdinalIgnoreCase) != -1) { platforms |= AppPlatforms.Mac; } if (oslist.IndexOf("linux", StringComparison.OrdinalIgnoreCase) != -1) { platforms |= AppPlatforms.Linux; } } result = new AppInfo(id, name, type, platforms); // Get parent VdfFileNode parentNode = commonNode.GetNodeAt(new string[] { "parent" }, false); if (parentNode != null) { result.Parent = parentNode.NodeInt; } } return(result); }
private void GetAllDataFromPage(string page) { // Genres Match m = RegexGenre.Match(page); if (m.Success) { Genres = new List <string>(); foreach (Capture cap in m.Groups[2].Captures) { Genres.Add(cap.Value); } } // Flags MatchCollection matches = RegexFlags.Matches(page); if (matches.Count > 0) { Flags = new List <string>(); foreach (Match ma in matches) { string flag = ma.Groups[1].Value; if (!string.IsNullOrWhiteSpace(flag)) { Flags.Add(flag); } } } //Tags matches = RegexTags.Matches(page); if (matches.Count > 0) { Tags = new List <string>(); foreach (Match ma in matches) { string tag = WebUtility.HtmlDecode(ma.Groups[1].Value.Trim()); if (!string.IsNullOrWhiteSpace(tag)) { Tags.Add(tag); } } } //Get VR Support headsets m = RegexVrSupportHeadsetsSection.Match(page); if (m.Success) { matches = RegexVrSupportFlagMatch.Matches(m.Groups[1].Value.Trim()); VrSupport.Headsets = new List <string>(); foreach (Match ma in matches) { string headset = WebUtility.HtmlDecode(ma.Groups[1].Value.Trim()); if (!string.IsNullOrWhiteSpace(headset)) { VrSupport.Headsets.Add(headset); } } } //Get VR Support Input m = RegexVrSupportInputSection.Match(page); if (m.Success) { matches = RegexVrSupportFlagMatch.Matches(m.Groups[1].Value.Trim()); VrSupport.Input = new List <string>(); foreach (Match ma in matches) { string input = WebUtility.HtmlDecode(ma.Groups[1].Value.Trim()); if (!string.IsNullOrWhiteSpace(input)) { VrSupport.Input.Add(input); } } } //Get VR Support Play Area m = RegexVrSupportPlayAreaSection.Match(page); if (m.Success) { matches = RegexVrSupportFlagMatch.Matches(m.Groups[1].Value.Trim()); VrSupport.PlayArea = new List <string>(); foreach (Match ma in matches) { string playArea = WebUtility.HtmlDecode(ma.Groups[1].Value.Trim()); if (!string.IsNullOrWhiteSpace(playArea)) { VrSupport.PlayArea.Add(playArea); } } } //Get Language Support matches = RegexLanguageSupport.Matches(page); if (matches.Count > 0) { LanguageSupport = new LanguageSupport { Interface = new List <string>(), FullAudio = new List <string>(), Subtitles = new List <string>() }; foreach (Match ma in matches) { string language = WebUtility.HtmlDecode(ma.Groups[1].Value.Trim()); if (language.StartsWith("#lang") || language.StartsWith("(")) { continue; //Some store pages on steam are bugged. } if (WebUtility.HtmlDecode(ma.Groups[2].Value.Trim()) != "") //Interface { LanguageSupport.Interface.Add(language); } if (WebUtility.HtmlDecode(ma.Groups[3].Value.Trim()) != "") //Full Audio { LanguageSupport.FullAudio.Add(language); } if (WebUtility.HtmlDecode(ma.Groups[4].Value.Trim()) != "") //Subtitles { LanguageSupport.Subtitles.Add(language); } } } //Get Achievement number m = RegexAchievements.Match(page); if (m.Success) { //sometimes games have achievements but don't have the "Steam Achievements" flag in the store if (!Flags.Contains("Steam Achievements")) { Flags.Add("Steam Achievements"); } if (int.TryParse(m.Groups[1].Value, out int num)) { TotalAchievements = num; } } // Get Developer m = RegexDevelopers.Match(page); if (m.Success) { Developers = new List <string>(); foreach (Capture cap in m.Groups[3].Captures) { Developers.Add(WebUtility.HtmlDecode(cap.Value)); } } // Get Publishers m = RegexPublishers.Match(page); if (m.Success) { Publishers = new List <string>(); foreach (Capture cap in m.Groups[3].Captures) { Publishers.Add(WebUtility.HtmlDecode(cap.Value)); } } // Get release date m = RegexReleaseDate.Match(page); if (m.Success) { SteamReleaseDate = m.Groups[1].Captures[0].Value; } // Get user review data m = RegexReviews.Match(page); if (m.Success) { if (int.TryParse(m.Groups[1].Value, out int num)) { ReviewPositivePercentage = num; } if (int.TryParse(m.Groups[2].Value, NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out num)) { ReviewTotal = num; } } // Get metacritic url m = RegexMetacriticLink.Match(page); if (m.Success) { MetacriticUrl = m.Groups[1].Captures[0].Value; } // Get Platforms m = RegexPlatformWindows.Match(page); if (m.Success) { Platforms |= AppPlatforms.Windows; } m = RegexPlatformMac.Match(page); if (m.Success) { Platforms |= AppPlatforms.Mac; } m = RegexPlatformLinux.Match(page); if (m.Success) { Platforms |= AppPlatforms.Linux; } }
public void ScrapeTrueSteamAchievements() { // We can only scrape TrueSteamAchievements in English if (Database.Language != StoreLanguage.English) { Logger.Warn("Scraping TSA {0}: Database langauge is not English, aborting scraping", Id); return; } if (string.IsNullOrWhiteSpace(Name)) { Logger.Warn("Scraping TSA {0}: Entry name is empty, aborting scraping", Id); return; } string page; string name = Name.Replace(" ", "-").Replace(":", "").Replace("'", ""); string hubPage = string.Format(CultureInfo.InvariantCulture, "https://truesteamachievements.com/game/{0}", name); try { using (WebClient webClient = new WebClient()) { page = webClient.DownloadString(hubPage); } } catch (Exception e) { Logger.Warn("Scraping TSA {0}: Page read failed. {1}", Id, e.Message); LastStoreScrape = 0; return; } MatchCollection matches = RegexPlatformTSA.Matches(page); if (matches.Count > 0) { Platforms = AppPlatforms.None; foreach (Match m in matches) { string platform = m.Groups[1].Value; if (platform.Contains("Windows")) { Platforms |= AppPlatforms.Windows; } if (platform.Contains("Mac")) { Platforms |= AppPlatforms.Mac; } if (platform.Contains("Linux")) { Platforms |= AppPlatforms.Linux; } } } Match match = RegexDevelopersTSA.Match(page); if (match.Success) { string developer = match.Groups[1].Value; if (!string.IsNullOrWhiteSpace(developer)) { Developers = new List <string>(); string[] developers = developer.Split(','); foreach (string dev in developers) { if (!string.IsNullOrWhiteSpace(dev)) { Developers.Add(dev); } } } } match = RegexPublisherTSA.Match(page); if (match.Success) { string publisher = match.Groups[1].Value; if (!string.IsNullOrWhiteSpace(publisher)) { Publishers = new List <string>(); string[] publishers = publisher.Split(','); foreach (string pub in publishers) { if (!string.IsNullOrWhiteSpace(pub)) { Publishers.Add(pub); } } } } matches = RegexGenreTSA.Matches(page); if (matches.Count > 0) { Genres = new List <string>(); foreach (Match m in matches) { string genre = WebUtility.HtmlDecode(m.Groups[1].Value.Trim()); if (!string.IsNullOrWhiteSpace(genre)) { Genres.Add(genre); } } } LastStoreScrape = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); Logger.Info("Scraping TSA {0}: Parsed. Genre: {1}", Id, string.Join(",", Genres)); }
/// <summary> /// Merges in data from another entry. Useful for merging scrape results, but could also merge data from a different /// database. /// Uses newer data when there is a conflict. /// Does NOT perform deep copies of list fields. /// </summary> /// <param name="other">GameDBEntry containing info to be merged into this entry.</param> public void MergeIn(DatabaseEntry other) { bool useAppInfoFields = (other.LastAppInfoUpdate > LastAppInfoUpdate) || ((LastAppInfoUpdate == 0) && (other.LastStoreScrape >= LastStoreScrape)); bool useScrapeOnlyFields = other.LastStoreScrape >= LastStoreScrape; if ((other.AppType != AppType.Unknown) && ((AppType == AppType.Unknown) || useAppInfoFields)) { AppType = other.AppType; } if ((other.LastStoreScrape >= LastStoreScrape) || ((LastStoreScrape == 0) && (other.LastAppInfoUpdate > LastAppInfoUpdate)) || (Platforms == AppPlatforms.None)) { Platforms = other.Platforms; } if (useAppInfoFields) { if (!string.IsNullOrEmpty(other.Name)) { Name = other.Name; } if (other.ParentId > 0) { ParentId = other.ParentId; } } if (useScrapeOnlyFields) { if ((other.Genres != null) && (other.Genres.Count > 0)) { Genres = other.Genres; } if ((other.Flags != null) && (other.Flags.Count > 0)) { Flags = other.Flags; } if ((other.Tags != null) && (other.Tags.Count > 0)) { Tags = other.Tags; } if ((other.Developers != null) && (other.Developers.Count > 0)) { Developers = other.Developers; } if ((other.Publishers != null) && (other.Publishers.Count > 0)) { Publishers = other.Publishers; } if (!string.IsNullOrEmpty(other.SteamReleaseDate)) { SteamReleaseDate = other.SteamReleaseDate; } if (other.TotalAchievements != 0) { TotalAchievements = other.TotalAchievements; } //VR Support if ((other.VrSupport.Headsets != null) && (other.VrSupport.Headsets.Count > 0)) { VrSupport.Headsets = other.VrSupport.Headsets; } if ((other.VrSupport.Input != null) && (other.VrSupport.Input.Count > 0)) { VrSupport.Input = other.VrSupport.Input; } if ((other.VrSupport.PlayArea != null) && (other.VrSupport.PlayArea.Count > 0)) { VrSupport.PlayArea = other.VrSupport.PlayArea; } //Language Support if ((other.LanguageSupport.FullAudio != null) && (other.LanguageSupport.FullAudio.Count > 0)) { LanguageSupport.FullAudio = other.LanguageSupport.FullAudio; } if ((other.LanguageSupport.Interface != null) && (other.LanguageSupport.Interface.Count > 0)) { LanguageSupport.Interface = other.LanguageSupport.Interface; } if ((other.LanguageSupport.Subtitles != null) && (other.LanguageSupport.Subtitles.Count > 0)) { LanguageSupport.Subtitles = other.LanguageSupport.Subtitles; } if (other.ReviewTotal != 0) { ReviewTotal = other.ReviewTotal; ReviewPositivePercentage = other.ReviewPositivePercentage; } if (!string.IsNullOrEmpty(other.MetacriticUrl)) { MetacriticUrl = other.MetacriticUrl; } } if (other.LastStoreScrape > LastStoreScrape) { LastStoreScrape = other.LastStoreScrape; } if (other.LastAppInfoUpdate > LastAppInfoUpdate) { LastAppInfoUpdate = other.LastAppInfoUpdate; } }
public void ScrapeTrueSteamAchievements() { // We can only scrape TrueSteamAchievements in English if (Settings.Instance.StoreLanguage != StoreLanguage.English) { return; } if (string.IsNullOrWhiteSpace(Name)) { return; } string page; string name = Name.Replace(" ", "-").Replace(":", "").Replace("'", ""); string hubPage = string.Format(CultureInfo.InvariantCulture, "https://truesteamachievements.com/game/{0}", name); using (WebClient webClient = new WebClient()) { page = webClient.DownloadString(hubPage); } MatchCollection matches = RegexPlatformTSA.Matches(page); if (matches.Count > 0) { Platforms = AppPlatforms.None; foreach (Match m in matches) { string platform = m.Groups[1].Value; if (platform.Contains("Windows")) { Platforms |= AppPlatforms.Windows; } if (platform.Contains("Mac")) { Platforms |= AppPlatforms.Mac; } if (platform.Contains("Linux")) { Platforms |= AppPlatforms.Linux; } } } Match match = RegexDevelopersTSA.Match(page); if (match.Success) { string developer = match.Groups[1].Value; if (!string.IsNullOrWhiteSpace(developer)) { Developers = new List <string>(); string[] developers = developer.Split(','); foreach (string dev in developers) { if (!string.IsNullOrWhiteSpace(dev)) { Developers.Add(dev); } } } } match = RegexPublisherTSA.Match(page); if (match.Success) { string publisher = match.Groups[1].Value; if (!string.IsNullOrWhiteSpace(publisher)) { Publishers = new List <string>(); string[] publishers = publisher.Split(','); foreach (string pub in publishers) { if (!string.IsNullOrWhiteSpace(pub)) { Publishers.Add(pub); } } } } matches = RegexGenreTSA.Matches(page); if (matches.Count > 0) { Genres = new List <string>(); foreach (Match m in matches) { string genre = WebUtility.HtmlDecode(m.Groups[1].Value.Trim()); if (!string.IsNullOrWhiteSpace(genre)) { Genres.Add(genre); } } } LastStoreScrape = Utility.GetCurrentUTime(); }