diff --git a/checks/core.py b/checks/core.py index 2766483..3ea8c1d 100644 --- a/checks/core.py +++ b/checks/core.py @@ -1,9 +1,9 @@ import html import re -from pkg_resources import parse_version from .vars import * from .utils.utils import * +from .utils import obsversion def checkClassic(lines): @@ -60,52 +60,49 @@ def getOBSVersionString(lines): return versionString.split()[1] -obsver_re = re.compile(r""" - (?i) - (?P[0-9]+) - \. - (?P[0-9]+) - \. - (?P[0-9]+) - ( - - - (?P (?P rc|beta) \d*) - )? - $ - """, re.VERBOSE) +def checkObsVersion(lines): + version = obsversion.ObsVersion(getOBSVersionString(lines)) + if not version.parsed: + return [LEVEL_INFO, f"Unparseable OBS Version ({html.escape(version.string)})", + f"""Your OBS version identifies itself as '{html.escape(version.string)}', which cannot be parsed as a valid OBS version number."""] -def checkObsVersion(lines): - versionString = getOBSVersionString(lines) - - if parse_version(versionString) == parse_version('21.1.0'): - return [LEVEL_WARNING, "Broken Auto-Update", - """You are not running the latest version of OBS Studio. Automatic updates in version 21.1.0 are broken due to a bug.
Please update by downloading the latest installer from the downloads page and running it."""] - - m = obsver_re.search(versionString.replace('-modified', '')) - - if m is None and re.match(r"(?:\d)+\.(?:\d)+\.(?:\d)+\+(?:[\d\w\-\.~\+])+", versionString): - return [LEVEL_INFO, "Unofficial OBS Build (%s)" % (html.escape(versionString)), """Your OBS version identifies itself as '%s', which is not an official build.
If you are on Linux, ensure you're using the PPA. If you cannot switch to the PPA, contact the maintainer of the package for any support issues.""" % (html.escape(versionString))] - if m is None and re.match(r"(?:\d)+\.(?:\d)+\.(?:\d\w)+(?:-caffeine)", versionString): - return [LEVEL_INFO, "Third party OBS Version (%s)" % (html.escape(versionString)), """Your OBS version identifies itself as '%s', which is made by a third party. Contact them for any support issues.""" % (html.escape(versionString))] - if m is None and re.match(r"(?:\d)+\.(?:\d)+\.(?:\d)+-(?:[\d-])*([a-z0-9]+)(?:-modified){0,1}", versionString): - return [LEVEL_INFO, "Custom OBS Build (%s)" % (html.escape(versionString)), """Your OBS version identifies itself as '%s', which is not a released OBS version.""" % (html.escape(versionString))] - if m is None: - return [LEVEL_INFO, "Unparseable OBS Version (%s)" % (html.escape(versionString)), """Your OBS version identifies itself as '%s', which cannot be parsed as a valid OBS version number.""" % (html.escape(versionString))] - - # Do we want these to check the version number and tell the user that a - # release version is actually available, if one is actually available? - # We can consider adding something like that later. - if m.group("special") is not None: - if m.group("special_type") == "beta": - return [LEVEL_INFO, "Beta OBS Version (%s)" % (html.escape(versionString)), """You are running a beta version of OBS. There is nothing wrong with this, but you may experience problems that you may not experience with fully released OBS versions. You are encouraged to upgrade to a released version of OBS as soon as one is available."""] - - if m.group("special_type") == "rc": - return [LEVEL_INFO, "Release Candidate OBS Version (%s)" % (html.escape(versionString)), """You are running a release candidate version of OBS. There is nothing wrong with this, but you may experience problems that you may not experience with fully released OBS versions. You are encouraged to upgrade to a released version of OBS as soon as one is available."""] - - if parse_version(versionString.replace('-modified', '')) < parse_version(CURRENT_VERSION): - return [LEVEL_WARNING, "Old Version (%s)" % versionString, - """You are running an old version of OBS Studio (%s). Please update to version %s by going to Help -> Check for updates in OBS or by downloading the latest installer from the downloads page and running it.""" % (versionString, CURRENT_VERSION)] + if version.modified: + return [LEVEL_INFO, f"Custom OBS Build ({html.escape(version.string)})", + f"""Your OBS version identifies itself as '{html.escape(version.string)}', which is not a released OBS version."""] + + if version.trail and 'caffeine' in version.trail: + return [LEVEL_INFO, f"Third party OBS Version ({html.escape(version.string)})", + f"""Your OBS version identifies itself as '{html.escape(version.string)}', which is made by a third party. Contact them for any support issues."""] + + if version.trail: + if checkOperatingSystem(lines) == "linux": + return [LEVEL_INFO, f"Unofficial OBS Build ({html.escape(version.string)})", + f"""Your OBS version identifies itself as '{html.escape(version.string)}', which is not an official build.
Only the PPA and the flatpak aare official releases. If you cannot or wish not switch to those, please contact the maintainer of your package for any support issues."""] + else: + return [LEVEL_INFO, f"Unofficial OBS Build ({html.escape(version.string)})", + f"""Your OBS version identifies itself as '{html.escape(version.string)}', which is not an official build.
Please contact the maintainer of your release for any support issues."""] + + if version.beta: + if version.version.beta_type == version._beta_types["beta"]: + if version < CURRENT_VERSION: + return [LEVEL_WARNING, f"Outdated Beta OBS Version ({html.escape(version.string)})", + f"""The beta version of OBS you are running is outdated. It is recommended you update to version {CURRENT_VERSION} by going to Help -> Check for updates in OBS or by downloading the latest installer from the downloads page and running it."""] + else: + return [LEVEL_INFO, f"Beta OBS Version ({html.escape(version.string)})", + f"""You are running a beta version of OBS. There is nothing wrong with this, but you may experience problems that you may not experience with fully released OBS versions. You are encouraged to upgrade to a released version of OBS as soon as one is available."""] + + if version.version.beta_type == version._beta_types["rc"]: + if version < CURRENT_VERSION: + return [LEVEL_WARNING, f"Outdated Release Candidate OBS Version ({html.escape(version.string)})", + f"""The release candidate version of OBS you are running is outdated. It is recommended you update to version {CURRENT_VERSION} by going to Help -> Check for updates in OBS or by downloading the latest installer from the downloads page and running it."""] + else: + return [LEVEL_INFO, f"Release Candidate OBS Version ({html.escape(version.string)})", + f"""You are running a release candidate version of OBS. There is nothing wrong with this, but you may experience problems that you may not experience with fully released OBS versions. You are encouraged to upgrade to a released version of OBS as soon as one is available."""] + + if version < CURRENT_VERSION: + return [LEVEL_WARNING, f"Old Version ({html.escape(version.string)})", + f"""You are running an old version of OBS Studio ({html.escape(version.string)}). Please update to version {CURRENT_VERSION} by going to Help -> Check for updates in OBS or by downloading the latest installer from the downloads page and running it."""] def checkOperatingSystem(lines): diff --git a/checks/utils/obsversion.py b/checks/utils/obsversion.py new file mode 100644 index 0000000..be03d29 --- /dev/null +++ b/checks/utils/obsversion.py @@ -0,0 +1,82 @@ +from collections import namedtuple +import re + + +class ObsVersion(): + """ Bespoke OBS version parser + Follows the semver 2.0.0 spec at https://semver.org/ + + Pre-release versioning is stricter than the full semver spec + and MUST have the following formatting : `` + with `` being one of `alpha`, `beta`, or `rc` + and `` (optional) being any number of digits, optionally preceded by a dot + """ + _nan = float('nan') + _regex = re.compile(r"(?P\d+)\.(?P\d+)\.(?P\d+)(-(?Palpha|beta|rc)\.?(?P\d*))?(-(?Pmodified))?((-|\+)(?P[0-9A-Za-z-]+))?") + _VersionNum = namedtuple('VersionNum', 'major, minor, patch, beta_type, beta_patch') + _beta_types = {"alpha": 0, + "beta": 1, + "rc": 2, + None: 3} + + def __init__(self, version_string): + self.string = version_string + self.parsed = False + self.version = self._VersionNum(self._nan, self._nan, self._nan, 3, 0) + # NaN for false comparisons + self.modified = None + self.trail = None + self.beta = False + + try: + match = self._regex.fullmatch(version_string) + if match: + self.version = self._VersionNum(int(match.group('major')), + int(match.group('minor')), + int(match.group('patch')), + self._beta_types[match.group('beta_type')], + int(match.group('beta_patch')) if match.group('beta_patch') else 0 + ) + self.modified = match.group('modified') + self.trail = match.group('trail') + self.beta = self.version.beta_type != self._beta_types[None] + self.parsed = True + + except TypeError: + return + + def __str__(self): + return self.string + + def __repr__(self): + return f"OBS version {self.string}{'' if self.parsed else' (unparseable)'}" + + def __eq__(self, other): + try: + return self.version == other.version + except AttributeError: + return self == ObsVersion(other) + + def __lt__(self, other): + try: + return self.version < other.version + except AttributeError: + return self < ObsVersion(other) + + def __le__(self, other): + try: + return self.version <= other.version + except AttributeError: + return self <= ObsVersion(other) + + def __gt__(self, other): + try: + return self.version > other.version + except AttributeError: + return self > ObsVersion(other) + + def __ge__(self, other): + try: + return self.version >= other.version + except AttributeError: + return self >= ObsVersion(other) diff --git a/checks/windows.py b/checks/windows.py index 792681f..8376d86 100644 --- a/checks/windows.py +++ b/checks/windows.py @@ -1,5 +1,4 @@ import html -from pkg_resources import parse_version from .vars import * from .utils.utils import * @@ -308,14 +307,6 @@ def checkWindowsVer(lines): html.escape(verinfo["name"]), verinfo["EoS"].strftime("%B %Y")) return [LEVEL_WARNING, wv, msg] - # special case for OBS 24.0.3 and earlier, which report Windows 10/1909 - # as being Windows 10/1903 - versionString = getOBSVersionString(lines) - if parse_version(versionString) <= parse_version("24.0.3"): - if verinfo["version"] == "10.0" and verinfo["release"] == 1903: - return [LEVEL_INFO, "Windows 10 1903/1909", - "Due to a bug in OBS versions 24.0.3 and earlier, the exact release of Windows 10 you are using cannot be determined. You are using either release 1903, or release 1909. Fortunately, there were no major changes in behavior between Windows 10 release 1903 and Windows 10 release 1909, and instructions given here for release 1903 can also be used for release 1909, and vice versa."] - # our windows version isn't out of support, so just say what version the user has and when # it actually does go out of support wv = "%s (OK)" % (html.escape(verinfo["name"]))