cog/Playlist/XmlContainer.m

125 lines
3.7 KiB
Objective-C

//
// XmlContainer.m
// Xml
//
// Created by Christopher Snowhill on 10/9/13.
// Copyright 2013 __NoWork, Inc__. All rights reserved.
//
#import "XmlContainer.h"
#import "Logging.h"
#import "SandboxBroker.h"
@implementation XmlContainer
+ (NSURL *)urlForPath:(NSString *)path relativeTo:(NSString *)baseFilename {
NSRange protocolRange = [path rangeOfString:@"://"];
if(protocolRange.location != NSNotFound) {
return [NSURL URLWithString:path];
}
NSMutableString *unixPath = [path mutableCopy];
// Get the fragment
NSString *fragment = @"";
NSScanner *scanner = [NSScanner scannerWithString:unixPath];
NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@"#1234567890"];
while(![scanner isAtEnd]) {
NSString *possibleFragment;
[scanner scanUpToString:@"#" intoString:nil];
if([scanner scanCharactersFromSet:characterSet intoString:&possibleFragment] && [scanner isAtEnd]) {
fragment = possibleFragment;
[unixPath deleteCharactersInRange:NSMakeRange([scanner scanLocation] - [possibleFragment length], [possibleFragment length])];
break;
}
}
DLog(@"Fragment: %@", fragment);
if(![unixPath hasPrefix:@"/"]) {
// Only relative paths would have windows backslashes.
[unixPath replaceOccurrencesOfString:@"\\" withString:@"/" options:0 range:NSMakeRange(0, [unixPath length])];
NSString *basePath = [[[baseFilename stringByStandardizingPath] stringByDeletingLastPathComponent] stringByAppendingString:@"/"];
[unixPath insertString:basePath atIndex:0];
}
// Append the fragment
NSURL *url = [NSURL URLWithString:[[[NSURL fileURLWithPath:unixPath] absoluteString] stringByAppendingString:fragment]];
return url;
}
+ (NSDictionary *)entriesForContainerURL:(NSURL *)url {
if(![url isFileURL])
return nil;
NSError *error;
NSString *filename = [url path];
const void *sbHandle = [[SandboxBroker sharedSandboxBroker] beginFolderAccess:url];
NSString *contents = [NSString stringWithContentsOfFile:filename
encoding:NSUTF8StringEncoding
error:&error];
[[SandboxBroker sharedSandboxBroker] endFolderAccess:sbHandle];
if(!contents) {
ALog(@"Error: %@", error);
return nil;
}
NSData *plistData = [contents dataUsingEncoding:NSUTF8StringEncoding];
NSPropertyListFormat format;
id plist = [NSPropertyListSerialization propertyListWithData:plistData
options:NSPropertyListImmutable
format:&format
error:&error];
if(!plist) {
ALog(@"Error: %@", error);
return nil;
}
BOOL isArray = [plist isKindOfClass:[NSArray class]];
BOOL isDict = [plist isKindOfClass:[NSDictionary class]];
if(!isDict && !isArray) return nil;
NSArray *items;
NSDictionary *albumArt;
NSArray *queueList;
if(isArray) {
items = (NSArray *)plist;
albumArt = nil;
queueList = @[];
} else {
NSDictionary *dict = (NSDictionary *)plist;
items = dict[@"items"];
albumArt = dict[@"albumArt"];
queueList = dict[@"queue"];
if(!queueList) queueList = @[];
}
NSMutableArray *entries = [NSMutableArray array];
for(NSDictionary *entry in items) {
NSMutableDictionary *preparedEntry = [NSMutableDictionary dictionaryWithDictionary:entry];
preparedEntry[@"URL"] = [self urlForPath:preparedEntry[@"URL"] relativeTo:filename];
if(albumArt && preparedEntry[@"albumArt"])
preparedEntry[@"albumArt"] = albumArt[preparedEntry[@"albumArt"]];
[entries addObject:[NSDictionary dictionaryWithDictionary:preparedEntry]];
}
return @{ @"entries": entries, @"queue": queueList };
}
@end