Sort RIPs after non-RIPs.
Uglify output table per YouSmellFunky's request. Removes dependency on tabulate. Rename Games->Game, Updates->Update in table header. Abbreviate number of reviews using SI prefixes.
This commit is contained in:
parent
419333fac3
commit
d109ce92c5
|
@ -10,9 +10,8 @@ from datetime import datetime, timedelta
|
||||||
|
|
||||||
import prawcore
|
import prawcore
|
||||||
import requests_cache
|
import requests_cache
|
||||||
from tabulate import tabulate
|
|
||||||
|
|
||||||
from dailyreleases import config, __version__
|
from dailyreleases import config, __version__, util
|
||||||
from dailyreleases.gog import GOG
|
from dailyreleases.gog import GOG
|
||||||
from dailyreleases.predb import Predb
|
from dailyreleases.predb import Predb
|
||||||
from dailyreleases.reddit import Reddit
|
from dailyreleases.reddit import Reddit
|
||||||
|
@ -148,16 +147,15 @@ class DailyReleasesBot(object):
|
||||||
else:
|
else:
|
||||||
platform = "Windows"
|
platform = "Windows"
|
||||||
|
|
||||||
# Find type (games/dlc/updates)
|
# Find type (game/dlc/update)
|
||||||
rls_type = "Games"
|
# Order of the if-statements is important: Update trumps DLC because an update to a DLC is an update, not a DLC!
|
||||||
|
rls_type = "Game"
|
||||||
# Order of the if-statements is important: update trumps dlc because an update to a DLC is an update, not a dlc!
|
|
||||||
if re.search("(?<!incl[._-])dlc", # 'Incl.DLC' isn't a DLC-release
|
if re.search("(?<!incl[._-])dlc", # 'Incl.DLC' isn't a DLC-release
|
||||||
rls_name, flags=re.IGNORECASE):
|
rls_name, flags=re.IGNORECASE):
|
||||||
rls_type = "DLC"
|
rls_type = "DLC"
|
||||||
if re.search("update|v[0-9]|addon|Crack[._-]?fix|DIR[._-]?FIX|build[._-]?[0-9]+",
|
if re.search("update|v[0-9]|addon|Crack[._-]?fix|DIR[._-]?FIX|build[._-]?[0-9]+",
|
||||||
rls_name, flags=re.IGNORECASE):
|
rls_name, flags=re.IGNORECASE):
|
||||||
rls_type = "Updates"
|
rls_type = "Update"
|
||||||
|
|
||||||
logger.info("Offline: %s %s : %s - %s", platform, rls_type, game_name, group)
|
logger.info("Offline: %s %s : %s - %s", platform, rls_type, game_name, group)
|
||||||
logger.info("Tags: %s. Highlights: %s", tags, highlights)
|
logger.info("Tags: %s. Highlights: %s", tags, highlights)
|
||||||
|
@ -170,10 +168,9 @@ class DailyReleasesBot(object):
|
||||||
logger.info("Skipping %s: no store link (probably software)", dirname)
|
logger.info("Skipping %s: no store link (probably software)", dirname)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Sadly, Steam is the de facto pc game store. Therefore, (almost) all the popular games are published there.
|
# Game score and number of reviews is -1 by default; it is updated if the game exists on Steam
|
||||||
# For this reason, game popularity and score is -1 be default; it is updated if the game exists on Steam.
|
score = -1
|
||||||
popularity = -1
|
num_reviews = -1
|
||||||
review_score = -1
|
|
||||||
|
|
||||||
# If one of the store links we found is to Steam, use their API to get (better) information about the game.
|
# If one of the store links we found is to Steam, use their API to get (better) information about the game.
|
||||||
# Note: Doesn't apply to Steam bundles, as Steam has no public API for those.
|
# Note: Doesn't apply to Steam bundles, as Steam has no public API for those.
|
||||||
|
@ -188,11 +185,11 @@ class DailyReleasesBot(object):
|
||||||
# Set game name to package name (e.g. 'Fallout New Vegas Ultimate' instead of 'Fallout New Vegas')
|
# Set game name to package name (e.g. 'Fallout New Vegas Ultimate' instead of 'Fallout New Vegas')
|
||||||
game_name = steam_packagedetails["name"]
|
game_name = steam_packagedetails["name"]
|
||||||
|
|
||||||
# Find the "base game" of the package (the most popular app in the package)
|
# Find "base game" of the package; the most popular app (i.e. the one with the most reviews)
|
||||||
steam_package_appids = {str(app["id"]) for app in steam_packagedetails["apps"]}
|
steam_package_appids = [str(app["id"]) for app in steam_packagedetails["apps"]]
|
||||||
steam_package_appdetails = [self.steam.appdetails(appid) for appid in steam_package_appids]
|
steam_package_apps_appdetails = [self.steam.appdetails(appid) for appid in steam_package_appids]
|
||||||
steam_package_basegame_appdetails = max(steam_package_appdetails,
|
steam_package_basegame_appdetails = max(steam_package_apps_appdetails,
|
||||||
key=lambda app: self.steam.popularity(app["steam_appid"]))
|
key=lambda app: self.steam.reviews(app["steam_appid"]).number)
|
||||||
|
|
||||||
# Use the base game of the package as the basis for further computation
|
# Use the base game of the package as the basis for further computation
|
||||||
steam_appdetails = steam_package_basegame_appdetails
|
steam_appdetails = steam_package_basegame_appdetails
|
||||||
|
@ -203,14 +200,13 @@ class DailyReleasesBot(object):
|
||||||
steam_appdetails = self.steam.appdetails(steam_appid)
|
steam_appdetails = self.steam.appdetails(steam_appid)
|
||||||
game_name = steam_appdetails["name"]
|
game_name = steam_appdetails["name"]
|
||||||
|
|
||||||
# Now that we have chosen a single Steam game to represent the release, use it to improve the information
|
# Now that we have a single Steam game to represent the release, use it to improve the information
|
||||||
popularity = self.steam.popularity(steam_appid)
|
score, num_reviews = self.steam.reviews(steam_appid)
|
||||||
review_score = self.steam.review_score(steam_appid)
|
|
||||||
|
|
||||||
# DLC releases doesn't always contain the word "dlc" (e.g. 'Fallout New Vegas: Dead Money'), so some DLCs
|
# DLC releases doesn't always contain the word "dlc" (e.g. 'Fallout New Vegas: Dead Money'), so some DLCs
|
||||||
# get mislabeled as games during offline parsing. We can use the Steam API to get the correct release type,
|
# get mislabeled as games during offline parsing. We can use the Steam API to get the correct release type,
|
||||||
# but if the release was already deemed an update, keep it as such, because an update to a DLC is an update.
|
# but if the release was already deemed an update, keep it as such, because an update to a DLC is an update.
|
||||||
if rls_type != "Updates" and steam_appdetails["type"] == "dlc":
|
if steam_appdetails["type"] == "dlc" and rls_type != "Update":
|
||||||
rls_type = "DLC"
|
rls_type = "DLC"
|
||||||
|
|
||||||
# If Steam links to a 3rd-party EULAs, check it for the word "denuvo" and add a highlight if it occurs
|
# If Steam links to a 3rd-party EULAs, check it for the word "denuvo" and add a highlight if it occurs
|
||||||
|
@ -231,8 +227,8 @@ class DailyReleasesBot(object):
|
||||||
"type": rls_type,
|
"type": rls_type,
|
||||||
"platform": platform,
|
"platform": platform,
|
||||||
"store_links": store_links,
|
"store_links": store_links,
|
||||||
"popularity": popularity,
|
"score": score,
|
||||||
"review_score": review_score,
|
"num_reviews": num_reviews,
|
||||||
"tags": tags,
|
"tags": tags,
|
||||||
"highlights": highlights
|
"highlights": highlights
|
||||||
}
|
}
|
||||||
|
@ -299,41 +295,53 @@ class DailyReleasesBot(object):
|
||||||
post.append(f"# {platform_name}")
|
post.append(f"# {platform_name}")
|
||||||
|
|
||||||
for type_name, type_releases in sorted(platform_releases.items(),
|
for type_name, type_releases in sorted(platform_releases.items(),
|
||||||
key=lambda n: ("Games", "Updates", "DLC").index(n[0])):
|
key=lambda n: ("Game", "Update", "DLC").index(n[0])):
|
||||||
# Skip release type if there are no releases for it
|
# Skip release type if there are no releases for it
|
||||||
if not type_releases:
|
if not type_releases:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# The sub-tables for updates will use the entire rls_name as the name, while games and dlcs will show
|
# Releases in the tables are grouped by release group, and the groups are ordered according to the most
|
||||||
# tags and highlights, as well as the actual game_name
|
# popular game within the group. Games are sorted by popularity internally in the groups as well.
|
||||||
def row(r):
|
# The popularity of a game is defined by the number of reviews it has on Steam. The popularity of the
|
||||||
if type_name == "Updates":
|
# release itself extends this definition, but ranks RIPs lower than non-RIPS.
|
||||||
name = "[{}]({})".format(r["rls_name"], r["nfo_link"])
|
def popularity(rls):
|
||||||
else:
|
is_rip = "RIP" in [tag.upper() for tag in rls["tags"]]
|
||||||
tags = " ({})".format(" ".join(r["tags"])) if r["tags"] else ""
|
return rls["num_reviews"], not is_rip
|
||||||
highlights = " **- {}**".format(", ".join(r["highlights"])) if r["highlights"] else ""
|
|
||||||
name = "[{}{}]({}){}".format(r["game_name"], tags, r["nfo_link"], highlights)
|
|
||||||
|
|
||||||
if r["review_score"] != -1:
|
group_order = defaultdict(lambda: (-1, False))
|
||||||
reviews = "{:.0%} ^^\({}\)".format(r["review_score"], r["popularity"])
|
|
||||||
else:
|
|
||||||
reviews = "-"
|
|
||||||
|
|
||||||
stores = ", ".join(f"[{name}]({link})" for name, link in r["store_links"].items())
|
|
||||||
|
|
||||||
return name, r["group"], reviews, stores
|
|
||||||
|
|
||||||
# Releases in the sub-tables are grouped by release group, and the groups are ordered according to the
|
|
||||||
# most popular game within the group. Games are sorted by popularity internally in the groups.
|
|
||||||
group_popularity = defaultdict(int)
|
|
||||||
for rls in type_releases:
|
for rls in type_releases:
|
||||||
group_popularity[rls["group"]] = max(group_popularity[rls["group"]], rls["popularity"])
|
group = rls["group"]
|
||||||
|
group_order[group] = max(group_order[group], popularity(rls))
|
||||||
|
|
||||||
table = [row(rls)
|
sorted_releases = sorted(type_releases,
|
||||||
for rls in sorted(type_releases,
|
key=lambda r: (group_order[r["group"]],
|
||||||
key=lambda r: (group_popularity[r["group"]], r["group"], r["popularity"]),
|
r["group"], # ensure grouping if two groups share group_order
|
||||||
reverse=True)]
|
popularity(r)),
|
||||||
post.append(tabulate(table, headers=(type_name, "Group", "Reviews", "Stores"), tablefmt="pipe"))
|
reverse=True)
|
||||||
|
|
||||||
|
# The rows in tables containing updates will use the full rls_name as the name, while tables containing
|
||||||
|
# game and DLC releases will show tags and highlights, as well as the actual stylized game_name.
|
||||||
|
def row(rls):
|
||||||
|
if type_name == "Update":
|
||||||
|
name = "[{}]({})".format(rls["rls_name"], rls["nfo_link"])
|
||||||
|
else:
|
||||||
|
tags = " ({})".format(" ".join(rls["tags"])) if rls["tags"] else ""
|
||||||
|
highlights = " **- {}**".format(", ".join(rls["highlights"])) if rls["highlights"] else ""
|
||||||
|
name = "[{}{}]({}){}".format(rls["game_name"], tags, rls["nfo_link"], highlights)
|
||||||
|
|
||||||
|
if rls["score"] == -1:
|
||||||
|
reviews = "-"
|
||||||
|
else:
|
||||||
|
num_reviews_humanized = util.humanize(rls["num_reviews"], precision=1, prefix="dec", suffix="")
|
||||||
|
reviews = "{:.0%} ({})".format(rls["score"], num_reviews_humanized)
|
||||||
|
|
||||||
|
stores = ", ".join(f"[{name}]({link})" for name, link in rls["store_links"].items())
|
||||||
|
|
||||||
|
return name, rls["group"], stores, reviews
|
||||||
|
|
||||||
|
post.append(f"| {type_name} | Group | Store | Score (Reviews) |")
|
||||||
|
post.append("|:-|:-|:-|:-|")
|
||||||
|
post.extend("| {} | {} | {} | {} |".format(*row(rls)) for rls in sorted_releases)
|
||||||
|
|
||||||
post.append("")
|
post.append("")
|
||||||
post.append(" ")
|
post.append(" ")
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
from dailyreleases import util
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -33,14 +36,15 @@ class Steam(object):
|
||||||
r = self.cache.get(f"https://store.steampowered.com/appreviews/{appid}", params=payload)
|
r = self.cache.get(f"https://store.steampowered.com/appreviews/{appid}", params=payload)
|
||||||
return r.json()["query_summary"]
|
return r.json()["query_summary"]
|
||||||
|
|
||||||
def review_score(self, appid):
|
def reviews(self, appid):
|
||||||
app_review = self.appreviews(appid)
|
app_review = self.appreviews(appid)
|
||||||
if app_review["total_reviews"] == 0:
|
Reviews = namedtuple("Reviews", ("score", "number"))
|
||||||
return -1
|
|
||||||
return app_review["total_positive"] / app_review["total_reviews"]
|
|
||||||
|
|
||||||
def popularity(self, appid):
|
if app_review["total_reviews"] == 0:
|
||||||
return self.appreviews(appid)["total_reviews"]
|
return Reviews(-1, -1)
|
||||||
|
|
||||||
|
positive = app_review["total_positive"] / app_review["total_reviews"]
|
||||||
|
return Reviews(positive, app_review["total_reviews"])
|
||||||
|
|
||||||
def eula(self, appid):
|
def eula(self, appid):
|
||||||
return self.cache.get(f"https://store.steampowered.com//eula/{appid}_eula_0").text
|
return self.cache.get(f"https://store.steampowered.com//eula/{appid}_eula_0").text
|
||||||
|
|
|
@ -1,6 +1,31 @@
|
||||||
import difflib
|
import difflib
|
||||||
|
|
||||||
|
|
||||||
|
def humanize(n, precision=2, prefix="bin", suffix="B") -> str:
|
||||||
|
"""
|
||||||
|
Return a humanized string representation of a number (of bytes).
|
||||||
|
Adapted from Doug Latornell - http://code.activestate.com/recipes/577081/
|
||||||
|
"""
|
||||||
|
abbrevs = {
|
||||||
|
"dec": [
|
||||||
|
(1000 ** 5, 'P' + suffix),
|
||||||
|
(1000 ** 4, 'T' + suffix),
|
||||||
|
(1000 ** 3, 'G' + suffix),
|
||||||
|
(1000 ** 2, 'M' + suffix),
|
||||||
|
(1000 ** 1, 'k' + suffix)
|
||||||
|
],
|
||||||
|
"bin": [
|
||||||
|
(1 << 50, 'Pi' + suffix),
|
||||||
|
(1 << 40, 'Ti' + suffix),
|
||||||
|
(1 << 30, 'Gi' + suffix),
|
||||||
|
(1 << 20, 'Mi' + suffix),
|
||||||
|
(1 << 10, 'ki' + suffix)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
factor, suffix = next(((f, s) for f, s in abbrevs[prefix] if n >= f), (1, suffix))
|
||||||
|
return "{1:.{0}f}".format(precision, n / factor).rstrip("0").rstrip(".") + suffix
|
||||||
|
|
||||||
|
|
||||||
def case_insensitive_close_matches(word, possibilities, n=3, cutoff=0.6):
|
def case_insensitive_close_matches(word, possibilities, n=3, cutoff=0.6):
|
||||||
"""
|
"""
|
||||||
Python's difflib.get_close_matches does case sensitive sequence matching, this function decorates the library
|
Python's difflib.get_close_matches does case sensitive sequence matching, this function decorates the library
|
||||||
|
|
3
setup.py
3
setup.py
|
@ -40,8 +40,7 @@ setup(
|
||||||
"requests",
|
"requests",
|
||||||
"requests_cache",
|
"requests_cache",
|
||||||
"praw",
|
"praw",
|
||||||
"beautifulsoup4",
|
"beautifulsoup4"
|
||||||
"tabulate"
|
|
||||||
],
|
],
|
||||||
entry_points={
|
entry_points={
|
||||||
"console_scripts": [
|
"console_scripts": [
|
||||||
|
|
|
@ -14,7 +14,7 @@ class ParseDirnameTestCase(unittest.TestCase):
|
||||||
self.assertEqual("Aztez", p["rls_name"])
|
self.assertEqual("Aztez", p["rls_name"])
|
||||||
self.assertEqual("Aztez", p["game_name"])
|
self.assertEqual("Aztez", p["game_name"])
|
||||||
self.assertEqual("Windows", p["platform"])
|
self.assertEqual("Windows", p["platform"])
|
||||||
self.assertEqual("Games", p["type"])
|
self.assertEqual("Game", p["type"])
|
||||||
self.assertEqual("DARKSiDERS", p["group"])
|
self.assertEqual("DARKSiDERS", p["group"])
|
||||||
self.assertIn("store.steampowered.com/app/244750", p["store_links"]["Steam"])
|
self.assertIn("store.steampowered.com/app/244750", p["store_links"]["Steam"])
|
||||||
self.assertEqual([], p["tags"])
|
self.assertEqual([], p["tags"])
|
||||||
|
@ -27,7 +27,7 @@ class ParseDirnameTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test_update(self):
|
def test_update(self):
|
||||||
p = self.bot.parse_dirname("Car.Mechanic.Simulator.2018.Plymouth.Update.v1.5.1.Hotfix-PLAZA")
|
p = self.bot.parse_dirname("Car.Mechanic.Simulator.2018.Plymouth.Update.v1.5.1.Hotfix-PLAZA")
|
||||||
self.assertEqual("Updates", p["type"])
|
self.assertEqual("Update", p["type"])
|
||||||
|
|
||||||
def test_proper_highlight(self):
|
def test_proper_highlight(self):
|
||||||
p = self.bot.parse_dirname("Death.Coming.PROPER-SiMPLEX")
|
p = self.bot.parse_dirname("Death.Coming.PROPER-SiMPLEX")
|
||||||
|
@ -36,17 +36,17 @@ class ParseDirnameTestCase(unittest.TestCase):
|
||||||
def test_macos_release(self):
|
def test_macos_release(self):
|
||||||
p = self.bot.parse_dirname("The_Fall_Part_2_Unbound_MacOS-Razor1911")
|
p = self.bot.parse_dirname("The_Fall_Part_2_Unbound_MacOS-Razor1911")
|
||||||
self.assertEqual("Mac OSX", p["platform"])
|
self.assertEqual("Mac OSX", p["platform"])
|
||||||
self.assertEqual("Games", p["type"])
|
self.assertEqual("Game", p["type"])
|
||||||
|
|
||||||
def test_macosx_update(self):
|
def test_macosx_update(self):
|
||||||
p = self.bot.parse_dirname("Man_O_War_Corsair_Warhammer_Naval_Battles_v1.3.2_MacOSX-Razor1911")
|
p = self.bot.parse_dirname("Man_O_War_Corsair_Warhammer_Naval_Battles_v1.3.2_MacOSX-Razor1911")
|
||||||
self.assertEqual("Mac OSX", p["platform"])
|
self.assertEqual("Mac OSX", p["platform"])
|
||||||
self.assertEqual("Updates", p["type"])
|
self.assertEqual("Update", p["type"])
|
||||||
|
|
||||||
def test_linux_release(self):
|
def test_linux_release(self):
|
||||||
p = self.bot.parse_dirname("Sphinx_And_The_Cursed_Mummy_Linux-Razor1911")
|
p = self.bot.parse_dirname("Sphinx_And_The_Cursed_Mummy_Linux-Razor1911")
|
||||||
self.assertEqual("Linux", p["platform"])
|
self.assertEqual("Linux", p["platform"])
|
||||||
self.assertEqual("Games", p["type"])
|
self.assertEqual("Game", p["type"])
|
||||||
|
|
||||||
def test_dlc_explicit(self):
|
def test_dlc_explicit(self):
|
||||||
p = self.bot.parse_dirname("Fallout.4.Far.Harbor.DLC-CODEX")
|
p = self.bot.parse_dirname("Fallout.4.Far.Harbor.DLC-CODEX")
|
||||||
|
@ -59,30 +59,31 @@ class ParseDirnameTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test_incl_dlc_update(self):
|
def test_incl_dlc_update(self):
|
||||||
p = self.bot.parse_dirname("Wolfenstein.II.The.New.Colossus.Update.5.incl.DLC-CODEX")
|
p = self.bot.parse_dirname("Wolfenstein.II.The.New.Colossus.Update.5.incl.DLC-CODEX")
|
||||||
self.assertEqual("Updates", p["type"])
|
self.assertEqual("Update", p["type"])
|
||||||
|
|
||||||
def test_incl_dlc_release(self):
|
def test_incl_dlc_release(self):
|
||||||
p = self.bot.parse_dirname("Mutiny.Incl.DLC-DARKSiDERS")
|
p = self.bot.parse_dirname("Mutiny.Incl.DLC-DARKSiDERS")
|
||||||
self.assertEqual("Games", p["type"])
|
self.assertEqual("Game", p["type"])
|
||||||
|
|
||||||
def test_popularity_steam(self):
|
def test_score_steam(self):
|
||||||
p1 = self.bot.parse_dirname("BioShock_Infinite-FLT")
|
p1 = self.bot.parse_dirname("BioShock_Infinite-FLT")
|
||||||
p2 = self.bot.parse_dirname("Duke.Nukem.Forever.Complete-PLAZA")
|
p2 = self.bot.parse_dirname("Duke.Nukem.Forever.Complete-PLAZA")
|
||||||
self.assertGreater(p1["popularity"], p2["popularity"])
|
self.assertGreater(p1["score"], p2["score"])
|
||||||
|
|
||||||
def test_non_steam(self):
|
def test_non_steam(self):
|
||||||
p = self.bot.parse_dirname("Battlefield.1.REPACK-CPY")
|
p = self.bot.parse_dirname("Battlefield.1.REPACK-CPY")
|
||||||
self.assertIn("www.origin.com/usa/en-us/store/battlefield/battlefield-1", p["store_links"]["Origin"])
|
self.assertIn("www.origin.com/usa/en-us/store/battlefield/battlefield-1", p["store_links"]["Origin"])
|
||||||
self.assertEqual(-1, p["popularity"])
|
self.assertEqual(-1, p["score"])
|
||||||
|
self.assertEqual(-1, p["num_reviews"])
|
||||||
|
|
||||||
def test_gog_exclusive(self):
|
def test_gog_exclusive(self):
|
||||||
p = self.bot.parse_dirname("Dungeons.and.Dragons.Dragonshard.v2.0.0.10.Multilingual-DELiGHT")
|
p = self.bot.parse_dirname("Dungeons.and.Dragons.Dragonshard.v2.0.0.10.Multilingual-DELiGHT")
|
||||||
self.assertIn("gog.com/game/dungeons_dragons_dragonshard", p["store_links"]["GOG"])
|
self.assertIn("gog.com/game/dungeons_dragons_dragonshard", p["store_links"]["GOG"])
|
||||||
self.assertEqual(-1, p["popularity"])
|
self.assertEqual(-1, p["score"])
|
||||||
|
|
||||||
def test_popularity_non_steam(self):
|
def test_score_non_steam(self):
|
||||||
p = self.bot.parse_dirname("Ode.RIP.MULTI12-SiMPLEX")
|
p = self.bot.parse_dirname("Ode.RIP.MULTI12-SiMPLEX")
|
||||||
self.assertEqual(-1, p["popularity"])
|
self.assertEqual(-1, p["score"])
|
||||||
|
|
||||||
def test_tags(self):
|
def test_tags(self):
|
||||||
p = self.bot.parse_dirname("Teenage.Mutant.Ninja.Turtles.Portal.Power.RIP.MULTI8-SiMPLEX")
|
p = self.bot.parse_dirname("Teenage.Mutant.Ninja.Turtles.Portal.Power.RIP.MULTI8-SiMPLEX")
|
||||||
|
@ -95,13 +96,13 @@ class ParseDirnameTestCase(unittest.TestCase):
|
||||||
def test_steam_package(self):
|
def test_steam_package(self):
|
||||||
p = self.bot.parse_dirname("Farming.Simulator.17.Platinum.Edition.Update.v1.5.3-BAT")
|
p = self.bot.parse_dirname("Farming.Simulator.17.Platinum.Edition.Update.v1.5.3-BAT")
|
||||||
self.assertEqual("Farming Simulator 17 - Platinum Edition", p["game_name"])
|
self.assertEqual("Farming Simulator 17 - Platinum Edition", p["game_name"])
|
||||||
self.assertEqual("Updates", p["type"])
|
self.assertEqual("Update", p["type"])
|
||||||
self.assertIn("store.steampowered.com/sub/202103", p["store_links"]["Steam"])
|
self.assertIn("store.steampowered.com/sub/202103", p["store_links"]["Steam"])
|
||||||
|
|
||||||
def test_steam_package_with_dlc_first(self):
|
def test_steam_package_with_dlc_first(self):
|
||||||
p = self.bot.parse_dirname("The.Witcher.3.Wild.Hunt.Game.of.The.Year.Edition-RELOADED")
|
p = self.bot.parse_dirname("The.Witcher.3.Wild.Hunt.Game.of.The.Year.Edition-RELOADED")
|
||||||
self.assertEqual("The Witcher 3: Wild Hunt - Game of the Year Edition", p["game_name"])
|
self.assertEqual("The Witcher 3: Wild Hunt - Game of the Year Edition", p["game_name"])
|
||||||
self.assertEqual("Games", p["type"])
|
self.assertEqual("Game", p["type"])
|
||||||
self.assertIn("store.steampowered.com/sub/124923", p["store_links"]["Steam"])
|
self.assertIn("store.steampowered.com/sub/124923", p["store_links"]["Steam"])
|
||||||
|
|
||||||
def test_steam_bundle(self):
|
def test_steam_bundle(self):
|
||||||
|
@ -109,7 +110,7 @@ class ParseDirnameTestCase(unittest.TestCase):
|
||||||
self.assertEqual("Valve.Complete.Pack-FAKE", p["dirname"])
|
self.assertEqual("Valve.Complete.Pack-FAKE", p["dirname"])
|
||||||
self.assertEqual("Valve Complete Pack", p["game_name"])
|
self.assertEqual("Valve Complete Pack", p["game_name"])
|
||||||
self.assertEqual("Windows", p["platform"])
|
self.assertEqual("Windows", p["platform"])
|
||||||
self.assertEqual("Games", p["type"])
|
self.assertEqual("Game", p["type"])
|
||||||
self.assertIn("store.steampowered.com/bundle/232", p["store_links"]["Steam"])
|
self.assertIn("store.steampowered.com/bundle/232", p["store_links"]["Steam"])
|
||||||
|
|
||||||
def test_denuvo_eula(self):
|
def test_denuvo_eula(self):
|
||||||
|
@ -129,7 +130,7 @@ class ParseDirnameTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test_build_is_update(self):
|
def test_build_is_update(self):
|
||||||
p = self.bot.parse_dirname("DUSK.Episode.1.Build.2.6-SKIDROW")
|
p = self.bot.parse_dirname("DUSK.Episode.1.Build.2.6-SKIDROW")
|
||||||
self.assertEqual("Updates", p["type"])
|
self.assertEqual("Update", p["type"])
|
||||||
|
|
||||||
def test_readnfo_microsoft_store(self):
|
def test_readnfo_microsoft_store(self):
|
||||||
p = self.bot.parse_dirname("Zoo.Tycoon.Ultimate.Animal.Collection.READNFO-CODEX")
|
p = self.bot.parse_dirname("Zoo.Tycoon.Ultimate.Animal.Collection.READNFO-CODEX")
|
||||||
|
|
Reference in a new issue