julen / pootle

Web-based translation and translation management tool

This URL has Read+Write access

pootle / pootle.py
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 1 #!/usr/bin/env python
a953d6ab » davidfraser 2005-07-01 added encoding markers for ... 2 # -*- coding: utf-8 -*-
d8ec3e47 » dwaynebailey 2006-06-15 [Forwardport] Update copyri... 3 #
4 # Copyright 2004-2006 Zuza Software Foundation
5 #
6 # This file is part of translate.
7 #
8 # translate is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
12 #
13 # translate is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with translate; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 21
22 from jToolkit.web import server
b00bca80 » davidfraser 2006-04-26 [forwardport from Pootle-ki... 23 from jToolkit.web import templateserver
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 24 from jToolkit.web import session
25 from jToolkit import prefs
26 from jToolkit import localize
27 from jToolkit.widgets import widgets
6ec9b636 » davidfraser 2005-06-28 added module filelocations ... 28 from jToolkit.widgets import spellui
e76c8b73 » friedelwolff 2006-06-14 Enable caching for CSS, JS,... 29 from jToolkit.widgets import thumbgallery
f64ab86c » davidfraser 2005-06-26 moved option parsing into a... 30 from jToolkit.web import simplewebserver
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 31 from Pootle import indexpage
32 from Pootle import adminpages
33 from Pootle import translatepage
34 from Pootle import pagelayout
35 from Pootle import projects
36 from Pootle import potree
db0d83a0 » friedelwolff 2007-06-20 Fix incorrect function call... 37 from Pootle import pootlefile
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 38 from Pootle import users
6ec9b636 » davidfraser 2005-06-28 added module filelocations ... 39 from Pootle import filelocations
24ff0e2f » andreaspauley 2007-01-22 Used the warning method def... 40 from translate.misc import optrecurse
4a8b56ea » dwaynebailey 2006-07-18 Add version info for kid an... 41 # Versioning information
c677c29e » dwaynebailey 2006-06-01 [Forwardport] pass through ... 42 from Pootle import __version__ as pootleversion
43 from translate import __version__ as toolkitversion
44 from jToolkit import __version__ as jtoolkitversion
49ca02f8 » winterstream 2008-07-01 Merged in changes from bran... 45 from Pootle import statistics
08972f30 » dwaynebailey 2007-07-10 Fix ElementTree import for ... 46 try:
08083c40 » friedelwolff 2007-07-10 Fix the ElementTree import ... 47 from xml.etree import ElementTree
08972f30 » dwaynebailey 2007-07-10 Fix ElementTree import for ... 48 except ImportError:
49 from elementtree import ElementTree
4cbd92c0 » friedelwolff 2006-07-10 Import kid, so we know if i... 50 # We don't need kid in this file, but this will show quickly if it is not
51 # installed. jToolkit won't complain, so we have to stop here if we don't have kid
52 import kid
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 53 import sys
54 import os
dfb6361c » friedelwolff 2007-05-16 Changed obsolete sre refere... 55 import re
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 56 import random
b00bca80 » davidfraser 2006-04-26 [forwardport from Pootle-ki... 57 import pprint
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 58
b00bca80 » davidfraser 2006-04-26 [forwardport from Pootle-ki... 59 class PootleServer(users.OptionalLoginAppServer, templateserver.TemplateServer):
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 60 """the Server that serves the Pootle Pages"""
61 def __init__(self, instance, webserver, sessioncache=None, errorhandler=None, loginpageclass=users.LoginPage):
62 if sessioncache is None:
63 sessioncache = session.SessionCache(sessionclass=users.PootleSession)
64 self.potree = potree.POTree(instance)
65 super(PootleServer, self).__init__(instance, webserver, sessioncache, errorhandler, loginpageclass)
b00bca80 » davidfraser 2006-04-26 [forwardport from Pootle-ki... 66 self.templatedir = filelocations.templatedir
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 67 self.setdefaultoptions()
68
b00bca80 » davidfraser 2006-04-26 [forwardport from Pootle-ki... 69 def loadurl(self, filename, context):
70 """loads a url internally for overlay code"""
c677c29e » dwaynebailey 2006-06-01 [Forwardport] pass through ... 71 # print "call to load %s with context:\n%s" % (filename, pprint.pformat(context))
b00bca80 » davidfraser 2006-04-26 [forwardport from Pootle-ki... 72 filename = os.path.join(self.templatedir, filename+os.extsep+"html")
73 if os.path.exists(filename):
74 return open(filename, "r").read()
75 return None
76
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 77 def saveprefs(self):
78 """saves any changes made to the preferences"""
79 # TODO: this is a hack, fix it up nicely :-)
80 prefsfile = self.instance.__root__.__dict__["_setvalue"].im_self
81 prefsfile.savefile()
82
83 def setdefaultoptions(self):
84 """sets the default options in the preferences"""
85 changed = False
86 if not hasattr(self.instance, "title"):
87 setattr(self.instance, "title", "Pootle Demo")
88 changed = True
89 if not hasattr(self.instance, "description"):
90 defaultdescription = "This is a demo installation of pootle. The administrator can customize the description in the preferences."
91 setattr(self.instance, "description", defaultdescription)
92 changed = True
93 if not hasattr(self.instance, "baseurl"):
94 setattr(self.instance, "baseurl", "/")
95 changed = True
0fc2f1aa » friedelwolff 2008-06-13 Enable translation while di... 96 if not hasattr(self.instance, "enablealtsrc"):
97 setattr(self.instance, "enablealtsrc", False)
98 changed = True
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 99 if changed:
100 self.saveprefs()
101
102 def changeoptions(self, argdict):
103 """changes options on the instance"""
104 for key, value in argdict.iteritems():
105 if not key.startswith("option-"):
106 continue
107 optionname = key.replace("option-", "", 1)
108 setattr(self.instance, optionname, value)
109 self.saveprefs()
110
9fc02a32 » friedelwolff 2006-08-11 Initialise the language for... 111 def initlanguage(self, req, session):
112 """Initialises the session language from the request"""
113 availablelanguages = self.potree.getlanguagecodes('pootle')
114 acceptlanguageheader = req.headers_in.getheader('Accept-Language')
115 if not acceptlanguageheader:
116 return
117
118 for langpref in acceptlanguageheader.split(","):
3fad1d0f » friedelwolff 2006-10-12 Convert the browser's Accep... 119 langpref = pagelayout.localelanguage(langpref)
9fc02a32 » friedelwolff 2006-08-11 Initialise the language for... 120 pos = langpref.find(";")
121 if pos >= 0:
122 langpref = langpref[:pos]
123 if langpref in availablelanguages:
124 session.setlanguage(langpref)
125 return
126 elif langpref.startswith("en"):
127 session.setlanguage(None)
128 return
129 session.setlanguage(None)
130
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 131 def inittranslation(self, localedir=None, localedomains=None, defaultlanguage=None):
132 """initializes live translations using the Pootle PO files"""
133 self.localedomains = ['jToolkit', 'pootle']
134 self.localedir = None
135 self.languagelist = self.potree.getlanguagecodes('pootle')
45537b69 » friedelwolff 2006-08-11 Initialse languagenames as ... 136 self.languagenames = self.potree.getlanguages()
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 137 self.defaultlanguage = defaultlanguage
138 if self.defaultlanguage is None:
7dbfaf87 » dwaynebailey 2005-05-14 Checks the prefs file for d... 139 self.defaultlanguage = getattr(self.instance, "defaultlanguage", "en")
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 140 if self.potree.hasproject(self.defaultlanguage, 'pootle'):
141 try:
142 self.translation = self.potree.getproject(self.defaultlanguage, 'pootle')
143 return
a211a05c » friedelwolff 2007-08-01 Give more information about... 144 except Exception, e:
145 self.errorhandler.logerror("Could not initialize translation:\n%s" % str(e))
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 146 # if no translation available, set up a blank translation
147 super(PootleServer, self).inittranslation()
45537b69 » friedelwolff 2006-08-11 Initialse languagenames as ... 148 # the inherited method overwrites self.languagenames, so we have to redo it
9d0620b9 » friedelwolff 2006-08-11 Initialise languagenames la... 149 self.languagenames = self.potree.getlanguages()
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 150
151 def gettranslation(self, language):
152 """returns a translation object for the given language (or default if language is None)"""
153 if language is None:
154 return self.translation
155 else:
156 try:
157 return self.potree.getproject(language, 'pootle')
a211a05c » friedelwolff 2007-08-01 Give more information about... 158 except Exception, e:
a3dbe57c » friedelwolff 2006-10-12 Don't complain if no Englis... 159 if not language.startswith('en'):
a211a05c » friedelwolff 2007-08-01 Give more information about... 160 self.errorhandler.logerror("Could not get translation for language %r:\n%s" % (language,str(e)))
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 161 return self.translation
162
5ccb20bc » davidfraser 2005-05-11 added ability to specify fi... 163 def refreshstats(self, args):
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 164 """refreshes all the available statistics..."""
5ccb20bc » davidfraser 2005-05-11 added ability to specify fi... 165 if args:
166 def filtererrorhandler(functionname, str1, str2, e):
167 print "error in filter %s: %r, %r, %s" % (functionname, str1, str2, e)
168 return False
034aa41a » friedelwolff 2007-07-18 Rename POChecker -> UnitChe... 169 checkerclasses = [projects.checks.StandardChecker, projects.checks.StandardUnitChecker]
c35ceb2c » friedelwolff 2007-07-18 Remove references to POTeeC... 170 stdchecker = projects.checks.TeeChecker(checkerclasses=checkerclasses, errorhandler=filtererrorhandler)
5ccb20bc » davidfraser 2005-05-11 added ability to specify fi... 171 for arg in args:
172 if not os.path.exists(arg):
173 print "file not found:", arg
174 if os.path.isdir(arg):
65c42c53 » davidfraser 2005-06-15 added DummyStatsProject so ... 175 if not arg.endswith(os.sep):
176 arg += os.sep
177 projectcode, languagecode = self.potree.getcodesfordir(arg)
9e8f165b » davidfraser 2005-07-02 move DummyStatsProject to p... 178 dummyproject = projects.DummyStatsProject(arg, stdchecker, projectcode, languagecode)
5ccb20bc » davidfraser 2005-05-11 added ability to specify fi... 179 def refreshdir(dummy, dirname, fnames):
65c42c53 » davidfraser 2005-06-15 added DummyStatsProject so ... 180 reldirname = dirname.replace(dummyproject.podir, "")
5ccb20bc » davidfraser 2005-05-11 added ability to specify fi... 181 for fname in fnames:
65c42c53 » davidfraser 2005-06-15 added DummyStatsProject so ... 182 fpath = os.path.join(reldirname, fname)
db0d83a0 » friedelwolff 2007-06-20 Fix incorrect function call... 183 fullpath = os.path.join(dummyproject.podir, fpath)
60d30ab2 » friedelwolff 2007-01-11 Increase the version of the... 184 #TODO: PO specific
db0d83a0 » friedelwolff 2007-06-20 Fix incorrect function call... 185 if fname.endswith(".po") and not os.path.isdir(fullpath):
05cf18b0 » friedelwolff 2007-06-20 Print error on missing file... 186 if not os.path.exists(fullpath):
187 print "file does not exist:", fullpath
188 return
5ccb20bc » davidfraser 2005-05-11 added ability to specify fi... 189 print "refreshing stats for", fpath
db0d83a0 » friedelwolff 2007-06-20 Fix incorrect function call... 190 pootlefile.pootlefile(dummyproject, fpath).statistics.updatequickstats()
5ccb20bc » davidfraser 2005-05-11 added ability to specify fi... 191 os.path.walk(arg, refreshdir, None)
65c42c53 » davidfraser 2005-06-15 added DummyStatsProject so ... 192 if projectcode and languagecode:
193 dummyproject.savequickstats()
5ccb20bc » davidfraser 2005-05-11 added ability to specify fi... 194 elif os.path.isfile(arg):
9e8f165b » davidfraser 2005-07-02 move DummyStatsProject to p... 195 dummyproject = projects.DummyStatsProject(".", stdchecker)
5ccb20bc » davidfraser 2005-05-11 added ability to specify fi... 196 print "refreshing stats for", arg
197 projects.pootlefile.pootlefile(dummyproject, arg)
198 else:
199 print "refreshing stats for all files in all projects"
200 self.potree.refreshstats()
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 201
202 def generateactivationcode(self):
203 """generates a unique activation code"""
204 return "".join(["%02x" % int(random.random()*0x100) for i in range(16)])
205
8512011e » friedelwolff 2006-08-10 Generate a robots.txt file ... 206 def generaterobotsfile(self):
207 """generates the robots.txt file"""
208 langcodes = self.potree.getlanguagecodes()
209 excludedfiles = ["login.html", "register.html", "activate.html"]
210 content = "User-agent: *\n"
211 for excludedfile in excludedfiles:
212 content += "Disallow: /%s\n" % excludedfile
213 for langcode in langcodes:
214 content += "Disallow: /%s/\n" % langcode
215 return content
216
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 217 def getpage(self, pathwords, session, argdict):
218 """return a page that will be sent to the user"""
d8fa12d6 » friedelwolff 2006-08-10 [backport] Hack to ensure w... 219 #Ensure we get unicode from argdict
220 #TODO: remove when jToolkit does this
221 newargdict = {}
222 for key, value in argdict.iteritems():
223 if isinstance(key, str):
224 key = key.decode("utf-8")
225 if isinstance(value, str):
226 value = value.decode("utf-8")
227 newargdict[key] = value
228 argdict = newargdict
84b22bcb » friedelwolff 2007-01-26 [Contributed by Lars Kruse]... 229
230 # Strip of the base url
dfb6361c » friedelwolff 2007-05-16 Changed obsolete sre refere... 231 baseurl = re.sub('http://[^/]', '', self.instance.baseurl)
84b22bcb » friedelwolff 2007-01-26 [Contributed by Lars Kruse]... 232 # Split up and remove empty parts
233 basepathwords = filter(None, baseurl.split('/'))
234 while pathwords and basepathwords and basepathwords[0] == pathwords[0]:
235 basepathwords = basepathwords[1:]
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 236 pathwords = pathwords[1:]
84b22bcb » friedelwolff 2007-01-26 [Contributed by Lars Kruse]... 237
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 238 if pathwords:
239 top = pathwords[0]
240 else:
241 top = ""
6ec9b636 » davidfraser 2005-06-28 added module filelocations ... 242 if top == 'js':
243 pathwords = pathwords[1:]
244 jsfile = os.path.join(filelocations.htmldir, 'js', *pathwords)
245 if not os.path.exists(jsfile):
246 jsfile = os.path.join(filelocations.jtoolkitdir, 'js', *pathwords)
247 if not os.path.exists(jsfile):
248 return None
249 jspage = widgets.PlainContents(None)
250 jspage.content_type = "application/x-javascript"
251 jspage.sendfile_path = jsfile
e76c8b73 » friedelwolff 2006-06-14 Enable caching for CSS, JS,... 252 jspage.allowcaching = True
6ec9b636 » davidfraser 2005-06-28 added module filelocations ... 253 return jspage
e76c8b73 » friedelwolff 2006-06-14 Enable caching for CSS, JS,... 254 elif pathwords and pathwords[-1].endswith(".css"):
255 cssfile = os.path.join(filelocations.htmldir, *pathwords)
256 if not os.path.exists(cssfile):
257 cssfile = os.path.join(filelocations.jtoolkitdir, *pathwords)
258 if not os.path.exists(cssfile):
259 return None
260 csspage = widgets.PlainContents(None)
261 csspage.content_type = "text/css"
262 csspage.sendfile_path = cssfile
263 csspage.allowcaching = True
264 return csspage
346c0e94 » zejn 2006-10-09 Removing selenium from svn ... 265 elif top in ['selenium', 'tests']:
266 picturefile = os.path.join(filelocations.htmldir, *pathwords)
6fdfe625 » zejn 2006-10-09 Adding selenium for testing... 267 picture = widgets.SendFile(picturefile)
268 if picturefile.endswith(".html"):
269 picture.content_type = 'text/html'
270 elif picturefile.endswith(".js"):
271 picture.content_type = 'text/javascript'
272 picture.allowcaching = True
273 return picture
e76c8b73 » friedelwolff 2006-06-14 Enable caching for CSS, JS,... 274 elif top == 'images':
275 pathwords = pathwords[1:]
276 picturefile = os.path.join(filelocations.htmldir, 'images', *pathwords)
277 picture = widgets.SendFile(picturefile)
278 picture.content_type = thumbgallery.getcontenttype(pathwords[-1])
279 picture.allowcaching = True
280 return picture
f7cfaa5b » friedelwolff 2006-08-04 Fix serving of .ico properly 281 elif pathwords and pathwords[-1].endswith(".ico"):
e6f8376e » friedelwolff 2006-08-03 Enable caching for favicon 282 picturefile = os.path.join(filelocations.htmldir, *pathwords)
283 picture = widgets.SendFile(picturefile)
284 picture.content_type = 'image/ico'
285 picture.allowcaching = True
286 return picture
8512011e » friedelwolff 2006-08-10 Generate a robots.txt file ... 287 elif top == "robots.txt":
288 robotspage = widgets.PlainContents(self.generaterobotsfile())
289 robotspage.content_type = 'text/plain'
290 robotspage.allowcaching = True
291 return robotspage
b00bca80 » davidfraser 2006-04-26 [forwardport from Pootle-ki... 292 elif top == "testtemplates.html":
293 return templateserver.TemplateServer.getpage(self, pathwords, session, argdict)
6ec9b636 » davidfraser 2005-06-28 added module filelocations ... 294 elif not top or top == "index.html":
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 295 return indexpage.PootleIndex(self.potree, session)
296 elif top == 'about.html':
297 return indexpage.AboutPage(session)
298 elif top == "login.html":
299 if session.isopen:
60069444 » davidfraser 2005-05-20 allow preferences to set ho... 300 returnurl = argdict.get('returnurl', None) or getattr(self.instance, 'homepage', 'home/')
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 301 return server.Redirect(returnurl)
986213fe » friedelwolff 2006-07-19 Support introtext on login ... 302 message = None
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 303 if 'username' in argdict:
304 session.username = argdict["username"]
d4b5e43b » friedelwolff 2006-09-15 Allow users to change their... 305 message = session.localize("Login failed")
986213fe » friedelwolff 2006-07-19 Support introtext on login ... 306 return users.LoginPage(session, languagenames=self.languagenames, message=message)
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 307 elif top == "register.html":
308 return self.registerpage(session, argdict)
309 elif top == "activate.html":
310 return self.activatepage(session, argdict)
311 elif top == "projects":
312 pathwords = pathwords[1:]
313 if pathwords:
314 top = pathwords[0]
315 else:
316 top = ""
317 if not top or top == "index.html":
318 return indexpage.ProjectsIndex(self.potree, session)
319 else:
320 projectcode = top
321 if not self.potree.hasproject(None, projectcode):
322 return None
323 pathwords = pathwords[1:]
324 if pathwords:
325 top = pathwords[0]
326 else:
327 top = ""
328 if not top or top == "index.html":
329 return indexpage.ProjectLanguageIndex(self.potree, projectcode, session)
330 elif top == "admin.html":
331 return adminpages.ProjectAdminPage(self.potree, projectcode, session, argdict)
332 elif top == "languages":
333 pathwords = pathwords[1:]
334 if pathwords:
335 top = pathwords[0]
336 else:
337 top = ""
338 if not top or top == "index.html":
339 return indexpage.LanguagesIndex(self.potree, session)
340 elif top == "home":
341 pathwords = pathwords[1:]
342 if pathwords:
343 top = pathwords[0]
344 else:
345 top = ""
346 if not session.isopen:
b00bca80 » davidfraser 2006-04-26 [forwardport from Pootle-ki... 347 templatename = "redirect"
348 templatevars = {
349 "pagetitle": session.localize("Redirecting to login..."),
350 "refresh": 1,
351 "refreshurl": "login.html",
352 "message": session.localize("Need to log in to access home page"),
353 }
354 pagelayout.completetemplatevars(templatevars, session)
355 return server.Redirect("../login.html", withtemplate=(templatename, templatevars))
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 356 if not top or top == "index.html":
357 return indexpage.UserIndex(self.potree, session)
358 elif top == "options.html":
d4b5e43b » friedelwolff 2006-09-15 Allow users to change their... 359 message = None
360 try:
361 if "changeoptions" in argdict:
362 session.setoptions(argdict)
363 if "changepersonal" in argdict:
364 session.setpersonaloptions(argdict)
365 message = session.localize("Personal details updated")
366 if "changeinterface" in argdict:
367 session.setinterfaceoptions(argdict)
368 except users.RegistrationError, errormessage:
369 message = errormessage
370 return users.UserOptions(self.potree, session, message)
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 371 elif top == "admin":
372 pathwords = pathwords[1:]
373 if pathwords:
374 top = pathwords[0]
375 else:
376 top = ""
377 if not session.isopen:
b00bca80 » davidfraser 2006-04-26 [forwardport from Pootle-ki... 378 templatename = "redirect"
379 templatevars = {
380 "pagetitle": session.localize("Redirecting to login..."),
381 "refresh": 1,
382 "refreshurl": "login.html",
383 "message": session.localize("Need to log in to access admin page"),
384 }
385 pagelayout.completetemplatevars(templatevars, session)
386 return server.Redirect("../login.html", withtemplate=(templatename, templatevars))
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 387 if not session.issiteadmin():
b00bca80 » davidfraser 2006-04-26 [forwardport from Pootle-ki... 388 templatename = "redirect"
389 templatevars = {
390 "pagetitle": session.localize("Redirecting to home..."),
391 "refresh": 1,
392 "refreshurl": "login.html",
393 "message": self.localize("You do not have the rights to administer pootle."),
394 }
395 pagelayout.completetemplatevars(templatevars, session)
396 return server.Redirect("../index.html", withtemplate=(templatename, templatevars))
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 397 if not top or top == "index.html":
398 if "changegeneral" in argdict:
399 self.changeoptions(argdict)
400 return adminpages.AdminPage(self.potree, session, self.instance)
401 elif top == "users.html":
402 if "changeusers" in argdict:
403 self.changeusers(session, argdict)
404 return adminpages.UsersAdminPage(self, session.loginchecker.users, session, self.instance)
405 elif top == "languages.html":
406 if "changelanguages" in argdict:
407 self.potree.changelanguages(argdict)
408 return adminpages.LanguagesAdminPage(self.potree, session, self.instance)
409 elif top == "projects.html":
410 if "changeprojects" in argdict:
411 self.potree.changeprojects(argdict)
412 return adminpages.ProjectsAdminPage(self.potree, session, self.instance)
da21d7a3 » davidfraser 2005-06-26 added support for Templates... 413 elif top == "templates" or self.potree.haslanguage(top):
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 414 languagecode = top
415 pathwords = pathwords[1:]
416 if pathwords:
417 top = pathwords[0]
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 418 bottom = pathwords[-1]
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 419 else:
420 top = ""
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 421 bottom = ""
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 422 if not top or top == "index.html":
423 return indexpage.LanguageIndex(self.potree, languagecode, session)
424 if self.potree.hasproject(languagecode, top):
425 projectcode = top
426 project = self.potree.getproject(languagecode, projectcode)
427 pathwords = pathwords[1:]
428 if pathwords:
429 top = pathwords[0]
430 else:
431 top = ""
432 if not top or top == "index.html":
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 433 return indexpage.ProjectIndex(project, session, argdict)
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 434 elif top == "admin.html":
435 return adminpages.TranslationProjectAdminPage(self.potree, project, session, argdict)
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 436 elif bottom == "translate.html":
437 if len(pathwords) > 1:
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 438 dirfilter = os.path.join(*pathwords[:-1])
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 439 else:
440 dirfilter = ""
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 441 try:
442 return translatepage.TranslatePage(project, session, argdict, dirfilter)
443 except projects.RightsError, stoppedby:
444 argdict["message"] = str(stoppedby)
445 return indexpage.ProjectIndex(project, session, argdict, dirfilter)
6ec9b636 » davidfraser 2005-06-28 added module filelocations ... 446 elif bottom == "spellcheck.html":
447 # the full review page
f19ac49b » davidfraser 2005-06-28 pass the language code to t... 448 argdict["spellchecklang"] = languagecode
6ec9b636 » davidfraser 2005-06-28 added module filelocations ... 449 return spellui.SpellingReview(session, argdict, js_url="/js/spellui.js")
450 elif bottom == "spellingstandby.html":
451 # a simple 'loading' page
452 return spellui.SpellingStandby()
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 453 elif bottom.endswith("." + project.fileext):
454 pofilename = os.path.join(*pathwords)
455 if argdict.get("translate", 0):
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 456 try:
457 return translatepage.TranslatePage(project, session, argdict, dirfilter=pofilename)
458 except projects.RightsError, stoppedby:
86a0f80b » friedelwolff 2007-01-26 Rather send user to index p... 459 if len(pathwords) > 1:
460 dirfilter = os.path.join(*pathwords[:-1])
461 else:
462 dirfilter = ""
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 463 argdict["message"] = str(stoppedby)
86a0f80b » friedelwolff 2007-01-26 Rather send user to index p... 464 return indexpage.ProjectIndex(project, session, argdict, dirfilter=dirfilter)
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 465 elif argdict.get("index", 0):
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 466 return indexpage.ProjectIndex(project, session, argdict, dirfilter=pofilename)
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 467 else:
468 pofile = project.getpofile(pofilename, freshen=False)
469 page = widgets.SendFile(pofile.filename)
690b6e7f » davidfraser 2005-06-27 added code to allow HTTP ca... 470 page.etag = str(pofile.pomtime)
e94dbf4b » andreaspauley 2007-03-30 Cater for xliff files, they... 471 encoding = getattr(pofile, "encoding", "UTF-8")
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 472 page.content_type = "text/plain; charset=%s" % encoding
473 return page
d9352980 » friedelwolff 2007-07-12 Ensure that we test for a .... 474 elif bottom.endswith(".csv") or bottom.endswith(".xlf") or bottom.endswith(".ts") or bottom.endswith(".po") or bottom.endswith(".mo"):
beaaea10 » davidfraser 2005-07-02 use the convert function di... 475 destfilename = os.path.join(*pathwords)
476 basename, extension = os.path.splitext(destfilename)
477 pofilename = basename + os.extsep + project.fileext
478 extension = extension[1:]
479 if extension == "mo":
480 if not "pocompile" in project.getrights(session):
481 return None
482 etag, filepath_or_contents = project.convert(pofilename, extension)
483 if etag:
484 page = widgets.SendFile(filepath_or_contents)
61a37290 » davidfraser 2005-07-02 the etag needs to be a stri... 485 page.etag = str(etag)
beaaea10 » davidfraser 2005-07-02 use the convert function di... 486 else:
487 page = widgets.PlainContents(filepath_or_contents)
ce7bf39b » dwaynebailey 2008-06-04 Use mimetypes for downloads... 488 if extension == "po":
489 page.content_type = "text/x-gettext-translation; charset=UTF-8"
490 elif extension == "csv":
491 page.content_type = "text/csv; charset=UTF-8"
492 elif extension == "xlf":
493 page.content_type = "application/x-xliff; charset=UTF-8"
494 elif extension == "ts":
495 page.content_type = "application/x-linguist; charset=UTF-8"
beaaea10 » davidfraser 2005-07-02 use the convert function di... 496 elif extension == "mo":
ce7bf39b » dwaynebailey 2008-06-04 Use mimetypes for downloads... 497 page.content_type = "application/x-gettext-translation"
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 498 return page
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 499 elif bottom.endswith(".zip"):
500 if not "archive" in project.getrights(session):
501 return None
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 502 if len(pathwords) > 1:
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 503 dirfilter = os.path.join(*pathwords[:-1])
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 504 else:
505 dirfilter = None
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 506 goal = argdict.get("goal", None)
507 if goal:
92cd5464 » dwaynebailey 2005-04-28 The about link on the proje... 508 goalfiles = project.getgoalfiles(goal)
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 509 pofilenames = []
510 for goalfile in goalfiles:
511 pofilenames.extend(project.browsefiles(goalfile))
512 else:
513 pofilenames = project.browsefiles(dirfilter)
514 archivecontents = project.getarchive(pofilenames)
515 page = widgets.PlainContents(archivecontents)
516 page.content_type = "application/zip"
517 return page
79086cc5 » friedelwolff 2006-03-16 Generate GSI's from within ... 518 elif bottom.endswith(".sdf") or bottom.endswith(".sgi"):
519 if not "pocompile" in project.getrights(session):
520 return None
521 oocontents = project.getoo()
522 page = widgets.PlainContents(oocontents)
523 page.content_type = "text/tab-seperated-values"
524 return page
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 525 elif bottom == "index.html":
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 526 if len(pathwords) > 1:
527 dirfilter = os.path.join(*pathwords[:-1])
528 else:
529 dirfilter = None
149fbd4c » davidfraser 2005-07-02 allow getting a pofile with... 530 return indexpage.ProjectIndex(project, session, argdict, dirfilter)
531 else:
532 return indexpage.ProjectIndex(project, session, argdict, os.path.join(*pathwords))
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 533 return None
534
f64ab86c » davidfraser 2005-06-26 moved option parsing into a... 535 class PootleOptionParser(simplewebserver.WebOptionParser):
536 def __init__(self):
4a8b56ea » dwaynebailey 2006-07-18 Add version info for kid an... 537 versionstring = "%%prog %s\njToolkit %s\nTranslate Toolkit %s\nKid %s\nElementTree %s\nPython %s (on %s/%s)" % (pootleversion.ver, jtoolkitversion.ver, toolkitversion.ver, kid.__version__, ElementTree.VERSION, sys.version, sys.platform, os.name)
c677c29e » dwaynebailey 2006-06-01 [Forwardport] pass through ... 538 simplewebserver.WebOptionParser.__init__(self, version=versionstring)
6ec9b636 » davidfraser 2005-06-28 added module filelocations ... 539 self.set_default('prefsfile', filelocations.prefsfile)
f64ab86c » davidfraser 2005-06-26 moved option parsing into a... 540 self.set_default('instance', 'Pootle')
6ec9b636 » davidfraser 2005-06-28 added module filelocations ... 541 self.set_default('htmldir', filelocations.htmldir)
f64ab86c » davidfraser 2005-06-26 moved option parsing into a... 542 self.add_option('', "--refreshstats", dest="action", action="store_const", const="refreshstats",
543 default="runwebserver", help="refresh the stats files instead of running the webserver")
884dce24 » dwaynebailey 2006-07-25 Add psyco to Pootle. 544 psycomodes=["none", "full", "profile"]
49ca02f8 » winterstream 2008-07-01 Merged in changes from bran... 545 self.add_option('', "--statsdb_file", action="store", type="string", dest="statsdb_file",
546 default=None, help="Specifies the location of the SQLite stats db file.")
e3f83065 » winterstream 2008-07-29 This adds some profiling co... 547 self.add_option('', "--profile", action="store", type="string", dest="profile",
548 help="Perform profiling, storing the result to the supplied filename.")
884dce24 » dwaynebailey 2006-07-25 Add psyco to Pootle. 549 try:
550 import psyco
551 self.add_option('', "--psyco", dest="psyco", default=None, choices=psycomodes, metavar="MODE",
552 help="use psyco to speed up the operation, modes: %s" % (", ".join(psycomodes)))
9818f854 » friedelwolff 2008-02-15 Only swallow an ImportError... 553 except ImportError, e:
884dce24 » dwaynebailey 2006-07-25 Add psyco to Pootle. 554 return
f64ab86c » davidfraser 2005-06-26 moved option parsing into a... 555
6f0926b9 » dwaynebailey 2006-06-15 Makre sure that you have th... 556 def checkversions():
557 """Checks that version dependencies are met"""
4f8bdad6 » friedelwolff 2008-03-18 Require at least build numb... 558 if not hasattr(toolkitversion, "build") or toolkitversion.build < 11000:
559 raise RuntimeError("requires Translate Toolkit version >= 1.1. Current installed version is: %s" % toolkitversion.ver)
6f0926b9 » dwaynebailey 2006-06-15 Makre sure that you have th... 560
884dce24 » dwaynebailey 2006-07-25 Add psyco to Pootle. 561 def usepsyco(options):
562 # options.psyco == None means the default, which is "full", but don't give a warning...
563 # options.psyco == "none" means don't use psyco at all...
9aefe93c » friedelwolff 2006-07-28 Make sure we run if psyco i... 564 if getattr(options, "psyco", "none") == "none":
884dce24 » dwaynebailey 2006-07-25 Add psyco to Pootle. 565 return
566 try:
567 import psyco
88aa19f2 » andreaspauley 2007-01-16 General code improvements t... 568 except ImportError:
884dce24 » dwaynebailey 2006-07-25 Add psyco to Pootle. 569 if options.psyco is not None:
24ff0e2f » andreaspauley 2007-01-22 Used the warning method def... 570 optrecurse.RecursiveOptionParser(formats={}).warning("psyco unavailable", options, sys.exc_info())
884dce24 » dwaynebailey 2006-07-25 Add psyco to Pootle. 571 return
572 if options.psyco is None:
573 options.psyco = "full"
574 if options.psyco == "full":
575 psyco.full()
576 elif options.psyco == "profile":
577 psyco.profile()
578 # tell psyco the functions it cannot compile, to prevent warnings
579 import encodings
580 psyco.cannotcompile(encodings.search_function)
581
e3f83065 » winterstream 2008-07-29 This adds some profiling co... 582 def profile_runner(server, options):
583 import cProfile
f6e14048 » winterstream 2008-08-04 Used an incorrect import st... 584 import Pootle.profiling.lsprofcalltree as lsprofcalltree
e3f83065 » winterstream 2008-07-29 This adds some profiling co... 585
586 def write_cache_grind(profiler, file):
587 k_cache_grind = lsprofcalltree.KCacheGrind(profiler)
588 k_cache_grind.output(file)
589 file.close()
590
591 def do_profile_run(file):
592 profiler = cProfile.Profile()
593 try:
594 profiler.runcall(simplewebserver.run, server, options)
595 finally:
596 write_cache_grind(profiler, file)
597
598 try:
599 profile_file = open(options.profile, "w+")
600 do_profile_run(profile_file)
601 except IOError, _e:
602 print "Could not open profiling file %s" % (options.profile,)
603
604 def get_runner(options):
605 if getattr(options, "profile", None) != None:
606 return profile_runner
607 else:
608 return simplewebserver.run
609
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 610 def main():
611 # run the web server
6f0926b9 » dwaynebailey 2006-06-15 Makre sure that you have th... 612 checkversions()
f64ab86c » davidfraser 2005-06-26 moved option parsing into a... 613 parser = PootleOptionParser()
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 614 options, args = parser.parse_args()
24ff0e2f » andreaspauley 2007-01-22 Used the warning method def... 615 options.errorlevel = options.logerrors
884dce24 » dwaynebailey 2006-07-25 Add psyco to Pootle. 616 usepsyco(options)
49ca02f8 » winterstream 2008-07-01 Merged in changes from bran... 617 statistics.STATS_DB_FILE = options.statsdb_file
f814f294 » davidfraser 2005-06-30 if not actually running the... 618 if options.action != "runwebserver":
619 options.servertype = "dummy"
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 620 server = parser.getserver(options)
7900c171 » friedelwolff 2006-08-16 Store optparse options in P... 621 server.options = options
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 622 if options.action == "runwebserver":
e3f83065 » winterstream 2008-07-29 This adds some profiling co... 623 run = get_runner(options)
624 run(server, options)
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 625 elif options.action == "refreshstats":
5ccb20bc » davidfraser 2005-05-11 added ability to specify fi... 626 server.refreshstats(args)
ca3d8109 » davidfraser 2005-04-20 moved from translate/pootle... 627
628 if __name__ == '__main__':
629 main()
630