Repository: searx/searx

Issue:
Langue missing [Occitan]
Hello,
the Occitan is missing, I saw another issue that explains it's because it's not part of another project.
But things have changed and now the Occitan is part of it, and well documented I have to say.
Can the troubadours's language be included now?
Best regards !


Discussion:
> But things have changed and now the Occitan is part of it

Could you provide links?

As I see it still doesn't work:
```
[...]
babel.core.UnknownLocaleError: unknown locale 'oc'
```
```
$ python3 -c 'import babel; print(babel.__version__)'
2.5.3
```
I was talking about the CLDR sorry, it's in there.
Heya, I was led here by @Quenty31 's comment on Babel.

I take it this is an i18n thing, and Babel is grumpy when it can't find a CLDR locale for the language when trying to manipulate a message catalog?
I hope we find a solution :) 
Now the PR is merged, when does searx will speak Occitan? :D 
@asciimoo & @akx Have you got any news about this?
added in b6a2aff94a5669b85785eae22a0a77a4e2d6d443
Unfortunately Babel still doesn't support Occitan and Flask still breaks when given an unsupported locale, so searx still breaks when you set Occitan as the interface language. You can reproduce this bug in every instance that is running version 0.16.0 by setting the interface language to Occitan and saving preferences.

I was able to make Occitan work in https://www.recerca.net, but it was only possible with a hack. Long story short I added [some binary files I manually compiled here](https://github.com/MarcAbonce/python-babel-extra-locales/tree/master/locale-data) to `env/lib/python3.7/site-packages/babel/locale-data/` in my virtual environment.

A better solution would be to patch Flask-Babel. I actually made a PR to Flask-Babel to address this a couple of years ago, but it hasn't been merged yet and now that I check back my code I can see that it sucks. So, I'm going to try and rewrite this on the weekend and hopefully have a cleaner PR that actually gets merged.
Meh, sorry, I should have test it better. What about monkey-patching[0] flask-babel from searx?

[0] https://www.geeksforgeeks.org/monkey-patching-in-python-dynamic-behavior/
If you ask me .. monkey patching is the beginning of all evil :)
@return42 I don't fully agree, monkey patching can be quite useful in some cases. The question is that this case is one of the useful cases or it isn't.
I'm not familiar with the internals of flask-babel/babel but if it only requires a wrapper around the code that decides if occitan is a valid locale, it can work.
In Germany we have a saying. Hammer a nail into the wall and everyone will hang their jacket on it.

But if it is just for a interim fix, why not.  On the long term we should see that @MarcAbonce  [PR](https://github.com/python-babel/flask-babel/pull/122) is merged into flask-babel. 



Resolving patch:
diff --git a/searx/webapp.py b/searx/webapp.py
--- a/searx/webapp.py
+++ b/searx/webapp.py
@@ -45,6 +45,7 @@
     from cgi import escape
 except:
     from html import escape
+from six import next
 from datetime import datetime, timedelta
 from time import time
 from werkzeug.middleware.proxy_fix import ProxyFix
@@ -52,6 +53,8 @@
     Flask, request, render_template, url_for, Response, make_response,
     redirect, send_from_directory
 )
+from babel.support import Translations
+import flask_babel
 from flask_babel import Babel, gettext, format_date, format_decimal
 from flask.json import jsonify
 from searx import settings, searx_dir, searx_debug
@@ -156,6 +159,22 @@
 
 outgoing_proxies = settings['outgoing'].get('proxies') or None
 
+_flask_babel_get_translations = flask_babel.get_translations
+
+
+# monkey patch for flask_babel.get_translations
+def _get_translations():
+    translation_locale = request.form.get('use-translation')
+    if translation_locale:
+        babel_ext = flask_babel.current_app.extensions['babel']
+        translation = Translations.load(next(babel_ext.translation_directories), 'oc')
+    else:
+        translation = _flask_babel_get_translations()
+    return translation
+
+
+flask_babel.get_translations = _get_translations
+
 
 def _get_browser_language(request, lang_list):
     for lang in request.headers.get("Accept-Language", "en").split(","):
@@ -180,6 +199,10 @@ def get_locale():
     if locale == 'zh_TW':
         locale = 'zh_Hant_TW'
 
+    if locale == 'oc':
+        request.form['use-translation'] = 'oc'
+        locale = 'fr_FR'
+
     logger.debug("selected locale is `%s`", locale)
 
     return locale


Test patch: