5 * Created by Alan Humpherys on Wed Mar 19 2003.
6 * Copyright (c) 2003. All rights reserved.
8 * Modernized and modified by Evan Schoenberg on Sun mar 12 2006.
9 * Some parts copyright (c) 2006. All rights reserved.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #import "TranslationEngine.h"
27 #import "AITranslatorPlugin.h"
28 #import "AITranslatorRequestDelegate.h"
30 @interface NSString (FireStringAdditions)
31 - (NSString *)URLEncodedStringUsingCFEncoding:(CFStringEncoding)encoding;
34 @implementation TranslationEngine
36 // Currently, the translation engine uses www.worldlingo.com to power the
37 // translations. If this ever becomes unavailable, it is possible to use:
38 // www.translations.com
39 // www.freetranslation.com
40 // babelfish.altavista.com
42 - (void)translate:(NSDictionary *)messageDict notifyingTarget:(id)target
44 NSString *POSTBody = nil;
45 NSString *inputString = nil;
48 NSString *encodedMsg = nil;
49 NSDictionary *translationEncodingDict = nil;
50 NSNumber *latinEncoding;
51 unsigned int srcEncoding;
53 inputString = [messageDict objectForKey:TC_MESSAGE_KEY];
54 from = [messageDict objectForKey:TC_FROM_KEY];
55 to = [messageDict objectForKey:TC_TO_KEY];
57 if (!inputString || !from || !to) {
58 TRANSLATION_ERROR(TE_BAD_PARMS);
62 // Normalize and Validate languages
63 if ([from isEqualToString:@"DefaultLanguage"]) {
64 // This shouldn't occur with proper localization
65 // Defaulting to English
68 if ([to isEqualToString:@"DefaultLanguage"]) {
69 // This shouldn't occur with proper localization
70 // Defaulting to English
74 // Match the cases used on their website
75 from = [from uppercaseString];
76 to = [to lowercaseString];
78 if ([[from lowercaseString] isEqualToString:to]) {
79 //No Translation needed
80 [target translatedString:inputString forMessageDict:messageDict];
85 latinEncoding = [NSNumber numberWithUnsignedInt:kCFStringEncodingISOLatin1];
87 // This is the list of encodings expected by the website
88 translationEncodingDict = [[NSDictionary alloc] initWithObjectsAndKeys:
96 [NSNumber numberWithUnsignedInt:kCFStringEncodingISOLatinGreek],@"el",
97 [NSNumber numberWithUnsignedInt:kCFStringEncodingDOSRussian], @"ru",
98 [NSNumber numberWithUnsignedInt:kCFStringEncodingShiftJIS], @"ja",
99 [NSNumber numberWithUnsignedInt:kCFStringEncodingEUC_CN], @"zh_cn",
100 [NSNumber numberWithUnsignedInt:kCFStringEncodingBig5], @"zh_tw",
101 [NSNumber numberWithUnsignedInt:kCFStringEncodingEUC_KR], @"ko",
104 // Change string to proper encoding and URLEncode it
105 srcEncoding = [(NSNumber *)[translationEncodingDict objectForKey:[from lowercaseString]] unsignedIntValue];
106 [translationEncodingDict release];
108 if (!CFStringIsEncodingAvailable(srcEncoding)) {
109 TRANSLATION_ERROR(TE_LANG_NOT_SUPPORTED);
113 encodedMsg = [inputString URLEncodedStringUsingCFEncoding:srcEncoding];
115 POSTBody = [NSString stringWithFormat:
116 @"wl_srclang=%@&wl_trglang=%@&wl_text=%@&wl_url=&wl_glossary=gl1&wl_documenttype=dt9",
121 NSMutableURLRequest *request;
123 request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.worldlingo.com/wl/translate"]
124 cachePolicy:NSURLRequestReloadIgnoringCacheData
125 timeoutInterval:120];
126 [request setHTTPMethod:@"POST"];
127 [request setHTTPBody:[POSTBody dataUsingEncoding:NSUTF8StringEncoding]];
128 [request addValue:@"www.worldlingo.com" forHTTPHeaderField:@"Host"];
129 [request addValue:@"http://www.worldlingo.com/products_services/worldlingo_translator.html" forHTTPHeaderField:@"Referer"];
130 [request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];
132 AITranslatorRequestDelegate *requestDelegate = [AITranslatorRequestDelegate translatorRequestDelegateForDict:messageDict
133 notifyingTarget:target];
134 [NSURLConnection connectionWithRequest:request delegate:requestDelegate];
139 @implementation NSString (FireStringAdditons)
140 + (NSString *)URLEncodingForCharacter:(const unsigned char)c
144 } else if (c == '\n') {
145 // Change linefeeds to the CR-LF pair expected
147 } else if (isalnum(c)) {
148 // Regular AlphaNumerics
149 return [NSString stringWithFormat:@"%c",c];
151 // Non-Printable, NULL, Non-ASCII, and other "dangerous" characters
152 return [NSString stringWithFormat:@"%%%02X",c];
156 - (NSString *)URLEncodedStringUsingCFEncoding:(CFStringEncoding)encoding {
157 NSMutableString *rValue = nil;
159 unsigned int dataLength;
161 unsigned char *dataBytes;
163 if ((encoding == kCFStringEncodingInvalidId) || !CFStringIsEncodingAvailable(encoding)) {
164 // Unknown encoding type
168 encodedData = (NSData *)CFStringCreateExternalRepresentation (NULL, (CFStringRef)self, encoding, '*');
169 [encodedData autorelease];
171 dataLength = [encodedData length];
172 dataBytes = (unsigned char *)[encodedData bytes];
173 rValue = [[[NSMutableString alloc] init] autorelease];
175 for(i=0;i < dataLength;i++) {
176 [rValue appendString:[NSString URLEncodingForCharacter:dataBytes[i]]];