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

Revision 734, 16.4 KB checked in by gbooker, 6 years ago (diff)

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

Line 
1#import "SapphireMovie.h"
2#import "SapphireGenre.h"
3#import "SapphireCast.h"
4#import "SapphireDirector.h"
5#import "CoreDataSupportFunctions.h"
6#import "SapphireMetaDataSupport.h"
7#import "SapphireFileMetaData.h"
8#import "SapphireApplianceController.h"
9#import "SapphireXMLMovieData.h"
10#import "SapphireXMLData.h"
11#import "NSString-Extensions.h"
12#import "SapphireMovieTranslation.h"
13
14NSString *FILE_DID_CHANGE_MOVIE_NOTIFICATION = @"FileDidChangeMovie";
15
16#define ORDERED_CAST_KEY                        @"orderedCast"
17#define ORDERED_CAST_DATA                       @"orderedCastData"
18#define OVERRIDDEN_CAST_DATA            @"overriddenCastData"
19#define ORDERED_DIRECTOR_KEY            @"orderedDirectors"
20#define ORDERED_DIRECTOR_DATA           @"orderedDirectorsData"
21#define OVERRIDDEN_DIRECTOR_DATA        @"overriddenDirectorsData"
22#define ORDERED_GENRES_KEY                      @"orderedGenres"
23#define ORDERED_GENRES_DATA                     @"orderedGenresData"
24#define OVERRIDDEN_GENRES_DATA          @"overriddenGenresData"
25
26
27@implementation SapphireMovie
28
29+ (SapphireMovie *)movieWithIMDB:(int)imdbNumber inContext:(NSManagedObjectContext *)moc
30{
31        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"imdbNumber == %d", imdbNumber];
32        return (SapphireMovie *)doSingleFetchRequest(SapphireMovieName, moc, predicate);
33}
34       
35+ (SapphireMovie *)createMovieWithIMDB:(int)imdbNumber inContext:(NSManagedObjectContext *)moc
36{
37        SapphireMovie *ret = [SapphireMovie movieWithIMDB:imdbNumber inContext:moc];
38        if(ret != nil)
39                return ret;
40       
41        ret = [NSEntityDescription insertNewObjectForEntityForName:SapphireMovieName inManagedObjectContext:moc];
42        ret.imdbNumber = [NSNumber numberWithInt:imdbNumber];
43        return ret;
44}
45
46+ (SapphireMovie *)movieWithTitle:(NSString *)title inContext:(NSManagedObjectContext *)moc
47{
48        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"imdbNumber == nil && title == %@", title];
49        return (SapphireMovie *)doSingleFetchRequest(SapphireMovieName, moc, predicate);
50}
51
52+ (SapphireMovie *)createMovieWithTitle:(NSString *)title inContext:(NSManagedObjectContext *)moc
53{
54        SapphireMovie *ret = [SapphireMovie movieWithTitle:title inContext:moc];
55        if(ret != nil)
56                return ret;
57       
58        ret = [NSEntityDescription insertNewObjectForEntityForName:SapphireMovieName inManagedObjectContext:moc];
59        ret.title = title;
60        ret.imdbNumber = nil;
61        return ret;
62}
63
64+ (SapphireMovie *)movieWithDictionary:(NSDictionary *)dict inContext:(NSManagedObjectContext *)moc
65{
66        NSString *imdbStr = [dict objectForKey:META_MOVIE_IDENTIFIER_KEY];
67        int imdbNumber = [SapphireMovie imdbNumberFromString:imdbStr];
68        if(imdbNumber == 0)
69                return nil;
70       
71        SapphireMovie *ret = [SapphireMovie createMovieWithIMDB:imdbNumber inContext:moc];
72        ret.title = [dict objectForKey:META_MOVIE_TITLE_KEY];
73        ret.releaseDate = [dict objectForKey:META_MOVIE_RELEASE_DATE_KEY];
74        ret.MPAARating = [dict objectForKey:META_MOVIE_MPAA_RATING_KEY];
75        ret.imdbRating = [dict objectForKey:META_MOVIE_IMDB_RATING_KEY];
76        ret.plot = [dict objectForKey:META_MOVIE_PLOT_KEY];
77        id value = [dict objectForKey:META_MOVIE_IMDB_250_KEY];
78        int i;
79        if((i = [value intValue]) != 0)
80                ret.imdbTop250RankingValue = i;
81        value = [dict objectForKey:META_MOVIE_OSCAR_KEY];
82        if((i = [value intValue]) != 0)
83                ret.oscarsWonValue = i;
84        NSMutableArray *genreArray = [NSMutableArray array];
85        NSEnumerator *genreEnum = [[dict objectForKey:META_MOVIE_GENRES_KEY] objectEnumerator];
86        NSString *genre;
87        while((genre = [genreEnum nextObject]) != nil)
88                [genreArray addObject:[SapphireGenre createGenre:genre inContext:moc]];
89        ret.orderedGenres = genreArray;
90       
91        NSMutableArray *dirArray = [NSMutableArray array];
92        NSEnumerator *directorEnum = [[dict objectForKey:META_MOVIE_DIRECTOR_KEY] objectEnumerator];
93        NSString *director;
94        while((director = [directorEnum nextObject]) != nil)
95                [dirArray addObject:[SapphireDirector createDirector:director inContext:moc]];
96        ret.orderedDirectors = dirArray;
97
98        NSMutableArray *castArray = [NSMutableArray array];
99        NSEnumerator *castEnum = [[dict objectForKey:META_MOVIE_CAST_KEY] objectEnumerator];
100        NSString *cast;
101        while((cast = [castEnum nextObject]) != nil)
102                [castArray addObject:[SapphireCast createCast:cast inContext:moc]];
103        ret.orderedCast = castArray;
104        return ret;
105}
106
107+ (int)imdbNumberFromString:(NSString *)imdbStr
108{
109        int imdbNumber = 0;
110        if(imdbStr != nil)
111        {
112                NSScanner *scanner = [NSScanner scannerWithString:imdbStr];
113                [scanner scanUpToCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] intoString:nil];
114                [scanner scanInt:&imdbNumber];
115        }
116        return imdbNumber;
117}
118
119+ (NSDictionary *)upgradeV1MoviesFromContext:(NSManagedObjectContext *)oldMoc toContext:(NSManagedObjectContext *)newMoc withCast:(NSDictionary *)cast directors:(NSDictionary *)directors genres:(NSDictionary *)genres
120{
121        NSMutableDictionary *lookup = [NSMutableDictionary dictionary];
122        NSArray *oldMovies = doFetchRequest(SapphireMovieName, oldMoc, nil);
123        NSEnumerator *movieEnum = [oldMovies objectEnumerator];
124        NSManagedObject *oldMovie;
125        while((oldMovie = [movieEnum nextObject]) != nil)
126        {
127                SapphireMovie *newMovie = [NSEntityDescription insertNewObjectForEntityForName:SapphireMovieName inManagedObjectContext:newMoc];
128                NSNumber *imdbNumber = [oldMovie valueForKey:@"imdbNumber"];
129                newMovie.imdbNumber = imdbNumber;
130                newMovie.imdbRating = [oldMovie valueForKey:@"imdbRating"];
131                newMovie.imdbTop250Ranking = [oldMovie valueForKey:@"imdbTop250Ranking"];
132                newMovie.MPAARating = [oldMovie valueForKey:@"MPAARating"];
133                newMovie.orderedCastData = [oldMovie valueForKey:@"orderedCastData"];
134                newMovie.orderedDirectorsData = [oldMovie valueForKey:@"orderedDirectorsData"];
135                newMovie.orderedGenresData = [oldMovie valueForKey:@"orderedGenresData"];
136                newMovie.oscarsWon = [oldMovie valueForKey:@"oscarsWon"];
137                newMovie.plot = [oldMovie valueForKey:@"plot"];
138                newMovie.releaseDate = [oldMovie valueForKey:@"releaseDate"];
139                newMovie.title = [oldMovie valueForKey:@"title"];
140                NSArray *castNames = [oldMovie valueForKeyPath:@"cast.name"];
141                NSEnumerator *castEnum = [castNames objectEnumerator];
142                NSString *name;
143                NSMutableSet *objSet = [NSMutableSet set];
144                while((name = [castEnum nextObject]) != nil)
145                {
146                        [objSet addObject:[cast objectForKey:name]];
147                }
148                [newMovie.castSet setSet:objSet];
149                NSArray *directorNames = [oldMovie valueForKeyPath:@"directors.name"];
150                NSEnumerator *directorEnum = [directorNames objectEnumerator];
151                objSet = [NSMutableSet set];
152                while((name = [directorEnum nextObject]) != nil)
153                {
154                        [objSet addObject:[directors objectForKey:name]];
155                }
156                [newMovie.directorsSet setSet:objSet];
157                NSArray *genreNames = [oldMovie valueForKeyPath:@"genres.name"];
158                NSEnumerator *genreEnum = [genreNames objectEnumerator];
159                objSet = [NSMutableSet set];
160                while((name = [genreEnum nextObject]) != nil)
161                {
162                        [objSet addObject:[genres objectForKey:name]];
163                }
164                [newMovie.genresSet setSet:objSet];
165               
166                NSEnumerator *translationEnum = [[oldMovie valueForKey:@"translations"] objectEnumerator];
167                NSManagedObject *translation;
168                while((translation = [translationEnum nextObject]) != nil)
169                {
170                        [SapphireMovieTranslation upgradeV1MovieTranslation:translation toMovie:newMovie];
171                }
172                [lookup setObject:newMovie forKey:imdbNumber];
173        }
174        return lookup;
175}
176
177- (NSComparisonResult)releaseDateCompare:(SapphireMovie *)other
178{
179        return [self.releaseDate compare:other.releaseDate];
180}
181
182- (NSComparisonResult)titleCompare:(SapphireMovie *)other
183{
184        return [self.title nameCompare:other.title];
185}
186
187- (NSComparisonResult)imdbTop250RankingCompare:(SapphireMovie *)other
188{
189        return [self.imdbTop250Ranking compare:other.imdbTop250Ranking];
190}
191
192- (NSComparisonResult)oscarsWonCompare:(SapphireMovie *)other
193{
194        return [self.oscarsWon compare:other.oscarsWon];
195}
196
197- (NSComparisonResult)imdbRatingCompare:(SapphireMovie *)other
198{
199        NSNumber *otherNum = other.imdbRating;
200        NSNumber *myNum = self.imdbRating;
201        if(myNum != nil)
202                if(otherNum != nil)
203                        return [myNum compare:otherNum];
204                else
205                        return NSOrderedDescending;
206        else if(otherNum != nil)
207                return NSOrderedAscending;
208        return NSOrderedSame;
209}
210
211- (NSArray *)orderedCast
212{
213        [self willAccessValueForKey:ORDERED_CAST_KEY];
214        NSArray *ret = [self primitiveValueForKey:ORDERED_CAST_KEY];
215        [self didAccessValueForKey:ORDERED_CAST_KEY];
216        if(ret == nil)
217        {
218                NSData *propData = [self valueForKey:OVERRIDDEN_CAST_DATA];
219                if(propData == nil)
220                        propData = [self valueForKey:ORDERED_CAST_DATA];
221                if(propData != nil)
222                {
223                        NSArray *names = [NSKeyedUnarchiver unarchiveObjectWithData:propData];
224                        NSMutableArray *mutRet = [NSMutableArray arrayWithCapacity:[names count]];
225                        NSManagedObjectContext *moc = [self managedObjectContext];
226                        NSEnumerator *nameEnum = [names objectEnumerator];
227                        NSString *name;
228                        while((name = [nameEnum nextObject]) != nil)
229                        {
230                                SapphireCast *aCast = [SapphireCast cast:name inContext:moc];
231                                if(aCast != nil)
232                                        [mutRet addObject:aCast];
233                        }
234                        ret = [NSArray arrayWithArray:mutRet];
235                        [self setPrimitiveValue:ret forKey:ORDERED_CAST_KEY];
236                }
237        }
238       
239        return ret;
240}
241
242- (void)setOrderedCast:(NSArray *)ordered
243{
244        [self willChangeValueForKey:ORDERED_CAST_KEY];
245        [self setPrimitiveValue:ordered forKey:ORDERED_CAST_KEY];
246        [self didChangeValueForKey:ORDERED_CAST_KEY];
247        NSArray *arc = [ordered valueForKey:@"name"];
248        [self setValue:[NSKeyedArchiver archivedDataWithRootObject:arc] forKey:ORDERED_CAST_DATA];
249        [self.castSet setSet:[NSSet setWithArray:ordered]];
250        int i, count=[ordered count];
251        if(count > 10)
252                count = 10;
253        for(i=0; i<count; i++)
254        {
255                ((SapphireCast *)[ordered objectAtIndex:i]).hasMajorRoleValue = YES;
256        }       
257}
258
259- (NSArray *)orderedGenres
260{
261        [self willAccessValueForKey:ORDERED_GENRES_KEY];
262        NSArray *ret = [self primitiveValueForKey:ORDERED_GENRES_KEY];
263        [self didAccessValueForKey:ORDERED_GENRES_KEY];
264        if(ret == nil)
265        {
266                NSData *propData = [self valueForKey:OVERRIDDEN_GENRES_DATA];
267                if(propData == nil)
268                        propData = [self valueForKey:ORDERED_GENRES_DATA];
269                if(propData != nil)
270                {
271                        NSArray *genres = [NSKeyedUnarchiver unarchiveObjectWithData:propData];
272                        NSMutableArray *mutRet = [NSMutableArray arrayWithCapacity:[genres count]];
273                        NSManagedObjectContext *moc = [self managedObjectContext];
274                        NSEnumerator *genreEnum = [genres objectEnumerator];
275                        NSString *genre;
276                        while((genre = [genreEnum nextObject]) != nil)
277                        {
278                                SapphireGenre *aGenre = [SapphireGenre genre:genre inContext:moc];
279                                if(aGenre != nil)
280                                        [mutRet addObject:aGenre];
281                        }
282                        ret = [NSArray arrayWithArray:mutRet];
283                        [self setPrimitiveValue:ret forKey:ORDERED_GENRES_KEY];
284                }
285        }
286       
287        return ret;
288}
289
290- (void)setOrderedGenres:(NSArray *)ordered
291{
292        [self willChangeValueForKey:ORDERED_GENRES_KEY];
293        [self setPrimitiveValue:ordered forKey:ORDERED_GENRES_KEY];
294        [self didChangeValueForKey:ORDERED_GENRES_KEY];
295        NSArray *arc = [ordered valueForKey:@"name"];
296        [self setValue:[NSKeyedArchiver archivedDataWithRootObject:arc] forKey:ORDERED_GENRES_DATA];
297        [self.genresSet addObjectsFromArray:ordered];
298}
299
300- (NSArray *)orderedDirectors
301{
302        [self willAccessValueForKey:ORDERED_DIRECTOR_KEY];
303        NSArray *ret = [self primitiveValueForKey:ORDERED_DIRECTOR_KEY];
304        [self didAccessValueForKey:ORDERED_DIRECTOR_KEY];
305        if(ret == nil)
306        {
307                NSData *propData = [self valueForKey:OVERRIDDEN_DIRECTOR_DATA];
308                if(propData == nil)
309                        propData = [self valueForKey:ORDERED_DIRECTOR_DATA];
310                if(propData != nil)
311                {
312                        NSArray *names = [NSKeyedUnarchiver unarchiveObjectWithData:propData];
313                        NSMutableArray *mutRet = [NSMutableArray arrayWithCapacity:[names count]];
314                        NSManagedObjectContext *moc = [self managedObjectContext];
315                        NSEnumerator *nameEnum = [names objectEnumerator];
316                        NSString *name;
317                        while((name = [nameEnum nextObject]) != nil)
318                        {
319                                SapphireDirector *aDir = [SapphireDirector director:name inContext:moc];
320                                if(aDir != nil)
321                                        [mutRet addObject:aDir];
322                        }
323                        ret = [NSArray arrayWithArray:mutRet];
324                        [self setPrimitiveValue:ret forKey:ORDERED_DIRECTOR_KEY];
325                }
326        }
327       
328        return ret;
329}
330
331- (void)setOrderedDirectors:(NSArray *)ordered
332{
333        [self willChangeValueForKey:ORDERED_DIRECTOR_KEY];
334        [self setPrimitiveValue:ordered forKey:ORDERED_DIRECTOR_KEY];
335        [self didChangeValueForKey:ORDERED_DIRECTOR_KEY];
336        NSArray *arc = [ordered valueForKey:@"name"];
337        [self setValue:[NSKeyedArchiver archivedDataWithRootObject:arc] forKey:ORDERED_DIRECTOR_DATA];
338        [self.directorsSet addObjectsFromArray:ordered];
339}
340
341#define checkOrderedData(property, overridden) \
342{ \
343        NSEnumerator *xmlEnum = [self.xmlSet objectEnumerator]; \
344        SapphireXMLMovieData *xml; \
345        while([overridden count] == 0 && (xml = [xmlEnum nextObject]) != nil) \
346                overridden = xml.property; \
347}
348
349- (void)checkOrderedCast
350{
351        NSArray *overridden = nil;
352        checkOrderedData(orderedCast, overridden);
353        if(![overridden count])
354                self.overriddenCastData = nil;
355        else
356        {
357                NSArray *names = [overridden valueForKey:@"name"];
358                self.overriddenCastData = [NSKeyedArchiver archivedDataWithRootObject:names];
359        }
360        [self setPrimitiveValue:nil forKey:ORDERED_CAST_KEY];
361        [self.castSet setSet:[NSSet setWithArray:self.orderedCast]];
362}
363
364- (void)checkOrderedGenres
365{
366        NSArray *overridden = nil;
367        checkOrderedData(orderedGenres, overridden);
368        if(![overridden count])
369                self.overriddenGenresData = nil;
370        else
371        {
372                NSArray *names = [overridden valueForKey:@"name"];
373                self.overriddenGenresData = [NSKeyedArchiver archivedDataWithRootObject:names];
374        }
375        [self setPrimitiveValue:nil forKey:ORDERED_GENRES_KEY];
376        [self.genresSet setSet:[NSSet setWithArray:self.orderedGenres]];
377}
378
379- (void)checkOrderedDirectors
380{
381        NSArray *overridden = nil;
382        checkOrderedData(orderedDirectors, overridden);
383        if(![overridden count])
384                self.overriddenDirectorsData = nil;
385        else
386        {
387                NSArray *names = [overridden valueForKey:@"name"];
388                self.overriddenDirectorsData = [NSKeyedArchiver archivedDataWithRootObject:names];
389        }
390        [self setPrimitiveValue:nil forKey:ORDERED_DIRECTOR_KEY];
391        [self.directorsSet setSet:[NSSet setWithArray:self.orderedDirectors]];
392}
393
394- (NSString *)title
395{
396        overrideWithXMLForKey(SapphireXMLMovieData, NSString, xml.title);
397        return super.title;
398}
399
400- (NSString *)plot
401{
402        overrideWithXMLForKey(SapphireXMLMovieData, NSString, xml.contentDescription);
403        overrideWithXMLForKey(SapphireXMLMovieData, NSString, xml.summary);
404        return super.plot;
405}
406
407- (BOOL)castMemberHasMajorRoleStatus:(SapphireCast *)cast
408{
409        NSArray *ordered = self.orderedCast;
410        int i, count=[ordered count];
411        if(count > 10)
412                count = 10;
413        for(i=0; i<count; i++)
414        {
415                if([ordered objectAtIndex:i] == cast)
416                        return YES;
417        }
418        return NO;
419}
420
421- (NSString *)path
422{
423        return [@"@MOVIES/Movie" stringByAppendingPathComponent:[self.imdbNumber stringValue]];
424}
425
426- (NSString *)coverArtPath
427{
428        return [NSString stringWithFormat:@"%@/@MOVIES/%@", [SapphireMetaDataSupport collectionArtPath], self.imdbNumber];
429}
430
431- (void)insertDisplayMetaData:(NSMutableDictionary *)dict
432{
433        id value = [self title];
434        if(value != nil)
435                [dict setObject:value forKey:META_MOVIE_TITLE_KEY];
436        value = [self MPAARating];
437        if(value != nil)
438                [dict setObject:value forKey:META_MOVIE_MPAA_RATING_KEY];
439        value = [self imdbRating];
440        if(value != nil)
441                [dict setObject:value forKey:META_MOVIE_IMDB_RATING_KEY];
442        value = [self plot];
443        if(value != nil)
444                [dict setObject:value forKey:META_MOVIE_PLOT_KEY];
445        value = [self releaseDate];
446        if(value != nil)
447                [dict setObject:value forKey:META_MOVIE_RELEASE_DATE_KEY];
448        value = [self imdbTop250Ranking];
449        if(value != nil)
450                [dict setObject:value forKey:META_MOVIE_IMDB_250_KEY];
451        value = [self oscarsWon];
452        if(value != nil)
453                [dict setObject:value forKey:META_MOVIE_OSCAR_KEY];
454        value = [[self orderedDirectors] valueForKey:@"name"];
455        if(value != nil)
456                [dict setObject:value forKey:META_MOVIE_DIRECTOR_KEY];
457        value = [[self orderedCast] valueForKey:@"name"];
458        if(value != nil)
459                [dict setObject:value forKey:META_MOVIE_CAST_KEY];
460        value = [[self orderedGenres] valueForKey:@"name"];
461        if(value != nil)
462                [dict setObject:value forKey:META_MOVIE_GENRES_KEY];
463}
464
465- (NSNumber *)watched
466{
467        NSSet *files = self.filesSet;
468        if([files count] < 2)
469                return [[files anyObject] watched];
470       
471        NSArray *remain = [[files allObjects] filteredArrayUsingPredicate:[SapphireApplianceController unwatchedPredicate]];
472        if([remain count])
473                return [NSNumber numberWithBool:YES];
474        return [NSNumber numberWithBool:NO];
475}
476
477- (NSNumber *)favorite
478{
479        NSSet *files = self.filesSet;
480        if([files count] < 2)
481                return [[files anyObject] favorite];
482       
483        NSArray *remain = [[files allObjects] filteredArrayUsingPredicate:[SapphireApplianceController favoritePredicate]];
484        if([remain count])
485                return [NSNumber numberWithBool:YES];
486        return [NSNumber numberWithBool:NO];
487}
488
489- (void)clearPredicateCache
490{
491        [self.orderedGenres makeObjectsPerformSelector:@selector(clearPredicateCache)];
492        [self.orderedDirectors makeObjectsPerformSelector:@selector(clearPredicateCache)];
493        [self.orderedCast makeObjectsPerformSelector:@selector(clearPredicateCache)];
494}
495
496@end
Note: See TracBrowser for help on using the repository browser.