Edit on GitHub

backend.workers.check_updates

 1import packaging.version
 2import requests
 3import json
 4
 5from common.lib.helpers import add_notification, get_github_version
 6from backend.lib.worker import BasicWorker
 7from pathlib import Path
 8
 9
10class UpdateChecker(BasicWorker):
11    """
12    Check for updates
13
14    Checks the configured Github repository (if any) for the latest packaged
15    release. If the tag of that release is newer than the current version (per
16    the .current-version file), a notification is shown to 4CAT admins in the
17    web interface. Once the current version is updated the notification is
18    automatically removed.
19    """
20    type = "check-for-updates"
21    max_workers = 1
22
23    # check once every three hours
24    ensure_job = {"remote_id": "", "interval": 10800}
25
26    def work(self):
27        versionfile = Path(self.config.get("PATH_ROOT"), "config/.current-version")
28        repo_url = self.config.get("4cat.github_url")
29
30        if not versionfile.exists() or not repo_url:
31            # need something to compare against...
32            return
33
34        timeout = 15
35        try:
36            (latest_tag, release_url) = get_github_version(self.config.get("4cat.github_url"), timeout)
37            if latest_tag == "unknown":
38                raise ValueError()
39        except ValueError:
40            self.log.warning("'4cat.github_url' may be misconfigured - repository does not exist or is private")
41            return
42        except requests.Timeout:
43            self.log.warning(f"GitHub URL '4cat.github_url' did not respond within {timeout} seconds - not checking for new version")
44            return
45        except (requests.RequestException, json.JSONDecodeError):
46            # some issue with the data, or the GitHub API, but not something we
47            # can fix from this end, so just silently fail
48            return
49
50        with versionfile.open() as infile:
51            current_version = infile.readline().strip()
52
53        if packaging.version.parse(latest_tag) > packaging.version.parse(current_version):
54            # update available!
55            # show a notification for all admins (normal users can't update
56            # after all)
57            add_notification(self.db, "!admin",
58                             "A new version of 4CAT is [available](%s). The latest version is %s; you are running version %s." % (
59                                 release_url, latest_tag, current_version
60                             ), allow_dismiss=True)
61
62        else:
63            # up to date? dismiss any notifications about new versions
64            self.db.execute("DELETE FROM users_notifications WHERE username = '!admin' "
65                            "AND notification LIKE 'A new version of 4CAT%'")
class UpdateChecker(backend.lib.worker.BasicWorker):
11class UpdateChecker(BasicWorker):
12    """
13    Check for updates
14
15    Checks the configured Github repository (if any) for the latest packaged
16    release. If the tag of that release is newer than the current version (per
17    the .current-version file), a notification is shown to 4CAT admins in the
18    web interface. Once the current version is updated the notification is
19    automatically removed.
20    """
21    type = "check-for-updates"
22    max_workers = 1
23
24    # check once every three hours
25    ensure_job = {"remote_id": "", "interval": 10800}
26
27    def work(self):
28        versionfile = Path(self.config.get("PATH_ROOT"), "config/.current-version")
29        repo_url = self.config.get("4cat.github_url")
30
31        if not versionfile.exists() or not repo_url:
32            # need something to compare against...
33            return
34
35        timeout = 15
36        try:
37            (latest_tag, release_url) = get_github_version(self.config.get("4cat.github_url"), timeout)
38            if latest_tag == "unknown":
39                raise ValueError()
40        except ValueError:
41            self.log.warning("'4cat.github_url' may be misconfigured - repository does not exist or is private")
42            return
43        except requests.Timeout:
44            self.log.warning(f"GitHub URL '4cat.github_url' did not respond within {timeout} seconds - not checking for new version")
45            return
46        except (requests.RequestException, json.JSONDecodeError):
47            # some issue with the data, or the GitHub API, but not something we
48            # can fix from this end, so just silently fail
49            return
50
51        with versionfile.open() as infile:
52            current_version = infile.readline().strip()
53
54        if packaging.version.parse(latest_tag) > packaging.version.parse(current_version):
55            # update available!
56            # show a notification for all admins (normal users can't update
57            # after all)
58            add_notification(self.db, "!admin",
59                             "A new version of 4CAT is [available](%s). The latest version is %s; you are running version %s." % (
60                                 release_url, latest_tag, current_version
61                             ), allow_dismiss=True)
62
63        else:
64            # up to date? dismiss any notifications about new versions
65            self.db.execute("DELETE FROM users_notifications WHERE username = '!admin' "
66                            "AND notification LIKE 'A new version of 4CAT%'")

Check for updates

Checks the configured Github repository (if any) for the latest packaged release. If the tag of that release is newer than the current version (per the .current-version file), a notification is shown to 4CAT admins in the web interface. Once the current version is updated the notification is automatically removed.

type = 'check-for-updates'
max_workers = 1
ensure_job = {'remote_id': '', 'interval': 10800}
def work(self):
27    def work(self):
28        versionfile = Path(self.config.get("PATH_ROOT"), "config/.current-version")
29        repo_url = self.config.get("4cat.github_url")
30
31        if not versionfile.exists() or not repo_url:
32            # need something to compare against...
33            return
34
35        timeout = 15
36        try:
37            (latest_tag, release_url) = get_github_version(self.config.get("4cat.github_url"), timeout)
38            if latest_tag == "unknown":
39                raise ValueError()
40        except ValueError:
41            self.log.warning("'4cat.github_url' may be misconfigured - repository does not exist or is private")
42            return
43        except requests.Timeout:
44            self.log.warning(f"GitHub URL '4cat.github_url' did not respond within {timeout} seconds - not checking for new version")
45            return
46        except (requests.RequestException, json.JSONDecodeError):
47            # some issue with the data, or the GitHub API, but not something we
48            # can fix from this end, so just silently fail
49            return
50
51        with versionfile.open() as infile:
52            current_version = infile.readline().strip()
53
54        if packaging.version.parse(latest_tag) > packaging.version.parse(current_version):
55            # update available!
56            # show a notification for all admins (normal users can't update
57            # after all)
58            add_notification(self.db, "!admin",
59                             "A new version of 4CAT is [available](%s). The latest version is %s; you are running version %s." % (
60                                 release_url, latest_tag, current_version
61                             ), allow_dismiss=True)
62
63        else:
64            # up to date? dismiss any notifications about new versions
65            self.db.execute("DELETE FROM users_notifications WHERE username = '!admin' "
66                            "AND notification LIKE 'A new version of 4CAT%'")

This is where the actual work happens

Whatever the worker is supposed to do, it should happen (or be initiated from) this method. By default it does nothing, descending classes should implement this method.