• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / zope.i18n / 16399678496

27 Sep 2024 06:55AM UTC coverage: 98.997% (-0.02%) from 99.018%
16399678496

push

github

icemac
Back to development: 5.3

747 of 784 branches covered (95.28%)

Branch coverage included in aggregate %.

3203 of 3206 relevant lines covered (99.91%)

1.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/zope/i18n/interfaces/__init__.py
1
##############################################################################
2
#
3
# Copyright (c) 2001-2008 Zope Foundation and Contributors.
4
# All Rights Reserved.
5
#
6
# This software is subject to the provisions of the Zope Public License,
7
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11
# FOR A PARTICULAR PURPOSE.
12
#
13
##############################################################################
14
"""Internationalization of content objects.
15
"""
16
from zope.interface import Attribute
1✔
17
from zope.interface import Interface
1✔
18
from zope.schema import Choice
1✔
19
from zope.schema import Dict
1✔
20
from zope.schema import Field
1✔
21
from zope.schema import TextLine
1✔
22

23

24
class II18nAware(Interface):
1✔
25
    """Internationalization aware content object."""
26

27
    def getDefaultLanguage():
1✔
28
        """Return the default language."""
29

30
    def setDefaultLanguage(language):
1✔
31
        """Set the default language, which will be used if the language is not
32
        specified, or not available.
33
        """
34

35
    def getAvailableLanguages():
1✔
36
        """Find all the languages that are available."""
37

38

39
class IMessageCatalog(Interface):
1✔
40
    """A catalog (mapping) of message ids to message text strings.
41

42
    This interface provides a method for translating a message or message id,
43
    including text with interpolation.  The message catalog basically serves
44
    as a fairly simple mapping object.
45

46
    A single message catalog represents a specific language and domain.
47
    Therefore you will have the following constructor arguments:
48

49
    language -- The language of the returned messages.  This is a read-only
50
                attribute.
51

52
    domain -- The translation domain for these messages.  This is a read-only
53
              attribute.  See ITranslationService.
54

55
    When we refer to text here, we mean text that follows the standard Zope 3
56
    text representation.
57

58
    Note: The IReadMessageCatalog is the absolut minimal version required for
59
          the TranslationService to function.
60
    """
61

62
    def getMessage(msgid):
1✔
63
        """Get the appropriate text for the given message id.
64

65
        An exception is raised if the message id is not found.
66
        """
67

68
    def queryMessage(msgid, default=None):
1✔
69
        """Look for the appropriate text for the given message id.
70

71
        If the message id is not found, default is returned.
72
        """
73

74
    def getPluralMessage(singular, plural, n):
1✔
75
        """Get the appropriate text for the given message id and the
76
        plural id.
77

78
        An exception is raised if nothing was found.
79
        """
80

81
    def queryPluralMessage(singular, plural, n, dft1=None, dft2=None):
1✔
82
        """Look for the appropriate text for the given message id and the
83
        plural id.
84

85
        If `n` is evaluated as a singular and the id is not found,
86
        `dft1` is returned.
87
        If `n` is evaluated as a plural and the plural id is not found,
88
        `dft2` is returned.
89
        """
90

91
    language = TextLine(
1✔
92
        title="Language",
93
        description="The language the catalog translates to.",
94
        required=True)
95

96
    domain = TextLine(
1✔
97
        title="Domain",
98
        description="The domain the catalog is registered for.",
99
        required=True)
100

101
    def getIdentifier():
1✔
102
        """Return a identifier for this message catalog. Note that this
103
        identifier does not have to be unique as several message catalog
104
        could serve the same domain and language.
105

106
        Also, there are no restrictions on the form of the identifier.
107
        """
108

109

110
class IGlobalMessageCatalog(IMessageCatalog):
1✔
111

112
    def reload():
1✔
113
        """Reload and parse .po file"""
114

115

