source: branches/CoreData/SapphireFrappliance/MetaData/SapphireMObjects/SapphireEpisode.m @ 734

Revision 734, 10.4 KB checked in by gbooker, 5 years ago (diff)

Switched the the next version of the metadata.
Fixes #264

Line 
1#import "SapphireEpisode.h"
2#import "SapphireSeason.h"
3#import "SapphireSubEpisode.h"
4#import "SapphireMediaPreview.h"
5#import "SapphireFileMetaData.h"
6#import "SapphireMetaDataSupport.h"
7#import "SapphireXMLEpisodeData.h"
8#import "SapphireXMLData.h"
9#import "SapphireApplianceController.h"
10#import "CoreDataSupportFunctions.h"
11
12@implementation SapphireEpisode
13
14+ (SapphireEpisode *)episode:(int)ep inSeason:(int)season forShow:(NSString *)show withPath:(NSString *)showPath inContext:(NSManagedObjectContext *)moc
15{
16        SapphireSeason *tvseason = [SapphireSeason season:season forShow:show withPath:showPath inContext:moc];
17        NSEnumerator *epEnum = [tvseason.episodesSet objectEnumerator];
18        SapphireEpisode *tvep;
19        while((tvep = [epEnum nextObject]) != nil)
20        {
21                if([SapphireSubEpisode subEpisode:ep inEpisode:tvep] != nil)
22                        return tvep;
23        }
24       
25        SapphireEpisode *ret = [NSEntityDescription insertNewObjectForEntityForName:SapphireEpisodeName inManagedObjectContext:moc];
26        ret.season = tvseason;
27        ret.tvShow = tvseason.tvShow;
28        [ret addSubEpisodesObject:[SapphireSubEpisode createSubEpisode:ep inEpisode:ret]];
29        return ret;
30}
31
32+ (SapphireEpisode *)episodeTitle:(NSString *)title inSeason:(int)season forShow:(NSString *)show withPath:(NSString *)showPath inContext:(NSManagedObjectContext *)moc
33{
34        SapphireSeason *tvseason = [SapphireSeason season:season forShow:show withPath:showPath inContext:moc];
35        NSEnumerator *epEnum = [tvseason.episodesSet objectEnumerator];
36        SapphireEpisode *tvep;
37        while((tvep = [epEnum nextObject]) != nil)
38        {
39                if([SapphireSubEpisode subEpisodeTitle:title inEpisode:tvep] != nil)
40                        return tvep;
41        }
42       
43        SapphireEpisode *ret = [NSEntityDescription insertNewObjectForEntityForName:SapphireEpisodeName inManagedObjectContext:moc];
44        ret.season = tvseason;
45        ret.tvShow = tvseason.tvShow;
46        [ret addSubEpisodesObject:[SapphireSubEpisode createSubEpisodeTitle:title inEpisode:ret]];
47        return ret;
48}
49
50+ (void)upgradeV1EpisodesFromContext:(NSManagedObjectContext *)oldMoc toContext:(NSManagedObjectContext *)newMoc file:(NSDictionary *)fileLookup
51{
52        NSArray *eps = doFetchRequest(SapphireEpisodeName, oldMoc, nil);
53        NSEnumerator *epEnum = [eps objectEnumerator];
54        NSManagedObject *oldEp;
55        while((oldEp = [epEnum nextObject]) != nil)
56        {
57                NSArray *oldFilePaths = [oldEp valueForKeyPath:@"files.path"];
58                NSEnumerator *pathEnum = [oldFilePaths objectEnumerator];
59                NSString *path;
60                NSMutableSet *newFiles = [NSMutableSet set];
61                while((path = [pathEnum nextObject]) != nil)
62                {
63                        SapphireFileMetaData *newFile = [fileLookup objectForKey:path];
64                        if(newFile != nil)
65                                [newFiles addObject:newFile];
66                }
67                if([newFiles count] == 0)
68                        continue;
69               
70                NSNumber *seasonNum = [oldEp valueForKeyPath:@"season.seasonNumber"];
71                NSString *showName = [oldEp valueForKeyPath:@"tvShow.name"];
72                NSString *showPath = [oldEp valueForKeyPath:@"tvShow.showPath"];
73               
74                SapphireSeason *season = [SapphireSeason season:[seasonNum intValue] forShow:showName withPath:showPath inContext:newMoc];
75                if(season == nil)
76                        continue;
77               
78                SapphireEpisode *newEp = [NSEntityDescription insertNewObjectForEntityForName:SapphireEpisodeName inManagedObjectContext:newMoc];
79                newEp.season = season;
80                newEp.tvShow = season.tvShow;
81                [newEp.filesSet setSet:newFiles];
82               
83                NSEnumerator *subEpEnum = [[oldEp valueForKey:@"subEpisodes"] objectEnumerator];
84                NSManagedObject *subEp;
85                while((subEp = [subEpEnum nextObject]) != nil)
86                        [SapphireSubEpisode upgradeV1SubEpisode:subEp toContext:newMoc inEpisode:newEp];
87        }
88}
89
90- (void) dealloc
91{
92        [sortedSubEpisodes release];
93        [super dealloc];
94}
95
96- (void)createSortedEpisodes
97{
98        if(sortedSubEpisodes != nil)
99                return;
100       
101        NSArray *unsorted = [self.subEpisodesSet allObjects];
102        sortedSubEpisodes = [[unsorted sortedArrayUsingSelector:@selector(compare:)] retain];
103}
104
105- (void)insertDictionary:(NSDictionary *)dict
106{
107        SapphireSubEpisode *sub = [self.subEpisodesSet anyObject];
108        int secondEp = [[dict objectForKey:META_EPISODE_2_NUMBER_KEY] intValue];
109        int setIndex = -1;
110        if(secondEp != 0)
111                setIndex = 0;
112        [sub insertDictionary:dict epIndex:setIndex];
113        if(secondEp != 0)
114        {
115                SapphireSubEpisode *sub = [SapphireSubEpisode createSubEpisode:secondEp inEpisode:self];
116                [sub insertDictionary:dict epIndex:1];
117                [self addSubEpisodesObject:sub];
118        }
119        else
120                [self.subEpisodesSet setSet:[NSSet setWithObject:sub]];
121}
122
123+ (SapphireEpisode *)episodeWithDictionary:(NSDictionary *)dict inContext:(NSManagedObjectContext *)moc
124{
125        NSString *show = [dict objectForKey:META_SHOW_NAME_KEY];
126        int season = [[dict objectForKey:META_SEASON_NUMBER_KEY] intValue];
127        int ep = [[dict objectForKey:META_EPISODE_NUMBER_KEY] intValue];
128       
129        if(show == nil || season == 0)
130                return nil;
131       
132        NSString *showPath = [dict objectForKey:META_SHOW_IDENTIFIER_KEY];
133        SapphireEpisode *ret;
134        if(ep == 0)
135        {
136                NSString *title = [dict objectForKey:META_TITLE_KEY];
137                ret = [SapphireEpisode episodeTitle:title inSeason:season forShow:show withPath:showPath inContext:moc];
138        }
139        else
140                ret = [SapphireEpisode episode:ep inSeason:season forShow:show withPath:showPath inContext:moc];
141        [ret insertDictionary:dict];
142        return ret;
143}
144
145- (NSNumber *)episodeNumber
146{
147        overrideWithXMLForKey(SapphireXMLEpisodeData, NSNumber, episodeNumber);
148        [self createSortedEpisodes];
149        return ((SapphireSubEpisode *)[sortedSubEpisodes objectAtIndex:0]).episodeNumber;
150}
151
152- (int)episodeNumberValue
153{
154        return [[self episodeNumber] intValue];
155}
156
157- (NSNumber *)lastEpisodeNumber
158{
159        overrideWithXMLForKey(SapphireXMLEpisodeData, NSNumber, lastEpisodeNumber);
160        [self createSortedEpisodes];
161        return ((SapphireSubEpisode *)[sortedSubEpisodes objectAtIndex:sortedSubEpisodes.count - 1]).episodeNumber;
162}
163
164- (int)lastEpisodeNumberValue
165{
166        return [[self lastEpisodeNumber] intValue];
167}
168
169- (NSNumber *)absoluteEpisodeNumber
170{
171        overrideWithXMLForKey(SapphireXMLEpisodeData, NSNumber, absoluteEpisodeNumber);
172        [self createSortedEpisodes];
173        return ((SapphireSubEpisode *)[sortedSubEpisodes objectAtIndex:0]).absoluteEpisodeNumber;
174}
175
176- (int)absoluteEpisodeNumberValue
177{
178        return [[self absoluteEpisodeNumber] intValue];
179}
180
181- (NSString *)episodeTitle
182{
183        overrideWithXMLForKey(SapphireXMLEpisodeData, NSString, xml.title);
184        [self createSortedEpisodes];
185        NSMutableArray *subs = [[sortedSubEpisodes valueForKey:@"episodeTitle"] mutableCopy];
186        [subs removeObject:[NSNull null]];
187        NSString *ret = [subs componentsJoinedByString:@" / "];
188        [subs release];
189        return ret;
190}
191
192- (NSString *)episodeDescription
193{
194        overrideWithXMLForKey(SapphireXMLEpisodeData, NSString, xml.contentDescription);
195        [self createSortedEpisodes];
196        NSMutableArray *subs = [[sortedSubEpisodes valueForKey:@"episodeDescription"] mutableCopy];
197        [subs removeObject:[NSNull null]];
198        NSString *ret = [subs componentsJoinedByString:@" / "];
199        [subs release];
200        return ret;
201}
202
203- (NSComparisonResult)compare:(SapphireEpisode *)other
204{
205        NSComparisonResult result = [self.season compare:other.season];
206        if(result != NSOrderedSame)
207                return result;
208       
209        NSNumber *myNumber = [self episodeNumber];
210        NSNumber *theirNumber = [other episodeNumber];
211        if([myNumber intValue] == 0 || [theirNumber intValue] == 0)
212                return [self airDateCompare:other];
213
214        return [myNumber compare:theirNumber];
215}
216
217- (NSDate *)airDate
218{
219        [self createSortedEpisodes];
220        return ((SapphireSubEpisode *)[sortedSubEpisodes objectAtIndex:0]).airDate;
221}
222
223- (NSComparisonResult)airDateCompare:(SapphireEpisode *)other
224{
225        return [[self airDate] compare:[other airDate]];
226}
227
228- (void)insertDisplayMetaData:(NSMutableDictionary *)dict
229{
230        id value = [self episodeTitle];
231        if(value != nil)
232                [dict setObject:value forKey:META_TITLE_KEY];
233        value = [self episodeDescription];
234        if(value != nil)
235                [dict setObject:value forKey:META_DESCRIPTION_KEY];
236        value = [[sortedSubEpisodes objectAtIndex:0] airDate];
237        if(value != nil)
238                [dict setObject:value forKey:META_SHOW_AIR_DATE];
239        int season = [[self season] seasonNumberValue];
240        int ep = [self episodeNumberValue];
241        if(season != 0)
242                [dict setObject:[[self season] seasonNumber] forKey:BRLocalizedString(META_SEASON_NUMBER_KEY, @"Season in metadata display")];
243        if(ep != 0)
244                [dict setObject:[NSNumber numberWithInt:ep] forKey:BRLocalizedString(META_EPISODE_NUMBER_KEY, @"Epsiode in metadata display")];
245        if(ep != 0 && season != 0)
246        {
247                int lastEp = [self lastEpisodeNumberValue];
248                NSString *key = BRLocalizedString(META_EPISODE_AND_SEASON_KEY, @"Season / Epsiode in metadata display");
249                if(lastEp != nil && lastEp != ep)
250                        [dict setObject:[NSString stringWithFormat:@"%@ - %d / %d-%d", [[self tvShow] name], season, ep, lastEp] forKey:key];
251                else
252                        [dict setObject:[NSString stringWithFormat:@"%@ - %d / %d", [[self tvShow] name], season, lastEp] forKey:key];         
253        }
254}
255
256- (void)insertAdditionalEpisode:(NSDictionary *)dict
257{
258        SapphireSubEpisode *sub = [SapphireSubEpisode createSubEpisode:[[dict objectForKey:META_EPISODE_NUMBER_KEY] intValue] inEpisode:self];
259        [sub insertDictionary:dict epIndex:-1];
260        [self addSubEpisodesObject:sub];
261}
262
263- (NSString *)path
264{
265        [self createSortedEpisodes];
266        return [[sortedSubEpisodes objectAtIndex:0] path];
267}
268
269- (NSString *)coverArtPath
270{
271        NSString *ret = [[SapphireMetaDataSupport collectionArtPath] stringByAppendingPathComponent:[self path]];
272        NSString *file = searchCoverArtExtForPath(ret);
273        if(file == nil)
274                return [self.season coverArtPath];
275        return ret;
276}
277
278- (NSNumber *)watched
279{
280        NSSet *files = self.filesSet;
281        if([files count] < 2)
282                return [[files anyObject] watched];
283       
284        NSArray *remain = [[files allObjects] filteredArrayUsingPredicate:[SapphireApplianceController unwatchedPredicate]];
285        if([remain count])
286                return [NSNumber numberWithBool:YES];
287        return [NSNumber numberWithBool:NO];
288}
289
290- (NSNumber *)favorite
291{
292        NSSet *files = self.filesSet;
293        if([files count] < 2)
294                return [[files anyObject] favorite];
295       
296        NSArray *remain = [[files allObjects] filteredArrayUsingPredicate:[SapphireApplianceController favoritePredicate]];
297        if([remain count])
298                return [NSNumber numberWithBool:YES];
299        return [NSNumber numberWithBool:NO];
300}
301
302/*Overrides*/
303- (void)addSubEpisodes:(NSSet*)value_
304{
305        [sortedSubEpisodes release];
306        sortedSubEpisodes = nil;
307        [super addSubEpisodes:value_];
308}
309
310- (void)removeSubEpisodes:(NSSet*)value_
311{
312        [sortedSubEpisodes release];
313        sortedSubEpisodes = nil;
314        [super removeSubEpisodes:value_];
315}
316
317- (void)addSubEpisodesObject:(SapphireSubEpisode*)value_
318{
319        [sortedSubEpisodes release];
320        sortedSubEpisodes = nil;
321        [super addSubEpisodesObject:value_];
322}
323
324- (void)removeSubEpisodesObject:(SapphireSubEpisode*)value_
325{
326        [sortedSubEpisodes release];
327        sortedSubEpisodes = nil;
328        [super removeSubEpisodesObject:value_]; 
329}
330
331- (void)clearPredicateCache
332{
333        [self.season clearPredicateCache];
334}
335
336@end
Note: See TracBrowser for help on using the repository browser.