New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show changelog from PPA packages - issue #56 #128

Merged
merged 11 commits into from Apr 19, 2016
@@ -83,6 +83,8 @@
update_origin = "ubuntu"
elif origin.origin == "Debian":
update_origin = "debian"
elif origin.origin.startswith("LP-PPA"):
update_origin = origin.origin
if origin.origin == "Ubuntu" and '-security' in origin.archive:
update_type = "security"
break
@@ -14,6 +14,8 @@
import time
import gettext
import fnmatch
import io
import tarfile
import urllib2
import re
from sets import Set
@@ -152,11 +154,95 @@ def __init__(self, package_update, wTree):
if ":" in self.version:
self.version = self.version.split(":")[-1]

def get_ppa_info(self):
ppa_sources_file = "/etc/apt/sources.list"
ppa_sources_dir = "/etc/apt/sources.list.d/"
ppa_words = self.origin.lstrip("LP-PPA-").split("-")

source = ppa_sources_file
if os.path.exists(ppa_sources_dir):
for filename in os.listdir(ppa_sources_dir):
if filename.startswith(self.origin.lstrip("LP-PPA-")):
source = os.path.join(ppa_sources_dir, filename)
break
if not os.path.exists(source):
return None, None
try:
with open(source) as f:
for line in f:
if (not line.startswith("#") and all(word in line for word in ppa_words)):
ppa_info = line.split("ppa.launchpad.net/")[1]
break
else:
return None, None
except EnvironmentError, e:
print "Error encountered while trying to get PPA owner and name: %s" % e
return None, None
ppa_owner, ppa_name, ppa_x = ppa_info.split("/", 2)
return ppa_owner, ppa_name

def get_ppa_changelog(self, ppa_owner, ppa_name):
max_tarball_size = 1000000
print "\nFetching changelog for PPA package %s/%s/%s ..." % (ppa_owner, ppa_name, self.source_package)
if self.source_package.startswith("lib"):
ppa_abbr = self.source_package[:4]
else:
ppa_abbr = self.source_package[0]
deb_dsc_uri = "http://ppa.launchpad.net/%s/%s/ubuntu/pool/main/%s/%s/%s_%s.dsc" % (ppa_owner, ppa_name, ppa_abbr, self.source_package, self.source_package, self.version)
try:
deb_dsc = urllib2.urlopen(deb_dsc_uri).readlines()
except urllib2.URLError, e:
print "Could not open Launchpad URL %s - %s" % (deb_dsc_uri, e)
return
for line in deb_dsc:
if "debian.tar" not in line:
continue
tarball_line = line.strip().split(" ", 2)
if len(tarball_line) == 3:
deb_checksum, deb_size, deb_filename = tarball_line
break
else:
deb_filename = None
if not deb_filename or not deb_size or not deb_size.isdigit():
print "Unsupported debian .dsc file format. Skipping this package."
return
if (int(deb_size) > max_tarball_size):
print "Tarball size %s B exceeds maximum download size %d B. Skipping download." % (deb_size, max_tarball_size)
return
deb_file_uri = "http://ppa.launchpad.net/%s/%s/ubuntu/pool/main/%s/%s/%s" % (ppa_owner, ppa_name, ppa_abbr, self.source_package, deb_filename)
try:
deb_file = urllib2.urlopen(deb_file_uri).read()
except urllib2.URLError, e:
print "Could not download tarball from %s - %s" % (deb_file_uri, e)
return
if deb_filename.endswith(".xz"):
cmd = ["xz", "--decompress"]
try:
xz = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
xz.stdin.write(deb_file)
xz.stdin.close()
deb_file = xz.stdout.read()
xz.stdout.close()
except EnvironmentError, e:
print "Error encountered while decompressing xz file: %s" % e
return
deb_file = io.BytesIO(deb_file)
try:
with tarfile.open(fileobj = deb_file) as f:
deb_changelog = f.extractfile("debian/changelog").read()
except tarfile.TarError, e:
print "Error encountered while reading tarball: %s" % e
return

return deb_changelog

def run(self):
gtk.gdk.threads_enter()
self.wTree.get_widget("textview_changes").get_buffer().set_text(_("Downloading changelog..."))
gtk.gdk.threads_leave()

changelog = _("No changelog available")

changelog_sources = []
if self.origin == "linuxmint":
changelog_sources.append("http://packages.linuxmint.com/dev/" + self.source_package + "_" + self.version + "_amd64.changes")
@@ -181,8 +267,16 @@ def run(self):
changelog_sources.append("http://metadata.ftp-master.debian.org/changelogs/main/%s/%s/%s_%s_changelog" % (self.source_package[0], self.source_package, self.source_package, self.version))
changelog_sources.append("http://metadata.ftp-master.debian.org/changelogs/contrib/%s/%s/%s_%s_changelog" % (self.source_package[0], self.source_package, self.source_package, self.version))
changelog_sources.append("http://metadata.ftp-master.debian.org/changelogs/non-free/%s/%s/%s_%s_changelog" % (self.source_package[0], self.source_package, self.source_package, self.version))

changelog = _("No changelog available")
elif self.origin.startswith("LP-PPA"):
ppa_owner, ppa_name = self.get_ppa_info()
if ppa_owner and ppa_name:
deb_changelog = self.get_ppa_changelog(ppa_owner, ppa_name)
if not deb_changelog:
changelog_sources.append("https://launchpad.net/~%s/+archive/ubuntu/%s/+files/%s_%s_source.changes" % (ppa_owner, ppa_name, self.source_package, self.version))
else:
changelog = "--- PPA Changelog ---\n\n%s\n" % deb_changelog
else:
print "PPA owner or name could not be determined"

if self.ps == {}:
# use default urllib2 proxy mechanisms (possibly *_proxy environment vars)
@@ -210,6 +304,9 @@ def run(self):
change = ""
if change == "" or stripped_change.startswith("*") or stripped_change.startswith("["):
changelog = changelog + change + "\n"
elif "launchpad.net" in changelog_source:
lpchange = source.split("Changes:")[1].split("Checksums")[0]
changelog = "--- PPA Changelog Latest Entry ---\n%s\n" % lpchange
else:
changelog = source
break
ProTip! Use n and p to navigate between commits in a pull request.