Browse Source

Version 0.2.0

* add gitlab support
* add arg to choose between github RSS and API usage
main 0.2.0
parent
commit
1bdef6c2d6
No known key found for this signature in database GPG Key ID: 26B14D36EB0D3C8E
4 changed files with 216 additions and 90 deletions
  1. +1
    -1
      pyproject.toml
  2. +19
    -0
      src/pkgupdates/__main__.py
  3. +181
    -89
      src/pkgupdates/remote.py
  4. +15
    -0
      src/pkgupdates/settings.py

+ 1
- 1
pyproject.toml View File

@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "pkgupdates" name = "pkgupdates"
description = "Tool to check ebuild pavkages for updates." description = "Tool to check ebuild pavkages for updates."
version = "0.1.0"
version = "0.2.0"
license = "GPL-3.0-or-later" license = "GPL-3.0-or-later"
readme = "README.md" readme = "README.md"
requires-python = "~=3.10" requires-python = "~=3.10"


+ 19
- 0
src/pkgupdates/__main__.py View File

@ -1,10 +1,29 @@
"""Main Module""" """Main Module"""
import argparse
from .package import get_packages, check_package from .package import get_packages, check_package
from .settings import set_gh_rss_get
def process_arguments():
"""Process Arguments"""
parser = argparse.ArgumentParser(
description='Check for Gentoo overlay package updates'
)
parser.add_argument('--github-rss-get',
type=bool,
default=False,
required=False,
help='Get updates for Github over RSS instead of API')
args = parser.parse_args()
set_gh_rss_get(args.github_rss_get)
def main(): def main():
"""Main Function""" """Main Function"""
process_arguments()
pkgs = get_packages() pkgs = get_packages()
for pkg, meta in pkgs.items(): for pkg, meta in pkgs.items():
check_package(pkg, meta) check_package(pkg, meta)


+ 181
- 89
src/pkgupdates/remote.py View File

@ -5,7 +5,9 @@ import re
from enum import Enum from enum import Enum
from xml.dom import minidom from xml.dom import minidom
import requests import requests
from github import GithubException, Github as GithubApi
from .version import rex_semantic from .version import rex_semantic
from .settings import get_gh_rss_get
class ERemote(Enum): class ERemote(Enum):
@ -230,36 +232,25 @@ class Ctan(Remote):
NAME = "ctan" NAME = "ctan"
# TODO: get_latest_commit
# TODO: get_latest_release
class FreedesktopGitlab(Remote):
"""Remote class for gitlab.freedesktop.org hosted projects
Gitlab instance of the FreeDesktop project"""
TYPE = ERemote.FREEDESKTOP_GITLAB
NAME = "freedesktop-gitlab"
# TODO: get_latest_commit
# TODO: get_latest_release
class Gentoo(Remote):
"""Remote class for gitweb.gentoo.org hosted projects
Repository for the Gentoo project"""
TYPE = ERemote.GENTOO
NAME = "gentoo"
class Github(Remote): class Github(Remote):
"""Remote class for github.com hosted projects""" """Remote class for github.com hosted projects"""
TYPE = ERemote.GITHUB TYPE = ERemote.GITHUB
NAME = "github" NAME = "github"
API = GithubApi()
GITHUB_ID_REX = re.compile("/([0-9a-zA-Z._-]+)$") GITHUB_ID_REX = re.compile("/([0-9a-zA-Z._-]+)$")
@classmethod
def split_user_repo(cls, pkg_repo):
"""Split "user/repo" into "username", "reponame"
Returns two values"""
if isinstance(pkg_repo, str):
elements = pkg_repo.split("/")
return elements[0], elements[1]
return '', ''
@classmethod @classmethod
def get_latest_release(cls, pkg_repo): def get_latest_release(cls, pkg_repo):
"""Get latest release name from either latest release tag or tag""" """Get latest release name from either latest release tag or tag"""
@ -278,16 +269,26 @@ class Github(Remote):
Why? Because github requires an API key for API calls. Why? Because github requires an API key for API calls.
""" """
url = "https://github.com/" + pkg_repo + "/releases.atom"
try:
with urllib.request.urlopen(url) as req:
feed = req.read()
except urllib.request.HTTPError:
return ""
dom = minidom.parseString(feed)
entries = dom.getElementsByTagName("entry")
titles = entries[0].getElementsByTagName("title")
version = titles[0].firstChild.nodeValue
if get_gh_rss_get():
print("Get RSS\n")
url = "https://github.com/" + pkg_repo + "/releases.atom"
try:
with urllib.request.urlopen(url) as req:
feed = req.read()
except urllib.request.HTTPError:
return ""
dom = minidom.parseString(feed)
entries = dom.getElementsByTagName("entry")
titles = entries[0].getElementsByTagName("title")
version = titles[0].firstChild.nodeValue
else:
print("Get API\n")
user, repo = cls.split_user_repo(pkg_repo)
try:
repo = cls.API.get_user(user).get_repo(repo)
version = repo.get_latest_release().title
except GithubException:
return ""
return version return version
@ -299,24 +300,33 @@ class Github(Remote):
Why? Because github requires an API key for API calls. Why? Because github requires an API key for API calls.
""" """
url = "https://github.com/" + pkg_repo + "/releases.atom"
try:
with urllib.request.urlopen(url) as req:
feed = req.read()
except urllib.request.HTTPError:
return ""
dom = minidom.parseString(feed)
nodelist = dom.getElementsByTagName("entry")
if len(nodelist) > 0:
nodelist = nodelist[0].getElementsByTagName("id")
else:
return ""
id_str = nodelist[0].firstChild.nodeValue
result = cls.GITHUB_ID_REX.search(id_str)
if result is not None:
version = result.groups()[0]
if get_gh_rss_get():
url = "https://github.com/" + pkg_repo + "/releases.atom"
try:
with urllib.request.urlopen(url) as req:
feed = req.read()
except urllib.request.HTTPError:
return ""
dom = minidom.parseString(feed)
nodelist = dom.getElementsByTagName("entry")
if len(nodelist) > 0:
nodelist = nodelist[0].getElementsByTagName("id")
else:
return ""
id_str = nodelist[0].firstChild.nodeValue
result = cls.GITHUB_ID_REX.search(id_str)
if result is not None:
version = result.groups()[0]
else:
version = ""
else: else:
version = ""
user, repo = cls.split_user_repo(pkg_repo)
try:
repo = cls.API.get_user(user).get_repo(repo)
version = repo.get_latest_release().tag_name
except GithubException:
return ""
return version return version
@ -327,15 +337,25 @@ class Github(Remote):
Uses the RSS feed. See above why. Uses the RSS feed. See above why.
""" """
url = "https://github.com/" + pkg_repo + "/commits.atom"
try:
with urllib.request.urlopen(url) as req:
feed = req.read()
except urllib.request.HTTPError:
return "HTTPError"
dom = minidom.parseString(feed)
nodelist = dom.getElementsByTagName("updated")
version = nodelist[0].firstChild.nodeValue
if get_gh_rss_get():
url = "https://github.com/" + pkg_repo + "/commits.atom"
try:
with urllib.request.urlopen(url) as req:
feed = req.read()
except urllib.request.HTTPError:
return "HTTPError"
dom = minidom.parseString(feed)
nodelist = dom.getElementsByTagName("updated")
version = nodelist[0].firstChild.nodeValue
else:
user, repo = cls.split_user_repo(pkg_repo)
try:
repo = cls.API.get_user(user).get_repo(repo)
branch = repo.get_branch(repo.default_branch)
version = branch.commit.commit.timestamp
except GithubException:
return ""
return version return version
@ -346,30 +366,42 @@ class Github(Remote):
Uses the RSS feed. See above why. Uses the RSS feed. See above why.
""" """
url = "https://github.com/" + pkg_repo + "/tags.atom"
try:
with urllib.request.urlopen(url) as req:
feed = req.read()
except urllib.request.HTTPError:
return ""
dom = minidom.parseString(feed)
nodelist = dom.getElementsByTagName("entry")
if len(nodelist) > 0:
nodelist = nodelist[0].getElementsByTagName("id")
else:
return ""
id_str = nodelist[0].firstChild.nodeValue
result = cls.GITHUB_ID_REX.search(id_str)
if result is not None:
version = result.groups()[0]
if get_gh_rss_get():
url = "https://github.com/" + pkg_repo + "/tags.atom"
try:
with urllib.request.urlopen(url) as req:
feed = req.read()
except urllib.request.HTTPError:
return ""
dom = minidom.parseString(feed)
nodelist = dom.getElementsByTagName("entry")
if len(nodelist) > 0:
nodelist = nodelist[0].getElementsByTagName("id")
else:
return ""
id_str = nodelist[0].firstChild.nodeValue
result = cls.GITHUB_ID_REX.search(id_str)
if result is not None:
version = result.groups()[0]
else:
version = ""
else: else:
version = ""
user, repo = cls.split_user_repo(pkg_repo)
try:
repo = cls.API.get_user(user).get_repo(repo)
tags = repo.get_tags()
if tags.totalCount > 0:
version = tags[0].commit.commit.timestamp
else:
return ""
except GithubException:
print(f"{pkg_repo}: API request failed")
return ""
return version return version
# TODO: get_latest_commit
# TODO: get_latest_release
class Gitlab(Remote): class Gitlab(Remote):
"""Remote class for gitlab.com hosted projects """Remote class for gitlab.com hosted projects
@ -377,17 +409,76 @@ class Gitlab(Remote):
TYPE = ERemote.GITLAB TYPE = ERemote.GITLAB
NAME = "gitlab" NAME = "gitlab"
URL = "https://gitlab.com/api/v4"
@classmethod
def get_latest_release(cls, pkg_repo):
ident = pkg_repo.replace("/", "%2F")
url = cls.URL + "/projects/" + ident + "/repository/tags"
version = ""
try:
with requests.get(url, timeout=5) as resp:
data = resp.json()
version = data[0]["name"]
except requests.HTTPError:
return ""
return version
@classmethod
def get_latest_commit(cls, pkg_repo):
ident = pkg_repo.replace("/", "%2F")
url = cls.URL + "/projects/" + ident + "/repository/commits"
version = ""
try:
with requests.get(url, timeout=5) as resp:
data = resp.json()
version = data[0]["created_at"]
except requests.HTTPError:
return ""
return version
class FreedesktopGitlab(Gitlab):
"""Remote class for gitlab.freedesktop.org hosted projects
Gitlab instance of the FreeDesktop project"""
TYPE = ERemote.FREEDESKTOP_GITLAB
NAME = "freedesktop-gitlab"
URL = "https://gitlab.freedesktop.org/api/v4"
# TODO: get_latest_commit # TODO: get_latest_commit
# TODO: get_latest_release # TODO: get_latest_release
class GnomeGitlab(Remote):
class Gentoo(Remote):
"""Remote class for gitweb.gentoo.org hosted projects
Repository for the Gentoo project"""
TYPE = ERemote.GENTOO
NAME = "gentoo"
class GnomeGitlab(Gitlab):
"""Remote class for gitlab.gnome.org hosted projects """Remote class for gitlab.gnome.org hosted projects
Gitlab instance of the GNOME project""" Gitlab instance of the GNOME project"""
TYPE = ERemote.GNOME_GITLAB TYPE = ERemote.GNOME_GITLAB
NAME = "gnome-gitlab" NAME = "gnome-gitlab"
URL = "https://gitlab.gnome.org/api/v4"
class KdeInvent(Gitlab):
"""Remote for invent.kde.org hosted projects
Gitlab instance of the KDE project"""
TYPE = ERemote.KDE_INVENT
NAME = "kde-invent"
URL = "https://invent.kde.org/api/v4"
# TODO: get_latest_commit # TODO: get_latest_commit
@ -421,17 +512,6 @@ class Heptapod(Remote):
NAME = "heptapod" NAME = "heptapod"
# TODO: get_latest_commit
# TODO: get_latest_release
class KdeInvent(Remote):
"""Remote for invent.kde.org hosted projects
Gitlab instance of the KDE project"""
TYPE = ERemote.KDE_INVENT
NAME = "kde-invent"
# TODO: get_latest_commit # TODO: get_latest_commit
# TODO: get_latest_release # TODO: get_latest_release
class Launchpad(Remote): class Launchpad(Remote):
@ -556,6 +636,18 @@ class Sourcehut(Remote):
TYPE = ERemote.SOURCEHUT TYPE = ERemote.SOURCEHUT
NAME = "sourcehut" NAME = "sourcehut"
# @classmethod
# def get_latest_commit(cls, pkg_repo):
# url = "https://git.sr.ht/api/"
# body = """
# query repositoryByDiskPath {
# }
# """
# try:
# with requests.get(url, json={"query": body}, timeout=5) as resp:
# data = resp.json()
# version = data[0]["created_at"]
# TODO: get_latest_commit # TODO: get_latest_commit
# TODO: get_latest_release # TODO: get_latest_release


+ 15
- 0
src/pkgupdates/settings.py View File

@ -0,0 +1,15 @@
"""Module Settings"""
GITHUB_RSS_GET = False
def get_gh_rss_get():
"""GITHUB_RSS_GET getter"""
return GITHUB_RSS_GET
def set_gh_rss_get(v):
"""GITHUB_RSS_GET setter"""
global GITHUB_RSS_GET
GITHUB_RSS_GET = v
return GITHUB_RSS_GET

Loading…
Cancel
Save