Localization en_US issue in 2.3.3

en_US should never have been in the database because there was never such a locale. I think there was a bug at some point where the locale ended up being stored nonetheless when a user’s preferred locale was en_US.

When changing the logic that handles accesses to the JS locale files fail properly with a 404 when trying to retrieve invalid locale files (instead of caching a minimal valid locale file for any weird random locale), this unfortunately broke the JS for people with such a locale set in the account/session.

Here’s a script you can paste in indico shell to fix this:

from indico.util.i18n import get_all_locales


valid_locales = set(get_all_locales())

for locale in valid_locales:
    query = UserSetting.query.filter(UserSetting.module == 'users',
                                     UserSetting.name == 'lang',
                                     UserSetting.value[()].astext != locale,
                                     db.func.lower(UserSetting.value[()].astext) == locale.lower())
    count = query.count()
    print('Incorrect versions of {}: {}'.format(locale, count))
    if count:
        query.update({UserSetting.value: locale}, synchronize_session=False)


query = UserSetting.query.filter(UserSetting.module == 'users',
                                 UserSetting.name == 'lang',
                                 UserSetting.value[()].astext.notin_(valid_locales))
count = query.count()
if count:
    invalid_locales = {us.value for us in query}
    print('Invalid locales: {} ({})'.format(count, ', '.join(sorted(invalid_locales))))
    query.update({UserSetting.value: 'en_GB'}, synchronize_session=False)

db.session.commit()

Afterwards, force a logout for all users (since the bad locale may be stored in their session as well). The easiest way to do this is to purge the redis cache using redis-cli -n 1 flushdb