Skip to content

Commit

Permalink
Localize *.swift files.
Browse files Browse the repository at this point in the history
  • Loading branch information
qiuyuzhou committed Jun 10, 2016
1 parent 7735d6e commit e5e2680
Show file tree
Hide file tree
Showing 5 changed files with 306 additions and 0 deletions.
17 changes: 17 additions & 0 deletions ShadowsocksX-NG.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
9B0BFFEB1D0460A70040E62B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9B0BFFEA1D0460A70040E62B /* Assets.xcassets */; };
9B0BFFEE1D0460A70040E62B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B0BFFEC1D0460A70040E62B /* MainMenu.xib */; };
9B0BFFF91D0460A70040E62B /* ShadowsocksX_NGTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B0BFFF81D0460A70040E62B /* ShadowsocksX_NGTests.swift */; };
9B172A6A1D0ADDDD00B87B9A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9B172A6C1D0ADDDD00B87B9A /* Localizable.strings */; };
9B2491B41D0ACC3A003BBECC /* PreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B2491B61D0ACC3A003BBECC /* PreferencesWindowController.xib */; };
9B2491B71D0ACC3E003BBECC /* AdvPreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B2491B91D0ACC3E003BBECC /* AdvPreferencesWindowController.xib */; };
9B3FFF0D1D05FEB30019A709 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B3FFF0C1D05FEB30019A709 /* Utils.swift */; };
Expand Down Expand Up @@ -115,6 +116,9 @@
9B0BFFFA1D0460A70040E62B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9B0BFFFF1D0460A70040E62B /* ShadowsocksX-NGUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ShadowsocksX-NGUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
9B172A5D1D0ACEA100B87B9A /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/AdvPreferencesWindowController.strings"; sourceTree = "<group>"; };
9B172A601D0ADA5B00B87B9A /* genstrings.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = genstrings.py; sourceTree = "<group>"; };
9B172A6B1D0ADDDD00B87B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; };
9B172A6D1D0ADDE800B87B9A /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
9B2491B51D0ACC3A003BBECC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PreferencesWindowController.xib; sourceTree = "<group>"; };
9B2491B81D0ACC3E003BBECC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AdvPreferencesWindowController.xib; sourceTree = "<group>"; };
9B2491BA1D0ACC49003BBECC /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/PreferencesWindowController.strings"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -213,6 +217,7 @@
9B07EFB01D048E900052D9DF /* Support Files */ = {
isa = PBXGroup;
children = (
9B172A6C1D0ADDDD00B87B9A /* Localizable.strings */,
9B3FFF4B1D09D8F70019A709 /* install_helper.sh */,
9B3FFF351D08CF110019A709 /* jquery.min.js */,
9B3FFF361D08CF110019A709 /* qrcode.min.js */,
Expand Down Expand Up @@ -245,6 +250,7 @@
9B0BFFDC1D0460A70040E62B = {
isa = PBXGroup;
children = (
9B172A601D0ADA5B00B87B9A /* genstrings.py */,
9B0BFFE71D0460A70040E62B /* ShadowsocksX-NG */,
9B0BFFF71D0460A70040E62B /* ShadowsocksX-NGTests */,
9B0B00021D0460A70040E62B /* ShadowsocksX-NGUITests */,
Expand Down Expand Up @@ -454,6 +460,7 @@
knownRegions = (
en,
Base,
"zh-Hans",
);
mainGroup = 9B0BFFDC1D0460A70040E62B;
productRefGroup = 9B0BFFE61D0460A70040E62B /* Products */;
Expand All @@ -475,6 +482,7 @@
files = (
9B3FFF541D09E2D10019A709 /* proxy_conf_helper in Resources */,
9BEEF0691D04D4D500FC52B3 /* install_ss_local.sh in Resources */,
9B172A6A1D0ADDDD00B87B9A /* Localizable.strings in Resources */,
9B2491B41D0ACC3A003BBECC /* PreferencesWindowController.xib in Resources */,
9B3FFF291D08A1DF0019A709 /* user-rule.txt in Resources */,
9BEEF06A1D04D4D500FC52B3 /* start_ss_local.sh in Resources */,
Expand Down Expand Up @@ -742,6 +750,15 @@
name = MainMenu.xib;
sourceTree = "<group>";
};
9B172A6C1D0ADDDD00B87B9A /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
9B172A6B1D0ADDDD00B87B9A /* Base */,
9B172A6D1D0ADDE800B87B9A /* zh-Hans */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
9B2491B61D0ACC3A003BBECC /* PreferencesWindowController.xib */ = {
isa = PBXVariantGroup;
children = (
Expand Down
46 changes: 46 additions & 0 deletions ShadowsocksX-NG/Base.lproj/Localizable.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@






/*
* SHARED STRINGS
*/

/*
* ./PACUtils.swift
*/

"PAC has been updated by latest GFW List." = "PAC has been updated by latest GFW List.";

"Failed to download latest GFW List." = "Failed to download latest GFW List.";

/*
* ./PreferencesWindowController.swift
*/

"New Server" = "New Server";

/*
* ./AppDelegate.swift
*/

"Add Shadowsocks Server Profile" = "Add Shadowsocks Server Profile";

"By scan QR Code" = "By scan QR Code";

" Encription Method: \(profile.method)" = " Encription Method: \(profile.method)";

"Current server profile is not valid." = "Current server profile is not valid.";

"No current server profile." = "No current server profile.";

"Shadowsocks: On" = "Shadowsocks: On";

"Close Shadowsocks" = "Close Shadowsocks";

"Shadowsocks: Off" = "Shadowsocks: Off";

"Open Shadowsocks" = "Open Shadowsocks";

42 changes: 42 additions & 0 deletions ShadowsocksX-NG/en.lproj/MainMenu.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

/* Class = "NSMenuItem"; title = "Global Mode"; ObjectID = "3Sa-e9-VXX"; */
"3Sa-e9-VXX.title" = "Global Mode";

/* Class = "NSMenu"; title = "Servers"; ObjectID = "9Y1-db-3HK"; */
"9Y1-db-3HK.title" = "Servers";

/* Class = "NSMenuItem"; title = "Open ShadowsocksX"; ObjectID = "GSu-Tf-StS"; */
"GSu-Tf-StS.title" = "Open ShadowsocksX";

/* Class = "NSMenu"; title = "ShadowsocksX-NE"; ObjectID = "Hob-KD-bx9"; */
"Hob-KD-bx9.title" = "ShadowsocksX-NE";

/* Class = "NSMenuItem"; title = "Server Preferences..."; ObjectID = "M5r-E7-44f"; */
"M5r-E7-44f.title" = "Server Preferences...";

/* Class = "NSMenuItem"; title = "Scan QR Code From Screen ..."; ObjectID = "Qe6-bF-paT"; */
"Qe6-bF-paT.title" = "Scan QR Code From Screen ...";

/* Class = "NSMenuItem"; title = "Show QR Code For Current Server..."; ObjectID = "R6A-96-Zcb"; */
"R6A-96-Zcb.title" = "Show QR Code For Current Server...";

/* Class = "NSMenuItem"; title = "Update PAC from GFW List"; ObjectID = "TFc-Ec-duM"; */
"TFc-Ec-duM.title" = "Update PAC from GFW List";

/* Class = "NSMenuItem"; title = "Advance Preference ..."; ObjectID = "bZ3-fy-34d"; */
"bZ3-fy-34d.title" = "Advance Preference ...";

/* Class = "NSMenuItem"; title = "Launch At Login"; ObjectID = "eUq-p7-ICK"; */
"eUq-p7-ICK.title" = "Launch At Login";

/* Class = "NSMenuItem"; title = "Showsocks: On"; ObjectID = "fzk-mE-CEV"; */
"fzk-mE-CEV.title" = "Showsocks: On";

/* Class = "NSMenuItem"; title = "Auto Mode By PAC"; ObjectID = "hOa-5N-3ik"; */
"hOa-5N-3ik.title" = "Auto Mode By PAC";

/* Class = "NSMenuItem"; title = "Servers"; ObjectID = "u5M-hQ-VSc"; */
"u5M-hQ-VSc.title" = "Servers";

/* Class = "NSMenuItem"; title = "Quit"; ObjectID = "vJS-JW-byz"; */
"vJS-JW-byz.title" = "Quit";
46 changes: 46 additions & 0 deletions ShadowsocksX-NG/zh-Hans.lproj/Localizable.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@






/*
* SHARED STRINGS
*/

/*
* ./PACUtils.swift
*/

"PAC has been updated by latest GFW List." = "已经使用最新的 GFW List 更新PAC";

"Failed to download latest GFW List." = "下载 GFW List 失败";

/*
* ./PreferencesWindowController.swift
*/

"New Server" = "新服务器";

/*
* ./AppDelegate.swift
*/

"Add Shadowsocks Server Profile" = "已添加新Shaodwsocks服务器配置";

"By scan QR Code" = "通过扫描二维码";

" Encription Method: \(profile.method)" = " 加密方法: \(profile.method)";

"Current server profile is not valid." = "当前服务器配置无效";

"No current server profile." = "未设置当前服务器配置";

"Shadowsocks: On" = "Shadowsocks: On";

"Close Shadowsocks" = "关闭 Shadowsocks";

"Shadowsocks: Off" = "Shadowsocks: Off";

"Open Shadowsocks" = "打开 Shadowsocks";

155 changes: 155 additions & 0 deletions genstrings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Created by Johannes Schriewer on 2011-11-30. Modified by Roy Marmelstein 2015-08-05
# Copyright (c) 2011 planetmutlu.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# This script is heavily copied from: https://github.com/dunkelstern/Cocoa-Localisation-Helper
# Copied from https://github.com/marmelroy/Localize-Swift By QiuYuzhou

import os, re, subprocess
import fnmatch

def fetch_files_recursive(directory, extension):
matches = []
for root, dirnames, filenames in os.walk(directory):
for filename in fnmatch.filter(filenames, '*' + extension):
matches.append(os.path.join(root, filename))
return matches


# prepare regexes
localizedStringComment = re.compile('NSLocalizedString\("([^"]*)",\s*"([^"]*)"\s*\)', re.DOTALL)
localizedStringNil = re.compile('NSLocalizedString\("([^"]*)",\s*nil\s*\)', re.DOTALL)
localized = re.compile('Localized\("([^"]*)"[^\n\r]*\)', re.DOTALL)
localizedProperty = re.compile('"([^"]*)".localized', re.DOTALL)# Add By QiuYuzhou
localizedSwift2 = re.compile('"([^"]*)".localized\(\)', re.DOTALL)
localizedSwift2WithFormat = re.compile('"([^"]*)".localizedFormat\([^\n\r]*\)', re.DOTALL)

# get string list
uid = 0
strings = []
for file in fetch_files_recursive('.', '.swift'):
with open(file, 'r') as f:
content = f.read()
for result in localizedStringComment.finditer(content):
uid += 1
strings.append((result.group(1), result.group(2), file, uid))
for result in localizedStringNil.finditer(content):
uid += 1
strings.append((result.group(1), '', file, uid))
for result in localized.finditer(content):
uid += 1
strings.append((result.group(1), '', file, uid))
# Add By QiuYuzhou, Begin
for result in localizedProperty.finditer(content):
uid += 1
strings.append((result.group(1), '', file, uid))
# Add By QiuYuzhou, End
for result in localizedSwift2.finditer(content):
uid += 1
strings.append((result.group(1), '', file, uid))
for result in localizedSwift2WithFormat.finditer(content):
uid += 1
strings.append((result.group(1), '', file, uid))

# prepare regexes
localizedString = re.compile('"[^=]*=\s*"([^"]*)";')

# Changed By QiuYuzhou, disable for *.xib
# fetch files
#for file in fetch_files_recursive('.', '.xib'):
# tempFile = file + '.strings'
# utf8tempFile = file + '.strings.utf8'
# subprocess.call('ibtool --export-strings-file "' + tempFile + '" "' + file + '" 2>/dev/null', shell=True)
# subprocess.call('iconv -s -f UTF-16 -t UTF-8 "' + tempFile + '" >"'+utf8tempFile+'" 2>/dev/null', shell=True)
#
# f = open(utf8tempFile, 'r')
# for line in f:
# result = localizedString.match(line)
# if result:
# uid += 1
# strings.append((result.group(1), '', file, uid))
# f.close()
#
# os.remove(utf8tempFile)
# os.remove(tempFile)

# find duplicates
duplicated = []
filestrings = {}
for string1 in strings:
dupmatch = 0
for string2 in strings:
if string1[3] == string2[3]:
continue
if string1[0] == string2[0]:
if string1[2] != string2[2]:
dupmatch = 1
break
if dupmatch == 1:
dupmatch = 0
for string2 in duplicated:
if string1[0] == string2[0]:
dupmatch = 1
break
if dupmatch == 0:
duplicated.append(string1)
else:
dupmatch = 0
if string1[2] in filestrings:
for fs in filestrings[string1[2]]:
if fs[0] == string1[0]:
dupmatch = 1
break
else:
filestrings[string1[2]] = []
if dupmatch == 0:
filestrings[string1[2]].append(string1)

print '\n\n\n\n\n'
print '/*\n * SHARED STRINGS\n */\n'

# output filewise
for key in filestrings.keys():
print '/*\n * ' + key + '\n */\n'

strings = filestrings[key]
for string in strings:
if string[1] == '':
print '"' + string[0] + '" = "' + string[0] + '";'
print
else:
print '/* ' + string[1] + ' */'
print '"' + string[0] + '" = "' + string[0] + '";'
print

# output duplicates
for string in duplicated:
if string[1] == '':
print '"' + string[0] + '" = "' + string[0] + '";'
print
else:
print '/* ' + string[1] + ' */'
print '"' + string[0] + '" = "' + string[0] + '";'
print

0 comments on commit e5e2680

Please sign in to comment.