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

Diff of /src/packages/gentoo.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.1 Revision 1.2
1#!/usr/bin/python -OO 1#!/usr/bin/python -OO
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: 1.2 $"
6# $Source: /var/cvsroot/gentoo/src/packages/gentoo.py,v $"
2 7
3import config 8import config
4import os 9import os
5import time 10import time
6import sys 11import sys
7import MySQLdb
8import ebuilddb 12import ebuilddb
13import bugs
9import changelogs 14import changelogs
10from cgi import escape 15from cgi import escape
11from urllib import quote 16from urllib import quote
12 17
18# import portage, but temporarily redirect stderr
19try:
20 portage
21except 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
29tree = portage.portdbapi('/usr/portage')
30
31def is_masked(ebuild):
32 """Return true if ebuild is masked"""
33
34 return (not tree.visible(['%(category)s/%(name)s-%(version)s' % ebuild]))
35
13def is_new(db,ebuild): 36def is_new(db,ebuild):
14 """Check for newness. An ebuild is considered new if it is the 37 """Check for newness. An ebuild is considered new if it is the
15 only ebuild with that category/name in ebuild and it has no prevarch""" 38 only ebuild with that category/name in ebuild and it has no prevarch"""
16 39
17 c = db.cursor() 40 c = db.cursor()
18 query = """SELECT prevarch FROM ebuild WHERE category="%s" AND name="%s" """ \ 41 query = ('SELECT prevarch FROM ebuild WHERE category="%s" AND name="%s"'
19 % (ebuild['category'], ebuild['name']) 42 % (ebuild['category'], ebuild['name']))
20 c.execute(query) 43 c.execute(query)
21 results = c.fetchall() 44 results = c.fetchall()
22 if len(results) == 1 and results[0][0] is None: 45 if len(results) == 1 and results[0][0] is None:
23 return 1 46 return 1
24 return 0 47 return 0
25 48
26def changelog_to_html(s): 49def changelog_to_html(changelog):
50 """HTML-ize a changelog entry"""
27 n = "" 51 html = ""
28 for c in s: 52 for char in changelog:
29 if c == '\n': 53 if char == '\n':
30 n = "%s<br>" % n 54 html = "%s<br>" % html
31 else: 55 else:
32 n = "%s%s" % (n,escape(c)) 56 html = "%s%s" % (html, escape(char))
33 n = changelogs.bugs_to_html(n) 57 html = changelogs.bugs_to_html(html)
34 return n 58 return html
35 59
36def homepage_to_html(s): 60def 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
75def license_to_html(license):
37 if not s.strip(): return "?" 76 if not license.strip(): return "?"
38 t = s.replace('|',' ') 77 license = license.replace('|',' ')
39 if ' ' in t:
40 pieces = t.split() 78 pieces = license.split()
41 return ' '.join([ homepage_to_html(piece) for piece in pieces ]) 79 html = ['<a href="http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/'
42 return ("""<a href="%s"><img border="0" src="%s/home.png" width="24" height="20" alt="Home Page" title="Home Page"></a>""" % (s, config.ICONS)) 80 'licenses/%s">%s</a>' % (piece, piece) for piece in pieces]
43 81 return '<br>\n'.join(html)
44def license_to_html(s):
45 if not s.strip(): return "?"
46 t = s.replace('|',' ')
47 if ' ' in t:
48 pieces = t.split()
49 return "<br>".join([ license_to_html(piece) for piece in pieces ])
50 return """<a href="http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/licenses/%s">%s</a>""" % (s,s)
51 82
52def package_to_html(pkginfo,db): 83def package_to_html(pkginfo,db):
53 """This function needs a database (db) connection because it performs a query_to_dict 84 """This function needs a database (db) connection because it performs a query_to_dict
54 on the package""" 85 on the package"""
55 #colspan = len(config.ARCHLIST) + 1 86
56 s = """<table class="ebuild"> 87 table_begin = '<table class="ebuild">'
57 <tr><td class="fields" colspan="4">%s</td></tr> 88 name = '<tr><td class="fields">%s</td></tr>' % pkginfo['name']
58 <tr><td class="item" colspan="4"><p><img align="right" alt="" src="%s/%s.png"> 89 description = ('<tr><td class="item">'
59 <b>Description: </b>%s</p> 90 '<img align="right" alt="" src="%s/%s.png">'
60 """ % (pkginfo['name'],config.ICONS,pkginfo['category'],escape(pkginfo['description'])) 91 '<b>Description: </b>%s</td></tr>' % (config.ICONS,
92 pkginfo['category'], escape(pkginfo['description'])))
61 ebuilds = get_recent_releases(pkginfo,db) 93 ebuilds = get_recent_releases(pkginfo,db)
62 if ebuilds: 94 releases = '<tr><td>%s</td></tr>' % archs_to_html(ebuilds, 'Releases')
63 s = """%s<p><b>Releases:</b></p> 95 bug_string = ''
64 <table class="releases"><tr><td>&nbsp;</td>""" % s 96 #bug_string = ('<br><h3>Related bugs:</h3>\n%s'
65 for i in config.ARCHLIST: 97 # % bugs_to_html(pkginfo['name']))
66 s = """%s<th class="arch">%s</th>""" % (s,i) 98 general = '<tr><td>%s</td></tr>' % general_info_to_html(pkginfo)
67 s = "%s</tr>\n" % s 99 table_end = '</table>'
100 rows = '\n\t'.join([name, description, releases, general])
101 return '\n\t'.join([table_begin, rows, table_end])
102
103def 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 = []
68 for ebuild in ebuilds: 111 for ebuild in ebuilds:
112 masked = is_masked(ebuild)
69 archs = ebuild['arch'].split() 113 archs = ebuild['arch'].split()
70 s = """%s<tr><th class="releases"><a href="%sebuilds/?%s-%s" title="%s">%s</a></th> 114 row_start = ('<tr>\n\t<th class="releases"><a href="%sebuilds/?%s-%s"'
71 """ % (s,config.FEHOME,ebuild['name'],ebuild['version'],ebuild['time'],ebuild['version']) 115 ' title="%s">%s</a></th>\n' % (config.FEHOME,
116 ebuild['name'], ebuild['version'], ebuild['time'],
117 ebuild['version']))
118 row_data = []
72 for arch in config.ARCHLIST: 119 for arch in config.ARCHLIST:
73 if arch in config.ARCHLIST:
74 if arch in archs:
75 arch_string = '+'
76 title = 'marked stable for %s' % arch
77 elif '~%s' % arch in archs:
78 arch_string = '~'
79 title = 'undergoing testing for %s' % arch
80 else:
81 arch_string = '-'
82 title = 'not available for %s' % arch
83 s = """%s<td class="archcell" arch="%s" title="%s">%s</td>
84 """ % (s,arch_string,title,arch_string)
85 s = "%s</tr>" % s
86 s = "%s</table>\n" % s
87
88 s = "%s\n%s</table>" % (s,general_info_to_html(pkginfo))
89 return s
90
91def archs_to_html(archs):
92 arch_string= '|'
93 for arch in config.ARCHLIST:
94 if arch in archs: 120 if arch in archs:
95 arch_icon = 'check.gif' 121 arch_string = '+'
96 alt = ": yes"
97 title = 'marked stable for %s' % arch
98 elif '~%s' % arch in archs: 122 elif '~%s' % arch in archs:
99 arch_icon = 'bug.gif' 123 arch_string = '~'
100 alt = ': testing'
101 title = 'undergoing testing for %s' % arch
102 else: 124 else:
103 arch_icon = 'no.gif'
104 alt = ': no'
105 title = 'not available for %s' % arch
106
107 arch_string = (' %s %s <img src="%simages/archs/%s" '
108 'alt="%s" title="%s"> |' % (
109 arch_string, 125 arch_string = '-'
110 arch, 126 if arch_string != '-' and masked:
111 config.FEHOME, 127 arch_string = 'M' + arch_string
112 arch_icon, 128 row_data.append('\t<td class="archcell" arch="%s">%s</td>'
113 alt, 129 % (arch_string, arch_string))
114 title)) 130 row_end = '</tr>'
115 131 rows.append('\n\t'.join([row_start] + row_data + [row_end]))
116 return arch_string 132 table_end = '</table>'
117 133 return '\n\t'.join([table_begin] + [header_row] + rows + [table_end])
134
118def ebuild_to_html(ebinfo,new=0): 135def ebuild_to_html(ebinfo, new=0, show_bugs=0):
119 try:
120 archs = ebinfo['arch'].split()
121 except KeyError:
122 archs = ()
123 arch_string = archs_to_html(archs)
124 changelogurl = ('http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/'
125 '%s/%s/ChangeLog' % (ebinfo['category'],ebinfo['name']))
126
127 if new: 136 if new:
128 new_string = """ &nbsp;&nbsp;<span class="new">new!</span> """ 137 new_string = """ &nbsp;&nbsp;<span class="new">new!</span> """
129 else: 138 else:
130 new_string = "" 139 new_string = ""
131 140
132 return ('<table class="ebuild">\n' 141 table_begin = '<table class="ebuild">'
133 '<tr><td colspan="4" class="fields">' 142 name_and_date = ('<tr><td class="fields">'
134 '<a href="%spackages/?category=%s;name=%s">%s</a> %s%s<br>' 143 '<a href="%spackages/?category=%s;name=%s">%s</a> %s%s<br>'
135 '<span class="time">%s</span><br>\n' 144 '<span class="time">%s</span>'
136 '</td></tr>\n' 145 '</td></tr>' % (config.FEHOME, quote(ebinfo['category']),
137 '<tr><td class="item" align="center" colspan="1">' 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">'
138 '<img alt="" src="%simages/%s.png">' 153 '<img alt="" align="right" src="%simages/%s.png">'
139 '<td class="item" valign="top" colspan="3">'
140 '<p><b>Description:</b> %s</p>\n' 154 '<p><b>Description:</b> %s</p>'
141 '<p><b>Changes:</b><br>\n' 155 '<p><b>Changes:</b><br>'
142 '%s</p></td></tr>\n' 156 '%s</p></td></tr>' % (
143 '<tr><td colspan="4" class="item"><p class="archs">%s</p>\n'
144 '</td></tr>\n'
145 '%s</table>\n'
146 '<br>\n' % (config.FEHOME,
147 quote(ebinfo['category']),
148 quote(ebinfo['name']),
149 ebinfo['name'],
150 ebinfo['version'],
151 new_string,
152 ebinfo['time'].localtime().strftime("%c %Z"),
153 config.FEHOME, 157 config.FEHOME,
154 ebinfo['category'], 158 ebinfo['category'],
155 escape(ebinfo['description']), 159 escape(ebinfo['description']),
156 changelog_to_html(ebinfo['changelog']), 160 changelog_to_html(ebinfo['changelog'])))
157 arch_string,
158 general_info_to_html(ebinfo)))
159 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
160def general_info_to_html(pkg): 179def general_info_to_html(pkg):
161 """This actually will (should) take either a package or ebuild dict 180 """This actually will (should) take either a package or ebuild dict
162 as an argument""" 181 as an argument"""
163 182
164 changelogurl = ('http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/' 183 changelogurl = ('http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/'
165 '%s/%s/ChangeLog' % (pkg['category'],pkg['name'])) 184 '%s/%s/ChangeLog' % (pkg['category'],pkg['name']))
166 return ('<tr><th class="category">Category</th>' 185 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']))
167 '<td class="homepage" rowspan="2">%s</td>' 190 homepage = ('<td class="homepage" rowspan="2">%s</td>'
168 #'<td class="homepage" rowspan="2"><a href="%s">Home Page</a></td>'
169 '<th class="license">License</th>'
170 '<td class="changelog" rowspan="2"><a href="%s">ChangeLog</a><td>\n'
171 '<tr><td class="category"><a href="%spackages/?category=%s">'
172 '%s</a></td>'
173 #'<td class="homepage"><a href="%s">Home Page</a></td>'
174 '<td class="license">%s</td></tr>\n'
175 % ( homepage_to_html(pkg['homepage']), 191 % homepage_to_html(pkg['homepage']))
176 changelogurl, 192 license = ('<td class="license">%s</td>'
177 config.FEHOME,
178 pkg['category'],
179 pkg['category'],
180 #pkg['homepage'],
181 license_to_html(pkg['license']))) 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>'])
182 209
210def 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
183def get_most_recent(db,max=config.MAXPERPAGE,arch="",branch=""): 231def get_most_recent(db,max=config.MAXPERPAGE,arch="",branch=""):
184 c = db.cursor() 232 c = db.cursor()
185 extra = '' 233 extra = ''
186 if arch: 234 if arch:
187 stable_extra = ('ebuild.arch REGEXP "^%s| %s" ' 235 stable_extra = ('ebuild.arch REGEXP "^%s| %s" '
219 """Return MAX_RECENT_RELEASES most recent releases for pkg. Returns and 267 """Return MAX_RECENT_RELEASES most recent releases for pkg. Returns and
220 ebuild-type dict""" 268 ebuild-type dict"""
221 c = db.cursor() 269 c = db.cursor()
222 query = """SELECT category,name,version,when_found,NULL,changelog,arch ,NULL,NULL 270 query = """SELECT category,name,version,when_found,NULL,changelog,arch ,NULL,NULL
223 FROM ebuild WHERE name="%s" AND 271 FROM ebuild WHERE name="%s" AND
224 category="%s" ORDER BY when_found DESC LIMIT %s 272 category="%s" ORDER BY version DESC LIMIT %s
225 """ % (pkg['name'],pkg['category'],max) 273 """ % (pkg['name'],pkg['category'],max)
226 c.execute(query) 274 c.execute(query)
227 results = c.fetchall() 275 results = c.fetchall()
228 #print results 276 #print results
229 return [ query_to_dict(i) for i in results ] 277 return [ query_to_dict(i) for i in results ]
234 <rss version="0.92"> 282 <rss version="0.92">
235 <channel> 283 <channel>
236 <title>Fresh ebuilds %s</title> 284 <title>Fresh ebuilds %s</title>
237 <link>%s</link> 285 <link>%s</link>
238 <description>Latest ebuilds from the Gentoo Linux portage tree</description> 286 <description>Latest ebuilds from the Gentoo Linux portage tree</description>
287 <![CDATA[<link rel="stylesheet" href="%s" type="text/css" title="styled" />]]>
239 <webMaster>www@gentoo.org</webMaster> 288 <webMaster>www@gentoo.org</webMaster>
240 <managingEditor>marduk@gentoo.org</managingEditor> 289 <managingEditor>marduk@gentoo.org</managingEditor>
241 <pubDate>%s</pubDate>""" % (subtitle,config.FEHOME, 290 <pubDate>%s</pubDate>""" % (subtitle,config.FEHOME, config.STYLESHEET,
242 time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()))) 291 time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())))
243 292
244 for ebuild in ebuilds: 293 for ebuild in ebuilds:
245 if simple: 294 if simple:
246 description = escape(ebuild['description']) 295 description = escape(ebuild['description'])
270 try: 319 try:
271 if sys.argv[1] == '-g': 320 if sys.argv[1] == '-g':
272 ebuilddb.main() 321 ebuilddb.main()
273 except IndexError: 322 except IndexError:
274 pass 323 pass
275 324
276 db = ebuilddb.db_connect() 325 db = ebuilddb.db_connect()
277 branches = ('','stable','testing') 326 branches = ('','stable','testing')
278 for arch in [''] + config.ARCHLIST: 327 for arch in [''] + config.ARCHLIST:
279 for branch in branches: 328 for branch in branches:
280 fullpath = os.path.join(config.LOCALHOME,"archs",arch,branch,config.INDEX) 329 fullpath = os.path.join(config.LOCALHOME,"archs",arch,branch,config.INDEX)
304 pkgfile.write(ebuild_html) 353 pkgfile.write(ebuild_html)
305 pkgfile.close() 354 pkgfile.close()
306 ebuildfilename = "%s/%s/%s/%s-%s.ebuild" % (ebuilddb.config.PORTAGE_DIR, 355 ebuildfilename = "%s/%s/%s/%s-%s.ebuild" % (ebuilddb.config.PORTAGE_DIR,
307 ebuild['category'],ebuild['name'],ebuild['name'], 356 ebuild['category'],ebuild['name'],ebuild['name'],
308 ebuild['version']) 357 ebuild['version'])
309 os.system('touch -r %s %s || touch -d "today -1 year" %s' % (ebuildfilename,pkgfilename,pkgfilename)) 358 os.system('touch -r %s %s || touch -d "today -1 year" %s'
359 % (ebuildfilename,pkgfilename,pkgfilename))
310 360
311 try: 361 try:
312 index.write('%s<br>\n\n\n' % (ebuild_html)) 362 index.write('%s\n\n' % (ebuild_html))
313 except IOError: 363 except IOError:
314 pass 364 pass
315 #index.write('<!--#include virtual="%s/ebuilds/%s-%s.html" --><br>\n\n\n'
316 # % (config.WEBBASE,ebuild['name'],ebuild['version']))
317 #index.write("""<hr class="seperator">\n""")
318
319 index.write("""</table>\n""") 365 index.write("""</table>\n""")
320 index.close() 366 index.close()
321 367
322 subtitle = ' %s %s' % (arch,branch) 368 subtitle = ' %s %s' % (arch,branch)
323 rss = open(os.path.join(config.LOCALHOME,"archs",arch,branch,config.RSS),'w') 369 rss = open(os.path.join(config.LOCALHOME,"archs",arch,branch,config.RSS),'w')

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

  ViewVC Help
Powered by ViewVC 1.1.20