source: branches/CoreData/SapphireFrappliance/MetaData/SapphireMObjects/SapphireDirectoryMetaData.m @ 696

Revision 696, 22.4 KB checked in by gbooker, 5 years ago (diff)

Putting back the stuff that was lost on server

Line 
1#import "SapphireDirectorySymLink.h"
2#import "SapphireFileSymLink.h"
3#import "NSFileManager-Extensions.h"
4#import "CoreDataSupportFunctions.h"
5#import "SapphireMetaDataScanner.h"
6#import "SapphireImportHelper.h"
7#import "NSString-Extensions.h"
8#import "SapphireMetaDataUpgrading.h"
9#import "SapphireBasicDirectoryFunctionsImports.h"
10#import "SapphireEpisode.h"
11#import "SapphireSubEpisode.h"
12#import "SapphireMovie.h"
13#import "NSManagedObject-Extensions.h"
14
15@implementation SapphireDirectoryMetaData
16
17+ (SapphireDirectoryMetaData *)directoryWithPath:(NSString *)path inContext:(NSManagedObjectContext *)moc
18{
19        SapphireMetaData *meta = [SapphireMetaData metaDataWithPath:path inContext:moc];
20        if([meta isKindOfClass:[SapphireDirectoryMetaData class]])
21                return (SapphireDirectoryMetaData *)meta;
22        return nil;
23}
24
25+ (SapphireDirectoryMetaData *)internalCreateDirectoryWithPath:(NSString *)path parent:(SapphireDirectoryMetaData *)parent inContext:(NSManagedObjectContext *)moc
26{
27        SapphireDirectoryMetaData *ret = [NSEntityDescription insertNewObjectForEntityForName:SapphireDirectoryMetaDataName inManagedObjectContext:moc];
28        ret.parent = parent;
29        ret.path = path;
30       
31        return ret;
32}
33
34+ (SapphireDirectoryMetaData *)createDirectoryWithPath:(NSString *)path inContext:(NSManagedObjectContext *)moc
35{
36        SapphireDirectoryMetaData *ret = [SapphireDirectoryMetaData directoryWithPath:path inContext:moc];
37        if(ret != nil)
38                return ret;
39       
40        SapphireDirectoryMetaData *parent = [SapphireDirectoryMetaData createDirectoryWithPath:[path stringByDeletingLastPathComponent] inContext:moc];
41        ret = [SapphireDirectoryMetaData internalCreateDirectoryWithPath:path parent:parent inContext:moc];
42       
43        return ret;
44}
45
46+ (SapphireDirectoryMetaData *)createDirectoryWithPath:(NSString *)path parent:(SapphireDirectoryMetaData *)parent inContext:(NSManagedObjectContext *)moc
47{
48        SapphireDirectoryMetaData *ret = [SapphireDirectoryMetaData directoryWithPath:path inContext:moc];
49        if(ret != nil)
50                return ret;
51
52        return [SapphireDirectoryMetaData internalCreateDirectoryWithPath:path parent:parent inContext:moc];
53}
54
55- (id)initWithEntity:(NSEntityDescription *)entity insertIntoManagedObjectContext:(NSManagedObjectContext *)context
56{
57        self = [super initWithEntity:entity insertIntoManagedObjectContext:context];
58        if(self == nil)
59                return self;
60       
61        Basic_Directory_Function_Inits
62       
63        return self;
64}       
65
66- (void) dealloc
67{
68        [importArray release];
69        [cachedLookup release];
70        Basic_Directory_Function_Deallocs
71        [super dealloc];
72}
73
74
75- (void)insertDictionary:(NSDictionary *)dict withDefer:(NSMutableDictionary *)defer andDisplay:(SapphireMetaDataUpgrading *)display
76{
77        NSManagedObjectContext *moc = [self managedObjectContext];
78        NSDictionary *dirs = [dict objectForKey:@"Dirs"];
79        NSArray *allDirs = [[dirs allKeys] sortedArrayUsingSelector:@selector(compare:)];
80        NSEnumerator *dirEnum = [allDirs objectEnumerator];
81        NSString *dir;
82        while((dir = [dirEnum nextObject]) != nil)
83        {
84                NSString *path = [self.path stringByAppendingPathComponent:dir];
85                SapphireDirectoryMetaData *newDir = [SapphireDirectoryMetaData createDirectoryWithPath:path parent:self inContext:moc];
86                [newDir insertDictionary:[dirs objectForKey:dir] withDefer:defer andDisplay:display];
87                if([newDir.metaDirsSet count] == 0 && [newDir.metaFilesSet count] == 0)
88                {
89                        newDir.parent = nil;
90                        [moc deleteObject:newDir];
91                }
92        }
93        NSDictionary *files = [dict objectForKey:@"Files"];
94        NSArray *allFiles = [[files allKeys] sortedArrayUsingSelector:@selector(compare:)];
95        NSEnumerator *fileEnum = [allFiles objectEnumerator];
96        NSString *file;
97        while((file = [fileEnum nextObject]) != nil)
98        {
99                NSString *path = [self.path stringByAppendingPathComponent:file];
100                [display setCurrentFile:[NSString stringByCroppingDirectoryPath:path toLength:3]];
101                SapphireFileMetaData *newFile = [SapphireFileMetaData createFileWithPath:path parent:self inContext:moc];
102                [newFile insertDictionary:[files objectForKey:file] withDefer:defer];
103        }
104}
105
106- (BOOL)checkPredicate:(NSPredicate *)pred duplicateSet:(NSMutableSet *)dups
107{
108        NSManagedObjectContext *moc = [self managedObjectContext];
109        NSPredicate *pathPredicate = [NSPredicate predicateWithFormat:@"path BEGINSWITH %@", [self.path stringByAppendingString:@"/"]];
110        NSPredicate *predicate;
111        if(pred == nil)
112                predicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:pathPredicate, filterPredicate, nil]];
113        else
114                predicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:pathPredicate, pred, filterPredicate, nil]];
115        if(entityExists(SapphireFileMetaDataName, moc, predicate))
116                return YES;
117       
118        NSArray *array = doFetchRequest(SapphireFileSymLinkName, moc, pathPredicate);
119        if([array count])
120        {
121                NSEnumerator *symEunm = [array objectEnumerator];
122                SapphireFileSymLink *sym;
123                while((sym = [symEunm nextObject]) != nil)
124                {
125                        SapphireFileMetaData *file = sym.file;
126                        //Doing a predicate check is likely faster than these two property fetches and prefix match
127/*                      NSString *finalPath = file.path;
128                        if([finalPath hasPrefix:self.path])
129                                continue;*/
130                        if(pred == nil || [pred evaluateWithObject:file])
131                                return YES;
132                }
133        }
134       
135        array = doFetchRequest(SapphireDirectorySymLinkName, moc, pathPredicate);
136        if([array count])
137        {
138                SapphireDirectorySymLink *sym = nil;
139                NSEnumerator *symEnum = [array objectEnumerator];
140                while((sym = [symEnum nextObject]) != nil)
141                {
142                        SapphireDirectoryMetaData *dir = sym.directory;
143                        NSString *finalPath = dir.path;
144                        if([dups containsObject:finalPath] || [finalPath hasPrefix:self.path])
145                                continue;
146                        [dups addObject:finalPath];
147                        [dir setFilterPredicate:filterPredicate];
148                        if([dir checkPredicate:pred duplicateSet:dups])
149                                return YES;
150                }
151        }
152        return NO;
153}
154
155NSComparisonResult fileAndLinkEpisodeCompare(id file1, id file2, void *context)
156{
157        /*Resolve link and try to sort by episodes*/
158        SapphireFileMetaData *first;
159        if([file1 isKindOfClass:[SapphireFileMetaData class]])
160                first = (SapphireFileMetaData *)file1;
161        else
162                first = ((SapphireFileSymLink *)file1).file;
163
164        SapphireFileMetaData *second;
165        if([file2 isKindOfClass:[SapphireFileMetaData class]])
166                second = (SapphireFileMetaData *)file2;
167        else
168                second = ((SapphireFileSymLink *)file2).file;
169       
170        NSComparisonResult result = [first episodeCompare:second];
171        if(result != NSOrderedSame)
172                return result;
173       
174        result = [first movieCompare:second];
175        if(result != NSOrderedSame)
176                return result;
177       
178        /*Finally sort by path*/
179        return [[[file1 valueForKey:@"path"] lastPathComponent] nameCompare:[[file2 valueForKey:@"path"] lastPathComponent]];
180}
181
182NSComparisonResult dirAndLinkPathCompare(id dir1, id dir2, void *context)
183{
184        return [[[dir1 valueForKey:@"path"] lastPathComponent] nameCompare:[[dir2 valueForKey:@"path"] lastPathComponent]];
185}
186
187- (NSArray *)files
188{
189        return cachedFiles;
190}
191
192- (NSArray *)directories
193{
194        return cachedDirs;
195}
196
197- (id <SapphireDirectory>)metaDataForDirectory:(NSString *)directory
198{
199        SapphireDirectoryMetaData *ret = [cachedLookup objectForKey:directory];
200        if(ret != nil)
201        {
202                if([ret isKindOfClass:[SapphireDirectorySymLink class]])
203                        ret = [(SapphireDirectorySymLink *)ret directory];
204                return ret;
205        }
206        SapphireLog(SAPPHIRE_LOG_GENERAL, SAPPHIRE_LOG_LEVEL_ERROR, @"Somehow couldn't get cache for %@ in %@", directory, self.path);
207        NSString *path = [self.path stringByAppendingPathComponent:directory];
208        NSPredicate *pred = [NSPredicate predicateWithFormat:@"path == %@", path];
209        NSArray *candidates = [[self.metaDirsSet allObjects] filteredArrayUsingPredicate:pred];
210        if([candidates count])
211                ret = [candidates objectAtIndex:0];
212        else
213        {
214                candidates  = [[self.linkedDirsSet allObjects] filteredArrayUsingPredicate:pred];
215                if([candidates count])
216                        ret = ((SapphireDirectorySymLink *)[candidates objectAtIndex:0]).directory;             
217        }
218        [ret setFilterPredicate:filterPredicate];
219       
220        return nil;
221}
222
223- (SapphireFileMetaData *)metaDataForFile:(NSString *)file
224{
225        SapphireFileMetaData *ret = [cachedLookup objectForKey:file];
226        if(ret != nil)
227        {
228                if([ret isKindOfClass:[SapphireFileSymLink class]])
229                        ret = [(SapphireFileSymLink *)ret file];
230                return ret;
231        }
232        NSString *path = [self.path stringByAppendingPathComponent:file];
233        NSPredicate *pred = [NSPredicate predicateWithFormat:@"path == %@", path];
234        NSArray *candidates = [[self.metaFilesSet allObjects] filteredArrayUsingPredicate:pred];
235        if([candidates count])
236                return [candidates objectAtIndex:0];
237       
238        candidates  = [[self.linkedFilesSet allObjects] filteredArrayUsingPredicate:pred];
239        if([candidates count])
240                return ((SapphireFileSymLink *)[candidates objectAtIndex:0]).file;
241       
242        return nil;
243}
244
245- (void)rescanDirWithExistingDirs:(NSMutableArray *)existingDirs files:(NSMutableArray *)existingFiles symDirs:(NSMutableArray *)existingSymDirs symFiles:(NSMutableArray *)existingSymFiles;
246{
247        [importArray release];
248        importArray = [[NSMutableArray alloc] init];
249
250        NSMutableDictionary *dirs = [[NSMutableDictionary alloc] init];
251        NSEnumerator *cachedEnum = [existingDirs objectEnumerator];
252        NSManagedObject *object;
253        while((object = [cachedEnum nextObject]) != nil)
254        {
255                [dirs setObject:object forKey:[object valueForKeyPath:@"path.lastPathComponent"]];
256        }
257       
258        NSMutableDictionary *files = [[NSMutableDictionary alloc] init];
259        cachedEnum = [existingFiles objectEnumerator];
260        while((object = [cachedEnum nextObject]) != nil)
261        {
262                [files setObject:object forKey:[object valueForKeyPath:@"path.lastPathComponent"]];
263        }
264
265        NSMutableDictionary *linkedDirs = [[NSMutableDictionary alloc] init];
266        cachedEnum = [existingSymDirs objectEnumerator];
267        while((object = [cachedEnum nextObject]) != nil)
268        {
269                [linkedDirs setObject:object forKey:[object valueForKeyPath:@"path.lastPathComponent"]];
270        }
271
272        NSMutableDictionary *linkedFiles = [[NSMutableDictionary alloc] init];
273        cachedEnum = [existingSymFiles objectEnumerator];
274        while((object = [cachedEnum nextObject]) != nil)
275        {
276                [linkedFiles setObject:object forKey:[object valueForKeyPath:@"path.lastPathComponent"]];
277        }
278       
279        NSFileManager *fm = [NSFileManager defaultManager];
280        NSManagedObjectContext *moc = [self managedObjectContext];
281       
282        NSArray *names = [fm directoryContentsAtPath:self.path];
283        NSEnumerator *nameEnum = [names objectEnumerator];
284        NSString *name;
285        BOOL modified = NO;     
286        while((name = [nameEnum nextObject]) != nil)
287        {
288                NSString *filePath = [self.path stringByAppendingPathComponent:name];
289                if(![fm acceptFilePath:filePath])
290                        continue;
291               
292                NSDictionary *attributes = [fm fileAttributesAtPath:filePath traverseLink:NO];
293                if([[attributes fileType] isEqualToString:NSFileTypeSymbolicLink])
294                {
295                        /*Sym links are fun*/
296                        NSString *resolvedPath = [filePath stringByResolvingSymlinksInPath];
297                        if(![fm acceptFilePath:resolvedPath])
298                                continue;
299                       
300                        if([fm isDirectory:resolvedPath])
301                        {
302                                if([dirs objectForKey:name] != nil)
303                                {
304                                        //Dir moved, but original data is still here
305                                        SapphireDirectoryMetaData *resolved = [SapphireDirectoryMetaData directoryWithPath:resolvedPath inContext:moc];
306                                        if(resolved != nil)
307                                                [moc deleteObject:resolved];
308                                       
309                                        resolved = (SapphireDirectoryMetaData *)[self metaDataForDirectory:name];
310                                        resolved.parent = [SapphireDirectoryMetaData createDirectoryWithPath:[resolvedPath stringByDeletingLastPathComponent] inContext:moc];
311                                        resolved.path = resolvedPath;
312                                        [dirs removeObjectForKey:name];
313                                }
314                                SapphireDirectorySymLink *newLink = [SapphireDirectorySymLink createDirectoryLinkWithPath:filePath toPath:resolvedPath inContext:moc];
315                                if([linkedDirs objectForKey:name] != nil)
316                                        [linkedDirs removeObjectForKey:name];
317                                else
318                                        [existingSymDirs addObject:newLink];
319                        }
320                        else
321                        {
322                                if([files objectForKey:name] != nil)
323                                {
324                                        //File moved, but original data is still here
325                                        SapphireFileMetaData *resolved = [SapphireFileMetaData fileWithPath:resolvedPath inContext:moc];
326                                        if(resolved != nil)
327                                                [moc deleteObject:resolved];
328                                       
329                                        resolved = [self metaDataForFile:name];
330                                        resolved.parent = [SapphireDirectoryMetaData createDirectoryWithPath:[resolvedPath stringByDeletingLastPathComponent] inContext:moc];
331                                        resolved.path = resolvedPath;
332                                        [files removeObjectForKey:name];
333                                }
334                                SapphireFileSymLink *newLink = [SapphireFileSymLink createFileLinkWithPath:filePath toPath:resolvedPath inContext:moc];
335                                if([linkedFiles objectForKey:name] != nil)
336                                        [linkedFiles removeObjectForKey:name];
337                                else
338                                        [existingSymFiles addObject:newLink];
339                        }
340                        /*      It's not always modified, but rather than figuring out all the cases where it is or isn't
341                         just set it to YES for a rare case and figure it out later if it's an issue*/
342                        modified = YES;
343                }
344                else if([fm isDirectory:filePath])
345                {
346                        SapphireDirectoryMetaData *subDir = [dirs objectForKey:name];
347                        if(subDir == nil)
348                        {
349                                subDir = [SapphireDirectoryMetaData createDirectoryWithPath:filePath parent:self inContext:moc];
350                                [existingDirs addObject:subDir];
351                                modified = YES;
352                        }
353                        else
354                                [dirs removeObjectForKey:name];
355                }
356                else
357                {
358                        SapphireFileMetaData *subFile = [files objectForKey:name];
359                        if(subFile == nil)
360                        {
361                                subFile = [SapphireFileMetaData createFileWithPath:filePath parent:self inContext:moc];
362                                [existingFiles addObject:subFile];
363                                [importArray addObject:subFile];
364                                modified = YES;
365                        }
366                        else
367                        {
368                                [files removeObjectForKey:name];
369                                if([subFile needsUpdating])
370                                        [importArray addObject:subFile];                               
371                        }
372                }
373        }
374       
375        NSEnumerator *objectEnum = [files objectEnumerator];
376        while((object = [objectEnum nextObject]) != nil)
377        {
378                [existingFiles removeObject:object];
379                [moc deleteObject:object];
380                modified = YES;
381        }
382       
383        objectEnum = [dirs objectEnumerator];
384        while((object = [objectEnum nextObject]) != nil)
385        {
386                [existingDirs removeObject:object];
387                [moc deleteObject:object];
388                modified = YES;
389        }
390       
391        objectEnum = [linkedFiles objectEnumerator];
392        while((object = [objectEnum nextObject]) != nil)
393        {
394                [existingSymFiles removeObject:object];
395                [moc deleteObject:object];
396                modified = YES;
397        }
398       
399        objectEnum = [linkedDirs objectEnumerator];
400        while((object = [objectEnum nextObject]) != nil)
401        {
402                [existingSymDirs removeObject:object];
403                [moc deleteObject:object];
404                modified = YES;
405        }
406       
407        if(modified)
408        {
409                [self clearPredicateCache];
410                [SapphireMetaDataSupport save:moc];
411        }
412}
413
414- (void)reloadDirectoryContents
415{
416        NSManagedObjectContext *moc = [self managedObjectContext];
417        [moc refreshObject:self mergeChanges:YES];
418       
419        [cachedLookup release];
420        cachedLookup = [[NSMutableDictionary alloc] init];
421
422        NSPredicate *fetchPred = [NSPredicate predicateWithFormat:@"parent == %@", self];
423        NSMutableArray *fetchedFiles = [doFetchRequest(SapphireFileMetaDataName, moc, fetchPred) mutableCopy];
424        NSMutableArray *fetchedDirs = [doFetchRequest(SapphireDirectoryMetaDataName, moc, fetchPred) mutableCopy];
425        NSMutableArray *linkedFiles = [[self.linkedFilesSet allObjects] mutableCopy];
426        NSMutableArray *linkedDirs = [[self.linkedDirsSet allObjects] mutableCopy];
427       
428        [self rescanDirWithExistingDirs:fetchedDirs files:fetchedFiles symDirs:linkedDirs symFiles:linkedFiles];
429       
430        NSMutableArray *allFiles = [fetchedFiles mutableCopy];
431        [allFiles addObjectsFromArray:linkedFiles];
432        if(filterPredicate != nil)
433                [allFiles filterUsingPredicate:filterPredicate];
434
435        if([allFiles count])
436        {
437                NSMutableSet *files = [NSMutableSet setWithArray:fetchedFiles];
438                [files addObjectsFromArray:[linkedFiles valueForKey:@"file"]];
439                NSSet *allEps = [files valueForKeyPath:@"tvEpisode.objectID"];
440                if([allEps count])
441                {
442                        NSPredicate *fetchPred = [NSPredicate predicateWithFormat:@"SELF IN %@", allEps];
443                        NSArray *episodes = doFetchRequest(SapphireEpisodeName, moc, fetchPred);
444                        if([episodes count])
445                        {
446                                fetchPred = [NSPredicate predicateWithFormat:@"episode IN %@", episodes];
447                                doFetchRequest(SapphireSubEpisodeName, moc, fetchPred);
448                        }
449                }
450                NSSet *allMovies = [files valueForKeyPath:@"movie.objectID"];
451                if([allMovies count])
452                {
453                        NSPredicate *fetchPred = [NSPredicate predicateWithFormat:@"SELF IN %@", allMovies];
454                        doFetchRequest(SapphireMovieName, moc, fetchPred);
455                }
456        }               
457        [allFiles sortUsingFunction:fileAndLinkEpisodeCompare context:nil];
458        [cachedFiles release];
459        cachedFiles = [[NSMutableArray alloc] init];
460        NSEnumerator *objEnum = [allFiles objectEnumerator];
461        SapphireFileMetaData *file;
462        while((file = [objEnum nextObject]) != nil)
463        {
464                NSString *name = [file.path lastPathComponent];
465                [cachedFiles addObject:name];
466                [cachedLookup setObject:file forKey:name];
467        }
468        [allFiles release];
469        [fetchedFiles release];
470        [linkedFiles release];
471       
472        NSMutableArray *allDirs = [fetchedDirs mutableCopy];
473        if(filterPredicate != nil)
474        {
475                int i, count = [allDirs count];
476                for(i=0; i<count; i++)
477                {
478                        SapphireDirectoryMetaData *dir = [allDirs objectAtIndex:i];
479                        if(filterPredicate != [SapphireApplianceController unfilteredPredicate] && ![dir containsFileMatchingFilterPredicate:filterPredicate])
480                        {
481                                [allDirs removeObjectAtIndex:i];
482                                i--;
483                                count--;
484                        }
485                        else
486                        {
487                                [dir setFilterPredicate:filterPredicate];
488                        }
489                }
490        }
491        if(filterPredicate != nil)
492        {
493                int i, count = [linkedDirs count];
494                for(i=0; i<count; i++)
495                {
496                        SapphireDirectorySymLink *link = [linkedDirs objectAtIndex:i];
497                        SapphireDirectoryMetaData *dir = [link directory];
498                        if([dir containsFileMatchingFilterPredicate:filterPredicate])
499                        {
500                                [allDirs addObject:link];
501                                [dir setFilterPredicate:filterPredicate];
502                        }
503                }
504        }
505        else
506                [allDirs addObjectsFromArray:linkedDirs];
507        [allDirs sortUsingFunction:dirAndLinkPathCompare context:nil];
508        [cachedDirs release];
509        cachedDirs = [[NSMutableArray alloc] init];
510        objEnum = [allDirs objectEnumerator];
511        SapphireDirectoryMetaData *dir;
512        while((dir = [objEnum nextObject]) != nil)
513        {
514                NSString *name = [dir.path lastPathComponent];
515                [cachedDirs addObject:name];
516                [cachedLookup setObject:dir forKey:name];
517        }
518        [allDirs release];
519        [fetchedDirs release];
520        [linkedDirs release];
521        [delegate directoryContentsChanged];
522}
523
524- (NSString *)coverArtPathUpToParents:(int)parents
525{
526        NSString *ret = searchCoverArtExtForPath([[self path] stringByAppendingPathComponent:@"Cover Art/cover"]);
527        if(ret != nil)
528                return ret;
529       
530        ret = searchCoverArtExtForPath([[self path] stringByAppendingPathComponent:@"cover"]);
531        if(ret != nil)
532                return ret;
533       
534        if(parents != 0)
535                return [[self parent] coverArtPathUpToParents:parents-1];
536        return nil;
537}
538
539- (NSString *)coverArtPath
540{
541        return [self coverArtPathUpToParents:2];
542}
543
544- (void)invokeOnAllFiles:(NSInvocation *)fileInv
545{
546        NSManagedObjectContext *moc = [self managedObjectContext];
547        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"path BEGINSWITH %@", [self.path stringByAppendingString:@"/"]];
548        if(filterPredicate != nil)
549                predicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:predicate, filterPredicate, nil]];
550        NSArray *array = doFetchRequest(SapphireFileMetaDataName, moc, predicate);
551
552        if([array count])
553        {
554                SapphireFileMetaData *file;
555                NSEnumerator *fileEnum = [array objectEnumerator];
556                while((file = [fileEnum nextObject]) != nil)
557                {
558                        [fileInv invokeWithTarget:file];
559                }
560        }
561}
562
563- (BOOL)checkPredicate:(NSPredicate *)pred
564{
565        NSMutableSet *dupSet = [[NSMutableSet alloc] init];
566        BOOL ret = [self checkPredicate:pred duplicateSet:dupSet];
567        [dupSet release];
568        return ret;
569}
570
571- (void)conductScanWithDelegate:(id <SapphireMetaDataScannerDelegate>)subDelegate skipDirectories:(NSMutableSet *)skip andResults:(BOOL)results
572{
573        /*Scan dir and create scanner*/
574        SapphireMetaDataScanner *scanner = [[SapphireMetaDataScanner alloc] initWithDirectoryMetaData:self delegate:subDelegate];
575       
576        NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat:@"path BEGINSWITH %@", [self.path stringByAppendingString:@"/"]];
577        NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"path" ascending:YES];
578        NSManagedObjectContext *moc = [self managedObjectContext];
579        NSArray *dirs = doSortedFetchRequest(SapphireDirectoryMetaDataName, moc, fetchPredicate, sort);
580        NSArray *files = doSortedFetchRequest(SapphireFileMetaDataName, moc, fetchPredicate, sort);
581        NSArray *symDirs = doSortedFetchRequest(SapphireDirectorySymLinkName, moc, fetchPredicate, sort);
582        NSArray *symFiles = doSortedFetchRequest(SapphireFileSymLinkName, moc, fetchPredicate, sort);
583        [sort release];
584       
585        [scanner setSubDirs:dirs files:files symDirs:symDirs symFiles:symFiles];
586       
587        /*Add ourselves to not rescan*/
588        [skip addObject:self.path];
589        [scanner setSkipDirectories:skip];
590        /*We want results*/
591        [scanner setGivesResults:results];
592        [scanner release];
593}
594
595- (void)getSubFileMetasWithDelegate:(id <SapphireMetaDataScannerDelegate>)subDelegate skipDirectories:(NSMutableSet *)skip
596{
597        [self conductScanWithDelegate:subDelegate skipDirectories:skip andResults:YES];
598}
599
600- (void)scanForNewFilesWithDelegate:(id <SapphireMetaDataScannerDelegate>)subDelegate skipDirectories:(NSMutableSet *)skip
601{
602        [self conductScanWithDelegate:subDelegate skipDirectories:skip andResults:NO];
603}
604
605- (void)processNextFile
606{
607        if(![importArray count])
608        {
609                importing &= ~2;
610                return;
611        }
612        SapphireFileMetaData *file = [importArray objectAtIndex:0];
613       
614        /*Get the file and update it*/
615        importing |= 2;
616        [[SapphireImportHelper sharedHelperForContext:[self managedObjectContext]] importAllData:file inform:self];
617}
618
619- (oneway void)informComplete:(BOOL)updated
620{
621        /*Tell delegate we updated*/
622        [SapphireMetaDataSupport save:[self managedObjectContext]];
623        SapphireFileMetaData *file = [importArray objectAtIndex:0];
624        [delegate updateCompleteForFile:[[file path] lastPathComponent]];
625       
626        /*Remove from list and redo timer*/
627        [importArray removeObjectAtIndex:0];
628        if(importing & 1)
629                [self processNextFile];
630        else
631                importing = 0;
632}
633
634- (void)cancelImport
635{
636        importing &= ~1;
637}
638
639- (void)resumeImport
640{
641        importing |= 1;
642        if(!(importing & 2) && ![self isDeleted])
643                [self processNextFile];
644}
645
646- (void)faultAllObjects
647{
648        if([self isFault] || delegate != nil)
649                return;
650        NSManagedObjectContext *moc = [self managedObjectContext];
651        NSEnumerator *objEnum;
652        NSManagedObject *obj;
653       
654        objEnum = [self.metaFilesSet objectEnumerator];
655        while((obj = [objEnum nextObject]) != nil)
656                [obj faultOjbectInContext:moc];
657       
658        objEnum = [self.metaDirsSet objectEnumerator];
659        while((obj = [objEnum nextObject]) != nil)
660                [obj faultOjbectInContext:moc];
661       
662        objEnum = [self.linkedFilesSet objectEnumerator];
663        while((obj = [objEnum nextObject]) != nil)
664        {
665                SapphireFileSymLink *link = (SapphireFileSymLink *)obj;
666                if(![link isFault])
667                {
668                        [link.file faultOjbectInContext:moc];
669                        [link faultOjbectInContext:moc];
670                }
671        }
672       
673        objEnum = [self.linkedDirsSet objectEnumerator];
674        while((obj = [objEnum nextObject]) != nil)
675        {
676                SapphireDirectorySymLink *link = (SapphireDirectorySymLink *)obj;
677                if(![link isFault])
678                {
679                        [link.directory faultOjbectInContext:moc];
680                        [link faultOjbectInContext:moc];
681                }
682        }
683       
684        [self faultOjbectInContext:moc];
685}
686
687- (id <SapphireDirectory>)parentDirectory
688{
689        return self.parent;
690}
691
692#define RECURSIVE_FUNCTIONS_ALREADY_DEFINED
693#include "SapphireBasicDirectoryFunctions.h"
694
695@end
Note: See TracBrowser for help on using the repository browser.