1 # -*- coding: utf-8 -*-
2 #############################################################################
5 # Author : Frederic Lepied
6 # Created on : Mon Nov 22 20:02:56 1999
7 # Version : $Id: I18NCheck.py 1798 2010-06-23 19:47:26Z scop $
8 # Purpose : checks i18n bugs.
9 #############################################################################
15 from Filter import addDetails, printError, printWarning
16 from __isocodes__ import COUNTRIES, LANGUAGES
20 # Associative array of invalid value => correct value
30 'lug': 'lg', # 'lug' is valid, but we standardize on 2 letter codes
33 package_regex = re.compile('-(' + '|'.join(LANGUAGES) + ')$')
34 locale_regex = re.compile('^(/(usr|opt/kde3|opt/gnome)/share/locale/([^/]+))/')
35 correct_subdir_regex = re.compile('^(([a-z][a-z]([a-z])?(_[A-Z][A-Z])?)([.@].*$)?)$')
36 lc_messages_regex = re.compile('/usr/share/locale/([^/]+)/LC_MESSAGES/.*(mo|po)$')
37 man_regex = re.compile('/usr(?:/share)?/man/([^/]+)/man[0-9n][^/]*/[^/]+$')
41 # note: ISO-8859-9E is non standard, ISO-8859-{6,8} are of limited use
42 # as locales (since all modern handling of bidi is based on utf-8 anyway),
43 # so they should be removed once UTF-8 is deployed)
44 EXCEPTION_DIRS = ('C', 'POSIX', 'CP1251', 'CP1255', 'CP1256',
45 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5',
46 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-9E',
47 'ISO-8859-10', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15',
48 'KOI8-R', 'KOI8-U', 'UTF-8', 'default')
50 def is_valid_lang(lang):
51 # TODO: @Foo and charset handling
52 lang = re.sub("[@.].*$", "", lang)
61 # TODO: don't accept all lang_COUNTRY combinations
64 if country not in COUNTRIES:
68 if lang not in LANGUAGES:
73 class I18NCheck(AbstractCheck.AbstractCheck):
76 AbstractCheck.AbstractCheck.__init__(self, 'I18NCheck')
83 files = pkg.files().keys()
85 locales = [] # list of locales for this packages
88 i18n_tags = pkg[rpm.RPMTAG_HEADERI18NTABLE] or ()
92 correct = INCORRECT_LOCALES[i]
93 printError(pkg, 'incorrect-i18n-tag-' + correct, i)
97 # as some webapps have their files under /var/www/html, and
98 # others in /usr/share or /usr/lib, the only reliable way
99 # sofar to detect them is to look for an apache configuration file
101 if f.startswith('/etc/apache2/') or \
102 f.startswith('/etc/httpd/conf.d/'):
106 res = locale_regex.search(f)
108 locale = res.group(2)
109 # checks the same locale only once
110 if locale not in locales:
111 locales.append(locale)
112 res2 = correct_subdir_regex.search(locale)
114 if locale not in EXCEPTION_DIRS:
115 printError(pkg, 'incorrect-locale-subdir', f)
117 locale_name = res2.group(2)
119 correct = INCORRECT_LOCALES[locale_name]
120 printError(pkg, 'incorrect-locale-' + correct, f)
123 res = lc_messages_regex.search(f)
126 subdir = res.group(1)
127 if not is_valid_lang(subdir):
128 printError(pkg, 'invalid-lc-messages-dir', f)
130 res = man_regex.search(f)
132 subdir = res.group(1)
133 if is_valid_lang(subdir):
136 printError(pkg, 'invalid-locale-man-dir', f)
138 if f.endswith('.mo') or subdir:
139 if pkg.files()[f].lang == '' and not webapp:
140 printWarning(pkg, 'file-not-in-%lang', f)
142 main_dir, main_lang = ("", "")
144 lang = pkg.files()[f].lang
145 if main_lang and lang == "" and is_prefix(main_dir + '/', f):
146 printError(pkg, 'subfile-not-in-%lang', f)
147 if main_lang != lang:
148 main_dir, main_lang = f, lang
151 res = package_regex.search(name)
153 locales = 'locales-' + res.group(1)
155 if locales not in (x[0] for x in pkg.requires()):
156 printError(pkg, 'no-dependency-on', locales)
159 return len(p) <= len(s) and p == s[:len(p)]
161 # Create an object to enable the auto registration of the test
165 # Need to add a function to list all the locales
166 'incorrect-i18n-tag-',
170 'incorrect-locale-subdir',
178 'invalid-lc-messages-dir',
182 'invalid-locale-man-dir',
194 'subfile-not-in-%lang',
195 """ If /foo/bar is not tagged %lang(XX) whereas /foo is, the package won't be
196 installable if XX is not in %_install_langs.""",
200 # I18NCheck.py ends here
203 # indent-tabs-mode: nil
204 # py-indent-offset: 4