116
class ITranslationDomain(Interface):
1✔
117
    """The Translation Domain utility
118

119
    This interface provides methods for translating text, including text with
120
    interpolation.
121

122
    When we refer to text here, we mean text that follows the standard Zope 3
123
    text representation.
124

125
    The domain is used to specify which translation to use.  Different
126
    products will often use a specific domain naming translations supplied
127
    with the product.
128

129
    A favorite example is: How do you translate 'Sun'? Is it our star, the
130
    abbreviation of Sunday or the company?  Specifying the domain, such as
131
    'Stars' or 'DaysOfWeek' will solve this problem for us.
132

133
    Standard arguments in the methods described below:
134

135
        msgid -- The id of the message that should be translated.  This may be
136
                 an implicit or an explicit message id.
137

138
        mapping -- The object to get the interpolation data from.
139

140
        target_language -- The language to translate to.
141

142
        msgid_plural -- The id of the plural message that should be translated.
143

144
        number -- The number of items linked to the plural of the message.
145

146
        context -- An object that provides contextual information for
147
                   determining client language preferences.  It must implement
148
                   or have an adapter that implements IUserPreferredLanguages.
149
                   It will be to determine the language to translate to if
150
                   target_language is not specified explicitly.
151

152
        Also note that language tags are defined by RFC 1766.
153
    """
154

155
    domain = TextLine(
1✔
156
        title="Domain Name",
157
        description="The name of the domain this object represents.",
158
        required=True)
159

160
    def translate(msgid, mapping=None, context=None, target_language=None,
1✔
161
                  default=None, msgid_plural=None, default_plural=None,
162
                  number=None):
163
        """Return the translation for the message referred to by msgid.
164

165
        Return the default if no translation is found.
166

167
        However, the method does a little more than a vanilla translation.
168
        The method also looks for a possible language to translate to.
169
        After a translation it also replaces any $name variable variables
170
        inside the post-translation string with data from `mapping`. If a
171
        value of `mapping` is a Message it is also translated before
172
        interpolation.
173

174
        """
175

176

177
class IFallbackTranslationDomainFactory(Interface):
1✔
178
    """Factory for creating fallback translation domains
179

180
    Fallback translation domains are primarily used for testing or
181
    debugging i18n.
182
    """
183

184
    def __call__(domain_id=""):
1✔
185
        """Return a fallback translation domain for the given domain id.
186
        """
187

188

189
class ITranslator(Interface):
1✔
190
    """A collaborative object which contains the domain, context, and locale.
191

192
    It is expected that object be constructed with enough information to find
193
    the domain, context, and target language.
194
    """
195

196
    def translate(msgid, mapping=None, default=None,
1✔
197
                  msgid_plural=None, default_plural=None, number=None):
198
        """Translate the source msgid using the given mapping.
199

200
        See ITranslationService for details.
201
        """
202

203

204
class IMessageImportFilter(Interface):
1✔
205
    """The Import Filter for Translation Service Messages.
206

207
       Classes implementing this interface should usually be Adaptors, as
208
       they adapt the IEditableTranslationService interface."""
209

210
    def importMessages(domains, languages, file):
1✔
211
        """Import all messages that are defined in the specified domains and
212
           languages.
213

214
           Note that some implementations might limit to only one domain and
215
           one language. A good example for that is a GettextFile.
216
        """
217

218

219
class ILanguageAvailability(Interface):
1✔
220

221
    def getAvailableLanguages():
1✔
222
        """Return a sequence of 3-tuples for available languages
223

224
        Each 3-tuple should be of the form (language,country,variant) so as
225
        to be suitable for passing to methods in
226
        zope.i18n.interfaces.locales.ILocaleProvider.
227
        """
228

229

230
class IUserPreferredLanguages(Interface):
1✔
231
    """This interface provides language negotiation based on user preferences.
232

233
    See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
234
    """
235

236
    def getPreferredLanguages():
1✔
237
        """Return a sequence of user preferred languages.
238

239
        The sequence is sorted in order of quality, with the most preferred
240
        languages first.
241
        """
242

243

244
class IModifiableUserPreferredLanguages(IUserPreferredLanguages):
1✔
245

