2 # -*- coding: utf-8 -*-
4 # Copyright 2004-2006 Zuza Software Foundation
6 # This file is part of translate.
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.
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.
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
22 """manages the whole set of projects and languages for a pootle installation"""
24 from Pootle
import projects
25 from Pootle
import pootlefile
26 from Pootle
import pagelayout
27 from translate
.misc
import autoencode
31 languagere
= re
.compile("^[a-z]{2,3}([_-][A-Z]{2,3}|)$")
32 regionre
= re
.compile("^[_-][A-Z]{2,3}$")
35 """Manages the tree of projects and languages"""
36 def __init__(self
, instance
):
37 self
.languages
= instance
.languages
38 if not self
.haslanguage("templates"):
39 setattr(self
.languages
, "templates.fullname", "Templates")
41 self
.projects
= instance
.projects
42 self
.podirectory
= instance
.podirectory
43 self
.instance
= instance
44 self
.projectcache
= {}
47 """saves any changes made to the preferences"""
48 # TODO: this is a hack, fix it up nicely :-)
49 prefsfile
= self
.languages
.__root
__.__dict
__["_setvalue"].im_self
52 def changelanguages(self
, argdict
):
53 """changes language entries"""
54 for key
, value
in argdict
.iteritems():
55 if key
.startswith("languageremove-"):
56 languagecode
= key
.replace("languageremove-", "", 1)
57 if self
.haslanguage(languagecode
):
58 delattr(self
.languages
, languagecode
)
59 elif key
.startswith("languagename-"):
60 languagecode
= key
.replace("languagename-", "", 1)
61 if self
.haslanguage(languagecode
):
62 languagename
= self
.getlanguagename(languagecode
)
63 if languagename
!= value
:
64 self
.setlanguagename(languagecode
, value
)
65 elif key
.startswith("languagespecialchars-"):
66 languagecode
= key
.replace("languagespecialchars-", "", 1)
67 if self
.haslanguage(languagecode
):
68 languagespecialchars
= self
.getlanguagespecialchars(languagecode
)
69 if languagespecialchars
!= value
:
70 self
.setlanguagespecialchars(languagecode
, value
)
71 elif key
.startswith("languagenplurals-"):
72 languagecode
= key
.replace("languagenplurals-", "", 1)
73 if self
.haslanguage(languagecode
):
74 languagenplurals
= self
.getlanguagenplurals(languagecode
)
75 if languagenplurals
!= value
:
76 self
.setlanguagenplurals(languagecode
, value
)
77 elif key
.startswith("languagepluralequation-"):
78 languagecode
= key
.replace("languagepluralequation-", "", 1)
79 if self
.haslanguage(languagecode
):
80 languagepluralequation
= self
.getlanguagepluralequation(languagecode
)
81 if languagepluralequation
!= value
:
82 self
.setlanguagepluralequation(languagecode
, value
)
83 elif key
== "newlanguagecode":
84 languagecode
= value
.lower()
85 if not languagecode
.strip():
87 if not languagecode
.isalpha():
88 languagecode
= pagelayout
.localelanguage(languagecode
)
89 if languagecode
.find("_") >= 0:
90 for part
in languagecode
.split("_"):
91 if not part
.isalpha():
92 raise ValueError("Language code must be alphabetic")
93 languagecode
, countrycode
= languagecode
.split("_")
94 countrycode
= countrycode
.upper()
95 languagecode
= "%s_%s" % (languagecode
, countrycode
)
97 raise ValueError("Language code must be alphabetic")
98 if self
.haslanguage(languagecode
):
99 raise ValueError("Already have language with the code %s" % languagecode
)
100 languagename
= argdict
.get("newlanguagename", languagecode
)
101 languagespecialchars
= argdict
.get("newlanguagespecialchars", "")
102 languagenplurals
= argdict
.get("newlanguagenplurals", "")
103 languagepluralequation
= argdict
.get("newlanguagepluralequation", "")
104 # FIXME need to check that default values are not present
105 # if languagename == self.localize("(add language here)"):
106 # raise ValueError("Please set a value for the language name")
107 print "nplurals: %s" % languagenplurals
108 if not languagenplurals
.isdigit() and not languagenplurals
== "":
109 raise ValueError("Number of plural forms must be numeric")
110 # if languagenplurals == self.localize("(number of plurals)"):
111 # raise ValueError("Please set a value for the number of plural forms")
112 # if languagepluralequation == self.localize("(plural equation)"):
113 # raise ValueError("Please set a value for the plural equation")
114 if not languagenplurals
== "" and languagepluralequation
== "":
115 raise ValueError("Please set both the number of plurals and the plural equation OR leave both blank")
116 setattr(self
.languages
, languagecode
+ ".fullname", languagename
)
117 setattr(self
.languages
, languagecode
+ ".specialchars", languagespecialchars
)
118 setattr(self
.languages
, languagecode
+ ".nplurals", languagenplurals
)
119 setattr(self
.languages
, languagecode
+ ".pluralequation", languagepluralequation
)
122 def changeprojects(self
, argdict
):
123 """changes project entries"""
124 #Let's reset all "createmofiles" to 0, otherwise we can't disable one
125 #since the key will never arrive
126 for project
in self
.getprojectcodes():
127 self
.setprojectcreatemofiles(project
, 0)
128 for key
, value
in argdict
.iteritems():
129 if key
.startswith("projectremove-"):
130 projectcode
= key
.replace("projectremove-", "", 1)
131 if hasattr(self
.projects
, projectcode
):
132 delattr(self
.projects
, projectcode
)
133 elif key
.startswith("projectname-"):
134 projectcode
= key
.replace("projectname-", "", 1)
135 if hasattr(self
.projects
, projectcode
):
136 projectname
= self
.getprojectname(projectcode
)
137 if projectname
!= value
:
138 self
.setprojectname(projectcode
, value
)
139 elif key
.startswith("projectdescription-"):
140 projectcode
= key
.replace("projectdescription-", "", 1)
141 if hasattr(self
.projects
, projectcode
):
142 projectdescription
= self
.getprojectdescription(projectcode
)
143 if projectdescription
!= value
:
144 self
.setprojectdescription(projectcode
, value
)
145 elif key
.startswith("projectcheckerstyle-"):
146 projectcode
= key
.replace("projectcheckerstyle-", "", 1)
147 if hasattr(self
.projects
, projectcode
):
148 projectcheckerstyle
= self
.getprojectcheckerstyle(projectcode
)
149 if projectcheckerstyle
!= value
:
150 self
.setprojectcheckerstyle(projectcode
, value
)
151 elif key
.startswith("projectfiletype-"):
152 projectcode
= key
.replace("projectfiletype-", "", 1)
153 if hasattr(self
.projects
, projectcode
):
154 projectlocalfiletype
= self
.getprojectlocalfiletype(projectcode
)
155 if projectlocalfiletype
!= value
:
156 self
.setprojectlocalfiletype(projectcode
, value
)
157 elif key
.startswith("projectcreatemofiles-"):
158 projectcode
= key
.replace("projectcreatemofiles-", "", 1)
159 if hasattr(self
.projects
, projectcode
):
160 self
.setprojectcreatemofiles(projectcode
, 1)
161 elif key
== "newprojectcode":
162 projectcode
= value
.lower()
165 if not (projectcode
[:1].isalpha() and projectcode
.replace("_","").isalnum()):
166 raise ValueError("Project code must be alphanumeric and start with an alphabetic character (got %r)" % projectcode
)
167 if hasattr(self
.projects
, projectcode
):
168 raise ValueError("Already have project with the code %s" % projectcode
)
169 projectname
= argdict
.get("newprojectname", projectcode
)
170 projecttype
= argdict
.get("newprojectfiletype", "")
171 projectdescription
= argdict
.get("newprojectdescription", "")
172 projectcheckerstyle
= argdict
.get("newprojectcheckerstyle", "")
173 projectcreatemofiles
= argdict
.get("newprojectcreatemofiles", "")
174 setattr(self
.projects
, projectcode
+ ".fullname", projectname
)
175 setattr(self
.projects
, projectcode
+ ".localfiletype", projecttype
)
176 setattr(self
.projects
, projectcode
+ ".description", projectdescription
)
177 setattr(self
.projects
, projectcode
+ ".checkerstyle", projectcheckerstyle
)
178 setattr(self
.projects
, projectcode
+ ".createmofiles", projectcreatemofiles
)
179 projectdir
= os
.path
.join(self
.podirectory
, projectcode
)
180 if not os
.path
.isdir(projectdir
):
184 def haslanguage(self
, languagecode
):
185 """checks if this language exists"""
186 return hasattr(self
.languages
, languagecode
)
188 def getlanguageprefs(self
, languagecode
):
189 """returns the language object"""
190 return getattr(self
.languages
, languagecode
)
192 def getlanguagename(self
, languagecode
):
193 """returns the language's full name"""
194 return getattr(self
.getlanguageprefs(languagecode
), "fullname", languagecode
)
196 def setlanguagename(self
, languagecode
, languagename
):
197 """stes the language's full name"""
198 setattr(self
.getlanguageprefs(languagecode
), "fullname", languagename
)
200 def getlanguagespecialchars(self
, languagecode
):
201 """returns the language's special characters"""
202 return autoencode
.autoencode(getattr(self
.getlanguageprefs(languagecode
), "specialchars", ""), "utf-8")
204 def setlanguagespecialchars(self
, languagecode
, languagespecialchars
):
205 """sets the language's special characters"""
206 setattr(self
.getlanguageprefs(languagecode
), "specialchars", languagespecialchars
)
208 def getlanguagenplurals(self
, languagecode
):
209 """returns the language's number of plural forms"""
210 return getattr(self
.getlanguageprefs(languagecode
), "nplurals", "")
212 def setlanguagenplurals(self
, languagecode
, languagenplurals
):
213 """sets the language's number of plural forms"""
214 setattr(self
.getlanguageprefs(languagecode
), "nplurals", languagenplurals
)
216 def getlanguagepluralequation(self
, languagecode
):
217 """returns the language's number of plural forms"""
218 return getattr(self
.getlanguageprefs(languagecode
), "pluralequation", "")
220 def setlanguagepluralequation(self
, languagecode
, languagepluralequation
):
221 """sets the language's number of plural forms"""
222 setattr(self
.getlanguageprefs(languagecode
), "pluralequation", languagepluralequation
)
224 def getlanguagecodes(self
, projectcode
=None):
225 """returns a list of valid languagecodes for a given project or all projects"""
226 alllanguagecodes
= [languagecode
for languagecode
, language
in self
.languages
.iteritems()]
227 if projectcode
is None:
228 languagecodes
= alllanguagecodes
230 projectdir
= os
.path
.join(self
.podirectory
, projectcode
)
231 if not os
.path
.exists(projectdir
):
233 if self
.isgnustyle(projectcode
):
234 languagecodes
= [languagecode
for languagecode
in alllanguagecodes
if self
.hasproject(languagecode
, projectcode
)]
236 subdirs
= [fn
for fn
in os
.listdir(projectdir
) if os
.path
.isdir(os
.path
.join(projectdir
, fn
))]
238 for potentialcode
in subdirs
:
239 if not self
.languagematch(None, potentialcode
):
241 if potentialcode
in alllanguagecodes
:
242 languagecodes
.append(potentialcode
)
244 if "-" in potentialcode
:
245 potentialcode
= potentialcode
[:potentialcode
.find("-")]
246 elif "_" in potentialcode
:
247 potentialcode
= potentialcode
[:potentialcode
.find("_")]
248 if potentialcode
in alllanguagecodes
:
249 languagecodes
.append(potentialcode
)
253 def getlanguages(self
, projectcode
=None, sortbyname
=True):
254 """gets a list of (languagecode, languagename) tuples"""
255 languagecodes
= self
.getlanguagecodes(projectcode
)
257 languages
= [(self
.getlanguagename(languagecode
), languagecode
) for languagecode
in languagecodes
]
259 return [(languagecode
, languagename
) for languagename
, languagecode
in languages
]
261 return [(languagecode
, self
.getlanguagename(languagecode
)) for languagecode
in languagecodes
]
263 def getprojectcodes(self
, languagecode
=None):
264 """returns a list of project codes that are valid for the given languagecode or all projects"""
265 projectcodes
= [projectcode
for projectcode
, projectprefs
in self
.projects
.iteritems()]
267 if languagecode
is None:
270 return [projectcode
for projectcode
in projectcodes
if self
.hasproject(languagecode
, projectcode
)]
272 def hasproject(self
, languagecode
, projectcode
):
273 """returns whether the project exists for the language"""
274 if not hasattr(self
.projects
, projectcode
):
276 if languagecode
is None:
278 if not self
.haslanguage(languagecode
):
281 self
.getpodir(languagecode
, projectcode
)
286 def gettemplates(self
, projectcode
):
287 """returns templates for the given project"""
288 projectdir
= os
.path
.join(self
.podirectory
, projectcode
)
289 templatesdir
= os
.path
.join(projectdir
, "templates")
290 if not os
.path
.exists(templatesdir
):
291 templatesdir
= os
.path
.join(projectdir
, "pot")
292 if not os
.path
.exists(templatesdir
):
293 templatesdir
= projectdir
295 def addfiles(podir
, dirname
, fnames
):
296 """adds the files to the set of files for this project"""
297 basedirname
= dirname
.replace(podir
, "", 1)
298 while basedirname
.startswith(os
.sep
):
299 basedirname
= basedirname
.replace(os
.sep
, "", 1)
300 ponames
= [fname
for fname
in fnames
if fname
.endswith(os
.extsep
+"pot")]
301 potfilenames
.extend([os
.path
.join(basedirname
, poname
) for poname
in ponames
])
302 os
.path
.walk(templatesdir
, addfiles
, templatesdir
)
305 def getproject(self
, languagecode
, projectcode
):
306 """returns the project object for the languagecode and projectcode"""
307 if (languagecode
, projectcode
) not in self
.projectcache
:
308 if languagecode
== "templates":
309 self
.projectcache
[languagecode
, projectcode
] = projects
.TemplatesProject(projectcode
, self
)
311 self
.projectcache
[languagecode
, projectcode
] = projects
.TranslationProject(languagecode
, projectcode
, self
)
312 return self
.projectcache
[languagecode
, projectcode
]
314 def isgnustyle(self
, projectcode
):
315 """checks whether the whole project is a GNU-style project"""
316 projectdir
= os
.path
.join(self
.podirectory
, projectcode
)
317 return self
.hasgnufiles(projectdir
)
319 def addtranslationproject(self
, languagecode
, projectcode
):
320 """creates a new TranslationProject"""
321 if self
.hasproject(languagecode
, projectcode
):
322 raise ValueError("projects.TranslationProject for project %s, language %s already exists" % (projectcode
, languagecode
))
323 self
.projectcache
[languagecode
, projectcode
] = projects
.TranslationProject(languagecode
, projectcode
, self
, create
=True)
325 def getprojectname(self
, projectcode
):
326 """returns the full name of the project"""
327 projectprefs
= getattr(self
.projects
, projectcode
)
328 return getattr(projectprefs
, "fullname", projectcode
)
330 def setprojectname(self
, projectcode
, projectname
):
331 """returns the full name of the project"""
332 projectprefs
= getattr(self
.projects
, projectcode
)
333 setattr(projectprefs
, "fullname", projectname
)
335 def getprojectdescription(self
, projectcode
):
336 """returns the project description"""
337 projectprefs
= getattr(self
.projects
, projectcode
)
338 return getattr(projectprefs
, "description", projectcode
)
340 def setprojectdescription(self
, projectcode
, projectdescription
):
341 """returns the project description"""
342 projectprefs
= getattr(self
.projects
, projectcode
)
343 setattr(projectprefs
, "description", projectdescription
)
345 def getprojectlocalfiletype(self
, projectcode
):
346 """returns the project allowed file type. We assume it is .po if nothing
347 else is specified."""
348 projectprefs
= getattr(self
.projects
, projectcode
)
349 type = getattr(projectprefs
, "localfiletype", "po")
354 def setprojectlocalfiletype(self
, projectcode
, projectfiletype
):
355 """sets the allowed file type for the project"""
356 projectprefs
= getattr(self
.projects
, projectcode
)
357 setattr(projectprefs
, "localfiletype", projectfiletype
)
359 def getprojectcheckerstyle(self
, projectcode
):
360 """returns the project checker style"""
361 projectprefs
= getattr(self
.projects
, projectcode
)
362 return getattr(projectprefs
, "checkerstyle", projectcode
)
364 def setprojectcheckerstyle(self
, projectcode
, projectcheckerstyle
):
365 """sets the project checker style"""
366 projectprefs
= getattr(self
.projects
, projectcode
)
367 setattr(projectprefs
, "checkerstyle", projectcheckerstyle
)
369 def getprojectcreatemofiles(self
, projectcode
):
370 """returns whether the project builds MO files"""
371 projectprefs
= getattr(self
.projects
, projectcode
)
372 return getattr(projectprefs
, "createmofiles", False)
374 def setprojectcreatemofiles(self
, projectcode
, projectcreatemofiles
):
375 """sets whether the project builds MO files"""
376 projectprefs
= getattr(self
.projects
, projectcode
)
377 setattr(projectprefs
, "createmofiles", projectcreatemofiles
)
379 def hasgnufiles(self
, podir
, languagecode
=None, depth
=0, maxdepth
=3, poext
="po"):
380 """returns whether this directory contains gnu-style PO filenames for the given language"""
382 if (podir
.startswith(self
.podirectory
)):
383 def getprojectcode(podir
=podir
):
384 """Get the projectcode using the supplied podir."""
385 dirs
= podir
[len(self
.podirectory
):].split(os
.sep
)
387 projectcode
= dirs
[0]
389 projectcode
= dirs
[1]
391 projectprefs
= getattr(self
.projects
, getprojectcode())
392 style
= getattr(projectprefs
, "treestyle")
394 or style
== "nongnu":
397 print "Unsupported treestyle value (project %s): %s"%(projectcode
,style
)
400 #Let's check to see if we specifically find the correct gnu file
402 if not os
.path
.isdir(podir
):
404 fnames
= os
.listdir(podir
)
405 poext
= os
.extsep
+ "po"
408 if os
.path
.isdir(os
.path
.join(podir
, fn
)):
409 # if we have a language subdirectory, we're probably not GNU-style
410 if self
.languagematch(languagecode
, fn
):
412 #ignore hidden directories (like index directories)
415 subdirs
.append(os
.path
.join(podir
, fn
))
416 elif fn
.endswith(poext
):
417 if self
.languagematch(languagecode
, fn
[:-len(poext
)]):
419 elif not self
.languagematch(None, fn
[:-len(poext
)]):
422 for subdir
in subdirs
:
423 style
= self
.hasgnufiles(subdir
, languagecode
, depth
+1, maxdepth
)
424 if style
== "nongnu":
434 def getcodesfordir(self
, dirname
):
435 """returns projectcode and languagecode if dirname is a project directory"""
436 canonicalpath
= lambda path
: os
.path
.normcase(os
.path
.normpath(os
.path
.realpath(os
.path
.abspath(path
))))
437 dirname
= canonicalpath(dirname
)
438 podirectory
= canonicalpath(self
.podirectory
)
439 if dirname
== podirectory
:
441 for projectcode
, projectprefs
in self
.projects
.iteritems():
442 projectdir
= canonicalpath(os
.path
.join(self
.podirectory
, projectcode
))
443 if projectdir
== dirname
:
444 return projectcode
, None
445 for languagecode
, languageprefs
in self
.languages
.iteritems():
446 languagedir
= canonicalpath(os
.path
.join(projectdir
, languagecode
))
447 if not os
.path
.exists(languagedir
):
448 languagedirs
= [canonicalpath(languagedir
) for languagedir
in os
.listdir(projectdir
) if self
.languagematch(languagecode
, languagedir
)]
449 if dirname
in languagedirs
:
450 return projectcode
, languagecode
451 elif languagedir
== dirname
:
452 return projectcode
, languagecode
455 def getpodir(self
, languagecode
, projectcode
):
456 """returns the base directory containing po files for the project"""
457 projectdir
= os
.path
.join(self
.podirectory
, projectcode
)
458 if not os
.path
.exists(projectdir
):
459 raise IndexError("directory not found for project %s" % (projectcode
))
460 languagedir
= os
.path
.join(projectdir
, languagecode
)
461 if not os
.path
.exists(languagedir
):
462 languagedirs
= [languagedir
for languagedir
in os
.listdir(projectdir
) if self
.languagematch(languagecode
, languagedir
)]
464 # if no matching directories can be found, check if it is a GNU-style project
465 if self
.hasgnufiles(projectdir
, languagecode
) == "gnu":
467 raise IndexError("directory not found for language %s, project %s" % (languagecode
, projectcode
))
468 # TODO: handle multiple regions
469 if len(languagedirs
) > 1:
470 raise IndexError("multiple regions defined for language %s, project %s" % (languagecode
, projectcode
))
471 languagedir
= os
.path
.join(projectdir
, languagedirs
[0])
474 def languagematch(self
, languagecode
, otherlanguagecode
):
475 """matches a languagecode to another, ignoring regions in the second"""
476 if languagecode
is None:
477 return languagere
.match(otherlanguagecode
)
478 return languagecode
== otherlanguagecode
or \
479 (otherlanguagecode
.startswith(languagecode
) and regionre
.match(otherlanguagecode
[len(languagecode
):]))
481 def getpofiles(self
, languagecode
, projectcode
, poext
="po"):
482 """returns a list of po files for the project and language"""
484 prefix
= os
.curdir
+ os
.sep
486 def addfiles(podir
, dirname
, fnames
):
487 """adds the files to the set of files for this project"""
488 if dirname
== os
.curdir
:
491 basedirname
= dirname
.replace(prefix
, "", 1)
493 # check that it actually exists (to avoid problems with broken symbolic
494 # links, for example)
495 fpath
= os
.path
.join(basedirname
, fname
)
496 if fname
.endswith(os
.extsep
+poext
):
497 pofilenames
.append(fpath
)
499 def addgnufiles(podir
, dirname
, fnames
):
500 """adds the files to the set of files for this project"""
501 basedirname
= dirname
.replace(podir
, "", 1)
502 while basedirname
.startswith(os
.sep
):
503 basedirname
= basedirname
.replace(os
.sep
, "", 1)
504 ext
= os
.extsep
+ poext
505 ponames
= [fn
for fn
in fnames
if fn
.endswith(ext
) and self
.languagematch(languagecode
, fn
[:-len(ext
)])]
506 pofilenames
.extend([os
.path
.join(basedirname
, poname
) for poname
in ponames
])
508 podir
= self
.getpodir(languagecode
, projectcode
)
509 if self
.hasgnufiles(podir
, languagecode
) == "gnu":
510 os
.path
.walk(podir
, addgnufiles
, podir
)
512 pwd
= os
.path
.abspath(os
.curdir
)
514 os
.path
.walk(os
.curdir
, addfiles
, None)
518 def getdefaultrights(self
):
519 """Returns the default rights for a logged in user on this Pootle server."""
520 return getattr(self
.instance
, "defaultrights", "view, suggest, archive, pocompile")
522 def refreshstats(self
):
523 """manually refreshes (all or missing) the stats files"""
524 for projectcode
in self
.getprojectcodes():
525 print "Project %s:" % (projectcode
)
526 for languagecode
in self
.getlanguagecodes(projectcode
):
527 print "Project %s, Language %s:" % (projectcode
, languagecode
)
528 translationproject
= self
.getproject(languagecode
, projectcode
)
529 translationproject
.stats
= {}
530 for pofilename
in translationproject
.pofilenames
:
531 translationproject
.getpostats(pofilename
)
532 translationproject
.pofiles
[pofilename
] = pootlefile
.pootlefile(translationproject
, pofilename
)
535 self
.projectcache
= {}
538 """A dummy PO tree for testing etc - just treats everything as a single directory"""
539 def __init__(self
, podir
):
540 self
.podirectory
= podir
541 def getlanguagename(self
, languagecode
):
543 def getprojectname(self
, projectcode
):
545 def getprojectdescription(self
, projectcode
):
547 def getprojectcheckerstyle(self
, projectcode
):
549 def getpodir(self
, languagecode
, projectcode
):
550 return self
.podirectory
551 def hasgnufiles(self
, podir
, languagecode
):
553 def getprojectcreatemofiles(self
, projectcode
):
555 def getpofiles(self
, languagecode
, projectcode
, poext
):
557 for dirpath
, subdirs
, filenames
in os
.walk(self
.podirectory
, topdown
=False):
558 if dirpath
== self
.podirectory
:
561 subdirpath
= dirpath
.replace(self
.podirectory
+os
.path
.sep
, "", 1)
562 print dirpath
, subdirpath
, self
.podirectory
563 pofiles
.extend([os
.path
.join(subdirpath
, name
) for name
in filenames
if name
.endswith(poext
)])
565 def gettemplates(self
, projectcode
):
567 def languagematch(self
, languagecode
, filename
):