Skip to content
  • Isis Lovecruft's avatar
    Fix the parsing of Accept-Language to actually support fallbacks. · e1ae7a0a
    Isis Lovecruft authored
    All right. Going through the most significant bugs in this function:
    
     * The line from the original function:
         ``langs = request.getHeader('accept-language').split(',')``
       getHeader() returns ``None`` if the header isn't present, so this results
       in a TypeError on the split().
    
     * The line from the original function:
         ``langs = filter(lambda x: re.match('^[a-z\-]{1,5}', x), langs)``
       This chucks locales with capital letters, and doesn't much at all to insure
       that we're actually getting a well-formed header, all at the expense of a
       (rather expensive; they're slow in Python) regex call.
    
     * These lines from the original:
           # add fallback languages
           langs_only = filter(lambda x: '-' in x, langs)
           langs.extend(map(lambda x: x.split('-')[0], langs_only))
       If my 'Accept-Language' header starts with 'en-GB,en-US;q=0.92[…]', then
       this would add ['en','en'] to the end of my header, without even checking
       if I already have 'en'. Instead, we should check if 'en' is already there,
       and iff not, then add it *after the other English headers*. Not after
       Mandarin, Japanese, Arabic, Russian, and the other slew of languages that I
       half-assedly learned at some point.
    
     * These lines from the original:
           # gettext wants _, not -
           map(lambda x: x.replace('-', '_'), langs)
       Great. A pretty mapping. Good thing the returned values weren't saved as
       anything; otherwise they might have been useful!
    
     * Lastly, the way that languages, once parsed were added to gettext, would
       raise UnhandledErrors, *and* it didn't even add the fallbacks correctly,
       meaning we could only get one language at a time.
    e1ae7a0a