From 31c0d8c11cdaec5889d8c140a84350fdab55935f Mon Sep 17 00:00:00 2001 From: Arnaud Fontaine <arnaud.fontaine@nexedi.com> Date: Mon, 18 Apr 2022 12:17:56 +0200 Subject: [PATCH] itools: Updated to latest version (0.77.8) as it was code from 2009. Mainly for maintenance sake and to update the code before porting it to python3. --- product/Localizer/itools/README.txt | 18 +- product/Localizer/itools/i18n/__init__.py | 20 +- product/Localizer/itools/i18n/accept.py | 4 +- product/Localizer/itools/i18n/base.py | 57 ---- product/Localizer/itools/i18n/fuzzy.py | 14 +- product/Localizer/itools/i18n/languages.py | 251 ++++++++++++++++++ product/Localizer/itools/i18n/languages.txt | 234 ----------------- product/Localizer/itools/i18n/locale_.py | 133 ++++++++-- product/Localizer/itools/i18n/oracle.py | 276 ++++++++++---------- product/Localizer/itools/utils.py | 85 ++++-- 10 files changed, 590 insertions(+), 502 deletions(-) delete mode 100644 product/Localizer/itools/i18n/base.py create mode 100644 product/Localizer/itools/i18n/languages.py delete mode 100644 product/Localizer/itools/i18n/languages.txt diff --git a/product/Localizer/itools/README.txt b/product/Localizer/itools/README.txt index 0fa58f751a..8dc52378b1 100644 --- a/product/Localizer/itools/README.txt +++ b/product/Localizer/itools/README.txt @@ -8,26 +8,18 @@ The intention is that even these few remaining functionalities should be replaced by native Zope API calls. The original itools distribution on which this stub is based is the -0.50 branch of the itools repository at: +0.77.8 branch of the itools repository at: -https://github.com/hforge/itools/tree/0.50 - -The original CREDITS.txt file can be seen at: - -https://github.com/hforge/itools/blob/0.50/CREDITS +https://github.com/hforge/itools/tree/0.77 The copyright notice of the original code is as follows: Copyright --------- -Copyright (C) 2002-2008 Juan David Ibáñez Palomar <jdavid@itaapy.com> -Copyright (C) 2005-2008 Luis Arturo Belmar-Letelier <luis@itaapy.com> -Copyright (C) 2005-2008 Hervé Cauwelier <herve@itaapy.com> -Copyright (C) 2005-2008 Nicolas Deram <nicolas@itaapy.com> - -And others. Check the CREDITS file for complete list. - +Copyright (C) 2004-2012 J. David Ibáñez <jdavid.ibp@gmail.com> +Copyright (C) 2008 David Versmisse <versmisse@lil.univ-littoral.fr> +Copyright (C) 2009 Hervé Cauwelier <herve@oursours.net> License ------- diff --git a/product/Localizer/itools/i18n/__init__.py b/product/Localizer/itools/i18n/__init__.py index 9d88655210..1a4ff3ee5c 100644 --- a/product/Localizer/itools/i18n/__init__.py +++ b/product/Localizer/itools/i18n/__init__.py @@ -1,6 +1,7 @@ # -*- coding: UTF-8 -*- -# Copyright (C) 2006-2008 Juan David Ibáñez Palomar <jdavid@itaapy.com> -# Copyright (C) 2008 Henry Obein <henry@itaapy.com> +# Copyright (C) 2004, 2006-2009 J. David Ibáñez <jdavid.ibp@gmail.com> +# Copyright (C) 2008 Henry Obein <henry.obein@gmail.com> +# Copyright (C) 2010 Hervé Cauwelier <herve@oursours.net> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,13 +17,13 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # Import from itools -from __future__ import absolute_import -from .accept import AcceptLanguageType, get_accept, select_language -from .accept import init_language_selector -from .base import has_language, get_languages, get_language_name -from .fuzzy import get_distance, get_similarity, is_similar, get_most_similar -from .locale_ import format_date, format_time, format_datetime -from .oracle import guess_language, is_asian_character, is_punctuation +from accept import AcceptLanguageType, get_accept, select_language +from accept import init_language_selector +from fuzzy import get_distance, get_similarity, is_similar, get_most_similar +from languages import has_language, get_languages, get_language_name +from locale_ import format_date, format_time, format_datetime +from locale_ import format_number +from oracle import guess_language, is_asian_character, is_punctuation @@ -41,6 +42,7 @@ __all__ = [ 'format_date', 'format_time', 'format_datetime', + 'format_number', # oracle 'guess_language', 'is_asian_character', diff --git a/product/Localizer/itools/i18n/accept.py b/product/Localizer/itools/i18n/accept.py index 676cc790b3..67f1113fff 100644 --- a/product/Localizer/itools/i18n/accept.py +++ b/product/Localizer/itools/i18n/accept.py @@ -1,5 +1,5 @@ -# -*- coding: utf-8 -*- -# Copyright (C) 2002-2008 Juan David Ibáñez Palomar <jdavid@itaapy.com> +# -*- coding: UTF-8 -*- +# Copyright (C) 2002-2008, 2010 J. David Ibáñez <jdavid.ibp@gmail.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/product/Localizer/itools/i18n/base.py b/product/Localizer/itools/i18n/base.py deleted file mode 100644 index e32242cef2..0000000000 --- a/product/Localizer/itools/i18n/base.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (C) 2002-2003, 2007-2008 Juan David Ibáñez Palomar <jdavid@itaapy.com> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -# Import from itools -from ..utils import get_abspath - - -# Initializes a dictionary containing the iso 639 language codes/names -languages = {} -filename = get_abspath('languages.txt') -for line in open(filename).readlines(): - line = line.strip() - if line and line[0] != '#': - code, name = line.split(' ', 1) - languages[code] = name - -# Builds a sorted list with the languages code and name -language_codes = languages.keys() -language_codes.sort() -langs = [ {'code': x, 'name': languages[x]} for x in language_codes ] - - - -def has_language(code): - return code in languages - - - -def get_languages(): - """Returns a list of tuples with the code and the name of each language. - """ - return [ x.copy() for x in langs ] - - - -def get_language_name(code): - """Returns the name of a language. - """ - # FIXME The value returned should be a MSG object, but the MSG class comes - # from the itools.gettext module, which is higher level than itools.i18n - if code in languages: - return languages[code] - return u'???' - diff --git a/product/Localizer/itools/i18n/fuzzy.py b/product/Localizer/itools/i18n/fuzzy.py index 900d68a6b2..1c008f6d6e 100644 --- a/product/Localizer/itools/i18n/fuzzy.py +++ b/product/Localizer/itools/i18n/fuzzy.py @@ -1,6 +1,6 @@ # -*- coding: UTF-8 -*- # Copyright (C) 2004 Thierry Fromon <from.t@free.fr> -# Copyright (C) 2006-2007 Juan David Ibáñez Palomar <jdavid@itaapy.com> +# Copyright (C) 2004, 2006-2007, 2009 J. David Ibáñez <jdavid.ibp@gmail.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,12 +17,11 @@ def get_distance(a, b): - """ - This function was giving by Magnus Lie Hetland. It calculates the gap + """This function was giving by Magnus Lie Hetland. It calculates the gap (mathematical distance) between two strings with the cost of word's translation inside the string. """ - # XXX Find URL to original code, check license + # FIXME Find URL to original code, check license c = {} n = len(a) m = len(b) @@ -52,8 +51,7 @@ def get_similarity(a, b): def is_similar(a, b, limit=0.8): - """ - Returns True if both text strings are close enough, False otherwise. + """Returns True if both text strings are close enough, False otherwise. The optional parameter 'limit' defines the degree of similarity required to be considered 'close enough', it is a float value between '0' (completely different) and '1' (the same string). @@ -62,8 +60,8 @@ def is_similar(a, b, limit=0.8): def get_most_similar(a, *args): - """ - Returns the text string from 'args' that is closest to the given string. + """Returns the text string from 'args' that is closest to the given + string. """ if not args: return None diff --git a/product/Localizer/itools/i18n/languages.py b/product/Localizer/itools/i18n/languages.py new file mode 100644 index 0000000000..c4bf4c6c4d --- /dev/null +++ b/product/Localizer/itools/i18n/languages.py @@ -0,0 +1,251 @@ +# -*- coding: UTF-8 -*- +# Copyright (C) 2009 J. David Ibáñez <jdavid.ibp@gmail.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# ISO 639-2 (alpha-2) +# http://www.loc.gov/standards/iso639-2/php/code_list.php + + +languages = { + 'aa': u'Afar', + 'ab': u'Abkhazian', + 'ae': u'Avestan', + 'af': u'Afrikaans', + 'ak': u'Akan', + 'am': u'Amharic', + 'an': u'Aragonese', + 'ar': u'Arabic', + 'as': u'Assamese', + 'av': u'Avaric', + 'ay': u'Aymara', + 'az': u'Azerbaijani', + 'ba': u'Bashkir', + 'be': u'Belarusian', + 'bg': u'Bulgarian', + 'bh': u'Bihari', + 'bi': u'Bislama', + 'bm': u'Bambara', + 'bn': u'Bengali', + 'bo': u'Tibetan', + 'br': u'Breton', + 'bs': u'Bosnian', + 'ca': u'Catalan', + 'ce': u'Chechen', + 'ch': u'Chamorro', + 'co': u'Corsican', + 'cr': u'Cree', + 'cs': u'Czech', + 'cu': u'Church Slavic', + 'cv': u'Chuvash', + 'cy': u'Welsh', + 'da': u'Danish', + 'de': u'German', + 'de-AU': u'German/Austria', + 'de-DE': u'German/Germany', + 'de-CH': u'German/Switzerland', + 'dv': u'Divehi; Dhivehi; Maldivian', + 'dz': u'Dzongkha', + 'ee': u'Ewe', + 'el': u'Greek', + 'en': u'English', + 'en-GB': u'English/United Kingdom', + 'en-US': u'English/United States', + 'eo': u'Esperanto', + 'es': u'Spanish', + 'es-AR': u'Spanish/Argentina', + 'es-CO': u'Spanish/Colombia', + 'es-MX': u'Spanish/Mexico', + 'es-ES': u'Spanish/Spain', + 'et': u'Estonian', + 'eu': u'Basque', + 'fa': u'Persian', + 'ff': u'Fulah', + 'fi': u'Finnish', + 'fj': u'Fijian', + 'fo': u'Faroese', + 'fr': u'French', + 'fr-BE': u'French/Belgium', + 'fr-CA': u'French/Canada', + 'fr-FR': u'French/France', + 'fr-CH': u'French/Switzerland', + 'fy': u'Frisian', + 'ga': u'Irish', + 'gd': u'Gaelic', + 'gl': u'Galician', + 'gn': u'Guarani', + 'gu': u'Gujarati', + 'gv': u'Manx', + 'ha': u'Hausa', + 'he': u'Hebrew', + 'hi': u'Hindi', + 'ho': u'Hiri Motu', + 'hr': u'Croatian', + 'ht': u'Haitian', + 'hu': u'Hungarian', + 'hy': u'Armenian', + 'hz': u'Herero', + 'ia': u'Interlingua', + 'id': u'Indonesian', + 'ie': u'Interlingue; Occidental', + 'ig': u'Igbo', + 'ii': u'Sichuan Yi; Nuosu', + 'ik': u'Inupiak', + 'io': u'Ido', + 'is': u'Icelandic', + 'it': u'Italian', + 'iu': u'Inuktitut', + 'ja': u'Japanese', + 'jv': u'Javanese', + 'ka': u'Georgian', + 'kg': u'Kongo', + 'ki': u'Kikuyu; Gikuyu', + 'kj': u'Kuanyama; Kwanyama', + 'kk': u'Kazakh', + 'kl': u'Kalaallisut; Greenlandic', + 'km': u'Khmer', + 'kn': u'Kannada', + 'ko': u'Korean', + 'kr': u'Kanuri', + 'ks': u'Kashmiri', + 'ku': u'Kurdish', + 'kv': u'Komi', + 'kw': u'Cornish', + 'ky': u'Kirghiz; Kyrgyz', + 'la': u'Latin', + 'lb': u'Luxembourgish', + 'lg': u'Ganda', + 'li': u'Limburgan', + 'ln': u'Lingala', + 'lo': u'Lao', + 'lt': u'Lithuanian', + 'lu': u'Luba-Katanga', + 'lv': u'Latvian', + 'mg': u'Malagasy', + 'mh': u'Marshallese', + 'mi': u'Maori', + 'mk': u'Macedonian', + 'ml': u'Malayalam', + 'mn': u'Mongolian', + 'mr': u'Marathi', + 'ms': u'Malay', + 'mt': u'Maltese', + 'my': u'Burmese', + 'na': u'Nauru', + 'nb': u'Norwegian Bokmal', + 'nd': u'Ndebele, North', + 'ne': u'Nepali', + 'ng': u'Ndonga', + 'nl': u'Dutch', + 'nl-BE': u'Dutch/Belgium', + 'nn': u'Norwegian Nyrnosk', + 'no': u'Norwegian', + 'nr': u'Ndebele, South', + 'nv': u'Navajo; Navaho', + 'ny': u'Chichewa; Chewa; Nyanja', + 'oc': u'Occitan', + 'oj': u'Ojibwa', + 'om': u'Oromo', + 'or': u'Oriya', + 'os': u'Ossetian; Ossetic', + 'pa': u'Panjabi; Punjabi', + 'pi': u'Pali', + 'pl': u'Polish', + 'ps': u'Pushto; Pashto', + 'pt': u'Portuguese', + 'pt-BR': u'Portuguese/Brazil', + 'qu': u'Quechua', + 'rm': u'Romansh', + 'rn': u'Rundi', + 'ro': u'Romanian; Moldavian', + 'ru': u'Russian', + 'rw': u'Kinyarwanda', + 'sa': u'Sanskrit', + 'sc': u'Sardinian', + 'sd': u'Sindhi', + 'se': u'Sami', + 'sg': u'Sango', + 'si': u'Sinhala; Sinhalese', + 'sk': u'Slovak', + 'sl': u'Slovenian', + 'sm': u'Samoan', + 'sn': u'Shona', + 'so': u'Somali', + 'sq': u'Albanian', + 'sr': u'Serbian', + 'ss': u'Swati', + 'st': u'Sotho', + 'su': u'Sundanese', + 'sv': u'Swedish', + 'sw': u'Swahili', + 'ta': u'Tamil', + 'te': u'Telugu', + 'tg': u'Tajik', + 'th': u'Thai', + 'ti': u'Tigrinya', + 'tk': u'Turkmen', + 'tl': u'Tagalog', + 'tn': u'Tswana', + 'to': u'Tonga', + 'tr': u'Turkish', + 'ts': u'Tsonga', + 'tt': u'Tatar', + 'tw': u'Twi', + 'ty': u'Tahitian', + 'ug': u'Uighur; Uyghur', + 'uk': u'Ukrainian', + 'ur': u'Urdu', + 'uz': u'Uzbek', + 've': u'Venda', + 'vi': u'Vietnamese', + 'vo': u'Volapuk', + 'wa': u'Walloon', + 'wo': u'Wolof', + 'xh': u'Xhosa', + 'yi': u'Yiddish', + 'yo': u'Yoruba', + 'za': u'Zhuang; Chuang', + 'zh': u'Chinese', + 'zh-CN': u'Chinese/China', + 'zh-TW': u'Chinese/Taiwan', + 'zu': u'Zulu', + } + + +langs = [ {'code': x, 'name': languages[x]} for x in sorted(languages.keys()) ] + + +########################################################################### +# API +########################################################################### +def has_language(code): + return code in languages + + +def get_languages(): + """Returns a list of tuples with the code and the name of each language. + """ + return [ x.copy() for x in langs ] + + + +def get_language_name(code): + """Returns the name of a language. + """ + # FIXME The value returned should be a MSG object, but the MSG class comes + # from the itools.gettext module, which is higher level than itools.i18n + if code in languages: + return languages[code] + return u'???' + diff --git a/product/Localizer/itools/i18n/languages.txt b/product/Localizer/itools/i18n/languages.txt deleted file mode 100644 index 50282c0b21..0000000000 --- a/product/Localizer/itools/i18n/languages.txt +++ /dev/null @@ -1,234 +0,0 @@ -# ISO 639-2 -# http://www.loc.gov/standards/iso639-2/php/code_list.php -# -# Format: "<alpha-2 code> <language name>" - -aa Afar -ab Abkhazian -ae Avestan -af Afrikaans -ak Akan -am Amharic -an Aragonese -ar Arabic -as Assamese -av Avaric -ay Aymara -az Azerbaijani - -ba Bashkir -be Belarusian -bg Bulgarian -bh Bihari -bi Bislama -bm Bambara -bn Bengali -bo Tibetan -br Breton -bs Bosnian - -ca Catalan -ce Chechen -ch Chamorro -co Corsican -cr Cree -cs Czech -cu Church Slavic -cv Chuvash -cy Welsh - -da Danish -de German -de-AU German/Austria -de-DE German/Germany -de-CH German/Switzerland -dv Divehi; Dhivehi; Maldivian -dz Dzongkha - -ee Ewe -el Greek -en English -en-GB English/United Kingdom -en-US English/United States -eo Esperanto -es Spanish -es-AR Spanish/Argentina -es-CO Spanish/Colombia -es-MX Spanish/Mexico -es-ES Spanish/Spain -et Estonian -eu Basque - -fa Persian -ff Fulah -fi Finnish -fj Fijian -fo Faroese -fr French -fr-BE French/Belgium -fr-CA French/Canada -fr-FR French/France -fr-CH French/Switzerland -fy Frisian - -ga Irish -gd Gaelic -gl Galician -gn Guarani -gu Gujarati -gv Manx - -ha Hausa -he Hebrew -hi Hindi -ho Hiri Motu -hr Croatian -ht Haitian -hu Hungarian -hy Armenian -hz Herero - -ia Interlingua -id Indonesian -ie Interlingue; Occidental -ig Igbo -ii Sichuan Yi; Nuosu -ik Inupiak -io Ido -is Icelandic -it Italian -iu Inuktitut - -ja Japanese -jv Javanese - -ka Georgian -kg Kongo -ki Kikuyu; Gikuyu -kj Kuanyama; Kwanyama -kk Kazakh -kl Kalaallisut; Greenlandic -km Khmer -kn Kannada -ko Korean -kr Kanuri -ks Kashmiri -ku Kurdish -kv Komi -kw Cornish -ky Kirghiz; Kyrgyz - -la Latin -lb Luxembourgish -lg Ganda -li Limburgan -ln Lingala -lo Lao -lt Lithuanian -lu Luba-Katanga -lv Latvian - -mg Malagasy -mh Marshallese -mi Maori -mk Macedonian -ml Malayalam -mn Mongolian -mr Marathi -ms Malay -mt Maltese -my Burmese - -na Nauru -nb Norwegian Bokmal -nd Ndebele, North -ne Nepali -ng Ndonga -nl Dutch -nl-BE Dutch/Belgium -nn Norwegian Nyrnosk -no Norwegian -nr Ndebele, South -nv Navajo; Navaho -ny Chichewa; Chewa; Nyanja - -oc Occitan -oj Ojibwa -om Oromo -os Ossetian; Ossetic -or Oriya - -pa Panjabi; Punjabi -pi Pali -pl Polish -ps Pushto; Pashto -pt Portuguese -pt-BR Portuguese/Brazil - -qu Quechua - -rm Romansh -rn Rundi -ro Romanian; Moldavian -ru Russian -rw Kinyarwanda - -sa Sanskrit -sc Sardinian -sd Sindhi -se Sami -sg Sango -si Sinhala; Sinhalese -sk Slovak -sl Slovenian -sm Samoan -sn Shona -so Somali -sq Albanian -sr Serbian -ss Swati -st Sotho -su Sundanese -sv Swedish -sw Swahili - -ta Tamil -te Telugu -tg Tajik -th Thai -ti Tigrinya -tk Turkmen -tl Tagalog -tn Tswana -to Tonga -tr Turkish -ts Tsonga -tt Tatar -tw Twi -ty Tahitian - -ug Uighur; Uyghur -uk Ukrainian -ur Urdu -uz Uzbek - -ve Venda -vi Vietnamese -vo Volapuk - -wa Walloon -wo Wolof - -xh Xhosa - -yi Yiddish -yo Yoruba - -za Zhuang; Chuang -zh Chinese -zh-CN Chinese/China -zh-TW Chinese/Taiwan -zu Zulu - - -# Add here the languages you need diff --git a/product/Localizer/itools/i18n/locale_.py b/product/Localizer/itools/i18n/locale_.py index c28190f06b..2d6248acca 100644 --- a/product/Localizer/itools/i18n/locale_.py +++ b/product/Localizer/itools/i18n/locale_.py @@ -1,5 +1,6 @@ # -*- coding: UTF-8 -*- -# Copyright (C) 2007 Juan David Ibáñez Palomar <jdavid@itaapy.com> +# Copyright (C) 2007, 2009 J. David Ibáñez <jdavid.ibp@gmail.com> +# Copyright (C) 2010 Hervé Cauwelier <herve@oursours.net> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,50 +18,140 @@ """ Output dates and times in locale format. """ -from __future__ import absolute_import -# Import from itools -from .accept import get_accept - - -formats = { - # Date, Time, DateTime - 'en': ('%d/%m/%Y', '%H:%M', '%d/%m/%Y %H:%M'), - 'es': ('%d/%m/%Y', '%H.%M', '%d/%m/%Y %H.%M'), - 'fr': ('%d/%m/%Y', '%Hh%M', '%d/%m/%Y %Hh%M'), - } - - - -available_languages = formats.keys() +# Import from the Standard Library +from decimal import Decimal +# Import from itools +from accept import get_accept -def get_format(accept): +def get_format(source, accept): # By default use the computer's locale if accept is None: accept = get_accept() # Negotiate + available_languages = source.keys() language = accept.select_language(available_languages) if language is None: language = 'en' # The format - return formats[language] + return source[language] + +# +# Date and Time +# + def format_date(x, accept=None): - format = get_format(accept)[0] + format = get_format(date_formats, accept)[0] return x.strftime(format) def format_time(x, accept=None): - format = get_format(accept)[1] + format = get_format(date_formats, accept)[1] return x.strftime(format) def format_datetime(x, accept=None): - format = get_format(accept)[2] + format = get_format(date_formats, accept)[2] return x.strftime(format) + + +# +# Decimal +# + +# http://docs.python.org/library/decimal.html#recipes +# Modified for unicode and trailing currency +def moneyfmt(value, places=2, curr=u'', sep=u',', dp=u'.', pos=u'', + neg=u'-', trailneg=u''): + """Convert Decimal to a money formatted unicode. + + places: required number of places after the decimal point + curr: optional currency symbol (may be blank) + sep: optional grouping separator (comma, period, space, or blank) + dp: decimal point indicator (comma or period) + only specify as blank when places is zero + pos: optional sign for positive numbers: '+', space or blank + neg: optional sign for negative numbers: '-', '(', space or blank + trailneg:optional trailing minus indicator: '-', ')', space or blank + + >>> d = Decimal('-1234567.8901') + >>> moneyfmt(d, curr='$') + '-1,234,567.89$' + >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-') + '1.234.568-' + >>> moneyfmt(d, curr='$', neg='(', trailneg=')') + '(1,234,567.89$)' + >>> moneyfmt(Decimal(123456789), sep=' ') + '123 456 789.00' + >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>') + '<0.02>' + + """ + q = Decimal(10) ** -places # 2 places --> '0.01' + sign, digits, exp = value.quantize(q).as_tuple() + result = [] + digits = map(unicode, digits) + build, next = result.append, digits.pop + if curr: + build(curr) + if sign: + build(trailneg) + for i in range(places): + build(next() if digits else u'0') + build(dp) + if not digits: + build(u'0') + i = 0 + while digits: + build(next()) + i += 1 + if i == 3 and digits: + i = 0 + build(sep) + build(neg if sign else pos) + return u''.join(reversed(result)) + + +def format_number(x, places=2, curr='', pos=u'', neg=u'-', trailneg=u"", + accept=None): + """Convert Decimal to a number formatted unicode. + + places: required number of places after the decimal point + curr: optional currency symbol (may be blank) + pos: optional sign for positive numbers: '+', space or blank + neg: optional sign for negative numbers: '-', '(', space or blank + trailneg:optional trailing minus indicator: '-', ')', space or blank + """ + if type(x) is not Decimal: + x = Decimal(x) + format = get_format(number_formats, accept) + return moneyfmt(x, places=places, curr=curr, pos=pos, neg=neg, + trailneg=trailneg, **format) + + + +########################################################################### +# Initialize the module +########################################################################### + +date_formats = { + # Date, Time, DateTime + 'en': ('%d/%m/%Y', '%H:%M', '%d/%m/%Y %H:%M'), + 'es': ('%d/%m/%Y', '%H.%M', '%d/%m/%Y %H.%M'), + 'fr': ('%d/%m/%Y', '%Hh%M', '%d/%m/%Y %Hh%M'), + } + + +number_formats = { + # See "moneyfmt" docstring for help + 'en': {'sep': u',', 'dp': u'.'}, + 'es': {'sep': u'.', 'dp': u','}, + 'fr': {'sep': u' ', 'dp': u','}, + } diff --git a/product/Localizer/itools/i18n/oracle.py b/product/Localizer/itools/i18n/oracle.py index ed48065b0c..65fb58b9bf 100644 --- a/product/Localizer/itools/i18n/oracle.py +++ b/product/Localizer/itools/i18n/oracle.py @@ -1,7 +1,7 @@ # -*- coding: UTF-8 -*- # Copyright (C) 2004 Thierry Fromon <from.t@free.fr> -# Copyright (C) 2004, 2006-2007 Juan David Ibáñez Palomar <jdavid@itaapy.com> -# Copyright (C) 2008 Henry Obein <henry@itaapy.com> +# Copyright (C) 2004, 2006-2007, 2009 J. David Ibáñez <jdavid.ibp@gmail.com> +# Copyright (C) 2008 Henry Obein <henry.obein@gmail.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,143 +16,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -########################################################################### -# To add a new language, edit the dictionaries below: -# -# - positive_chars -# -# Defines special characters (like accentuated characters) that belong -# to the language. -# -# - negative_chars -# -# Defines special characters (like accentuated characters) that do not -# belong to the language. -# -# - positive_words -# -# Defines common words that belong to the language. -# -# - negative_words -# -# Defines some words that do not belong to the language. -########################################################################### - -import unicodedata - -positive_chars = { - u'¡': ['es'], - u'¿': ['es'], - u'ä': ['de'], - u'ß': ['de'], - u'ç': ['fr'], - u'ê': ['fr'], - u'Ã': ['es'], - u'ñ': ['es'], - u'ö': ['de'], - u'ó': ['es'], - u'ü': ['de'], - u'ú': ['es'], - # Asian languages - # Japanese : based on particles (hiragana) - u'ã®': ['ja'], - u'ã¯': ['ja'], - u'ã§': ['ja'], - u'ã«': ['ja'], - u'ãŒ': ['ja'], - u'ã¸': ['ja'], - u'ã‚’': ['ja'], - u'ã‚„': ['ja'], - u'ã¨': ['ja'], - # Japanese : punctuation - u'ã€': ['ja'], - u'。': ['ja'], -} - -negative_chars = {} - - -positive_words = { - u'à ': ['fr'], - u'al': ['es'], - u'an': ['en'], - u'and': ['en'], - u'are': ['en'], - u'as': ['en'], - u'aux': ['fr'], - u'but': ['en'], - u'como': ['es'], - u'con': ['es'], - u'de': ['es', 'fr'], - u'del': ['es'], - u'des': ['fr'], - u'donc': ['fr'], - u'du': ['fr'], - u'el': ['es'], - u'elle': ['fr'], - u'elles': ['fr'], - u'es': ['es'], - u'est': ['fr'], - u'está': ['es'], - u'et': ['fr'], - u'from': ['en'], - u'hay': ['es'], - u'he': ['en', 'es'], - u'i': ['en'], - u'il': ['fr'], - u'ils': ['fr'], - u'in': ['en'], - u'is': ['en'], - u'it': ['en'], - u'je': ['fr'], - u'las': ['es'], - u'le': ['es', 'fr'], - u'lo': ['es'], - u'les': ['es', 'fr'], - u'los': ['es'], - u'mais': ['fr'], - u'no': ['en', 'es'], - u'nous': ['fr'], - u'nueva': ['es'], - u'o': ['es'], - u'of': ['en'], - u'on': ['en'], - u'or': ['en'], - u'où': ['fr'], - u'para': ['es'], - u'pero': ['es'], - u'por': ['es'], - u'que': ['es', 'fr'], - u'qué': ['es'], - u'she': ['en'], - u'su': ['es'], - u'sur': ['fr'], - u'that': ['en'], - u'the': ['en'], - u'their': ['en'], - u'this': ['en'], - u'to': ['en'], - u'tu': ['es', 'fr'], - u'un': ['es', 'fr'], - u'una': ['es'], - u'une': ['fr'], - u'vous': ['fr'], - u'when': ['en'], - u'where': ['en'], - u'y': ['es'], - u'you': ['en'], - u'your': ['en'], -} - - -negative_words = { - u'du': ['es'], -} - - -# One thousand words should be enough -MAX_WORDS = 1000 - def is_asian_character(c): @@ -340,3 +203,138 @@ def guess_language(text): return None + +########################################################################### +# Initialize the module +# +# To add a new language, edit the dictionaries below: +# +# - positive_chars +# Defines special characters (like accentuated characters) that belong to +# the language. +# +# - negative_chars +# Defines special characters (like accentuated characters) that do not +# belong to the language. +# +# - positive_words +# Defines common words that belong to the language. +# +# - negative_words +# Defines some words that do not belong to the language. +# +########################################################################### + +positive_chars = { + u'¡': ['es'], + u'¿': ['es'], + u'ä': ['de'], + u'ß': ['de'], + u'ç': ['fr'], + u'ê': ['fr'], + u'Ã': ['es'], + u'ñ': ['es'], + u'ö': ['de'], + u'ó': ['es'], + u'ü': ['de'], + u'ú': ['es'], + # Asian languages + # Japanese : based on particles (hiragana) + u'ã®': ['ja'], + u'ã¯': ['ja'], + u'ã§': ['ja'], + u'ã«': ['ja'], + u'ãŒ': ['ja'], + u'ã¸': ['ja'], + u'ã‚’': ['ja'], + u'ã‚„': ['ja'], + u'ã¨': ['ja'], + # Japanese : punctuation + u'ã€': ['ja'], + u'。': ['ja'], + } + +negative_chars = {} + + +positive_words = { + u'à ': ['fr'], + u'al': ['es'], + u'an': ['en'], + u'and': ['en'], + u'are': ['en'], + u'as': ['en'], + u'aux': ['fr'], + u'but': ['en'], + u'como': ['es'], + u'con': ['es'], + u'de': ['es', 'fr'], + u'del': ['es'], + u'des': ['fr'], + u'donc': ['fr'], + u'du': ['fr'], + u'el': ['es'], + u'elle': ['fr'], + u'elles': ['fr'], + u'es': ['es'], + u'est': ['fr'], + u'está': ['es'], + u'et': ['fr'], + u'from': ['en'], + u'hay': ['es'], + u'he': ['en', 'es'], + u'i': ['en'], + u'il': ['fr'], + u'ils': ['fr'], + u'in': ['en'], + u'is': ['en'], + u'it': ['en'], + u'je': ['fr'], + u'las': ['es'], + u'le': ['es', 'fr'], + u'lo': ['es'], + u'les': ['es', 'fr'], + u'los': ['es'], + u'mais': ['fr'], + u'no': ['en', 'es'], + u'nous': ['fr'], + u'nueva': ['es'], + u'o': ['es'], + u'of': ['en'], + u'on': ['en'], + u'or': ['en'], + u'où': ['fr'], + u'para': ['es'], + u'pero': ['es'], + u'por': ['es'], + u'que': ['es', 'fr'], + u'qué': ['es'], + u'she': ['en'], + u'su': ['es'], + u'sur': ['fr'], + u'that': ['en'], + u'the': ['en'], + u'their': ['en'], + u'this': ['en'], + u'to': ['en'], + u'tu': ['es', 'fr'], + u'un': ['es', 'fr'], + u'una': ['es'], + u'une': ['fr'], + u'vous': ['fr'], + u'when': ['en'], + u'where': ['en'], + u'y': ['es'], + u'you': ['en'], + u'your': ['en'], + } + + +negative_words = { + u'du': ['es'], + } + + +# One thousand words should be enough +MAX_WORDS = 1000 + diff --git a/product/Localizer/itools/utils.py b/product/Localizer/itools/utils.py index 4b1262d867..f18bf206d4 100644 --- a/product/Localizer/itools/utils.py +++ b/product/Localizer/itools/utils.py @@ -1,6 +1,6 @@ -# -*- coding: utf-8 -*- -# Copyright (C) 2006-2008 Juan David Ibáñez Palomar <jdavid@itaapy.com> -# Copyright (C) 2008 Gautier Hayoun <gautier.hayoun@itaapy.com> +# -*- coding: UTF-8 -*- +# Copyright (C) 2008-2010 J. David Ibáñez <jdavid.ibp@gmail.com> +# Copyright (C) 2009 David Versmisse <versmisse@lil.univ-littoral.fr> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,19 +16,12 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # Import from the Standard Library -from distutils import core -from distutils.errors import DistutilsOptionError -from distutils.command.build_py import build_py -from distutils.command.register import register -from distutils.command.upload import upload -from getpass import getpass -from mimetypes import MimeTypes -from os import getcwd, open as os_open, devnull, dup2, O_RDWR -from os.path import exists, join as join_path, sep, splitdrive -from re import search -from sys import _getframe, platform, exit, stdin, stdout, stderr -from urllib2 import HTTPPasswordMgr -import sys +from os import getcwd +from os.path import exists, join, sep, splitdrive +from subprocess import Popen, PIPE +from sys import _getframe, modules, getsizeof +from gc import get_referents + def get_abspath(local_path, mname=None): """Returns the absolute path to the required file. @@ -39,19 +32,73 @@ def get_abspath(local_path, mname=None): if mname == '__main__' or mname == '__init__': mpath = getcwd() else: - module = sys.modules[mname] + module = modules[mname] if hasattr(module, '__path__'): mpath = module.__path__[0] elif '.' in mname: - mpath = sys.modules[mname[:mname.rfind('.')]].__path__[0] + mpath = modules[mname[:mname.rfind('.')]].__path__[0] else: mpath = mname drive, mpath = splitdrive(mpath) - mpath = drive + join_path(mpath, local_path) + mpath = drive + join(mpath, local_path) # Make it working with Windows. Internally we use always the "/". if sep == '\\': mpath = mpath.replace(sep, '/') return mpath + + + +def get_version(mname=None): + if mname is None: + mname = _getframe(1).f_globals.get('__name__') + + path = get_abspath('version.txt', mname=mname) + if exists(path): + return open(path).read().strip() + return None + + + +def merge_dicts(d, *args, **kw): + """Merge two or more dictionaries into a new dictionary object. + """ + new_d = d.copy() + for dic in args: + new_d.update(dic) + new_d.update(kw) + return new_d + + + +def get_sizeof(obj): + """Return the size of an object and all objects refered by it. + """ + size = 0 + done = set() + todo = {id(obj): obj} + while todo: + obj_id, obj = todo.popitem() + size += getsizeof(obj) + done.add(obj_id) + done.add(id(obj.__class__)) # Do not count the class + for obj in get_referents(obj): + obj_id = id(obj) + if obj_id not in done: + todo[obj_id] = obj + + return size + + + +def get_pipe(command, cwd=None): + """Wrapper around 'subprocess.Popen' + """ + popen = Popen(command, stdout=PIPE, stderr=PIPE, cwd=cwd) + stdoutdata, stderrdata = popen.communicate() + if popen.returncode != 0: + raise EnvironmentError, (popen.returncode, stderrdata) + return stdoutdata + -- 2.30.9