source: branches/CoreData/SapphireFrappliance/MetaData/SapphireMObjects/SapphireCollectionDirectory.m @ 823

Revision 823, 7.0 KB checked in by gbooker, 5 years ago (diff)

Corrected a mutate error from mutating a set during enumeration.

Line 
1#import "SapphireCollectionDirectory.h"
2#import "SapphireDirectoryMetaData.h"
3#import "CoreDataSupportFunctions.h"
4#import "SapphireMetaDataSupport.h"
5#import "SapphireDirectorySymLink.h"
6#import "NSFileManager-Extensions.h"
7
8#include <sys/types.h>
9#include <sys/stat.h>
10#include <sys/mount.h>
11
12#define MOUNT_INFORMATION_KEY   @"mountInformation"
13#define MOUNT_INFORMATION_DATA  @"mountInformationData"
14
15@implementation SapphireCollectionDirectory
16
17+ (SapphireCollectionDirectory *)collectionAtPath:(NSString *)path mount:(BOOL)isMount skip:(BOOL)skip hidden:(BOOL)hidden manual:(BOOL)manual inContext:(NSManagedObjectContext *)moc
18{
19        SapphireDirectoryMetaData *dir = [SapphireDirectoryMetaData createDirectoryWithPath:path inContext:moc];
20        SapphireCollectionDirectory *ret = dir.collectionDirectory;
21        if(ret != nil)
22        {
23                if(isMount)
24                        ret.isMountValue = isMount;
25                return ret;
26        }
27       
28        ret = [NSEntityDescription insertNewObjectForEntityForName:SapphireCollectionDirectoryName inManagedObjectContext:moc];
29       
30        ret.manualCollectionValue = manual;
31        ret.isMountValue = isMount;
32        ret.skipValue = skip;
33        ret.hiddenValue = hidden;
34        ret.directory = dir;
35       
36        return ret;
37}
38
39+ (SapphireCollectionDirectory *)collectionAtPath:(NSString *)path inContext:(NSManagedObjectContext *)moc
40{
41        return [SapphireCollectionDirectory collectionAtPath:path mount:YES skip:NO hidden:NO manual:NO inContext:moc];
42}
43
44+ (SapphireCollectionDirectory *)upgradeV1CollectionDirectory:(NSManagedObject *)oldCol toContext:(NSManagedObjectContext *)newMoc
45{
46        SapphireCollectionDirectory *ret = [NSEntityDescription insertNewObjectForEntityForName:SapphireCollectionDirectoryName inManagedObjectContext:newMoc];
47        ret.hidden = [oldCol valueForKey:@"hidden"];
48        ret.isMount = [oldCol valueForKey:@"isMount"];
49        ret.manualCollection = [oldCol valueForKey:@"manualCollection"];
50        ret.skip = [oldCol valueForKey:@"skip"];
51       
52        return ret;
53}
54
55+ (NSString *)resolveSymLinksInCollectionPath:(NSString *)path inContext:(NSManagedObjectContext *)moc
56{
57        NSArray *components = [path pathComponents];
58        NSFileManager *fm = [NSFileManager defaultManager];
59       
60        NSEnumerator *pathCompEnum = [components objectEnumerator];
61        NSString *pathComp;
62        NSString *subPath = [pathCompEnum nextObject];  //Skip "/"
63        while((pathComp = [pathCompEnum nextObject]) != nil)
64        {
65                subPath = [subPath stringByAppendingPathComponent:pathComp];
66                if([fm isDirectory:subPath])
67                {
68                        NSDictionary *attributes = [fm fileAttributesAtPath:subPath traverseLink:NO];
69                        if([[attributes fileType] isEqualToString:NSFileTypeSymbolicLink])
70                        {
71                                SapphireDirectoryMetaData *dir = [SapphireDirectoryMetaData directoryWithPath:subPath inContext:moc];
72                                if(dir != nil)
73                                {
74                                        NSString *resolvedPath = [subPath stringByResolvingSymlinksInPath];
75                                        SapphireDirectoryMetaData *redundant = [SapphireDirectoryMetaData directoryWithPath:resolvedPath inContext:moc];
76                                        if(redundant != nil)
77                                                [moc deleteObject:redundant];
78                                        [dir setPath:resolvedPath];
79                                        [SapphireDirectorySymLink createDirectoryLinkWithPath:subPath toPath:resolvedPath inContext:moc];
80                                }
81                        }
82                }
83        }
84        return [path stringByResolvingSymlinksInPath];
85}
86
87+ (NSArray *)availableCollectionDirectoriesInContext:(NSManagedObjectContext *)moc
88{
89        NSFileManager *fm = [NSFileManager defaultManager];
90        NSMutableSet *colSet = [NSMutableSet set];
91    struct statfs *mntbufp;
92       
93        NSMutableSet *dvds = [NSMutableSet set];
94        NSEnumerator *dvdEnum = [[NSClassFromString(@"BRDiskArbHandler") mountedDVDs] objectEnumerator];
95        BRDiskInfo *dvdInfo;
96        while((dvdInfo = [dvdEnum nextObject]) != nil)
97                [dvds addObject:[dvdInfo mountpoint]];
98       
99    int i, mountCount = getmntinfo(&mntbufp, MNT_NOWAIT);
100        for(i=0; i<mountCount; i++)
101        {
102                if(!strcmp(mntbufp[i].f_fstypename, "autofs"))
103                        continue;
104                if(!strcmp(mntbufp[i].f_fstypename, "volfs"))
105                        continue;
106                if(!strcmp(mntbufp[i].f_mntonname, "/dev"))
107                        continue;
108                [colSet addObject:[fm stringWithFileSystemRepresentation:mntbufp[i].f_mntonname length:strlen(mntbufp[i].f_mntonname)]];
109        }
110        [colSet removeObject:@"/mnt"];
111        [colSet removeObject:@"/CIFS"];
112        [colSet removeObject:NSHomeDirectory()];
113        NSString *homeMoviesPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Movies"];
114        if([[NSFileManager defaultManager] fileExistsAtPath:homeMoviesPath])
115                [colSet addObject:homeMoviesPath];
116        NSEnumerator *mountEnum = [[NSSet setWithSet:colSet] objectEnumerator];
117        NSString *mountPoint;
118        while((mountPoint = [mountEnum nextObject]) != nil)
119        {
120                if([dvds containsObject:mountPoint])
121                        //Don't show DVDs as collections
122                        continue;
123                NSString *newPath = [SapphireCollectionDirectory resolveSymLinksInCollectionPath:mountPoint inContext:moc];
124                [SapphireCollectionDirectory collectionAtPath:newPath mount:YES skip:NO hidden:NO manual:NO inContext:moc];
125                if(![newPath isEqualToString:mountPoint])
126                {
127                        [colSet removeObject:mountPoint];
128                        [colSet addObject:newPath];
129                }
130        }
131       
132        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(hidden == NO) AND ((manualCollection == YES) OR (directory.path IN %@))", colSet];
133        NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"directory.path" ascending:YES];
134        NSArray *ret = doSortedFetchRequest(SapphireCollectionDirectoryName, moc, predicate, sort);
135
136        [sort release];
137        return ret;
138}
139
140+ (NSArray *)skippedCollectionDirectoriesInContext:(NSManagedObjectContext *)moc
141{
142        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"skip == YES"];
143        NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"directory.path" ascending:YES];
144        NSArray *ret = doSortedFetchRequest(SapphireCollectionDirectoryName, moc, predicate, sort);
145       
146        [sort release];
147        return ret;
148}
149
150+ (NSArray *)allCollectionsInContext:(NSManagedObjectContext *)moc
151{
152        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(manualCollection == YES) OR (isMount == YES)"];
153        NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"directory.path" ascending:YES];
154        NSArray *ret = doSortedFetchRequest(SapphireCollectionDirectoryName, moc, predicate, sort);
155       
156        [sort release];
157        return ret;
158}
159
160- (BOOL)deleteValue
161{
162        return toDelete;
163}
164
165- (void)setDeleteValue:(BOOL)del
166{
167        toDelete = del;
168}
169
170- (NSString *)rename:(NSString *)name
171{
172        self.name = name;
173        [SapphireMetaDataSupport save:[self managedObjectContext]];
174        return nil;
175}
176
177- (NSString *)name
178{
179        NSString *name = super.name;
180        if(name == nil)
181                return [self.directory path];
182        return name;
183}
184
185- (NSDictionary *)mountInformation
186{
187        [self willAccessValueForKey:MOUNT_INFORMATION_KEY];
188        NSDictionary *ret = [self primitiveValueForKey:MOUNT_INFORMATION_KEY];
189        [self didAccessValueForKey:MOUNT_INFORMATION_KEY];
190        if(ret == nil)
191        {
192                NSData *propData = [self valueForKey:MOUNT_INFORMATION_DATA];
193                if(propData != nil)
194                {
195                        ret = [NSKeyedUnarchiver unarchiveObjectWithData:propData];
196                        [self setPrimitiveValue:ret forKey:MOUNT_INFORMATION_KEY];
197                }
198        }
199        return ret;
200}
201
202- (void)setMountInformation:(NSDictionary *)info
203{
204        [self willChangeValueForKey:MOUNT_INFORMATION_KEY];
205        [self setPrimitiveValue:info forKey:MOUNT_INFORMATION_KEY];
206        [self didChangeValueForKey:MOUNT_INFORMATION_KEY];
207        [self setValue:[NSKeyedArchiver archivedDataWithRootObject:info] forKey:MOUNT_INFORMATION_DATA];
208}
209
210@end
Note: See TracBrowser for help on using the repository browser.