Enable/disable the okay button based on the presence of text in the To: field for...
[adiumx.git] / Plugins / Translation / TranslationEngine.m
blob49692023fce5780916ea43787adf738de189a8a9
1 /*
2  * TranslationEngine.m
3  * Fire
4  *
5  * Created by Alan Humpherys on Wed Mar 19 2003.
6  * Copyright (c) 2003. All rights reserved.
7  *
8  * Modernized and modified by Evan Schoenberg on Sun mar 12 2006.
9  * Some parts copyright (c) 2006. All rights reserved.
10  *
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.
15  *
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.
20  *
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
24  */
26 #import "TranslationEngine.h"
27 #import "AITranslatorPlugin.h"
28 #import "AITranslatorRequestDelegate.h"
30 @interface NSString (FireStringAdditions)
31 - (NSString *)URLEncodedStringUsingCFEncoding:(CFStringEncoding)encoding;
32 @end
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
43 {   
44     NSString *POSTBody = nil;
45     NSString *inputString = nil;
46     NSString *from = nil;
47     NSString *to = nil;
48     NSString *encodedMsg = nil;
49     NSDictionary *translationEncodingDict = nil;
50     NSNumber *latinEncoding;
51     unsigned int srcEncoding;
52         
53     inputString = [messageDict objectForKey:TC_MESSAGE_KEY];
54     from = [messageDict objectForKey:TC_FROM_KEY];
55     to = [messageDict objectForKey:TC_TO_KEY];
56         
57     if (!inputString || !from || !to) {
58         TRANSLATION_ERROR(TE_BAD_PARMS);
59         return;
60     }
61     
62     // Normalize and Validate languages
63     if ([from isEqualToString:@"DefaultLanguage"]) {
64         // This shouldn't occur with proper localization
65         // Defaulting to English
66         from = @"en";
67     }
68     if ([to isEqualToString:@"DefaultLanguage"]) {
69         // This shouldn't occur with proper localization
70         // Defaulting to English
71         to = @"en";
72     }
73         
74     // Match the cases used on their website
75     from = [from uppercaseString];
76     to = [to lowercaseString];
77         
78     if ([[from lowercaseString] isEqualToString:to]) {
79         //No Translation needed
80                 [target translatedString:inputString forMessageDict:messageDict];
82         return;
83     }
84         
85     latinEncoding = [NSNumber numberWithUnsignedInt:kCFStringEncodingISOLatin1];
86         
87     // This is the list of encodings expected by the website
88     translationEncodingDict = [[NSDictionary alloc] initWithObjectsAndKeys:
89         latinEncoding,  @"en",
90         latinEncoding,  @"es",
91         latinEncoding,  @"fr",
92         latinEncoding,  @"de",
93         latinEncoding,  @"pt",
94         latinEncoding,  @"it",
95         latinEncoding,  @"nl",
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",
102         nil];
103         
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);
110         return;
111     }
112         
113         encodedMsg = [inputString URLEncodedStringUsingCFEncoding:srcEncoding];
115     POSTBody = [NSString stringWithFormat:
116         @"wl_srclang=%@&wl_trglang=%@&wl_text=%@&wl_url=&wl_glossary=gl1&wl_documenttype=dt9",
117         from,
118         to,
119         encodedMsg];
120         
121         NSMutableURLRequest *request;
122         
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];
137 @end
139 @implementation NSString (FireStringAdditons)
140 + (NSString *)URLEncodingForCharacter:(const unsigned char)c
142     if (c == ' ') {
143         return @"+";
144     } else if (c == '\n') {
145         // Change linefeeds to the CR-LF pair expected
146         return @"%0D%0A";
147     } else if (isalnum(c)) {
148         // Regular AlphaNumerics
149         return [NSString stringWithFormat:@"%c",c];
150     } else {
151         // Non-Printable, NULL, Non-ASCII, and other "dangerous" characters
152         return [NSString stringWithFormat:@"%%%02X",c];
153     }
156 - (NSString *)URLEncodedStringUsingCFEncoding:(CFStringEncoding)encoding {
157     NSMutableString *rValue = nil;
158     NSData *encodedData;
159     unsigned int dataLength;
160     unsigned int i;
161     unsigned char *dataBytes;
162         
163     if ((encoding == kCFStringEncodingInvalidId) || !CFStringIsEncodingAvailable(encoding)) {
164         // Unknown encoding type
165         return nil;
166     }
167         
168     encodedData = (NSData *)CFStringCreateExternalRepresentation (NULL, (CFStringRef)self, encoding, '*');
169     [encodedData autorelease];
170     
171     dataLength = [encodedData length];
172     dataBytes = (unsigned char *)[encodedData bytes];
173     rValue = [[[NSMutableString alloc] init] autorelease];
174         
175     for(i=0;i < dataLength;i++) {
176         [rValue appendString:[NSString URLEncodingForCharacter:dataBytes[i]]];
177     }
178         
179     return rValue;
182 @end