From 88aecc7de210787aa1b15114de6959b0816a1307 Mon Sep 17 00:00:00 2001 From: vspader Date: Tue, 9 Oct 2007 01:20:46 +0000 Subject: [PATCH] Added AudioContainer plugin and made pls and m3u loaders that use it. --- Application/AppController.m | 2 +- Audio/AudioContainer.h | 18 ++ Audio/AudioContainer.m | 20 ++ Audio/AudioDecoder.m | 8 +- Audio/AudioMetadataReader.m | 9 +- Audio/AudioPlayer.h | 1 + Audio/AudioPlayer.m | 8 +- Audio/AudioPropertiesReader.m | 17 +- Audio/AudioSource.h | 2 +- Audio/AudioSource.m | 10 +- Audio/CogAudio.xcodeproj/project.pbxproj | 8 + Audio/Plugin.h | 17 +- Audio/PluginController.h | 7 +- Audio/PluginController.m | 86 +++++- Cog.xcodeproj/project.pbxproj | 86 ++++++ Playlist/PlaylistLoader.h | 7 +- Playlist/PlaylistLoader.m | 100 +------ Plugins/Flac/FlacDecoder.m | 2 +- Plugins/M3u/English.lproj/InfoPlist.strings | Bin 0 -> 204 bytes Plugins/M3u/Info.plist | 26 ++ Plugins/M3u/M3u.xcodeproj/project.pbxproj | 276 ++++++++++++++++++++ Plugins/M3u/M3uContainer.h | 17 ++ Plugins/M3u/M3uContainer.m | 70 +++++ Plugins/M3u/M3uPlugin.h | 17 ++ Plugins/M3u/M3uPlugin.m | 20 ++ Plugins/M3u/M3u_Prefix.pch | 7 + Plugins/Pls/English.lproj/InfoPlist.strings | Bin 0 -> 204 bytes Plugins/Pls/Info.plist | 26 ++ Plugins/Pls/Pls.xcodeproj/project.pbxproj | 273 +++++++++++++++++++ Plugins/Pls/PlsContainer.h | 17 ++ Plugins/Pls/PlsContainer.m | 81 ++++++ Plugins/Pls/PlsPlugin.h | 17 ++ Plugins/Pls/PlsPlugin.m | 20 ++ Plugins/Pls/Pls_Prefix.pch | 7 + Plugins/TagLib/TagLibMetadataReader.m | 2 +- 35 files changed, 1137 insertions(+), 147 deletions(-) create mode 100644 Audio/AudioContainer.h create mode 100644 Audio/AudioContainer.m create mode 100644 Plugins/M3u/English.lproj/InfoPlist.strings create mode 100644 Plugins/M3u/Info.plist create mode 100644 Plugins/M3u/M3u.xcodeproj/project.pbxproj create mode 100644 Plugins/M3u/M3uContainer.h create mode 100644 Plugins/M3u/M3uContainer.m create mode 100644 Plugins/M3u/M3uPlugin.h create mode 100644 Plugins/M3u/M3uPlugin.m create mode 100644 Plugins/M3u/M3u_Prefix.pch create mode 100644 Plugins/Pls/English.lproj/InfoPlist.strings create mode 100644 Plugins/Pls/Info.plist create mode 100644 Plugins/Pls/Pls.xcodeproj/project.pbxproj create mode 100644 Plugins/Pls/PlsContainer.h create mode 100644 Plugins/Pls/PlsContainer.m create mode 100644 Plugins/Pls/PlsPlugin.h create mode 100644 Plugins/Pls/PlsPlugin.m create mode 100644 Plugins/Pls/Pls_Prefix.pch diff --git a/Application/AppController.m b/Application/AppController.m index 519e96269..ddd6c3c0b 100644 --- a/Application/AppController.m +++ b/Application/AppController.m @@ -150,7 +150,7 @@ increase/decrease as long as the user holds the left/right, plus/minus button */ p = [NSSavePanel savePanel]; - [p setAllowedFileTypes:[playlistLoader acceptablePlaylistTypes]]; + [p setAllowedFileTypes:[playlistLoader acceptableContainerTypes]]; [p beginSheetForDirectory:nil file:nil modalForWindow:mainWindow modalDelegate:self didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:NULL]; } diff --git a/Audio/AudioContainer.h b/Audio/AudioContainer.h new file mode 100644 index 000000000..36a0ece7a --- /dev/null +++ b/Audio/AudioContainer.h @@ -0,0 +1,18 @@ +// +// AudioContainer.h +// CogAudio +// +// Created by Zaphod Beeblebrox on 10/8/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import +#import "Plugin.h" + +@interface AudioContainer : NSObject { + +} + ++ (NSArray *) urlsForContainerURL:(NSURL *)url; + +@end diff --git a/Audio/AudioContainer.m b/Audio/AudioContainer.m new file mode 100644 index 000000000..3025038c0 --- /dev/null +++ b/Audio/AudioContainer.m @@ -0,0 +1,20 @@ +// +// AudioContainer.m +// CogAudio +// +// Created by Zaphod Beeblebrox on 10/8/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "AudioContainer.h" + +#import "PluginController.h" + +@implementation AudioContainer + ++ (NSArray *) urlsForContainerURL:(NSURL *)url +{ + return [[PluginController sharedPluginController] urlsForContainerURL:url]; +} + +@end diff --git a/Audio/AudioDecoder.m b/Audio/AudioDecoder.m index 70521e8c6..a2673721d 100644 --- a/Audio/AudioDecoder.m +++ b/Audio/AudioDecoder.m @@ -14,13 +14,7 @@ + (id) audioDecoderForURL:(NSURL *)url { - NSString *ext = [[url path] pathExtension]; - - NSDictionary *decoders = [[PluginController sharedPluginController] decoders]; - - Class decoder = NSClassFromString([decoders objectForKey:[ext lowercaseString]]); - - return [[[decoder alloc] init] autorelease]; + return [[PluginController sharedPluginController] audioDecoderForURL:url]; } @end diff --git a/Audio/AudioMetadataReader.m b/Audio/AudioMetadataReader.m index c99631e1d..b0d49f648 100644 --- a/Audio/AudioMetadataReader.m +++ b/Audio/AudioMetadataReader.m @@ -13,14 +13,7 @@ + (NSDictionary *)metadataForURL:(NSURL *)url { - NSString *ext = [[url path] pathExtension]; - - NSDictionary *metadataReaders = [[PluginController sharedPluginController] metadataReaders]; - - Class metadataReader = NSClassFromString([metadataReaders objectForKey:[ext lowercaseString]]); - - return [[[[metadataReader alloc] init] autorelease] metadataForURL:url]; - + return [[PluginController sharedPluginController] metadataForURL:url]; } @end diff --git a/Audio/AudioPlayer.h b/Audio/AudioPlayer.h index a26c12b24..af08df3cc 100644 --- a/Audio/AudioPlayer.h +++ b/Audio/AudioPlayer.h @@ -48,6 +48,7 @@ + (NSArray *)fileTypes; + (NSArray *)schemes; ++ (NSArray *)containerTypes; @end diff --git a/Audio/AudioPlayer.m b/Audio/AudioPlayer.m index 3d01636c0..9bd2e2ccc 100644 --- a/Audio/AudioPlayer.m +++ b/Audio/AudioPlayer.m @@ -270,16 +270,23 @@ return output; } ++ (NSArray *)containerTypes +{ + return [[[PluginController sharedPluginController] containers] allKeys]; +} + + (NSArray *)fileTypes { PluginController *pluginController = [PluginController sharedPluginController]; + NSArray *containerTypes = [[pluginController containers] allKeys]; NSArray *decoderTypes = [[pluginController decoders] allKeys]; NSArray *metdataReaderTypes = [[pluginController metadataReaders] allKeys]; NSArray *propertiesReaderTypes = [[pluginController propertiesReaders] allKeys]; NSMutableSet *types = [NSMutableSet set]; + [types addObjectsFromArray:containerTypes]; [types addObjectsFromArray:decoderTypes]; [types addObjectsFromArray:metdataReaderTypes]; [types addObjectsFromArray:propertiesReaderTypes]; @@ -294,5 +301,4 @@ return [[pluginController sources] allKeys]; } - @end diff --git a/Audio/AudioPropertiesReader.m b/Audio/AudioPropertiesReader.m index 506f19593..f82da3887 100644 --- a/Audio/AudioPropertiesReader.m +++ b/Audio/AudioPropertiesReader.m @@ -15,22 +15,7 @@ + (NSDictionary *)propertiesForURL:(NSURL *)url { - NSString *ext = [[url path] pathExtension]; - - id source = [AudioSource audioSourceForURL:url]; - if (![source open:url]) - return nil; - - NSDictionary *propertiesReaders = [[PluginController sharedPluginController] propertiesReaders]; - - Class propertiesReader = NSClassFromString([propertiesReaders objectForKey:[ext lowercaseString]]); - - NSDictionary *properties = [propertiesReader propertiesForSource:source]; - - [source close]; - - return properties; - + return [[PluginController sharedPluginController] propertiesForURL:url]; } @end diff --git a/Audio/AudioSource.h b/Audio/AudioSource.h index aeb1758ec..00b1ffcff 100644 --- a/Audio/AudioSource.h +++ b/Audio/AudioSource.h @@ -13,6 +13,6 @@ @interface AudioSource : NSObject { } -+ audioSourceForURL:(NSURL *)url; ++ (id) audioSourceForURL:(NSURL *)url; @end diff --git a/Audio/AudioSource.m b/Audio/AudioSource.m index b6db2edc5..5ec2d74a1 100644 --- a/Audio/AudioSource.m +++ b/Audio/AudioSource.m @@ -11,15 +11,9 @@ @implementation AudioSource -+ audioSourceForURL:(NSURL *)url ++ (id) audioSourceForURL:(NSURL *)url { - NSString *scheme = [url scheme]; - - NSDictionary *sources = [[PluginController sharedPluginController] sources]; - - Class source = NSClassFromString([sources objectForKey:scheme]); - - return [[[source alloc] init] autorelease]; + return [[PluginController sharedPluginController] audioSourceForURL:url]; } @end diff --git a/Audio/CogAudio.xcodeproj/project.pbxproj b/Audio/CogAudio.xcodeproj/project.pbxproj index 5e590ce00..d212c47f5 100644 --- a/Audio/CogAudio.xcodeproj/project.pbxproj +++ b/Audio/CogAudio.xcodeproj/project.pbxproj @@ -44,6 +44,8 @@ 17F94DD60B8D0F7000A34E87 /* PluginController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17F94DD40B8D0F7000A34E87 /* PluginController.m */; }; 17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DDC0B8D101100A34E87 /* Plugin.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; + 8E8D3D2F0CBAEE6E00135C1B /* AudioContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D3D2E0CBAEE6E00135C1B /* AudioContainer.m */; }; 8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EC1225D0B993BD500C5B3AD /* ConverterNode.h */; }; 8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EC1225E0B993BD500C5B3AD /* ConverterNode.m */; }; /* End PBXBuildFile section */ @@ -103,6 +105,8 @@ 32DBCF5E0370ADEE00C91783 /* CogAudio_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogAudio_Prefix.pch; sourceTree = ""; }; 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 8DC2EF5B0486A6940098B216 /* CogAudio.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CogAudio.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioContainer.h; sourceTree = ""; }; + 8E8D3D2E0CBAEE6E00135C1B /* AudioContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioContainer.m; sourceTree = ""; }; 8EC1225D0B993BD500C5B3AD /* ConverterNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ConverterNode.h; sourceTree = ""; }; 8EC1225E0B993BD500C5B3AD /* ConverterNode.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = ConverterNode.m; sourceTree = ""; }; D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; @@ -167,6 +171,8 @@ 17F94DDC0B8D101100A34E87 /* Plugin.h */, 17D21EBB0B8BF44000D1EBDE /* AudioPlayer.h */, 17D21EBC0B8BF44000D1EBDE /* AudioPlayer.m */, + 8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */, + 8E8D3D2E0CBAEE6E00135C1B /* AudioContainer.m */, 17A2D3C30B8D1D37000778C4 /* AudioDecoder.h */, 17A2D3C40B8D1D37000778C4 /* AudioDecoder.m */, 17C940210B900909008627D6 /* AudioMetadataReader.h */, @@ -305,6 +311,7 @@ 17B619300B909BC300BC003F /* AudioPropertiesReader.h in Headers */, 17ADB13C0B97926D00257CA2 /* AudioSource.h in Headers */, 8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */, + 8E8D3D2F0CBAEE6E00135C1B /* AudioContainer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -378,6 +385,7 @@ 17B619310B909BC300BC003F /* AudioPropertiesReader.m in Sources */, 17ADB13D0B97926D00257CA2 /* AudioSource.m in Sources */, 8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */, + 8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Audio/Plugin.h b/Audio/Plugin.h index c246b853e..e714a4a36 100644 --- a/Audio/Plugin.h +++ b/Audio/Plugin.h @@ -5,6 +5,7 @@ */ #define kCogSource @"CogSource" +#define kCogContainer @"CogContainer" #define kCogDecoder @"CogDecoder" #define kCogMetadataReader @"CogMetadataReader" #define kCogPropertiesReader @"CogPropertiesReader" @@ -28,6 +29,12 @@ - (void)close; @end +@protocol CogContainer ++ (NSArray *)fileTypes; //mp3, ogg, etc + ++ (NSArray *)urlsForContainerURL:(NSURL *)url; +@end + @protocol CogDecoder + (NSArray *)fileTypes; //mp3, ogg, etc @@ -43,7 +50,7 @@ @protocol CogMetadataReader + (NSArray *)fileTypes; -+ (NSDictionary *)metadataForURL; ++ (NSDictionary *)metadataForURL:(NSURL *)url; @end @protocol CogPropertiesReader @@ -51,5 +58,13 @@ + (NSDictionary *)propertiesForSource:(id)source; @end +@protocol CogPluginController +- (id) audioSourceForURL:(NSURL *)url; +- (NSArray *) urlsForContainerURL:(NSURL *)url; +- (id) audioDecoderForURL:(NSURL *)url; +- (NSDictionary *) metadataForURL:(NSURL *)url; +- (NSDictionary *) propertiesForURL:(NSURL *)url; +@end + diff --git a/Audio/PluginController.h b/Audio/PluginController.h index 456484347..0f5fd60cf 100644 --- a/Audio/PluginController.h +++ b/Audio/PluginController.h @@ -2,10 +2,13 @@ #import +#import "Plugin.h" + //Singleton -@interface PluginController : NSObject +@interface PluginController : NSObject { NSMutableDictionary *sources; + NSMutableDictionary *containers; NSMutableDictionary *decoders; NSMutableDictionary *metadataReaders; NSMutableDictionary *propertiesReaders; @@ -20,11 +23,13 @@ - (void)loadPluginsAtPath:(NSString *)path; - (void)setupSource:(NSString *)className; +- (void)setupContainer:(NSString *)className; - (void)setupDecoder:(NSString *)className; - (void)setupMetadataReader:(NSString *)className; - (void)setupPropertiesReader:(NSString *)className; - (NSDictionary *)sources; +- (NSDictionary *)containers; - (NSDictionary *)decoders; - (NSDictionary *)metadataReaders; - (NSDictionary *)propertiesReaders; diff --git a/Audio/PluginController.m b/Audio/PluginController.m index 4e8993de2..f793813d8 100644 --- a/Audio/PluginController.m +++ b/Audio/PluginController.m @@ -59,6 +59,7 @@ static PluginController *sharedPluginController = nil; self = [super init]; if (self) { sources = [[NSMutableDictionary alloc] init]; + containers = [[NSMutableDictionary alloc] init]; decoders = [[NSMutableDictionary alloc] init]; metadataReaders = [[NSMutableDictionary alloc] init]; propertiesReaders = [[NSMutableDictionary alloc] init]; @@ -105,7 +106,10 @@ static PluginController *sharedPluginController = nil; id className; while (className = [e nextObject]) { id pluginType = [pluginInfo objectForKey:className]; - if ([pluginType isEqualToString:kCogDecoder]) { + if ([pluginType isEqualToString:kCogContainer]) { + [self setupContainer:className]; + } + else if ([pluginType isEqualToString:kCogDecoder]) { [self setupDecoder:className]; } else if ([pluginType isEqualToString:kCogMetadataReader]) { @@ -133,6 +137,19 @@ static PluginController *sharedPluginController = nil; [self loadPluginsAtPath:[@"~/Library/Application Support/Cog/Plugins" stringByExpandingTildeInPath]]; } +- (void)setupContainer:(NSString *)className +{ + Class container = NSClassFromString(className); + if (container && [container respondsToSelector:@selector(fileTypes)]) { + NSEnumerator *fileTypesEnum = [[container fileTypes] objectEnumerator]; + id fileType; + while (fileType = [fileTypesEnum nextObject]) + { + [containers setObject:className forKey:[fileType lowercaseString]]; + } + } +} + - (void)setupDecoder:(NSString *)className { Class decoder = NSClassFromString(className); @@ -187,10 +204,11 @@ static PluginController *sharedPluginController = nil; - (void)printPluginInfo { -/* NSLog(@"Sources: %@", sources); - NSLog(@"Decoders: %@", decoders); - NSLog(@"Metadata Readers: %@", metadataReaders); - NSLog(@"Properties Readers: %@", propertiesReaders); */ + //NSLog(@"Sources: %@", sources); + //NSLog(@"Containers: %@", containers); + //NSLog(@"Decoders: %@", decoders); + //NSLog(@"Metadata Readers: %@", metadataReaders); + //NSLog(@"Properties Readers: %@", propertiesReaders); } - (NSDictionary *)sources @@ -198,6 +216,11 @@ static PluginController *sharedPluginController = nil; return sources; } +- (NSDictionary *)containers +{ + return containers; +} + - (NSDictionary *)decoders { return decoders; @@ -214,7 +237,60 @@ static PluginController *sharedPluginController = nil; } +- (id) audioSourceForURL:(NSURL *)url +{ + NSString *scheme = [url scheme]; + + Class source = NSClassFromString([sources objectForKey:scheme]); + + return [[[source alloc] init] autorelease]; +} +- (NSArray *) urlsForContainerURL:(NSURL *)url +{ + NSString *ext = [[url path] pathExtension]; + + Class container = NSClassFromString([containers objectForKey:[ext lowercaseString]]); + + return [container urlsForContainerURL:url]; +} + +- (id) audioDecoderForURL:(NSURL *)url +{ + NSString *ext = [[url path] pathExtension]; + + Class decoder = NSClassFromString([decoders objectForKey:[ext lowercaseString]]); + + return [[[decoder alloc] init] autorelease]; +} + +- (NSDictionary *)metadataForURL:(NSURL *)url +{ + NSString *ext = [[url path] pathExtension]; + + Class metadataReader = NSClassFromString([metadataReaders objectForKey:[ext lowercaseString]]); + + return [metadataReader metadataForURL:url]; + +} + +- (NSDictionary *)propertiesForURL:(NSURL *)url +{ + NSString *ext = [[url path] pathExtension]; + + id source = [self audioSourceForURL:url]; + if (![source open:url]) + return nil; + + Class propertiesReader = NSClassFromString([propertiesReaders objectForKey:[ext lowercaseString]]); + + NSDictionary *properties = [propertiesReader propertiesForSource:source]; + + [source close]; + + return properties; + +} @end diff --git a/Cog.xcodeproj/project.pbxproj b/Cog.xcodeproj/project.pbxproj index 11f7c5dec..7e4ed55ea 100644 --- a/Cog.xcodeproj/project.pbxproj +++ b/Cog.xcodeproj/project.pbxproj @@ -109,6 +109,8 @@ 8E75757509F31D5A0080F1EE /* Shuffle.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E75753409F31D5A0080F1EE /* Shuffle.m */; }; 8E7575BE09F31D800080F1EE /* wheel.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8E7575A609F31D800080F1EE /* wheel.icns */; }; 8E7575DB09F31E930080F1EE /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8E7575D909F31E930080F1EE /* Localizable.strings */; }; + 8E8D40880CBB038E00135C1B /* M3u.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E8D40870CBB036600135C1B /* M3u.bundle */; }; + 8E8D41C80CBB0DA900135C1B /* Pls.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E8D41C70CBB0DA000135C1B /* Pls.bundle */; }; 8E9A2E860BA78B500091081B /* SecondsFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9A2E840BA78B500091081B /* SecondsFormatter.m */; }; 8E9A2EDA0BA78D9D0091081B /* IndexFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9A2ED80BA78D9D0091081B /* IndexFormatter.m */; }; 8E9A30160BA792DC0091081B /* NSFileHandle+CreateFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9A30140BA792DC0091081B /* NSFileHandle+CreateFile.m */; }; @@ -305,6 +307,34 @@ remoteGlobalIDString = 8D5B49AC048680CD000E48DA; remoteInfo = General; }; + 8E8D40860CBB036600135C1B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8E8D40820CBB036600135C1B /* M3u.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8D5B49B6048680CD000E48DA /* M3u.bundle */; + remoteInfo = M3u; + }; + 8E8D40920CBB03AF00135C1B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8E8D40820CBB036600135C1B /* M3u.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 8D5B49AC048680CD000E48DA /* M3u */; + remoteInfo = M3u; + }; + 8E8D41C60CBB0DA000135C1B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8D5B49B6048680CD000E48DA /* Pls.bundle */; + remoteInfo = Pls; + }; + 8E8D41CB0CBB0DD200135C1B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 8D5B49AC048680CD000E48DA /* Pls */; + remoteInfo = Pls; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -314,6 +344,8 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( + 8E8D41C80CBB0DA900135C1B /* Pls.bundle in CopyFiles */, + 8E8D40880CBB038E00135C1B /* M3u.bundle in CopyFiles */, 17C809E60C3BD487005707C4 /* CoreAudio.bundle in CopyFiles */, 17C8099A0C3BD233005707C4 /* FileSource.bundle in CopyFiles */, 17C809990C3BD231005707C4 /* Flac.bundle in CopyFiles */, @@ -509,6 +541,8 @@ 8E7575A609F31D800080F1EE /* wheel.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = wheel.icns; sourceTree = ""; }; 8E7575C809F31DCA0080F1EE /* English */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html; name = English; path = English.lproj/Credits.html; sourceTree = ""; }; 8E7575DA09F31E930080F1EE /* English */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Localizable.strings; sourceTree = ""; }; + 8E8D40820CBB036600135C1B /* M3u.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = M3u.xcodeproj; path = Plugins/M3u/M3u.xcodeproj; sourceTree = ""; }; + 8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Pls.xcodeproj; path = Plugins/Pls/Pls.xcodeproj; sourceTree = ""; }; 8E9A2E830BA78B500091081B /* SecondsFormatter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecondsFormatter.h; sourceTree = ""; }; 8E9A2E840BA78B500091081B /* SecondsFormatter.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = SecondsFormatter.m; sourceTree = ""; }; 8E9A2ED70BA78D9D0091081B /* IndexFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IndexFormatter.h; sourceTree = ""; }; @@ -757,6 +791,8 @@ 17B619FF0B909ED400BC003F /* PlugIns */ = { isa = PBXGroup; children = ( + 8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */, + 8E8D40820CBB036600135C1B /* M3u.xcodeproj */, 17C808C00C3BD1DD005707C4 /* WavPack.xcodeproj */, 17C808B70C3BD1D2005707C4 /* Vorbis.xcodeproj */, 17C808B00C3BD1C5005707C4 /* TagLib.xcodeproj */, @@ -1009,6 +1045,22 @@ path = Icons; sourceTree = ""; }; + 8E8D40830CBB036600135C1B /* Products */ = { + isa = PBXGroup; + children = ( + 8E8D40870CBB036600135C1B /* M3u.bundle */, + ); + name = Products; + sourceTree = ""; + }; + 8E8D41C30CBB0DA000135C1B /* Products */ = { + isa = PBXGroup; + children = ( + 8E8D41C70CBB0DA000135C1B /* Pls.bundle */, + ); + name = Products; + sourceTree = ""; + }; 8EFFCD410AA093AF00C458A5 /* FileDrawer */ = { isa = PBXGroup; children = ( @@ -1063,6 +1115,8 @@ 17C809E50C3BD47C005707C4 /* PBXTargetDependency */, 17F5613F0C3BD4E90019975C /* PBXTargetDependency */, 17F5623B0C3BD9280019975C /* PBXTargetDependency */, + 8E8D40930CBB03AF00135C1B /* PBXTargetDependency */, + 8E8D41CC0CBB0DD200135C1B /* PBXTargetDependency */, ); name = Cog; productInstallPath = "$(HOME)/Applications"; @@ -1113,6 +1167,10 @@ ProductGroup = 17C808840C3BD181005707C4 /* Products */; ProjectRef = 17C808830C3BD181005707C4 /* HTTPSource.xcodeproj */; }, + { + ProductGroup = 8E8D40830CBB036600135C1B /* Products */; + ProjectRef = 8E8D40820CBB036600135C1B /* M3u.xcodeproj */; + }, { ProductGroup = 17C8088D0C3BD192005707C4 /* Products */; ProjectRef = 17C8088C0C3BD192005707C4 /* MAD.xcodeproj */; @@ -1125,6 +1183,10 @@ ProductGroup = 17C8089F0C3BD1AB005707C4 /* Products */; ProjectRef = 17C8089E0C3BD1AB005707C4 /* Musepack.xcodeproj */; }, + { + ProductGroup = 8E8D41C30CBB0DA000135C1B /* Products */; + ProjectRef = 8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */; + }, { ProductGroup = 17C808A80C3BD1BA005707C4 /* Products */; ProjectRef = 17C808A70C3BD1BA005707C4 /* Shorten.xcodeproj */; @@ -1240,6 +1302,20 @@ remoteRef = 17F5622D0C3BD8FB0019975C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 8E8D40870CBB036600135C1B /* M3u.bundle */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = M3u.bundle; + remoteRef = 8E8D40860CBB036600135C1B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 8E8D41C70CBB0DA000135C1B /* Pls.bundle */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = Pls.bundle; + remoteRef = 8E8D41C60CBB0DA000135C1B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ @@ -1417,6 +1493,16 @@ name = General; targetProxy = 17F5623A0C3BD9280019975C /* PBXContainerItemProxy */; }; + 8E8D40930CBB03AF00135C1B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = M3u; + targetProxy = 8E8D40920CBB03AF00135C1B /* PBXContainerItemProxy */; + }; + 8E8D41CC0CBB0DD200135C1B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Pls; + targetProxy = 8E8D41CB0CBB0DD200135C1B /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ diff --git a/Playlist/PlaylistLoader.h b/Playlist/PlaylistLoader.h index c9366dd98..e55cc77d0 100755 --- a/Playlist/PlaylistLoader.h +++ b/Playlist/PlaylistLoader.h @@ -24,11 +24,6 @@ typedef enum { - (void)addURL:(NSURL *)url; - (void)insertURLs:(NSArray *)urls atIndex:(int)index sort:(BOOL)sort; -//load playlist auto-determines type to be either pls or m3u. -- (NSArray *)urlsFromPlaylist:(NSString *)filename; -- (NSArray *)urlsFromM3u:(NSString *)filename; -- (NSArray *)urlsFromPls:(NSString *)filename; - //save playlist, auto-determines type based on extension. Uses m3u if it cannot be determined. - (BOOL)save:(NSString *)filename; - (BOOL)save:(NSString *)filename asType:(PlaylistType)type; @@ -36,6 +31,6 @@ typedef enum { - (BOOL)savePls:(NSString *)filename; - (NSArray *)acceptableFileTypes; -- (NSArray *)acceptablePlaylistTypes; +- (NSArray *)acceptableContainerTypes; @end diff --git a/Playlist/PlaylistLoader.m b/Playlist/PlaylistLoader.m index 78d52e185..968afedd4 100755 --- a/Playlist/PlaylistLoader.m +++ b/Playlist/PlaylistLoader.m @@ -13,31 +13,10 @@ #import "NSFileHandle+CreateFile.h" #import "CogAudio/AudioPlayer.h" +#import "CogAudio/AudioContainer.h" @implementation PlaylistLoader -//load/save playlist auto-determines type to be either pls or m3u. -- (NSArray *)urlsFromPlaylist:(NSString *)filename -{ - NSString *ext = [filename pathExtension]; - if ([ext isEqualToString:@"m3u"]) - { - return [self urlsFromM3u:filename]; - } - else if ([ext isEqualToString:@"pls"]) - { - return [self urlsFromPls:filename]; - } - else - { - NSArray *entries = [self urlsFromPls:filename]; - if (entries == nil) - return [self urlsFromM3u:filename]; - - return entries; - } -} - - (BOOL)save:(NSString *)filename { NSString *ext = [filename pathExtension]; @@ -109,31 +88,6 @@ } -- (NSArray *)urlsFromM3u:(NSString *)filename -{ - NSError *error = nil; - NSString *contents = [NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:&error]; - if (error || !contents) { - NSLog(@"Could not open file...%@ %@", contents, error); - return NO; - } - - NSString *entry; - NSEnumerator *e = [[contents componentsSeparatedByString:@"\n"] objectEnumerator]; - NSMutableArray *entries = [NSMutableArray array]; - - while (entry = [[e nextObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]) - { - if ([entry hasPrefix:@"#"] || [entry isEqualToString:@""]) //Ignore extra info - continue; - - //Need to add basePath, and convert to URL - [entries addObject:[self urlForPath:entry relativeTo:filename]]; - } - - return entries; -} - - (BOOL)saveM3u:(NSString *)filename { NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filename createFile:YES]; @@ -157,42 +111,6 @@ return YES; } -- (NSArray *)urlsFromPls:(NSString *)filename -{ - NSError *error; - NSString *contents = [NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:&error]; - if (error || !contents) { - return nil; - } - - NSString *entry; - NSEnumerator *e = [[contents componentsSeparatedByString:@"\n"] objectEnumerator]; - NSMutableArray *entries = [NSMutableArray array]; - - while (entry = [[e nextObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]) - { - NSScanner *scanner = [[NSScanner alloc] initWithString:entry]; - NSString *lhs = nil; - NSString *rhs = nil; - - if (![scanner scanUpToString:@"=" intoString:&lhs] || // get LHS - ![scanner scanString:@"=" intoString:nil] || // skip the = - ![scanner scanUpToString:@"" intoString:&rhs] || // get RHS - ![lhs isEqualToString:@"File"]) // We only want file entries - { - [scanner release]; - continue; - } - - //need to add basepath if its a file, and convert to URL - [entries addObject:[self urlForPath:rhs relativeTo:filename]]; - - [scanner release]; - } - - return entries; -} - - (BOOL)savePls:(NSString *)filename { NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filename createFile:YES]; @@ -265,8 +183,8 @@ { if ([url isFileURL]) { BOOL isDir; - if ([[NSFileManager defaultManager] fileExistsAtPath:[url path] isDirectory:&isDir]) - { + if ([[NSFileManager defaultManager] fileExistsAtPath:[url path] isDirectory:&isDir]) + { if (isDir == YES) { //Get subpaths @@ -303,8 +221,10 @@ while (url = [urlEnumerator nextObject]) { //File url - if ([[self acceptablePlaylistTypes] containsObject:[[url path] pathExtension]]) { - [allURLs addObjectsFromArray:[self urlsFromPlaylist:[url path]]]; + if ([[self acceptableContainerTypes] containsObject:[[[url path] pathExtension] lowercaseString]]) { + if ([url isFileURL] ) { + [allURLs addObjectsFromArray:[AudioContainer urlsForContainerURL:url]]; + } } else { @@ -395,12 +315,12 @@ - (NSArray *)acceptableFileTypes { - return [[self acceptablePlaylistTypes] arrayByAddingObjectsFromArray:[AudioPlayer fileTypes]]; + return [[self acceptableContainerTypes] arrayByAddingObjectsFromArray:[AudioPlayer fileTypes]]; } -- (NSArray *)acceptablePlaylistTypes +- (NSArray *)acceptableContainerTypes { - return [NSArray arrayWithObjects:@"m3u",@"pls",nil]; + return [AudioPlayer containerTypes]; } @end diff --git a/Plugins/Flac/FlacDecoder.m b/Plugins/Flac/FlacDecoder.m index 9ff17eca8..7a54665ba 100644 --- a/Plugins/Flac/FlacDecoder.m +++ b/Plugins/Flac/FlacDecoder.m @@ -306,7 +306,7 @@ void ErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorS + (NSArray *)fileTypes { - return [NSArray arrayWithObject:@"flac"]; + return [NSArray arrayWithObjects:@"flac", @"fla", nil]; } @end diff --git a/Plugins/M3u/English.lproj/InfoPlist.strings b/Plugins/M3u/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..99142f9ac324654402807f6015e1c4594ec8981e GIT binary patch literal 204 zcmW-ZOAf&R6h+Utt7r@xK}-z9$bMd*s%ZBv=Kme5Fyy^_xDn;J8+CjLwb{$g|^>;M1& literal 0 HcmV?d00001 diff --git a/Plugins/M3u/Info.plist b/Plugins/M3u/Info.plist new file mode 100644 index 000000000..c8d20cdec --- /dev/null +++ b/Plugins/M3u/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleName + ${PRODUCT_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.yourcocoabundle + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSPrincipalClass + M3uPlugin + + diff --git a/Plugins/M3u/M3u.xcodeproj/project.pbxproj b/Plugins/M3u/M3u.xcodeproj/project.pbxproj new file mode 100644 index 000000000..d6266db0b --- /dev/null +++ b/Plugins/M3u/M3u.xcodeproj/project.pbxproj @@ -0,0 +1,276 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; }; + 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; + 8E8D40220CBAFF3900135C1B /* M3uPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D40210CBAFF3900135C1B /* M3uPlugin.m */; }; + 8E8D40290CBAFF4300135C1B /* M3uContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D40280CBAFF4300135C1B /* M3uContainer.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 32DBCF630370AF2F00C91783 /* M3u_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = M3u_Prefix.pch; sourceTree = ""; }; + 8D5B49B6048680CD000E48DA /* M3u.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = M3u.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; + 8E8D401B0CBAFEF200135C1B /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; + 8E8D40200CBAFF3900135C1B /* M3uPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = M3uPlugin.h; sourceTree = ""; }; + 8E8D40210CBAFF3900135C1B /* M3uPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = M3uPlugin.m; sourceTree = ""; }; + 8E8D40270CBAFF4300135C1B /* M3uContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = M3uContainer.h; sourceTree = ""; }; + 8E8D40280CBAFF4300135C1B /* M3uContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = M3uContainer.m; sourceTree = ""; }; + D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D5B49B3048680CD000E48DA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 089C166AFE841209C02AAC07 /* M3u */ = { + isa = PBXGroup; + children = ( + 08FB77AFFE84173DC02AAC07 /* Classes */, + 32C88E010371C26100C91783 /* Other Sources */, + 089C167CFE841241C02AAC07 /* Resources */, + 089C1671FE841209C02AAC07 /* Frameworks and Libraries */, + 19C28FB8FE9D52D311CA2CBB /* Products */, + ); + name = M3u; + sourceTree = ""; + }; + 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */, + 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */, + ); + name = "Frameworks and Libraries"; + sourceTree = ""; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8D5B49B7048680CD000E48DA /* Info.plist */, + 089C167DFE841241C02AAC07 /* InfoPlist.strings */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77AFFE84173DC02AAC07 /* Classes */ = { + isa = PBXGroup; + children = ( + 8E8D401B0CBAFEF200135C1B /* Plugin.h */, + 8E8D40200CBAFF3900135C1B /* M3uPlugin.h */, + 8E8D40210CBAFF3900135C1B /* M3uPlugin.m */, + 8E8D40270CBAFF4300135C1B /* M3uContainer.h */, + 8E8D40280CBAFF4300135C1B /* M3uContainer.m */, + ); + name = Classes; + sourceTree = ""; + }; + 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 089C167FFE841241C02AAC07 /* AppKit.framework */, + D2F7E65807B2D6F200F64583 /* CoreData.framework */, + 089C1672FE841209C02AAC07 /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FB8FE9D52D311CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D5B49B6048680CD000E48DA /* M3u.bundle */, + ); + name = Products; + sourceTree = ""; + }; + 32C88E010371C26100C91783 /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32DBCF630370AF2F00C91783 /* M3u_Prefix.pch */, + ); + name = "Other Sources"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D5B49AC048680CD000E48DA /* M3u */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "M3u" */; + buildPhases = ( + 8D5B49AF048680CD000E48DA /* Resources */, + 8D5B49B1048680CD000E48DA /* Sources */, + 8D5B49B3048680CD000E48DA /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = M3u; + productInstallPath = "$(HOME)/Library/Bundles"; + productName = M3u; + productReference = 8D5B49B6048680CD000E48DA /* M3u.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 089C1669FE841209C02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "M3u" */; + hasScannedForEncodings = 1; + mainGroup = 089C166AFE841209C02AAC07 /* M3u */; + projectDirPath = ""; + targets = ( + 8D5B49AC048680CD000E48DA /* M3u */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D5B49AF048680CD000E48DA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D5B49B1048680CD000E48DA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8E8D40220CBAFF3900135C1B /* M3uPlugin.m in Sources */, + 8E8D40290CBAFF4300135C1B /* M3uContainer.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C167EFE841241C02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1DEB913B08733D840010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = M3u_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + OBJROOT = ../../build; + PRODUCT_NAME = M3u; + SYMROOT = ../../build; + WRAPPER_EXTENSION = bundle; + ZERO_LINK = YES; + }; + name = Debug; + }; + 1DEB913C08733D840010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = M3u_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + OBJROOT = ../../build; + PRODUCT_NAME = M3u; + SYMROOT = ../../build; + WRAPPER_EXTENSION = bundle; + ZERO_LINK = NO; + }; + name = Release; + }; + 1DEB913F08733D840010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + 1DEB914008733D840010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "M3u" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB913B08733D840010E9CD /* Debug */, + 1DEB913C08733D840010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "M3u" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB913F08733D840010E9CD /* Debug */, + 1DEB914008733D840010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/Plugins/M3u/M3uContainer.h b/Plugins/M3u/M3uContainer.h new file mode 100644 index 000000000..21be729f2 --- /dev/null +++ b/Plugins/M3u/M3uContainer.h @@ -0,0 +1,17 @@ +// +// M3uContainer.h +// M3u +// +// Created by Zaphod Beeblebrox on 10/8/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import + +#import "Plugin.h" + +@interface M3uContainer : NSObject { + +} + +@end diff --git a/Plugins/M3u/M3uContainer.m b/Plugins/M3u/M3uContainer.m new file mode 100644 index 000000000..d54e9abb6 --- /dev/null +++ b/Plugins/M3u/M3uContainer.m @@ -0,0 +1,70 @@ +// +// M3uContainer.m +// M3u +// +// Created by Zaphod Beeblebrox on 10/8/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "M3uContainer.h" + + +@implementation M3uContainer + ++ (NSArray *)fileTypes +{ + return [NSArray arrayWithObject:@"m3u"]; +} + ++ (NSURL *)urlForPath:(NSString *)path relativeTo:(NSString *)baseFilename +{ + if ([path hasPrefix:@"/"]) { + return [NSURL fileURLWithPath:path]; + } + + NSRange foundRange = [path rangeOfString:@"://"]; + if (foundRange.location != NSNotFound) + { + return [NSURL URLWithString:path]; + } + + NSString *basePath = [[[baseFilename stringByStandardizingPath] stringByDeletingLastPathComponent] stringByAppendingString:@"/"]; + NSMutableString *unixPath = [path mutableCopy]; + + //Only relative paths would have windows backslashes. + [unixPath replaceOccurrencesOfString:@"\\" withString:@"/" options:0 range:NSMakeRange(0, [unixPath length])]; + + return [NSURL fileURLWithPath:[basePath stringByAppendingString:[unixPath autorelease]]]; +} + ++ (NSArray *)urlsForContainerURL:(NSURL *)url +{ + if (![url isFileURL]) + return [NSArray array]; + + NSString *filename = [url path]; + + NSError *error = nil; + NSString *contents = [NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:&error]; + if (error || !contents) { + NSLog(@"Could not open file...%@ %@", contents, error); + return NO; + } + + NSString *entry; + NSEnumerator *e = [[contents componentsSeparatedByString:@"\n"] objectEnumerator]; + NSMutableArray *entries = [NSMutableArray array]; + + while (entry = [[e nextObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]) + { + if ([entry hasPrefix:@"#"] || [entry isEqualToString:@""]) //Ignore extra info + continue; + + //Need to add basePath, and convert to URL + [entries addObject:[M3uContainer urlForPath:entry relativeTo:filename]]; + } + + return entries; +} + +@end diff --git a/Plugins/M3u/M3uPlugin.h b/Plugins/M3u/M3uPlugin.h new file mode 100644 index 000000000..913f902b0 --- /dev/null +++ b/Plugins/M3u/M3uPlugin.h @@ -0,0 +1,17 @@ +// +// M3uPlugin.h +// M3u +// +// Created by Zaphod Beeblebrox on 10/8/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import + +#import "Plugin.h" + +@interface M3uPlugin : NSObject { + +} + +@end diff --git a/Plugins/M3u/M3uPlugin.m b/Plugins/M3u/M3uPlugin.m new file mode 100644 index 000000000..0a93987c9 --- /dev/null +++ b/Plugins/M3u/M3uPlugin.m @@ -0,0 +1,20 @@ +// +// M3uPlugin.m +// M3u +// +// Created by Zaphod Beeblebrox on 10/8/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "M3uPlugin.h" + +#import "M3uContainer.h" + +@implementation M3uPlugin + ++ (NSDictionary *)pluginInfo +{ + return [NSDictionary dictionaryWithObject:kCogContainer forKey:[M3uContainer className]]; +} + +@end diff --git a/Plugins/M3u/M3u_Prefix.pch b/Plugins/M3u/M3u_Prefix.pch new file mode 100644 index 000000000..7a64a4c96 --- /dev/null +++ b/Plugins/M3u/M3u_Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'M3u' target in the 'M3u' project. +// + +#ifdef __OBJC__ + #import +#endif diff --git a/Plugins/Pls/English.lproj/InfoPlist.strings b/Plugins/Pls/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..99142f9ac324654402807f6015e1c4594ec8981e GIT binary patch literal 204 zcmW-ZOAf&R6h+Utt7r@xK}-z9$bMd*s%ZBv=Kme5Fyy^_xDn;J8+CjLwb{$g|^>;M1& literal 0 HcmV?d00001 diff --git a/Plugins/Pls/Info.plist b/Plugins/Pls/Info.plist new file mode 100644 index 000000000..cd36cfb50 --- /dev/null +++ b/Plugins/Pls/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleName + ${PRODUCT_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.yourcocoabundle + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSPrincipalClass + PlsPlugin + + diff --git a/Plugins/Pls/Pls.xcodeproj/project.pbxproj b/Plugins/Pls/Pls.xcodeproj/project.pbxproj new file mode 100644 index 000000000..106b5aa93 --- /dev/null +++ b/Plugins/Pls/Pls.xcodeproj/project.pbxproj @@ -0,0 +1,273 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; }; + 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; + 8E8D41980CBB0C9F00135C1B /* PlsPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D41970CBB0C9F00135C1B /* PlsPlugin.m */; }; + 8E8D41A10CBB0CA700135C1B /* PlsContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D41A00CBB0CA700135C1B /* PlsContainer.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 32DBCF630370AF2F00C91783 /* Pls_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pls_Prefix.pch; sourceTree = ""; }; + 8D5B49B6048680CD000E48DA /* Pls.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Pls.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; + 8E8D41960CBB0C9F00135C1B /* PlsPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlsPlugin.h; sourceTree = ""; }; + 8E8D41970CBB0C9F00135C1B /* PlsPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlsPlugin.m; sourceTree = ""; }; + 8E8D419F0CBB0CA700135C1B /* PlsContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlsContainer.h; sourceTree = ""; }; + 8E8D41A00CBB0CA700135C1B /* PlsContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlsContainer.m; sourceTree = ""; }; + 8E8D41A50CBB0CBE00135C1B /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; + D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D5B49B3048680CD000E48DA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 089C166AFE841209C02AAC07 /* Pls */ = { + isa = PBXGroup; + children = ( + 08FB77AFFE84173DC02AAC07 /* Classes */, + 32C88E010371C26100C91783 /* Other Sources */, + 089C167CFE841241C02AAC07 /* Resources */, + 089C1671FE841209C02AAC07 /* Frameworks and Libraries */, + 19C28FB8FE9D52D311CA2CBB /* Products */, + ); + name = Pls; + sourceTree = ""; + }; + 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */, + 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */, + ); + name = "Frameworks and Libraries"; + sourceTree = ""; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8D5B49B7048680CD000E48DA /* Info.plist */, + 089C167DFE841241C02AAC07 /* InfoPlist.strings */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77AFFE84173DC02AAC07 /* Classes */ = { + isa = PBXGroup; + children = ( + 8E8D41A50CBB0CBE00135C1B /* Plugin.h */, + 8E8D41960CBB0C9F00135C1B /* PlsPlugin.h */, + 8E8D41970CBB0C9F00135C1B /* PlsPlugin.m */, + 8E8D419F0CBB0CA700135C1B /* PlsContainer.h */, + 8E8D41A00CBB0CA700135C1B /* PlsContainer.m */, + ); + name = Classes; + sourceTree = ""; + }; + 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 089C167FFE841241C02AAC07 /* AppKit.framework */, + D2F7E65807B2D6F200F64583 /* CoreData.framework */, + 089C1672FE841209C02AAC07 /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FB8FE9D52D311CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D5B49B6048680CD000E48DA /* Pls.bundle */, + ); + name = Products; + sourceTree = ""; + }; + 32C88E010371C26100C91783 /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32DBCF630370AF2F00C91783 /* Pls_Prefix.pch */, + ); + name = "Other Sources"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D5B49AC048680CD000E48DA /* Pls */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "Pls" */; + buildPhases = ( + 8D5B49AF048680CD000E48DA /* Resources */, + 8D5B49B1048680CD000E48DA /* Sources */, + 8D5B49B3048680CD000E48DA /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Pls; + productInstallPath = "$(HOME)/Library/Bundles"; + productName = Pls; + productReference = 8D5B49B6048680CD000E48DA /* Pls.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 089C1669FE841209C02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "Pls" */; + hasScannedForEncodings = 1; + mainGroup = 089C166AFE841209C02AAC07 /* Pls */; + projectDirPath = ""; + targets = ( + 8D5B49AC048680CD000E48DA /* Pls */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D5B49AF048680CD000E48DA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D5B49B1048680CD000E48DA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8E8D41980CBB0C9F00135C1B /* PlsPlugin.m in Sources */, + 8E8D41A10CBB0CA700135C1B /* PlsContainer.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C167EFE841241C02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1DEB913B08733D840010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Pls_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + PRODUCT_NAME = Pls; + SYMROOT = ../../build; + WRAPPER_EXTENSION = bundle; + ZERO_LINK = YES; + }; + name = Debug; + }; + 1DEB913C08733D840010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Pls_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + PRODUCT_NAME = Pls; + SYMROOT = ../../build; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 1DEB913F08733D840010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + 1DEB914008733D840010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "Pls" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB913B08733D840010E9CD /* Debug */, + 1DEB913C08733D840010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "Pls" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB913F08733D840010E9CD /* Debug */, + 1DEB914008733D840010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/Plugins/Pls/PlsContainer.h b/Plugins/Pls/PlsContainer.h new file mode 100644 index 000000000..f5d2f4b53 --- /dev/null +++ b/Plugins/Pls/PlsContainer.h @@ -0,0 +1,17 @@ +// +// PlsContainer.h +// Pls +// +// Created by Zaphod Beeblebrox on 10/8/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import + +#import "Plugin.h" + +@interface PlsContainer : NSObject { + +} + +@end diff --git a/Plugins/Pls/PlsContainer.m b/Plugins/Pls/PlsContainer.m new file mode 100644 index 000000000..1cdc8f8e6 --- /dev/null +++ b/Plugins/Pls/PlsContainer.m @@ -0,0 +1,81 @@ +// +// PlsContainer.m +// Pls +// +// Created by Zaphod Beeblebrox on 10/8/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "PlsContainer.h" + + +@implementation PlsContainer + ++ (NSArray *)fileTypes +{ + return [NSArray arrayWithObject:@"pls"]; +} + ++ (NSURL *)urlForPath:(NSString *)path relativeTo:(NSString *)baseFilename +{ + if ([path hasPrefix:@"/"]) { + return [NSURL fileURLWithPath:path]; + } + + NSRange foundRange = [path rangeOfString:@"://"]; + if (foundRange.location != NSNotFound) + { + return [NSURL URLWithString:path]; + } + + NSString *basePath = [[[baseFilename stringByStandardizingPath] stringByDeletingLastPathComponent] stringByAppendingString:@"/"]; + NSMutableString *unixPath = [path mutableCopy]; + + //Only relative paths would have windows backslashes. + [unixPath replaceOccurrencesOfString:@"\\" withString:@"/" options:0 range:NSMakeRange(0, [unixPath length])]; + + return [NSURL fileURLWithPath:[basePath stringByAppendingString:[unixPath autorelease]]]; +} + ++ (NSArray *)urlsForContainerURL:(NSURL *)url +{ + if (![url isFileURL]) + return [NSArray array]; + + NSString *filename = [url path]; + + NSError *error; + NSString *contents = [NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:&error]; + if (error || !contents) { + return nil; + } + + NSString *entry; + NSEnumerator *e = [[contents componentsSeparatedByString:@"\n"] objectEnumerator]; + NSMutableArray *entries = [NSMutableArray array]; + + while (entry = [[e nextObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]) + { + NSScanner *scanner = [[NSScanner alloc] initWithString:entry]; + NSString *lhs = nil; + NSString *rhs = nil; + + if (![scanner scanUpToString:@"=" intoString:&lhs] || // get LHS + ![scanner scanString:@"=" intoString:nil] || // skip the = + ![scanner scanUpToString:@"" intoString:&rhs] || // get RHS + ![lhs isEqualToString:@"File"]) // We only want file entries + { + [scanner release]; + continue; + } + + //need to add basepath if its a file, and convert to URL + [entries addObject:[self urlForPath:rhs relativeTo:filename]]; + + [scanner release]; + } + + return entries; +} + +@end diff --git a/Plugins/Pls/PlsPlugin.h b/Plugins/Pls/PlsPlugin.h new file mode 100644 index 000000000..f23c994a1 --- /dev/null +++ b/Plugins/Pls/PlsPlugin.h @@ -0,0 +1,17 @@ +// +// PlsPlugin.h +// Pls +// +// Created by Zaphod Beeblebrox on 10/8/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import + +#import "Plugin.h" + +@interface PlsPlugin : NSObject { + +} + +@end diff --git a/Plugins/Pls/PlsPlugin.m b/Plugins/Pls/PlsPlugin.m new file mode 100644 index 000000000..109571966 --- /dev/null +++ b/Plugins/Pls/PlsPlugin.m @@ -0,0 +1,20 @@ +// +// PlsPlugin.m +// Pls +// +// Created by Zaphod Beeblebrox on 10/8/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "PlsPlugin.h" + +#import "PlsContainer.h" + +@implementation PlsPlugin + ++ (NSDictionary *)pluginInfo +{ + return [NSDictionary dictionaryWithObject:kCogContainer forKey:[PlsContainer className]]; +} + +@end diff --git a/Plugins/Pls/Pls_Prefix.pch b/Plugins/Pls/Pls_Prefix.pch new file mode 100644 index 000000000..094c4c865 --- /dev/null +++ b/Plugins/Pls/Pls_Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'Pls' target in the 'Pls' project. +// + +#ifdef __OBJC__ + #import +#endif diff --git a/Plugins/TagLib/TagLibMetadataReader.m b/Plugins/TagLib/TagLibMetadataReader.m index 7967436cf..349e133db 100644 --- a/Plugins/TagLib/TagLibMetadataReader.m +++ b/Plugins/TagLib/TagLibMetadataReader.m @@ -12,7 +12,7 @@ @implementation TagLibMetadataReader -- (NSDictionary *)metadataForURL:(NSURL *)url ++ (NSDictionary *)metadataForURL:(NSURL *)url { NSString *lArtist = @"", *lTitle = @"", *lAlbum = @"", *lGenre = @""; int lYear = 0, lTrack = 0;