XML playlists now store album art in an MD5 hash indexed dictionary, but continue to read the older format for backwards compatibility
parent
555ccc9e87
commit
754a22166a
|
@ -144,6 +144,8 @@
|
|||
56C63D910D647DF300EAE25A /* NSComparisonPredicate+CogPredicate.m in Sources */ = {isa = PBXBuildFile; fileRef = 56C63D900D647DF300EAE25A /* NSComparisonPredicate+CogPredicate.m */; };
|
||||
56DB084C0D6717DC00453B6A /* NSNumber+CogSort.m in Sources */ = {isa = PBXBuildFile; fileRef = 56DB084B0D6717DC00453B6A /* NSNumber+CogSort.m */; };
|
||||
56DB08550D67185300453B6A /* NSArray+CogSort.m in Sources */ = {isa = PBXBuildFile; fileRef = 56DB08540D67185300453B6A /* NSArray+CogSort.m */; };
|
||||
8355D6B6180612F300D05687 /* NSData+MD5.m in Sources */ = {isa = PBXBuildFile; fileRef = 8355D6B5180612F300D05687 /* NSData+MD5.m */; };
|
||||
8355D6B8180613FB00D05687 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8355D6B7180613FB00D05687 /* Security.framework */; };
|
||||
8359009D17FF06570060F3ED /* ArchiveSource.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8359FF3117FEF35D0060F3ED /* ArchiveSource.bundle */; };
|
||||
8360EF6D17F92E56005208A4 /* HighlyComplete.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8360EF0517F92B24005208A4 /* HighlyComplete.bundle */; };
|
||||
8375B36517FFEF130092A79F /* Opus.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8375B05717FFEA410092A79F /* Opus.bundle */; };
|
||||
|
@ -746,6 +748,9 @@
|
|||
56DB084B0D6717DC00453B6A /* NSNumber+CogSort.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSNumber+CogSort.m"; path = "Spotlight/NSNumber+CogSort.m"; sourceTree = "<group>"; };
|
||||
56DB08530D67185300453B6A /* NSArray+CogSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+CogSort.h"; path = "Spotlight/NSArray+CogSort.h"; sourceTree = "<group>"; };
|
||||
56DB08540D67185300453B6A /* NSArray+CogSort.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSArray+CogSort.m"; path = "Spotlight/NSArray+CogSort.m"; sourceTree = "<group>"; };
|
||||
8355D6B4180612F300D05687 /* NSData+MD5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+MD5.h"; sourceTree = "<group>"; };
|
||||
8355D6B5180612F300D05687 /* NSData+MD5.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+MD5.m"; sourceTree = "<group>"; };
|
||||
8355D6B7180613FB00D05687 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
||||
8359FF2C17FEF35C0060F3ED /* ArchiveSource.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ArchiveSource.xcodeproj; path = Plugins/ArchiveSource/ArchiveSource.xcodeproj; sourceTree = "<group>"; };
|
||||
8360EF0017F92B23005208A4 /* HighlyComplete.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HighlyComplete.xcodeproj; path = Plugins/HighlyComplete/HighlyComplete.xcodeproj; sourceTree = "<group>"; };
|
||||
8375B05117FFEA400092A79F /* Opus.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Opus.xcodeproj; path = Plugins/Opus/Opus.xcodeproj; sourceTree = "<group>"; };
|
||||
|
@ -789,6 +794,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8355D6B8180613FB00D05687 /* Security.framework in Frameworks */,
|
||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
|
||||
8E6889240AAA403C00AD3950 /* Carbon.framework in Frameworks */,
|
||||
17BB5CED0B8A86010009ACB1 /* AudioToolbox.framework in Frameworks */,
|
||||
|
@ -956,6 +962,8 @@
|
|||
07E18DF20D62B38400BB0E11 /* NSArray+ShuffleUtils.m */,
|
||||
17FAEBAA0F662985007C8707 /* ToolTipTextField.h */,
|
||||
17FAEBAB0F662985007C8707 /* ToolTipTextField.m */,
|
||||
8355D6B4180612F300D05687 /* NSData+MD5.h */,
|
||||
8355D6B5180612F300D05687 /* NSData+MD5.m */,
|
||||
);
|
||||
path = Utils;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1307,6 +1315,7 @@
|
|||
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8355D6B7180613FB00D05687 /* Security.framework */,
|
||||
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
|
||||
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
|
||||
);
|
||||
|
@ -1900,6 +1909,7 @@
|
|||
1770429C0B8BC53600B86321 /* AppController.m in Sources */,
|
||||
1770429E0B8BC53600B86321 /* PlaybackController.m in Sources */,
|
||||
1766C6930B911DF1004A7AE4 /* AudioScrobbler.m in Sources */,
|
||||
8355D6B6180612F300D05687 /* NSData+MD5.m in Sources */,
|
||||
1766C6950B911DF1004A7AE4 /* AudioScrobblerClient.m in Sources */,
|
||||
1755E1F90BA0D2B600CA3560 /* PlaylistLoader.m in Sources */,
|
||||
8E9A30160BA792DC0091081B /* NSFileHandle+CreateFile.m in Sources */,
|
||||
|
|
|
@ -255,18 +255,7 @@
|
|||
|
||||
- (void)setAlbumArt:(id)data
|
||||
{
|
||||
BOOL isData = NO;
|
||||
Class class = [data class];
|
||||
while (class)
|
||||
{
|
||||
if (class == [NSData class])
|
||||
{
|
||||
isData = YES;
|
||||
break;
|
||||
}
|
||||
class = [class superclass];
|
||||
}
|
||||
if (isData)
|
||||
if ([data isKindOfClass:[NSData class]])
|
||||
{
|
||||
[self setAlbumArtInternal:data];
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#import "XMlContainer.h"
|
||||
|
||||
#import "NSData+MD5.h"
|
||||
|
||||
@implementation PlaylistLoader
|
||||
|
||||
- (id)init
|
||||
|
@ -203,6 +205,8 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
|||
|
||||
NSArray * filterList = [NSArray arrayWithObjects:@"display", @"length", @"path", @"filename", @"status", @"statusMessage", @"spam", @"stopAfter", @"shuffleIndex", @"index", @"current", @"queued", @"currentPosition", @"queuePosition", @"error", @"removed", @"URL", @"albumArt", nil];
|
||||
|
||||
NSMutableDictionary * albumArtSet = [[NSMutableDictionary alloc] init];
|
||||
|
||||
NSMutableArray * topLevel = [[NSMutableArray alloc] init];
|
||||
|
||||
for (PlaylistEntry *pe in [playlistController content])
|
||||
|
@ -215,8 +219,11 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
|||
NSData * albumArt = [dict objectForKey:@"albumArtInternal"];
|
||||
if (albumArt)
|
||||
{
|
||||
[dict setObject:albumArt forKey:@"albumArt"];
|
||||
[dict removeObjectForKey:@"albumArtInternal"];
|
||||
NSString * hash = [albumArt MD5];
|
||||
if (![albumArtSet objectForKey:hash])
|
||||
[albumArtSet setObject:albumArt forKey:hash];
|
||||
[dict setObject:hash forKey:@"albumArt"];
|
||||
}
|
||||
|
||||
[topLevel addObject:dict];
|
||||
|
@ -224,7 +231,13 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
|||
[dict release];
|
||||
}
|
||||
|
||||
NSData * data = [NSPropertyListSerialization dataWithPropertyList:topLevel format:NSPropertyListXMLFormat_v1_0 options:0 error:0];
|
||||
NSDictionary * dictionary = [NSDictionary dictionaryWithObjectsAndKeys:albumArtSet, @"albumArt", topLevel, @"items", nil];
|
||||
|
||||
NSData * data = [NSPropertyListSerialization dataWithPropertyList:dictionary format:NSPropertyListXMLFormat_v1_0 options:0 error:0];
|
||||
|
||||
[albumArtSet release];
|
||||
|
||||
[topLevel release];
|
||||
|
||||
[fileHandle writeData:data];
|
||||
|
||||
|
|
|
@ -70,15 +70,23 @@
|
|||
NSData* plistData = [contents dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
NSPropertyListFormat format;
|
||||
NSArray* plist = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
|
||||
id plist = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
|
||||
if(!plist){
|
||||
NSLog(@"Error: %@",error);
|
||||
[error release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
BOOL isArray = [plist isKindOfClass:[NSArray class]];
|
||||
BOOL isDict = [plist isKindOfClass:[NSDictionary class]];
|
||||
|
||||
if (!isDict && !isArray) return nil;
|
||||
|
||||
NSArray * items = (isArray) ? (NSArray*)plist : [(NSDictionary *)plist objectForKey:@"items"];
|
||||
|
||||
NSDictionary *entry;
|
||||
NSEnumerator *e = [plist objectEnumerator];
|
||||
NSDictionary *albumArt = (isArray) ? nil : [(NSDictionary *)plist objectForKey:@"albumArt"];
|
||||
NSEnumerator *e = [items objectEnumerator];
|
||||
NSMutableArray *entries = [NSMutableArray array];
|
||||
|
||||
while ((entry = [e nextObject]))
|
||||
|
@ -87,6 +95,9 @@
|
|||
|
||||
[preparedEntry setObject:[self urlForPath:[preparedEntry objectForKey:@"URL"] relativeTo:filename] forKey:@"URL"];
|
||||
|
||||
if (albumArt && [preparedEntry objectForKey:@"albumArt"])
|
||||
[preparedEntry setObject:[albumArt objectForKey:[preparedEntry objectForKey:@"albumArt"]] forKey:@"albumArt"];
|
||||
|
||||
[entries addObject:[NSDictionary dictionaryWithDictionary:preparedEntry]];
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// NSData+MD5.h
|
||||
// Cog
|
||||
//
|
||||
// Created by Christopher Snowhill on 10/9/13.
|
||||
//
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface NSData (MD5)
|
||||
|
||||
- (NSString*)MD5;
|
||||
|
||||
@end
|
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// NSData+MD5.m
|
||||
// Cog
|
||||
//
|
||||
// Created by Christopher Snowhill on 10/9/13.
|
||||
//
|
||||
//
|
||||
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
|
||||
#import "NSData+MD5.h"
|
||||
|
||||
@implementation NSData (MD5)
|
||||
|
||||
- (NSString*)MD5
|
||||
{
|
||||
// Create pointer to the string as UTF8
|
||||
const void * ptr = [self bytes];
|
||||
NSUInteger len = [self length];
|
||||
|
||||
// Create byte array of unsigned chars
|
||||
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
|
||||
|
||||
// Create 16 byte MD5 hash value, store in buffer
|
||||
CC_MD5(ptr, len, md5Buffer);
|
||||
|
||||
// Convert MD5 value in the buffer to NSString of hex values
|
||||
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
|
||||
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
|
||||
[output appendFormat:@"%02x",md5Buffer[i]];
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@end
|
Loading…
Reference in New Issue