246
    def setPreferredLanguages(languages):
1✔
247
        """Set a sequence of user preferred languages.
248

249
        The sequence should be sorted in order of quality, with the most
250
        preferred languages first.
251
        """
252

253

254
class IMessageExportFilter(Interface):
1✔
255
    """The Export Filter for Translation Service Messages.
256

257
       Classes implementing this interface should usually be Adaptors, as
258
       they adapt the IEditableTranslationService interface."""
259

260
    def exportMessages(domains, languages):
1✔
261
        """Export all messages that are defined in the specified domains and
262
           languages.
263

264
           Note that some implementations might limit to only one domain and
265
           one language. A good example for that is a GettextFile.
266
        """
267

268

269
class INegotiator(Interface):
1✔
270
    """A language negotiation service.
271
    """
272

273
    def getLanguage(langs, env):
1✔
274
        """Return the matching language to use.
275

276
        The decision of which language to use is based on the list of
277
        available languages, and the given user environment.  An
278
        IUserPreferredLanguages adapter for the environment is obtained and
279
        the list of acceptable languages is retrieved from the environment.
280

281
        If no match is found between the list of available languages and the
282
        list of acceptable languages, None is returned.
283

284
        Arguments:
285

286
        langs -- sequence of languages (not necessarily ordered)
287

288
        env  -- environment passed to the service to determine a sequence
289
                of user prefered languages
290
        """
291

292
        # TODO: I'd like for there to be a symmetric interface method, one in
293
        # which an adapter is gotten for both the first arg and the second
294
        # arg.  I.e. getLanguage(obj, env)
295
        # But this isn't a good match for the ITranslationService.translate()
296
        # method. :(
297

298

299
class IUserPreferredCharsets(Interface):
1✔
300
    """This interface provides charset negotiation based on user preferences.
301
    """
302

303
    def getPreferredCharsets():
1✔
304
        """Return a sequence of user preferred charsets. Note that the order
305
           should describe the order of preference. Therefore the first
306
           character set in the list is the most preferred one.
307
        """
308

309

310
class IFormat(Interface):
1✔
311
    """A generic formatting class. It basically contains the parsing and
312
    construction method for the particular object the formatting class
313
    handles.
314

315
    The constructor will always require a pattern (specific to the object).
316
    """
317

318
    def setPattern(pattern):
1✔
319
        """Overwrite the old formatting pattern with the new one."""
320

321
    def getPattern():
1✔
322
        """Get the currently used pattern."""
323

324
    def parse(text, pattern=None):
1✔
325
        """Parse the text and convert it to an object, which is returned."""
326

327
    def format(obj, pattern=None):
1✔
328
        """Format an object to a string using the pattern as a rule."""
329

330

331
class INumberFormat(IFormat):
1✔
332
    r"""Specific number formatting interface. Here are the formatting
333
    rules (I modified the rules from ICU a bit, since I think they did not
334
    agree well with the real world XML formatting strings):
335

336
    .. code-block:: none
337

338
      posNegPattern      := ({subpattern};{subpattern} | {subpattern})
339
      subpattern         := {padding}{prefix}{padding}{integer}{fraction}
340
                            {exponential}{padding}{suffix}{padding}
341
      prefix             := '\u0000'..'\uFFFD' - specialCharacters *
342
      suffix             := '\u0000'..'\uFFFD' - specialCharacters *
343
      integer            := {digitField}'0'
344
      fraction           := {decimalPoint}{digitField}
345
      exponential        := E integer
346
      digitField         := ( {digitField} {groupingSeparator} |
347
                              {digitField} '0'* |
348
                              '0'* |
349
                              {optionalDigitField} )
350
      optionalDigitField := ( {digitField} {groupingSeparator} |
351
                              {digitField} '#'* |
352
                              '#'* )
353
      groupingSeparator  := ,
354
      decimalPoint       := .
355
      padding            := * '\u0000'..'\uFFFD'
356

357

358

359
    Possible pattern symbols::
360

361
      0    A digit. Always show this digit even if the value is zero.
362
      #    A digit, suppressed if zero
363
      .    Placeholder for decimal separator
364
      ,    Placeholder for grouping separator
365
      E    Separates mantissa and exponent for exponential formats
366
      ;    Separates formats (that is, a positive number format verses a
367
           negative number format)
368
      -    Default negative prefix. Note that the locale's minus sign
369
           character is used.
370
      +    If this symbol is specified the locale's plus sign character is
371
           used.
372
      %    Multiply by 100, as percentage
373
      ?    Multiply by 1000, as per mille
374
      \u00A4    This is the currency sign. it will be replaced by a currency
375
           symbol. If it is present in a pattern, the monetary decimal
376
           separator is used instead of the decimal separator.
377
      \u00A4\u00A4   This is the international currency sign. It will be
378
           replaced by an international currency symbol.  If it is present
379
           in a pattern, the monetary decimal separator is used instead of
380
           the decimal separator.
381
      X    Any other characters can be used in the prefix or suffix
382
      '    Used to quote special characters in a prefix or suffix
383
    """
