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

Contents of /src/packages/gentoo.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations) (download) (as text)
Thu May 27 02:29:48 2004 UTC (10 years, 7 months ago) by marduk
Branch: MAIN
Changes since 1.1: +195 -149 lines
File MIME type: text/x-python
Oh, this is a big update: code cleanups, HTML cleanups, support for hard
masked packages and smart, er, less-brain-dead search reporting.

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

  ViewVC Help
Powered by ViewVC 1.1.20