julen / pootle
- Source
- Commits
- Network (0)
- Issues (0)
- Downloads (0)
- Wiki (1)
- Graphs
-
Tree:
30bd9d6
pootle / indexpage.py
| ca3d8109 » | davidfraser | 2005-04-20 | 1 | #!/usr/bin/env python | |
| a953d6ab » | davidfraser | 2005-07-01 | 2 | # -*- coding: utf-8 -*- | |
| a141f386 » | winterstream | 2008-08-19 | 3 | # | |
| 24fe43ed » | friedelwolff | 2007-07-31 | 4 | # Copyright 2004-2007 Zuza Software Foundation | |
| a141f386 » | winterstream | 2008-08-19 | 5 | # | |
| d8ec3e47 » | dwaynebailey | 2006-06-15 | 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. | ||||
| a141f386 » | winterstream | 2008-08-19 | 12 | # | |
| d8ec3e47 » | dwaynebailey | 2006-06-15 | 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 | 21 | ||
| 22 | from Pootle import pagelayout | ||||
| 23 | from Pootle import projects | ||||
| 24 | from Pootle import pootlefile | ||||
| b1a89a4d » | friedelwolff | 2007-09-14 | 25 | from translate.storage import versioncontrol | |
| 4a8b56ea » | dwaynebailey | 2006-07-18 | 26 | # Versioning information | |
| cbd5838f » | davidfraser | 2005-04-22 | 27 | from Pootle import __version__ as pootleversion | |
| e08e1dfb » | friedelwolff | 2006-03-05 | 28 | from translate import __version__ as toolkitversion | |
| cbd5838f » | davidfraser | 2005-04-22 | 29 | from jToolkit import __version__ as jtoolkitversion | |
| 4a8b56ea » | dwaynebailey | 2006-07-18 | 30 | from kid import __version__ as kidversion | |
| 08972f30 » | dwaynebailey | 2007-07-10 | 31 | try: | |
| 24fe43ed » | friedelwolff | 2007-07-31 | 32 | # ElementTree is part of Python 2.5, so let's try that first | |
| 08083c40 » | friedelwolff | 2007-07-10 | 33 | from xml.etree import ElementTree | |
| 08972f30 » | dwaynebailey | 2007-07-10 | 34 | except ImportError: | |
| 35 | from elementtree import ElementTree | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 36 | import os | |
| cbd5838f » | davidfraser | 2005-04-22 | 37 | import sys | |
| dfb6361c » | friedelwolff | 2007-05-16 | 38 | import re | |
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 39 | import locale | |
| dd593f78 » | winterstream | 2008-09-08 | 40 | import util | |
| 1a9b15c3 » | winterstream | 2008-08-19 | 41 | ||
| 99714754 » | friedelwolff | 2006-10-12 | 42 | def shortdescription(descr): | |
| a141f386 » | winterstream | 2008-08-19 | 43 | """Returns a short description by removing markup and only including up | |
| 99714754 » | friedelwolff | 2006-10-12 | 44 | to the first br-tag""" | |
| 45 | stopsign = descr.find("<br") | ||||
| 46 | if stopsign >= 0: | ||||
| 47 | descr = descr[:stopsign] | ||||
| dfb6361c » | friedelwolff | 2007-05-16 | 48 | return re.sub("<[^>]*>", "", descr).strip() | |
| a141f386 » | winterstream | 2008-08-19 | 49 | ||
| ca3d8109 » | davidfraser | 2005-04-20 | 50 | class AboutPage(pagelayout.PootlePage): | |
| 51 | """the bar at the side describing current login details etc""" | ||||
| 52 | def __init__(self, session): | ||||
| 53 | self.localize = session.localize | ||||
| 54 | pagetitle = getattr(session.instance, "title") | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 55 | description = getattr(session.instance, "description") | |
| fb4e281d » | friedelwolff | 2006-09-04 | 56 | meta_description = shortdescription(description) | |
| b06eaf9b » | friedelwolff | 2008-08-20 | 57 | keywords = ["Pootle", "locamotion", "translate", "translation", "localisation", | |
| 70eae9a4 » | friedelwolff | 2006-08-22 | 58 | "localization", "l10n", "traduction", "traduire"] | |
| b00bca80 » | davidfraser | 2006-04-26 | 59 | abouttitle = self.localize("About Pootle") | |
| 0afd0073 » | friedelwolff | 2006-08-30 | 60 | # l10n: Take care to use HTML tags correctly. A markup error could cause a display error. | |
| b00bca80 » | davidfraser | 2006-04-26 | 61 | introtext = self.localize("<strong>Pootle</strong> is a simple web portal that should allow you to <strong>translate</strong>! Since Pootle is <strong>Free Software</strong>, you can download it and run your own copy if you like. You can also help participate in the development in many ways (you don't have to be able to program).") | |
| 62 | hosttext = self.localize('The Pootle project itself is hosted at <a href="http://translate.sourceforge.net/">translate.sourceforge.net</a> where you can find the details about source code, mailing lists etc.') | ||||
| 0afd0073 » | friedelwolff | 2006-08-30 | 63 | # l10n: If your language uses right-to-left layout and you leave the English untranslated, consider enclosing the necessary text with <span dir="ltr">.......</span> to help browsers to display it correctly. | |
| 64 | # l10n: Take care to use HTML tags correctly. A markup error could cause a display error. | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 65 | nametext = self.localize('The name stands for <b>PO</b>-based <b>O</b>nline <b>T</b>ranslation / <b>L</b>ocalization <b>E</b>ngine, but you may need to read <a href="http://www.thechestnut.com/flumps.htm">this</a>.') | |
| 66 | versiontitle = self.localize("Versions") | ||||
| 0afd0073 » | friedelwolff | 2006-08-30 | 67 | # l10n: If your language uses right-to-left layout and you leave the English untranslated, consider enclosing the necessary text with <span dir="ltr">.......</span> to help browsers to display it correctly. | |
| 68 | # l10n: Take care to use HTML tags correctly. A markup error could cause a display error. | ||||
| 4a8b56ea » | dwaynebailey | 2006-07-18 | 69 | versiontext = self.localize("This site is running:<br />Pootle %s<br />Translate Toolkit %s<br />jToolkit %s<br />Kid %s<br />ElementTree %s<br />Python %s (on %s/%s)", pootleversion.ver, toolkitversion.ver, jtoolkitversion.ver, kidversion, ElementTree.VERSION, sys.version, sys.platform, os.name) | |
| b00bca80 » | davidfraser | 2006-04-26 | 70 | templatename = "about" | |
| 71 | instancetitle = getattr(session.instance, "title", session.localize("Pootle Demo")) | ||||
| 72 | sessionvars = {"status": session.status, "isopen": session.isopen, "issiteadmin": session.issiteadmin()} | ||||
| 73 | templatevars = {"pagetitle": pagetitle, "description": description, | ||||
| b111144f » | friedelwolff | 2006-09-01 | 74 | "meta_description": meta_description, "keywords": keywords, | |
| b00bca80 » | davidfraser | 2006-04-26 | 75 | "abouttitle": abouttitle, "introtext": introtext, | |
| 76 | "hosttext": hosttext, "nametext": nametext, "versiontitle": versiontitle, "versiontext": versiontext, | ||||
| e388c541 » | friedelwolff | 2006-06-26 | 77 | "session": sessionvars, "instancetitle": instancetitle} | |
| b00bca80 » | davidfraser | 2006-04-26 | 78 | pagelayout.PootlePage.__init__(self, templatename, templatevars, session) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 79 | ||
| 80 | class PootleIndex(pagelayout.PootlePage): | ||||
| a141f386 » | winterstream | 2008-08-19 | 81 | """The main page listing projects and languages. It is also reused for | |
| 42d26941 » | friedelwolff | 2006-08-01 | 82 | LanguagesIndex and ProjectsIndex""" | |
| ca3d8109 » | davidfraser | 2005-04-20 | 83 | def __init__(self, potree, session): | |
| 84 | self.potree = potree | ||||
| 85 | self.localize = session.localize | ||||
| a3586432 » | dwaynebailey | 2005-05-19 | 86 | self.nlocalize = session.nlocalize | |
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 87 | self.tr_lang = session.tr_lang | |
| de0dfb7e » | friedelwolff | 2007-08-02 | 88 | self.listseperator = session.lang.listseperator | |
| b00bca80 » | davidfraser | 2006-04-26 | 89 | templatename = "index" | |
| 70eae9a4 » | friedelwolff | 2006-08-22 | 90 | description = getattr(session.instance, "description") | |
| fb4e281d » | friedelwolff | 2006-09-04 | 91 | meta_description = shortdescription(description) | |
| 70eae9a4 » | friedelwolff | 2006-08-22 | 92 | keywords = ["Pootle", "WordForge", "translate", "translation", "localisation", "localization", | |
| 93 | "l10n", "traduction", "traduire"] + self.getprojectnames() | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 94 | languagelink = self.localize('Languages') | |
| 95 | projectlink = self.localize('Projects') | ||||
| 96 | instancetitle = getattr(session.instance, "title", session.localize("Pootle Demo")) | ||||
| e388c541 » | friedelwolff | 2006-06-26 | 97 | pagetitle = instancetitle | |
| b00bca80 » | davidfraser | 2006-04-26 | 98 | sessionvars = {"status": session.status, "isopen": session.isopen, "issiteadmin": session.issiteadmin()} | |
| de0dfb7e » | friedelwolff | 2007-08-02 | 99 | languages = [{"code": code, "name": self.tr_lang(name), "sep": self.listseperator} for code, name in self.potree.getlanguages()] | |
| c64edd3f » | friedelwolff | 2007-07-17 | 100 | # rewritten for compatibility with Python 2.3 | |
| 101 | # languages.sort(cmp=locale.strcoll, key=lambda dict: dict["name"]) | ||||
| 102 | languages.sort(lambda x,y: locale.strcoll(x["name"], y["name"])) | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 103 | if languages: | |
| 104 | languages[-1]["sep"] = "" | ||||
| a141f386 » | winterstream | 2008-08-19 | 105 | templatevars = {"pagetitle": pagetitle, "description": description, | |
| b111144f » | friedelwolff | 2006-09-01 | 106 | "meta_description": meta_description, "keywords": keywords, | |
| b00bca80 » | davidfraser | 2006-04-26 | 107 | "languagelink": languagelink, "languages": languages, | |
| 108 | "projectlink": projectlink, "projects": self.getprojects(), | ||||
| e388c541 » | friedelwolff | 2006-06-26 | 109 | "session": sessionvars, "instancetitle": instancetitle} | |
| b00bca80 » | davidfraser | 2006-04-26 | 110 | pagelayout.PootlePage.__init__(self, templatename, templatevars, session) | |
| 111 | |||||
| 112 | def getprojects(self): | ||||
| 99714754 » | friedelwolff | 2006-10-12 | 113 | """gets the options for the projects""" | |
| 114 | projects = [] | ||||
| 115 | for projectcode in self.potree.getprojectcodes(): | ||||
| 116 | projectname = self.potree.getprojectname(projectcode) | ||||
| 117 | description = shortdescription(self.potree.getprojectdescription(projectcode)) | ||||
| de0dfb7e » | friedelwolff | 2007-08-02 | 118 | projects.append({"code": projectcode, "name": projectname, "description": description, "sep": self.listseperator}) | |
| 99714754 » | friedelwolff | 2006-10-12 | 119 | if projects: | |
| 120 | projects[-1]["sep"] = "" | ||||
| 121 | return projects | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 122 | ||
| 70eae9a4 » | friedelwolff | 2006-08-22 | 123 | def getprojectnames(self): | |
| 99714754 » | friedelwolff | 2006-10-12 | 124 | return [self.potree.getprojectname(projectcode) for projectcode in self.potree.getprojectcodes()] | |
| 70eae9a4 » | friedelwolff | 2006-08-22 | 125 | ||
| ca3d8109 » | davidfraser | 2005-04-20 | 126 | class UserIndex(pagelayout.PootlePage): | |
| 127 | """home page for a given user""" | ||||
| 128 | def __init__(self, potree, session): | ||||
| 129 | self.potree = potree | ||||
| 130 | self.session = session | ||||
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 131 | self.tr_lang = session.tr_lang | |
| ca3d8109 » | davidfraser | 2005-04-20 | 132 | self.localize = session.localize | |
| a3586432 » | dwaynebailey | 2005-05-19 | 133 | self.nlocalize = session.nlocalize | |
| b00bca80 » | davidfraser | 2006-04-26 | 134 | pagetitle = self.localize("User Page for: %s", session.username) | |
| 135 | templatename = "home" | ||||
| 136 | optionslink = self.localize("Change options") | ||||
| 137 | adminlink = self.localize("Admin page") | ||||
| fdcc07e4 » | friedelwolff | 2006-10-12 | 138 | admintext = self.localize("Administrate") | |
| b00bca80 » | davidfraser | 2006-04-26 | 139 | quicklinkstitle = self.localize("Quick Links") | |
| 140 | instancetitle = getattr(session.instance, "title", session.localize("Pootle Demo")) | ||||
| 141 | sessionvars = {"status": session.status, "isopen": session.isopen, "issiteadmin": session.issiteadmin()} | ||||
| 142 | quicklinks = self.getquicklinks() | ||||
| 143 | setoptionstext = self.localize("Please click on 'Change options' and select some languages and projects") | ||||
| 144 | templatevars = {"pagetitle": pagetitle, "optionslink": optionslink, | ||||
| a141f386 » | winterstream | 2008-08-19 | 145 | "adminlink": adminlink, "admintext": admintext, | |
| fdcc07e4 » | friedelwolff | 2006-10-12 | 146 | "quicklinkstitle": quicklinkstitle, | |
| b00bca80 » | davidfraser | 2006-04-26 | 147 | "quicklinks": quicklinks, "setoptionstext": setoptionstext, | |
| e388c541 » | friedelwolff | 2006-06-26 | 148 | "session": sessionvars, "instancetitle": instancetitle} | |
| b00bca80 » | davidfraser | 2006-04-26 | 149 | pagelayout.PootlePage.__init__(self, templatename, templatevars, session) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 150 | ||
| 151 | def getquicklinks(self): | ||||
| 99714754 » | friedelwolff | 2006-10-12 | 152 | """gets a set of quick links to user's project-languages""" | |
| 153 | quicklinks = [] | ||||
| 154 | for languagecode in self.session.getlanguages(): | ||||
| 155 | if not self.potree.haslanguage(languagecode): | ||||
| 156 | continue | ||||
| 157 | languagename = self.potree.getlanguagename(languagecode) | ||||
| 158 | langlinks = [] | ||||
| 159 | for projectcode in self.session.getprojects(): | ||||
| 160 | if self.potree.hasproject(languagecode, projectcode): | ||||
| fdcc07e4 » | friedelwolff | 2006-10-12 | 161 | projecttitle = self.potree.getprojectname(projectcode) | |
| 162 | project = self.potree.getproject(languagecode, projectcode) | ||||
| 163 | isprojectadmin = "admin" in project.getrights(session=self.session) \ | ||||
| 164 | or self.session.issiteadmin() | ||||
| a141f386 » | winterstream | 2008-08-19 | 165 | langlinks.append({"code": projectcode, "name": projecttitle, | |
| fdcc07e4 » | friedelwolff | 2006-10-12 | 166 | "isprojectadmin": isprojectadmin, "sep": "<br />"}) | |
| 99714754 » | friedelwolff | 2006-10-12 | 167 | if langlinks: | |
| 168 | langlinks[-1]["sep"] = "" | ||||
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 169 | quicklinks.append({"code": languagecode, "name": self.tr_lang(languagename), "projects": langlinks}) | |
| c64edd3f » | friedelwolff | 2007-07-17 | 170 | # rewritten for compatibility with Python 2.3 | |
| 171 | # quicklinks.sort(cmp=locale.strcoll, key=lambda dict: dict["name"]) | ||||
| 172 | quicklinks.sort(lambda x,y: locale.strcoll(x["name"], y["name"])) | ||||
| 99714754 » | friedelwolff | 2006-10-12 | 173 | return quicklinks | |
| ca3d8109 » | davidfraser | 2005-04-20 | 174 | ||
| 175 | class ProjectsIndex(PootleIndex): | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 176 | """the list of languages""" | |
| 177 | def __init__(self, potree, session): | ||||
| 178 | PootleIndex.__init__(self, potree, session) | ||||
| 179 | self.templatename = "projects" | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 180 | ||
| 181 | class LanguagesIndex(PootleIndex): | ||||
| 182 | """the list of languages""" | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 183 | def __init__(self, potree, session): | |
| 184 | PootleIndex.__init__(self, potree, session) | ||||
| 185 | self.templatename = "languages" | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 186 | ||
| 338b78d1 » | davidfraser | 2005-05-06 | 187 | class LanguageIndex(pagelayout.PootleNavPage): | |
| 42d26941 » | friedelwolff | 2006-08-01 | 188 | """The main page for a language, listing all the projects in it""" | |
| ca3d8109 » | davidfraser | 2005-04-20 | 189 | def __init__(self, potree, languagecode, session): | |
| 190 | self.potree = potree | ||||
| 191 | self.languagecode = languagecode | ||||
| 192 | self.localize = session.localize | ||||
| a3586432 » | dwaynebailey | 2005-05-19 | 193 | self.nlocalize = session.nlocalize | |
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 194 | self.tr_lang = session.tr_lang | |
| 2f55f730 » | davidfraser | 2005-06-26 | 195 | self.languagename = self.potree.getlanguagename(self.languagecode) | |
| 62d7600d » | davidfraser | 2005-05-05 | 196 | self.initpagestats() | |
| b00bca80 » | davidfraser | 2006-04-26 | 197 | languageprojects = self.getprojects() | |
| 198 | self.projectcount = len(languageprojects) | ||||
| 37ffb851 » | davidfraser | 2005-05-09 | 199 | average = self.getpagestats() | |
| b00bca80 » | davidfraser | 2006-04-26 | 200 | languagestats = self.nlocalize("%d project, average %d%% translated", "%d projects, average %d%% translated", self.projectcount, self.projectcount, average) | |
| 2f55f730 » | davidfraser | 2005-06-26 | 201 | languageinfo = self.getlanguageinfo() | |
| e388c541 » | friedelwolff | 2006-06-26 | 202 | instancetitle = getattr(session.instance, "title", session.localize("Pootle Demo")) | |
| 203 | # l10n: The first parameter is the name of the installation | ||||
| 204 | # l10n: The second parameter is the name of the project/language | ||||
| 205 | # l10n: This is used as a page title. Most languages won't need to change this | ||||
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 206 | pagetitle = self.localize("%s: %s", instancetitle, self.tr_lang(self.languagename)) | |
| b00bca80 » | davidfraser | 2006-04-26 | 207 | templatename = "language" | |
| 208 | adminlink = self.localize("Admin") | ||||
| 209 | sessionvars = {"status": session.status, "isopen": session.isopen, "issiteadmin": session.issiteadmin()} | ||||
| 210 | templatevars = {"pagetitle": pagetitle, | ||||
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 211 | "language": {"code": languagecode, "name": self.tr_lang(self.languagename), "stats": languagestats, "info": languageinfo}, | |
| a141f386 » | winterstream | 2008-08-19 | 212 | "projects": languageprojects, | |
| 9a013cf4 » | friedelwolff | 2006-05-22 | 213 | "statsheadings": self.getstatsheadings(), | |
| e388c541 » | friedelwolff | 2006-06-26 | 214 | "session": sessionvars, "instancetitle": instancetitle} | |
| f1e50e8a » | friedelwolff | 2007-09-26 | 215 | pagelayout.PootleNavPage.__init__(self, templatename, templatevars, session, bannerheight=80) | |
| 2f55f730 » | davidfraser | 2005-06-26 | 216 | ||
| 217 | def getlanguageinfo(self): | ||||
| 99714754 » | friedelwolff | 2006-10-12 | 218 | """returns information defined for the language""" | |
| 219 | # specialchars = self.potree.getlanguagespecialchars(self.languagecode) | ||||
| 220 | nplurals = self.potree.getlanguagenplurals(self.languagecode) | ||||
| 221 | pluralequation = self.potree.getlanguagepluralequation(self.languagecode) | ||||
| 222 | infoparts = [(self.localize("Language Code"), self.languagecode), | ||||
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 223 | (self.localize("Language Name"), self.tr_lang(self.languagename)), | |
| 99714754 » | friedelwolff | 2006-10-12 | 224 | # (self.localize("Special Characters"), specialchars), | |
| 225 | (self.localize("Number of Plurals"), str(nplurals)), | ||||
| 226 | (self.localize("Plural Equation"), pluralequation), | ||||
| 227 | ] | ||||
| 228 | return [{"title": title, "value": value} for title, value in infoparts] | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 229 | ||
| b00bca80 » | davidfraser | 2006-04-26 | 230 | def getprojects(self): | |
| 99714754 » | friedelwolff | 2006-10-12 | 231 | """gets the info on the projects""" | |
| 232 | projectcodes = self.potree.getprojectcodes(self.languagecode) | ||||
| 233 | self.projectcount = len(projectcodes) | ||||
| 234 | projectitems = [self.getprojectitem(projectcode) for projectcode in projectcodes] | ||||
| 235 | for n, item in enumerate(projectitems): | ||||
| 236 | item["parity"] = ["even", "odd"][n % 2] | ||||
| 237 | return projectitems | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 238 | ||
| 239 | def getprojectitem(self, projectcode): | ||||
| 99714754 » | friedelwolff | 2006-10-12 | 240 | href = '%s/' % projectcode | |
| 241 | projectname = self.potree.getprojectname(projectcode) | ||||
| 242 | projectdescription = shortdescription(self.potree.getprojectdescription(projectcode)) | ||||
| 243 | project = self.potree.getproject(self.languagecode, projectcode) | ||||
| 244 | projectstats = project.getquickstats() | ||||
| a1e6de8f » | friedelwolff | 2007-07-26 | 245 | projectdata = self.getstats(project, projectstats) | |
| 7187a205 » | friedelwolff | 2007-07-26 | 246 | self.updatepagestats(projectdata["translatedsourcewords"], projectdata["totalsourcewords"]) | |
| 99714754 » | friedelwolff | 2006-10-12 | 247 | return {"code": projectcode, "href": href, "icon": "folder", "title": projectname, "description": projectdescription, "data": projectdata, "isproject": True} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 248 | ||
| 338b78d1 » | davidfraser | 2005-05-06 | 249 | class ProjectLanguageIndex(pagelayout.PootleNavPage): | |
| 42d26941 » | friedelwolff | 2006-08-01 | 250 | """The main page for a project, listing all the languages belonging to it""" | |
| ca3d8109 » | davidfraser | 2005-04-20 | 251 | def __init__(self, potree, projectcode, session): | |
| 252 | self.potree = potree | ||||
| 253 | self.projectcode = projectcode | ||||
| 254 | self.localize = session.localize | ||||
| a3586432 » | dwaynebailey | 2005-05-19 | 255 | self.nlocalize = session.nlocalize | |
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 256 | self.tr_lang = session.tr_lang | |
| 62d7600d » | davidfraser | 2005-05-05 | 257 | self.initpagestats() | |
| b00bca80 » | davidfraser | 2006-04-26 | 258 | languages = self.getlanguages() | |
| 37ffb851 » | davidfraser | 2005-05-09 | 259 | average = self.getpagestats() | |
| 99714754 » | friedelwolff | 2006-10-12 | 260 | projectstats = self.nlocalize("%d language, average %d%% translated", "%d languages, average %d%% translated", self.languagecount, self.languagecount, average) | |
| b00bca80 » | davidfraser | 2006-04-26 | 261 | projectname = self.potree.getprojectname(self.projectcode) | |
| fb4e281d » | friedelwolff | 2006-09-04 | 262 | description = self.potree.getprojectdescription(projectcode) | |
| 263 | meta_description = shortdescription(description) | ||||
| e388c541 » | friedelwolff | 2006-06-26 | 264 | instancetitle = getattr(session.instance, "title", session.localize("Pootle Demo")) | |
| 265 | # l10n: The first parameter is the name of the installation | ||||
| 266 | # l10n: The second parameter is the name of the project/language | ||||
| 267 | # l10n: This is used as a page title. Most languages won't need to change this | ||||
| 268 | pagetitle = self.localize("%s: %s", instancetitle, projectname) | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 269 | templatename = "project" | |
| 270 | adminlink = self.localize("Admin") | ||||
| 271 | sessionvars = {"status": session.status, "isopen": session.isopen, "issiteadmin": session.issiteadmin()} | ||||
| 7b3dda9d » | friedelwolff | 2006-05-23 | 272 | statsheadings = self.getstatsheadings() | |
| 273 | statsheadings["name"] = self.localize("Language") | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 274 | templatevars = {"pagetitle": pagetitle, | |
| 275 | "project": {"code": projectcode, "name": projectname, "stats": projectstats}, | ||||
| a141f386 » | winterstream | 2008-08-19 | 276 | "description": description, "meta_description": meta_description, | |
| b00bca80 » | davidfraser | 2006-04-26 | 277 | "adminlink": adminlink, "languages": languages, | |
| a141f386 » | winterstream | 2008-08-19 | 278 | "session": sessionvars, "instancetitle": instancetitle, | |
| 7b3dda9d » | friedelwolff | 2006-05-23 | 279 | "statsheadings": statsheadings} | |
| f1e50e8a » | friedelwolff | 2007-09-26 | 280 | pagelayout.PootleNavPage.__init__(self, templatename, templatevars, session, bannerheight=80) | |
| b00bca80 » | davidfraser | 2006-04-26 | 281 | ||
| 282 | def getlanguages(self): | ||||
| 99714754 » | friedelwolff | 2006-10-12 | 283 | """gets the stats etc of the languages""" | |
| 284 | languages = self.potree.getlanguages(self.projectcode) | ||||
| 285 | self.languagecount = len(languages) | ||||
| 286 | languageitems = [self.getlanguageitem(languagecode, languagename) for languagecode, languagename in languages] | ||||
| c64edd3f » | friedelwolff | 2007-07-17 | 287 | # rewritten for compatibility with Python 2.3 | |
| 288 | # languageitems.sort(cmp=locale.strcoll, key=lambda dict: dict["title"]) | ||||
| 289 | languageitems.sort(lambda x,y: locale.strcoll(x["title"], y["title"])) | ||||
| 99714754 » | friedelwolff | 2006-10-12 | 290 | for n, item in enumerate(languageitems): | |
| 291 | item["parity"] = ["even", "odd"][n % 2] | ||||
| 292 | return languageitems | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 293 | ||
| 938ae0cd » | davidfraser | 2005-06-13 | 294 | def getlanguageitem(self, languagecode, languagename): | |
| 99714754 » | friedelwolff | 2006-10-12 | 295 | language = self.potree.getproject(languagecode, self.projectcode) | |
| 296 | href = "../../%s/%s/" % (languagecode, self.projectcode) | ||||
| 297 | quickstats = language.getquickstats() | ||||
| a1e6de8f » | friedelwolff | 2007-07-26 | 298 | data = self.getstats(language, quickstats) | |
| 7187a205 » | friedelwolff | 2007-07-26 | 299 | self.updatepagestats(data["translatedsourcewords"], data["totalsourcewords"]) | |
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 300 | return {"code": languagecode, "icon": "language", "href": href, "title": self.tr_lang(languagename), "data": data} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 301 | ||
| dd593f78 » | winterstream | 2008-09-08 | 302 | class LazyStats(object): | |
| 303 | def __init__(self, project, pofilenames): | ||||
| 304 | self._project = project | ||||
| 305 | self._pofilenames = pofilenames | ||||
| 306 | self._basic = util.undefined | ||||
| 307 | self._assign = util.undefined | ||||
| 308 | self._units = util.undefined | ||||
| 309 | |||||
| 310 | @util.lazy('_basic') | ||||
| 311 | def _get_basic(self): | ||||
| 312 | return self._project.getquickstats(self._pofilenames) | ||||
| 313 | basic = property(_get_basic) | ||||
| 314 | |||||
| 315 | @util.lazy('_assign') | ||||
| 316 | def _get_assign(self): | ||||
| 317 | return self._project.combineassignstats(self._pofilenames) | ||||
| 318 | assign = property(_get_assign) | ||||
| 319 | |||||
| 320 | @util.lazy('_units') | ||||
| 321 | def _get_units(self): | ||||
| 322 | return self._project.combine_unit_stats(self._pofilenames) | ||||
| 323 | units = property(_get_units) | ||||
| 324 | |||||
| 338b78d1 » | davidfraser | 2005-05-06 | 325 | class ProjectIndex(pagelayout.PootleNavPage): | |
| 42d26941 » | friedelwolff | 2006-08-01 | 326 | """The main page of a project in a specific language""" | |
| ca3d8109 » | davidfraser | 2005-04-20 | 327 | def __init__(self, project, session, argdict, dirfilter=None): | |
| 328 | self.project = project | ||||
| 329 | self.session = session | ||||
| 330 | self.localize = session.localize | ||||
| a3586432 » | dwaynebailey | 2005-05-19 | 331 | self.nlocalize = session.nlocalize | |
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 332 | self.tr_lang = session.tr_lang | |
| ca3d8109 » | davidfraser | 2005-04-20 | 333 | self.rights = self.project.getrights(self.session) | |
| 334 | message = argdict.get("message", "") | ||||
| 335 | if dirfilter == "": | ||||
| 336 | dirfilter = None | ||||
| 337 | self.dirfilter = dirfilter | ||||
| 338 | if dirfilter and dirfilter.endswith(".po"): | ||||
| a631f634 » | friedelwolff | 2007-07-03 | 339 | self.dirname = os.path.dirname(dirfilter) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 340 | else: | |
| 341 | self.dirname = dirfilter or "" | ||||
| 342 | self.argdict = argdict | ||||
| 343 | # handle actions before generating URLs, so we strip unneccessary parameters out of argdict | ||||
| 344 | self.handleactions() | ||||
| 6bf278f3 » | friedelwolff | 2006-06-23 | 345 | # generate the navigation bar maintaining state | |
| 346 | navbarpath_dict = self.makenavbarpath_dict(project=self.project, session=self.session, currentfolder=dirfilter, argdict=self.argdict) | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 347 | self.showtracks = self.getboolarg("showtracks") | |
| 348 | self.showchecks = self.getboolarg("showchecks") | ||||
| 349 | self.showassigns = self.getboolarg("showassigns") | ||||
| 350 | self.showgoals = self.getboolarg("showgoals") | ||||
| 9a013cf4 » | friedelwolff | 2006-05-22 | 351 | self.editing = self.getboolarg("editing") | |
| 7352cf81 » | davidfraser | 2005-05-20 | 352 | self.currentgoal = self.argdict.pop("goal", None) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 353 | if dirfilter and dirfilter.endswith(".po"): | |
| 354 | actionlinks = [] | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 355 | mainstats = "" | |
| 62d7600d » | davidfraser | 2005-05-05 | 356 | mainicon = "file" | |
| ca3d8109 » | davidfraser | 2005-04-20 | 357 | else: | |
| 49ca02f8 » | winterstream | 2008-07-01 | 358 | pofilenames = self.project.browsefiles(dirfilter) | |
| dd593f78 » | winterstream | 2008-09-08 | 359 | projectstats = LazyStats(self.project, pofilenames) | |
| 9a013cf4 » | friedelwolff | 2006-05-22 | 360 | if self.editing: | |
| 361 | actionlinks = self.getactionlinks("", projectstats, ["editing", "mine", "review", "check", "assign", "goal", "quick", "all", "zip", "sdf"], dirfilter) | ||||
| 684d2f79 » | winterstream | 2008-08-19 | 362 | else: | |
| 280abca3 » | friedelwolff | 2006-06-23 | 363 | actionlinks = self.getactionlinks("", projectstats, ["editing", "goal", "zip", "sdf"]) | |
| 49ca02f8 » | winterstream | 2008-07-01 | 364 | mainstats = self.getitemstats("", pofilenames, len(pofilenames)) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 365 | if self.showgoals: | |
| 366 | childitems = self.getgoalitems(dirfilter) | ||||
| 367 | else: | ||||
| 368 | childitems = self.getchilditems(dirfilter) | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 369 | instancetitle = getattr(session.instance, "title", session.localize("Pootle Demo")) | |
| e388c541 » | friedelwolff | 2006-06-26 | 370 | # l10n: The first parameter is the name of the installation (like "Pootle") | |
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 371 | pagetitle = self.localize("%s: Project %s, Language %s", instancetitle, self.project.projectname, self.tr_lang(self.project.languagename)) | |
| e388c541 » | friedelwolff | 2006-06-26 | 372 | templatename = "fileindex" | |
| b00bca80 » | davidfraser | 2006-04-26 | 373 | sessionvars = {"status": session.status, "isopen": session.isopen, "issiteadmin": session.issiteadmin()} | |
| 374 | templatevars = {"pagetitle": pagetitle, | ||||
| 375 | "project": {"code": self.project.projectcode, "name": self.project.projectname}, | ||||
| ca4ee7c6 » | friedelwolff | 2007-05-16 | 376 | "language": {"code": self.project.languagecode, "name": self.tr_lang(self.project.languagename)}, | |
| b00bca80 » | davidfraser | 2006-04-26 | 377 | # optional sections, will appear if these values are replaced | |
| 378 | "assign": None, "goals": None, "upload": None, | ||||
| c168a115 » | murgilduta | 2008-08-14 | 379 | "search": {"title": self.localize("Search"), | |
| 380 | "advanced_title": self.localize("Advanced Search"), | ||||
| 0ce1e29c » | murgilduta | 2008-08-18 | 381 | "fields": self.getsearchfields() }, | |
| c168a115 » | murgilduta | 2008-08-14 | 382 | "message": message, | |
| b00bca80 » | davidfraser | 2006-04-26 | 383 | # navigation bar | |
| 384 | "navitems": [{"icon": "folder", "path": navbarpath_dict, "actions": actionlinks, "stats": mainstats}], | ||||
| 385 | # children | ||||
| 386 | "children": childitems, | ||||
| 9a013cf4 » | friedelwolff | 2006-05-22 | 387 | # are we in editing mode (otherwise stats) | |
| 388 | "editing": self.editing, | ||||
| 389 | # stats table headings | ||||
| a141f386 » | winterstream | 2008-08-19 | 390 | "statsheadings": self.getstatsheadings(), | |
| b00bca80 » | davidfraser | 2006-04-26 | 391 | # general vars | |
| e388c541 » | friedelwolff | 2006-06-26 | 392 | "session": sessionvars, "instancetitle": instancetitle} | |
| f1e50e8a » | friedelwolff | 2007-09-26 | 393 | pagelayout.PootleNavPage.__init__(self, templatename, templatevars, session, bannerheight=80) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 394 | if self.showassigns and "assign" in self.rights: | |
| b00bca80 » | davidfraser | 2006-04-26 | 395 | self.templatevars["assign"] = self.getassignbox() | |
| ca3d8109 » | davidfraser | 2005-04-20 | 396 | if "admin" in self.rights: | |
| 397 | if self.showgoals: | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 398 | self.templatevars["goals"] = self.getgoalbox() | |
| 55d4caae » | friedelwolff | 2008-02-29 | 399 | if "admin" in self.rights or "translate" in self.rights or "suggest" in self.rights: | |
| b00bca80 » | davidfraser | 2006-04-26 | 400 | self.templatevars["upload"] = self.getuploadbox() | |
| ca3d8109 » | davidfraser | 2005-04-20 | 401 | ||
| 402 | def handleactions(self): | ||||
| 403 | """handles the given actions that must be taken (changing operations)""" | ||||
| 404 | if "doassign" in self.argdict: | ||||
| 405 | assignto = self.argdict.pop("assignto", None) | ||||
| 406 | action = self.argdict.pop("action", None) | ||||
| 407 | if not assignto and action: | ||||
| 408 | raise ValueError("cannot doassign, need assignto and action") | ||||
| 409 | search = pootlefile.Search(dirfilter=self.dirfilter) | ||||
| 410 | assigncount = self.project.assignpoitems(self.session, search, assignto, action) | ||||
| 411 | print "assigned %d strings to %s for %s" % (assigncount, assignto, action) | ||||
| 412 | del self.argdict["doassign"] | ||||
| 413 | if self.getboolarg("removeassigns"): | ||||
| 414 | assignedto = self.argdict.pop("assignedto", None) | ||||
| 415 | removefilter = self.argdict.pop("removefilter", "") | ||||
| 416 | if removefilter: | ||||
| 417 | if self.dirfilter: | ||||
| 418 | removefilter = self.dirfilter + removefilter | ||||
| 419 | else: | ||||
| 420 | removefilter = self.dirfilter | ||||
| 421 | search = pootlefile.Search(dirfilter=removefilter) | ||||
| 422 | search.assignedto = assignedto | ||||
| 423 | assigncount = self.project.unassignpoitems(self.session, search, assignedto) | ||||
| 424 | print "removed %d assigns from %s" % (assigncount, assignedto) | ||||
| 425 | del self.argdict["removeassigns"] | ||||
| 426 | if "doupload" in self.argdict: | ||||
| 1bde2edd » | varsist | 2006-11-28 | 427 | extensiontypes = ("xlf", "xlff", "xliff", "po") | |
| b32cba34 » | friedelwolff | 2007-01-11 | 428 | if "Yes" in self.argdict.pop("dooverwrite", []): | |
| 1bde2edd » | varsist | 2006-11-28 | 429 | overwrite = True | |
| 430 | else: | ||||
| 431 | overwrite = False | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 432 | uploadfile = self.argdict.pop("uploadfile", None) | |
| 1bde2edd » | varsist | 2006-11-28 | 433 | # multiple translation file extensions check | |
| 434 | if filter(uploadfile.filename.endswith, extensiontypes): | ||||
| 96d253e7 » | winterstream | 2008-08-19 | 435 | transfiles = True | |
| 1bde2edd » | varsist | 2006-11-28 | 436 | else: | |
| 96d253e7 » | winterstream | 2008-08-19 | 437 | transfiles = False | |
| 92cd5464 » | dwaynebailey | 2005-04-28 | 438 | if not uploadfile.filename: | |
| 439 | raise ValueError(self.localize("Cannot upload file, no file attached")) | ||||
| 1bde2edd » | varsist | 2006-11-28 | 440 | if transfiles: | |
| 441 | self.project.uploadfile(self.session, self.dirname, uploadfile.filename, uploadfile.contents, overwrite) | ||||
| 30214079 » | winterstream | 2008-09-08 | 442 | self.project.scanpofiles() | |
| ca3d8109 » | davidfraser | 2005-04-20 | 443 | elif uploadfile.filename.endswith(".zip"): | |
| 444 | self.project.uploadarchive(self.session, self.dirname, uploadfile.contents) | ||||
| 30214079 » | winterstream | 2008-09-08 | 445 | self.project.scanpofiles() | |
| ca3d8109 » | davidfraser | 2005-04-20 | 446 | else: | |
| 92cd5464 » | dwaynebailey | 2005-04-28 | 447 | raise ValueError(self.localize("Can only upload PO files and zips of PO files")) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 448 | del self.argdict["doupload"] | |
| 449 | if "doupdate" in self.argdict: | ||||
| 450 | updatefile = self.argdict.pop("updatefile", None) | ||||
| 451 | if not updatefile: | ||||
| 452 | raise ValueError("cannot update file, no file specified") | ||||
| b6dad550 » | andreaspauley | 2007-04-03 | 453 | if updatefile.endswith("." + self.project.fileext): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 454 | self.project.updatepofile(self.session, self.dirname, updatefile) | |
| 30214079 » | winterstream | 2008-09-08 | 455 | self.project.scanpofiles() | |
| ca3d8109 » | davidfraser | 2005-04-20 | 456 | else: | |
| b6dad550 » | andreaspauley | 2007-04-03 | 457 | raise ValueError("can only update files with extension ." + self.project.fileext) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 458 | del self.argdict["doupdate"] | |
| bcb3eea4 » | friedelwolff | 2006-06-22 | 459 | if "docommit" in self.argdict: | |
| 460 | commitfile = self.argdict.pop("commitfile", None) | ||||
| 581277bd » | friedelwolff | 2006-06-22 | 461 | if not commitfile: | |
| bcb3eea4 » | friedelwolff | 2006-06-22 | 462 | raise ValueError("cannot commit file, no file specified") | |
| 3c87e224 » | andreaspauley | 2007-04-03 | 463 | if commitfile.endswith("." + self.project.fileext): | |
| 581277bd » | friedelwolff | 2006-06-22 | 464 | self.project.commitpofile(self.session, self.dirname, commitfile) | |
| bcb3eea4 » | friedelwolff | 2006-06-22 | 465 | else: | |
| 3c87e224 » | andreaspauley | 2007-04-03 | 466 | raise ValueError("can only commit files with extension ." + self.project.fileext) | |
| bcb3eea4 » | friedelwolff | 2006-06-22 | 467 | del self.argdict["docommit"] | |
| ca3d8109 » | davidfraser | 2005-04-20 | 468 | if "doaddgoal" in self.argdict: | |
| 469 | goalname = self.argdict.pop("newgoal", None) | ||||
| 470 | if not goalname: | ||||
| 471 | raise ValueError("cannot add goal, no name given") | ||||
| 472 | self.project.setgoalfiles(self.session, goalname.strip(), "") | ||||
| 473 | del self.argdict["doaddgoal"] | ||||
| 474 | if "doeditgoal" in self.argdict: | ||||
| 475 | goalnames = self.argdict.pop("editgoal", None) | ||||
| 476 | goalfile = self.argdict.pop("editgoalfile", None) | ||||
| 477 | if not goalfile: | ||||
| 478 | raise ValueError("cannot add goal, no filename given") | ||||
| 479 | if self.dirname: | ||||
| 480 | goalfile = os.path.join(self.dirname, goalfile) | ||||
| 481 | if not isinstance(goalnames, list): | ||||
| 482 | goalnames = [goalnames] | ||||
| 483 | goalnames = [goalname.strip() for goalname in goalnames if goalname.strip()] | ||||
| 484 | self.project.setfilegoals(self.session, goalnames, goalfile) | ||||
| 485 | del self.argdict["doeditgoal"] | ||||
| 486 | if "doeditgoalusers" in self.argdict: | ||||
| 487 | goalname = self.argdict.pop("editgoalname", "").strip() | ||||
| 488 | if not goalname: | ||||
| 489 | raise ValueError("cannot edit goal, no name given") | ||||
| 490 | goalusers = self.project.getgoalusers(goalname) | ||||
| 491 | addusername = self.argdict.pop("newgoaluser", "").strip() | ||||
| 492 | if addusername: | ||||
| 493 | self.project.addusertogoal(self.session, goalname, addusername) | ||||
| 494 | del self.argdict["doeditgoalusers"] | ||||
| 495 | if "doedituser" in self.argdict: | ||||
| 7d1b19b1 » | davidfraser | 2005-05-20 | 496 | goalnames = self.argdict.pop("editgoal", None) | |
| f89f5797 » | davidfraser | 2005-05-20 | 497 | goalusers = self.argdict.pop("editfileuser", "") | |
| ca3d8109 » | davidfraser | 2005-04-20 | 498 | goalfile = self.argdict.pop("editgoalfile", None) | |
| cd79ed6b » | davidfraser | 2005-05-21 | 499 | assignwhich = self.argdict.pop("edituserwhich", "all") | |
| ca3d8109 » | davidfraser | 2005-04-20 | 500 | if not goalfile: | |
| 7d1b19b1 » | davidfraser | 2005-05-20 | 501 | raise ValueError("cannot add user to file for goal, no filename given") | |
| ca3d8109 » | davidfraser | 2005-04-20 | 502 | if self.dirname: | |
| 503 | goalfile = os.path.join(self.dirname, goalfile) | ||||
| 7d1b19b1 » | davidfraser | 2005-05-20 | 504 | if not isinstance(goalusers, list): | |
| 505 | goalusers = [goalusers] | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 506 | goalusers = [goaluser.strip() for goaluser in goalusers if goaluser.strip()] | |
| 7d1b19b1 » | davidfraser | 2005-05-20 | 507 | if not isinstance(goalnames, list): | |
| 508 | goalnames = [goalnames] | ||||
| 509 | goalnames = [goalname.strip() for goalname in goalnames if goalname.strip()] | ||||
| 510 | search = pootlefile.Search(dirfilter=goalfile) | ||||
| cd79ed6b » | davidfraser | 2005-05-21 | 511 | if assignwhich == "all": | |
| 512 | pass | ||||
| 513 | elif assignwhich == "untranslated": | ||||
| 49ca02f8 » | winterstream | 2008-07-01 | 514 | search.matchnames = ["fuzzy", "untranslated"] | |
| 2d7d324b » | davidfraser | 2005-05-21 | 515 | elif assignwhich == "unassigned": | |
| 516 | search.assignedto = [None] | ||||
| 517 | elif assignwhich == "unassigneduntranslated": | ||||
| 49ca02f8 » | winterstream | 2008-07-01 | 518 | search.matchnames = ["fuzzy", "untranslated"] | |
| 2d7d324b » | davidfraser | 2005-05-21 | 519 | search.assignedto = [None] | |
| cd79ed6b » | davidfraser | 2005-05-21 | 520 | else: | |
| 521 | raise ValueError("unexpected assignwhich") | ||||
| 1b2674ac » | davidfraser | 2005-05-20 | 522 | for goalname in goalnames: | |
| 523 | action = "goal-" + goalname | ||||
| 524 | self.project.reassignpoitems(self.session, search, goalusers, action) | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 525 | del self.argdict["doedituser"] | |
| b00bca80 » | davidfraser | 2006-04-26 | 526 | # pop arguments we don't want to propogate through inadvertently... | |
| a141f386 » | winterstream | 2008-08-19 | 527 | for argname in ("assignto", "action", "assignedto", "removefilter", | |
| 528 | "uploadfile", "updatefile", "commitfile", | ||||
| b0561291 » | friedelwolff | 2006-08-01 | 529 | "newgoal", "editgoal", "editgoalfile", "editgoalname", | |
| 530 | "newgoaluser", "editfileuser", "edituserwhich"): | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 531 | self.argdict.pop(argname, "") | |
| ca3d8109 » | davidfraser | 2005-04-20 | 532 | ||
| 533 | def getboolarg(self, argname, default=False): | ||||
| 534 | """gets a boolean argument from self.argdict""" | ||||
| 535 | value = self.argdict.get(argname, default) | ||||
| 536 | if isinstance(value, bool): | ||||
| 537 | return value | ||||
| 538 | elif isinstance(value, int): | ||||
| 539 | return bool(value) | ||||
| 540 | elif isinstance(value, (str, unicode)): | ||||
| a141f386 » | winterstream | 2008-08-19 | 541 | value = value.lower() | |
| ca3d8109 » | davidfraser | 2005-04-20 | 542 | if value.isdigit(): | |
| 543 | return bool(int(value)) | ||||
| 544 | if value == "true": | ||||
| 545 | return True | ||||
| 546 | if value == "false": | ||||
| 547 | return False | ||||
| 548 | raise ValueError("Invalid boolean value for %s: %r" % (argname, value)) | ||||
| 549 | |||||
| b00bca80 » | davidfraser | 2006-04-26 | 550 | def getassignbox(self): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 551 | """adds a box that lets the user assign strings""" | |
| f9194f2a » | friedelwolff | 2006-10-12 | 552 | users = self.project.getuserswithinterest(self.session) | |
| b00bca80 » | davidfraser | 2006-04-26 | 553 | return { | |
| 554 | "users": users, | ||||
| 555 | "title": self.localize("Assign Strings"), | ||||
| 556 | "action_text": self.localize("Assign Action"), | ||||
| 557 | "users_text": self.localize("Assign to User"), | ||||
| 558 | "button": self.localize("Assign Strings") | ||||
| 559 | } | ||||
| 560 | |||||
| 561 | def getgoalbox(self): | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 562 | """adds a box that lets the user add a new goal""" | |
| a141f386 » | winterstream | 2008-08-19 | 563 | return {"title": self.localize('goals'), | |
| 564 | "name-title": self.localize("Enter goal name"), | ||||
| 0afd0073 » | friedelwolff | 2006-08-30 | 565 | "button": self.localize("Add Goal")} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 566 | ||
| b00bca80 » | davidfraser | 2006-04-26 | 567 | def getuploadbox(self): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 568 | """adds a box that lets the user assign strings""" | |
| b32cba34 » | friedelwolff | 2007-01-11 | 569 | uploadbox = { | |
| 570 | "title": self.localize("Upload File"), | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 571 | "file_title": self.localize("Select file to upload"), | |
| b32cba34 » | friedelwolff | 2007-01-11 | 572 | "upload_button": self.localize("Upload File") | |
| 573 | } | ||||
| 574 | if "admin" in self.rights or "overwrite" in self.rights: | ||||
| 575 | uploadbox.update({ | ||||
| 813aa41a » | friedelwolff | 2007-01-12 | 576 | #l10n: radio button text | |
| 577 | "overwrite": self.localize("Overwrite"), | ||||
| 578 | #l10n: tooltip | ||||
| 579 | "overwrite_title": self.localize("Overwrite the current file if it exists"), | ||||
| 580 | #l10n: radio button text | ||||
| 581 | "merge": self.localize("Merge"), | ||||
| 582 | #l10n: tooltip | ||||
| 583 | "merge_title": self.localize("Merge the file with the current file and turn conflicts into suggestions"), | ||||
| b32cba34 » | friedelwolff | 2007-01-11 | 584 | }) | |
| 585 | return uploadbox | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 586 | ||
| 587 | def getchilditems(self, dirfilter): | ||||
| 588 | """get all the items for directories and files viewable at this level""" | ||||
| 589 | if dirfilter is None: | ||||
| 590 | depth = 0 | ||||
| 591 | else: | ||||
| 592 | depth = dirfilter.count(os.path.sep) | ||||
| 21e7d0f3 » | varsist | 2006-10-30 | 593 | if not dirfilter.endswith(os.path.extsep + self.project.fileext): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 594 | depth += 1 | |
| 595 | diritems = [] | ||||
| 596 | for childdir in self.project.browsefiles(dirfilter=dirfilter, depth=depth, includedirs=True, includefiles=False): | ||||
| 597 | diritem = self.getdiritem(childdir) | ||||
| 598 | diritems.append((childdir, diritem)) | ||||
| 599 | diritems.sort() | ||||
| 600 | fileitems = [] | ||||
| 601 | for childfile in self.project.browsefiles(dirfilter=dirfilter, depth=depth, includefiles=True, includedirs=False): | ||||
| 602 | fileitem = self.getfileitem(childfile) | ||||
| 603 | fileitems.append((childfile, fileitem)) | ||||
| 604 | fileitems.sort() | ||||
| 605 | childitems = [diritem for childdir, diritem in diritems] + [fileitem for childfile, fileitem in fileitems] | ||||
| 62d7600d » | davidfraser | 2005-05-05 | 606 | self.polarizeitems(childitems) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 607 | return childitems | |
| 608 | |||||
| d64cc6a0 » | davidfraser | 2005-05-19 | 609 | def getitems(self, itempaths, linksrequired=None, **newargs): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 610 | """gets the listed dir and fileitems""" | |
| 611 | diritems, fileitems = [], [] | ||||
| 612 | for item in itempaths: | ||||
| 21e7d0f3 » | varsist | 2006-10-30 | 613 | if item.endswith(os.path.extsep + self.project.fileext): | |
| d64cc6a0 » | davidfraser | 2005-05-19 | 614 | fileitem = self.getfileitem(item, linksrequired=linksrequired, **newargs) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 615 | fileitems.append((item, fileitem)) | |
| 616 | else: | ||||
| 617 | if item.endswith(os.path.sep): | ||||
| 618 | item = item.rstrip(os.path.sep) | ||||
| d64cc6a0 » | davidfraser | 2005-05-19 | 619 | diritem = self.getdiritem(item, linksrequired=linksrequired, **newargs) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 620 | diritems.append((item, diritem)) | |
| 621 | diritems.sort() | ||||
| 622 | fileitems.sort() | ||||
| 623 | childitems = [diritem for childdir, diritem in diritems] + [fileitem for childfile, fileitem in fileitems] | ||||
| 62d7600d » | davidfraser | 2005-05-05 | 624 | self.polarizeitems(childitems) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 625 | return childitems | |
| 626 | |||||
| 627 | def getgoalitems(self, dirfilter): | ||||
| 628 | """get all the items for directories and files viewable at this level""" | ||||
| 629 | if dirfilter is None: | ||||
| 630 | depth = 0 | ||||
| 631 | else: | ||||
| 632 | depth = dirfilter.count(os.path.sep) | ||||
| 21e7d0f3 » | varsist | 2006-10-30 | 633 | if not dirfilter.endswith(os.path.extsep + self.project.fileext): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 634 | depth += 1 | |
| 635 | allitems = [] | ||||
| 636 | goalchildren = {} | ||||
| 637 | allchildren = [] | ||||
| 638 | for childname in self.project.browsefiles(dirfilter=dirfilter, depth=depth, includedirs=True, includefiles=False): | ||||
| a631f634 » | friedelwolff | 2007-07-03 | 639 | allchildren.append(childname + os.path.sep) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 640 | for childname in self.project.browsefiles(dirfilter=dirfilter, depth=depth, includedirs=False, includefiles=True): | |
| 641 | allchildren.append(childname) | ||||
| 366a160f » | davidfraser | 2005-05-10 | 642 | initial = dirfilter | |
| 21e7d0f3 » | varsist | 2006-10-30 | 643 | if initial and not initial.endswith(os.path.extsep + self.project.fileext): | |
| 366a160f » | davidfraser | 2005-05-10 | 644 | initial += os.path.sep | |
| 645 | if initial: | ||||
| 646 | maxdepth = initial.count(os.path.sep) | ||||
| 647 | else: | ||||
| 648 | maxdepth = 0 | ||||
| 011a8ad7 » | davidfraser | 2005-05-14 | 649 | # using a goal of "" means that the file has no goal | |
| 650 | nogoal = "" | ||||
| d64cc6a0 » | davidfraser | 2005-05-19 | 651 | if self.currentgoal is None: | |
| 011a8ad7 » | davidfraser | 2005-05-14 | 652 | goalnames = self.project.getgoalnames() + [nogoal] | |
| 653 | else: | ||||
| d64cc6a0 » | davidfraser | 2005-05-19 | 654 | goalnames = [self.currentgoal] | |
| 011a8ad7 » | davidfraser | 2005-05-14 | 655 | goalfiledict = {} | |
| 656 | for goalname in goalnames: | ||||
| 231e91b8 » | davidfraser | 2005-05-14 | 657 | goalfiles = self.project.getgoalfiles(goalname, dirfilter, maxdepth=maxdepth, expanddirs=True, includepartial=True) | |
| 366a160f » | davidfraser | 2005-05-10 | 658 | goalfiles = [goalfile for goalfile in goalfiles if goalfile != initial] | |
| 011a8ad7 » | davidfraser | 2005-05-14 | 659 | goalfiledict[goalname] = goalfiles | |
| ca3d8109 » | davidfraser | 2005-04-20 | 660 | for goalfile in goalfiles: | |
| 661 | goalchildren[goalfile] = True | ||||
| 662 | goalless = [] | ||||
| 663 | for item in allchildren: | ||||
| 664 | itemgoals = self.project.getfilegoals(item) | ||||
| 665 | if not itemgoals: | ||||
| 666 | goalless.append(item) | ||||
| 011a8ad7 » | davidfraser | 2005-05-14 | 667 | goalfiledict[nogoal] = goalless | |
| 668 | for goalname in goalnames: | ||||
| 669 | goalfiles = goalfiledict[goalname] | ||||
| 670 | goalusers = self.project.getgoalusers(goalname) | ||||
| 231e91b8 » | davidfraser | 2005-05-14 | 671 | goalitem = self.getgoalitem(goalname, dirfilter, goalusers) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 672 | allitems.append(goalitem) | |
| d64cc6a0 » | davidfraser | 2005-05-19 | 673 | if self.currentgoal == goalname: | |
| 674 | goalchilditems = self.getitems(goalfiles, linksrequired=["editgoal"], goal=self.currentgoal) | ||||
| 011a8ad7 » | davidfraser | 2005-05-14 | 675 | allitems.extend(goalchilditems) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 676 | return allitems | |
| 677 | |||||
| 231e91b8 » | davidfraser | 2005-05-14 | 678 | def getgoalitem(self, goalname, dirfilter, goalusers): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 679 | """returns an item showing a goal entry""" | |
| 231e91b8 » | davidfraser | 2005-05-14 | 680 | pofilenames = self.project.getgoalfiles(goalname, dirfilter, expanddirs=True, includedirs=False) | |
| b00bca80 » | davidfraser | 2006-04-26 | 681 | goal = {"actions": None, "icon": "goal", "isgoal": True, "goal": {"name": goalname}} | |
| 011a8ad7 » | davidfraser | 2005-05-14 | 682 | if goalname: | |
| b00bca80 » | davidfraser | 2006-04-26 | 683 | goal["title"] = goalname | |
| 011a8ad7 » | davidfraser | 2005-05-14 | 684 | else: | |
| 54b56ce6 » | friedelwolff | 2006-06-13 | 685 | goal["title"] = self.localize("Not in a goal") | |
| b00bca80 » | davidfraser | 2006-04-26 | 686 | goal["href"] = self.makelink("index.html", goal=goalname) | |
| 231e91b8 » | davidfraser | 2005-05-14 | 687 | if pofilenames: | |
| dd593f78 » | winterstream | 2008-09-08 | 688 | actionlinks = self.getactionlinks("", LazyStats(self.project, pofilenames), linksrequired=["mine", "review", "translate", "zip"], goal=goalname) | |
| b00bca80 » | davidfraser | 2006-04-26 | 689 | goal["actions"] = actionlinks | |
| 92cd5464 » | dwaynebailey | 2005-04-28 | 690 | goaluserslist = [] | |
| ca3d8109 » | davidfraser | 2005-04-20 | 691 | if goalusers: | |
| 92cd5464 » | dwaynebailey | 2005-04-28 | 692 | goalusers.sort() | |
| b00bca80 » | davidfraser | 2006-04-26 | 693 | goaluserslist = [{"name": goaluser, "sep": ", "} for goaluser in goalusers] | |
| 694 | if goaluserslist: | ||||
| 695 | goaluserslist[-1]["sep"] = "" | ||||
| 696 | goal["goal"]["users"] = goaluserslist | ||||
| d64cc6a0 » | davidfraser | 2005-05-19 | 697 | if goalname and self.currentgoal == goalname: | |
| 7d1b19b1 » | davidfraser | 2005-05-20 | 698 | if "admin" in self.rights: | |
| f9194f2a » | friedelwolff | 2006-10-12 | 699 | unassignedusers = self.project.getuserswithinterest(self.session) | |
| 7d1b19b1 » | davidfraser | 2005-05-20 | 700 | for user in goalusers: | |
| 701 | if user in unassignedusers: | ||||
| f9194f2a » | friedelwolff | 2006-10-12 | 702 | unassignedusers.pop(user) | |
| b00bca80 » | davidfraser | 2006-04-26 | 703 | goal["goal"]["show_adduser"] = True | |
| 704 | goal["goal"]["otherusers"] = unassignedusers | ||||
| 705 | goal["goal"]["adduser_title"] = self.localize("Add User") | ||||
| a141f386 » | winterstream | 2008-08-19 | 706 | goal["stats"] = self.getitemstats("", pofilenames, len(pofilenames), {'goal': goalname}) | |
| 49ca02f8 » | winterstream | 2008-07-01 | 707 | projectstats = self.project.getquickstats(pofilenames) | |
| a1e6de8f » | friedelwolff | 2007-07-26 | 708 | goal["data"] = self.getstats(self.project, projectstats) | |
| b00bca80 » | davidfraser | 2006-04-26 | 709 | return goal | |
| ca3d8109 » | davidfraser | 2005-04-20 | 710 | ||
| d64cc6a0 » | davidfraser | 2005-05-19 | 711 | def getdiritem(self, direntry, linksrequired=None, **newargs): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 712 | """returns an item showing a directory entry""" | |
| 713 | pofilenames = self.project.browsefiles(direntry) | ||||
| 714 | basename = os.path.basename(direntry) | ||||
| a7f63cdf » | dwaynebailey | 2005-07-26 | 715 | browseurl = self.getbrowseurl("%s/" % basename, **newargs) | |
| b00bca80 » | davidfraser | 2006-04-26 | 716 | diritem = {"href": browseurl, "title": basename, "icon": "folder", "isdir": True} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 717 | basename += "/" | |
| dd593f78 » | winterstream | 2008-09-08 | 718 | actionlinks = self.getactionlinks(basename, LazyStats(self.project, pofilenames), linksrequired=linksrequired) | |
| b00bca80 » | davidfraser | 2006-04-26 | 719 | diritem["actions"] = actionlinks | |
| 231e91b8 » | davidfraser | 2005-05-14 | 720 | if self.showgoals and "goal" in self.argdict: | |
| 1a9b15c3 » | winterstream | 2008-08-19 | 721 | goalfilenames = self.project.getgoalfiles(self.currentgoal, dirfilter=direntry, includedirs=False, expanddirs=True) | |
| 49ca02f8 » | winterstream | 2008-07-01 | 722 | diritem["stats"] = self.getitemstats(basename, goalfilenames, (len(goalfilenames), len(pofilenames))) | |
| 723 | projectstats = self.project.getquickstats(goalfilenames) | ||||
| a1e6de8f » | friedelwolff | 2007-07-26 | 724 | diritem["data"] = self.getstats(self.projects, projectstats) | |
| 231e91b8 » | davidfraser | 2005-05-14 | 725 | else: | |
| 49ca02f8 » | winterstream | 2008-07-01 | 726 | diritem["stats"] = self.getitemstats(basename, pofilenames, len(pofilenames)) | |
| 727 | projectstats = self.project.getquickstats(pofilenames) | ||||
| a1e6de8f » | friedelwolff | 2007-07-26 | 728 | diritem["data"] = self.getstats(self.project, projectstats) | |
| b00bca80 » | davidfraser | 2006-04-26 | 729 | return diritem | |
| ca3d8109 » | davidfraser | 2005-04-20 | 730 | ||
| d64cc6a0 » | davidfraser | 2005-05-19 | 731 | def getfileitem(self, fileentry, linksrequired=None, **newargs): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 732 | """returns an item showing a file entry""" | |
| 733 | if linksrequired is None: | ||||
| 77e8bfed » | andreaspauley | 2007-04-02 | 734 | if fileentry.endswith('.po'): | |
| 735 | linksrequired = ["mine", "review", "quick", "all", "po", "xliff", "ts", "csv", "mo", "update", "commit"] | ||||
| 736 | else: | ||||
| 3cb6d3ce » | andreaspauley | 2007-04-03 | 737 | linksrequired = ["mine", "review", "quick", "all", "po", "xliff", "update", "commit"] | |
| ca3d8109 » | davidfraser | 2005-04-20 | 738 | basename = os.path.basename(fileentry) | |
| d64cc6a0 » | davidfraser | 2005-05-19 | 739 | browseurl = self.getbrowseurl(basename, **newargs) | |
| cb586beb » | friedelwolff | 2006-05-04 | 740 | fileitem = {"href": browseurl, "title": basename, "icon": "file", "isfile": True} | |
| dd593f78 » | winterstream | 2008-09-08 | 741 | actions = self.getactionlinks(basename, LazyStats(self.project, [fileentry]), linksrequired=linksrequired) | |
| b00bca80 » | davidfraser | 2006-04-26 | 742 | actionlinks = actions["extended"] | |
| ca3d8109 » | davidfraser | 2005-04-20 | 743 | if "po" in linksrequired: | |
| 3cb6d3ce » | andreaspauley | 2007-04-03 | 744 | poname = basename.replace(".xlf", ".po") | |
| 745 | polink = {"href": poname, "text": self.localize('PO file')} | ||||
| 746 | actionlinks.append(polink) | ||||
| 92cd5464 » | dwaynebailey | 2005-04-28 | 747 | if "xliff" in linksrequired and "translate" in self.rights: | |
| 748 | xliffname = basename.replace(".po", ".xlf") | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 749 | xlifflink = {"href": xliffname, "text": self.localize('XLIFF file')} | |
| 92cd5464 » | dwaynebailey | 2005-04-28 | 750 | actionlinks.append(xlifflink) | |
| c29a4dff » | dwaynebailey | 2005-06-30 | 751 | if "ts" in linksrequired and "translate" in self.rights: | |
| 752 | tsname = basename.replace(".po", ".ts") | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 753 | tslink = {"href": tsname, "text": self.localize('Qt .ts file')} | |
| c29a4dff » | dwaynebailey | 2005-06-30 | 754 | actionlinks.append(tslink) | |
| 92cd5464 » | dwaynebailey | 2005-04-28 | 755 | if "csv" in linksrequired and "translate" in self.rights: | |
| ca3d8109 » | davidfraser | 2005-04-20 | 756 | csvname = basename.replace(".po", ".csv") | |
| b00bca80 » | davidfraser | 2006-04-26 | 757 | csvlink = {"href": csvname, "text": self.localize('CSV file')} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 758 | actionlinks.append(csvlink) | |
| 759 | if "mo" in linksrequired: | ||||
| 760 | if self.project.hascreatemofiles(self.project.projectcode) and "pocompile" in self.rights: | ||||
| 761 | moname = basename.replace(".po", ".mo") | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 762 | molink = {"href": moname, "text": self.localize('MO file')} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 763 | actionlinks.append(molink) | |
| 764 | if "update" in linksrequired and "admin" in self.rights: | ||||
| 94169f82 » | larskr | 2007-10-19 | 765 | if versioncontrol.hasversioning(os.path.join(self.project.podir, | |
| 766 | self.dirname, basename)): | ||||
| 0afd0073 » | friedelwolff | 2006-08-30 | 767 | # l10n: Update from version control (like CVS or Subversion) | |
| 581277bd » | friedelwolff | 2006-06-22 | 768 | updatelink = {"href": "index.html?editing=1&doupdate=1&updatefile=%s" % (basename), "text": self.localize('Update')} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 769 | actionlinks.append(updatelink) | |
| bcb3eea4 » | friedelwolff | 2006-06-22 | 770 | if "commit" in linksrequired and "commit" in self.rights: | |
| 94169f82 » | larskr | 2007-10-19 | 771 | if versioncontrol.hasversioning(os.path.join(self.project.podir, | |
| 772 | self.dirname, basename)): | ||||
| 0afd0073 » | friedelwolff | 2006-08-30 | 773 | # l10n: Commit to version control (like CVS or Subversion) | |
| 581277bd » | friedelwolff | 2006-06-22 | 774 | commitlink = {"href": "index.html?editing=1&docommit=1&commitfile=%s" % (basename), "text": self.localize('Commit')} | |
| bcb3eea4 » | friedelwolff | 2006-06-22 | 775 | actionlinks.append(commitlink) | |
| b00bca80 » | davidfraser | 2006-04-26 | 776 | # update the separators | |
| 777 | for n, actionlink in enumerate(actionlinks): | ||||
| 778 | if n < len(actionlinks)-1: | ||||
| 779 | actionlink["sep"] = " | " | ||||
| 780 | else: | ||||
| 781 | actionlink["sep"] = "" | ||||
| 782 | fileitem["actions"] = actions | ||||
| 49ca02f8 » | winterstream | 2008-07-01 | 783 | fileitem["stats"] = self.getitemstats(basename, [fileentry], None) | |
| 1a9b15c3 » | winterstream | 2008-08-19 | 784 | fileitem["data"] = self.getstats(self.project, self.project.getquickstats([fileentry])) | |
| b00bca80 » | davidfraser | 2006-04-26 | 785 | return fileitem | |
| 786 | |||||
| 787 | def getgoalform(self, basename, goalfile, filegoals): | ||||
| 788 | """Returns a form for adjusting goals""" | ||||
| 789 | goalformname = "goal_%s" % (basename.replace("/", "_").replace(".", "_")) | ||||
| 790 | goalnames = self.project.getgoalnames() | ||||
| 791 | useroptions = [] | ||||
| 792 | for goalname in filegoals: | ||||
| 793 | useroptions += self.project.getgoalusers(goalname) | ||||
| 794 | multifiles = None | ||||
| 795 | if len(filegoals) > 1: | ||||
| 796 | multifiles = "multiple" | ||||
| 797 | multiusers = None | ||||
| 798 | assignusers = [] | ||||
| 799 | assignwhich = [] | ||||
| 800 | if len(useroptions) > 1: | ||||
| 801 | assignfilenames = self.project.browsefiles(dirfilter=goalfile) | ||||
| 802 | if self.currentgoal: | ||||
| 803 | action = "goal-" + self.currentgoal | ||||
| 804 | else: | ||||
| 805 | action = None | ||||
| 806 | assignstats = self.project.combineassignstats(assignfilenames, action) | ||||
| 49ca02f8 » | winterstream | 2008-07-01 | 807 | assignusers = list(assignstats.iterkeys()) | |
| b00bca80 » | davidfraser | 2006-04-26 | 808 | useroptions += [username for username in assignusers if username not in useroptions] | |
| 809 | if len(assignusers) > 1: | ||||
| 810 | multiusers = "multiple" | ||||
| a141f386 » | winterstream | 2008-08-19 | 811 | assignwhich = [('all', self.localize("All Strings")), | |
| 0afd0073 » | friedelwolff | 2006-08-30 | 812 | ('untranslated', self.localize("Untranslated")), | |
| a141f386 » | winterstream | 2008-08-19 | 813 | ('unassigned', self.localize('Unassigned')), | |
| 0afd0073 » | friedelwolff | 2006-08-30 | 814 | ('unassigneduntranslated', self.localize("Unassigned and Untranslated"))] | |
| b00bca80 » | davidfraser | 2006-04-26 | 815 | return { | |
| 816 | "name": goalformname, | ||||
| 817 | "filename": basename, | ||||
| 818 | "goalnames": goalnames, | ||||
| 819 | "filegoals": dict([(goalname, goalname in filegoals or None) for goalname in goalnames]), | ||||
| 820 | "multifiles": multifiles, | ||||
| 821 | "setgoal_text": self.localize("Set Goal"), | ||||
| 822 | "users": useroptions, | ||||
| 823 | "assignusers": dict([(username, username in assignusers or None) for username in useroptions]), | ||||
| 824 | "multiusers": multiusers, | ||||
| 1e87c7e5 » | friedelwolff | 2006-08-07 | 825 | "selectmultiple_text": self.localize("Select Multiple"), | |
| b00bca80 » | davidfraser | 2006-04-26 | 826 | "assignwhich": [{"value": value, "text": text} for value, text in assignwhich], | |
| 827 | "assignto_text": self.localize("Assign To"), | ||||
| 828 | } | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 829 | ||
| 830 | def getactionlinks(self, basename, projectstats, linksrequired=None, filepath=None, goal=None): | ||||
| 831 | """get links to the actions that can be taken on an item (directory / file)""" | ||||
| 832 | if linksrequired is None: | ||||
| f21fe835 » | davidfraser | 2005-05-20 | 833 | linksrequired = ["mine", "review", "quick", "all"] | |
| ca3d8109 » | davidfraser | 2005-04-20 | 834 | actionlinks = [] | |
| b00bca80 » | davidfraser | 2006-04-26 | 835 | actions = {} | |
| 59609720 » | friedelwolff | 2006-05-18 | 836 | actions["goalform"] = None | |
| ca3d8109 » | davidfraser | 2005-04-20 | 837 | if not basename or basename.endswith("/"): | |
| 838 | baseactionlink = basename + "translate.html?" | ||||
| 839 | baseindexlink = basename + "index.html?" | ||||
| 840 | else: | ||||
| 841 | baseactionlink = "%s?translate=1" % basename | ||||
| 842 | baseindexlink = "%s?index=1" % basename | ||||
| 843 | if goal: | ||||
| 844 | baseactionlink += "&goal=%s" % goal | ||||
| 845 | baseindexlink += "&goal=%s" % goal | ||||
| 846 | def addoptionlink(linkname, rightrequired, attrname, showtext, hidetext): | ||||
| 847 | if linkname in linksrequired: | ||||
| 848 | if rightrequired and not rightrequired in self.rights: | ||||
| 849 | return | ||||
| 850 | if getattr(self, attrname, False): | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 851 | link = {"href": self.makelink(baseindexlink, **{attrname:0}), "text": hidetext} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 852 | else: | |
| b00bca80 » | davidfraser | 2006-04-26 | 853 | link = {"href": self.makelink(baseindexlink, **{attrname:1}), "text": showtext} | |
| 854 | link["sep"] = " | " | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 855 | actionlinks.append(link) | |
| a141f386 » | winterstream | 2008-08-19 | 856 | addoptionlink("editing", None, "editing", self.localize("Show Editing Functions"), | |
| 0afd0073 » | friedelwolff | 2006-08-30 | 857 | self.localize("Show Statistics")) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 858 | addoptionlink("track", None, "showtracks", self.localize("Show Tracks"), self.localize("Hide Tracks")) | |
| 0ff4e080 » | friedelwolff | 2006-08-01 | 859 | # l10n: "Checks" are quality checks that Pootle performs on translations to test for common mistakes | |
| ca3d8109 » | davidfraser | 2005-04-20 | 860 | addoptionlink("check", "translate", "showchecks", self.localize("Show Checks"), self.localize("Hide Checks")) | |
| 7352cf81 » | davidfraser | 2005-05-20 | 861 | addoptionlink("goal", None, "showgoals", self.localize("Show Goals"), self.localize("Hide Goals")) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 862 | addoptionlink("assign", "translate", "showassigns", self.localize("Show Assigns"), self.localize("Hide Assigns")) | |
| b00bca80 » | davidfraser | 2006-04-26 | 863 | actions["basic"] = actionlinks | |
| 864 | actionlinks = [] | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 865 | if not goal: | |
| 866 | goalfile = os.path.join(self.dirname, basename) | ||||
| 867 | filegoals = self.project.getfilegoals(goalfile) | ||||
| 7352cf81 » | davidfraser | 2005-05-20 | 868 | if self.showgoals: | |
| ca3d8109 » | davidfraser | 2005-04-20 | 869 | if len(filegoals) > 1: | |
| 903e6e5b » | friedelwolff | 2006-06-13 | 870 | #TODO: This is not making sense. For now make it an unclickable link | |
| 871 | allgoalslink = {"href": "", "text": self.localize("All Goals: %s", (", ".join(filegoals)))} | ||||
| 872 | actionlinks.append(allgoalslink) | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 873 | if "editgoal" in linksrequired and "admin" in self.rights: | |
| b00bca80 » | davidfraser | 2006-04-26 | 874 | actions["goalform"] = self.getgoalform(basename, goalfile, filegoals) | |
| f21fe835 » | davidfraser | 2005-05-20 | 875 | if "mine" in linksrequired and self.session.isopen: | |
| 876 | if "translate" in self.rights: | ||||
| 877 | minelink = self.localize("Translate My Strings") | ||||
| 878 | else: | ||||
| 879 | minelink = self.localize("View My Strings") | ||||
| dd593f78 » | winterstream | 2008-09-08 | 880 | mystats = projectstats.assign.get(self.session.username, []) | |
| f21fe835 » | davidfraser | 2005-05-20 | 881 | if len(mystats): | |
| b00bca80 » | davidfraser | 2006-04-26 | 882 | minelink = {"href": self.makelink(baseactionlink, assignedto=self.session.username), "text": minelink} | |
| f21fe835 » | davidfraser | 2005-05-20 | 883 | else: | |
| b00bca80 » | davidfraser | 2006-04-26 | 884 | minelink = {"title": self.localize("No strings assigned to you"), "text": minelink} | |
| f21fe835 » | davidfraser | 2005-05-20 | 885 | actionlinks.append(minelink) | |
| 5a65a24d » | davidfraser | 2005-05-20 | 886 | if "quick" in linksrequired and "translate" in self.rights: | |
| dd593f78 » | winterstream | 2008-09-08 | 887 | if len(mystats) > 0: # A little shortcut to avoid the call to projectstats.units if we don't have anything assigned | |
| 888 | mytranslatedstats = [statsitem for statsitem in mystats if statsitem in projectstats.units.get("translated", [])] | ||||
| 889 | else: | ||||
| 890 | mytranslatedstats = [] | ||||
| 5a65a24d » | davidfraser | 2005-05-20 | 891 | quickminelink = self.localize("Quick Translate My Strings") | |
| a339b460 » | davidfraser | 2005-05-20 | 892 | if len(mytranslatedstats) < len(mystats): | |
| 49ca02f8 » | winterstream | 2008-07-01 | 893 | quickminelink = {"href": self.makelink(baseactionlink, assignedto=self.session.username, fuzzy=1, untranslated=1), "text": quickminelink} | |
| 5a65a24d » | davidfraser | 2005-05-20 | 894 | else: | |
| b00bca80 » | davidfraser | 2006-04-26 | 895 | quickminelink = {"title": self.localize("No untranslated strings assigned to you"), "text": quickminelink} | |
| 5a65a24d » | davidfraser | 2005-05-20 | 896 | actionlinks.append(quickminelink) | |
| 82243c5c » | winterstream | 2008-09-22 | 897 | if "review" in linksrequired and projectstats.units.get("check-hassuggestion", []): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 898 | if "review" in self.rights: | |
| 899 | reviewlink = self.localize("Review Suggestions") | ||||
| 900 | else: | ||||
| 901 | reviewlink = self.localize("View Suggestions") | ||||
| 49ca02f8 » | winterstream | 2008-07-01 | 902 | reviewlink = {"href": self.makelink(baseactionlink, review=1, **{"hassuggestion": 1}), "text": reviewlink} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 903 | actionlinks.append(reviewlink) | |
| 904 | if "quick" in linksrequired: | ||||
| 905 | if "translate" in self.rights: | ||||
| 906 | quicklink = self.localize("Quick Translate") | ||||
| 907 | else: | ||||
| 908 | quicklink = self.localize("View Untranslated") | ||||
| dd593f78 » | winterstream | 2008-09-08 | 909 | if projectstats.basic.get("translated", 0) < projectstats.basic.get("total", 0): | |
| 49ca02f8 » | winterstream | 2008-07-01 | 910 | quicklink = {"href": self.makelink(baseactionlink, fuzzy=1, untranslated=1), "text": quicklink} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 911 | else: | |
| b00bca80 » | davidfraser | 2006-04-26 | 912 | quicklink = {"title": self.localize("No untranslated items"), "text": quicklink} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 913 | actionlinks.append(quicklink) | |
| 914 | if "all" in linksrequired and "translate" in self.rights: | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 915 | translatelink = {"href": self.makelink(baseactionlink), "text": self.localize('Translate All')} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 916 | actionlinks.append(translatelink) | |
| 917 | if "zip" in linksrequired and "archive" in self.rights: | ||||
| 918 | if filepath and filepath.endswith(".po"): | ||||
| a631f634 » | friedelwolff | 2007-07-03 | 919 | currentfolder = os.path.dirname(filepath) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 920 | else: | |
| 921 | currentfolder = filepath | ||||
| 922 | archivename = "%s-%s" % (self.project.projectcode, self.project.languagecode) | ||||
| 923 | if currentfolder: | ||||
| a631f634 » | friedelwolff | 2007-07-03 | 924 | archivename += "-%s" % currentfolder.replace(os.path.sep, "-") | |
| ca3d8109 » | davidfraser | 2005-04-20 | 925 | if goal: | |
| 926 | archivename += "-%s" % goal | ||||
| 927 | archivename += ".zip" | ||||
| 928 | if goal: | ||||
| 929 | archivename += "?goal=%s" % goal | ||||
| 930 | linktext = self.localize('ZIP of goal') | ||||
| 931 | else: | ||||
| 932 | linktext = self.localize('ZIP of folder') | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 933 | ziplink = {"href": archivename, "text": linktext, "title": archivename} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 934 | actionlinks.append(ziplink) | |
| 79086cc5 » | friedelwolff | 2006-03-16 | 935 | ||
| 936 | if "sdf" in linksrequired and "pocompile" in self.rights and \ | ||||
| 937 | self.project.ootemplate() and not (basename or filepath): | ||||
| 938 | archivename = self.project.languagecode + ".sdf" | ||||
| 939 | linktext = self.localize('Generate SDF') | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 940 | oolink = {"href": archivename, "text": linktext, "title": archivename} | |
| 79086cc5 » | friedelwolff | 2006-03-16 | 941 | actionlinks.append(oolink) | |
| b00bca80 » | davidfraser | 2006-04-26 | 942 | for n, actionlink in enumerate(actionlinks): | |
| 943 | if n < len(actionlinks)-1: | ||||
| 944 | actionlink["sep"] = " | " | ||||
| 945 | else: | ||||
| 946 | actionlink["sep"] = "" | ||||
| 947 | actions["extended"] = actionlinks | ||||
| 948 | if not actions["extended"] and not actions["goalform"] and actions["basic"]: | ||||
| 949 | actions["basic"][-1]["sep"] = "" | ||||
| 950 | return actions | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 951 | ||
| a141f386 » | winterstream | 2008-08-19 | 952 | def getitemstats(self, basename, pofilenames, numfiles, url_opts={}): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 953 | """returns a widget summarizing item statistics""" | |
| feb9b74e » | winterstream | 2008-08-19 | 954 | stats = {"summary": self.describestats(self.project, self.project.getquickstats(pofilenames), numfiles), "checks": [], "tracks": [], "assigns": []} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 955 | if not basename or basename.endswith("/"): | |
| 956 | linkbase = basename + "translate.html?" | ||||
| 957 | else: | ||||
| 958 | linkbase = basename + "?translate=1" | ||||
| 49ca02f8 » | winterstream | 2008-07-01 | 959 | if pofilenames: | |
| 37ffb851 » | davidfraser | 2005-05-09 | 960 | if self.showchecks: | |
| a141f386 » | winterstream | 2008-08-19 | 961 | stats["checks"] = self.getcheckdetails(pofilenames, linkbase, url_opts) | |
| 37ffb851 » | davidfraser | 2005-05-09 | 962 | if self.showtracks: | |
| 963 | trackfilter = (self.dirfilter or "") + basename | ||||
| 964 | trackpofilenames = self.project.browsefiles(trackfilter) | ||||
| 965 | projecttracks = self.project.gettracks(trackpofilenames) | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 966 | stats["tracks"] = self.gettrackdetails(projecttracks, linkbase) | |
| 37ffb851 » | davidfraser | 2005-05-09 | 967 | if self.showassigns: | |
| 968 | if not basename or basename.endswith("/"): | ||||
| 969 | removelinkbase = "?showassigns=1&removeassigns=1" | ||||
| 970 | else: | ||||
| 971 | removelinkbase = "?showassigns=1&removeassigns=1&removefilter=%s" % basename | ||||
| 49ca02f8 » | winterstream | 2008-07-01 | 972 | stats["assigns"] = self.getassigndetails(pofilenames, linkbase, removelinkbase) | |
| b00bca80 » | davidfraser | 2006-04-26 | 973 | return stats | |
| ca3d8109 » | davidfraser | 2005-04-20 | 974 | ||
| 975 | def gettrackdetails(self, projecttracks, linkbase): | ||||
| 976 | """return a list of strings describing the results of tracks""" | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 977 | return [trackmessage for trackmessage in projecttracks] | |
| ca3d8109 » | davidfraser | 2005-04-20 | 978 | ||
| a141f386 » | winterstream | 2008-08-19 | 979 | def getcheckdetails(self, pofilenames, linkbase, url_opts={}): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 980 | """return a list of strings describing the results of checks""" | |
| 49ca02f8 » | winterstream | 2008-07-01 | 981 | projectstats = self.project.combine_unit_stats(pofilenames) | |
| 597e1eb0 » | davidfraser | 2005-05-07 | 982 | total = max(len(projectstats.get("total", [])), 1) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 983 | checklinks = [] | |
| 984 | keys = projectstats.keys() | ||||
| 985 | keys.sort() | ||||
| 986 | for checkname in keys: | ||||
| 987 | if not checkname.startswith("check-"): | ||||
| 988 | continue | ||||
| 597e1eb0 » | davidfraser | 2005-05-07 | 989 | checkcount = len(projectstats[checkname]) | |
| ca3d8109 » | davidfraser | 2005-04-20 | 990 | checkname = checkname.replace("check-", "", 1) | |
| 991 | if total and checkcount: | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 992 | stats = self.nlocalize("%d string (%d%%) failed", "%d strings (%d%%) failed", checkcount, checkcount, (checkcount * 100 / total)) | |
| a141f386 » | winterstream | 2008-08-19 | 993 | url_opts[str(checkname)] = 1 | |
| 994 | checklink = {"href": self.makelink(linkbase, **url_opts), "text": checkname, "stats": stats} | ||||
| 995 | del url_opts[str(checkname)] | ||||
| c97e3f43 » | friedelwolff | 2006-05-15 | 996 | checklinks += [checklink] | |
| ca3d8109 » | davidfraser | 2005-04-20 | 997 | return checklinks | |
| 998 | |||||
| 49ca02f8 » | winterstream | 2008-07-01 | 999 | def getassigndetails(self, pofilenames, linkbase, removelinkbase): | |
| ca3d8109 » | davidfraser | 2005-04-20 | 1000 | """return a list of strings describing the assigned strings""" | |
| 99a1692e » | davidfraser | 2005-05-20 | 1001 | # TODO: allow setting of action, so goals can only show the appropriate action assigns | |
| 684ce2d2 » | davidfraser | 2005-05-20 | 1002 | # quick lookup of what has been translated | |
| dd593f78 » | winterstream | 2008-09-08 | 1003 | projectstats = LazyStats(self.project, pofilenames) | |
| 1004 | totalcount = projectstats.basic.get("total", 0) | ||||
| 1005 | totalwords = projectstats.basic.get("totalsourcewords", 0) | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 1006 | assignlinks = [] | |
| dd593f78 » | winterstream | 2008-09-08 | 1007 | keys = projectstats.assign.keys() | |
| ca3d8109 » | davidfraser | 2005-04-20 | 1008 | keys.sort() | |
| b00bca80 » | davidfraser | 2006-04-26 | 1009 | for assignname in keys: | |
| dd593f78 » | winterstream | 2008-09-08 | 1010 | assigned = projectstats.assign[assignname] | |
| 165c51c0 » | davidfraser | 2005-05-20 | 1011 | assigncount = len(assigned) | |
| 1012 | assignwords = self.project.countwords(assigned) | ||||
| dd593f78 » | winterstream | 2008-09-08 | 1013 | complete = [statsitem for statsitem in assigned if statsitem in projectstats.units.get('translated', [])] | |
| 684ce2d2 » | davidfraser | 2005-05-20 | 1014 | completecount = len(complete) | |
| 1015 | completewords = self.project.countwords(complete) | ||||
| 165c51c0 » | davidfraser | 2005-05-20 | 1016 | if totalcount and assigncount: | |
| b00bca80 » | davidfraser | 2006-04-26 | 1017 | assignlink = {"href": self.makelink(linkbase, assignedto=assignname), "text": assignname} | |
| 165c51c0 » | davidfraser | 2005-05-20 | 1018 | percentassigned = assignwords * 100 / max(totalwords, 1) | |
| 684ce2d2 » | davidfraser | 2005-05-20 | 1019 | percentcomplete = completewords * 100 / max(assignwords, 1) | |
| b00bca80 » | davidfraser | 2006-04-26 | 1020 | stats = self.localize("%d/%d words (%d%%) assigned", assignwords, totalwords, percentassigned) | |
| 1021 | stringstats = self.localize("[%d/%d strings]", assigncount, totalcount) | ||||
| 1022 | completestats = self.localize("%d/%d words (%d%%) translated", completewords, assignwords, percentcomplete) | ||||
| 1023 | completestringstats = self.localize("[%d/%d strings]", completecount, assigncount) | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 1024 | if "assign" in self.rights: | |
| 1025 | removetext = self.localize("Remove") | ||||
| b00bca80 » | davidfraser | 2006-04-26 | 1026 | removelink = {"href": self.makelink(removelinkbase, assignedto=assignname), "text": removetext} | |
| ca3d8109 » | davidfraser | 2005-04-20 | 1027 | else: | |
| b00bca80 » | davidfraser | 2006-04-26 | 1028 | removelink = None | |
| 1029 | assignlinks.append({"assign": assignlink, "stats": stats, "stringstats": stringstats, "completestats": completestats, "completestringstats": completestringstats, "remove": removelink}) | ||||
| ca3d8109 » | davidfraser | 2005-04-20 | 1030 | return assignlinks | |
| 1031 | |||||
