forked from zammad/zammad
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
…#556, fixes zammad#3275 - Refactoring: Implement new translation toolchain based on gettext. - Translations are no longer fetched from the cloud. - Instead, they are extracted from the codebase and stored in i18n/zammad.pot. - Translations will be managed via a public Weblate instance soon. - The translated .po files are fed to the database as before. - It is now possible to change "translation" strings for en-us locally via the admin GUI. - It is no longer possible to submit local changes.
- Loading branch information
Showing
481 changed files
with
534,431 additions
and
3,439 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
module.exports = class DetectTranslatableString | ||
|
||
# coffeelint: disable=detect_translatable_string | ||
rule: | ||
name: 'detect_translatable_string' | ||
level: 'ignore' | ||
message: 'The following string looks like it should be marked as translatable via __(...)' | ||
description: ''' | ||
''' | ||
|
||
constructor: -> | ||
@callTokens = [] | ||
|
||
tokens: ['STRING', 'CALL_START', 'CALL_END'] | ||
|
||
lintToken: (token, tokenApi) -> | ||
[type, tokenValue] = token | ||
|
||
if type in ['CALL_START', 'CALL_END'] | ||
@trackCall token, tokenApi | ||
return | ||
|
||
return false if @isInIgnoredMethod() | ||
|
||
return @lintString(token, tokenApi) | ||
|
||
lintString: (token, tokenApi) -> | ||
[type, tokenValue] = token | ||
|
||
# Remove quotes. | ||
string = tokenValue[1..-2] | ||
|
||
# Ignore strings with less than two words. | ||
return false if string.split(' ').length < 2 | ||
|
||
# Ignore strings that are being used as exception; unlike Ruby exceptions, these should not reach the user. | ||
return false if tokenApi.peek(-3)[1] == 'throw' | ||
return false if tokenApi.peek(-2)[1] == 'throw' | ||
return false if tokenApi.peek(-1)[1] == 'throw' | ||
|
||
# Ignore strings that are being used for comparison | ||
return false if tokenApi.peek(-1)[1] == '==' | ||
|
||
# String interpolation is handled via concatenation, ignore such strings. | ||
return false if tokenApi.peek(1)[1] == '+' | ||
return false if tokenApi.peek(2)[1] == '+' | ||
|
||
BLOCKLIST = [ | ||
# Only look at strings starting with upper case letters | ||
/^[^A-Z]/, | ||
# # Ignore strings starting with three upper case letters like SELECT, POST etc. | ||
# /^[A-Z]{3}/, | ||
] | ||
|
||
return false if BLOCKLIST.some (entry) -> | ||
#console.log([string, entry, string.match(entry), token, tokenApi.peek(-1), tokenApi.peek(1)]) | ||
string.match(entry) | ||
|
||
# console.log(tokenApi.peek(-3)) | ||
# console.log(tokenApi.peek(-2)) | ||
# console.log(tokenApi.peek(-1)) | ||
# console.log(token) | ||
|
||
return { context: "Found: #{token[1]}" } | ||
|
||
ignoredMethods: { | ||
'__': true, | ||
'log': true, | ||
'T': true, | ||
'controllerBind': true, | ||
'error': true, # App.Log.error | ||
'set': true, # App.Config.set | ||
'translateInline': true, | ||
'translateContent': true, | ||
'translatePlain': true, | ||
} | ||
|
||
isInIgnoredMethod: -> | ||
#console.log(@callTokens) | ||
for t in @callTokens | ||
return true if t.isIgnoredMethod | ||
return false | ||
|
||
trackCall: (token, tokenApi) -> | ||
if token[0] is 'CALL_START' | ||
p = tokenApi.peek(-1) | ||
token.isIgnoredMethod = p and @ignoredMethods[p[1]] | ||
@callTokens.push(token) | ||
else | ||
@callTokens.pop() | ||
return null |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/ | ||
|
||
module RuboCop | ||
module Cop | ||
module Zammad | ||
class DetectTranslatableString < Base | ||
extend AutoCorrector | ||
|
||
MSG = 'This string looks like it should be marked as translatable via __(...).'.freeze | ||
|
||
def on_str(node) | ||
# Constants like __FILE__ are handled as strings, but don't respond to begin. | ||
return if !node.loc.respond_to?(:begin) || !node.loc.begin | ||
return if part_of_ignored_node?(node) | ||
|
||
return if !offense?(node) | ||
|
||
add_offense(node) do |corrector| | ||
corrector.replace(node, "__(#{node.source})") | ||
end | ||
end | ||
|
||
def on_regexp(node) | ||
ignore_node(node) | ||
end | ||
|
||
METHOD_NAME_BLOCKLIST = %i[ | ||
__ translate | ||
include? eql? parse | ||
debug info warn error fatal unknown log log_error | ||
].freeze | ||
|
||
def on_send(node) | ||
ignore_node(node) if METHOD_NAME_BLOCKLIST.include? node.method_name | ||
end | ||
|
||
private | ||
|
||
PARENT_SOURCE_BLOCKLIST = [ | ||
# Ignore logged strings | ||
'Rails.logger' | ||
].freeze | ||
|
||
NODE_START_BLOCKLIST = [ | ||
# Only look at strings starting with upper case letters | ||
%r{[^A-Z]}, | ||
# Ignore strings starting with three upper case letters like SELECT, POST etc. | ||
%r{[A-Z]{3}}, | ||
].freeze | ||
|
||
NODE_CONTAIN_BLOCKLIST = [ | ||
# Ignore strings with interpolation. | ||
'#{', | ||
# Ignore Email addresses | ||
'@' | ||
].freeze | ||
|
||
def offense?(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity | ||
|
||
# Ignore Hash Keys | ||
return false if node.parent.type.eql?(:pair) && node.parent.children.first.equal?(node) | ||
|
||
# Ignore equality checks like ... == 'My String' | ||
return false if node.left_sibling.eql?(:==) | ||
|
||
# Remove quotes | ||
node_source = node.source[1..-2] | ||
|
||
# Only match strings with at least two words | ||
return false if node_source.split.count < 2 | ||
|
||
NODE_START_BLOCKLIST.each do |entry| | ||
return false if node_source.start_with? entry | ||
end | ||
|
||
NODE_CONTAIN_BLOCKLIST.each do |entry| | ||
return false if node_source.include? entry | ||
end | ||
|
||
parent_source = node.parent.source | ||
PARENT_SOURCE_BLOCKLIST.each do |entry| | ||
return false if parent_source.include? entry | ||
end | ||
|
||
true | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.