2 # -*- coding: utf-8 -*-
4 # Copyright 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 from Pootle
import pagelayout
23 from Pootle
import projects
24 from translate
.filters
import checks
28 class AdminPage(pagelayout
.PootlePage
):
29 """page for administering pootle..."""
30 def __init__(self
, potree
, session
, instance
):
32 self
.session
= session
33 self
.instance
= instance
34 self
.localize
= session
.localize
35 templatename
= "adminindex"
36 sessionvars
= {"status": self
.session
.status
, "isopen": self
.session
.isopen
, "issiteadmin": self
.session
.issiteadmin()}
37 instancetitle
= getattr(self
.instance
, "title", session
.localize("Pootle Demo"))
38 text
= self
.gettext(session
)
39 templatevars
= {"options": self
.getoptions(), "session": sessionvars
, "instancetitle": instancetitle
, "text": text
}
40 pagelayout
.PootlePage
.__init
__(self
, templatename
, templatevars
, session
)
42 def gettext(self
, session
):
43 """Localize the text"""
45 text
["home"] = session
.localize("Home")
46 text
["users"] = session
.localize("Users")
47 text
["languages"] = session
.localize("Languages")
48 text
["projects"] = session
.localize("Projects")
49 text
["generaloptions"] = session
.localize("General options")
50 text
["option"] = session
.localize("Option")
51 text
["currentvalue"] = session
.localize("Current value")
52 text
["savechanges"] = session
.localize("Save changes")
56 optiontitles
= {"title": self
.localize("Title"),
57 "description": self
.localize("Description"),
58 "baseurl": self
.localize("Base URL"),
59 "homepage": self
.localize("Home Page")}
61 for optionname
, optiontitle
in optiontitles
.items():
62 optionvalue
= getattr(self
.instance
, optionname
, "")
63 option
= {"name": "option-%s" % optionname
, "title": optiontitle
, "value": optionvalue
}
64 options
.append(option
)
67 class LanguagesAdminPage(pagelayout
.PootlePage
):
68 """page for administering pootle..."""
69 def __init__(self
, potree
, session
, instance
):
71 self
.session
= session
72 self
.instance
= instance
73 self
.localize
= session
.localize
74 templatename
= "adminlanguages"
75 sessionvars
= {"status": self
.session
.status
, "isopen": self
.session
.isopen
, "issiteadmin": self
.session
.issiteadmin()}
76 instancetitle
= getattr(self
.instance
, "title", session
.localize("Pootle Demo"))
77 text
= self
.gettext(session
)
78 templatevars
= {"languages": self
.getlanguagesoptions(), "options": self
.getoptions(), "session": sessionvars
, "instancetitle": instancetitle
, "text": text
}
79 pagelayout
.PootlePage
.__init
__(self
, templatename
, templatevars
, session
)
81 def gettext(self
, session
):
82 """Localize the text"""
84 text
["home"] = session
.localize("Home")
85 text
["admin"] = session
.localize("Main admin page")
86 text
["languages"] = session
.localize("Languages")
87 text
["savechanges"] = session
.localize("Save changes")
91 options
= [{"name": "code", "title": self
.localize("ISO Code"), "size": 6, "newvalue": ""},
92 {"name": "name", "title": self
.localize("Full Name"),
93 "newvalue": self
.localize("(add language here)")},
94 {"name": "specialchars", "title": self
.localize("Special Chars"), "newvalue": self
.localize("(special characters)")},
95 {"name": "nplurals", "title": self
.localize("Number of Plurals"), "newvalue": self
.localize("(number of plurals)")},
96 {"name": "pluralequation", "title": self
.localize("Plural Equation"), "newvalue": self
.localize("(plural equation)")},
97 {"name": "remove", "title": self
.localize("Remove Language")}]
98 for option
in options
:
99 if "newvalue" in option
:
100 option
["newname"] = "newlanguage" + option
["name"]
103 def getlanguagesoptions(self
):
105 for languagecode
, languagename
in self
.potree
.getlanguages():
106 languagespecialchars
= self
.potree
.getlanguagespecialchars(languagecode
)
107 languagenplurals
= self
.potree
.getlanguagenplurals(languagecode
)
108 languagepluralequation
= self
.potree
.getlanguagepluralequation(languagecode
)
109 languageremove
= None
110 # TODO: make label work like this
111 # l10n: The parameter is a languagecode, projectcode or username
112 removelabel
= self
.localize("Remove %s", languagecode
)
113 languageoptions
= [{"name": "languagename-%s" % languagecode
, "value": languagename
, "type": "text"},
114 {"name": "languagespecialchars-%s" % languagecode
, "value": languagespecialchars
, "type": "text"},
115 {"name": "languagenplurals-%s" % languagecode
, "value": languagenplurals
, "type": "text"},
116 {"name": "languagepluralequation-%s" % languagecode
, "value": languagepluralequation
, "type": "text"},
117 {"name": "languageremove-%s" % languagecode
, "value": languageremove
, "type": "checkbox", "label": removelabel
}]
118 languages
.append({"code": languagecode
, "options": languageoptions
})
121 class ProjectsAdminPage(pagelayout
.PootlePage
):
122 """page for administering pootle..."""
123 def __init__(self
, potree
, session
, instance
):
125 self
.session
= session
126 self
.instance
= instance
127 self
.localize
= session
.localize
128 templatename
= "adminprojects"
129 projectfiletypes
= ["po","xlf"]
130 self
.allchecks
= [{"value": check
, "description": check
} for check
in checks
.projectcheckers
.keys()]
131 self
.allchecks
.insert(0, {"value": "", "description": self
.localize("Standard")})
132 self
.alltypes
= [{"value": check
, "description": check
} for check
in projectfiletypes
]
133 sessionvars
= {"status": self
.session
.status
, "isopen": self
.session
.isopen
, "issiteadmin": self
.session
.issiteadmin()}
134 instancetitle
= getattr(self
.instance
, "title", session
.localize("Pootle Demo"))
135 text
= self
.gettext(session
)
136 templatevars
= {"projects": self
.getprojectsoptions(), "options": self
.getoptions(), "session": sessionvars
, "instancetitle": instancetitle
, "text": text
}
137 pagelayout
.PootlePage
.__init
__(self
, templatename
, templatevars
, session
)
139 def gettext(self
, session
):
140 """Localize the text"""
142 text
["home"] = session
.localize("Home")
143 text
["admin"] = session
.localize("Main admin page")
144 text
["projects"] = session
.localize("Projects")
145 text
["savechanges"] = session
.localize("Save changes")
148 def getoptions(self
):
149 options
= [{"name": "code", "title": self
.localize("Project Code"), "size": 6, "newvalue": ""},
150 {"name": "name", "title": self
.localize("Full Name"),
151 "newvalue": self
.localize("(add project here)")},
152 {"name": "description", "title": self
.localize("Project Description"), "newvalue": self
.localize("(project description)")},
153 {"name": "checkerstyle", "title": self
.localize("Checker Style"), "selectoptions": self
.allchecks
, "newvalue": ""},
154 {"name": "filetype", "title": self
.localize("File Type"), "selectoptions": self
.alltypes
, "newvalue": ""},
155 {"name": "createmofiles", "title": self
.localize("Create MO Files"), "type": "checkbox", "newvalue": ""},
156 {"name": "remove", "title": self
.localize("Remove Project")}]
157 for option
in options
:
158 if "newvalue" in option
:
159 option
["newname"] = "newproject" + option
["name"]
160 if "type" not in option
and "selectoptions" not in option
:
161 option
["type"] = "text"
164 def getprojectsoptions(self
):
166 for projectcode
in self
.potree
.getprojectcodes():
167 projectadminlink
= "../projects/%s/admin.html" % projectcode
168 projectname
= self
.potree
.getprojectname(projectcode
)
169 projectdescription
= self
.potree
.getprojectdescription(projectcode
)
170 projectname
= self
.potree
.getprojectname(projectcode
)
171 projectcheckerstyle
= self
.potree
.getprojectcheckerstyle(projectcode
)
172 projectfiletype
= self
.potree
.getprojectlocalfiletype(projectcode
)
173 if self
.potree
.getprojectcreatemofiles(projectcode
):
174 projectcreatemofiles
= "checked"
176 projectcreatemofiles
= ""
178 # l10n: The parameter is a languagecode, projectcode or username
179 removelabel
= self
.localize("Remove %s", projectcode
)
180 projectoptions
= [{"name": "projectname-%s" % projectcode
, "value": projectname
, "type": "text"},
181 {"name": "projectdescription-%s" % projectcode
, "value": projectdescription
, "type": "text"},
182 {"name": "projectcheckerstyle-%s" % projectcode
, "value": projectcheckerstyle
, "selectoptions": self
.allchecks
},
183 {"name": "projectfiletype-%s" % projectcode
, "value": projectfiletype
, "selectoptions": self
.alltypes
},
184 {"name": "projectcreatemofiles-%s" % projectcode
, "value": projectcreatemofiles
, "type": "checkbox", projectcreatemofiles
: projectcreatemofiles
},
185 {"name": "projectremove-%s" % projectcode
, "value": projectremove
, "type": "checkbox", "label": removelabel
}]
186 projects
.append({"code": projectcode
, "adminlink": projectadminlink
, "options": projectoptions
})
189 class UsersAdminPage(pagelayout
.PootlePage
):
190 """page for administering pootle..."""
191 def __init__(self
, server
, users
, session
, instance
):
194 self
.session
= session
195 self
.instance
= instance
196 self
.localize
= session
.localize
197 templatename
= "adminusers"
198 sessionvars
= {"status": self
.session
.status
, "isopen": self
.session
.isopen
, "issiteadmin": self
.session
.issiteadmin()}
199 instancetitle
= getattr(self
.instance
, "title", session
.localize("Pootle Demo"))
200 text
= self
.gettext(session
)
201 templatevars
= {"users": self
.getusersoptions(), "options": self
.getoptions(), "session": sessionvars
, "instancetitle": instancetitle
, "text": text
}
202 pagelayout
.PootlePage
.__init
__(self
, templatename
, templatevars
, session
)
204 def gettext(self
, session
):
205 """Localize the text"""
207 text
["home"] = session
.localize("Home")
208 text
["admin"] = session
.localize("Main admin page")
209 text
["users"] = session
.localize("Users")
210 text
["savechanges"] = session
.localize("Save changes")
213 def getoptions(self
):
214 options
= [{"name": "name", "title": self
.localize("Username"), "newvalue": "", "size": 6},
215 {"name": "fullname", "title": self
.localize("Full Name"),
216 "newvalue": self
.localize("(add full name here)")},
217 {"name": "email", "title": self
.localize("Email Address"), "newvalue": self
.localize("(add email here)")},
218 {"name": "password", "title": self
.localize("Password"), "newvalue": self
.localize("(add password here)")},
219 {"name": "activated", "title": self
.localize("Activated"), "type": "checkbox", "checked": "true", "newvalue": "", "label": self
.localize("Activate New User")},
220 {"name": "remove", "title": self
.localize("Remove User"), "type": "checkbox"}]
221 for option
in options
:
222 if "newvalue" in option
:
223 # TODO: rationalize this in the form processing
224 if option
["name"] == "activated":
225 option
["newname"] = "newuseractivate"
227 option
["newname"] = "newuser" + option
["name"]
230 def getusersoptions(self
):
232 for usercode
, usernode
in self
.users
.iteritems(sorted=True):
233 fullname
= getattr(usernode
, "name", "")
234 email
= getattr(usernode
, "email", "")
235 activated
= getattr(usernode
, "activated", 0) == 1
237 activatedattr
= "checked"
241 # l10n: The parameter is a languagecode, projectcode or username
242 removelabel
= self
.localize("Remove %s", usercode
)
243 useroptions
= [{"name": "username-%s" % usercode
, "value": fullname
, "type": "text"},
244 {"name": "useremail-%s" % usercode
, "value": email
, "type": "text"},
245 {"name": "userpassword-%s" % usercode
, "value": None, "type": "text"},
246 {"name": "useractivated-%s" % usercode
, "type": "checkbox", activatedattr
: activatedattr
},
247 {"name": "userremove-%s" % usercode
, "value": None, "type": "checkbox", "label": removelabel
}]
248 users
.append({"code": usercode
, "options": useroptions
})
251 class ProjectAdminPage(pagelayout
.PootlePage
):
252 """list of languages belonging to a project"""
253 def __init__(self
, potree
, projectcode
, session
, argdict
):
255 self
.projectcode
= projectcode
256 self
.session
= session
257 self
.localize
= session
.localize
258 self
.tr_lang
= session
.tr_lang
259 projectname
= self
.potree
.getprojectname(self
.projectcode
)
260 if self
.session
.issiteadmin():
261 if "doaddlanguage" in argdict
:
262 newlanguage
= argdict
.get("newlanguage", None)
264 raise ValueError("You must select a new language")
265 self
.potree
.addtranslationproject(newlanguage
, self
.projectcode
)
266 if "doupdatelanguage" in argdict
:
267 languagecodes
= argdict
.get("updatelanguage", None)
268 if not languagecodes
:
269 raise ValueError("No languagecode given in doupdatelanguage")
270 if isinstance(languagecodes
, (str, unicode)):
271 languagecodes
= [languagecodes
]
272 for languagecode
in languagecodes
:
273 translationproject
= self
.potree
.getproject(languagecode
, self
.projectcode
)
274 translationproject
.converttemplates(self
.session
)
275 main_link
= self
.localize("Back to main page")
276 existing_title
= self
.localize("Existing languages")
277 existing_languages
= self
.getexistinglanguages()
278 new_languages
= self
.getnewlanguages()
279 # l10n: This refers to updating the translation files from the templates like with .pot files
280 update_button
= self
.localize("Update Languages")
281 pagetitle
= self
.localize("Pootle Admin: %s", projectname
)
282 norights_text
= self
.localize("You do not have the rights to administer this project.")
283 iso_code
= self
.localize("ISO Code")
284 full_name
= self
.localize("Full Name")
285 # l10n: This refers to updating the translation files from the templates like with .pot files
286 update_link
= self
.localize("Update from templates")
287 templatename
= "projectadmin"
288 sessionvars
= {"status": self
.session
.status
, "isopen": self
.session
.isopen
, "issiteadmin": self
.session
.issiteadmin()}
289 instancetitle
= getattr(self
.session
.instance
, "title", session
.localize("Pootle Demo"))
290 templatevars
= {"pagetitle": pagetitle
, "norights_text": norights_text
,
291 "project": {"code": projectcode
, "name": projectname
},
292 "iso_code": iso_code
, "full_name": full_name
,
293 "existing_title": existing_title
, "existing_languages": existing_languages
,
294 "new_languages": new_languages
,
295 "update_button": update_button
, "add_button": self
.localize("Add Language"),
296 "main_link": main_link
, "update_link": update_link
,
297 "session": sessionvars
, "instancetitle": instancetitle
}
298 pagelayout
.PootlePage
.__init
__(self
, templatename
, templatevars
, session
, bannerheight
=80)
300 def getexistinglanguages(self
):
301 """gets the info on existing languages"""
302 languages
= self
.potree
.getlanguages(self
.projectcode
)
303 languageitems
= [{"code": languagecode
, "name": self
.tr_lang(languagename
)} for languagecode
, languagename
in languages
]
304 # rewritten for compatibility with Python 2.3
305 # languageitems.sort(cmp=locale.strcoll, key=lambda dict: dict["name"])
306 languageitems
.sort(lambda x
,y
: locale
.strcoll(x
["name"], y
["name"]))
307 for n
, item
in enumerate(languageitems
):
308 item
["parity"] = ["even", "odd"][n
% 2]
311 def getnewlanguages(self
):
312 """returns a box that lets the user add new languages"""
313 existingcodes
= self
.potree
.getlanguagecodes(self
.projectcode
)
314 allcodes
= self
.potree
.getlanguagecodes()
315 newcodes
= [code
for code
in allcodes
if not (code
in existingcodes
or code
== "templates")]
316 newoptions
= [(self
.potree
.getlanguagename(code
), code
) for code
in newcodes
]
318 newoptions
= [{"code": code
, "name": self
.tr_lang(languagename
)} for (languagename
, code
) in newoptions
]
319 # rewritten for compatibility with Python 2.3
320 # newoptions.sort(cmp=locale.strcoll, key=lambda dict: dict["name"])
321 newoptions
.sort(lambda x
,y
: locale
.strcoll(x
["name"], y
["name"]))
324 class TranslationProjectAdminPage(pagelayout
.PootlePage
):
325 """admin page for a translation project (project+language)"""
326 def __init__(self
, potree
, project
, session
, argdict
):
328 self
.project
= project
329 self
.session
= session
330 self
.localize
= session
.localize
331 self
.rightnames
= self
.project
.getrightnames(session
)
332 # l10n: This is the page title. The first parameter is the language name, the second parameter is the project name
333 pagetitle
= self
.localize("Pootle Admin: %s %s", self
.project
.languagename
, self
.project
.projectname
)
334 main_link
= self
.localize("Project home page")
335 if "admin" in self
.project
.getrights(self
.session
):
336 if "doupdaterights" in argdict
:
337 for key
, value
in argdict
.iteritems():
338 if isinstance(key
, str):
339 key
= key
.decode("utf-8")
340 if key
.startswith("rights-"):
341 username
= key
.replace("rights-", "", 1)
342 self
.project
.setrights(username
, value
)
343 if key
.startswith("rightsremove-"):
344 username
= key
.replace("rightsremove-", "", 1)
345 self
.project
.delrights(self
.session
, username
)
346 username
= argdict
.get("rightsnew-username", None)
348 username
= username
.strip()
349 if self
.session
.loginchecker
.userexists(username
):
350 self
.project
.setrights(username
, argdict
.get("rightsnew", ""))
352 raise IndexError(self
.localize("Cannot set rights for username %s - user does not exist", username
))
353 norights_text
= self
.localize("You do not have the rights to administer this project.")
354 templatename
= "projectlangadmin"
355 sessionvars
= {"status": self
.session
.status
, "isopen": self
.session
.isopen
, "issiteadmin": self
.session
.issiteadmin()}
356 instancetitle
= getattr(self
.session
.instance
, "title", session
.localize("Pootle Demo"))
357 templatevars
= {"pagetitle": pagetitle
, "norights_text": norights_text
,
358 "project": {"code": self
.project
.projectcode
, "name": self
.project
.projectname
},
359 "language": {"code": self
.project
.languagecode
, "name": self
.project
.languagename
},
360 "main_link": main_link
,
361 "session": sessionvars
, "instancetitle": instancetitle
}
362 templatevars
.update(self
.getoptions())
363 pagelayout
.PootlePage
.__init
__(self
, templatename
, templatevars
, session
, bannerheight
=80)
365 def getoptions(self
):
366 """returns a box that describes the options"""
367 self
.project
.readprefs()
368 if self
.project
.filestyle
== "gnu":
369 filestyle_text
= self
.localize("This is a GNU-style project (one directory, files named per language).")
371 filestyle_text
= self
.localize("This is a standard style project (one directory per language).")
372 permissions_title
= self
.localize("User Permissions")
373 username_title
= self
.localize("Username")
374 adduser_text
= self
.localize("(select to add user)")
375 rights_title
= self
.localize("Rights")
376 remove_title
= self
.localize("Remove")
377 nobodyrights
= self
.project
.getrights(username
=None)
378 nobody_dict
= self
.getuserdict("nobody", delete
=False)
379 defaultrights
= self
.project
.getrights(username
="default")
380 default_dict
= self
.getuserdict("default", delete
=False)
381 users_with_rights
= ["nobody", "default"]
382 rights
= {"nobody": nobodyrights
, "default": defaultrights
}
383 for username
in self
.project
.getuserswithrights():
384 if username
in ("nobody", "default"): continue
385 users_with_rights
.append(username
)
386 rights
[username
] = self
.project
.getrights(username
=username
)
387 users
= self
.project
.getuserswithinterest(self
.session
)
388 user_details
= {"nobody": nobody_dict
, "default": default_dict
}
389 for username
, usernode
in users
.iteritems():
390 if not isinstance(username
, unicode):
391 username
= username
.decode("utf-8")
392 user_dict
= self
.getuserdict(username
, usernode
=usernode
)
393 user_details
[username
] = user_dict
394 # We need to make sure that users_with_rights are also in user_details,
395 # since they might not be there yet or anymore
396 for username
in users_with_rights
:
397 if username
in user_details
:
399 user_dict
= self
.getuserdict(username
, usernode
=None)
400 user_details
[username
] = user_dict
401 users_without_rights
= [username
for username
in user_details
if username
not in users_with_rights
]
402 newuser_dict
= self
.getuserdict(None, delete
=False)
403 updaterights_text
= self
.localize("Update Rights")
404 return {"filestyle_text": filestyle_text
,
405 "permissions_title": permissions_title
,
406 "username_title": username_title
,
407 "rights_title": rights_title
,
408 "remove_title": remove_title
,
409 "users_with_rights": users_with_rights
,
410 "users_without_rights": users_without_rights
,
411 "user_details": user_details
,
413 "newuser": newuser_dict
,
414 "updaterights_text": updaterights_text
,
415 "rightnames": self
.rightnames
,
416 "adduser_text": adduser_text
,
419 def getuserdict(self
, username
, delete
=True, usernode
=None):
420 """gets a dictionary for the given user given user's rights"""
421 # l10n: The parameter is a languagecode, projectcode or username
422 remove_text
= self
.localize("Remove %s", username
)
423 description
= getattr(usernode
, "description", None) or username
424 userdict
= {"username": username
, "delete": delete
or None, "remove_text": remove_text
, "description": description
}