On Wed, 2012-04-25 at 15:51 +0200, Tomáš Chvátal wrote:
What I think we could do:
Provide some simple wiki page with links to latest versions + git.
I guess its worth a shot, e.g. you setting up the wiki page, fill it
with links to the "best" upstreams of various linguistic stuff, and
script something that tries to scrape out the latest versions of those
when they're bumped and/or someone adds something new to the page and
generate snapshot extensions or whatever out of the ones that don't come
in exactly the right format.
FWIW, here's my "is fedora up to date with the packages I maintain"
script which does some lunacy to try and make sensible upgradeable
name-version-revisions out of all the various upstream systems, lots of
the hunspell/hyphen/thesaurus stuff is listed there and their upstream
locations as best as I could figure out.
C.
#!/bin/env python
# vim: set fileencoding=utf-8 :
import re, socket, os, sys
from ftplib import FTP
from httplib import HTTPConnection
from HTMLParser import HTMLParser
from datetime import datetime
from time import strptime, strftime, localtime
import makenvr
fedoramirrors = []
#http://download.fedora.redhat.com/pub/fedora/linux/development/rawhide/source/SRPMS/
#fedoramirrors.append(('download.fedora.redhat.com',
'/pub/fedora/linux/development/rawhide/source/SRPMS/'))
fedoramirrors.append(('ftp.heanet.ie', '/pub/fedora/linux/development/rawhide/source/SRPMS/'))
fedoramirrors.append(('ftp.fi.muni.cz',
'/pub/linux/fedora/linux/development/rawhide/source/SRPMS/'))
fedoramirrors.append(('sunsite.mff.cuni.cz',
'MIRRORS/fedora.redhat.com/linux/development/rawhide/source/SRPMS/'))
debug = 0
class MyHTMLParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.data = ''
def handle_data(self, data):
self.data = self.data + data
def isreleaseid(number):
bits = number.split('.')
try:
for bit in bits:
int(bit)
except:
return False
return True
def getminor(key):
bits = key.split('.')
minor = int(bits[1])
return minor
def sortbyurl(a, b):
if a.host == b.host:
return a.dir < b.dir
return a.host < b.host
def sortkeys(a, b):
return makenvr.compare_vr(a[0].lower(), b[0].lower(), a[1].lower(), b[1].lower())
class package:
def __init__(self, style, srpmname, upstreamprjname='', upstreampkgname='', host='',
dir='', pattern='', monthsdiff=0, datestring='', ispost=-1, fixrule=None):
self.style = style
self.name = srpmname
if upstreamprjname == '':
self.upstreamprjname = srpmname
else:
self.upstreamprjname = upstreamprjname
if upstreampkgname == '':
self.upstreampkgname = self.upstreamprjname
else:
self.upstreampkgname = upstreampkgname
self.host = host
self.dir = dir
self.pattern = pattern
self.monthsdiff = monthsdiff
self.datestring = datestring
self.ispost = ispost
self.fixrule = fixrule
droppedlist = []
firstcol = 37
secondcol = 29
def alignit(name, count):
for i in range(len(name), count):
name = name + ' '
print name, ':',
ftplist = []
def collector(line = ''):
global ftplist
if debug: print 'ftpline is', line
ftplist.append(line)
class packagemanager:
def __init__(self, packagelist):
self.keys = {}
for package in packagelist:
if not self.keys.has_key(package.style):
self.keys[package.style] = []
self.keys[package.style].append(package)
for key in self.keys:
packages = self.keys[key]
packages.sort(sortbyurl)
self.keys[key] = packages
for mirror in fedoramirrors:
try:
self.ftp = FTP(mirror[0])
self.ftp.login()
self.srpmlist = []
print "collecting srpms",
#use koji -q latest-pkg rawhide foo bar baz
sys.stdout.flush()
for letter in range(ord('a'), ord('z')):
print chr(letter),
sys.stdout.flush()
self.ftp.cwd(mirror[1]+chr(letter))
self.srpmlist = self.srpmlist + self.ftp.nlst()
print
print "Fedora Mirror:", mirror[0]
sys.stdout.flush()
break
except:
print "Skipping:", mirror[0], "because", sys.exc_info()[1]
pass
def latestsrpm(self, pack):
releases = []
for entry in self.srpmlist:
nameprefix = pack.name + '-'
prefix = nameprefix
if entry[:len(prefix)] == prefix:
rpmname, rpmversion, rpmrelease = makenvr.get_nvr(entry,
pack.ispost)
if rpmname == pack.name:
rpmrelease = makenvr.scrub_disttag(rpmrelease)
rpmrelease = makenvr.undo_prerelease(rpmrelease)
releases.append((rpmversion, rpmrelease))
keys = self.cleanandsort(releases)
if len(keys):
return keys[0]
return None
def fetch(self):
for key in self.keys:
try:
if key == 'gnome':
# self.ftp = FTP('ftp.acc.umu.se')
self.ftp = FTP('ftp.heanet.ie')
self.ftp.login()
for package in self.keys[key]:
try:
latest = self.latestsrpm(package)
if latest:
alignit(package.name+'-'+latest[0]+'-'+latest[1], firstcol)
self.getgnomelatest(package, latest)
else:
droppedlist.append(package.name);
except:
print 'ERROR fetching:', package.name,
'from'
print '
ftp://ftp.heanet.ie'+'/mirrors/ftp.gnome.org/sources/' +\
pack.upstreampkgname
print ' error is:', sys.exc_info()[0],
sys.exc_info()[1]
elif key == 'sourceforge':
# self.ftp = FTP('ftp.heanet.ie')
self.ftp = FTP('www.mirrorservice.org')
self.ftp.login()
for package in self.keys[key]:
try:
latest = self.latestsrpm(package)
if latest:
alignit(package.name+'-'+latest[0]+'-'+latest[1], firstcol)
self.getsourceforgelatest(package,
latest)
else:
droppedlist.append(package.name);
except:
print 'ERROR fetching:', package.name,
'from'
print '
ftp://www.mirrorservice.org'+self.getsourceforgedir(package)
print ' error is:', sys.exc_info()[0],
sys.exc_info()[1]
elif key == 'ftp':
lasthost = ''
for package in self.keys[key]:
try:
if package.host != lasthost:
self.ftp = FTP(package.host)
self.ftp.login()
lasthost = package.host
self.ftp.cwd(package.dir)
dirlist = self.ftp.nlst()
dirlist = self.dofixrule(dirlist, package)
#print dirlist
latest = self.latestsrpm(package)
if latest:
alignit(package.name+'-'+latest[0]+'-'+latest[1], firstcol)
self.getsimplelatest(package.upstreampkgname, latest, dirlist, package.ispost, False)
else:
droppedlist.append(package.name);
except:
print 'ERROR fetching:', package.name,
'from'
print ' ftp://'+package.host+package.dir
print ' error is:', sys.exc_info()[0],
sys.exc_info()[1]
elif key == 'http-regexp':
lasthost = ''
lastdir = ''
conn = None
for package in self.keys[key]:
try:
if debug: print package.host, package.dir
if package.host != lasthost:
conn = HTTPConnection(package.host)
if package.host != lasthost or package.dir
!= lastdir:
headers = {"User-Agent":
"latestpackages/1.0.0"}
conn.request("GET", package.dir,
headers=headers)
response = conn.getresponse()
data = response.read().splitlines()
lasthost = package.host
lastdir = package.dir
if debug: print data
p = re.compile(package.pattern)
dirlist = []
for line in data:
try:
for m in re.finditer(p,
line):
if debug: print
'MATCH', line
result = m.group(1)
if
len(package.datestring):
dttm =
datetime(*strptime(result, package.datestring)[0:6])
if
dttm.year == 1900:
dttm = datetime(datetime.today().year, \
dttm.month, dttm.day)
result =
dttm.strftime("%Y%m%d")
dirlist.append(package.upstreampkgname+'-'+result+'.tar.gz')
except:
pass
dirlist = self.dofixrule(dirlist, package)
if debug: print dirlist
latest = self.latestsrpm(package)
if latest:
alignit(package.name+'-'+latest[0]+'-'+latest[1], firstcol)
self.getsimplelatest(package.upstreampkgname, latest, dirlist, \
package.ispost, False,
package.monthsdiff)
else:
droppedlist.append(package.name);
except:
print 'ERROR fetching:', package.name,
'from'
print ' http://'+package.host+package.dir
print ' error is:', sys.exc_info()[0],
sys.exc_info()[1]
elif key == 'http-last-modified':
# lasthost = ''
conn = None
for package in self.keys[key]:
try:
if debug: print package.dir
# if package.host != lasthost:
conn = HTTPConnection(package.host)
# lasthost = package.host
headers = {"User-Agent":
"latestpackages/1.0.0"}
conn.request("GET", package.dir,
headers=headers)
response = conn.getresponse()
s = response.getheader('last-modified')
if debug: print s
dirlist = []
result = datetime(*strptime(s, "%a, %d %b
%Y %H:%M:%S %Z")[0:6])
datestring = result.strftime("%Y%m%d")
dirlist.append(package.upstreampkgname+'-'+datestring+'.tar.gz')
latest = self.latestsrpm(package)
if latest:
alignit(package.name+'-'+latest[0]+'-'+latest[1], firstcol)
self.getsimplelatest(package.upstreampkgname, latest, dirlist, \
package.ispost, False,
package.monthsdiff)
else:
droppedlist.append(package.name);
except:
print 'ERROR fetching:', package.name,
'from'
print ' http://'+package.host+package.dir
print ' error is:', sys.exc_info()[0],
sys.exc_info()[1]
elif key == 'ftp-last-modified':
global ftplist
lasthost = ''
for package in self.keys[key]:
try:
if package.host != lasthost:
self.ftp = FTP(package.host)
self.ftp.login()
lasthost = package.host
dirlist = []
pattern = r'.*?(... .\d \d\d\d\d)'
p = re.compile(pattern)
pattern2 = r'.*? (... .\d )'
p2 = re.compile(pattern2)
ftplist = []
self.ftp.dir(package.dir, collector)
for line in ftplist:
m = p.match(line)
if m:
result =
datetime(*strptime(m.group(1), "%b %d %Y")[0:6])
datestring =
result.strftime("%Y%m%d")
dirlist.append(package.upstreampkgname+'-'+datestring+'.tar.gz')
else:
m = p2.match(line)
if m:
try:
result =
datetime(*strptime(m.group(1), "%b %d ")[0:6])
result =
datetime(datetime.today().year, \
result.month, result.day)
datestring
= result.strftime("%Y%m%d")
dirlist.append(package.upstreampkgname+'-'+datestring+'.tar.gz')
except:
pass
if debug: print 'dirlist is now', dirlist
latest = self.latestsrpm(package)
if latest:
alignit(package.name+'-'+latest[0]+'-'+latest[1], firstcol)
self.getsimplelatest(package.upstreampkgname, latest, dirlist, package.ispost, False)
else:
droppedlist.append(package.name);
except:
print 'ERROR fetching:', package.name,
'from'
print ' ftp://'+package.host+package.dir
print ' error is:', sys.exc_info()[0],
sys.exc_info()[1]
elif key == 'svn-propget-date':
for package in self.keys[key]:
try:
#print package.dir
if package.dir[-1] == '/':
cmd = 'svn propget --revprop -rHEAD
svn:date https://' + package.host + \
package.dir
fd = os.popen(cmd, "r")
s = fd.readline()[:-1]
else:
cmd = 'svn ls --xml --depth empty
https://' + package.host + \
package.dir + '|grep
date|sed -e "s/<date>//g"|sed -e "s/<\/date>//g"'
fd = os.popen(cmd, "r")
s = fd.readline()[:-1]
dirlist = []
s = s.split('.')[0]
result = datetime(*strptime(s,
"%Y-%m-%dT%H:%M:%S")[0:6])
datestring = result.strftime("%Y%m%d")
if package.dir[-1] == '/': #temp hack
dirlist.append(package.upstreampkgname+'-'+datestring+'.tar.gz')
else:
dirlist.append(package.upstreampkgname+'-'+datestring+'svn.tar.gz')
latest = self.latestsrpm(package)
if latest:
alignit(package.name+'-'+latest[0]+'-'+latest[1], firstcol)
self.getsimplelatest(package.upstreampkgname, latest, dirlist, \
package.ispost, False,
package.monthsdiff)
else:
droppedlist.append(package.name);
except:
print 'ERROR fetching:', package.name,
'from'
print ' http://'+package.host+package.dir
print ' error is:', sys.exc_info()[0],
sys.exc_info()[1]
except socket.error:
for package in self.keys[key]:
print 'TIMEOUT fetching', package.name
except:
print 'Oops!', sys.exc_info()[0]
for package in self.keys[key]:
print 'ERROR fetching', package.name
def cleanandsort(self, keys):
if debug: print 'candidate keys are', keys
keys.sort(sortkeys)
keys.reverse()
return keys
def getgnomelatest(self, pack, latest):
self.ftp.cwd('/mirrors/ftp.gnome.org/sources/' + pack.upstreampkgname)
# self.ftp.cwd('/pub/GNOME/sources/' + pack.upstreampkgname)
dirlist = self.ftp.nlst()
vrs = []
for entry in dirlist:
vrs.append((entry,'1'))
keys = self.cleanandsort(vrs)
result = 'Upstream '
for key in keys:
minor = getminor(key[0])
self.ftp.cwd(key[0])
dirlist = self.ftp.nlst()
dirlist = self.dofixrule(dirlist, pack)
ret = "NONE!"
for file in dirlist:
if len(file) > 10 and file[0:10] == 'LATEST-IS-':
ret = file[10:]
break
if not minor % 2:
result = result + str(ret)+'-1'
alignit(result, secondcol)
if sortkeys(latest, (ret,'1')) < 0:
print 'NOT UPTODATE'
else:
print 'UpToDate'
break
self.ftp.cwd('..')
def latestkey(self, keys, latestsrpm, monthsdiff=0):
if len(keys) == 0:
alignit('MISSING', secondcol)
print
else:
result = 'Upstream '
for key in keys:
result = result + key[0]+'-'+key[1]
old = False
alignit(result, secondcol)
if sortkeys(latestsrpm, key) < 0:
old = True
if monthsdiff != 0:
srpmvr = latestsrpm[0]+'-'+latestsrpm[1]
upstreamvr = key[0]+'-'+key[1]
pattern = r'.*?(\d\d\d\d\d\d\d\d)'
p = re.compile(pattern)
m = p.match(srpmvr)
if m:
srpmdate = m.group(1)
m = p.match(upstreamvr)
if m:
upstreamdate = m.group(1)
latestyear = int(srpmdate[-8:-4])
latestmonth = int(srpmdate[-4:-2])
for i in range(0, monthsdiff):
if latestmonth == 12:
latestyear = latestyear + 1
latestmonth = 1
else:
latestmonth = latestmonth + 1
theday = int(srpmdate[-2:])
while (1):
try:
srpmvaliduntil =
datetime(latestyear, latestmonth, \
theday)
break
except ValueError:
theday = theday - 1
pass
upstreamdt = datetime(int(upstreamdate[-8:-4]),
int(upstreamdate[-4:-2]), \
int(upstreamdate[-2:]))
if debug: print 'allowing difference of',
monthsdiff, 'month between', \
srpmvaliduntil, 'and', upstreamdt
if upstreamdt < srpmvaliduntil:
old = False
if old:
print 'NOT UPTODATE'
else:
print 'UpToDate'
break
def getsimplelatest(self, name, latest, dirlist, ispost, strict = True, monthsdiff=0):
blacklistwords = ['win32', 'MinGW', 'Darwin', 'MSVC', 'hunspell_UNO', 'cs.net',
'or.newer', 'or_newer']
releases = []
for sep in ['-', '_', '.']:
for entry in dirlist:
nameprefix = name + sep
prefix = nameprefix
if debug: print 'entry is', entry
if debug: print 'prefix is', prefix
if entry[:len(prefix)] == prefix:
skip = False
for word in blacklistwords:
if entry.find(word) != -1:
skip = True
break
if skip:
continue
try:
dummyname, version, release =
makenvr.make_nvr(entry, '', ispost)
releases.append((version, release))
except makenvr.NVRException:
pass
keys = self.cleanandsort(releases)
self.latestkey(keys, latest, monthsdiff)
def getsourceforgedir(self, pack):
return '/sites/download.sourceforge.net/pub/sourceforge/' + pack.upstreamprjname[0]
+ '/project/' + \
pack.upstreamprjname[0:2] + '/' + pack.upstreamprjname + '/' +
pack.upstreampkgname + '/'
def dofixrule(self, dirlist, pack):
if not pack.fixrule:
return dirlist
newdirlist = []
for e in dirlist:
newdirlist.append(re.sub(pack.fixrule[0], pack.fixrule[1], e))
return newdirlist
def getsourceforgelatest(self, pack, latest):
self.ftp.cwd(self.getsourceforgedir(pack))
dirlist = self.ftp.nlst()
dirlist = self.dofixrule(dirlist, pack)
vrs = []
for entry in dirlist:
for sep in ['-', '_', '.']:
prefix = pack.upstreampkgname + sep
if entry[:len(prefix)] == prefix:
entry = entry[len(prefix):]
break
dummyname, version, release = makenvr.make_nvr(prefix+'-'+entry+'.tar.gz',
'', pack.ispost)
vrs.append((version, release))
keys = self.cleanandsort(vrs)
result = 'Upstream '
self.latestkey(keys, latest)
# for key in keys:
# self.ftp.cwd(key[0])
# dirlist = self.ftp.nlst()
# dirlist = self.dofixrule(dirlist, pack)
# ret = "NONE!"
# result = result + str(ret)+'-1'
# alignit(result, secondcol)
# if sortkeys(latest, (ret,'1')) < 0:
# print 'NOT UPTODATE'
# else:
# print 'UpToDate'
# break
# self.ftp.cwd('..')
#
#
# dirlist = self.ftp.nlst()
# if debug: print 'dirlist is', dirlist
# dirlist = self.dofixrule(dirlist, pack)
# self.getsimplelatest(pack.upstreampkgname, latest, dirlist, pack.ispost, False)
packagelist = []
#http regexp
packagelist.append(package('http-regexp', 'hunspell-wa', 'aspell-wa', \
'aspell-wa', 'chanae.walon.org', '/walon/aspell.php', \
r'.*?href="aspell-wa-(.*?).tar.bz2">'))
packagelist.append(package('http-regexp', 'hunspell-uz', 'uzbek-wordlist', \
'uzbek-wordlist', 'www-user.uni-bremen.de', '/~kmashrab/uzbek-word-list/', \
r'.*?href="uzbek-wordlist-(.*?).tar.bz2">'))
packagelist.append(package('http-regexp', 'hunspell-sq', 'myspell-sq_AL', \
'myspell-sq_AL', 'www.shkenca.org', '/k6i/albanian_dictionary_for_myspell_en.html', \
r'.*?href="http://www.shkenca.org/shkarkime/myspell-sq_AL-(.*?).zip">'))
packagelist.append(package('http-regexp', 'hunspell-mi', 'hunspell-mi', \
'hunspell-mi', 'packages.papakupu.maori.nz', '/hunspell/', \
r'.*?href="hunspell-mi-(.*?).tar.gz">'))
packagelist.append(package('http-regexp', 'hyphen-mi', 'hyphen-mi', \
'hyphen-mi', 'packages.papakupu.maori.nz', '/hunspell-hyphen/', \
r'.*?href="hunspell-hyphen-mi-(.*?).tar.gz">'))
packagelist.append(package('http-regexp', 'mythes-mi', 'mythes-mi', \
'mythes-mi', 'packages.papakupu.maori.nz', '/mythes/', \
r'.*?href="mythes-mi-(.*?).tar.gz">'))
packagelist.append(package('http-regexp', 'mythes-ne', 'mythes-ne', \
'mythes-ne', 'hg.services.openoffice.org',
'/hg/DEV300/raw-file/tip/dictionaries/ne_NP/README_th_ne_NP_v2.txt', \
r'.*?Release (.*?) '))
packagelist.append(package('http-regexp', 'hunspell-fur', 'myspell-fur', \
'myspell-fur', 'digilander.libero.it', '/paganf/coretors/dizionaris.html', \
r'.*?href="myspell-fur-(.*?).zip">'))
packagelist.append(package('http-regexp', 'fribidi', 'fribidi', \
'fribidi', 'fribidi.org', '/download/', \
r'.*?href="fribidi-(.*?).tar.gz">'))
packagelist.append(package('http-regexp', 'libexttextcat', 'libexttextcat', \
'libexttextcat', 'dev-www.libreoffice.org', '/src/libexttextcat/', \
r'.*?href="libexttextcat-(.*?).tar.gz">'))
packagelist.append(package('http-regexp', 'libvisio', 'libvisio', \
'libvisio', 'dev-www.libreoffice.org', '/src/', \
r'.*?href="libvisio-(.*?).tar.bz2">'))
packagelist.append(package('http-regexp', 'sac', 'sac', \
'sac', 'www.w3.org', '/Style/CSS/SAC/', \
r'.*?sacjava-(.*?).zip'))
packagelist.append(package('http-regexp', 'agg', 'agg', \
'agg', 'www.antigrain.com', '/download/', \
r'.*?http://www.antigrain.com/agg-(.*?).tar.gz'))
packagelist.append(package('http-regexp', 'icu', 'icu', \
'icu', 'site.icu-project.org', '/download/', \
r'.*?#ICU4C".*?>(.*?)<'))
packagelist.append(package('http-regexp', 'hunspell-ga', 'ispell-gaeilge', \
'ispell-gaeilge', 'borel.slu.edu', '/ispell/sios.html', \
r'.*?ispell-gaeilge-(.*?).tar.gz'))
packagelist.append(package('http-regexp', 'hunspell-sk', 'hunspell-sk', \
'hunspell-sk', 'www.sk-spell.sk.cx', '/hunspell-sk', \
r'.*?hunspell-sk-(\d\d\d\d\d\d\d\d).zip'))
packagelist.append(package('http-regexp', 'hunspell-da', 'myspell-da', \
'myspell-da', 'da.speling.org', '/filer/', \
r'.*?a href="myspell-da-(.*?).tar.gz">'))
packagelist.append(package('http-regexp', 'hunspell-fo', 'myspell-fo', \
'myspell-fo', 'fo.speling.org', '/filer/', \
r'.*?a href="myspell-fo-(.*?).tar.gz">'))
packagelist.append(package('http-regexp', 'hyphen-hu', 'huhyphn', \
'huhyphn', 'www.tipogral.hu', '/', \
r'.*?hungarian hyphenation patterns v(.*?)</tt>'))
packagelist.append(package('http-regexp', 'hunspell-ur', 'UrduDictionary', \
'UrduDictionary', 'urdudictionary.codeplex.com', '/', \
r'.*?>Release (.*?)<'))
packagelist.append(package('http-regexp', 'hunspell-af', 'dict_af', \
'dict_af', 'extensions.services.openoffice.org', '/project/dict_af', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-nr', 'dict-nr', \
'dict-nr', 'extensions.services.openoffice.org', '/project/dict-nr', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-ss', 'dict-ss', \
'dict-ss', 'extensions.services.openoffice.org', '/project/dict-ss', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-st', 'dict-st', \
'dict-st', 'extensions.services.openoffice.org', '/project/dict-st', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-ts', 'dict-ts', \
'dict-ts', 'extensions.services.openoffice.org', '/project/dict-ts', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-tn', 'dict-tn', \
'dict-tn', 'extensions.services.openoffice.org', '/project/dict-tn', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-ve', 'dict-ve', \
'dict-ve', 'extensions.services.openoffice.org', '/project/dict-ve', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-xh', 'dict-xh', \
'dict-xh', 'extensions.services.openoffice.org', '/project/dict-xh', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-nso', 'dict-ns_ZA', \
'dict-ns_ZA', 'extensions.services.openoffice.org', '/project/dict-nso', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-zu', 'dict-zu', \
'dict-zu', 'extensions.services.openoffice.org', '/project/dict-zu', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-de', 'igerman98', \
'igerman98', 'www.j3e.de', '/ispell/igerman98/dict/', \
r'.*?<a href="igerman98-(.*?).tar'))
packagelist.append(package('http-regexp', 'hunspell-nl', 'opentaal', \
'opentaal', 'www.opentaal.org', '/bestanden', \
r'.*?Woordenlijst v (.*?) '))
packagelist.append(package('http-regexp', 'mythes-en', 'WordNet', \
'WordNet', 'wordnet.princeton.edu', '/download/', \
r'.*?WordNet-(.*?).tar.bz2'))
packagelist.append(package('http-regexp', 'hunspell-sv', 'dsso', \
'dsso', 'dsso.se', '/download.html', \
r'.*?>dsso-(.*?).txt<'))
packagelist.append(package('http-regexp', 'mythes-sk', 'mythes-sk', \
'mythes-sk', 'www.sk-spell.sk.cx', '/thesaurus/faq.php', \
r'.*?OpenOffice.org 2.x.*?generovan.*?(\d\d\d\d-\d\d-\d\d)', 1))
packagelist.append(package('http-regexp', 'mythes-de', 'mythes-de', \
'mythes-de', 'www.openthesaurus.de', '/about/download', \
r'.*?(\d\d\d\d-\d\d-\d\d)', 1))
packagelist.append(package('http-regexp', 'mythes-es', 'mythes-es', \
'mythes-es', 'openthes-es.berlios.de', '/index.php', \
r'.*?(\d\d\d\d-\d\d-\d\d)\)', 1))
packagelist.append(package('http-regexp', 'mythes-sl', 'mythes-sl', \
'mythes-sl', '193.2.66.133:85', '/index.php', \
r'.*?(\d\d\d\d-\d\d-\d\d)\)', 1))
packagelist.append(package('http-regexp', 'mythes-nl', 'mythes-nl', \
'mythes-nl', 'data.opentaal.org', '/opentaalbank/thesaurus/', \
r'.*?(\d\d\d\d-\d\d-\d\d)\)', 1))
packagelist.append(package('http-regexp', 'hunspell-et', 'ispell-et', \
'ispell-et', 'www.meso.ee', '/~jjpp/speller/', \
r'.*?ispell-et_(\d\d\d\d\d\d\d\d).*'))
packagelist.append(package('http-regexp', 'hunspell-el', 'ispell-gr', \
'ispell-gr', 'ispell.math.upatras.gr', '/?section=oofficespell&subsection=howto', \
r'.*?OpenOffice Greek Dictionary v(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-pl', 'sjp-myspell-pl', \
'sjp-myspell-pl', 'www.sjp.pl', '/slownik/en/', \
r'.*?a href="http://sjp.pl/slownik/ort/sjp-myspell-pl-(\d\d\d\d\d\d\d\d).zip"', 1))
#packagelist.append(package('http-regexp', 'hunspell-km', 'khmersbbic', \
# 'khmersbbic', 'extensions.services.openoffice.org', '/project/khmersbbic', \
# r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)
packagelist.append(package('http-regexp', 'hunspell-pt', 'pt_BR', \
'pt_BR', 'www.broffice.org', '/verortografico/baixar/', \
r'.*?files/pt_BR-(\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-pt', 'pt_PT', \
'pt_PT', 'natura.di.uminho.pt', '/download/sources/Dictionaries/hunspell/', \
r'.*?hunspell-pt_PT-(\d\d\d\d\d\d\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-vi', 'hunspell-spellcheck-vi', \
'hunspell-spellcheck-vi', 'code.google.com', \
'/p/hunspell-spellcheck-vi/downloads/detail?name=vi_VN.zip', \
r'.*?<span class="date" .*?>(.*?)</span>', False, "%b %d, %Y"))
packagelist.append(package('http-regexp', 'hunspell-en', 'en_GB', \
'en_GB', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?en_GB.zip" rel="nofollow">English \(United Kingdom\)</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-rw', 'rw_RW', \
'rw_RW', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?rw_RW.zip" rel="nofollow">Spelling</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-mg', 'mg_MG', \
'mg_MG', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?mg_MG.zip" rel="nofollow">Spelling</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-id', 'id_ID', \
'id_ID', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?id_ID.zip" rel="nofollow">Spelling</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-th', 'th_TH', \
'th_TH', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?th_TH.zip" rel="nofollow">Spelling</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-sl', 'sl_SI', \
'sl_SI', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?sl_SI.zip" rel="nofollow">Spelling</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-cy', 'cy_GB', \
'cy_GB', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?cy_GB.zip" rel="nofollow">Spelling</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-ms', 'ms_MY', \
'ms_MY', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?ms_MY.zip" rel="nofollow">Spelling</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-no', 'nb_NO', \
'spell-norwegian', 'alioth.debian.org', '/frs/?group_id=30577', \
r'.*?spell-norwegian-(.*?).tar.gz'))
packagelist.append(package('http-regexp', 'hunspell-mk', 'mk_MK', \
'mk_MK', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?mk_MK.zip" rel="nofollow">Spelling</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-tl', 'tl_PH', \
'tl_PH', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?tl_PH.zip" rel="nofollow">Spelling</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'mythes-cs', 'thes_cs_CZ_v2', \
'thes_cs_CZ_v2', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?thes_cs_CZ_v2.zip" rel="nofollow">Thesaurus</a> .*? (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-sv', 'hyph_sv_SE', \
'hyph_sv_SE', 'extensions.services.openoffice.org', '/node/1968', \
r'.*?>Swedish hyphenation (.*?)</a>'))
packagelist.append(package('http-regexp', 'mythes-sv', 'SweThes', \
'SweThes', 'extensions.services.openoffice.org', '/project/SweThes', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hyphen-ga', 'hyph_ga_IE', \
'hyph_ga_IE', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_ga_IE.zip" rel="nofollow">Hyphenation</a> \(version .*?\) (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'mythes-ga', 'thes_ga_IE', \
'thes_ga_IE', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?thes_ga_IE_v2.zip" rel="nofollow">Thesaurus</a> \(version .*?\) (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'mythes-el', 'thes_el_GR', \
'thes_el_GR', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?th_el.zip" rel="nofollow">Thesaurus</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'mythes-ru', 'thes_ru_RU', \
'thes_ru_RU', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?thes_ru_RU_v2.zip" rel="nofollow">Thesaurus</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-ru', 'hyph_ru_RU', \
'hyph_ru_RU', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_ru_RU.zip" rel="nofollow">Hyphenation</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-pl', 'hyph_pl_PL', \
'hyph_pl_PL', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_pl_PL.zip" rel="nofollow">Hyphenation</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-nl', 'hyph_nl_NL', \
'hyph_nl_NL', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_nl_NL.zip" rel="nofollow">Hyphenation</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-de', 'hyph_de_DE', \
'hyph_de_DE', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_de_DE.zip" rel="nofollow">German \(Germany\)</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-da', 'hyph_da_DK', \
'hyph_da_DK', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_da_DK.zip" rel="nofollow">Hyphenation</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-it', 'hyph_it_IT', \
'hyph_it_IT', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_it_IT.zip" rel="nofollow">Hyphenation</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-sl', 'hyph_sl_SI', \
'hyph_sl_SI', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_sl_SI.zip" rel="nofollow">Hyphenation</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-sk', 'hyph_sk_SK', \
'hyph_sk_SK', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_sk_SK.zip" rel="nofollow">Hyphenation</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-el', 'hyph_el_GR', \
'hyph_el_GR', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_el_GR.zip" rel="nofollow">Hyphenation</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-es', 'hyph_es_ES', \
'hyph_es_ES', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_es_ES.zip" rel="nofollow">Hyphenation</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-is', 'hyph_is_IS', \
'hyph_is_IS', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_is_IS.zip" rel="nofollow">Hyphenation</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-id', 'hyph_id_ID', \
'hyph_id_ID', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_id_ID.zip" rel="nofollow">Hyphenation</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-uk', 'hyph_uk_UA', \
'hyph_uk_UA', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_uk_UA.zip" rel="nofollow">Hyphenation</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hyphen-pt', 'hyph_pt_PT', \
'hyph_pt_PT', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?hyph_pt_PT.zip" rel="nofollow">.*? (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-ber', 'hunspell-am', \
'hunspell-am', 'ayaspell.sourceforge.net', '/am.html', \
r'.*?(\d\d\d\d-\d\d-\d\d) <a href="http'))
packagelist.append(package('http-regexp', 'hunspell-sc', 'dict-sc', \
'dict-sc', 'extensions.services.openoffice.org', '/project/Dict_sc', \
r'.*?Download.*?a href=.*?>(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-mn', 'mnSpell', \
'mnSpell', 'extensions.services.openoffice.org', '/project/mnSpell', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-la', 'dict-la', \
'dict-la', 'extensions.services.openoffice.org', '/project/dict-la', \
r'.*?Download.*?a href=.*?>(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-sw', 'sw_TZ', \
'sw_TZ', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?sw_TZ.*?Spelling</a> .*? (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-cop', 'copt_dict', \
'copt_dict', 'extensions.services.openoffice.org', '/project/copt_dict', \
r'.*?/node/4579">(.*?)</a>'))
packagelist.append(package('http-regexp', 'mythes-ca', 'thesaurus-ca', \
'thesaurus-ca', 'extensions.services.openoffice.org', '/project/thesaurus-ca', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'mythes-da', 'danske_synonymer', \
'danske_synonymer', 'extensions.services.openoffice.org', '/project/danske_synonymer', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-kk', 'dict-kk', \
'dict-kk', 'extensions.services.openoffice.org', '/node/1172/release', \
r'.*?This (.*?) release'))
packagelist.append(package('http-regexp', 'hunspell-tet', 'tet_ID', \
'tet_ID', 'wiki.services.openoffice.org', '/wiki/Dictionaries', \
r'.*?tet_ID.*?Spelling</a> (\d\d\d\d-\d\d-\d\d)'))
packagelist.append(package('http-regexp', 'hunspell-so', 'Alif-Higgaad-saxe', \
'Alif-Higgaad-saxe', 'extensions.services.openoffice.org', '/project/Alif-Higgaad-saxe', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-sr', 'dict-sr', \
'dict-sr', 'extensions.services.openoffice.org', '/project/dict-sr', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hyphen-ku', 'kitandin', \
'kitandin', 'extensions.services.openoffice.org', '/project/kitandin', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-be', 'dict-be-official', \
'dict-be-official', 'extensions.services.openoffice.org', '/project/dict-be-official', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hyphen-gl', 'hyphenation-gl', \
# 'hyphenation-gl', 'extensions.services.openoffice.org',
'/project/Extension_Guionizador_galego_OOo', \
'hyphenation-gl', 'extensions.services.openoffice.org', '/en/node/2014', \
# r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
r'.*?<font color="black">(.*?) </font>'))
packagelist.append(package('http-regexp', 'hunspell-gd', 'gd_GB', \
'gd_GB', 'extensions.services.openoffice.org', '/project/faclair-afb', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-br', 'Dict-br_Drouizig', \
'Dict-br_Drouizig', 'extensions.services.openoffice.org', '/project/Dict-br_Drouizig', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-is', 'dict-is', \
'dict-is', 'extensions.services.openoffice.org', '/project/dict-is', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hyphen-ca', 'ca_hyph', \
'ca_hyph', 'extensions.services.openoffice.org', '/project/ca_hyph', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'mythes-hu', 'hu_dicts', \
'hu_dicts', 'extensions.services.openoffice.org', '/project/hu_dicts', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-grc', 'grc', \
'grc', 'extensions.services.openoffice.org', '/project/ancientgreekspellchecker', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-dsb', 'lower_sorbian_spelling_dictionary', \
'lower_sorbian_spelling_dictionary', 'extensions.services.openoffice.org',
'/project/HunSpellDic_dsb_DE', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-qu', 'qu_EC', \
'qu_EC', 'extensions.services.openoffice.org', '/project/KichwaSpellchecker', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-ht', 'kok', \
'kok', 'extensions.services.openoffice.org', '/project/kok', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-eo', 'literumilo', \
'literumilo', 'extensions.services.openoffice.org', '/project/literumilo', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-ast', 'asturianu', \
'asturianu', 'extensions.services.openoffice.org', '/project/asturianu', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-ny', 'chicspell', \
'chicspell', 'extensions.services.openoffice.org', '/project/chicspell', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'writer2latex', 'writer2latex', \
'writer2latex', 'extensions.services.openoffice.org', '/en/project/writer2latex', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-tpi', 'tok-pisin-spell-checker', \
'tok-pisin-spell-checker', 'extensions.services.openoffice.org',
'/en/project/tok-pisin-spell-checker', \
r'.*?Download extension.*?<a href="/en/node/.*?">(.*?)</a>'))
packagelist.append(package('http-regexp', 'hunspell-cv', 'hunspell-cv', \
'hunspell-cv', 'hunspell.chv.su', '/download.shtml', \
r'.*?>dict-cv-(.*?).oxt</a>', fixrule=('-u','')))
packagelist.append(package('http-regexp', 'mythes-pt', 'thes_pt_PT_v2', \
'thes_pt_PT_v2', 'openthesaurus.caixamagica.pt', '/', \
r'.*?(\d\d\d\d-\d\d-\d\d)\)', 1))
packagelist.append(package('http-regexp', 'hyphen-tk', 'hyph-tk', \
'hyph-tk', 'tug.org',
'/svn/texhyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-tk.tex?view=log', \
r'.*?<em>(.*) UTC</em>', datestring="%a %b %d %H:%M:%S %Y"))
packagelist.append(package('http-regexp', 'hyphen-mn', 'hyph-mn-cyrl', \
'hyph-mn-cyrl', 'tug.org',
'/svn/texhyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-mn-cyrl.tex?view=log', \
r'.*?<em>(.*) UTC</em>', datestring="%a %b %d %H:%M:%S %Y"))
packagelist.append(package('http-regexp', 'hyphen-hsb', 'hyph-hsb', \
'hyph-hsb', 'tug.org',
'/svn/texhyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-hsb.tex?view=log', \
r'.*?<em>(.*) UTC</em>', datestring="%a %b %d %H:%M:%S %Y"))
packagelist.append(package('http-regexp', 'hyphen-sa', 'hyph-sa', \
'hyph-sa', 'tug.org',
'/svn/texhyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-sa.tex?view=log', \
r'.*?<em>(.*) UTC</em>', datestring="%a %b %d %H:%M:%S %Y"))
packagelist.append(package('http-regexp', 'hyphen-eu', 'hyph-eu', \
'hyph-eu', 'tug.org',
'/svn/texhyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-eu.tex?view=log', \
r'.*?<em>(.*) UTC</em>', datestring="%a %b %d %H:%M:%S %Y"))
packagelist.append(package('http-regexp', 'hyphen-cy', 'hyph-cy', \
'hyph-cy', 'tug.org',
'/svn/texhyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-cy.tex?view=log', \
r'.*?<em>(.*) UTC</em>', datestring="%a %b %d %H:%M:%S %Y"))
packagelist.append(package('http-regexp', 'hyphen-grc', 'hyph-grc', \
'hyph-grc', 'tug.org',
'/svn/texhyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-grc.tex?view=log', \
r'.*?<em>(.*) UTC</em>', datestring="%a %b %d %H:%M:%S %Y"))
packagelist.append(package('http-regexp', 'hyphen-lt', 'hyph-lt', \
'hyph-lt', 'tug.org',
'/svn/texhyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-lt.tex?view=log', \
r'.*?<em>(.*) UTC</em>', datestring="%a %b %d %H:%M:%S %Y"))
packagelist.append(package('http-regexp', 'hyphen-fa', 'fahyph', \
'fahyph', 'ftp.heanet.ie', '/pub/CTAN/tex/language/hyphenation/', \
r'.*?<a href="fahyph.zip">fahyph.zip</a>.*?(\d\d-...-\d\d\d\d)', datestring="%d-%b-%Y"))
packagelist.append(package('http-regexp', 'hyphen-ia', 'iahyphen', \
'iahyphen', 'ftp.heanet.ie', '/pub/CTAN/tex/language/hyphenation/', \
r'.*?<a href="iahyphen.tex">iahyphen.tex</a>.*?(\d\d-...-\d\d\d\d)', datestring="%d-%b-%Y"))
packagelist.append(package('http-regexp', 'hunspell-shs', 'hunspell-shs', \
'hunspell', 'secpewt.sd73.bc.ca', '/hunspell/', \
r'.*?hunspell-shs-ca.tar.gz.*?(\d\d-...-\d\d\d\d)', datestring="%d-%b-%Y"))
packagelist.append(package('http-regexp', 'hunspell-fr', 'hunspell_fr', \
'hunspell_fr', 'www.dicollecte.org', '/download.php?prj=fr', \
r'.*?hunspell.fr.classique.reforme1990-v(.*?).zip'))
packagelist.append(package('http-regexp', 'openoffice-lv', 'dict_lv_LV', \
'dict_lv_LV', 'dict.dv.lv', '/download.php?prj=lv', \
r'.*?lv_LV(.*?).oxt'))
packagelist.append(package('http-regexp', 'hyphen-fr', 'hyph_fr_FR', \
'hyph_fr_FR', 'www.dicollecte.org', '/download.php?prj=fr', \
r'.*?hyph_fr_(.*?).zip'))
packagelist.append(package('http-regexp', 'mythes-fr', 'thesaurus', \
'thesaurus', 'www.dicollecte.org', '/download.php?prj=fr', \
r'.*?thesaurus-v(.*?).zip'))
packagelist.append(package('http-regexp', 'hunspell-se', 'hunspell-se', \
'hunspell-se', 'www.divvun.no', '/index.html', \
r'.*\s+(.*?):.*?<a href="static_files/hunspell-se.tar.gz"'))
packagelist.append(package('http-regexp', 'hunspell-smj', 'hunspell-smj', \
'hunspell-smj', 'www.divvun.no', '/index.html', \
r'.*\s+(.*?):.*?<a href="static_files/hunspell-smj.tar.gz"'))
packagelist.append(package('http-regexp', 'hunspell-ko', 'hunspell-ko', \
'hunspell-dict-ko', 'code.google.com', '/p/spellcheck-ko/downloads/list', \
r'.*?hunspell-dict-ko-(.*?).tar.gz'))
packagelist.append(package('http-regexp', 'hyphen-fo', 'hyph_fo_FO', \
'hyph_fo_FO', 'fo.speling.org', '/filer/', \
r'.*?hyph_fo_FO-(\d\d\d\d\d\d\d\d).*zip'))
packagelist.append(package('http-regexp', 'hunspell-hil', 'hunspell-hil', \
'hunspell-hil', 'borel.slu.edu', '/obair/', \
r'.*?hunspell-hil-(.*?).oxt'))
packagelist.append(package('http-regexp', 'hunspell-om', 'om_ET', \
'om_ET', 'borel.slu.edu', '/obair/', \
r'.*?hunspell-om-(.*?).oxt'))
packagelist.append(package('http-regexp', 'hunspell-ca', 'hunspell-ca', \
'hunspell-ca', 'www.softcatala.org',
"/wiki/Rebost:Corrector_ortogràfic_de_català_(general)_per_a_l'OpenOffice.org", \
r'.*?\(versió (.*?)\)'))
#ftp dirs of sane packages
packagelist.append(package('ftp', 'hunspell-ak', 'akan_ns__mfuaasekyer', \
'akan_ns__mfuaasekyer', 'ftp.heanet.ie', \
'/mirrors/ftp.mozilla.org/pub/mozilla.org/addons/9978/'))
packagelist.append(package('ftp', 'hunspell-oc', 'occitan-languedocien', \
'occitan-languedocien', 'ftp.heanet.ie', \
'/mirrors/ftp.mozilla.org/pub/mozilla.org/addons/8235/'))
packagelist.append(package('ftp', 'hunspell-fy', 'frysk_wurdboek', \
'frysk_wurdboek', 'ftp.heanet.ie', \
'/mirrors/ftp.mozilla.org/pub/mozilla.org/addons/5679/'))
packagelist.append(package('ftp', 'hunspell-hsb', 'upper_sorbian_spelling_dictionary', \
'upper_sorbian_spelling_dictionary', 'ftp.heanet.ie', \
'/mirrors/ftp.mozilla.org/pub/mozilla.org/addons/3956/'))
packagelist.append(package('ftp', 'hunspell-tk', 'turkmen_spell_checker', \
'turkmen_spell_checker', 'ftp.heanet.ie', \
'/mirrors/ftp.mozilla.org/pub/mozilla.org/addons/204314/'))
#packagelist.append(package('http-last-modified', 'hunspell-fj', 'fj_FJ', \
# 'fj_FJ', 'www.foss.usp.ac.fj', '/OOo_fj/OOo_fj_FJ.zip'))
packagelist.append(package('ftp', 'hunspell-fj', 'fijian_spelling_dictionary', \
'fijian_spelling_dictionary', 'ftp.heanet.ie', \
'/mirrors/ftp.mozilla.org/pub/mozilla.org/addons/12115/'))
packagelist.append(package('ftp', 'hunspell-haw', 'hawaiian_spell_checker', \
'hawaiian_spell_checker', 'ftp.heanet.ie', \
'/mirrors/ftp.mozilla.org/pub/mozilla.org/addons/204309/'))
packagelist.append(package('ftp', 'hunspell-ru', 'rus-ispell', \
'rus-ispell', 'scon155.phys.msu.ru', '/pub/russian/ispell/'))
packagelist.append(package('ftp', 'hunspell-lt', 'lt_LT', \
'lt_LT', 'ftp.akl.lt', '/ispell-lt/'))
#horrific unversioned direct http links, off last-modified time
packagelist.append(package('http-last-modified', 'hunspell-es', 'es_ANY', \
'es_ANY', 'es.openoffice.org', '/files/documents/73/3001/es_ANY.zip'))
packagelist.append(package('http-last-modified', 'hunspell-gl', 'gl_ES-pack', \
'gl_ES-pack', 'openoffice.mancomun.org', '/libreeengalego/Corrector/gl_ES-pack.zip'))
packagelist.append(package('http-last-modified', 'hunspell-hr', 'hr_HR', \
'hr_HR', 'cvs.linux.hr', '/spell/myspell/hr_HR.zip'))
packagelist.append(package('http-last-modified', 'hunspell-eu', 'eu-ES-hunspell', \
'eu-ES-hunspell', 'www.euskara.euskadi.net',\
'/r59-20660/eu/contenidos/informacion/euskarazko_softwarea/eu_9567/adjuntos/eu-ES-hunspell.tar.gz'))
packagelist.append(package('http-last-modified', 'hunspell-mt', 'spellcheck-mt', \
'spellcheck-mt', 'linux.org.mt', '/downloads/spellcheck-mt-0.3.tar.gz'))
#packagelist.append(package('http-last-modified', 'hunspell-ia', 'ia_myspell', \
# 'ia_myspell', 'download.savannah.gnu.org', '/releases/interlingua/ia_myspell.zip'))
packagelist.append(package('http-last-modified', 'hunspell-ia', 'ia_myspell', \
'ia_myspell', 'nongnu.uib.no', '/interlingua/ia_myspell.zip'))
packagelist.append(package('http-last-modified', 'hunspell-quh', 'quh_BO-pack', \
'quh_BO-pack', 'www.runasimipi.org', '/quh_BO-pack.zip'))
packagelist.append(package('http-last-modified', 'hunspell-am', 'am_ET', \
'am_ET', 'www.cs.ru.nl', '/~biniam/geez/dict/am_ET.zip'))
packagelist.append(package('http-last-modified', 'hunspell-ti', 'ti_ER', \
'ti_ER', 'www.cs.ru.nl', '/~biniam/geez/dict/ti_ER.zip'))
packagelist.append(package('http-last-modified', 'hunspell-mos', 'mos_BF', \
'mos_BF', 'abcburkina.net', '/ancien/documents/lingu/DicoMoore.zip'))
#horrific unversioned direct ftp dirs, off last-modified time
packagelist.append(package('ftp-last-modified', 'hunspell-az', 'aspell-az', \
'aspell-az', 'ftp.gnu.org', '/gnu/aspell/dict/az/'))
packagelist.append(package('ftp-last-modified', 'hunspell-csb', 'aspell-csb', \
'aspell-csb', 'ftp.gnu.org', '/gnu/aspell/dict/csb/'))
packagelist.append(package('ftp-last-modified', 'hunspell-fa', 'aspell-fa', \
'aspell-fa', 'ftp.gnu.org', '/gnu/aspell/dict/fa/'))
packagelist.append(package('ftp-last-modified', 'hunspell-gv', 'aspell-gv', \
'aspell-gv', 'ftp.gnu.org', '/gnu/aspell/dict/gv/'))
packagelist.append(package('ftp-last-modified', 'hunspell-ky', 'aspell-ky', \
'aspell-ky', 'ftp.gnu.org', '/gnu/aspell/dict/ky/'))
#horrific unversioned svn, off svn propget svn:date --revprop -rHEAD
packagelist.append(package('svn-propget-date', 'hunspell-en', 'en_US', \
'en_US', 'wordlist.svn.sourceforge.net', '/svnroot/wordlist/trunk/'))
packagelist.append(package('svn-propget-date', 'zaf', 'hyph_af_ZA', \
'hyph_af_ZA', 'zaf.svn.sourceforge.net', '/svnroot/zaf/trunk/dict/af/hyph/hyph_af_ZA.dic',
ispost=0))
packagelist.append(package('svn-propget-date', 'zaf', 'hyph_zu_ZA', \
'hyph_zu_ZA', 'zaf.svn.sourceforge.net', '/svnroot/zaf/trunk/dict/zu/hyph/hyph_zu_ZA.dic',
ispost=0))
#sane gnome packages
packagelist.append(package('gnome', 'libgsf'))
packagelist.append(package('gnome', 'planner'))
#sane sourceforge packages
packagelist.append(package('sourceforge', 'hunspell', 'hunspell', 'Hunspell'))
packagelist.append(package('sourceforge', 'libcmis', 'libcmis', 'libcmis'))
packagelist.append(package('sourceforge', 'hyphen', 'hunspell', 'Hyphen'))
packagelist.append(package('sourceforge', 'mythes', 'hunspell', 'MyThes'))
packagelist.append(package('sourceforge', 'libwpd'))
packagelist.append(package('sourceforge', 'libwmf', 'wvware', 'libwmf'))
packagelist.append(package('sourceforge', 'mythes-pl', 'synonimy', 'synonimy'))
packagelist.append(package('sourceforge', 'hunspell-bg', 'bgoffice', 'OpenOffice.org Spell BG'))
packagelist.append(package('sourceforge', 'hyphen-bg', 'bgoffice', 'OpenOffice.org Hyphenation BG'))
packagelist.append(package('sourceforge', 'mythes-bg', 'bgoffice', 'OpenOffice.org Thesaurus BG'))
packagelist.append(package('sourceforge', 'hunspell-hu', 'magyarispell', 'Magyar Ispell'))
packagelist.append(package('sourceforge', 'hunspell-it', 'linguistico', 'Dizionario italiano per
OOo', ispost=0))
packagelist.append(package('sourceforge', 'mythes-it', 'linguistico', 'Thesaurus OOo 2.x.x',
ispost=1, fixrule=('02_0','02_0_')))
packagelist.append(package('sourceforge', 'hunspell-uk', 'ispell-uk', 'spell-uk'))
packagelist.append(package('sourceforge', 'mythes-uk', 'ispell-uk', 'spell-uk'))
packagelist.append(package('sourceforge', 'hunspell-ro', 'rospell', 'Romanian dictionaries'))
packagelist.append(package('sourceforge', 'hyphen-ro', 'rospell', 'Romanian dictionaries'))
packagelist.append(package('sourceforge', 'mythes-ro', 'rospell', 'Romanian dictionaries'))
packagelist.append(package('sourceforge', 'hunspell-ku', 'myspellkurdish', 'MySpell'))
packagelist.append(package('sourceforge', 'hunspell-hy', 'armspell', 'myspell-hy'))
packagelist.append(package('sourceforge', 'hunspell-nds', 'aspell-nds', 'hunspell-nds'))
packagelist.append(package('sourceforge', 'hunspell-ln', 'lingala', 'hunspell-ln'))
packagelist.append(package('sourceforge', 'jcommon', 'jfreechart', '3. JCommon', fixrule=('Version
','')))
packagelist.append(package('sourceforge', 'lpsolve'))
packagelist.append(package('sourceforge', 'silgraphite'))
packagelist.append(package('http-regexp', 'libbase', 'jfreereport', \
'libbase', 'www.mirrorservice.org',
'/sites/download.sourceforge.net/pub/sourceforge/j/project/jf/jfreereport/02.%20Libraries/1.1.2-stable/',
\
r'.*?>libbase-(.*?).zip<'))
packagelist.append(package('http-regexp', 'libserializer', 'jfreereport', \
'libserializer', 'www.mirrorservice.org',
'/sites/download.sourceforge.net/pub/sourceforge/j/project/jf/jfreereport/02.%20Libraries/1.1.2-stable/',
\
r'.*?>libserializer-(.*?).zip<'))
packagelist.append(package('http-regexp', 'libloader', 'jfreereport', \
'libloader', 'www.mirrorservice.org',
'/sites/download.sourceforge.net/pub/sourceforge/j/project/jf/jfreereport/02.%20Libraries/1.1.2-stable/',
\
r'.*?>libloader-(.*?).zip<'))
packagelist.append(package('http-regexp', 'pentaho-libxml', 'jfreereport', \
'libxml', 'www.mirrorservice.org',
'/sites/download.sourceforge.net/pub/sourceforge/j/project/jf/jfreereport/02.%20Libraries/1.1.2-stable/',
\
r'.*?>libxml-(.*?).zip<'))
packagelist.append(package('http-regexp', 'libfonts', 'jfreereport', \
'libfonts', 'www.mirrorservice.org',
'/sites/download.sourceforge.net/pub/sourceforge/j/project/jf/jfreereport/02.%20Libraries/1.1.2-stable/',
\
r'.*?>libfonts-(.*?).zip<'))
packagelist.append(package('http-regexp', 'libformula', 'jfreereport', \
'libformula', 'www.mirrorservice.org',
'/sites/download.sourceforge.net/pub/sourceforge/j/project/jf/jfreereport/02.%20Libraries/1.1.2-stable/',
\
r'.*?>libformula-(.*?).zip<'))
packagelist.append(package('http-regexp', 'librepository', 'jfreereport', \
'librepository', 'www.mirrorservice.org',
'/sites/download.sourceforge.net/pub/sourceforge/j/project/jf/jfreereport/02.%20Libraries/1.1.2-stable/',
\
r'.*?>librepository-(.*?).zip<'))
packagelist.append(package('http-regexp', 'flute', 'jfreereport', \
'flute', 'www.mirrorservice.org',
'/sites/download.sourceforge.net/pub/sourceforge/j/project/jf/jfreereport/30.%20OpenOffice%20Branches/OOo31/',
\
r'.*?>flute-(.*?).zip<', ispost=1))
packagelist.append(package('http-regexp', 'liblayout', 'jfreereport', \
'liblayout', 'www.mirrorservice.org',
'/sites/download.sourceforge.net/pub/sourceforge/j/project/jf/jfreereport/30.%20OpenOffice%20Branches/OOo31/',
\
r'.*?>liblayout-(.*?).zip<', ispost=1))
packagelist.append(package('http-regexp', 'pentaho-reporting-flow-engine', 'jfreereport', \
'flow-engine', 'www.mirrorservice.org',
'/sites/download.sourceforge.net/pub/sourceforge/j/project/jf/jfreereport/30.%20OpenOffice%20Branches/OOo31/',
\
r'.*?>flow-engine-(.*?).zip<', ispost=1))
packagelist.append(package('http-regexp', 'jcommon-serializer', 'jfreereport', \
'jcommon-serializer', 'www.mirrorservice.org',
'/sites/download.sourceforge.net/pub/sourceforge/j/project/jf/jfreereport/99.%20Archive/07.%20JCommon-Serializer/',
\
r'.*/sites/download.*?">(.*)</A></TD>', fixrule=('-GA','')))
packagelist.append(package('http-regexp', 'hunspell-lb', 'SpellcheckerLu', \
'SpellcheckerLu', 'spellchecker.lu', '/download/openoffice/', \
r'.*?Leschten Update: <strong>(.*)</strong>'))
#packagelist = []
#packagelist.append(package('http-regexp', 'mythes-de', 'mythes-de', \
# 'mythes-de', 'www.openthesaurus.de', '/about/download', \
# r'.*?(\d\d\d\d-\d\d-\d\d)', 1))
socket.setdefaulttimeout(120) # timeout in seconds
task = packagemanager(packagelist)
task.fetch()
if len(droppedlist):
print "No SRPMS seen for",
for dropped in droppedlist:
print dropped,
print
#!/bin/env python
import sys, re, string
seps = ['-', '_', '.']
debug = 0
#define the split between name and version
#as where the first occurance of a
#-, or _, or . is followed by a number
def is_name_version_split_loc(tarball, i):
return tarball[i] in seps and tarball[i+1].isdigit()
def strip_trailing_sep(text):
while len(text) and text[-1] in seps:
text = text[:-1]
return text
def is_simple_pre_nonnumeric(nonnumeric):
nonnumeric = nonnumeric.lower()
if nonnumeric == 'rc':
return True
if nonnumeric == 'beta':
return True
if nonnumeric == 'alpha':
return True
if nonnumeric == 'dev':
return True
return False
def is_pre_nonnumeric(nonnumeric):
nonnumeric = nonnumeric.lower()
if is_simple_pre_nonnumeric(nonnumeric):
return True
for pre in 'rc', 'alpha', 'beta', 'test', 'pre', 'd0', 'dev':
if nonnumeric[0:len(pre)] == pre:
try:
num = int(nonnumeric[len(pre):])
return True
except:
pass
return False
def normalize_known_nonnumerics(nonnumeric):
newnonnumeric = nonnumeric.lower()
if newnonnumeric == 'alpha':
return newnonnumeric
if newnonnumeric == 'beta':
return newnonnumeric
if newnonnumeric == '+cvs' or newnonnumeric == 'cvs':
return 'cvs'
if newnonnumeric == '+svn' or newnonnumeric == 'svn':
return 'svn'
return nonnumeric
def is_okver_nonnumeric(nonnumeric):
nonnumerics=0
for a in nonnumeric:
if not a.isdigit():
nonnumerics = nonnumerics + 1
if nonnumerics == 1:
return True
return False
def is_post_nonnumeric(nonnumeric):
nonnumeric = nonnumeric.lower()
if nonnumeric == '+cvs':
return True
if nonnumeric == '+svn':
return True
return False
def has_ambiguous_nonnumeric(chunks):
ret = False
for chunk in chunks:
if chunk[1] == 0:
if is_okver_nonnumeric(chunk[0]):
continue
if is_post_nonnumeric(chunk[0]):
continue
if is_pre_nonnumeric(chunk[0]):
continue
ret = True
break
return ret
def easydateable(version):
return len(version) == 0 or version == "0" or version == "0.0"
def isrunawayprelease(version, date, nonnumeric):
return (version == '0.1' or version == '0') and nonnumeric and nonnumeric.lower() == 'beta'
and date
class NVRException(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class PrePostError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
def is_pre_vr(vr):
return (vr == '0' or vr == '0.0' or vr == '0.1')
def has_date(chunks):
ret = False
for chunk in chunks:
if chunk[1] == 2:
ret = True
break
return ret
def ishexdigit(char):
return char in string.hexdigits
#allow 1.1f but enforce 1.1.foo
#don't allow d01/d02
def issimplehexstring(strng):
if len(strng) > 2:
return 0
return filter(ishexdigit, strng) == strng
def first_nonsimple_index(chunks, ispost=-1):
chunkcount = len(chunks)
lastchunk = 0
for i in range(0, chunkcount):
if chunks[i][1] == 2:
break
# if chunks[i][1] == 0 and (len(chunks[i][0]) > 1 or ispost != -1):
if chunks[i][1] == 0 and ((not issimplehexstring(chunks[i][0])) or ispost == 0):
break
lastchunk = i+1
return lastchunk
def fix_broken_ver(vr):
if len(vr) == 0:
vr = '0'
elif len(vr) > 1 and vr[0] == '0':
pos = vr.find('.')
if pos == -1:
vr = vr[0] + '.' + vr[1:]
elif pos != 1:
vr = vr[1:]
return vr
def generate_fedora_vr(chunks, ispost=-1):
vr = ''
lastchunk = first_nonsimple_index(chunks, ispost)
if debug: print 'pre/post status is', ispost, 'lastchunk is', lastchunk
for i in range(0, lastchunk):
if len(vr) > 0:
#allow 1.1f but enforce 1.1.foo
if not (i > 0 and chunks[i][1] == 0 and (len(chunks[i][0]) == 1 or
issimplehexstring(chunks[i][0])) and chunks[i-1][1] == 1):
vr = vr + '.'
vr = vr + chunks[i][0]
vr = fix_broken_ver(vr)
if debug: print 'base vr is', vr
if debug: print 'lastchunk is', lastchunk
if ispost == -1 and is_pre_vr(vr) and has_date(chunks):
newchunks = []
for chunk in chunks:
if chunk[1] == 0 and is_simple_pre_nonnumeric(chunk[0]):
continue
newchunks.append(chunk)
chunks = newchunks
lastchunk = first_nonsimple_index(chunks, ispost)
vr = '0'
for chunk in chunks:
if chunk[1] == 0:
if is_pre_nonnumeric(chunk[0]):
ispost = 0
elif is_post_nonnumeric(chunk[0]):
ispost = 1
if debug: print 'pre/post status is', ispost
if has_ambiguous_nonnumeric(chunks) and ispost not in [1, 0]:
raise PrePostError("Can't guess if pre/post due to nonnumeric text in" +
str(chunks))
if has_date(chunks) and ispost not in [1, 0] and not is_pre_vr(vr):
raise PrePostError("Can't guess if pre/post due to a date")
if ispost == 0 and len(chunks) > lastchunk:
vr = vr + '-' + '0.1'
elif ispost == 1:
vr = vr + '-' + '1'
if debug: print 'vr is now', vr
for i in range(lastchunk, len(chunks)):
if i > lastchunk and chunks[i][1] == 2 and chunks[i-1][1] == 0:
tempchunk = chunks[i]
chunks[i] = chunks[i-1]
chunks[i-1] = tempchunk
for i in range(lastchunk, len(chunks)):
if len(vr) > 0 and not (chunks[i-1][1] == 2 and chunks[i][1] == 0):
vr = vr + '.'
vr = vr + normalize_known_nonnumerics(chunks[i][0])
if debug: print 'and vr is now', vr
if vr.find('-') == -1:
vr = vr + '-1'
if debug: print 'vr is finally', vr
return vr
# if has_ambiguous_nonnumeric(chunks) and ispost not in [1, 0]:
# raise PrePostError("Can't guess if pre/post due to " + chunks)
# if date and ispost not in [1, 0] and not (easydateable(version) or nonnumeric):
# raise PrePostError("Can't guess if pre/post due to " + date)
# if len(version) == 0:
# version = "0"
#
# if (nonnumeric or date) and ispost not in [1, 0]:
# if nonnumeric:
# if isrunawayprelease(version, date, nonnumeric):
# ispost = -1
# nonnumeric = None
# version = "0"
# elif is_pre_nonnumeric(nonnumeric):
# ispost = 0
# elif is_post_nonnumeric(nonnumeric):
# ispost = 1
#
# if len(version) > 1 and version[0] == '0' and version[1].isdigit():
# version = version[0] + '.' + version[1:]
#
# if nonnumeric or date:
# if ispost == 1:
# version = version + '-' + '1.'
# elif ispost == 0:
# version = version + '-' + '0.1.'
#
# version = version.replace('%{X}', '1')
#
# if date:
# if version[-1].isdigit():
# version = version + '.' + date
# else:
# version = version + date
#
# if nonnumeric:
# if version[-1] != '.' and not date and not is_okver_nonnumeric(nonnumeric):
# version = version + '.'
# version = version + normalize_known_nonnumerics(nonnumeric)
#
# if version.find('-') == -1:
# version = version + '-1'
#
# return version
def determine_type(chunk, isnumber):
number = int(isnumber)
if len(chunk) == 8 and chunk.isdigit():
#make an effort to fix a reversed date
if int(chunk[0:4]) < 1900 and int(chunk[4:8]) > 1900:
chunk = chunk[4:8]+chunk[2:4]+chunk[0:2]
number = 2
else:
chunk = chunk.strip()
return chunk, number
def split_version_date_nonnumeric(version):
date = None
version = version.replace('-', '.').replace('_', '.')
pattern = r'.*?(\d\d\d\d[-_\.]\d\d[-_\.]\d)[^\d]'
p = re.compile(pattern)
m = p.match(version)
if m:
date = m.group(1)
version = version[:m.start(1)] + \
m.group(1)[0:-1] + '0' + m.group(1)[-1] + \
version[m.end(1):]
pattern = r'.*?(\d\d\d\d[-_\.]?\d\d[-_\.]?\d\d)'
p = re.compile(pattern)
m = p.match(version)
if m:
date = m.group(1)
for sep in seps:
date = date.replace(sep, '')
pre = version[:m.start(1)]
if len(pre) > 1 and pre[-1] != '.':
pre = pre + '.'
post = version[m.end(1):]
if len(post) > 1 and post[0] != '.':
post = '.' + post
version = pre + date + post
chunks = []
chunk = ''
isnumber = True
for c in version:
if chunk == '':
isnumber = c.isdigit()
if isnumber and c.isdigit():
chunk = chunk + c
elif not isnumber and c != '.':
chunk = chunk + c
elif c == '.':
chunks.append(determine_type(chunk, isnumber))
chunk = ''
else:
chunks.append(determine_type(chunk, isnumber))
chunk = c
isnumber = c.isdigit()
chunks.append(determine_type(chunk, isnumber))
if debug: print chunks
return chunks
def split_name_version(tarball, prefix):
version = None
name = None
suffixes = [
'_source.tar.bz2', '_source.tar.gz', '_source.tar.zip',
'_src.bz2', '_src.gz', '_src.zip',
'.tar.bz2', '.tar.gz', '.tgz', '-pack.zip', '.zip',
'-fx+tb+sm.xpi', '-fx+zm+tb.xpi', '-fx+tb.xpi',
'-tb+fx+sm.xpi', '-fx.xpi', '.xpi', '.oxt' ]
if tarball[:len(prefix)] == prefix:
for suffix in suffixes:
if tarball[-len(suffix):] == suffix:
name = prefix
for i in range(len(prefix),len(tarball)-len(suffix)):
if is_name_version_split_loc(tarball, i):
break
name = name + tarball[i]
version=tarball[len(name)+1:len(tarball)-len(suffix)]
break
return name, version
def make_nvr(origname, prefix='', ispost=-1):
if debug: print 'origname is', origname
name, version = split_name_version(origname, prefix)
if debug: print 'name', 'version', name, version
if name == None or version == None:
raise NVRException('Unrecognized format for ' + origname)
chunks = split_version_date_nonnumeric(version)
if debug: print 'chunks', chunks
ret = generate_fedora_vr(chunks, ispost)
vr = ret.split('-')
if debug: print 'nvr', vr
return name, vr[0], vr[1]
def get_nvr(srcrpm, ispost=-1):
suffix = '.src.rpm'
if srcrpm[-len(suffix):] == suffix:
suf = -len(suffix)
rel = suf
while srcrpm[rel] != '-':
rel = rel - 1
release = srcrpm[rel+1:suf]
if ispost == 1:
postbit = release.find('.')
release = '1' + release[postbit:]
ver = rel-1
while srcrpm[ver] != '-':
ver = ver - 1
version = srcrpm[ver+1:rel]
name = srcrpm[0:ver]
if debug: print 'making', name, version, release, 'from', srcrpm
return name, version, release
return None
def scrub_disttag(release):
knowntags =[ '.fc7', '.fc8', '.fc9', '.fc10', '.fc11', '.fc12', '.fc13', '.fc14', '.fc15',
'.fc16', '.fc17' ]
for tag in knowntags:
release = release.replace(tag, '')
return release
def undo_prerelease(release):
chunks = release.split('.')
if chunks > 2 and chunks[0] == '0':
try:
anum = int(chunks[1])
except:
pass
release = chunks[0] + '.1'
for chunk in chunks[2:]:
release = release + '.' + chunk
return release
def rpmsplit(instr):
chunks = []
chunk = ''
for c in instr:
if chunk == '':
mode = c.isdigit()
if not c.isalnum():
chunks.append(chunk)
chunk = ''
elif mode == c.isdigit():
chunk = chunk + c
else:
chunks.append(chunk)
chunk = c
mode = c.isdigit()
chunks.append(chunk)
return chunks
def compare_key(a, b):
abits = rpmsplit(a)
bbits = rpmsplit(b)
min = len(abits)
if min > len(bbits):
min = len(bbits)
for i in range(0, min):
aisnum = True
bisnum = True
try:
anum = int(abits[i])
except:
aisnum = False
pass
try:
bnum = int(bbits[i])
except:
bisnum = False
pass
if aisnum and bisnum:
if anum > bnum:
return 1
elif anum < bnum:
return -1
elif not aisnum and not bisnum:
if abits[i] > bbits[i]:
return 1
elif bbits[i] > abits[i]:
return -1
else:
if aisnum > bisnum:
return 1
elif aisnum < bisnum:
return -1
if len(abits) > len(bbits):
return 1
elif len(bbits) > len(abits):
return -1
return 0
def compare_vr(aver, bver, arel, brel):
ret = compare_key(aver, bver)
if ret == 0:
ret = compare_key(arel, brel)
return ret
if __name__ == "__main__":
upstreamnames = [
'hunspell-1.1.tar.gz',
'italiano_2_4_2007_09_01.zip',
'upper_sorbian_spelling_dictionary-0.0.20060327.2-fx+tb+sm.xpi',
'foo-1.1-beta1.zip',
'foo-2009.10.10-beta-1.oxt'
]
#'th_ro_RO.3.3-test3.zip'
for origname in upstreamnames:
try:
name, version, release = make_nvr(origname)
print name, version, release
except PrePostError:
pass
srcrpms = [
'hunspell-it-2.4-0.99.20070901.fc8.src.rpm',
]
for rpm in srcrpms:
rpmname, rpmversion, rpmrelease = get_nvr(rpm)
rpmrelease = scrub_disttag(rpmrelease)
rpmrelease = undo_prerelease(rpmrelease)
print rpmname, rpmversion, rpmrelease
print compare_vr(rpmversion, version, rpmrelease, release)
Context
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.