Skip to content

Commit

Permalink
Niutrans support dev (tisfeng#239)
Browse files Browse the repository at this point in the history
* niutrans-support check dev

* niutrans-support check dev

* niutrans-support check dev

* niutrans-support check dev

* perf: remove unused code

* style: update file author info

---------

Co-authored-by: tisfeng <[email protected]>
  • Loading branch information
BigGuang97 and tisfeng authored Nov 23, 2023
1 parent d540347 commit 53bca6d
Show file tree
Hide file tree
Showing 13 changed files with 345 additions and 2 deletions.
20 changes: 20 additions & 0 deletions Easydict.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@
03F14A3B2956016B00CB7379 /* EZVolcanoTranslate.m in Sources */ = {isa = PBXBuildFile; fileRef = 03F14A3A2956016B00CB7379 /* EZVolcanoTranslate.m */; };
03F25CB329327BC200E66A12 /* EZShortcut.m in Sources */ = {isa = PBXBuildFile; fileRef = 03F25CB229327BC200E66A12 /* EZShortcut.m */; };
03F639952AA6CFBB009B9914 /* EZBingConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 03F639942AA6CFBB009B9914 /* EZBingConfig.m */; };
17BCAEF72B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BCAEF52B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m */; };
17BCAEF82B0DFF9000A7D372 /* EZNiuTransTranslate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BCAEF62B0DFF9000A7D372 /* EZNiuTransTranslate.m */; };
27B7919E2AEC36A1006E07C6 /* Easydict.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 27B7919C2AEC36A1006E07C6 /* Easydict.xcconfig */; };
27B7919F2AEC36A1006E07C6 /* Easydict-debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 27B7919D2AEC36A1006E07C6 /* Easydict-debug.xcconfig */; };
6220AD5B2A82812300BBFB52 /* EZBingService.m in Sources */ = {isa = PBXBuildFile; fileRef = 6220AD5A2A82812300BBFB52 /* EZBingService.m */; };
Expand Down Expand Up @@ -629,6 +631,10 @@
03F639932AA6CFBB009B9914 /* EZBingConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZBingConfig.h; sourceTree = "<group>"; };
03F639942AA6CFBB009B9914 /* EZBingConfig.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZBingConfig.m; sourceTree = "<group>"; };
06E15747A7BD34D510ADC6A8 /* Pods-Easydict.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Easydict.debug.xcconfig"; path = "Target Support Files/Pods-Easydict/Pods-Easydict.debug.xcconfig"; sourceTree = "<group>"; };
17BCAEF32B0DFF9000A7D372 /* EZNiuTransTranslateResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZNiuTransTranslateResponse.h; sourceTree = "<group>"; };
17BCAEF42B0DFF9000A7D372 /* EZNiuTransTranslate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZNiuTransTranslate.h; sourceTree = "<group>"; };
17BCAEF52B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZNiuTransTranslateResponse.m; sourceTree = "<group>"; };
17BCAEF62B0DFF9000A7D372 /* EZNiuTransTranslate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZNiuTransTranslate.m; sourceTree = "<group>"; };
27B7919C2AEC36A1006E07C6 /* Easydict.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Easydict.xcconfig; sourceTree = "<group>"; };
27B7919D2AEC36A1006E07C6 /* Easydict-debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Easydict-debug.xcconfig"; sourceTree = "<group>"; };
27B791A02AEC3A5C006E07C6 /* Easydict-debug.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "Easydict-debug.entitlements"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1144,6 +1150,7 @@
03B0222B29231FA6001C7E63 /* Service */ = {
isa = PBXGroup;
children = (
17BCAEF22B0DFF9000A7D372 /* Niutrans */,
6220AD582A8280E800BBFB52 /* Bing */,
0399C6A929A8608000B4AFCC /* OpenAI */,
03F14A382956011400CB7379 /* Volcano */,
Expand Down Expand Up @@ -1810,6 +1817,17 @@
path = Volcano;
sourceTree = "<group>";
};
17BCAEF22B0DFF9000A7D372 /* Niutrans */ = {
isa = PBXGroup;
children = (
17BCAEF42B0DFF9000A7D372 /* EZNiuTransTranslate.h */,
17BCAEF62B0DFF9000A7D372 /* EZNiuTransTranslate.m */,
17BCAEF32B0DFF9000A7D372 /* EZNiuTransTranslateResponse.h */,
17BCAEF52B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m */,
);
path = Niutrans;
sourceTree = "<group>";
};
6220AD582A8280E800BBFB52 /* Bing */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2209,6 +2227,7 @@
03BDA7BC2A26DA280079D04F /* XPMArgumentSignature.m in Sources */,
03B0230229231FA6001C7E63 /* EZWordResultView.m in Sources */,
0399C6A529A747E600B4AFCC /* EZDeepLTranslateResponse.m in Sources */,
17BCAEF82B0DFF9000A7D372 /* EZNiuTransTranslate.m in Sources */,
039F5506294B6E29004AB940 /* EZSettingViewController.m in Sources */,
03BD281E29481C0400F5891A /* EZAudioPlayer.m in Sources */,
03E02A2629250D1D00A10260 /* EZEventMonitor.m in Sources */,
Expand Down Expand Up @@ -2291,6 +2310,7 @@
03542A4F2937B64B00C34C33 /* EZYoudaoOCRResponse.m in Sources */,
03B0233929231FA6001C7E63 /* MMTool.m in Sources */,
03542A552937B7DE00C34C33 /* EZTranslateError.m in Sources */,
17BCAEF72B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m in Sources */,
03BDA7B82A26DA280079D04F /* XPMValuedArgument.m in Sources */,
036196762A000F5900806370 /* NSData+Base64.m in Sources */,
03BDA7BA2A26DA280079D04F /* XPMMutableAttributedArray.m in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "小牛翻译.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions Easydict/App/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -2193,6 +2193,22 @@
}
}
},
"niuTrans_translate" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "NiuTrans"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "小牛翻译"
}
}
}
},
"Youdao" : {
"extractionState" : "manual",
"localizations" : {
Expand Down
1 change: 1 addition & 0 deletions Easydict/Feature/Service/Model/EZConstKey.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ static NSString *const EZOpenAIModelKey = @"EZOpenAIModelKey";
static NSString *const EZDeepLAuthKey = @"EZDeepLAuthKey";

static NSString *const EZBingCookieKey = @"EZBingCookieKey";
static NSString *const EZNiuTransAPIKey = @"EZNiuTransAPIKey";


@interface EZConstKey : NSObject
Expand Down
2 changes: 1 addition & 1 deletion Easydict/Feature/Service/Model/EZEnumTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ FOUNDATION_EXPORT EZServiceType const EZServiceTypeVolcano;
FOUNDATION_EXPORT EZServiceType const EZServiceTypeOpenAI;
FOUNDATION_EXPORT EZServiceType const EZServiceTypeAppleDictionary;
FOUNDATION_EXPORT EZServiceType const EZServiceTypeBing;

FOUNDATION_EXPORT EZServiceType const EZServiceTypeNiuTrans;

FOUNDATION_EXPORT NSString *const EZQueryTextTypeKey;
FOUNDATION_EXPORT NSString *const EZIntelligentQueryTextTypeKey;
Expand Down
2 changes: 1 addition & 1 deletion Easydict/Feature/Service/Model/EZEnumTypes.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
NSString *const EZServiceTypeVolcano = @"Volcano";
NSString *const EZServiceTypeOpenAI = @"OpenAI";
NSString *const EZServiceTypeBing = @"Bing";

NSString *const EZServiceTypeNiuTrans = @"NiuTrans";

NSString *const EZServiceTypeAppleDictionary = @"AppleDictionary";

Expand Down
2 changes: 2 additions & 0 deletions Easydict/Feature/Service/Model/EZServiceTypes.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import "EZBingService.h"
#import "EZConfiguration.h"
#import "EZAppleDictionary.h"
#import "EZNiuTransTranslate.h"

@interface EZServiceTypes ()

Expand Down Expand Up @@ -57,6 +58,7 @@ + (instancetype)allocWithZone:(struct _NSZone *)zone {
EZServiceTypeBaidu, [EZBaiduTranslate class],
EZServiceTypeBing, [EZBingService class],
EZServiceTypeVolcano, [EZVolcanoTranslate class],
EZServiceTypeNiuTrans, [EZNiuTransTranslate class],
nil];
return allServiceDict;
}
Expand Down
17 changes: 17 additions & 0 deletions Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// EZNiuTransTranslate.h
// Easydict
//
// Created by BigGuang97 on 2023/11/23.
// Copyright © 2022 izual. All rights reserved.
//

#import "EZQueryService.h"

NS_ASSUME_NONNULL_BEGIN

@interface EZNiuTransTranslate : EZQueryService

@end

NS_ASSUME_NONNULL_END
190 changes: 190 additions & 0 deletions Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
//
// EZNiuTransTranslate.m
// Easydict
//
// Created by BigGuang97 on 2023/11/23.
// Copyright © 2023 izual. All rights reserved.
//

#import "EZNiuTransTranslate.h"
#import "NSArray+EZChineseText.h"
#import "EZNiuTransTranslateResponse.h"
#import "FWEncryptorAES.h"

static NSString *kNiuTransTranslateURL = @"https://api.niutrans.com/NiuTransServer/translation";


@interface EZNiuTransTranslate ()

@property (nonatomic, copy) NSString *apiKey;

@end

@implementation EZNiuTransTranslate

- (instancetype)init {
if (self = [super init]) {
}
return self;
}

- (NSString *)apiKey {
// This is a test APIKey, please do not abuse it. It is recommended to go to the official website to apply for a personal APIKey.
NSString *defaultEncryptedAPIKey = @"O5C+RKrWBR5GLMtqiOHlyS6Ib9D8JPY7aN8/S49gwmRYZNcxpbQ6eeNso6KoJVeR";
NSString *defaultAPIKey = [FWEncryptorAES decryptText:defaultEncryptedAPIKey key:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]];
NSString *apiKey = [[NSUserDefaults standardUserDefaults] stringForKey:EZNiuTransAPIKey];
if (apiKey.length == 0) {
apiKey = defaultAPIKey;
}
return apiKey;
}


#pragma mark - 重写父类方法

- (EZServiceType)serviceType {
return EZServiceTypeNiuTrans;
}

- (NSString *)name {
return NSLocalizedString(@"niuTrans_translate", nil);
}

- (NSString *)link {
return kNiuTransTranslateURL;
}

// Supported languages: https://niutrans.com/documents/contents/trans_text#languageList
- (MMOrderedDictionary<EZLanguage, NSString *> *)supportLanguagesDictionary {
MMOrderedDictionary *orderedDict = [[MMOrderedDictionary alloc] initWithKeysAndObjects:
EZLanguageAuto, @"auto",
EZLanguageSimplifiedChinese, @"zh",
EZLanguageTraditionalChinese, @"cht",
EZLanguageEnglish, @"en",
EZLanguageJapanese, @"ja",
EZLanguageKorean, @"ko",
EZLanguageFrench, @"fr",
EZLanguageSpanish, @"es",
EZLanguagePortuguese, @"pt",
EZLanguageItalian, @"it",
EZLanguageGerman, @"de",
EZLanguageRussian, @"ru",
EZLanguageArabic, @"ar",
EZLanguageSwedish, @"sv",
EZLanguageRomanian, @"ro",
EZLanguageThai, @"th",
EZLanguageSlovak, @"sk",
EZLanguageDutch, @"nl",
EZLanguageHungarian, @"hu",
EZLanguageGreek, @"el",
EZLanguageDanish, @"da",
EZLanguageFinnish, @"fi",
EZLanguagePolish, @"pl",
EZLanguageCzech, @"cs",
EZLanguageTurkish, @"tr",
EZLanguageLithuanian, @"lt",
EZLanguageLatvian, @"lv",
EZLanguageUkrainian, @"uk",
EZLanguageBulgarian, @"bg",
EZLanguageIndonesian, @"id",
EZLanguageMalay, @"ms",
EZLanguageSlovenian, @"sl",
EZLanguageEstonian, @"et",
EZLanguageVietnamese, @"vi",
EZLanguagePersian, @"fa",
EZLanguageHindi, @"hi",
EZLanguageTelugu, @"te",
EZLanguageTamil, @"ta",
EZLanguageUrdu, @"ur",
EZLanguageFilipino, @"fil",
EZLanguageKhmer, @"km",
EZLanguageLao, @"lo",
EZLanguageBengali, @"bn",
EZLanguageBurmese, @"my",
EZLanguageNorwegian, @"no",
EZLanguageSerbian, @"sr",
EZLanguageCroatian, @"hr",
EZLanguageMongolian, @"mn",
EZLanguageHebrew, @"he",
nil];
return orderedDict;
}

- (void)translate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to completion:(void (^)(EZQueryResult *, NSError *_Nullable))completion {
if ([self prehandleQueryTextLanguage:text autoConvertChineseText:YES from:from to:to completion:completion]) {
return;
}

[self niuTransTranslate:text from:from to:to completion:completion];
}

- (void)ocr:(EZQueryModel *)queryModel completion:(void (^)(EZOCRResult *_Nullable, NSError *_Nullable))completion {
NSLog(@"NiuTrans not support ocr");
}

#pragma mark - NiuTrans API

- (void)niuTransTranslate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to completion:(void (^)(EZQueryResult *_Nullable, NSError *_Nullable))completion {
NSString *souceLangCode = [self languageCodeForLanguage:from];
NSString *targetLangCode = [self languageCodeForLanguage:to];

// NiuTrans API free and NiuTrans pro API use different URL host
NSString *host = @"https://api.niutrans.com";
NSString *url = [NSString stringWithFormat:@"%@/NiuTransServer/translation", host];

NSDictionary *params = @{
@"apikey" : self.apiKey,
@"src_text" : text,
@"from" : souceLangCode,
@"to" : targetLangCode,
@"source" : @"Easydict"
};

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer=[AFJSONResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html", @"text/plain", nil];
manager.session.configuration.timeoutIntervalForRequest = EZNetWorkTimeoutInterval;
NSURLSessionTask *task = [manager POST:url parameters:params progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {
EZNiuTransTranslateResponse *niuTransTranslateResult = [EZNiuTransTranslateResponse mj_objectWithKeyValues:responseObject];
NSString *translatedText = niuTransTranslateResult.tgtText;
// When translated text has multiple paragraphs, it will have an extra line break at the end, which we need to remove.
translatedText = [translatedText stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];

if (translatedText) {
self.result.translatedResults = [translatedText toParagraphs];
self.result.raw = responseObject;
completion(self.result, nil);
} else {
NSString *errorCode = niuTransTranslateResult.errorCode;
NSString *errorMsg = niuTransTranslateResult.errorMsg;
if (errorCode.length) {
NSString *message = errorCode;
if (errorMsg) {
message = [NSString stringWithFormat:@"%@, %@", errorCode, errorMsg];
}
NSError *error = [EZTranslateError errorWithType:EZErrorTypeAPI
message:message
request:task.currentRequest];
completion(self.result, error);
}
}
} failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {
if ([self.queryModel isServiceStopped:self.serviceType]) {
return;
}

if (error.code == NSURLErrorCancelled) {
return;
}

NSLog(@"NiuTransTranslate error: %@", error);

completion(self.result, error);
}];

[self.queryModel setStopBlock:^{
[task cancel];
} serviceType:self.serviceType];
}

@end
Loading

0 comments on commit 53bca6d

Please sign in to comment.