source: trunk/macosx/BlocklistDownloader.m @ 13219

Last change on this file since 13219 was 13219, checked in by livings124, 10 years ago

replace NSAutoreleasePool objects with @autoreleasepool blocks

  • Property svn:keywords set to Date Rev Author Id
File size: 8.8 KB
Line 
1/******************************************************************************
2 * $Id: BlocklistDownloader.m 13219 2012-02-11 05:13:46Z livings124 $
3 *
4 * Copyright (c) 2008-2012 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#import "BlocklistDownloader.h"
26#import "BlocklistDownloaderViewController.h"
27#import "BlocklistScheduler.h"
28#import "PrefsController.h"
29
30@interface BlocklistDownloader (Private)
31
32- (void) startDownload;
33- (void) decompressBlocklist;
34- (void) finishDownloadSuccess;
35
36@end
37
38@implementation BlocklistDownloader
39
40BlocklistDownloader * fDownloader = nil;
41+ (BlocklistDownloader *) downloader
42{
43    if (!fDownloader)
44    {
45        fDownloader = [[BlocklistDownloader alloc] init];
46        [fDownloader startDownload];
47    }
48   
49    return fDownloader;
50}
51
52+ (BOOL) isRunning
53{
54    return fDownloader != nil;
55}
56
57- (void) setViewController: (BlocklistDownloaderViewController *) viewController
58{
59    fViewController = viewController;
60    if (fViewController)
61    {
62        switch (fState)
63        {
64            case BLOCKLIST_DL_START:
65                [fViewController setStatusStarting];
66                break;
67            case BLOCKLIST_DL_DOWNLOADING:
68                [fViewController setStatusProgressForCurrentSize: fCurrentSize expectedSize: fExpectedSize];
69                break;
70            case BLOCKLIST_DL_PROCESSING:
71                [fViewController setStatusProcessing];
72                break;
73        }
74    }
75}
76
77- (void) dealloc
78{
79    [fDownload release];
80    [fDestination release];
81    [super dealloc];
82}
83
84- (void) cancelDownload
85{
86    [fViewController setFinished];
87   
88    [fDownload cancel];
89   
90    [[BlocklistScheduler scheduler] updateSchedule];
91   
92    fDownloader = nil;
93    [self release];
94}
95
96//using the actual filename is the best bet
97- (void) download: (NSURLDownload *) download decideDestinationWithSuggestedFilename: (NSString *) filename
98{
99    [fDownload setDestination: [NSTemporaryDirectory() stringByAppendingPathComponent: filename] allowOverwrite: NO];
100}
101
102- (void) download: (NSURLDownload *) download didCreateDestination: (NSString *) path
103{
104    [fDestination release];
105    fDestination = [path retain];
106}
107
108- (void) download: (NSURLDownload *) download didReceiveResponse: (NSURLResponse *) response
109{
110    fState = BLOCKLIST_DL_DOWNLOADING;
111   
112    fCurrentSize = 0;
113    fExpectedSize = [response expectedContentLength];
114   
115    [fViewController setStatusProgressForCurrentSize: fCurrentSize expectedSize: fExpectedSize];
116}
117
118- (void) download: (NSURLDownload *) download didReceiveDataOfLength: (NSUInteger) length
119{
120    fCurrentSize += length;
121    [fViewController setStatusProgressForCurrentSize: fCurrentSize expectedSize: fExpectedSize];
122}
123
124- (void) download: (NSURLDownload *) download didFailWithError: (NSError *) error
125{
126    [fViewController setFailed: [error localizedDescription]];
127   
128    [[NSUserDefaults standardUserDefaults] setObject: [NSDate date] forKey: @"BlocklistNewLastUpdate"];
129    [[BlocklistScheduler scheduler] updateSchedule];
130   
131    fDownloader = nil;
132    [self release];
133}
134
135- (void) downloadDidFinish: (NSURLDownload *) download
136{
137    fState = BLOCKLIST_DL_PROCESSING;
138    [self performSelectorInBackground: @selector(finishDownloadSuccess) withObject: nil];
139}
140
141- (BOOL) download: (NSURLDownload *) download shouldDecodeSourceDataOfMIMEType: (NSString *) encodingType
142{
143    return YES;
144}
145
146@end
147
148@implementation BlocklistDownloader (Private)
149
150- (void) startDownload
151{
152    fState = BLOCKLIST_DL_START;
153   
154    [[BlocklistScheduler scheduler] cancelSchedule];
155   
156    NSString * urlString = [[NSUserDefaults standardUserDefaults] stringForKey: @"BlocklistURL"];
157    if (!urlString)
158        urlString = @"";
159    else if (![urlString isEqualToString: @""] && [urlString rangeOfString: @"://"].location == NSNotFound)
160        urlString = [@"http://" stringByAppendingString: urlString];
161   
162    NSURLRequest * request = [NSURLRequest requestWithURL: [NSURL URLWithString: urlString]];
163   
164    fDownload = [[NSURLDownload alloc] initWithRequest: request delegate: self];
165}
166
167//.gz, .tar.gz, .tgz, and .bgz will be decompressed by NSURLDownload for us. However, we have to do .zip files manually.
168- (void) decompressBlocklist
169{
170        if ([[[fDestination pathExtension] lowercaseString] isEqualToString: @"zip"]) {
171                BOOL success = NO;
172       
173        NSString * workingDirectory = [fDestination stringByDeletingLastPathComponent];
174               
175                //First, perform the actual unzipping
176                NSTask  * unzip = [[NSTask alloc] init];
177                [unzip setLaunchPath: @"/usr/bin/unzip"];
178                [unzip setCurrentDirectoryPath: workingDirectory];
179                [unzip setArguments: [NSArray arrayWithObjects:
180                                @"-o",  /* overwrite */
181                                @"-q", /* quiet! */
182                                fDestination, /* source zip file */
183                                @"-d", workingDirectory, /*destination*/
184                                nil]];
185               
186                @try
187                {
188                        [unzip launch];
189                        [unzip waitUntilExit];
190                       
191                        if ([unzip terminationStatus] == 0)
192                                success = YES;
193                }
194                @catch(id exc)
195                {
196                        success = NO;
197                }
198                [unzip release];
199               
200                if (success) {
201                        //Now find out what file we actually extracted; don't just assume it matches the zipfile's name
202                        NSTask *zipinfo;
203                       
204                        zipinfo = [[NSTask alloc] init];
205                        [zipinfo setLaunchPath: @"/usr/bin/zipinfo"];
206                        [zipinfo setArguments: [NSArray arrayWithObjects:
207                                    @"-1",  /* just the filename */
208                                    fDestination, /* source zip file */
209                                    nil]];
210                        [zipinfo setStandardOutput: [NSPipe pipe]];
211                                               
212                        @try
213                        {
214                                NSFileHandle * zipinfoOutput = [[zipinfo standardOutput] fileHandleForReading];
215
216                                [zipinfo launch];
217                                [zipinfo waitUntilExit];
218                               
219                                NSString * actualFilename = [[[NSString alloc] initWithData: [zipinfoOutput readDataToEndOfFile]
220                                                encoding: NSUTF8StringEncoding] autorelease];
221                                actualFilename = [actualFilename stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
222                                NSString * newBlocklistPath = [workingDirectory stringByAppendingPathComponent: actualFilename];
223                               
224                                //Finally, delete the ZIP file; we're done with it, and we'll return the unzipped blocklist
225                                [[NSFileManager defaultManager] removeItemAtPath: fDestination error: NULL];
226               
227                [fDestination release];
228                fDestination = [newBlocklistPath retain];
229                        }
230            @catch(id exc) {}
231                        [zipinfo release];
232                }               
233        }
234}
235
236
237- (void) finishDownloadSuccess
238{
239    @autoreleasepool
240    {
241        [fViewController setStatusProcessing];
242       
243        //process data
244        NSAssert(fDestination != nil, @"the blocklist file destination has not been specified");
245       
246        [self decompressBlocklist];
247       
248        const int count = tr_blocklistSetContent([PrefsController handle], [fDestination UTF8String]);
249       
250        //delete downloaded file
251        [[NSFileManager defaultManager] removeItemAtPath: fDestination error: NULL];
252       
253        if (count > 0)
254            [fViewController setFinished];
255        else
256            [fViewController setFailed: NSLocalizedString(@"The specified blocklist file did not contain any valid rules.",
257                                            "blocklist fail message")];
258       
259        //update last updated date for schedule
260        NSDate * date = [NSDate date];
261        [[NSUserDefaults standardUserDefaults] setObject: date forKey: @"BlocklistNewLastUpdate"];
262        [[NSUserDefaults standardUserDefaults] setObject: date forKey: @"BlocklistNewLastUpdateSuccess"];
263        [[BlocklistScheduler scheduler] updateSchedule];
264       
265        [[NSNotificationCenter defaultCenter] postNotificationName: @"BlocklistUpdated" object: nil];
266    }
267   
268    fDownloader = nil;
269    [self release];
270}
271
272@end
Note: See TracBrowser for help on using the repository browser.