Commit 24545cce authored by Enrico Zini's avatar Enrico Zini

ported to python3

parent b99aa350
#!/usr/bin/python #!/usr/bin/python3
# TODO: # TODO:
# - Filter packages by tags (not just role::program) # - Filter packages by tags (not just role::program)
...@@ -13,13 +13,14 @@ import apt ...@@ -13,13 +13,14 @@ import apt
import sys import sys
from debian import debtags from debian import debtags
from optparse import OptionParser from optparse import OptionParser
from cStringIO import StringIO import io
import xdg.BaseDirectory import xdg.BaseDirectory
import urllib2 import urllib.request
import logging import logging
log = logging.getLogger("horoscope") log = logging.getLogger("horoscope")
def get_by_inst(): def get_by_inst():
""" """
Acquire, cache and parse the by_inst file Acquire, cache and parse the by_inst file
...@@ -34,23 +35,26 @@ def get_by_inst(): ...@@ -34,23 +35,26 @@ def get_by_inst():
url = "http://popcon.debian.org/by_inst.gz" url = "http://popcon.debian.org/by_inst.gz"
log.info("Downloading %s...", url) log.info("Downloading %s...", url)
try: try:
fd = urllib2.urlopen(url) fd = urllib.request.urlopen(url)
data = fd.read() data = fd.read()
finally: finally:
fd.close() fd.close()
with open(by_inst, "wb") as fd: with open(by_inst, "wb") as fd:
fd.write(data) fd.write(data)
zfd = StringIO(data) zfd = io.BytesIO(data)
with gzip.GzipFile(None, "rb", fileobj=zfd) as fd: with gzip.open(zfd, "rt") as fd:
for line in fd: for line in fd:
if line[0] in "#-": continue if line[0] in "#-":
continue
fields = line.split() fields = line.split()
if fields[1] == "Total": continue if fields[1] == "Total":
continue
inst = float(fields[2]) inst = float(fields[2])
pkg = fields[1] pkg = fields[1]
yield pkg, inst yield pkg, inst
def get_tags(): def get_tags():
""" """
Get the Debtags database Get the Debtags database
...@@ -60,10 +64,11 @@ def get_tags(): ...@@ -60,10 +64,11 @@ def get_tags():
sys.exit(2) sys.exit(2)
db = debtags.DB() db = debtags.DB()
with open('/var/lib/debtags/package-tags', "rb") as fd: with open('/var/lib/debtags/package-tags', "rt") as fd:
db.read(fd) db.read(fd)
return db return db
def parse_vote(fd): def parse_vote(fd):
""" """
Parse a popcon vote file, generating the names of the valid packages in Parse a popcon vote file, generating the names of the valid packages in
...@@ -91,6 +96,7 @@ def parse_vote(fd): ...@@ -91,6 +96,7 @@ def parse_vote(fd):
# Recently installed packages # Recently installed packages
yield data[2], 0.8 yield data[2], 0.8
def get_popcon(): def get_popcon():
if not os.path.exists('/var/log/popularity-contest'): if not os.path.exists('/var/log/popularity-contest'):
sys.stderr.write("Sorry, /var/log/popularity-contest does not exist: you need to participate in the popularity contest to use this command") sys.stderr.write("Sorry, /var/log/popularity-contest does not exist: you need to participate in the popularity contest to use this command")
...@@ -117,23 +123,29 @@ class Horoscope(object): ...@@ -117,23 +123,29 @@ class Horoscope(object):
db = get_tags() db = get_tags()
#if (opts.tagoutput): # if (opts.tagoutput):
# # TODO do stuff # # TODO do stuff
# pass # pass
for pkg, tf in get_popcon(): for pkg, tf in get_popcon():
if not pkg in apt_cache: continue if pkg not in apt_cache:
continue
aptpkg = apt_cache[pkg] aptpkg = apt_cache[pkg]
if not aptpkg.installed: continue if not aptpkg.installed:
continue
if 'role::program' not in db.tags_of_package(pkg): if 'role::program' not in db.tags_of_package(pkg):
continue continue
tfidf.append((pkg, tf * math.log(total / count[pkg]))) pkgcount = count.get(pkg, None)
if pkgcount is None:
print("no count found for", pkg)
else:
tfidf.append((pkg, tf * math.log(total / pkgcount)))
tfidf.sort(key=lambda x:x[1], reverse=True) tfidf.sort(key=lambda x: x[1], reverse=True)
for rank, word in enumerate(tfidf[:opts.count]): for rank, word in enumerate(tfidf[:opts.count]):
pkg = apt_cache[word[0]] pkg = apt_cache[word[0]]
print rank+1, word[0], '-', pkg.candidate.summary print(rank+1, word[0], '-', pkg.candidate.summary)
if __name__ == "__main__": if __name__ == "__main__":
...@@ -147,21 +159,23 @@ if __name__ == "__main__": ...@@ -147,21 +159,23 @@ if __name__ == "__main__":
sys.exit(2) sys.exit(2)
parser = Parser(usage="usage: %prog [options] filename", parser = Parser(usage="usage: %prog [options] filename",
version="%prog 0.1", version="%prog 0.1",
description="Generate package or tag usage profile") description="Generate package or tag usage profile")
parser.add_option("--packages", action="store_true", dest="packageoutput", default=True, help="Show package profiles (default: %default)") parser.add_option("--packages", action="store_true", dest="packageoutput", default=True,
parser.add_option("--tags", action="store_true", dest="tagoutput", default=False, help="Show tag profiles (default: %default)") help="Show package profiles (default: %default)")
parser.add_option("--tags", action="store_true", dest="tagoutput", default=False,
help="Show tag profiles (default: %default)")
parser.add_option("--count", default=10, help="Number of items to show (default: %default)") parser.add_option("--count", default=10, help="Number of items to show (default: %default)")
(opts, args) = parser.parse_args() (opts, args) = parser.parse_args()
FORMAT = "%(asctime)-15s %(levelname)s %(message)s" FORMAT = "%(asctime)-15s %(levelname)s %(message)s"
#if opts.debug: # if opts.debug:
# logging.basicConfig(level=logging.DEBUG, stream=sys.stderr, format=FORMAT) # logging.basicConfig(level=logging.DEBUG, stream=sys.stderr, format=FORMAT)
#elif opts.verbose: # elif opts.verbose:
# logging.basicConfig(level=logging.INFO, stream=sys.stderr, format=FORMAT) # logging.basicConfig(level=logging.INFO, stream=sys.stderr, format=FORMAT)
#else: # else:
# logging.basicConfig(level=logging.WARN, stream=sys.stderr, format=FORMAT) # logging.basicConfig(level=logging.WARN, stream=sys.stderr, format=FORMAT)
logging.basicConfig(level=logging.INFO, stream=sys.stderr, format=FORMAT) logging.basicConfig(level=logging.INFO, stream=sys.stderr, format=FORMAT)
opts.count = int(opts.count) opts.count = int(opts.count)
...@@ -170,10 +184,9 @@ if __name__ == "__main__": ...@@ -170,10 +184,9 @@ if __name__ == "__main__":
parser.error("You must choose a type of output") parser.error("You must choose a type of output")
if (opts.tagoutput): if (opts.tagoutput):
#TODO remove me later # TODO remove me later
sys.stderr.write("Tag output not yet implemented") sys.stderr.write("Tag output not yet implemented")
sys.exit(2); sys.exit(2)
horoscope = Horoscope() horoscope = Horoscope()
horoscope.compute_horoscope() horoscope.compute_horoscope()
#!/usr/bin/python #!/usr/bin/python3
# coding: utf8
# TODO: # TODO:
# - Filter packages by tags (for example, keep only role::program packages) # - Filter packages by tags (for example, keep only role::program packages)
...@@ -20,6 +19,7 @@ if not os.path.exists('/var/lib/debtags/package-tags'): ...@@ -20,6 +19,7 @@ if not os.path.exists('/var/lib/debtags/package-tags'):
sys.stderr.write("Sorry, /var/lib/debtags/package-tags doesn't exist and is required") sys.stderr.write("Sorry, /var/lib/debtags/package-tags doesn't exist and is required")
sys.exit(2) sys.exit(2)
class Parser(OptionParser): class Parser(OptionParser):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
OptionParser.__init__(self, *args, **kwargs) OptionParser.__init__(self, *args, **kwargs)
...@@ -29,9 +29,10 @@ class Parser(OptionParser): ...@@ -29,9 +29,10 @@ class Parser(OptionParser):
self.print_help(sys.stderr) self.print_help(sys.stderr)
sys.exit(2) sys.exit(2)
parser = Parser(usage="usage: %prog [options] filename", parser = Parser(usage="usage: %prog [options] filename",
version="%prog 0.1", version="%prog 0.1",
description="Count of packages grouped by implementation language") description="Count of packages grouped by implementation language")
(opts, args) = parser.parse_args() (opts, args) = parser.parse_args()
...@@ -89,15 +90,17 @@ with open("/var/log/popularity-contest") as infd: ...@@ -89,15 +90,17 @@ with open("/var/log/popularity-contest") as infd:
by_lang[t] = 0 by_lang[t] = 0
for pkg, tf in parse_vote(infd): for pkg, tf in parse_vote(infd):
if not pkg in apt_cache: continue if pkg not in apt_cache:
continue
aptpkg = apt_cache[pkg] aptpkg = apt_cache[pkg]
if not aptpkg.installed: continue if not aptpkg.installed:
continue
tags = db.tags_of_package(pkg) tags = db.tags_of_package(pkg)
if args: if args:
for t in tags: for t in tags:
if t == args[0]: if t == args[0]:
print pkg print(pkg)
break break
else: else:
for t in tags: for t in tags:
...@@ -105,19 +108,19 @@ with open("/var/log/popularity-contest") as infd: ...@@ -105,19 +108,19 @@ with open("/var/log/popularity-contest") as infd:
by_lang[t] += 1 by_lang[t] += 1
if not args: if not args:
for tag, count in sorted(by_lang.iteritems()): for tag, count in sorted(by_lang.items()):
if tag == "implemented-in::TODO": if tag == "implemented-in::TODO":
if count == 0: if count == 0:
print "You have no packages implemented in obscure languages: WIN!" print("You have no packages implemented in obscure languages: WIN!")
else: else:
print "You have %d packages implemented in obscure languages. Good luck with that." % count print("You have %d packages implemented in obscure languages. Good luck with that." % count)
lang = tag.split("::")[1] lang = tag.split("::")[1]
if count == 0: if count == 0:
print "You have no packages implemented in %s: WIN!" % lang print("You have no packages implemented in %s: WIN!" % lang)
else: else:
comment = horror_urls.get(tag, None) comment = horror_urls.get(tag, None)
if comment is None: if comment is None:
print "You have %d %s packages. That's bad news, but I don't have a link to explain why." % (count, lang) print("You have %d %s packages. That's bad news, but I don't have a link to explain why." % (count, lang))
else: else:
print "You have %d %s packages. Please see \"%s\"" % (count, lang, comment) print("You have %d %s packages. Please see \"%s\"" % (count, lang, comment))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment