/[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.16.2.2 Revision 1.16.2.3
1#!/usr/bin/python -O 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.16.2.2 $" 5__revision__ = "$Revision: 1.16.2.3 $"
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
13import ebuilddb 13import ebuilddb
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 18from portage_versions import pkgcmp, pkgsplit
19endversion={"pre":-2,"p":0,"alpha":-4,"beta":-3,"rc":-1}
20# as there's no reliable way to set {}.keys() order
21# netversion_keys will be used instead of endversion.keys
22# to have fixed search order, so that "pre" is checked
23# before "p"
24endversion_keys = ["pre", "p", "alpha", "beta", "rc"]
25 19
26def is_new(db, ebuild): 20def is_new(db, ebuild):
27 """Check for newness.""" 21 """Check for newness."""
28 22
29 c = db.cursor() 23 c = db.cursor()
331 """Compare two ebuilds""" 325 """Compare two ebuilds"""
332 fields_a = pkgsplit('%s-%s' % (a['name'], a['version'])) 326 fields_a = pkgsplit('%s-%s' % (a['name'], a['version']))
333 fields_b = pkgsplit('%s-%s' % (b['name'], b['version'])) 327 fields_b = pkgsplit('%s-%s' % (b['name'], b['version']))
334 return pkgcmp(fields_a, fields_b) 328 return pkgcmp(fields_a, fields_b)
335 329
336pkgcache={}
337
338def pkgsplit(mypkg,silent=1):
339 try:
340 if not pkgcache[mypkg]:
341 return None
342 return pkgcache[mypkg][:]
343 except KeyError:
344 pass
345 myparts=string.split(mypkg,'-')
346 if len(myparts)<2:
347 if not silent:
348 print "!!! Name error in",mypkg+": missing a version or name part."
349 pkgcache[mypkg]=None
350 return None
351 for x in myparts:
352 if len(x)==0:
353 if not silent:
354 print "!!! Name error in",mypkg+": empty \"-\" part."
355 pkgcache[mypkg]=None
356 return None
357 #verify rev
358 revok=0
359 myrev=myparts[-1]
360 if len(myrev) and myrev[0]=="r":
361 try:
362 int(myrev[1:])
363 revok=1
364 except SystemExit, e:
365 raise
366 except:
367 pass
368 if revok:
369 if ververify(myparts[-2]):
370 if len(myparts)==2:
371 pkgcache[mypkg]=None
372 return None
373 else:
374 for x in myparts[:-2]:
375 if ververify(x):
376 pkgcache[mypkg]=None
377 return None
378 #names can't have versiony looking parts
379 myval=[string.join(myparts[:-2],"-"),myparts[-2],myparts[-1]]
380 pkgcache[mypkg]=myval
381 return myval
382 else:
383 pkgcache[mypkg]=None
384 return None
385
386 elif ververify(myparts[-1],silent=silent):
387 if len(myparts)==1:
388 if not silent:
389 print "!!! Name error in",mypkg+": missing name part."
390 pkgcache[mypkg]=None
391 return None
392 else:
393 for x in myparts[:-1]:
394 if ververify(x):
395 if not silent:
396 print "!!! Name error in",mypkg+": multiple version parts."
397 pkgcache[mypkg]=None
398 return None
399 myval=[string.join(myparts[:-1],"-"),myparts[-1],"r0"]
400 pkgcache[mypkg]=myval[:]
401 return myval
402 else:
403 pkgcache[mypkg]=None
404 return None
405
406vercache={}
407def ververify(myorigval,silent=1):
408 try:
409 return vercache[myorigval]
410 except KeyError:
411 pass
412 if len(myorigval)==0:
413 if not silent:
414 print "!!! Name error: package contains empty \"-\" part."
415 return 0
416 myval=string.split(myorigval,'.')
417 if len(myval)==0:
418 if not silent:
419 print "!!! Name error: empty version string."
420 vercache[myorigval]=0
421 return 0
422 #all but the last version must be a numeric
423 for x in myval[:-1]:
424 if not len(x):
425 if not silent:
426 print "!!! Name error in",myorigval+": two decimal points in a row"
427 vercache[myorigval]=0
428 return 0
429 try:
430 foo=int(x)
431 except SystemExit, e:
432 raise
433 except:
434 if not silent:
435 print "!!! Name error in",myorigval+": \""+x+"\" is not a valid version component."
436 vercache[myorigval]=0
437 return 0
438 if not len(myval[-1]):
439 if not silent:
440 print "!!! Name error in",myorigval+": two decimal points in a row"
441 vercache[myorigval]=0
442 return 0
443 try:
444 foo=int(myval[-1])
445 vercache[myorigval]=1
446 return 1
447 except SystemExit, e:
448 raise
449 except:
450 pass
451 #ok, our last component is not a plain number or blank, let's continue
452 if myval[-1][-1] in string.lowercase:
453 try:
454 foo=int(myval[-1][:-1])
455 vercache[myorigval]=1
456 return 1
457 # 1a, 2.0b, etc.
458 except SystemExit, e:
459 raise
460 except:
461 pass
462 #ok, maybe we have a 1_alpha or 1_beta2; let's see
463 #ep="endpart"
464 ep=string.split(myval[-1],"_")
465 if len(ep)!=2:
466 if not silent:
467 print "!!! Name error in",myorigval
468 vercache[myorigval]=0
469 return 0
470 try:
471 foo=int(ep[0][-1])
472 chk=ep[0]
473 except SystemExit, e:
474 raise
475 except:
476 # because it's ok last char is not numeric. example: foo-1.0.0a_pre1
477 chk=ep[0][:-1]
478
479 try:
480 foo=int(chk)
481 except SystemExit, e:
482 raise
483 except:
484 #this needs to be numeric or numeric+single letter,
485 #i.e. the "1" in "1_alpha" or "1a_alpha"
486 if not silent:
487 print "!!! Name error in",myorigval+": characters before _ must be numeric or numeric+single letter"
488 vercache[myorigval]=0
489 return 0
490 for mye in endversion_keys:
491 if ep[1][0:len(mye)]==mye:
492 if len(mye)==len(ep[1]):
493 #no trailing numeric; ok
494 vercache[myorigval]=1
495 return 1
496 else:
497 try:
498 foo=int(ep[1][len(mye):])
499 vercache[myorigval]=1
500 return 1
501 except SystemExit, e:
502 raise
503 except:
504 #if no endversions work, *then* we return 0
505 pass
506 if not silent:
507 print "!!! Name error in",myorigval
508 vercache[myorigval]=0
509 return 0
510
511def relparse(myver):
512 "converts last version part into three components"
513 number=0
514 suffix=0
515 endtype=0
516 endnumber=0
517
518 mynewver=string.split(myver,"_")
519 myver=mynewver[0]
520
521 #normal number or number with letter at end
522 divider=len(myver)-1
523 if myver[divider:] not in "1234567890":
524 #letter at end
525 suffix=ord(myver[divider:])
526 number=string.atof(myver[0:divider])
527 else:
528 number=string.atof(myver)
529
530 if len(mynewver)==2:
531 #an endversion
532 for x in endversion_keys:
533 elen=len(x)
534 if mynewver[1][:elen] == x:
535 endtype=endversion[x]
536 try:
537 endnumber=string.atof(mynewver[1][elen:])
538 except:
539 endnumber=0
540 break
541 return [number,suffix,endtype,endnumber]
542
543# vercmp:
544# ripped from portage.py to prevent having to import
545vcmpcache={}
546def vercmp(val1,val2):
547 if val1==val2:
548 #quick short-circuit
549 return 0
550 valkey=val1+" "+val2
551 try:
552 return vcmpcache[valkey]
553 try:
554 return -vcmpcache[val2+" "+val1]
555 except KeyError:
556 pass
557 except KeyError:
558 pass
559
560 # consider 1_p2 vc 1.1
561 # after expansion will become (1_p2,0) vc (1,1)
562 # then 1_p2 is compared with 1 before 0 is compared with 1
563 # to solve the bug we need to convert it to (1,0_p2)
564 # by splitting _prepart part and adding it back _after_expansion
565 val1_prepart = val2_prepart = ''
566 if val1.count('_'):
567 val1, val1_prepart = val1.split('_', 1)
568 if val2.count('_'):
569 val2, val2_prepart = val2.split('_', 1)
570
571 # replace '-' by '.'
572 # FIXME: Is it needed? can val1/2 contain '-'?
573 val1=string.split(val1,'-')
574 if len(val1)==2:
575 val1[0]=val1[0]+"."+val1[1]
576 val2=string.split(val2,'-')
577 if len(val2)==2:
578 val2[0]=val2[0]+"."+val2[1]
579
580 val1=string.split(val1[0],'.')
581 val2=string.split(val2[0],'.')
582
583 #add back decimal point so that .03 does not become "3" !
584 for x in range(1,len(val1)):
585 if val1[x][0] == '0' :
586 val1[x]='.' + val1[x]
587 for x in range(1,len(val2)):
588 if val2[x][0] == '0' :
589 val2[x]='.' + val2[x]
590
591 # extend version numbers
592 if len(val2)<len(val1):
593 val2.extend(["0"]*(len(val1)-len(val2)))
594 elif len(val1)<len(val2):
595 val1.extend(["0"]*(len(val2)-len(val1)))
596
597 # add back _prepart tails
598 if val1_prepart:
599 val1[-1] += '_' + val1_prepart
600 if val2_prepart:
601 val2[-1] += '_' + val2_prepart
602 #The above code will extend version numbers out so they
603 #have the same number of digits.
604 for x in range(0,len(val1)):
605 cmp1=relparse(val1[x])
606 cmp2=relparse(val2[x])
607 for y in range(0,4):
608 myret=cmp1[y]-cmp2[y]
609 if myret != 0:
610 vcmpcache[valkey]=myret
611 return myret
612 vcmpcache[valkey]=0
613 return 0
614
615# pkgcmp:
616# ripped from portage.py to prevent having to import
617def pkgcmp(pkg1,pkg2):
618 """if returnval is less than zero, then pkg2 is newer than pkg1, zero if equal and positive if older."""
619 if pkg1[0] != pkg2[0]:
620 return None
621 mycmp=vercmp(pkg1[1],pkg2[1])
622 if mycmp>0:
623 return 1
624 if mycmp<0:
625 return -1
626 r1=int(pkg1[2][1:])
627 r2=int(pkg2[2][1:])
628 if r1>r2:
629 return 1
630 if r2>r1:
631 return -1
632 return 0
633
634def ebuilds_to_rss(fp, ebuilds, simple=False, subtitle=""): 330def ebuilds_to_rss(fp, ebuilds, simple=False, subtitle=""):
635 """write out ebuild info to RSS file (fp)""" 331 """write out ebuild info to RSS file (fp)"""
636 332
637 # web link for RSS feed 333 # web link for RSS feed
638 if subtitle: 334 if subtitle:

Legend:
Removed from v.1.16.2.2  
changed lines
  Added in v.1.16.2.3

  ViewVC Help
Powered by ViewVC 1.1.20