Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support I18n #2135

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ ARG LOGGER_LEVEL=''
ENV LOGGER_LEVEL "$LOGGER_LEVEL"

WORKDIR /app
RUN pybabel compile -d changedetectionio/translations
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compiling happens here

CMD ["python", "./changedetection.py", "-d", "/datastore"]


2 changes: 2 additions & 0 deletions changedetectionio/babel.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[jinja2: **.html]
Constantin1489 marked this conversation as resolved.
Show resolved Hide resolved
[python: **.py]
4 changes: 2 additions & 2 deletions changedetectionio/blueprint/tags/templates/edit-tag.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@

<div class="tabs collapsable">
<ul>
<li class="tab" id=""><a href="#general">General</a></li>
<li class="tab" id=""><a href="#general">{{ _('General') }}</a></li>
Constantin1489 marked this conversation as resolved.
Show resolved Hide resolved
<li class="tab"><a href="#filters-and-triggers">Filters &amp; Triggers</a></li>
<li class="tab"><a href="#notifications">Notifications</a></li>
<li class="tab"><a href="#notifications">{{ _('Notifications') }}</a></li>
</ul>
</div>

Expand Down
8 changes: 8 additions & 0 deletions changedetectionio/flask_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
session,
url_for,
)
from flask_babel import Babel
from flask_babel import _

from flask_paginate import Pagination, get_page_parameter

Expand All @@ -55,6 +57,12 @@
static_folder="static",
template_folder="templates")

def get_locale():
# Debug i8n with simple trick
#return 'ko'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to debug conveniently.

return request.accept_languages.best_match(['en', 'ko'])
babel = Babel(app)
babel.init_app(app, locale_selector=get_locale)
# Super handy for compressing large BrowserSteps responses and others
FlaskCompress(app)

Expand Down
43 changes: 22 additions & 21 deletions changedetectionio/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from wtforms.validators import ValidationError

from validators.url import url as url_validator
from flask_babel import _


# default
Expand Down Expand Up @@ -181,19 +182,19 @@ def __call__(self, form, field):

except urllib3.exceptions.MaxRetryError as e:
driver_url = some_object.command_executor
message = field.gettext('Content fetcher \'%s\' did not respond.' % (field.data))
message += '<br>' + field.gettext(
message = _("Content fetcher '{}' did not respond.".format(field.data))
message += '<br>' + _(
'Be sure that the selenium/webdriver runner is running and accessible via network from this container/host.')
message += '<br>' + field.gettext('Did you follow the instructions in the wiki?')
message += '<br><br>' + field.gettext('WebDriver Host: %s' % (driver_url))
message += '<br>' + _('Did you follow the instructions in the wiki?')
message += '<br><br>' + _('WebDriver Host: {}'.format(driver_url))
message += '<br><a href="https://github.com/dgtlmoon/changedetection.io/wiki/Fetching-pages-with-WebDriver">Go here for more information</a>'
message += '<br>'+field.gettext('Content fetcher did not respond properly, unable to use it.\n %s' % (str(e)))
message += '<br>'+_('Content fetcher did not respond properly, unable to use it.\n {}'.format(str(e)))

raise ValidationError(message)

except Exception as e:
message = field.gettext('Content fetcher \'%s\' did not respond properly, unable to use it.\n %s')
raise ValidationError(message % (field.data, e))
message = _("Content fetcher '{}' did not respond properly, unable to use it.\n {}")
raise ValidationError(message.format(field.data, e))


class ValidateNotificationBodyAndTitleWhenURLisSet(object):
Expand All @@ -208,7 +209,7 @@ def __init__(self, message=None):
def __call__(self, form, field):
if len(field.data):
if not len(form.notification_title.data) or not len(form.notification_body.data):
message = field.gettext('Notification Body and Title is required when a Notification URL is used')
message = _('Notification Body and Title is required when a Notification URL is used')
raise ValidationError(message)

class ValidateAppRiseServers(object):
Expand All @@ -225,7 +226,7 @@ def __call__(self, form, field):

for server_url in field.data:
if not apobj.add(server_url):
message = field.gettext('\'%s\' is not a valid AppRise URL.' % (server_url))
message = _("'{}' is not a valid AppRise URL.".format(server_url))
raise ValidationError(message)

class ValidateJinja2Template(object):
Expand Down Expand Up @@ -302,8 +303,8 @@ def __call__(self, form, field):
regex = html_tools.perl_style_slash_enclosed_regex_to_options(line)
re.compile(regex)
except re.error:
message = field.gettext('RegEx \'%s\' is not a valid regular expression.')
raise ValidationError(message % (line))
message = _("RegEx '{}' is not a valid regular expression.")
raise ValidationError(message.format(line))

class ValidateCSSJSONXPATHInput(object):
"""
Expand Down Expand Up @@ -342,8 +343,8 @@ def __call__(self, form, field):
try:
elementpath.select(tree, line.strip(), parser=XPath3Parser)
except elementpath.ElementPathError as e:
message = field.gettext('\'%s\' is not a valid XPath expression. (%s)')
raise ValidationError(message % (line, str(e)))
message = _("'{}' is not a valid XPath expression. ({})")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested with wrong xpath syntax and worked. But am I right?
I'm totally unaware of the field.gettext. If it is come from wtforms, the gettext is from python builtin lib.

raise ValidationError(message.format(line, str(e)))
except:
raise ValidationError("A system-error occurred when validating your XPath expression")

Expand All @@ -357,8 +358,8 @@ def __call__(self, form, field):
try:
tree.xpath(line.strip())
except etree.XPathEvalError as e:
message = field.gettext('\'%s\' is not a valid XPath expression. (%s)')
raise ValidationError(message % (line, str(e)))
message = _("'{}' is not a valid XPath expression. ({})")
raise ValidationError(message.format(line, str(e)))
except:
raise ValidationError("A system-error occurred when validating your XPath expression")

Expand All @@ -377,8 +378,8 @@ def __call__(self, form, field):
try:
parse(input)
except (JsonPathParserError, JsonPathLexerError) as e:
message = field.gettext('\'%s\' is not a valid JSONPath expression. (%s)')
raise ValidationError(message % (input, str(e)))
message = _("'{}' is not a valid JSONPath expression. ({})")
raise ValidationError(message.format(input, str(e)))
except:
raise ValidationError("A system-error occurred when validating your JSONPath expression")

Expand All @@ -399,8 +400,8 @@ def __call__(self, form, field):
try:
jq.compile(input)
except (ValueError) as e:
message = field.gettext('\'%s\' is not a valid jq expression. (%s)')
raise ValidationError(message % (input, str(e)))
message = _("'{}' is not a valid jq expression. ({})")
raise ValidationError(message.format(input, str(e)))
except:
raise ValidationError("A system-error occurred when validating your jq expression")

Expand All @@ -409,9 +410,9 @@ class quickWatchForm(Form):

url = fields.URLField('URL', validators=[validateURL()])
tags = StringTagUUID('Group tag', [validators.Optional()])
watch_submit_button = SubmitField('Watch', render_kw={"class": "pure-button pure-button-primary"})
watch_submit_button = SubmitField(_('Watch'), render_kw={"class": "pure-button pure-button-primary"})
processor = RadioField(u'Processor', choices=processors.available_processors(), default="text_json_diff")
edit_and_watch_submit_button = SubmitField('Edit > Watch', render_kw={"class": "pure-button pure-button-primary"})
edit_and_watch_submit_button = SubmitField(_('Edit > Watch'), render_kw={"class": "pure-button pure-button-primary"})


# Common to a single watch and the global settings
Expand Down
Loading