#!/usr/bin/python -O
"""These functions mainly take ebuild info (grabbed from the database and
convert it to HTML. See the "main" function at the bottom."""
__revision__ = "$Revision: 1.16.2.5 $"
# $Source: /var/cvsroot/gentoo/src/packages/gentoo.py,v $
import config
import os
import time
import sys
import ebuilddb
import bugs
import changelogs
from cgi import escape
from urllib import quote
from portage_versions import pkgcmp, pkgsplit
def is_new(db, ebuild):
"""Check for newness."""
c = db.cursor()
query = ('SELECT new FROM package WHERE category="%s" AND name="%s"'
% (ebuild['category'], ebuild['name']))
c.execute(query)
results = c.fetchall()
if len(results) == 1 and results[0][0]:
return 1
return 0
changelog_to_html = changelogs.bugs_to_html
def homepage_to_html(homepage):
"""convert HOMEPAGE entry to HTML"""
if not homepage.strip():
return "?"
homepage = homepage.replace('|',' ')
pieces = homepage.split()
count = len(pieces)
if count == 1:
return (''
'Homepage ' % pieces[0])
html = ['[%s ]' % (page, index + 1) for index,
page in enumerate(pieces)]
return " ".join(['Homepages'] + html +
[' '])
def license_to_html(license):
"""Create link to license[s]"""
if not license.strip(): return "?"
license = license.replace('|',' ')
license = license.replace('(', '')
license = license.replace(')', '')
pieces = license.split()
html = ['%s ' % (piece, piece) for piece in pieces]
return ' \n'.join(html)
def package_to_html(pkginfo, db, full=False):
"""This function needs a database (db) connection because it performs a
query_to_dict on the package"""
table_begin = '
'
name = '%s ' % pkginfo['name']
if full:
image = (' ' %
(config.ICONS, pkginfo['category'], pkginfo['name'])
)
else:
image = ''
description = (''
'%sDescription: %s '
% (image, escape(pkginfo['description']))
)
ebuilds = get_recent_releases(pkginfo, db)
releases = '%s ' % archs_to_html(ebuilds, 'Releases')
#bug_string = ('Related bugs: \n%s'
# % bugs_to_html(pkginfo['name']))
general = '%s ' % general_info_to_html(pkginfo)
#similar = '%s ' % create_similar_pkgs_link(pkginfo)
table_end = '
'
rows = '\n\t'.join([name, description, releases, general])
return '\n\t'.join([table_begin, rows, table_end])
def archs_to_html(ebuilds, heading = None):
"""Create table for availability on each architecture"""
heading = heading or ' '
table_begin = ''
header_row = ''.join(['%s ' % heading] +
['%s ' % i.replace('-',' ') for i in config.ARCHLIST] +
[' ']
)
rows = []
ebuilds.sort(cmp_ebuilds)
ebuilds.reverse()
for ebuild in ebuilds:
archs = ebuild['arch'].split(',')
row_start = ('\n\t%s \n' % (config.FEHOME,
ebuild['name'], ebuild['version'], ebuild['time'],
ebuild['version']))
row_data = []
for arch in config.ARCHLIST:
if arch in archs:
arch_string = '+'
elif '~%s' % arch in archs:
arch_string = '~'
else:
arch_string = '-'
if arch_string != '-' and ebuild['masked']:
arch_string = 'M' + arch_string
row_data.append('\t%s '
% (arch_string, arch_string))
row_end = ' '
rows.append('\n\t'.join([row_start] + row_data + [row_end]))
table_end = '
'
return '\n\t'.join([table_begin] + [header_row] + rows + [table_end])
def ebuild_to_html(ebinfo, new=0, show_bugs=0, full = False):
"""Convert ebuild (dict) to html, if new, print out a "this is new" notice
if show_bugs, show bugs for this particular ebuild (requires access to
bugzilla"""
if new:
new_string = """ new! """
else:
new_string = ""
table_begin = ''
name_and_date = (''
'%s %s%s '
'%s '
' ' % (config.FEHOME, quote(ebinfo['category']),
quote(ebinfo['name']),
ebinfo['name'],
ebinfo['version'],
new_string,
ebinfo['time'].strftime("%c %Z")))
if full:
image = (' ' %
(config.ICONS, ebinfo['category'], ebinfo['name'])
)
else:
image = ''
desc_and_changes = (''
'Description: %s %s
'
'Changes: '
'%s
' % (
escape(ebinfo['description']),
image,
changelog_to_html(ebinfo['changelog'])))
archs = '%s ' % archs_to_html([ebinfo])
general = '%s ' % general_info_to_html(ebinfo)
table_end = '
'
bug_string = ''
if show_bugs:
bug_string = bugs_to_html(ebinfo['name'])
if bug_string:
bug_string = 'Related bugs: %s' \
% bug_string
return '\n\t'.join([table_begin,
name_and_date,
desc_and_changes,
archs,
general,
table_end,
bug_string])
def general_info_to_html(pkg):
"""This actually will (should) take either a package or ebuild dict
as an argument"""
import forums
changelogurl = ('http://sources.gentoo.org/viewcvs.py/*checkout*/'
'gentoo-x86/%s/%s/ChangeLog' % (pkg['category'],pkg['name']))
cat_header = 'Category '
license_header = 'License '
category = (''
'%s ' % (config.FEHOME,
pkg['category'], pkg['category']))
homepage = ('%s '
% homepage_to_html(pkg['homepage']))
license = ('%s '
% license_to_html(pkg['license']))
changelog = (''
'ChangeLog ' % changelogurl)
similar = (''
'%s ' % create_similar_pkgs_link(pkg))
related_bugs = (''
'%s ' % create_related_bugs_link(pkg))
forums_link = (''
'%s ' % forums.create_forums_link(pkg))
return '\n\t'.join(['',
'',
cat_header,
homepage,
license_header,
changelog,
similar,
related_bugs,
forums_link,
' ',
'',
category,
license,
' ',
'
'])
def create_similar_pkgs_link(pkg):
"""Create a link to similar packages"""
return 'Similar ' % pkg
def create_related_bugs_link(pkg):
"""Create a link to related bugs"""
url = ('http://bugs.gentoo.org/buglist.cgi?query_format='
'&short_desc_type=allwords'
'&short_desc=%s'
'&bug_status=UNCONFIRMED'
'&bug_status=NEW'
'&bug_status=ASSIGNED'
'&bug_status=REOPENED'
% escape(pkg['name']))
return 'Bugs ' % url
def bugs_to_html(package):
"""Given package name (no version #s), return html text of bugs as
reported by bugzilla"""
# Right now we have an issue with the bugzilla site. New interface
# needs to be written, Bail out.
#return ""
import urllib2
url = ('http://bugs.gentoo.org/buglist.cgi?query_format='
'&short_desc_type=allwords'
'&short_desc=%s'
'&bug_status=UNCONFIRMED'
'&bug_status=NEW'
'&bug_status=ASSIGNED'
'&bug_status=REOPENED'
'&ctype=csv'
% package)
fp = urllib2.urlopen(url)
factory = bugs.BugFactory()
package_bugs = factory.fromCSV(fp)
if package_bugs:
writer = bugs.HTMLWriter(package_bugs, 'bugs.gentoo.org')
return str(writer)
else:
return ""
def get_most_recent(db, max=config.MAXPERPAGE, arch="", branch="", new = False):
c = db.cursor()
extra = ''
if arch:
stable_extra = ('FIND_IN_SET("%s", ebuild.arch) > 0 AND '
'FIND_IN_SET("%s", ebuild.prevarch) = 0 ' % (arch, arch))
testing_extra = ('FIND_IN_SET("~%s", ebuild.arch) > 0 AND '
'FIND_IN_SET("~%s", ebuild.prevarch) = 0 ' % (arch, arch))
if branch == 'stable':
extra = ' AND (%s) ' % stable_extra
elif branch == 'testing':
extra = ' AND (%s) ' % testing_extra
else:
extra = ' AND ((%s) OR (%s)) ' % (stable_extra, testing_extra)
if new:
extra = ('%s AND package.new=1 ' % extra)
query = """SELECT ebuild.category,ebuild.name,version,ebuild.when_found,description,
changelog,arch,homepage,license,is_masked FROM ebuild,package WHERE ebuild.name=\
package.name AND ebuild.category=package.category %s ORDER by ebuild.when_found DESC \
LIMIT %s""" % (extra,max)
c.execute(query)
results = c.fetchall()
return results
def get_most_recent_bumps(db, max=config.MAXPERPAGE):
"""Return most recent version bumps (pkgs with no prevarch)"""
c = db.cursor()
query = ('SELECT ebuild.category, ebuild.name, version, when_found, '
'description, changelog, arch, homepage, license,is_masked FROM ebuild, package '
'WHERE ebuild.name=package.name AND ebuild.category=package.category '
'AND prevarch="" AND version NOT LIKE "%%-r_" AND version NOT LIKE '
'"%%-r__" AND NOT new ORDER by when_found '
'DESC LIMIT %s' % max)
c.execute(query)
results = c.fetchall()
return results
def query_to_dict(d):
"""Convert a SQL query to a dict"""
einfo = {}
keys = ('category', 'name', 'version', 'time', 'description', 'changelog',
'arch', 'homepage', 'license', 'masked')
for i in range(len(keys)):
try:
einfo[keys[i]] = d[i]
except IndexError:
continue
return einfo
def get_recent_releases(pkg, db, max=config.MAX_RECENT_RELEASES):
"""Return MAX_RECENT_RELEASES most recent releases for pkg. Returns and
ebuild-type dict"""
c = db.cursor()
query = ('SELECT category,name,version,when_found,NULL,changelog,arch ,'
'NULL,NULL,is_masked FROM ebuild WHERE name="%s" AND category="%s" ORDER BY '
'version DESC LIMIT %s' % (pkg['name'],pkg['category'],max))
c.execute(query)
results = c.fetchall()
#print results
return [ query_to_dict(i) for i in results ]
def cmp_ebuilds(a, b):
"""Compare two ebuilds"""
fields_a = pkgsplit('%s-%s' % (a['name'], a['version']))
fields_b = pkgsplit('%s-%s' % (b['name'], b['version']))
return pkgcmp(fields_a, fields_b)
def ebuilds_to_rss(fp, ebuilds, simple=False, subtitle=""):
"""write out ebuild info to RSS file (fp)"""
# web link for RSS feed
if subtitle:
link = '%s/%s' % (config.FEHOME, subtitle.replace(' ','/',1))
else:
link = config.FEHOME
pubDate = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
fp.write("""
packages.gentoo.org [ %s ]
%s
Latest ebuilds from the Gentoo Linux portage tree
www@gentoo.org
Online Package Database
%s
%s
marduk@gentoo.org
%s """ % (subtitle, link, config.RSS_IMAGE,
config.FEHOME, pubDate))
for ebuild in ebuilds:
if simple:
description = escape(ebuild['description'])
else:
description = ('\n'
'\n'
'%s\n]]>' % (config.STYLESHEET, ebuild_to_html(ebuild, full=True))
)
fp.write("""-
%s/%s %s
%sebuilds/?%s-%s
%s
%s
""" % (ebuild['category'],
ebuild['name'],
ebuild['version'],
config.FEHOME,
ebuild['name'],
ebuild['version'],
description,
ebuild['time'].strftime("%a, %d %b %Y %H:%M:%S +0000"))
)
fp.write("\n\
\n\
Search \n\
%s/search/\n\
Search the Online Package Database \n\
sstring \n\
\n\
\n\
\n" % config.FEHOME)
def main(argv=None):
if argv is None:
argv = sys.argv
try:
if argv[1] == '-g':
ebuilddb.main()
except IndexError:
pass
db = ebuilddb.db_connect()
branches = ('', 'stable', 'testing')
for arch in [''] + config.ARCHLIST:
for branch in branches:
fullpath = os.path.join(config.LOCALHOME, "archs", arch, branch,
config.INDEX)
index = open(fullpath,'w')
index.write("""\n""")
index.write("""\n""")
index.write('\n\n \n'
'')
results = get_most_recent(db, arch=arch, branch=branch)
ebuilds = [ query_to_dict(i) for i in results ]
for ebuild in ebuilds:
new = is_new(db, ebuild)
pkgfilename = "%s/%s-%s.html" % (
config.EBUILD_FILES,ebuild['name'],ebuild['version'])
ebuild_html = ebuild_to_html(ebuild, new, show_bugs = False)
if arch == '' and branch == '':
pkgfile = open(pkgfilename,'w')
pkgfile.write(ebuild_html)
pkgfile.close()
ebuildfilename = "%s/%s/%s/%s-%s.ebuild" \
% (ebuilddb.config.PORTAGE_DIR,
ebuild['category'],ebuild['name'],ebuild['name'],
ebuild['version'])
os.system('touch -r %s %s || touch -d "today -1 year" %s'
% (ebuildfilename,pkgfilename,pkgfilename))
try:
index.write('%s\n\n' % (ebuild_html))
except IOError:
continue
index.write("""
\n""")
index.close()
subtitle = ' %s %s' % (arch, branch)
rss = open(os.path.join(config.LOCALHOME, "archs", arch, branch,
config.RSS), 'w')
ebuilds_to_rss(rss, ebuilds, simple=False, subtitle=subtitle)
rss.close()
rss2 = open(os.path.join(config.LOCALHOME, "archs", arch, branch,
config.RSS2), 'w')
ebuilds_to_rss(rss2, ebuilds, simple=True, subtitle=subtitle)
rss.close()
if __name__ == '__main__':
sys.exit(main())