/[gentoo]/src/packages/gentoo.py
Gentoo

Contents of /src/packages/gentoo.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (hide annotations) (download) (as text)
Sun Oct 17 16:53:21 2004 UTC (10 years, 1 month ago) by marduk
Branch: MAIN
Changes since 1.6: +41 -5 lines
File MIME type: text/x-python
Various fixes & enhancements

1 marduk 1.1 #!/usr/bin/python -OO
2 marduk 1.2 """These functions mainly take ebuild info (grabbed from the database and
3     convert it to HTML. See the "main" function at the bottom."""
4    
5 marduk 1.7 __revision__ = "$Revision: 1.6 $"
6 marduk 1.4 # $Source: /var/cvsroot/gentoo/src/packages/gentoo.py,v $
7 marduk 1.1
8     import config
9     import os
10     import time
11 marduk 1.7 import string
12 marduk 1.1 import sys
13     import ebuilddb
14 marduk 1.2 import bugs
15 marduk 1.1 import changelogs
16     from cgi import escape
17     from urllib import quote
18    
19 marduk 1.2 # import portage, but temporarily redirect stderr
20 marduk 1.3 if 'portage' not in dir():
21 marduk 1.2 null = open('/dev/null', 'w')
22     tmp = sys.stderr
23     sys.stderr = null
24     sys.path = ["/usr/lib/portage/pym"]+sys.path
25     import portage
26     sys.stderr = tmp
27 marduk 1.3 sys.path = sys.path[1:]
28 marduk 1.2
29     tree = portage.portdbapi('/usr/portage')
30    
31     def is_masked(ebuild):
32     """Return true if ebuild is masked"""
33    
34     return (not tree.visible(['%(category)s/%(name)s-%(version)s' % ebuild]))
35    
36 marduk 1.3 def is_new(db, ebuild):
37 marduk 1.1 """Check for newness. An ebuild is considered new if it is the
38     only ebuild with that category/name in ebuild and it has no prevarch"""
39    
40     c = db.cursor()
41 marduk 1.2 query = ('SELECT prevarch FROM ebuild WHERE category="%s" AND name="%s"'
42     % (ebuild['category'], ebuild['name']))
43 marduk 1.1 c.execute(query)
44     results = c.fetchall()
45     if len(results) == 1 and results[0][0] is None:
46     return 1
47     return 0
48    
49 marduk 1.2 def changelog_to_html(changelog):
50     """HTML-ize a changelog entry"""
51     html = ""
52     for char in changelog:
53     if char == '\n':
54     html = "%s<br>" % html
55 marduk 1.1 else:
56 marduk 1.2 html = "%s%s" % (html, escape(char))
57     html = changelogs.bugs_to_html(html)
58     return html
59    
60     def homepage_to_html(homepage):
61     """convert HOMEPAGE entry to HTML"""
62 marduk 1.3 if not homepage.strip():
63     return "?"
64 marduk 1.2 homepage = homepage.replace('|',' ')
65     pieces = homepage.split()
66     count = len(pieces)
67     if count == 1:
68     return ('<a class="homepage" href="%s">'
69     'Homepage</a>' % pieces[0])
70    
71     html = ['[<a href="%s">%s</a>]' % (page, index + 1) for index,
72     page in enumerate(pieces)]
73     return " ".join(['<span class="homepage">Homepages'] + html +
74     ['</span>'])
75    
76     def license_to_html(license):
77 marduk 1.3 """Create link to license[s]"""
78 marduk 1.2 if not license.strip(): return "?"
79     license = license.replace('|',' ')
80     pieces = license.split()
81     html = ['<a href="http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/'
82     'licenses/%s">%s</a>' % (piece, piece) for piece in pieces]
83     return '<br>\n'.join(html)
84 marduk 1.1
85 marduk 1.3 def package_to_html(pkginfo, db):
86     """This function needs a database (db) connection because it performs a
87     query_to_dict on the package"""
88 marduk 1.2
89     table_begin = '<table class="ebuild">'
90     name = '<tr><td class="fields">%s</td></tr>' % pkginfo['name']
91     description = ('<tr><td class="item">'
92     '<img align="right" alt="" src="%s/%s.png">'
93     '<b>Description: </b>%s</td></tr>' % (config.ICONS,
94     pkginfo['category'], escape(pkginfo['description'])))
95 marduk 1.3 ebuilds = get_recent_releases(pkginfo, db)
96 marduk 1.2 releases = '<tr><td>%s</td></tr>' % archs_to_html(ebuilds, 'Releases')
97     #bug_string = ('<br><h3>Related bugs:</h3>\n%s'
98     # % bugs_to_html(pkginfo['name']))
99     general = '<tr><td>%s</td></tr>' % general_info_to_html(pkginfo)
100 marduk 1.7 similar = '<tr><td>%s</td></tr>' % create_similar_pkgs_link(pkginfo)
101 marduk 1.2 table_end = '</table>'
102     rows = '\n\t'.join([name, description, releases, general])
103     return '\n\t'.join([table_begin, rows, table_end])
104    
105     def archs_to_html(ebuilds, heading = None):
106 marduk 1.3 """Create table for availability on each architecture"""
107 marduk 1.2 heading = heading or '&nbsp;'
108     table_begin = '<table class="releases">'
109     header_row = ''.join(['<tr><td><b>%s</b></td>' % heading] +
110 marduk 1.7 ['<th class="arch">%s</th>' % i.replace('-',' ') for i in config.ARCHLIST] +
111 marduk 1.2 ['</tr>']
112     )
113     rows = []
114 marduk 1.7 ebuilds.sort(cmp_ebuilds)
115     ebuilds.reverse()
116 marduk 1.2 for ebuild in ebuilds:
117     masked = is_masked(ebuild)
118     archs = ebuild['arch'].split()
119     row_start = ('<tr>\n\t<th class="releases"><a href="%sebuilds/?%s-%s"'
120     ' title="%s">%s</a></th>\n' % (config.FEHOME,
121     ebuild['name'], ebuild['version'], ebuild['time'],
122     ebuild['version']))
123     row_data = []
124     for arch in config.ARCHLIST:
125     if arch in archs:
126     arch_string = '+'
127     elif '~%s' % arch in archs:
128     arch_string = '~'
129     else:
130     arch_string = '-'
131     if arch_string != '-' and masked:
132     arch_string = 'M' + arch_string
133     row_data.append('\t<td class="archcell" arch="%s">%s</td>'
134     % (arch_string, arch_string))
135     row_end = '</tr>'
136     rows.append('\n\t'.join([row_start] + row_data + [row_end]))
137     table_end = '</table>'
138     return '\n\t'.join([table_begin] + [header_row] + rows + [table_end])
139 marduk 1.1
140 marduk 1.2 def ebuild_to_html(ebinfo, new=0, show_bugs=0):
141 marduk 1.3 """Convert ebuild (dict) to html, if new, print out a "this is new" notice
142     if show_bugs, show bugs for this particular ebuild (requires access to
143     bugzilla"""
144 marduk 1.1 if new:
145     new_string = """ &nbsp;&nbsp;<span class="new">new!</span> """
146     else:
147     new_string = ""
148    
149 marduk 1.2 table_begin = '<table class="ebuild">'
150     name_and_date = ('<tr><td class="fields">'
151 marduk 1.1 '<a href="%spackages/?category=%s;name=%s">%s</a> %s%s<br>'
152 marduk 1.2 '<span class="time">%s</span>'
153     '</td></tr>' % (config.FEHOME, quote(ebinfo['category']),
154     quote(ebinfo['name']),
155     ebinfo['name'],
156     ebinfo['version'],
157     new_string,
158     ebinfo['time'].localtime().strftime("%c %Z")))
159    
160     desc_and_changes = ('<tr><td class="item" valign="top">'
161     '<img alt="" align="right" src="%simages/%s.png">'
162     '<p><b>Description:</b> %s</p>'
163     '<p><b>Changes:</b><br>'
164     '%s</p></td></tr>' % (
165     config.FEHOME,
166     ebinfo['category'],
167     escape(ebinfo['description']),
168     changelog_to_html(ebinfo['changelog'])))
169    
170     archs = '<tr><td>%s</td></tr>' % archs_to_html([ebinfo])
171     general = '<tr><td>%s</td></tr>' % general_info_to_html(ebinfo)
172     table_end = '</table>'
173    
174     if 1 == 1:
175     bug_string = ''
176     else:
177 marduk 1.3 bug_string = '<br><h3>Related bugs:</h3>%s' \
178     % bugs_to_html(ebinfo['name'])
179 marduk 1.2
180     return '\n\t'.join([table_begin,
181     name_and_date,
182     desc_and_changes,
183     archs,
184     general,
185     table_end,
186     bug_string])
187    
188 marduk 1.1 def general_info_to_html(pkg):
189     """This actually will (should) take either a package or ebuild dict
190     as an argument"""
191    
192     changelogurl = ('http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/'
193     '%s/%s/ChangeLog' % (pkg['category'],pkg['name']))
194 marduk 1.2 cat_header = '<th class="category">Category</th>'
195     license_header = '<th class="license">License</th>'
196     category = ('<td class="category">'
197     '<a href="%spackages/?category=%s">%s</a></td>' % (config.FEHOME,
198     pkg['category'], pkg['category']))
199     homepage = ('<td class="homepage" rowspan="2">%s</td>'
200     % homepage_to_html(pkg['homepage']))
201     license = ('<td class="license">%s</td>'
202     % license_to_html(pkg['license']))
203     changelog = ('<td class="changelog" rowspan="2">'
204 marduk 1.7 '<a href="%s">ChangeLog</a></td>' % changelogurl)
205     similar = ('<td class="similar" rowspan="2">'
206     '%s</td>' % create_similar_pkgs_link(pkg))
207 marduk 1.2
208     return '\n\t'.join(['<table class="general_info">',
209     '<tr>',
210     cat_header,
211     homepage,
212     license_header,
213     changelog,
214 marduk 1.7 similar,
215 marduk 1.2 '</tr>',
216     '<tr>',
217     category,
218     license,
219     '</tr>',
220     '</table>'])
221 marduk 1.1
222 marduk 1.7 def create_similar_pkgs_link(pkg):
223     """Create a link to similar packages"""
224    
225     def strip_chars(mystring):
226     newstring = ''
227     for char in mystring:
228     if char not in string.punctuation:
229     newstring = newstring + char
230     else:
231     newstring = newstring + ' '
232     return newstring
233    
234     description = strip_chars(pkg['description'].lower())
235    
236     words = [word for word in description.split()
237     if word and len(word)>2 and word not in config.EXCLUDED_FROM_SIMILAR]
238     words = words[:config.SIMILAR_MAX_WORDS] + [pkg['name']]
239     #query = ['[[:<:]]%s[[:>:]].*' % word for word in words]
240     query = ['[[:<:]]%s.*' % word for word in words]
241     query = '(%s){%s,}' % ('|'.join(query), config.SIMILAR_MIN_MATCHES)
242     url = '%ssearch/?sstring=%s' % (config.FEHOME, escape(query))
243     return '<a href="%s">Similar Packages</a>' % url
244    
245 marduk 1.2 def bugs_to_html(package):
246     """Given package name (no version #s), return html text of bugs as
247     reported by bugzilla"""
248     # Right now we have an issue with the bugzilla site. New interface
249     # needs to be written, Bail out.
250     return ""
251     import urllib2
252     url = ('http://bugs.gentoo.org/buglist.cgi?query_format='
253     '&short_desc_type=allwords&short_desc=%s'
254     '&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED'
255     '&bug_status=REOPENED'
256     '&ctype=csv' % package)
257     fp = urllib2.urlopen(url)
258     factory = bugs.BugFactory()
259     package_bugs = factory.fromCSV(fp)
260     if package_bugs:
261     writer = bugs.HTMLWriter(package_bugs, 'bugs.gentoo.org')
262     return str(writer)
263     else:
264     return "None"
265    
266 marduk 1.3 def get_most_recent(db, max=config.MAXPERPAGE, arch="", branch=""):
267 marduk 1.1 c = db.cursor()
268     extra = ''
269     if arch:
270     stable_extra = ('ebuild.arch REGEXP "^%s| %s" '
271     ' AND ebuild.prevarch NOT REGEXP"^%s| %s"'
272     % (arch,arch,arch,arch))
273     testing_extra = ('ebuild.arch REGEXP "^~%s| ~%s" '
274     ' AND ebuild.prevarch NOT REGEXP "^~%s| ~%s"'
275     % (arch,arch,arch,arch))
276     if branch == 'stable':
277     extra = ' AND (%s) ' % stable_extra
278     elif branch == 'testing':
279     extra = ' AND (%s) ' % testing_extra
280     else:
281     extra = ' AND ((%s) OR (%s)) ' % (stable_extra, testing_extra)
282     query = """SELECT ebuild.category,ebuild.name,version,when_found,description,
283     changelog,arch,homepage,license FROM ebuild,package WHERE ebuild.name=\
284     package.name AND ebuild.category=package.category %s ORDER by when_found DESC \
285     LIMIT %s""" % (extra,max)
286     c.execute(query)
287     results = c.fetchall()
288     return results
289    
290     def query_to_dict(d):
291 marduk 1.3 """Convert a SQL query to a dict"""
292 marduk 1.1 einfo = {}
293 marduk 1.3 keys = ('category', 'name', 'version', 'time', 'description', 'changelog',
294     'arch', 'homepage', 'license')
295 marduk 1.1 for i in range(len(keys)):
296     try:
297     einfo[keys[i]] = d[i]
298     except IndexError:
299     continue
300     return einfo
301    
302 marduk 1.3 def get_recent_releases(pkg, db, max=config.MAX_RECENT_RELEASES):
303 marduk 1.1 """Return MAX_RECENT_RELEASES most recent releases for pkg. Returns and
304     ebuild-type dict"""
305     c = db.cursor()
306 marduk 1.3 query = ('SELECT category,name,version,when_found,NULL,changelog,arch ,'
307     'NULL,NULL FROM ebuild WHERE name="%s" AND category="%s" ORDER BY '
308     'version DESC LIMIT %s' % (pkg['name'],pkg['category'],max))
309 marduk 1.1 c.execute(query)
310     results = c.fetchall()
311     #print results
312     return [ query_to_dict(i) for i in results ]
313 marduk 1.7
314     def cmp_ebuilds(a, b):
315     """Compare two ebuilds"""
316     fields_a = portage.pkgsplit('%s-%s' % (a['name'], a['version']))
317     fields_b = portage.pkgsplit('%s-%s' % (b['name'], b['version']))
318     return portage.pkgcmp(fields_a, fields_b)
319    
320 marduk 1.3 def ebuilds_to_rss(fp, ebuilds, simple=False, subtitle=""):
321 marduk 1.1 """write out ebuild info to RSS file (fp)"""
322 marduk 1.4 fp.write("""<?xml version="1.0" encoding="iso-8859-1"?>
323 marduk 1.1 <rss version="0.92">
324     <channel>
325 marduk 1.7 <title>packages.gentoo.org [ %s ]</title>
326 marduk 1.1 <link>%s</link>
327     <description>Latest ebuilds from the Gentoo Linux portage tree</description>
328 marduk 1.2 <![CDATA[<link rel="stylesheet" href="%s" type="text/css" title="styled" />]]>
329 marduk 1.1 <webMaster>www@gentoo.org</webMaster>
330     <managingEditor>marduk@gentoo.org</managingEditor>
331 marduk 1.2 <pubDate>%s</pubDate>""" % (subtitle,config.FEHOME, config.STYLESHEET,
332 marduk 1.1 time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())))
333    
334     for ebuild in ebuilds:
335     if simple:
336     description = escape(ebuild['description'])
337     else:
338     description = '\n<![CDATA[\n%s\n]]>' % ebuild_to_html(ebuild)
339    
340     fp.write("""<item>
341     <title>%s %s</title>
342     <link>%sebuilds/?%s-%s</link>
343     <description>
344     %s
345     </description>
346     <pubDate>%s</pubDate>
347     </item>
348     """ % (ebuild['name'],
349     ebuild['version'],
350     config.FEHOME,
351     ebuild['name'],
352     ebuild['version'],
353     description,
354     ebuild['time'].gmtime().strftime("%a, %d %b %Y %H:%M:%S +0000"))
355     )
356    
357     fp.write("</channel>\n</rss>\n")
358    
359 marduk 1.6 def main(argv=None):
360     if argv is None:
361     argv = sys.argv
362 marduk 1.1 try:
363 marduk 1.5 if argv[1] == '-g':
364 marduk 1.1 ebuilddb.main()
365     except IndexError:
366 marduk 1.3 pass
367 marduk 1.2
368 marduk 1.1 db = ebuilddb.db_connect()
369 marduk 1.3 branches = ('', 'stable', 'testing')
370 marduk 1.1 for arch in [''] + config.ARCHLIST:
371     for branch in branches:
372 marduk 1.3 fullpath = os.path.join(config.LOCALHOME, "archs", arch, branch,
373     config.INDEX)
374 marduk 1.1 index = open(fullpath,'w')
375     if arch:
376     sarch = arch
377     else:
378     sarch = 'all'
379     if branch:
380     sbranch = branch
381     else:
382     sbranch = 'all'
383    
384     index.write("""<table border="0" cellpadding="0" cellspacing="5"
385     width="100%">\n""")
386     index.write("""<tr><td valign="top">\n""")
387 marduk 1.3 index.write('<!--#include file="archnav.html" -->\n\n</td></tr>\n'
388     '<tr><td>')
389     results = get_most_recent(db, arch=arch, branch=branch)
390 marduk 1.1 ebuilds = [ query_to_dict(i) for i in results ]
391     for ebuild in ebuilds:
392 marduk 1.3 new = is_new(db, ebuild)
393 marduk 1.1 pkgfilename = "%s/%s-%s.html" % (
394     config.EBUILD_FILES,ebuild['name'],ebuild['version'])
395 marduk 1.3 ebuild_html = ebuild_to_html(ebuild, new)
396     if arch == '' and branch == '':
397 marduk 1.1 pkgfile = open(pkgfilename,'w')
398     pkgfile.write(ebuild_html)
399     pkgfile.close()
400 marduk 1.3 ebuildfilename = "%s/%s/%s/%s-%s.ebuild" \
401     % (ebuilddb.config.PORTAGE_DIR,
402 marduk 1.1 ebuild['category'],ebuild['name'],ebuild['name'],
403     ebuild['version'])
404 marduk 1.2 os.system('touch -r %s %s || touch -d "today -1 year" %s'
405     % (ebuildfilename,pkgfilename,pkgfilename))
406 marduk 1.1
407     try:
408 marduk 1.2 index.write('%s\n\n' % (ebuild_html))
409 marduk 1.1 except IOError:
410 marduk 1.3 continue
411 marduk 1.1 index.write("""</table>\n""")
412     index.close()
413    
414 marduk 1.3 subtitle = ' %s %s' % (arch, branch)
415     rss = open(os.path.join(config.LOCALHOME, "archs", arch, branch,
416     config.RSS), 'w')
417     ebuilds_to_rss(rss, ebuilds, simple=False, subtitle=subtitle)
418 marduk 1.1 rss.close()
419    
420 marduk 1.3 rss2 = open(os.path.join(config.LOCALHOME, "archs", arch, branch,
421     config.RSS2), 'w')
422     ebuilds_to_rss(rss2, ebuilds, simple=True, subtitle=subtitle)
423 marduk 1.1 rss.close()
424 marduk 1.5
425     if __name__ == '__main__':
426     sys.exit(main())

  ViewVC Help
Powered by ViewVC 1.1.20