/[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.7 Revision 1.8
1#!/usr/bin/python -OO 1#!/usr/bin/python -O
2"""These functions mainly take ebuild info (grabbed from the database and 2"""These functions mainly take ebuild info (grabbed from the database and
3 convert it to HTML. See the "main" function at the bottom.""" 3 convert it to HTML. See the "main" function at the bottom."""
4 4
5__revision__ = "$Revision: 1.7 $" 5__revision__ = "$Revision: 1.8 $"
6# $Source: /var/cvsroot/gentoo/src/packages/gentoo.py,v $ 6# $Source: /var/cvsroot/gentoo/src/packages/gentoo.py,v $
7 7
8import config 8import config
9import os 9import os
10import time 10import time
14import bugs 14import bugs
15import changelogs 15import changelogs
16from cgi import escape 16from cgi import escape
17from urllib import quote 17from urllib import quote
18 18
19# import portage, but temporarily redirect stderr 19endversion={"pre":-2,"p":0,"alpha":-4,"beta":-3,"rc":-1}
20if 'portage' not in dir(): 20# as there's no reliable way to set {}.keys() order
21 null = open('/dev/null', 'w') 21# netversion_keys will be used instead of endversion.keys
22 tmp = sys.stderr 22# to have fixed search order, so that "pre" is checked
23 sys.stderr = null 23# before "p"
24 sys.path = ["/usr/lib/portage/pym"]+sys.path 24endversion_keys = ["pre", "p", "alpha", "beta", "rc"]
25 import portage
26 sys.stderr = tmp
27 sys.path = sys.path[1:]
28 25
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
36def is_new(db, ebuild): 26def is_new(db, ebuild):
37 """Check for newness. An ebuild is considered new if it is the 27 """Check for newness."""
38 only ebuild with that category/name in ebuild and it has no prevarch"""
39 28
40 c = db.cursor() 29 c = db.cursor()
41 query = ('SELECT prevarch FROM ebuild WHERE category="%s" AND name="%s"' 30 query = ('SELECT new FROM package WHERE category="%s" AND name="%s"'
42 % (ebuild['category'], ebuild['name'])) 31 % (ebuild['category'], ebuild['name']))
43 c.execute(query) 32 c.execute(query)
44 results = c.fetchall() 33 results = c.fetchall()
45 if len(results) == 1 and results[0][0] is None: 34 if len(results) == 1 and results[0][0]:
46 return 1 35 return 1
47 return 0 36 return 0
48 37
49def changelog_to_html(changelog): 38def changelog_to_html(changelog):
50 """HTML-ize a changelog entry""" 39 """HTML-ize a changelog entry"""
75 64
76def license_to_html(license): 65def license_to_html(license):
77 """Create link to license[s]""" 66 """Create link to license[s]"""
78 if not license.strip(): return "?" 67 if not license.strip(): return "?"
79 license = license.replace('|',' ') 68 license = license.replace('|',' ')
69 license = license.replace('(', '')
70 license = license.replace(')', '')
80 pieces = license.split() 71 pieces = license.split()
81 html = ['<a href="http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/' 72 html = ['<a href="http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/'
82 'licenses/%s">%s</a>' % (piece, piece) for piece in pieces] 73 'licenses/%s">%s</a>' % (piece, piece) for piece in pieces]
83 return '<br>\n'.join(html) 74 return '<br>\n'.join(html)
84 75
85def package_to_html(pkginfo, db): 76def package_to_html(pkginfo, db, full=False):
86 """This function needs a database (db) connection because it performs a 77 """This function needs a database (db) connection because it performs a
87 query_to_dict on the package""" 78 query_to_dict on the package"""
88 79
89 table_begin = '<table class="ebuild">' 80 table_begin = '<table class="ebuild">'
90 name = '<tr><td class="fields">%s</td></tr>' % pkginfo['name'] 81 name = '<tr><td class="fields">%s</td></tr>' % pkginfo['name']
82 if full:
83 image = ('<img class="pkgimg"alt="" src="%s/%s/%s.jpg" align="right">' %
84 (config.ICONS, pkginfo['category'], pkginfo['name'])
85 )
86 else:
87 image = ''
91 description = ('<tr><td class="item">' 88 description = ('<tr><td class="item">'
92 '<img align="right" alt="" src="%s/%s.png">'
93 '<b>Description: </b>%s</td></tr>' % (config.ICONS, 89 '%s<b>Description: </b>%s</td></tr>'
94 pkginfo['category'], escape(pkginfo['description']))) 90 % (image, escape(pkginfo['description']))
91 )
95 ebuilds = get_recent_releases(pkginfo, db) 92 ebuilds = get_recent_releases(pkginfo, db)
96 releases = '<tr><td>%s</td></tr>' % archs_to_html(ebuilds, 'Releases') 93 releases = '<tr><td>%s</td></tr>' % archs_to_html(ebuilds, 'Releases')
97 #bug_string = ('<br><h3>Related bugs:</h3>\n%s' 94 #bug_string = ('<br><h3>Related bugs:</h3>\n%s'
98 # % bugs_to_html(pkginfo['name'])) 95 # % bugs_to_html(pkginfo['name']))
99 general = '<tr><td>%s</td></tr>' % general_info_to_html(pkginfo) 96 general = '<tr><td>%s</td></tr>' % general_info_to_html(pkginfo)
112 ) 109 )
113 rows = [] 110 rows = []
114 ebuilds.sort(cmp_ebuilds) 111 ebuilds.sort(cmp_ebuilds)
115 ebuilds.reverse() 112 ebuilds.reverse()
116 for ebuild in ebuilds: 113 for ebuild in ebuilds:
117 masked = is_masked(ebuild)
118 archs = ebuild['arch'].split() 114 archs = ebuild['arch'].split()
119 row_start = ('<tr>\n\t<th class="releases"><a href="%sebuilds/?%s-%s"' 115 row_start = ('<tr>\n\t<th class="releases"><a href="%sebuilds/?%s-%s"'
120 ' title="%s">%s</a></th>\n' % (config.FEHOME, 116 ' title="%s">%s</a></th>\n' % (config.FEHOME,
121 ebuild['name'], ebuild['version'], ebuild['time'], 117 ebuild['name'], ebuild['version'], ebuild['time'],
122 ebuild['version'])) 118 ebuild['version']))
126 arch_string = '+' 122 arch_string = '+'
127 elif '~%s' % arch in archs: 123 elif '~%s' % arch in archs:
128 arch_string = '~' 124 arch_string = '~'
129 else: 125 else:
130 arch_string = '-' 126 arch_string = '-'
131 if arch_string != '-' and masked: 127 if arch_string != '-' and ebuild['masked']:
132 arch_string = 'M' + arch_string 128 arch_string = 'M' + arch_string
133 row_data.append('\t<td class="archcell" arch="%s">%s</td>' 129 row_data.append('\t<td class="archcell" arch="%s">%s</td>'
134 % (arch_string, arch_string)) 130 % (arch_string, arch_string))
135 row_end = '</tr>' 131 row_end = '</tr>'
136 rows.append('\n\t'.join([row_start] + row_data + [row_end])) 132 rows.append('\n\t'.join([row_start] + row_data + [row_end]))
137 table_end = '</table>' 133 table_end = '</table>'
138 return '\n\t'.join([table_begin] + [header_row] + rows + [table_end]) 134 return '\n\t'.join([table_begin] + [header_row] + rows + [table_end])
139 135
140def ebuild_to_html(ebinfo, new=0, show_bugs=0): 136def ebuild_to_html(ebinfo, new=0, show_bugs=0, full = False):
141 """Convert ebuild (dict) to html, if new, print out a "this is new" notice 137 """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 138 if show_bugs, show bugs for this particular ebuild (requires access to
143 bugzilla""" 139 bugzilla"""
144 if new: 140 if new:
145 new_string = """ &nbsp;&nbsp;<span class="new">new!</span> """ 141 new_string = """ &nbsp;&nbsp;<span class="new">new!</span> """
155 ebinfo['name'], 151 ebinfo['name'],
156 ebinfo['version'], 152 ebinfo['version'],
157 new_string, 153 new_string,
158 ebinfo['time'].localtime().strftime("%c %Z"))) 154 ebinfo['time'].localtime().strftime("%c %Z")))
159 155
156 if full:
157 image = ('<img class="pkgimg" alt="" src="%s/%s/%s.jpg" align="right">' %
158 (config.ICONS, ebinfo['category'], ebinfo['name'])
159 )
160 else:
161 image = ''
160 desc_and_changes = ('<tr><td class="item" valign="top">' 162 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>Description:</b> %s %s</p>'
163 '<p><b>Changes:</b><br>' 164 '<p><b>Changes:</b><br>'
164 '%s</p></td></tr>' % ( 165 '%s</p></td></tr>' % (
165 config.FEHOME,
166 ebinfo['category'],
167 escape(ebinfo['description']), 166 escape(ebinfo['description']),
167 image,
168 changelog_to_html(ebinfo['changelog']))) 168 changelog_to_html(ebinfo['changelog'])))
169 169
170 archs = '<tr><td>%s</td></tr>' % archs_to_html([ebinfo]) 170 archs = '<tr><td>%s</td></tr>' % archs_to_html([ebinfo])
171 general = '<tr><td>%s</td></tr>' % general_info_to_html(ebinfo) 171 general = '<tr><td>%s</td></tr>' % general_info_to_html(ebinfo)
172 table_end = '</table>' 172 table_end = '</table>'
173 173
174 if 1 == 1:
175 bug_string = '' 174 bug_string = ''
176 else: 175 if show_bugs:
176 bug_string = bugs_to_html(ebinfo['name'])
177 if bug_string:
177 bug_string = '<br><h3>Related bugs:</h3>%s' \ 178 bug_string = '<br><h3 class="bugs">Related bugs:</h3>%s' \
178 % bugs_to_html(ebinfo['name']) 179 % bug_string
179 180
180 return '\n\t'.join([table_begin, 181 return '\n\t'.join([table_begin,
181 name_and_date, 182 name_and_date,
182 desc_and_changes, 183 desc_and_changes,
183 archs, 184 archs,
186 bug_string]) 187 bug_string])
187 188
188def general_info_to_html(pkg): 189def general_info_to_html(pkg):
189 """This actually will (should) take either a package or ebuild dict 190 """This actually will (should) take either a package or ebuild dict
190 as an argument""" 191 as an argument"""
192
193 import forums
191 194
192 changelogurl = ('http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/' 195 changelogurl = ('http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/'
193 '%s/%s/ChangeLog' % (pkg['category'],pkg['name'])) 196 '%s/%s/ChangeLog' % (pkg['category'],pkg['name']))
194 cat_header = '<th class="category">Category</th>' 197 cat_header = '<th class="category">Category</th>'
195 license_header = '<th class="license">License</th>' 198 license_header = '<th class="license">License</th>'
202 % license_to_html(pkg['license'])) 205 % license_to_html(pkg['license']))
203 changelog = ('<td class="changelog" rowspan="2">' 206 changelog = ('<td class="changelog" rowspan="2">'
204 '<a href="%s">ChangeLog</a></td>' % changelogurl) 207 '<a href="%s">ChangeLog</a></td>' % changelogurl)
205 similar = ('<td class="similar" rowspan="2">' 208 similar = ('<td class="similar" rowspan="2">'
206 '%s</td>' % create_similar_pkgs_link(pkg)) 209 '%s</td>' % create_similar_pkgs_link(pkg))
210 related_bugs = ('<td class="related_bugs" rowspan="2">'
211 '%s</td>' % create_related_bugs_link(pkg))
212 forums = ('<td class="forums" rowspan="2">'
213 '%s</td>' % forums.create_forums_link(pkg))
207 214
208 return '\n\t'.join(['<table class="general_info">', 215 return '\n\t'.join(['<table class="general_info">',
209 '<tr>', 216 '<tr>',
210 cat_header, 217 cat_header,
211 homepage, 218 homepage,
212 license_header, 219 license_header,
213 changelog, 220 changelog,
214 similar, 221 similar,
222 related_bugs,
223 forums,
215 '</tr>', 224 '</tr>',
216 '<tr>', 225 '<tr>',
217 category, 226 category,
218 license, 227 license,
219 '</tr>', 228 '</tr>',
238 words = words[:config.SIMILAR_MAX_WORDS] + [pkg['name']] 247 words = words[:config.SIMILAR_MAX_WORDS] + [pkg['name']]
239 #query = ['[[:<:]]%s[[:>:]].*' % word for word in words] 248 #query = ['[[:<:]]%s[[:>:]].*' % word for word in words]
240 query = ['[[:<:]]%s.*' % word for word in words] 249 query = ['[[:<:]]%s.*' % word for word in words]
241 query = '(%s){%s,}' % ('|'.join(query), config.SIMILAR_MIN_MATCHES) 250 query = '(%s){%s,}' % ('|'.join(query), config.SIMILAR_MIN_MATCHES)
242 url = '%ssearch/?sstring=%s' % (config.FEHOME, escape(query)) 251 url = '%ssearch/?sstring=%s' % (config.FEHOME, escape(query))
243 return '<a href="%s">Similar Packages</a>' % url 252 return '<a href="%s">Similar</a>' % url
244 253
254def create_related_bugs_link(pkg):
255 """Create a link to related bugs"""
256
257 url = ('http://bugs.gentoo.org/buglist.cgi?query_format='
258 '&amp;short_desc_type=allwords'
259 '&amp;short_desc=%s'
260 '&amp;bug_status=UNCONFIRMED'
261 '&amp;bug_status=NEW'
262 '&amp;bug_status=ASSIGNED'
263 '&amp;bug_status=REOPENED'
264 % escape(pkg['name']))
265
266 return '<a title="bugs.gentoo.org" href="%s">Bugs</a>' % url
267
245def bugs_to_html(package): 268def bugs_to_html(package):
246 """Given package name (no version #s), return html text of bugs as 269 """Given package name (no version #s), return html text of bugs as
247 reported by bugzilla""" 270 reported by bugzilla"""
248 # Right now we have an issue with the bugzilla site. New interface 271 # Right now we have an issue with the bugzilla site. New interface
249 # needs to be written, Bail out. 272 # needs to be written, Bail out.
250 return "" 273 #return ""
251 import urllib2 274 import urllib2
252 url = ('http://bugs.gentoo.org/buglist.cgi?query_format=' 275 url = ('http://bugs.gentoo.org/buglist.cgi?query_format='
253 '&short_desc_type=allwords&short_desc=%s' 276 '&amp;short_desc_type=allwords'
254 '&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED' 277 '&amp;short_desc=%s'
278 '&amp;bug_status=UNCONFIRMED'
279 '&amp;bug_status=NEW'
280 '&amp;bug_status=ASSIGNED'
255 '&bug_status=REOPENED' 281 '&amp;bug_status=REOPENED'
256 '&ctype=csv' % package) 282 '&amp;ctype=csv'
283 % package)
257 fp = urllib2.urlopen(url) 284 fp = urllib2.urlopen(url)
258 factory = bugs.BugFactory() 285 factory = bugs.BugFactory()
259 package_bugs = factory.fromCSV(fp) 286 package_bugs = factory.fromCSV(fp)
260 if package_bugs: 287 if package_bugs:
261 writer = bugs.HTMLWriter(package_bugs, 'bugs.gentoo.org') 288 writer = bugs.HTMLWriter(package_bugs, 'bugs.gentoo.org')
262 return str(writer) 289 return str(writer)
263 else: 290 else:
264 return "None" 291 return ""
265 292
266def get_most_recent(db, max=config.MAXPERPAGE, arch="", branch=""): 293def get_most_recent(db, max=config.MAXPERPAGE, arch="", branch="", new = False):
267 c = db.cursor() 294 c = db.cursor()
268 extra = '' 295 extra = ''
269 if arch: 296 if arch:
270 stable_extra = ('ebuild.arch REGEXP "^%s| %s" ' 297 stable_extra = ('ebuild.arch REGEXP "^%s| %s" '
271 ' AND ebuild.prevarch NOT REGEXP"^%s| %s"' 298 ' AND ebuild.prevarch NOT REGEXP"^%s| %s"'
277 extra = ' AND (%s) ' % stable_extra 304 extra = ' AND (%s) ' % stable_extra
278 elif branch == 'testing': 305 elif branch == 'testing':
279 extra = ' AND (%s) ' % testing_extra 306 extra = ' AND (%s) ' % testing_extra
280 else: 307 else:
281 extra = ' AND ((%s) OR (%s)) ' % (stable_extra, testing_extra) 308 extra = ' AND ((%s) OR (%s)) ' % (stable_extra, testing_extra)
309
310 if new:
311 extra = ('%s AND package.new=1 ' % extra)
312
282 query = """SELECT ebuild.category,ebuild.name,version,when_found,description, 313 query = """SELECT ebuild.category,ebuild.name,version,when_found,description,
283 changelog,arch,homepage,license FROM ebuild,package WHERE ebuild.name=\ 314 changelog,arch,homepage,license,is_masked FROM ebuild,package WHERE ebuild.name=\
284 package.name AND ebuild.category=package.category %s ORDER by when_found DESC \ 315 package.name AND ebuild.category=package.category %s ORDER by when_found DESC \
285 LIMIT %s""" % (extra,max) 316 LIMIT %s""" % (extra,max)
286 c.execute(query) 317 c.execute(query)
287 results = c.fetchall() 318 results = c.fetchall()
288 return results 319 return results
289 320
321def get_most_recent_bumps(db, max=config.MAXPERPAGE):
322 """Return most recent version bumps (pkgs with no prevarch)"""
323 c = db.cursor()
324 query = ('SELECT ebuild.category, ebuild.name, version, when_found, '
325 'description, changelog, arch, homepage, license,is_masked FROM ebuild, package '
326 'WHERE ebuild.name=package.name AND ebuild.category=package.category '
327 'AND prevarch="" AND version NOT LIKE "%%-r_" AND version NOT LIKE '
328 '"%%-r__" AND NOT new ORDER by when_found '
329 'DESC LIMIT %s' % max)
330
331 c.execute(query)
332 results = c.fetchall()
333 return results
334
290def query_to_dict(d): 335def query_to_dict(d):
291 """Convert a SQL query to a dict""" 336 """Convert a SQL query to a dict"""
292 einfo = {} 337 einfo = {}
293 keys = ('category', 'name', 'version', 'time', 'description', 'changelog', 338 keys = ('category', 'name', 'version', 'time', 'description', 'changelog',
294 'arch', 'homepage', 'license') 339 'arch', 'homepage', 'license', 'masked')
295 for i in range(len(keys)): 340 for i in range(len(keys)):
296 try: 341 try:
297 einfo[keys[i]] = d[i] 342 einfo[keys[i]] = d[i]
298 except IndexError: 343 except IndexError:
299 continue 344 continue
302def get_recent_releases(pkg, db, max=config.MAX_RECENT_RELEASES): 347def get_recent_releases(pkg, db, max=config.MAX_RECENT_RELEASES):
303 """Return MAX_RECENT_RELEASES most recent releases for pkg. Returns and 348 """Return MAX_RECENT_RELEASES most recent releases for pkg. Returns and
304 ebuild-type dict""" 349 ebuild-type dict"""
305 c = db.cursor() 350 c = db.cursor()
306 query = ('SELECT category,name,version,when_found,NULL,changelog,arch ,' 351 query = ('SELECT category,name,version,when_found,NULL,changelog,arch ,'
307 'NULL,NULL FROM ebuild WHERE name="%s" AND category="%s" ORDER BY ' 352 'NULL,NULL,is_masked FROM ebuild WHERE name="%s" AND category="%s" ORDER BY '
308 'version DESC LIMIT %s' % (pkg['name'],pkg['category'],max)) 353 'version DESC LIMIT %s' % (pkg['name'],pkg['category'],max))
309 c.execute(query) 354 c.execute(query)
310 results = c.fetchall() 355 results = c.fetchall()
311 #print results 356 #print results
312 return [ query_to_dict(i) for i in results ] 357 return [ query_to_dict(i) for i in results ]
313 358
314def cmp_ebuilds(a, b): 359def cmp_ebuilds(a, b):
315 """Compare two ebuilds""" 360 """Compare two ebuilds"""
316 fields_a = portage.pkgsplit('%s-%s' % (a['name'], a['version'])) 361 fields_a = pkgsplit('%s-%s' % (a['name'], a['version']))
317 fields_b = portage.pkgsplit('%s-%s' % (b['name'], b['version'])) 362 fields_b = pkgsplit('%s-%s' % (b['name'], b['version']))
318 return portage.pkgcmp(fields_a, fields_b) 363 return pkgcmp(fields_a, fields_b)
364
365pkgcache={}
366
367def pkgsplit(mypkg,silent=1):
368 try:
369 if not pkgcache[mypkg]:
370 return None
371 return pkgcache[mypkg][:]
372 except KeyError:
373 pass
374 myparts=string.split(mypkg,'-')
375 if len(myparts)<2:
376 if not silent:
377 print "!!! Name error in",mypkg+": missing a version or name part."
378 pkgcache[mypkg]=None
379 return None
380 for x in myparts:
381 if len(x)==0:
382 if not silent:
383 print "!!! Name error in",mypkg+": empty \"-\" part."
384 pkgcache[mypkg]=None
385 return None
386 #verify rev
387 revok=0
388 myrev=myparts[-1]
389 if len(myrev) and myrev[0]=="r":
390 try:
391 int(myrev[1:])
392 revok=1
393 except SystemExit, e:
394 raise
395 except:
396 pass
397 if revok:
398 if ververify(myparts[-2]):
399 if len(myparts)==2:
400 pkgcache[mypkg]=None
401 return None
402 else:
403 for x in myparts[:-2]:
404 if ververify(x):
405 pkgcache[mypkg]=None
406 return None
407 #names can't have versiony looking parts
408 myval=[string.join(myparts[:-2],"-"),myparts[-2],myparts[-1]]
409 pkgcache[mypkg]=myval
410 return myval
411 else:
412 pkgcache[mypkg]=None
413 return None
414
415 elif ververify(myparts[-1],silent=silent):
416 if len(myparts)==1:
417 if not silent:
418 print "!!! Name error in",mypkg+": missing name part."
419 pkgcache[mypkg]=None
420 return None
421 else:
422 for x in myparts[:-1]:
423 if ververify(x):
424 if not silent:
425 print "!!! Name error in",mypkg+": multiple version parts."
426 pkgcache[mypkg]=None
427 return None
428 myval=[string.join(myparts[:-1],"-"),myparts[-1],"r0"]
429 pkgcache[mypkg]=myval[:]
430 return myval
431 else:
432 pkgcache[mypkg]=None
433 return None
434
435vercache={}
436def ververify(myorigval,silent=1):
437 try:
438 return vercache[myorigval]
439 except KeyError:
440 pass
441 if len(myorigval)==0:
442 if not silent:
443 print "!!! Name error: package contains empty \"-\" part."
444 return 0
445 myval=string.split(myorigval,'.')
446 if len(myval)==0:
447 if not silent:
448 print "!!! Name error: empty version string."
449 vercache[myorigval]=0
450 return 0
451 #all but the last version must be a numeric
452 for x in myval[:-1]:
453 if not len(x):
454 if not silent:
455 print "!!! Name error in",myorigval+": two decimal points in a row"
456 vercache[myorigval]=0
457 return 0
458 try:
459 foo=int(x)
460 except SystemExit, e:
461 raise
462 except:
463 if not silent:
464 print "!!! Name error in",myorigval+": \""+x+"\" is not a valid version component."
465 vercache[myorigval]=0
466 return 0
467 if not len(myval[-1]):
468 if not silent:
469 print "!!! Name error in",myorigval+": two decimal points in a row"
470 vercache[myorigval]=0
471 return 0
472 try:
473 foo=int(myval[-1])
474 vercache[myorigval]=1
475 return 1
476 except SystemExit, e:
477 raise
478 except:
479 pass
480 #ok, our last component is not a plain number or blank, let's continue
481 if myval[-1][-1] in string.lowercase:
482 try:
483 foo=int(myval[-1][:-1])
484 vercache[myorigval]=1
485 return 1
486 # 1a, 2.0b, etc.
487 except SystemExit, e:
488 raise
489 except:
490 pass
491 #ok, maybe we have a 1_alpha or 1_beta2; let's see
492 #ep="endpart"
493 ep=string.split(myval[-1],"_")
494 if len(ep)!=2:
495 if not silent:
496 print "!!! Name error in",myorigval
497 vercache[myorigval]=0
498 return 0
499 try:
500 foo=int(ep[0][-1])
501 chk=ep[0]
502 except SystemExit, e:
503 raise
504 except:
505 # because it's ok last char is not numeric. example: foo-1.0.0a_pre1
506 chk=ep[0][:-1]
507
508 try:
509 foo=int(chk)
510 except SystemExit, e:
511 raise
512 except:
513 #this needs to be numeric or numeric+single letter,
514 #i.e. the "1" in "1_alpha" or "1a_alpha"
515 if not silent:
516 print "!!! Name error in",myorigval+": characters before _ must be numeric or numeric+single letter"
517 vercache[myorigval]=0
518 return 0
519 for mye in endversion_keys:
520 if ep[1][0:len(mye)]==mye:
521 if len(mye)==len(ep[1]):
522 #no trailing numeric; ok
523 vercache[myorigval]=1
524 return 1
525 else:
526 try:
527 foo=int(ep[1][len(mye):])
528 vercache[myorigval]=1
529 return 1
530 except SystemExit, e:
531 raise
532 except:
533 #if no endversions work, *then* we return 0
534 pass
535 if not silent:
536 print "!!! Name error in",myorigval
537 vercache[myorigval]=0
538 return 0
539
540def relparse(myver):
541 "converts last version part into three components"
542 number=0
543 suffix=0
544 endtype=0
545 endnumber=0
546
547 mynewver=string.split(myver,"_")
548 myver=mynewver[0]
549
550 #normal number or number with letter at end
551 divider=len(myver)-1
552 if myver[divider:] not in "1234567890":
553 #letter at end
554 suffix=ord(myver[divider:])
555 number=string.atof(myver[0:divider])
556 else:
557 number=string.atof(myver)
558
559 if len(mynewver)==2:
560 #an endversion
561 for x in endversion_keys:
562 elen=len(x)
563 if mynewver[1][:elen] == x:
564 match=1
565 endtype=endversion[x]
566 try:
567 endnumber=string.atof(mynewver[1][elen:])
568 except SystemExit, e:
569 raise
570 except:
571 endnumber=0
572 break
573 return [number,suffix,endtype,endnumber]
574
575# vercmp:
576# ripped from portage.py to prevent having to import
577vcmpcache={}
578def vercmp(val1,val2):
579 if val1==val2:
580 #quick short-circuit
581 return 0
582 valkey=val1+" "+val2
583 try:
584 return vcmpcache[valkey]
585 try:
586 return -vcmpcache[val2+" "+val1]
587 except KeyError:
588 pass
589 except KeyError:
590 pass
591
592 # consider 1_p2 vc 1.1
593 # after expansion will become (1_p2,0) vc (1,1)
594 # then 1_p2 is compared with 1 before 0 is compared with 1
595 # to solve the bug we need to convert it to (1,0_p2)
596 # by splitting _prepart part and adding it back _after_expansion
597 val1_prepart = val2_prepart = ''
598 if val1.count('_'):
599 val1, val1_prepart = val1.split('_', 1)
600 if val2.count('_'):
601 val2, val2_prepart = val2.split('_', 1)
602
603 # replace '-' by '.'
604 # FIXME: Is it needed? can val1/2 contain '-'?
605 val1=string.split(val1,'-')
606 if len(val1)==2:
607 val1[0]=val1[0]+"."+val1[1]
608 val2=string.split(val2,'-')
609 if len(val2)==2:
610 val2[0]=val2[0]+"."+val2[1]
611
612 val1=string.split(val1[0],'.')
613 val2=string.split(val2[0],'.')
614
615 #add back decimal point so that .03 does not become "3" !
616 for x in range(1,len(val1)):
617 if val1[x][0] == '0' :
618 val1[x]='.' + val1[x]
619 for x in range(1,len(val2)):
620 if val2[x][0] == '0' :
621 val2[x]='.' + val2[x]
622
623 # extend version numbers
624 if len(val2)<len(val1):
625 val2.extend(["0"]*(len(val1)-len(val2)))
626 elif len(val1)<len(val2):
627 val1.extend(["0"]*(len(val2)-len(val1)))
628
629 # add back _prepart tails
630 if val1_prepart:
631 val1[-1] += '_' + val1_prepart
632 if val2_prepart:
633 val2[-1] += '_' + val2_prepart
634 #The above code will extend version numbers out so they
635 #have the same number of digits.
636 for x in range(0,len(val1)):
637 cmp1=relparse(val1[x])
638 cmp2=relparse(val2[x])
639 for y in range(0,4):
640 myret=cmp1[y]-cmp2[y]
641 if myret != 0:
642 vcmpcache[valkey]=myret
643 return myret
644 vcmpcache[valkey]=0
645 return 0
646
647# pkgcmp:
648# ripped from portage.py to prevent having to import
649def pkgcmp(pkg1,pkg2):
650 """if returnval is less than zero, then pkg2 is newer than pkg1, zero if equal and positive if older."""
651 if pkg1[0] != pkg2[0]:
652 return None
653 mycmp=vercmp(pkg1[1],pkg2[1])
654 if mycmp>0:
655 return 1
656 if mycmp<0:
657 return -1
658 r1=int(pkg1[2][1:])
659 r2=int(pkg2[2][1:])
660 if r1>r2:
661 return 1
662 if r2>r1:
663 return -1
664 return 0
319 665
320def ebuilds_to_rss(fp, ebuilds, simple=False, subtitle=""): 666def ebuilds_to_rss(fp, ebuilds, simple=False, subtitle=""):
321 """write out ebuild info to RSS file (fp)""" 667 """write out ebuild info to RSS file (fp)"""
322 fp.write("""<?xml version="1.0" encoding="iso-8859-1"?> 668 fp.write("""<?xml version="1.0" encoding="iso-8859-1"?>
323 <rss version="0.92"> 669 <rss version="0.92">
324 <channel> 670 <channel>
325 <title>packages.gentoo.org [ %s ]</title> 671 <title>packages.gentoo.org [ %s ]</title>
326 <link>%s</link> 672 <link>%s</link>
327 <description>Latest ebuilds from the Gentoo Linux portage tree</description> 673 <description>Latest ebuilds from the Gentoo Linux portage tree</description>
328 <![CDATA[<link rel="stylesheet" href="%s" type="text/css" title="styled" />]]>
329 <webMaster>www@gentoo.org</webMaster> 674 <webMaster>www@gentoo.org</webMaster>
330 <managingEditor>marduk@gentoo.org</managingEditor> 675 <managingEditor>marduk@gentoo.org</managingEditor>
331 <pubDate>%s</pubDate>""" % (subtitle,config.FEHOME, config.STYLESHEET, 676 <pubDate>%s</pubDate>""" % (subtitle,config.FEHOME,
332 time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()))) 677 time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())))
333 678
334 for ebuild in ebuilds: 679 for ebuild in ebuilds:
335 if simple: 680 if simple:
336 description = escape(ebuild['description']) 681 description = escape(ebuild['description'])
337 else: 682 else:
338 description = '\n<![CDATA[\n%s\n]]>' % ebuild_to_html(ebuild) 683 description = ('\n'
684 '<![CDATA[\n'
685 '<link rel="stylesheet" type="text/css" href="%s"></link>\n'
686 '%s\n]]>' % (config.STYLESHEET, ebuild_to_html(ebuild, full=True))
687 )
339 688
340 fp.write("""<item> 689 fp.write("""<item>
341 <title>%s %s</title> 690 <title>%s %s</title>
342 <link>%sebuilds/?%s-%s</link> 691 <link>%sebuilds/?%s-%s</link>
343 <description> 692 <description>
390 ebuilds = [ query_to_dict(i) for i in results ] 739 ebuilds = [ query_to_dict(i) for i in results ]
391 for ebuild in ebuilds: 740 for ebuild in ebuilds:
392 new = is_new(db, ebuild) 741 new = is_new(db, ebuild)
393 pkgfilename = "%s/%s-%s.html" % ( 742 pkgfilename = "%s/%s-%s.html" % (
394 config.EBUILD_FILES,ebuild['name'],ebuild['version']) 743 config.EBUILD_FILES,ebuild['name'],ebuild['version'])
395 ebuild_html = ebuild_to_html(ebuild, new) 744 ebuild_html = ebuild_to_html(ebuild, new, show_bugs = False)
396 if arch == '' and branch == '': 745 if arch == '' and branch == '':
397 pkgfile = open(pkgfilename,'w') 746 pkgfile = open(pkgfilename,'w')
398 pkgfile.write(ebuild_html) 747 pkgfile.write(ebuild_html)
399 pkgfile.close() 748 pkgfile.close()
400 ebuildfilename = "%s/%s/%s/%s-%s.ebuild" \ 749 ebuildfilename = "%s/%s/%s/%s-%s.ebuild" \

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8

  ViewVC Help
Powered by ViewVC 1.1.20