| 1 |
#!/usr/bin/python
|
| 2 |
|
| 3 |
#
|
| 4 |
# This Python script is:
|
| 5 |
# (C) 2007, David Paleino <d.paleino@gmail.com>
|
| 6 |
#
|
| 7 |
# It is licensed under the terms of GNU General Public License (GPL)
|
| 8 |
# v3, or any later revision.
|
| 9 |
#
|
| 10 |
|
| 11 |
from urllib import urlopen, urlretrieve
|
| 12 |
import re
|
| 13 |
import HTMLTemplate
|
| 14 |
from datetime import datetime
|
| 15 |
from email.Utils import formatdate
|
| 16 |
import time
|
| 17 |
from Tools import parseTasks, grep
|
| 18 |
|
| 19 |
base = "/var/lib/gforge/chroot/home/groups/debian-med"
|
| 20 |
#base = "/home/neo/tmp/debmed"
|
| 21 |
ddtp_url = "http://ddtp.debian.net/debian/dists/sid/main/i18n/Translation-%s"
|
| 22 |
fetch_url = "http://kleptog.org/cgi-bin/ddtss2-cgi/%s/fetch?package=%s"
|
| 23 |
trans_url = "http://kleptog.org/cgi-bin/ddtss2-cgi/%s/translate/%s"
|
| 24 |
|
| 25 |
# Should we dinamically get this list from PO translations
|
| 26 |
# of the website?
|
| 27 |
langs = ["de", "fr", "it", "pt_BR", "es", "ja"]
|
| 28 |
langs.sort()
|
| 29 |
|
| 30 |
dict = {}
|
| 31 |
longs = {}
|
| 32 |
shorts = {}
|
| 33 |
|
| 34 |
#['adun.app', 'amap-align', 'amide', 'arb', 'bioimagesuite', 'bioperl', 'biosquid', 'blast2', 'boxshade', 'chemtool',
|
| 35 |
#'cimg-dev', 'clustalw', 'clustalw-mpi', 'clustalx', 'ctn', 'ctn-dev', 'ctsim', 'cycle', 'dcmtk', 'dialign',
|
| 36 |
#'dialign-t', 'dicomnifti', 'emboss', 'fastdnaml', 'fastlink', 'garlic', 'gdpc', 'gff2aplot', 'gff2ps', 'ghemical',
|
| 37 |
#'gnumed-client', 'gromacs', 'hmmer', 'imagej', 'kalign', 'libbio-ruby', 'libfslio0', 'libfslio0-dev',
|
| 38 |
#'libinsighttoolkit-dev', 'libmdc2-dev', 'libminc0-dev', 'libncbi6-dev', 'libniftiio0', 'libniftiio0-dev', 'loki',
|
| 39 |
#'mcl', 'medcon', 'melting', 'mencal', 'minc-tools', 'mipe', 'molphy', 'mummer', 'muscle', 'ncbi-epcr',
|
| 40 |
#'ncbi-tools-bin', 'ncbi-tools-x11', 'nifti-bin', 'njplot', 'octave', 'octave2.1', 'paw++', 'perlprimer', 'phylip',
|
| 41 |
#'poa', 'primer3', 'probcons', 'proda', 'pymol', 'python-biopython', 'python-nifti', 'r-base', 'r-base-core',
|
| 42 |
#'r-cran-qtl', 'rasmol', 'readseq', 'seaview', 'sibsim4', 'sigma-align', 'sim4', 't-coffee', 'tigr-glimmer',
|
| 43 |
#'tm-align', 'tree-ppuzzle', 'tree-puzzle', 'treetool', 'treeviewx', 'wise', 'xmedcon', 'zope-zms']
|
| 44 |
|
| 45 |
def force_fetch(packages, lang = langs):
|
| 46 |
global langs
|
| 47 |
|
| 48 |
# If it's a single language to be updated...
|
| 49 |
#
|
| 50 |
# NOT USED CURRENTLY.
|
| 51 |
if type(lang) == "str":
|
| 52 |
for name in packages:
|
| 53 |
urlopen(fetch_url % (lang, name))
|
| 54 |
else:
|
| 55 |
for lang_name in lang:
|
| 56 |
for pkg_name in packages:
|
| 57 |
#print "Fetching %s - %s" % (lang_name, pkg_name)
|
| 58 |
urlopen(fetch_url % (lang_name, pkg_name))
|
| 59 |
|
| 60 |
def get_status(package):
|
| 61 |
global dict
|
| 62 |
global langs
|
| 63 |
status = {}
|
| 64 |
|
| 65 |
for lang in langs:
|
| 66 |
# print "Parsing %s - %s" % (package, lang)
|
| 67 |
if grep("Package: %s\n" % package, "%s/data/ddtp/Translation-%s" % (base, lang)):
|
| 68 |
status[lang] = 1
|
| 69 |
else:
|
| 70 |
status[lang] = 0
|
| 71 |
|
| 72 |
dict[package] = status
|
| 73 |
|
| 74 |
def parse_description(package):
|
| 75 |
global dict
|
| 76 |
global longs
|
| 77 |
global shorts
|
| 78 |
|
| 79 |
tmp_long = {}
|
| 80 |
tmp_short = {}
|
| 81 |
for lang in langs:
|
| 82 |
if dict[package][lang]:
|
| 83 |
f = open("%s/data/ddtp/Translation-%s" % (base, lang), "r")
|
| 84 |
# Package: 9wm\nDescription-md5: (?P<md5sum>.{32})\nDescription-\w+: (?P<short>.*)\n(?P<long>.*\n)\n
|
| 85 |
# TODO: Fix the regex. (it worked in Kodos :()
|
| 86 |
regex = r"""Package: %s
|
| 87 |
Description-md5: (?P<md5sum>.{32})
|
| 88 |
Description-\w+: (?P<short>.*)
|
| 89 |
(?P<long>(^ .*$\n)+\n?)""" % package
|
| 90 |
|
| 91 |
p = re.compile(regex, re.MULTILINE)
|
| 92 |
m = p.search(f.read())
|
| 93 |
if m:
|
| 94 |
tmp_long[lang] = m.group("long").replace("\n ", "<br />").replace("<br />.<br />", "<br /><br />")
|
| 95 |
tmp_short[lang] = m.group("short")
|
| 96 |
f.close()
|
| 97 |
|
| 98 |
longs[package] = tmp_long
|
| 99 |
shorts[package] = tmp_short
|
| 100 |
|
| 101 |
def renderTemplate(node, langs, statuses):
|
| 102 |
node.langs.repeat(renderLangs, langs)
|
| 103 |
|
| 104 |
names = statuses.keys()
|
| 105 |
names.sort()
|
| 106 |
|
| 107 |
node.packages.repeat(renderStatuses, names, statuses)
|
| 108 |
|
| 109 |
t = datetime.now()
|
| 110 |
node.date.content = formatdate(time.mktime(t.timetuple()))
|
| 111 |
|
| 112 |
def renderLangs(node, lang):
|
| 113 |
node.code.raw = "<img src=\"/img/langs/%s.png\" alt=\"%s\" />" % (lang, lang)
|
| 114 |
|
| 115 |
def renderStatuses(node, package, status):
|
| 116 |
node.name.raw = '<a href="/ddtp/%s.php">%s</a>' % (package, package)
|
| 117 |
|
| 118 |
langs = dict[package].keys()
|
| 119 |
langs.sort()
|
| 120 |
|
| 121 |
node.translations.repeat(renderTrans, langs, package, dict[package])
|
| 122 |
|
| 123 |
def renderTrans(node, lang, package, status):
|
| 124 |
if status[lang] == 0:
|
| 125 |
node.status.raw = '<a href="%s"><img src="/img/no.png" alt="no" title="%s - <?=_("translation not available")?>" /></a>' % (trans_url % (lang, package), lang)
|
| 126 |
else:
|
| 127 |
node.status.raw = '<a href="%s"><img src="/img/ok.png" alt="<?=_("yes")?>" title="%s - <?=_("translated")?>" /></a><a href="%s"><img src="/img/go.png" alt="<?=_("edit")?>" title="%s - <?=_("edit translation")?>" /></a>' % ("/ddtp/%s.php" % package, lang, trans_url % (lang, package), lang)
|
| 128 |
|
| 129 |
#tem:
|
| 130 |
# con:package
|
| 131 |
# rep:langs
|
| 132 |
# con:name
|
| 133 |
# con:short
|
| 134 |
# con:long
|
| 135 |
def renderStatic(node, package):
|
| 136 |
node.package.content = package
|
| 137 |
node.langs.repeat(renderSingleTrans, dict[package], package)
|
| 138 |
|
| 139 |
t = datetime.now()
|
| 140 |
node.date.content = formatdate(time.mktime(t.timetuple()))
|
| 141 |
|
| 142 |
def renderSingleTrans(node, lang, package):
|
| 143 |
node.name.raw = '<img src="/img/langs/%s.png" alt="%s" title="%s"/>' % (lang, lang, lang)
|
| 144 |
if dict[package][lang]:
|
| 145 |
node.short.raw = shorts[package][lang]
|
| 146 |
node.long.raw = longs[package][lang]
|
| 147 |
else:
|
| 148 |
node.short.raw = '<?=_("untranslated")?>'
|
| 149 |
node.long.raw = '<?=_("untranslated")?><br /><?=_("Please follow the link below to start translating")?>:<br /><br /><a href="%s">%s</a>' % (trans_url % (lang, package), trans_url % (lang, package))
|
| 150 |
|
| 151 |
for lang in langs:
|
| 152 |
url = ddtp_url % lang
|
| 153 |
pos = url.rfind("/")
|
| 154 |
name = "%s/data/ddtp/%s" % (base, url[pos + 1:])
|
| 155 |
urlretrieve(url, name)
|
| 156 |
|
| 157 |
packages = parseTasks()
|
| 158 |
#packages = ["adun.app", "gcc", "emboss-explorer"]
|
| 159 |
packages.sort()
|
| 160 |
|
| 161 |
# XXX TODO HACK NEWS
|
| 162 |
# Re-enable this to force-fetch the packages.
|
| 163 |
# Shouldn't be done unless having talked to DDTSS admins.
|
| 164 |
# -- David
|
| 165 |
#force_fetch(packages)
|
| 166 |
for item in packages:
|
| 167 |
get_status(item)
|
| 168 |
parse_description(item)
|
| 169 |
|
| 170 |
#print dict
|
| 171 |
#print longs
|
| 172 |
#print shorts
|
| 173 |
|
| 174 |
# Let's generate the overview page
|
| 175 |
f = open("%s/htdocs/ddtp.tmpl" % base)
|
| 176 |
tmpl = HTMLTemplate.Template(renderTemplate, f.read())
|
| 177 |
f.close()
|
| 178 |
|
| 179 |
f = open("%s/static/ddtp.php" % base, "w")
|
| 180 |
f.write(tmpl.render(langs, dict))
|
| 181 |
f.close()
|
| 182 |
|
| 183 |
# Let's generate nice static overview per-package pages
|
| 184 |
for name in packages:
|
| 185 |
outfile = "%s/static/ddtp/%s.php" % (base, name)
|
| 186 |
f = open("%s/htdocs/ddtp_details.tmpl" % base)
|
| 187 |
tmpl = HTMLTemplate.Template(renderStatic, f.read())
|
| 188 |
f.close()
|
| 189 |
|
| 190 |
# print tmpl.structure()
|
| 191 |
|
| 192 |
f = open(outfile, "w")
|
| 193 |
f.write(tmpl.render(name))
|
| 194 |
f.close()
|