384

385
    type = Field(
1✔
386
        title="Type",
387
        description=("The type into which a string is parsed. If ``None``, "
388
                     "then ``int`` will be used for whole numbers and "
389
                     "``float`` for decimals."),
390
        default=None,
391
        required=False)
392

393
    symbols = Dict(
1✔
394
        title="Number Symbols",
395
        key_type=Choice(
396
            title="Dictionary Class",
397
            values=("decimal", "group", "list", "percentSign",
398
                    "nativeZeroDigit", "patternDigit", "plusSign",
399
                    "minusSign", "exponential", "perMille",
400
                    "infinity", "nan")),
401
        value_type=TextLine(title="Symbol"))
402

403

404
class IDateTimeFormat(IFormat):
1✔
405
    """DateTime formatting and parsing interface. Here is a list of
406
    possible characters and their meaning:
407

408
      ====== ===================== ================= =====================
409
      Symbol Meaning               Presentation      Example
410
      ====== ===================== ================= =====================
411
      G      era designator        (Text)            AD
412
      y      year                  (Number)          1996
413
      M      month in year         (Text and Number) July and 07
414
      d      day in month          (Number)          10
415
      h      hour in am/pm (1-12)  (Number)          12
416
      H      hour in day (0-23)    (Number)          0
417
      m      minute in hour        (Number)          30
418
      s      second in minute      (Number)          55
419
      S      millisecond           (Number)          978
420
      E      day in week           (Text and Number) Tuesday
421
      D      day in year           (Number)          189
422
      F      day of week in month  (Number)          2 (2nd Wed in July)
423
      w      week in year          (Number)          27
424
      W      week in month         (Number)          2
425
      a      am/pm marker          (Text)            pm
426
      k      hour in day (1-24)    (Number)          24
427
      K      hour in am/pm (0-11)  (Number)          0
428
      z      time zone             (Text)            Pacific Standard Time
429
      '      escape for text
430
      ''     single quote                            '
431
      ====== ===================== ================= =====================
432

433
    Meaning of the amount of characters:
434

435
      Text
436

437
        Four or more, use full form, <4, use short or abbreviated form if it
438
        exists. (for example, "EEEE" produces "Monday", "EEE" produces "Mon")
439

440
      Number
441

442
        The minimum number of digits. Shorter numbers are zero-padded to this
443
        amount (for example, if "m" produces "6", "mm" produces "06"). Year is
444
        handled specially; that is, if the count of 'y' is 2, the Year will be
445
        truncated to 2 digits. (for example, if "yyyy" produces "1997", "yy"
446
        produces "97".)
447

448
      Text and Number
449

450
        Three or over, use text, otherwise use number. (for example, "M"
451
        produces "1", "MM" produces "01", "MMM" produces "Jan", and "MMMM"
452
        produces "January".)  """
453

454
    calendar = Attribute("""This object must implement ILocaleCalendar. See
1✔
455
                            this interface's documentation for details.""")
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc