aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuido Günther <agx@sigxcpu.org>2022-10-25 10:37:01 +0200
committerGuido Günther <agx@sigxcpu.org>2022-10-25 11:45:42 +0200
commit7772d34fb24578662dd23e3b82b7d1faac2d2dc5 (patch)
treec3a39e2423fb7a7f6941b21f8a541b8ee8e6994e
parent741072c5dfa6f74fe834886b42fd1801c66bbd10 (diff)
Update to python3HEADv0.0.5master
While at that split out handle_pkg. This makes things easy to test locally via > import cl2vcs > cl2vcs.handle_pkg('multipath-tools', title='bla')
-rw-r--r--Makefile4
-rw-r--r--README6
-rw-r--r--cl2vcs.py153
-rw-r--r--htmlchangelog.py9
-rwxr-xr-xindex.cgi133
-rw-r--r--templates/index.html2
-rw-r--r--vcsbrowsers.py1
7 files changed, 171 insertions, 137 deletions
diff --git a/Makefile b/Makefile
index ee037e7..b8d8d9e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
-VERSION=$(shell grep ^VERSION index.cgi | sed -e s'/.*\="\([0-9.]\+\)".*/\1/')
+VERSION=$(shell grep ^VERSION cl2vcs.py | sed -e s'/.*\="\([0-9.]\+\)".*/\1/')
PKG=cl2vcs
all:
- nosetests --with-doctest
+ nosetests3 --with-doctest
clean:
rm -f *.pyc
diff --git a/README b/README
index 9963a36..16ebdc6 100644
--- a/README
+++ b/README
@@ -2,4 +2,8 @@ For more information see:
https://honk.sigxcpu.org/piki/projects/cl2vcs/
-Depends: python-lxml, python-urlgrabber, python-genshi, python-debian (>=0.1.11)
+To test locally try
+
+ python3 -c "import cl2vcs; cl2vcs.handle_pkg('multipath-tools', title='bla')" > out.html
+
+Depends: python3-lxml, python3-urlgrabber, python3-genshi, python3-debian
diff --git a/cl2vcs.py b/cl2vcs.py
new file mode 100644
index 0000000..be58145
--- /dev/null
+++ b/cl2vcs.py
@@ -0,0 +1,153 @@
+#!/usr/bin/python3 -u
+# vim: set fileencoding=utf-8 :
+#
+# (C) 2008,2015,2022 Guido Guenther <agx@sigxcpu.org>
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+"""Link Debian changelog entries to the VCS"""
+
+from builtins import str
+import cgi
+import os
+import re
+import sys
+import requests
+from lxml import etree
+from genshi.template import TemplateLoader
+import vcsbrowsers
+from htmlchangelog import HTMLChangelog
+from io import BytesIO
+
+VERSION="0.0.5"
+XMLNS='http://www.w3.org/1999/xhtml'
+PTS='http://packages.qa.debian.org'
+PKGNAMERE="[a-zA-Z0-9.+\-]+$"
+TITLE = "cl2vcs %s" % VERSION
+
+
+def fetch_changelog(cl_url):
+ resp = requests.get(cl_url, timeout=5.0)
+ resp.raise_for_status()
+ return resp.content
+
+
+def fetch_pts_page(package):
+ pts = None
+ url = "%s/%s" % (PTS, package)
+ resp = requests.get(url, timeout=5.0)
+ if resp.status_code == 404:
+ raise Exception("Can't find package '%s' on '%s'" % (package, PTS))
+ resp.raise_for_status()
+ return resp.content
+
+
+def parse_pts_xhtml(pts):
+ cl_url = None
+ vcs_url = None
+ vcs = None
+
+ tree = etree.parse(BytesIO(pts))
+ searcher = etree.ETXPath('/{%s}html/{%s}body//{%s}a[@href]' % (XMLNS, XMLNS, XMLNS))
+ result = searcher(tree)
+
+ for r in result:
+ if not r.text:
+ continue
+ if r.text.lower() == "changelog":
+ cl_url = r.attrib['href']
+ elif r.text.lower() == "browse":
+ vcs_url = r.attrib['href']
+ parent = r.getparent()
+ vcs = parent.getchildren()[0].text.lower()
+ return cl_url, vcs_url, vcs
+
+
+def get_vcsbrowser(vcs, vcs_url):
+ if vcs == "git":
+ return vcsbrowsers.guess_git_repo(vcs_url)
+ elif vcs == "Mercurial":
+ return vcsbrowsers.HgBrowser(vcs_url)
+
+
+def render_search_page(title, pkg=None, err=None):
+ loader = TemplateLoader('templates')
+ tmpl = loader.load('index.html', encoding='utf-8')
+ t = tmpl.generate(title=title, pkg=pkg, err=err)
+ print(t.render('xhtml', doctype='xhtml-strict'))
+
+
+
+def render_changelog_page(cl):
+ print(cl)
+
+
+def handle_pkg(pkg, title):
+ if pkg:
+ if not re.match(PKGNAMERE, pkg):
+ return render_search_page(title=title, err=u"Invalid package name: '%s'" % pkg)
+ else:
+ pkg = str(pkg)
+ else:
+ return render_search_page(title=title, err="")
+
+ try:
+ pts = fetch_pts_page(pkg)
+ except Exception as exc_err:
+ err = exc_err
+ pts = None
+
+ if not pts:
+ return render_search_page(title=title, pkg=pkg, err=err)
+
+ cl_url, vcs_url, vcs = parse_pts_xhtml(pts)
+ if cl_url == None:
+ return render_search_page(title=title, pkg=pkg,
+ err="Cannot parse changelog from PTS page.")
+ try:
+ cl_text = fetch_changelog(cl_url)
+ except urlgrabber.grabber.URLGrabError as e:
+ (errcode, errmsg) = e.args
+ return render_search_page(title=title,
+ err="Cannot fetch '%s': %s" % (cl_url, errmsg))
+ if vcs and vcs_url:
+ vcsbrowser = get_vcsbrowser(vcs, vcs_url)
+ else:
+ vcsbrowser = None
+ cl = HTMLChangelog(cl_text, vcsbrowser=vcsbrowser)
+ if cl:
+ render_changelog_page(cl)
+
+
+def main(argv):
+ err = ""
+
+ print("Content-Type: text/html; charset=utf-8")
+ print()
+
+ try:
+ form = cgi.FieldStorage()
+
+ if 'pkg' in form:
+ pkg = form.getfirst('pkg').strip()
+ else:
+ pkg = None
+
+ handle_pkg(pkg, TITLE)
+ except Exception as err:
+ import traceback
+ traceback.print_exc(file=sys.stderr)
+ render_search_page(title=TITLE, err="Unknown error")
+ return 0
+
diff --git a/htmlchangelog.py b/htmlchangelog.py
index 9dddcff..bc667db 100644
--- a/htmlchangelog.py
+++ b/htmlchangelog.py
@@ -1,7 +1,8 @@
# vim: set fileencoding=utf-8 :
+from builtins import object
import re
-import cgi
+import html
from genshi.template import TemplateLoader
import debian.changelog
@@ -22,7 +23,7 @@ class HTMLChangelogFilter(object):
def vcs_commit_filter(self, changes):
body = []
for line in changes:
- line = cgi.escape(line)
+ line = html.escape(line)
for regex in self.commit_id_res:
m = regex.match(line)
if m:
@@ -38,7 +39,7 @@ class HTMLChangelogFilter(object):
if self.vcsbrowser:
block.body = self.vcs_commit_filter(block.changes())
else:
- block.body = cgi.escape("\n".join(block.changes()))
+ block.body = html.escape("\n".join(block.changes()))
return block
@@ -61,5 +62,5 @@ class HTMLChangelog(debian.changelog.Changelog):
return self.html_tmpl.generate(title=title, blocks=self._blocks, markup_block=self.markup_block)
def __str__(self):
- return self.stream().render('xhtml', doctype='xhtml-strict').encode('utf-8')
+ return self.stream().render('xhtml', doctype='xhtml-strict')
diff --git a/index.cgi b/index.cgi
index 5af08fd..3ab09c4 100755
--- a/index.cgi
+++ b/index.cgi
@@ -1,7 +1,7 @@
-#!/usr/bin/python -u
+#!/usr/bin/python3 -u
# vim: set fileencoding=utf-8 :
#
-# (C) 2008,2015 Guido Guenther <agx@sigxcpu.org>
+# (C) 2008,2015,2022 Guido Guenther <agx@sigxcpu.org>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
@@ -18,134 +18,9 @@
#
"""Link Debian changelog entries to the VCS"""
-import cgi
-import os
-import re
import sys
-import urlgrabber
-from lxml import etree
-from genshi.template import TemplateLoader
-import vcsbrowsers
-from htmlchangelog import HTMLChangelog
-
-VERSION="0.0.4"
-XMLNS='http://www.w3.org/1999/xhtml'
-PTS='http://packages.qa.debian.org'
-PKGNAMERE="[a-zA-Z0-9.+\-]+$"
-
-
-def fetch_changelog(cl_url):
- changelog = urlgrabber.urlread(cl_url, timeout=5.0).decode('utf-8')
- return changelog
-
-
-def fetch_pts_page(package):
- pts = None
- try:
- url = "%s/%s" % (PTS, package)
- pts = urlgrabber.urlopen(url, timeout=5.0)
- except urlgrabber.grabber.URLGrabError as (code, msg):
- if code == 14:
- raise Exception, "Can't find package '%s' on '%s'" % (package, PTS)
- else:
- raise
- return pts
-
-
-def parse_pts_xhtml(pts):
- cl_url = None
- vcs_url = None
- vcs = None
-
- tree = etree.parse(pts)
- searcher = etree.ETXPath('/{%s}html/{%s}body//{%s}a[@href]' % (XMLNS, XMLNS, XMLNS))
- result = searcher(tree)
-
- for r in result:
- if not r.text:
- continue
- if r.text.lower() == "changelog":
- cl_url = r.attrib['href']
- elif r.text.lower() == "browse":
- vcs_url = r.attrib['href']
- parent = r.getparent()
- vcs = parent.getchildren()[0].text.lower()
- return cl_url, vcs_url, vcs
-
-
-def get_vcsbrowser(vcs, vcs_url):
- if vcs == "git":
- return vcsbrowsers.guess_git_repo(vcs_url)
- elif vcs == "Mercurial":
- return vcsbrowsers.HgBrowser(vcs_url)
-
-
-def render_search_page(title, pkg=None, err=None):
- loader = TemplateLoader('templates')
- tmpl = loader.load('index.html', encoding='utf-8')
- t = tmpl.generate(title=title, pkg=pkg, err=err)
- print t.render('xhtml', doctype='xhtml-strict').encode('utf-8')
-
-
-
-def render_changelog_page(cl):
- print cl
-
-
-def main(argv):
- title = "cl2vcs %s" % VERSION
- err = ""
-
- print "Content-Type: text/html; charset=utf-8"
- print
-
- try:
- form = cgi.FieldStorage()
-
- if form.has_key('pkg'):
- pkg = form.getfirst('pkg').decode('utf-8').strip()
- else:
- pkg = None
-
- if pkg:
- if not re.match(PKGNAMERE, pkg):
- return render_search_page(title=title, err=u"Invalid package name: '%s'" % pkg)
- else:
- pkg = str(pkg)
- else:
- return render_search_page(title=title, err=err)
-
- try:
- pts = fetch_pts_page(pkg)
- except Exception as exc_err:
- err = exc_err
- pts = None
-
- if not pts:
- return render_search_page(title=title, pkg=pkg, err=err)
-
- cl_url, vcs_url, vcs = parse_pts_xhtml(pts)
- if cl_url == None:
- return render_search_page(title=title, pkg=pkg,
- err="Cannot parse changelog from PTS page.")
- try:
- cl_text = fetch_changelog(cl_url)
- except urlgrabber.grabber.URLGrabError, (errcode, errmsg):
- return render_search_page(title=title,
- err="Cannot fetch '%s': %s" % (cl_url, errmsg))
- if vcs and vcs_url:
- vcsbrowser = get_vcsbrowser(vcs, vcs_url)
- else:
- vcsbrowser = None
- cl = HTMLChangelog(cl_text, vcsbrowser=vcsbrowser)
- if cl:
- render_changelog_page(cl)
- except Exception, err:
- import traceback
- traceback.print_exc(file=sys.stderr)
- render_search_page(title=title, err="Unknown error")
- return 0
+import cl2vcs
if __name__ == "__main__":
- sys.exit(main(sys.argv))
+ sys.exit(cl2vcs.main(sys.argv))
diff --git a/templates/index.html b/templates/index.html
index b8cd84c..b792778 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -27,7 +27,7 @@
<div id="footer">
<hr />
- <p>© 2008,2009,2015 Guido Günther <a href="mailto:agx@sigxcpu.org">&lt;agx@sigxcpu.org&gt;</a></p>
+ <p>© 2008,2009,2015,2022 Guido Günther <a href="mailto:agx@sigxcpu.org">&lt;agx@sigxcpu.org&gt;</a></p>
</div>
</body>
</html>
diff --git a/vcsbrowsers.py b/vcsbrowsers.py
index 2e082a6..409c1dc 100644
--- a/vcsbrowsers.py
+++ b/vcsbrowsers.py
@@ -1,6 +1,7 @@
# convenience wrappers to construct links
# into the webinterfaces of different VCSs
+from builtins import object
import re