Compare commits
4 commits
7c5e429ae0
...
1f182df473
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f182df473 | ||
|
|
800c4c2ee3 | ||
|
|
8e7fcc6ed2 | ||
|
|
11c3103e3b |
2 changed files with 72 additions and 41 deletions
72
config.py
72
config.py
|
|
@ -14,19 +14,40 @@ from issue_generator import FeedReader, GithubReader, GithubTagReader, PIPYReade
|
|||
TIMEOUT
|
||||
import _secrets
|
||||
|
||||
class AlpinePackageReader(FeedReader):
|
||||
'''Custom feed reader for Alpine packages'''
|
||||
def __init__(self, package: str, targets: IssuePoster):
|
||||
super().__init__(package, "https://gitlab.alpinelinux.org/alpine/aports/-/commits/master.atom", targets)
|
||||
self.regex = r'community/([^:]+): upgrade to (.+)'
|
||||
self.package = package
|
||||
|
||||
def is_valid_item(self, entry) -> bool:
|
||||
match = re.search(self.regex, entry.title)
|
||||
return match and match.groups(1) == self.package
|
||||
|
||||
def entry_get_version(self, entry: dict[str, Any]) -> tuple[str, str]:
|
||||
match = re.search(self.regex, entry.title)
|
||||
if match and match.groups(1) == self.package:
|
||||
return (match.groups(2),) * 2
|
||||
raise RuntimeError(f"Checking version for package {self.package} in invalid entry titled: {entry.title}")
|
||||
|
||||
def entry_get_link(self, entry: dict[str, Any]) -> str:
|
||||
return entry.id
|
||||
|
||||
|
||||
class UDSClientReader(FeedReader):
|
||||
'''Custom feed reader for UDSClient, whose version number appears in a .js file.'''
|
||||
|
||||
def __init__(self, target: IssuePoster):
|
||||
def __init__(self, targets: IssuePoster):
|
||||
'''Creates a new UDSClient Reader.'''
|
||||
super().__init__("udsclient", "https://polilabs.upv.es/uds/utility/uds.js", target)
|
||||
super().__init__("udsclient", "https://polilabs.upv.es/uds/utility/uds.js", targets)
|
||||
|
||||
def read_feed(self) -> bool | None:
|
||||
'''Checks for a new version of udsclient, by checking a .js file.'''
|
||||
get = requests.get(self.url, timeout = TIMEOUT)
|
||||
if not self.target.check_req(get, self.name):
|
||||
return None
|
||||
for target in self.targets:
|
||||
if not target.check_req(get, self.name):
|
||||
return None
|
||||
match = re.search(r"[/a-zA-Z_-]+udsclient\d+-(\d+\.\d+\.\d+)\.tar\.gz", get.text)
|
||||
if not match:
|
||||
return None
|
||||
|
|
@ -55,7 +76,7 @@ class NCAppReader(GithubReader):
|
|||
'''All GitHub releases readers that must alert Forgejo's `archpkgs`.'''
|
||||
def __init__(self, app, project):
|
||||
super().__init__(name = app, project = project,
|
||||
target = CGJForgejoPoster("archpkgs/" + app))
|
||||
targets = CGJForgejoPoster("archpkgs/" + app))
|
||||
|
||||
|
||||
# Issue Posters
|
||||
|
|
@ -70,20 +91,18 @@ FEED_READERS = [
|
|||
# Name FeedType Project TargetProject
|
||||
################################ Software used in MIST (Gitlab) ###################################
|
||||
# LanguageTool GHTags languagetool-org/languagetool 36 (sysadmin/boira)
|
||||
GithubTagReader(name = "LanguageTool", project = "languagetool-org/languagetool",
|
||||
target = GITLAB_BOIRA_CARGAJI),
|
||||
GithubTagReader(name = "LanguageTool", project = "languagetool-org/languagetool",
|
||||
targets = GITLAB_BOIRA_CARGAJI),
|
||||
# meshcentral GHReleases Ylianst/MeshCentral 36 (sysadmin/boira)
|
||||
GithubReader(name = "meshcentral", project = "Ylianst/MeshCentral",
|
||||
target = GITLAB_BOIRA_CARGAJI),
|
||||
# meshcentral GHReleases Ylianst/MeshCentral archpkgs/meshcentral
|
||||
GithubReader(name = "meshcentral", project = "Ylianst/MeshCentral",
|
||||
targets = [GITLAB_BOIRA_CARGAJI, CGJForgejoPoster("archpkgs/meshcentral")]),
|
||||
# python3-snakes PIPY snakes 37 (packages/python3-snakes)
|
||||
PIPYReader(name = "python3-snakes", package = "snakes",
|
||||
target = GITLAB_SNAKES_CARGAJI),
|
||||
PIPYReader(name = "python3-snakes", package = "snakes",
|
||||
targets = GITLAB_SNAKES_CARGAJI),
|
||||
################################ Software that I package (Forgejo) ################################
|
||||
# pdfbooklet GHReleases Averell7/PdfBooklet archpkgs/pdfbooklet
|
||||
NCAppReader(app = "pdfbooklet", project = "Averell7/PdfBooklet"),
|
||||
# meshcentral GHReleases Ylianst/MeshCentral archpkgs/meshcentral
|
||||
GithubReader(name = "meshcentral", project = "Ylianst/MeshCentral",
|
||||
target = CGJForgejoPoster("archpkgs/meshcentral")),
|
||||
# nc-cospend GHReleases eneiluj/cospend-nc archpkgs/nextcloud-app-cospend
|
||||
NCAppReader(app = "nextcloud-app-cospend", project = "eneiluj/cospend-nc"),
|
||||
# nc-f_autotagging GHReleases
|
||||
|
|
@ -94,32 +113,41 @@ FEED_READERS = [
|
|||
NCAppReader(app = "nextcloud-app-forms", project = "nextcloud/forms"),
|
||||
# nc-maps GHReleases nextcloud/maps archpkgs/nextcloud-app-maps
|
||||
NCAppReader(app = "nextcloud-app-maps", project = "nextcloud/maps"),
|
||||
# nc-music GHReleases owncloud/music archpkgs/nextcloud-app-music
|
||||
NCAppReader(app = "nextcloud-app-music", project = "owncloud/music"),
|
||||
# nc-music GHReleases nc-music/music archpkgs/nextcloud-app-music
|
||||
NCAppReader(app = "nextcloud-app-music", project = "nc-music/music"),
|
||||
# nc-onlyoffice GHReleases ONLYOFFICE/onlyoffice-nextcloud archpkgs/nextcloud-app-onlyoffice
|
||||
NCAppReader(app = "nextcloud-app-onlyoffice", project = "ONLYOFFICE/onlyoffice-nextcloud"),
|
||||
# NCAppReader(app = "nextcloud-app-onlyoffice", project = "ONLYOFFICE/onlyoffice-nextcloud"),
|
||||
# nc-phonetrack GHReleases julien-nc/phonetrack archpkgs/nextcloud-app-phonetrack
|
||||
NCAppReader(app = "nextcloud-app-phonetrack", project = "julien-nc/phonetrack"),
|
||||
# nc-polls GHReleases nextcloud/polls archpkgs/nextcloud-app-polls
|
||||
NCAppReader(app = "nextcloud-app-polls", project = "nextcloud/polls"),
|
||||
# nc-socialsharing GHReleases nextcloud/socialsharing archpkgs/nextcloud-app-socialsharing
|
||||
NCAppReader(app = "nextcloud-app-socialsharing", project = "nextcloud/socialsharing"),
|
||||
# udsclient Custom --- archpkgs/udsclient
|
||||
UDSClientReader(target = CGJForgejoPoster(project="archpkgs/udsclient")),
|
||||
UDSClientReader(targets = CGJForgejoPoster(project="archpkgs/udsclient")),
|
||||
# vigil GHReleases valeriansaliou/vigil archpkgs/vigil
|
||||
NCAppReader(app = "vigil", project = "valeriansaliou/vigil"),
|
||||
# vigil-local GHReleases valeriansaliou/vigil-local archpkgs/vigil-local
|
||||
NCAppReader(app = "vigil-local", project = "valeriansaliou/vigil-local"),
|
||||
# yourls GHReleases YOURLS/YOURLS archpkgs/yourls
|
||||
NCAppReader(app = "yourls", project = "YOURLS/YOURLS"),
|
||||
|
||||
################################ Critical software in servers ################################
|
||||
# zfs
|
||||
GithubReader(name = "zfs-dkms", project = "openzfs/zfs",
|
||||
targets = CGJForgejoPoster("kauron/solaris-packages")),
|
||||
# yay GHReleases Jguer/yay aur?
|
||||
GithubReader(name = "yay", project = "Jguer/yay",
|
||||
targets = CGJForgejoPoster("kauron/solaris-packages")),
|
||||
# qbittorrent-alpine
|
||||
AlpinePackageReader(package = "qbittorrent",
|
||||
targets = CGJForgejoPoster("kauron/solaris-packages")),
|
||||
]
|
||||
|
||||
## PENDING:
|
||||
# Software that I use exposed to the Internet
|
||||
# Name FeedType Project
|
||||
# gad GHReleases brianreumere/gandi-automatic-dns aur?
|
||||
# nextcloud GHReleases nextcloud/server pacman?
|
||||
# peertube GHReleases Chocobozzz/PeerTube aur?
|
||||
# vaultwarden GHReleases dani-garcia/vaultwarden pacman?
|
||||
# wallabag GHReleases wallabag/wallabag pacman?
|
||||
# yay GHReleases Jguer/yay aur?
|
||||
# Others?
|
||||
# duplicati ???
|
||||
|
|
|
|||
|
|
@ -157,15 +157,19 @@ class ForgejoPoster(IssuePoster):
|
|||
class FeedReader:
|
||||
'''Class to read an RSS/Atom feed and post an issue if a new version is found.'''
|
||||
|
||||
def __init__(self, name: str, url: str, target: IssuePoster):
|
||||
def __init__(self, name: str, url: str, targets: list[IssuePoster]):
|
||||
'''Create a new feed reader'''
|
||||
self.name = name
|
||||
self.url = url
|
||||
self.target = target
|
||||
self.targets = targets if type(targets) == list else [targets]
|
||||
self.version_file = CONFIG_DIR + self.name
|
||||
self.etag_file = CONFIG_DIR + self.name + ".etag"
|
||||
self.beta_strings = [ "nightly", "beta", "alpha", "rc", "pr" ]
|
||||
|
||||
def is_valid_item(self, entry) -> bool:
|
||||
version = self.entry_get_version(entry)[0]
|
||||
return all([beta not in version for beta in self.beta_strings])
|
||||
|
||||
def first_item(self) -> dict[str, Any] | None | int:
|
||||
'''Get the first item of the feed (newest)'''
|
||||
if os.path.isfile(self.etag_file):
|
||||
|
|
@ -173,7 +177,7 @@ class FeedReader:
|
|||
etag = file.readline()
|
||||
else: etag = None
|
||||
feed = feedparser.parse(self.url, etag=etag)
|
||||
if feed.etag and feed.etag != etag:
|
||||
if feed.etag and feed.etag != etag and feed.status // 100 in [2, 3]:
|
||||
if not os.path.isdir(CONFIG_DIR):
|
||||
os.mkdir(CONFIG_DIR)
|
||||
with open(self.etag_file, mode='w', encoding="UTF-8") as file:
|
||||
|
|
@ -183,12 +187,7 @@ class FeedReader:
|
|||
if len(feed.entries) == 0:
|
||||
return None
|
||||
for entry in feed.entries:
|
||||
skip = False
|
||||
for beta in self.beta_strings:
|
||||
if beta in self.entry_get_version(entry)[0]:
|
||||
skip = True
|
||||
break
|
||||
if not skip:
|
||||
if self.is_valid_item(entry):
|
||||
return entry
|
||||
return None
|
||||
|
||||
|
|
@ -223,10 +222,14 @@ class FeedReader:
|
|||
if match:
|
||||
return False
|
||||
# Match 2: with repository issues
|
||||
if not self.target.issue_exists(self.name, version):
|
||||
# Post the issue
|
||||
if not self.target.post_issue(self.name, version, link):
|
||||
return False
|
||||
issues_posted = True
|
||||
for target in self.targets:
|
||||
if not target.issue_exists(self.name, version):
|
||||
# Post the issue
|
||||
if not target.post_issue(self.name, version, link):
|
||||
issues_posted = False
|
||||
if not issues_posted:
|
||||
return False
|
||||
# Save to disk
|
||||
if not os.path.isdir(CONFIG_DIR):
|
||||
os.makedirs(CONFIG_DIR)
|
||||
|
|
@ -238,9 +241,9 @@ class FeedReader:
|
|||
class PIPYReader(FeedReader):
|
||||
'''Reader specialized in the PIPY repository.'''
|
||||
|
||||
def __init__(self, name: str, package: str, target: IssuePoster):
|
||||
def __init__(self, name: str, package: str, targets: IssuePoster):
|
||||
'''Create a new PIPY reader for the given package.'''
|
||||
super().__init__(name, f"https://pypi.org/rss/project/{package}/releases.xml", target)
|
||||
super().__init__(name, f"https://pypi.org/rss/project/{package}/releases.xml", targets)
|
||||
|
||||
def entry_get_version(self, entry: dict[str, Any]) -> tuple[str, str]:
|
||||
return entry.title, entry.title
|
||||
|
|
@ -252,9 +255,9 @@ class PIPYReader(FeedReader):
|
|||
class GithubTagReader(FeedReader):
|
||||
'''Reader specialized in GitHub Tags Atom feed.'''
|
||||
|
||||
def __init__(self, name: str, project: str, target: IssuePoster):
|
||||
def __init__(self, name: str, project: str, targets: IssuePoster):
|
||||
'''Create a new GitHub Tags reader for the given project.'''
|
||||
super().__init__(name, f"https://github.com/{project}/tags.atom", target)
|
||||
super().__init__(name, f"https://github.com/{project}/tags.atom", targets)
|
||||
|
||||
def entry_get_version(self, entry: dict[str, Any]) -> tuple[str, str]:
|
||||
return entry.title, str(entry.id)
|
||||
|
|
@ -266,8 +269,8 @@ class GithubTagReader(FeedReader):
|
|||
class GithubReader(GithubTagReader):
|
||||
'''Reader specialized in GitHub releases' Atom feed.'''
|
||||
|
||||
def __init__(self, name: str, project: str, target: IssuePoster):
|
||||
super().__init__(name, project, target)
|
||||
def __init__(self, name: str, project: str, targets: IssuePoster):
|
||||
super().__init__(name, project, targets)
|
||||
self.url = f"https://github.com/{project}/releases.atom"
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue