root/trunk/SapphireFrappliance/SapphireTVShowImporter.m

Revision 705, 23.0 kB (checked in by gbooker, 1 month ago)

The other half of [703]

Line 
1 /*
2  * SapphireTVShowImporter.m
3  * Sapphire
4  *
5  * Created by Graham Booker on Jun. 30, 2007.
6  * Copyright 2007 Sapphire Development Team and/or www.nanopi.net
7  * All rights reserved.
8  *
9  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10  * General Public License as published by the Free Software Foundation; either version 3 of the License,
11  * or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
14  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15  * Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along with this program; if not,
18  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  */
20
21 #import "SapphireTVShowImporter.h"
22 #import "SapphireMetaData.h"
23 #import "NSString-Extensions.h"
24 #import "NSFileManager-Extensions.h"
25 #import "SapphireShowChooser.h"
26 #import "SapphireMovieChooser.h"
27
28 /* TVRage XPATHS  */
29 #define TVRAGE_SHOWNAME_XPATH @".//font[@size=2][@color=\"white\"]/b/text()"
30 #define TVRAGE_EPLIST_XPATH @"//*[@class='b']"
31 #define TVRAGE_EP_INFO @".//*[@class='b2']/*"
32 #define TVRAGE_EP_TEXT @".//*[@class='b2']/text()"
33 #define TVRAGE_SCREEN_CAP_XPATH @".//img[contains(@src, 'screencap')]"
34 #define TVRAGE_SEARCH_XPATH @"//*[@class='b1']/a"
35 #define TVRAGE_UNKNOWN_XPATH @"//*[contains(text(), 'Unknown Page')]"
36
37 #define TRANSLATIONS_KEY                @"Translations"
38 #define LINK_KEY                                @"Link"
39 #define IMG_URL                                 @"imgURL"
40
41 /*Delegate class to download cover art*/
42 @interface SapphireTVShowDataMenuDownloadDelegate : NSObject
43 {
44         NSString *destination;
45 }
46 - (id)initWithDest:(NSString *)dest;
47 @end
48
49 @implementation SapphireTVShowDataMenuDownloadDelegate
50 /*!
51  * @brief Initialize a cover art downloader
52  *
53  * @param dest The path to save the file
54  */
55 - (id)initWithDest:(NSString *)dest
56 {
57         self = [super init];
58         if(!self)
59                 return nil;
60        
61         destination = [dest retain];
62        
63         return self;
64 }
65
66 - (void)dealloc
67 {
68         [destination release];
69         [super dealloc];
70 }
71
72 /*!
73  * @brief Delegate Method which prompts for location to save file.  Override and set new
74  * destination
75  *
76  * @param download The downloader
77  * @param filename The suggested filename
78  */
79 - (void)download:(NSURLDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename
80 {
81         [download setDestination:destination allowOverwrite:YES];
82 }
83 @end
84  
85 @interface SapphireTVShowImporter (private)
86 - (void)writeSettings;
87 @end
88
89 @implementation SapphireTVShowImporter
90
91 - (id) initWithSavedSetting:(NSString *)path
92 {
93         self = [super init];
94         if(!self)
95                 return nil;
96        
97         /*Get the settings*/
98         settingsPath = [path retain];
99         NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:path];
100         /*Get or create the show translation dict*/
101         showTranslations = [[settings objectForKey:TRANSLATIONS_KEY] mutableCopy];
102         if(showTranslations == nil)
103                 showTranslations = [NSMutableDictionary new];
104         /*Cached show info*/
105         showInfo = [NSMutableDictionary new];
106        
107         /*Initialize the regexes*/
108         regcomp(&letterMarking, "[\\. -]?S[0-9]+E[S0-9]+(-E?[0-9]+)?", REG_EXTENDED | REG_ICASE);
109         regcomp(&seasonByEpisode, "[\\. -]?[0-9]+x[S0-9]+(-[0-9]+)?", REG_EXTENDED | REG_ICASE);
110         regcomp(&seasonEpisodeTriple, "[\\. -][0-9]{1,3}[S0-9]{2}[\\. -]", REG_EXTENDED | REG_ICASE);   
111         return self;
112 }
113
114 - (void)dealloc
115 {
116         [showTranslations release];
117         [showInfo release];
118         [settingsPath release];
119         regfree(&letterMarking);
120         regfree(&seasonByEpisode);
121         regfree(&seasonEpisodeTriple);
122         [chooser release];
123         [super dealloc];
124 }
125
126 - (void)setImporterDataMenu:(SapphireImporterDataMenu *)theDataMenu
127 {
128         dataMenu = theDataMenu;
129 }
130
131 /*!
132  * @brief Add an episode's info into our cache dict
133  *
134  * @param showName The TV Show's name
135  * @param epTitle The episode's title
136  * @param season The episode's season
137  * @param ep The episodes's episode number within the season
138  * @param summary The episodes's summary
139  * @param eplink The episode's info URL
140  * @param epNumber The absolute episode number
141  * @param airDate The episode's air date
142  * @param imgURL The episode's screenshot URL
143  * @param dict The cache dictionary
144  */
145 - (void)addEp:(NSString *)showName title:(NSString *)epTitle season:(int)season epNum:(int)ep summary:(NSString *)summary link:(NSString *)epLink absEpNum:(int)epNumber airDate:(NSDate *)airDate showID:(NSString *)showID imgURL:(NSString *)imgURL toDict:(NSMutableDictionary *)dict
146 {
147         /*Set the key by which to store this.  Either by season/ep or season/title*/
148         NSNumber *epNum = [NSNumber numberWithInt:ep];
149         id key = epNum;
150         if(ep == 0)
151                 key = [epTitle lowercaseString];
152        
153         /*Get the ep dict*/
154         NSNumber *seasonNum = [NSNumber numberWithInt:season];
155         NSMutableDictionary *epDict = [dict objectForKey:key];
156         if(epDict == nil)
157         {
158                 epDict = [NSMutableDictionary new];
159                 [dict setObject:epDict forKey:key];
160                 [epDict release];
161         }
162         /*Add info*/
163         if(showName)
164         {
165                 [epDict setObject:showName forKey:META_SHOW_NAME_KEY] ;
166         }
167         if(ep != 0)
168                 [epDict setObject:epNum forKey:META_EPISODE_NUMBER_KEY];
169         if(season != 0)
170         {
171                 [epDict setObject:seasonNum forKey:META_SEASON_NUMBER_KEY];
172         }
173         if(epTitle != nil)
174                 [epDict setObject:epTitle forKey:META_TITLE_KEY];
175         if(epLink != nil)
176                 [epDict setObject:epLink forKey:LINK_KEY];
177         if(showID != nil)
178                 [epDict setObject:showID forKey:META_SHOW_IDENTIFIER_KEY];
179         if(summary != nil)
180                 [epDict setObject:summary forKey:META_DESCRIPTION_KEY];
181         if(epNumber != nil)
182                 [epDict setObject:[NSNumber numberWithInt:epNumber] forKey:META_ABSOLUTE_EP_NUMBER_KEY];
183         if(airDate != nil)
184                 [epDict setObject:airDate forKey:META_SHOW_AIR_DATE];
185         if(imgURL != nil)
186                 [epDict setObject:imgURL forKey:IMG_URL];
187 }
188
189 /*!
190  * @brief Fetch information about a season of a show
191  *
192  * @param seriesName The tvrage series name (part of the show's URL)
193  * @param season The season to fech
194  * @return A cached dictionary of the season's episodes
195  */
196 - (NSMutableDictionary *)getMetaForSeries:(NSString *)seriesName inSeason:(int)season
197 {
198         NSMutableDictionary *ret = [NSMutableDictionary dictionary];
199         NSCharacterSet *decimalSet = [NSCharacterSet decimalDigitCharacterSet];
200         /*Get the season's html*/
201         NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://www.tvrage.com%@/episode_guide/%d", seriesName, season]];
202         NSError *error = nil;
203         NSXMLDocument *document = [[NSXMLDocument alloc] initWithContentsOfURL:url options:NSXMLDocumentTidyHTML error:&error];
204         /* Dump XML document to disk (Dev Only) */
205 /*      NSString *documentPath =[NSHomeDirectory() stringByAppendingPathComponent:@"Library/Application Support/Sapphire/XML"];
206         [[document XMLDataWithOptions:NSXMLNodePrettyPrint] writeToFile:[NSString stringWithFormat:@"/%@%@.xml",documentPath,seriesName] atomically:YES] ;*/
207         /*Get the episode list*/
208         NSString *showName= nil;
209        
210        
211         NSXMLElement *html = [document rootElement];
212        
213         NSArray *titleArray=[html objectsForXQuery:TVRAGE_SHOWNAME_XPATH error:&error];
214         if([titleArray count])
215         {
216                 showName=[[titleArray objectAtIndex:0] stringValue];
217                 int length = [showName length];
218                 if([showName characterAtIndex:length - 1] == '\n')
219                         showName = [showName substringToIndex:length - 1];
220 /*              int index = [showName rangeOfString:@"Season" options:0].location;
221                 if(index != NSNotFound)
222                         showName = [showName substringToIndex:index - 1];*/
223         }
224
225         NSArray *eps = [html objectsForXQuery:TVRAGE_EPLIST_XPATH error:&error];
226         NSEnumerator *epEnum = [eps objectEnumerator];
227         NSXMLNode *epNode = nil;
228         while((epNode = [epEnum nextObject]) != nil)
229         {
230                 /*Parse the episode's info*/
231                 NSString *epTitle = nil;
232                 NSString *link = nil;
233                 int seasonNum = 0;
234                 int ep = 0;
235                 int epNumber = 0;
236                 NSMutableString *summary = nil;
237                 NSDate *airDate = nil;
238                 NSString *imageURL = nil;
239                
240                 /*Get the info pieces*/
241                 NSArray *epInfos = [epNode objectsForXQuery:TVRAGE_EP_INFO error:&error];
242                 NSEnumerator *epInfoEnum = [epInfos objectEnumerator];
243                 NSXMLNode *epInfo = nil;
244                 while((epInfo = [epInfoEnum nextObject]) != nil)
245                 {
246                         NSString *nodeName = [epInfo name];
247                         NSArray *summaryObjects = [epInfo objectsForXQuery:@".//font" error:&error];
248                         if([summaryObjects count] && ![nodeName isEqualToString:@"font"])
249                         {
250                                 /*Sometimes, the summary is inside formatting, strip*/
251                                 epInfo = [summaryObjects objectAtIndex:0];
252                                 nodeName = [epInfo name];
253                         }
254                         if(link == nil && [nodeName isEqualToString:@"a"])
255                         {
256                                 /*Get the URL*/
257                                 link = [[(NSXMLElement *)epInfo attributeForName:@"href"] stringValue];
258                                 link = [NSString stringWithFormat:@"http://www.tvrage.com%@", link];
259                                 /*Parse the name*/
260                                 NSString *epInfoStr = [[epInfo childAtIndex:0] stringValue];
261                                 if(epInfoStr != nil)
262                                 {
263                                         /*Get the season number and ep numbers*/
264                                         NSScanner *scanner = [NSScanner scannerWithString:epInfoStr];
265                                         NSRange range = [epInfoStr rangeOfString:@" - " options:0];
266                                         if(range.location != NSNotFound)
267                                         {
268                                                 [scanner scanInt:&epNumber];
269                                                 [scanner scanUpToCharactersFromSet:decimalSet intoString:nil];
270                                                 [scanner scanInt:&seasonNum];
271                                                 [scanner scanUpToCharactersFromSet:decimalSet intoString:nil];
272                                                 [scanner scanInt:&ep];
273                                                 [scanner setScanLocation:range.length + range.location];
274                                                 if(seasonNum == 0)
275                                                         seasonNum = season;
276                                         }
277                                         else
278                                                 seasonNum = season;
279                                         epTitle = [epInfoStr substringFromIndex:[scanner scanLocation]];
280                                 }
281                         }
282                         else if(summary == nil && [nodeName isEqualToString:@"font"])
283                         {
284                                 /*Get the summary*/
285                                 NSArray *summaries = [epInfo objectsForXQuery:@"replace(string(), '\n\n', '\n')" error:&error];
286                                 summary = [NSMutableString string];
287                                 NSEnumerator *sumEnum = [summaries objectEnumerator];
288                                 NSXMLNode *sum = nil;
289                                 while((sum = [sumEnum nextObject]) != nil)
290                                         [summary appendFormat:@"\n%@", sum];
291                                 if([summary length] > 3 && [[summary substringFromIndex:3] isEqualToString:@"No Summary (Add Here)"])
292                                         summary = nil;
293                                 if([summary length])
294                                         [summary deleteCharactersInRange:NSMakeRange(0,1)];
295                                 else
296                                         summary = nil;
297                         }
298                         else if(imageURL == nil)
299                         {
300                                 NSArray *images = [epInfo objectsForXQuery:TVRAGE_SCREEN_CAP_XPATH error:&error];
301                                 if([images count])
302                                 {
303                                         imageURL = [[(NSXMLElement *)[images objectAtIndex:0] attributeForName:@"src"] stringValue];
304                                 }
305                         }
306                 }
307                 epInfos = [epNode objectsForXQuery:TVRAGE_EP_TEXT error:&error];
308                 epInfoEnum = [epInfos objectEnumerator];
309                 epInfo = nil;
310                 while((epInfo = [epInfoEnum nextObject]) != nil)
311                 {
312                         /*Get the air date*/
313                         NSString *nodeName = [epInfo stringValue];
314                         if ([nodeName hasPrefix:@" ("] && [nodeName hasSuffix:@") "])
315                         {
316                                 NSString *subStr = [nodeName substringWithRange:NSMakeRange(2, [nodeName length] - 4)];
317                                
318                                 airDate = [NSDate dateWithNaturalLanguageString:subStr];
319                                 if([airDate timeIntervalSince1970] == 0)
320                                         airDate = nil;
321                                 else
322                                         break;
323                         }
324                 }
325                 /*Add to cache*/
326                 [self addEp:showName title:epTitle season:seasonNum epNum:ep summary:summary link:link absEpNum:epNumber airDate:airDate showID:seriesName imgURL:imageURL toDict:ret];
327         }
328         return ret;
329 }
330
331 /*!
332  * @brief Searches for a show based on the filename
333  *
334  * @param searchStr Part of the filename to use in the show search
335  * @return An array of possible results
336  */
337 - (NSArray *)searchResultsForSeries:(NSString *)searchStr
338 {
339         /*Load the search info*/
340         NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://www.tvrage.com/search.php?search=%@&sonly=1", [searchStr URLEncode]]];
341         NSError *error = nil;
342         NSXMLDocument *document = [[NSXMLDocument alloc] initWithContentsOfURL:url options:NSXMLDocumentTidyHTML error:&error];
343        
344         /*Get the results list*/
345         NSXMLElement *root = [document rootElement];
346         NSArray *results = [root objectsForXQuery:TVRAGE_SEARCH_XPATH error:&error];
347         NSMutableArray *ret = [NSMutableArray arrayWithCapacity:[results count]];
348         if([results count])
349         {
350                 /*Get each result*/
351                 NSEnumerator *resultEnum = [results objectEnumerator];
352                 NSXMLElement *result = nil;
353                 while((result = [resultEnum nextObject]) != nil)
354                 {
355                         /*Add the result to the list*/
356                         NSURL *resultURL = [NSURL URLWithString:[[result attributeForName:@"href"] stringValue]];
357                         if(resultURL == nil)
358                                 continue;
359                         [ret addObject:[NSDictionary dictionaryWithObjectsAndKeys:
360                                 [[result childAtIndex:0] stringValue], @"name",
361                                 [resultURL path], @"link",
362                                 nil]];
363                 }
364                 return ret;
365         }
366         /*No results found*/
367         return nil;
368 }
369
370 /*!
371  * @brief Fetch cached information about a show's season, and if none, fetch it
372  *
373  * @param show The tvrage series name
374  * @param season The season to fetch
375  * @return A dictionary with info about the season
376  */
377 - (NSMutableDictionary *)getInfo:(NSString *)show forSeason:(int)season
378 {
379         /*Get the show's info*/
380         NSMutableDictionary *showDict = [showInfo objectForKey:show];
381         NSMutableDictionary *seasonDict = nil;
382         NSNumber *seasonNum = [NSNumber numberWithInt:season];
383         if(!showDict)
384         {
385                 showDict = [NSMutableDictionary new];
386                 [showInfo setObject:showDict forKey:show];
387                 [showDict release];
388         }
389         else
390                 /*Get the season's info*/
391                 seasonDict = [showDict objectForKey:seasonNum];
392         if(!seasonDict)
393         {
394                 /*Not in cache, so fetch it*/
395                 seasonDict = [self getMetaForSeries:show inSeason:season];
396                 if(seasonDict != nil)
397                         /*Put the result in cache*/
398                         [showDict setObject:seasonDict forKey:seasonNum];
399         }
400         /*Return the info*/
401         return seasonDict;
402 }
403
404 /*!
405  * @brief Get info about a show's episode
406  *
407  * @param show The tvrage show name
408  * @param season The episode's season
409  * @param ep The episode's episode number
410  * @return The episode's info
411  */
412 - (NSMutableDictionary *)getInfo:(NSString *)show forSeason:(int)season episode:(int)ep
413 {
414         NSNumber *epNum = [NSNumber numberWithInt:ep];
415         return [NSMutableDictionary dictionaryWithDictionary:[[self getInfo:show forSeason:season] objectForKey:epNum]];
416 }
417
418 /*!
419  * @brief Get info about a show's episode which doesn't have an episode number (specials)
420  *
421  * @param show The tvrage show name
422  * @param season The episode's season
423  * @param epTitle The episode's title
424  * @return The episode's info
425  */
426 - (NSMutableDictionary *)getInfo:(NSString *)show forSeason:(int)season episodeTitle:(NSString *)epTitle
427 {
428         return [NSMutableDictionary dictionaryWithDictionary:[[self getInfo:show forSeason:season] objectForKey:[epTitle lowercaseString]]];
429 }
430
431 /*!
432  * @brief Write our setings out
433  */
434 - (void)writeSettings
435 {
436         NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
437                 showTranslations, TRANSLATIONS_KEY,
438                 nil];
439         [settings writeToFile:settingsPath atomically:YES];
440 }
441
442 - (void)combine:(NSMutableDictionary *)info with:(NSMutableDictionary *)info2
443 {
444         NSMutableDictionary *tdict = [info2 mutableCopy];
445         [tdict addEntriesFromDictionary:info];
446         NSString *secname = [info2 objectForKey:META_TITLE_KEY];
447         NSString *origname = [info objectForKey:META_TITLE_KEY];
448         if(secname != nil && origname != nil)
449                 [tdict setObject:[NSString stringWithFormat:@"%@ / %@", origname, secname] forKey:META_TITLE_KEY];
450
451         if([info objectForKey:META_EPISODE_NUMBER_KEY] != nil)
452         {
453                 NSNumber *secondEp = [info2 objectForKey:META_EPISODE_NUMBER_KEY];
454                 [tdict setObject:secondEp forKey:META_EPISODE_2_NUMBER_KEY];
455         }
456         NSString *secdesc = [info2 objectForKey:META_DESCRIPTION_KEY];
457         NSString *origdesc = [info objectForKey:META_DESCRIPTION_KEY];
458         if(secdesc != nil && origdesc != nil)
459                 [tdict setObject:[NSString stringWithFormat:@"%@ / %@", origdesc, secdesc] forKey:META_DESCRIPTION_KEY];
460
461         if([info objectForKey:META_ABSOLUTE_EP_NUMBER_KEY] != nil)
462         {
463                 NSNumber *secondEp = [info2 objectForKey:META_ABSOLUTE_EP_NUMBER_KEY];
464                 [tdict setObject:secondEp forKey:META_ABSOLUTE_EP_2_NUMBER_KEY];
465         }
466        
467         [info addEntriesFromDictionary:tdict];
468         [tdict release];
469 }
470
471 - (ImportState) importMetaData:(id <SapphireFileMetaDataProtocol>)metaData
472 {
473         currentData = metaData;
474         /*Check to see if it is already imported*/
475         if([metaData importedTimeFromSource:META_TVRAGE_IMPORT_KEY])
476                 return IMPORT_STATE_NOT_UPDATED;
477         id controller = [[dataMenu stack] peekController];
478         /* Check to see if we are waiting on the user to select a movie title */
479         if(![controller isKindOfClass:[SapphireImporterDataMenu class]])
480         {
481                 /* Another chooser is on the screen - delay further processing */
482                 return IMPORT_STATE_NOT_UPDATED;
483         }
484         /*Get path*/
485         NSString *path = [metaData path];
486 //      NSArray *pathComponents = [path pathComponents];
487         NSString *fileName = [path lastPathComponent];
488        
489         /*Check regexes to see if this is a tv show*/
490         int index = NSNotFound;
491         int secondEp = -1;
492         regmatch_t matches[3];
493         NSData *fileNameData = [fileName dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
494         const char *theFileName = [fileNameData bytes];
495         NSString *scanString = nil;
496         if(!regexec(&letterMarking, theFileName, 3, matches, 0))
497         {
498                 index = matches[0].rm_so;
499                 scanString = [fileName substringFromIndex:index];
500                 secondEp = matches[1].rm_so;
501         }
502         else if(!regexec(&seasonByEpisode, theFileName, 3, matches, 0))
503         {
504                 index = matches[0].rm_so;
505                 scanString = [fileName substringFromIndex:index];
506                 secondEp = matches[1].rm_so;
507         }
508         else if(!regexec(&seasonEpisodeTriple, theFileName, 3, matches, 0))
509         {
510                 index = matches[0].rm_so;
511                 /*Insert an artificial season/ep seperator so things are easier later*/
512                 NSMutableString *tempStr = [fileName mutableCopy];
513 //              if(index > [tempStr length] || index <= 0 )return NO;
514                 [tempStr deleteCharactersInRange:NSMakeRange(0, index+1)];
515                 [tempStr insertString:@"x" atIndex:matches[0].rm_eo - index - 4];
516                 scanString = [tempStr autorelease];
517         }
518        
519         /*See if we found a match*/
520         if(index == NSNotFound)
521                 return IMPORT_STATE_NOT_UPDATED;
522        
523         /*Get the show title*/
524         NSString *searchStr = [fileName substringToIndex:index];
525         /*Check to see if we know this title*/
526         NSString *show = [showTranslations objectForKey:[searchStr lowercaseString]];
527         if(show == nil)
528         {
529                 if(dataMenu == nil)
530                         /*There is no data menu, background import. So we can't ask user, skip*/
531                         return IMPORT_STATE_NOT_UPDATED;
532                 /*Ask the user what show this is*/
533                 NSArray *shows = [self searchResultsForSeries:searchStr];
534                 /*Bring up the prompt*/
535                 chooser = [[SapphireShowChooser alloc] initWithScene:[dataMenu scene]];
536                 [chooser setShows:shows];
537                 [chooser setFileName:fileName];
538                 [chooser setListTitle:BRLocalizedString(@"Select Show Title", @"Prompt the user for showname with a file")];
539                 [chooser setSearchStr:searchStr];
540                 /*And display prompt*/
541                 [[dataMenu stack] pushController:chooser];
542                 return IMPORT_STATE_NEEDS_SUSPEND;
543         }
544        
545         int season = 0;
546         int ep = 0;
547         /*Get the season*/
548         NSScanner *scanner = [NSScanner scannerWithString:scanString];
549         NSCharacterSet *digits = [NSCharacterSet decimalDigitCharacterSet];
550         [scanner scanUpToCharactersFromSet:digits intoString:nil];
551         [scanner scanInt:&season];
552         /*Get the episode number*/
553         NSString *skipped = nil;
554         [scanner scanUpToCharactersFromSet:digits intoString:&skipped];
555         [scanner scanInt:&ep];
556         /*Was there an S before the episode number?*/
557         if([skipped hasSuffix:@"S"])
558                 ep = 0;
559        
560         int overriddenSeason = [metaData overriddenSeasonNumber];
561         if(overriddenSeason != -1)
562                 season = overriddenSeason;
563
564         int overriddenEpisode = [metaData overriddenEpisodeNumber];
565         if(overriddenEpisode != -1)
566                 ep = overriddenEpisode;
567
568         /*No season, no info*/
569         if(season == 0)
570                 return IMPORT_STATE_NOT_UPDATED;
571        
572         int otherEp = 0;
573         if(secondEp != -1)
574         {
575                 [scanner setScanLocation:secondEp - index];
576                 [scanner scanUpToCharactersFromSet:digits intoString:nil];
577                 [scanner scanInt:&otherEp];
578         }
579        
580         overriddenEpisode = [metaData overriddenSecondEpisodeNumber];
581         if(overriddenEpisode != -1)
582                 otherEp = overriddenEpisode;
583
584         /*Get the episode's info*/
585         NSMutableDictionary *info = nil, *info2 = nil;
586         if(ep != 0)
587         {
588                 /*Match on s/e*/
589                 info = [self getInfo:show forSeason:season episode:ep];
590                 if(otherEp != 0)
591                         info2 = [self getInfo:show forSeason:season episode:otherEp];
592         }
593         else
594         {
595                 /*Match on show title*/
596                 NSString *showTitle = nil;
597                 [scanner scanUpToCharactersFromSet:[NSCharacterSet alphanumericCharacterSet] intoString:nil];
598                 if([scanner scanUpToString:@"." intoString:&showTitle])
599                         info = [self getInfo:show forSeason:season episodeTitle:showTitle];
600         }
601         /*No info, well, no info*/
602         if(!info)
603                 return IMPORT_STATE_NOT_UPDATED;
604                
605         /* Lets process the cover art directory structure */
606         NSString * previewArtPath=[NSString stringWithFormat:@"%@/@TV/%@/%@",
607                                                                         [SapphireMetaData collectionArtPath],
608                                                                         [info objectForKey:META_SHOW_NAME_KEY],
609                                                                         [NSString stringWithFormat:@"Season %d",[[info objectForKey:META_SEASON_NUMBER_KEY] intValue]]];
610                                                
611         [[NSFileManager defaultManager] constructPath:previewArtPath];
612         /*Check for screen cap locally and on server*/
613         NSString *imgURL = [info objectForKey:IMG_URL];
614         NSString *newPath = [previewArtPath stringByAppendingPathComponent:fileName];
615         if( [metaData fileContainerType] != FILE_CONTAINER_TYPE_VIDEO_TS )
616                 newPath = [newPath stringByDeletingPathExtension];
617        
618         NSString *imageDestination = [newPath stringByAppendingPathExtension:@"jpg"];
619         BOOL isDir = NO;
620         BOOL imageExists = [[NSFileManager defaultManager] fileExistsAtPath:imageDestination isDirectory:&isDir] && !isDir;
621         if(imgURL && !imageExists)
622         {
623                 /*Download the screen cap*/
624                 NSURL *imageURL = [NSURL URLWithString:imgURL];
625                 NSURLRequest *request = [NSURLRequest requestWithURL:imageURL];
626                 SapphireTVShowDataMenuDownloadDelegate *myDelegate = [[SapphireTVShowDataMenuDownloadDelegate alloc] initWithDest:imageDestination];
627                 [[NSURLDownload alloc] initWithRequest:request delegate:myDelegate];
628                 [myDelegate release];
629         }
630        
631         if(info2 != nil)
632                 [self combine:info with:info2];
633         /*Import the info*/
634         [info removeObjectForKey:LINK_KEY];
635         [metaData importInfo:info fromSource:META_TVRAGE_IMPORT_KEY withTime:[[NSDate date] timeIntervalSince1970]];
636         [metaData setFileClass:FILE_CLASS_TV_SHOW];
637        
638         /*We imported something*/
639         return IMPORT_STATE_UPDATED;
640 }
641
642 - (NSString *)completionText
643 {
644         return BRLocalizedString(@"All availble TV Show data has been imported", @"The TV Show import complete");
645 }
646
647 - (NSString *)initialText
648 {
649         return BRLocalizedString(@"Fetch TV Show Data", @"Title");
650 }
651
652 - (NSString *)informativeText
653 {
654         return BRLocalizedString(@"This tool will attempt to fetch information about your TV shows files from the Internet (TVRage).  This procedure may take quite some time and could ask you questions.  You may cancel at any time.", @"Description of the movie import");
655 }
656
657 - (NSString *)buttonTitle
658 {
659         return BRLocalizedString(@"Start Fetching Data", @"Button");
660 }
661
662 - (void) wasExhumed
663 {
664         /*See if it was a show chooser*/
665         if(chooser == nil)
666                 return;
667        
668         /*Get the user's selection*/
669         int selection = [chooser selection];
670         if(selection == SHOW_CHOOSE_CANCEL)
671                 /*They aborted, skip*/
672                 [dataMenu skipNextItem];
673         else if(selection == SHOW_CHOOSE_NOT_SHOW)
674         {
675                 /*They said it is not a show, so put in empty data so they are not asked again*/
676                 [currentData importInfo:[NSMutableDictionary dictionary] fromSource:META_TVRAGE_IMPORT_KEY withTime:[[NSDate date] timeIntervalSince1970]];
677                 if ([currentData fileClass] == FILE_CLASS_TV_SHOW)
678                         [currentData setFileClass:FILE_CLASS_UNKNOWN];
679         }
680         else
681         {
682                 /*They selected a show, save the translation and write it*/
683                 NSDictionary *show = [[chooser shows] objectAtIndex:selection];
684                 [showTranslations setObject:[show objectForKey:@"link"] forKey:[[chooser searchStr] lowercaseString]];
685                 [self writeSettings];
686         }
687         [chooser release];
688         chooser = nil;
689         /*We can resume now*/
690         [dataMenu resume];
691 }
692
693 @end
Note: See TracBrowser for help on using the browser.