41#import "MyOpenGLView.h"
50static NSString *
const kOOOXZDataURL =
@"http://addons.oolite.space/api/1.0/overview";
116NSComparisonResult
oxzSort(
id m1,
id m2,
void *context);
121#if OOLITE_MAC_OS_X_10_7
122@interface OOOXZManager (OOPrivate) <NSURLConnectionDataDelegate>
124@interface OOOXZManager (NSURLConnectionDataDelegate)
127- (NSString *) manifestPath;
128- (NSString *) downloadPath;
129- (NSString *) extractionBasePathForIdentifier:(NSString *)identifier andVersion:(NSString *)version;
130- (NSString *) dataURL;
131- (NSString *) humanSize:(NSUInteger)bytes;
133- (BOOL) ensureInstallPath;
135- (BOOL) beginDownload:(NSMutableURLRequest *)request;
136- (BOOL) processDownloadedManifests;
137- (BOOL) processDownloadedOXZ;
140- (
OOColor *) colorForManifest:(NSDictionary *)manifest;
141- (NSString *) installStatusForManifest:(NSDictionary *)manifest;
143- (BOOL) validateFilter:(NSString *)input;
145- (void) setOXZList:(NSArray *)list;
146- (void) setFilteredList:(NSArray *)list;
147- (NSArray *) applyCurrentFilter:(NSArray *)list;
149- (void) setCurrentDownload:(NSURLConnection *)download withLabel:(NSString *)label;
150- (void) setProgressStatus:(NSString *)newStatus;
152- (BOOL) installOXZ:(NSUInteger)item;
153- (BOOL) updateAllOXZ;
154- (BOOL) removeOXZ:(NSUInteger)item;
155- (NSArray *) installOptions;
156- (NSArray *) removeOptions;
158- (NSString *) extractOXZ:(NSUInteger)item;
161- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
162- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
163- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
164- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
168@interface OOOXZManager (OOFilterRules)
169- (BOOL) applyFilterByNoFilter:(NSDictionary *)manifest;
170- (BOOL) applyFilterByUpdateRequired:(NSDictionary *)manifest;
171- (BOOL) applyFilterByInstallable:(NSDictionary *)manifest;
172- (BOOL) applyFilterByKeyword:(NSDictionary *)manifest keyword:(NSString *)keyword;
173- (BOOL) applyFilterByAuthor:(NSDictionary *)manifest author:(NSString *)author;
174- (BOOL) applyFilterByDays:(NSDictionary *)manifest days:(NSString *)days;
175- (BOOL) applyFilterByTag:(NSDictionary *)manifest tag:(NSString *)tag;
198 [
self setOXZList:OOArrayFromFile([
self manifestPath])];
201 _currentFilter =
@"*";
203 _interfaceShowingOXZDetail = NO;
205 _downloadAllDependencies = NO;
206 _dependencyStack = [[NSMutableSet alloc] initWithCapacity:8];
207 [
self setProgressStatus:@""];
217 [
self setCurrentDownload:nil withLabel:nil];
229- (NSString *) installPath
231 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,NSUserDomainMask,YES);
232 NSString *appPath = [paths objectAtIndex:0];
235 appPath = [appPath stringByAppendingPathComponent:@"Oolite"];
237 appPath = [appPath stringByAppendingPathComponent:@"Managed AddOns"];
242 appPath = [appPath stringByAppendingPathComponent:@"ManagedAddOns"];
250- (NSString *) extractionBasePathForIdentifier:(NSString *)identifier andVersion:(NSString *)version
253 NSString *rawMainDir = [NSString stringWithFormat:@"%@-%@.off",identifier,version];
255 NSCharacterSet *blacklist = [NSCharacterSet characterSetWithCharactersInString:@"'#%^&{}[]/~|\\?<,:\" "];
256 return [[[basePath stringByAppendingPathComponent:[[rawMainDir componentsSeparatedByCharactersInSet:blacklist] componentsJoinedByString:@""]] retain] autorelease];
260- (BOOL) ensureInstallPath
262 BOOL exists, directory;
263 NSFileManager *fmgr = [NSFileManager defaultManager];
264 NSString *path = [
self installPath];
266 exists = [fmgr fileExistsAtPath:path isDirectory:&directory];
268 if (exists && !directory)
275 if (![fmgr oo_createDirectoryAtPath:path attributes:
nil])
286- (NSString *) manifestPath
295- (NSString *) downloadPath
308- (NSString *) dataURL
311 NSString *url = [[NSUserDefaults standardUserDefaults] stringForKey:kOOOXZDataConfig];
320- (NSString *) humanSize:(NSUInteger)bytes
324 return DESC(
@"oolite-oxzmanager-missing-field");
326 else if (bytes < 1024)
330 else if (bytes < 1024*1024)
332 return [NSString stringWithFormat:@"%lu kB",bytes>>10];
336 return [NSString stringWithFormat:@"%.2f MB",((float)(bytes>>10))/1024];
341- (void) setOXZList:(NSArray *)list
346 _oxzList = [[list sortedArrayUsingFunction:oxzSort context:NULL] retain];
353- (void) setFilteredList:(NSArray *)list
356 _filteredList = [list copy];
360- (void) setFilter:(NSString *)filter
363 _currentFilter = [[filter lowercaseString] copy];
367- (NSArray *) applyCurrentFilter:(NSArray *)list
369 SEL filterSelector =
@selector(applyFilterByNoFilter:);
370 NSString *parameter =
nil;
373 filterSelector =
@selector(applyFilterByUpdateRequired:);
377 filterSelector =
@selector(applyFilterByInstallable:);
381 filterSelector =
@selector(applyFilterByKeyword:keyword:);
382 parameter = [_currentFilter substringFromIndex:[kOOOXZFilterKeyword length]];
386 filterSelector =
@selector(applyFilterByAuthor:author:);
387 parameter = [_currentFilter substringFromIndex:[kOOOXZFilterAuthor length]];
391 filterSelector =
@selector(applyFilterByDays:days:);
392 parameter = [_currentFilter substringFromIndex:[kOOOXZFilterDays length]];
396 filterSelector =
@selector(applyFilterByTag:tag:);
397 parameter = [_currentFilter substringFromIndex:[kOOOXZFilterTag length]];
400 NSMutableArray *filteredList = [NSMutableArray arrayWithCapacity:[list count]];
401 NSDictionary *manifest =
nil;
402 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[
self class] instanceMethodSignatureForSelector:filterSelector]];
403 [invocation setSelector:filterSelector];
404 [invocation setTarget:self];
405 if (parameter !=
nil)
407 [invocation setArgument:¶meter atIndex:3];
410 foreach(manifest, list)
412 [invocation setArgument:&manifest atIndex:2];
414 BOOL filterAccepted = NO;
415 [invocation getReturnValue:&filterAccepted];
418 [filteredList addObject:manifest];
423 return [[filteredList copy] autorelease];
428- (BOOL) applyFilterByNoFilter:(NSDictionary *)manifest
434- (BOOL) applyFilterByUpdateRequired:(NSDictionary *)manifest
440- (BOOL) applyFilterByInstallable:(NSDictionary *)manifest
446- (BOOL) applyFilterByKeyword:(NSDictionary *)manifest keyword:(NSString *)keyword
448 NSString *parameter =
nil;
449 NSArray *parameters = [NSArray arrayWithObjects:kOOManifestTitle,kOOManifestDescription,kOOManifestCategory,nil];
450 foreach (parameter,parameters)
452 if ([[manifest oo_stringForKey:parameter] rangeOfString:keyword options:NSCaseInsensitiveSearch].location != NSNotFound)
458 parameters = [manifest oo_arrayForKey:kOOManifestTags];
459 foreach (parameter,parameters)
461 if ([parameter rangeOfString:keyword options:NSCaseInsensitiveSearch].location != NSNotFound)
471- (BOOL) applyFilterByAuthor:(NSDictionary *)manifest author:(NSString *)author
473 NSString *mAuth = [manifest oo_stringForKey:kOOManifestAuthor];
474 return ([mAuth rangeOfString:author options:NSCaseInsensitiveSearch].location != NSNotFound);
478- (BOOL) applyFilterByDays:(NSDictionary *)manifest days:(NSString *)days
480 NSInteger i = [days integerValue];
487 NSUInteger updated = [manifest oo_unsignedIntegerForKey:kOOManifestUploadDate];
488 NSUInteger now = (NSUInteger)[[NSDate date] timeIntervalSince1970];
489 return (updated + (86400 * i) > now);
494- (BOOL) applyFilterByTag:(NSDictionary *)manifest tag:(NSString *)tag
496 NSString *parameter =
nil;
497 NSArray *parameters = [manifest oo_arrayForKey:kOOManifestTags];
498 foreach (parameter,parameters)
500 if ([parameter rangeOfString:tag options:NSCaseInsensitiveSearch].location != NSNotFound)
511- (BOOL) validateFilter:(NSString *)input
513 NSString *filter = [input lowercaseString];
514 if (([filter length] == 0)
531- (void) setCurrentDownload:(NSURLConnection *)download withLabel:(NSString *)label
533 if (_currentDownload !=
nil)
535 [_currentDownload cancel];
537 _currentDownload = [download retain];
539 _currentDownloadName = [label copy];
543- (void) setProgressStatus:(NSString *)new
546 _progressStatus = [new copy];
549- (BOOL) updateManifests
551 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[
self dataURL]]];
558 [
self setProgressStatus:@""];
560 return [
self beginDownload:request];
564- (BOOL) beginDownload:(NSMutableURLRequest *)request
566 NSString *userAgent = [NSString stringWithFormat:@"Oolite/%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]];
567 [request setValue:userAgent forHTTPHeaderField:@"User-Agent"];
568 NSURLConnection *download = [[NSURLConnection alloc] initWithRequest:request delegate:self];
571 _downloadProgress = 0;
572 _downloadExpected = 0;
573 NSString *label =
DESC(
@"oolite-oxzmanager-download-label-list");
576 NSDictionary *expectedManifest =
nil;
577 expectedManifest = [_filteredList objectAtIndex:_item];
579 label = [expectedManifest oo_stringForKey:kOOManifestTitle defaultValue:DESC(@"oolite-oxzmanager-download-label-oxz")];
582 [
self setCurrentDownload:download withLabel:label];
584 OOLog(
kOOOXZDebugLog,
@"Download request received, using %@ and downloading to %@",[request URL],[
self downloadPath]);
603 if (_currentDownload !=
nil)
605 [_currentDownload cancel];
609 NSString *path = [
self downloadPath];
610 [[NSFileManager defaultManager] oo_removeItemAtPath:path];
626- (NSArray *) manifests
632- (NSArray *) managedOXZs
634 if (_managedList ==
nil)
638 NSArray *managedOXZs = [[NSFileManager defaultManager] oo_directoryContentsAtPath:[
self installPath]];
639 NSMutableArray *manifests = [NSMutableArray arrayWithCapacity:[managedOXZs count]];
641 NSString *fullpath =
nil;
642 NSDictionary *manifest =
nil;
645 fullpath = [[
self installPath] stringByAppendingPathComponent:filename];
649 NSMutableDictionary *adjManifest = [NSMutableDictionary dictionaryWithDictionary:manifest];
650 [adjManifest setObject:fullpath forKey:kOOManifestFilePath];
652 NSDictionary *stored =
nil;
657 BOOL foundInstallable = NO;
658 foreach (stored, _oxzList)
662 if (foundInstallable == NO)
664 [adjManifest setObject:[stored oo_stringForKey:kOOManifestVersion] forKey:kOOManifestAvailableVersion];
665 [adjManifest setObject:[stored oo_stringForKey:kOOManifestDownloadURL] forKey:kOOManifestDownloadURL];
668 foundInstallable = YES;
674 [manifests addObject:adjManifest];
677 [manifests sortUsingFunction:oxzSort context:NULL];
679 _managedList = [manifests copy];
685- (BOOL) processDownloadedManifests
691 [
self setOXZList:OOArrayFromFile([
self downloadPath])];
694 [_oxzList writeToFile:[
self manifestPath] atomically:YES];
696 [[NSFileManager defaultManager] oo_removeItemAtPath:[
self downloadPath]];
706 OOLog(
kOOOXZErrorLog,
@"Downloaded manifest was not a valid plist, has been left in %@",[
self downloadPath]);
708 [
self setOXZList:OOArrayFromFile([
self manifestPath])];
716- (BOOL) processDownloadedOXZ
723 NSDictionary *downloadedManifest =
OODictionaryFromFile([[
self downloadPath] stringByAppendingPathComponent:
@"manifest.plist"]);
724 if (downloadedManifest ==
nil)
727 OOLog(
kOOOXZErrorLog,
@"Downloaded OXZ does not contain a manifest.plist, has been left in %@",[
self downloadPath]);
732 NSDictionary *expectedManifest =
nil;
733 expectedManifest = [_filteredList objectAtIndex:_item];
735 if (expectedManifest ==
nil ||
741 OOLog(
kOOOXZErrorLog,
@"%@",
@"Downloaded OXZ does not have the same identifer and version as expected. This might be due to your manifests list being out of date - try updating it.");
748 NSString *
filename = [[downloadedManifest oo_stringForKey:kOOManifestIdentifier] stringByAppendingString:@".oxz"];
750 if (![
self ensureInstallPath])
760 NSString *destination = [[
self installPath] stringByAppendingPathComponent:filename];
761 [[NSFileManager defaultManager] oo_removeItemAtPath:destination];
764 if (![[NSFileManager defaultManager] oo_moveItemAtPath:[
self downloadPath] toPath:destination])
789 NSArray *
requires = [downloadedManifest oo_arrayForKey:kOOManifestRequiresOXPs defaultValue:nil];
793 requires = [expectedManifest oo_arrayForKey:kOOManifestRequiresOXPs defaultValue:nil];
795 NSDictionary *requirement =
nil;
796 NSMutableString *progress = [NSMutableString stringWithCapacity:2048];
799 if ([_dependencyStack
count] > 0)
802 NSSet *tempStack = [NSSet setWithSet:_dependencyStack];
803 foreach (requirement, tempStack)
806 if (![
ResourceManager manifest:downloadedManifest HasUnmetDependency:requirement logErrors:NO]
807 && requires !=
nil && [requires containsObject:requirement])
810 [progress appendFormat:DESC(@"oolite-oxzmanager-progress-now-has-@"),[requirement oo_stringForKey:kOOManifestRelationDescription defaultValue:[requirement oo_stringForKey:kOOManifestRelationIdentifier]]];
811 [_dependencyStack removeObject:requirement];
815 [_dependencyStack removeObject:requirement];
821 foreach (requirement,
requires)
823 if ([
ResourceManager manifest:downloadedManifest HasUnmetDependency:requirement logErrors:NO])
826 [_dependencyStack addObject:requirement];
827 [progress appendFormat:DESC(@"oolite-oxzmanager-progress-requires-@"),[requirement oo_stringForKey:kOOManifestRelationDescription defaultValue:[requirement oo_stringForKey:kOOManifestRelationIdentifier]]];
831 if ([_dependencyStack
count] > 0)
835 BOOL undownloadedRequirement = NO;
836 NSDictionary *availableDownload =
nil;
837 BOOL foundDownload = NO;
838 NSUInteger index = 0;
839 NSString *needsIdentifier =
nil;
843 undownloadedRequirement = YES;
844 requirement = [_dependencyStack anyObject];
847 if (!_downloadAllDependencies)
849 [progress appendString:DESC(@"oolite-oxzmanager-progress-get-required")];
851 needsIdentifier = [requirement oo_stringForKey:kOOManifestRelationIdentifier];
853 foreach (availableDownload, _oxzList)
861 index = [_oxzList indexOfObject:availableDownload];
875 [_dependencyStack removeObject:requirement];
876 if ([_dependencyStack
count] > 0)
879 undownloadedRequirement = NO;
890 while (!undownloadedRequirement);
895 [
self setFilteredList:_oxzList];
898 if (_downloadAllDependencies)
901 if (![
self installOXZ:index]) {
904 [progress appendFormat:DESC(@"oolite-oxzmanager-progress-required-@-not-found"),[requirement oo_stringForKey:kOOManifestRelationDescription defaultValue:[requirement oo_stringForKey:kOOManifestRelationIdentifier]]];
905 [
self setProgressStatus:progress];
906 OOLog(
kOOOXZErrorLog,
@"OXZ dependency %@ could not be found for automatic download.",needsIdentifier);
919 [
self setProgressStatus:progress];
924 else if ([_dependencyStack
count] > 0)
926 [progress appendFormat:DESC(@"oolite-oxzmanager-progress-required-@-not-found"),[requirement oo_stringForKey:kOOManifestRelationDescription defaultValue:[requirement oo_stringForKey:kOOManifestRelationIdentifier]]];
927 [
self setProgressStatus:progress];
928 OOLog(
kOOOXZErrorLog,
@"OXZ dependency %@ could not be found for automatic download.",needsIdentifier);
937 [
self setProgressStatus:@""];
939 [_dependencyStack removeAllObjects];
940 _downloadAllDependencies = NO;
946- (NSDictionary *) installedManifestForIdentifier:(NSString *)identifier
948 NSArray *installed = [
self managedOXZs];
949 NSDictionary *manifest =
nil;
950 foreach (manifest,installed)
963 NSString *title = [manifest oo_stringForKey:kOOManifestTitle defaultValue:nil];
964 NSString *identifier = [manifest oo_stringForKey:kOOManifestIdentifier defaultValue:nil];
966 if (![
ResourceManager checkVersionCompatibility:manifest forOXP:title])
971 NSDictionary *installed = [
self installedManifestForIdentifier:identifier];
972 if (installed ==
nil)
978 if (installed !=
nil)
986 && [[NSFileManager defaultManager] fileExistsAtPath:[installed oo_stringForKey:
kOOManifestFilePath]])
1004 if (installed !=
nil)
1006 NSString *availableVersion = [manifest oo_stringForKey:kOOManifestAvailableVersion];
1007 if (availableVersion ==
nil)
1009 availableVersion = [manifest oo_stringForKey:kOOManifestVersion];
1011 NSString *installedVersion = [installed oo_stringForKey:kOOManifestVersion];
1012 OOLog(
@"version.debug",
@"%@ mv:%@ mav:%@",identifier,installedVersion,availableVersion);
1020 if ([
ResourceManager manifestHasMissingDependencies:manifest logErrors:NO])
1028- (
OOColor *) colorForManifest:(NSDictionary *)manifest
1030 switch ([
self installableState:manifest])
1053- (NSString *) installStatusForManifest:(NSDictionary *)manifest
1055 switch ([
self installableState:manifest])
1058 return DESC(
@"oolite-oxzmanager-installable-okay");
1060 return DESC(
@"oolite-oxzmanager-installable-update");
1062 return DESC(
@"oolite-oxzmanager-installable-depend");
1064 return DESC(
@"oolite-oxzmanager-installable-conflicts");
1066 return DESC(
@"oolite-oxzmanager-installable-already");
1068 return DESC(
@"oolite-oxzmanager-installable-manual");
1070 return DESC(
@"oolite-oxzmanager-installable-version");
1072 return DESC(
@"oolite-oxzmanager-installable-noremote");
1088 [PLAYER destroySound];
1092 [gui
setTitle:DESC(@"oolite-oxzmanager-title")];
1096 switch (_interfaceState)
1099 [gui
setTitle:DESC(@"oolite-oxzmanager-title-setfilter")];
1100 [gui
setText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-currentfilter-is-@"),_currentFilter]
forRow:OXZ_GUI_ROW_FILTERCURRENT
align:GUI_ALIGN_LEFT];
1106 if (_oxzList ==
nil)
1109 [gui
setText:DESC(@"oolite-oxzmanager-download-list")
forRow:OXZ_GUI_ROW_UPDATE
align:GUI_ALIGN_CENTER];
1118 [gui
setText:DESC(@"oolite-oxzmanager-download-noupdate")
forRow:OXZ_GUI_ROW_PROCEED
align:GUI_ALIGN_CENTER];
1121 [gui
setText:DESC(@"oolite-oxzmanager-update-list")
forRow:OXZ_GUI_ROW_UPDATE
align:GUI_ALIGN_CENTER];
1138 [gui
setText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-currentfilter-is-@-@"),OOExpand(@"[oolite_key_oxzmanager_setfilter]"),_currentFilter]
forRow:OXZ_GUI_ROW_LISTFILTER
align:GUI_ALIGN_LEFT];
1142 [gui
setText:DESC(@"oolite-oxzmanager-install")
forRow:OXZ_GUI_ROW_INSTALL
align:GUI_ALIGN_CENTER];
1144 [gui
setText:DESC(@"oolite-oxzmanager-installed")
forRow:OXZ_GUI_ROW_INSTALLED
align:GUI_ALIGN_CENTER];
1145 [gui
setKey:@"_INSTALLED"
forRow:OXZ_GUI_ROW_INSTALLED];
1146 [gui
setText:DESC(@"oolite-oxzmanager-remove")
forRow:OXZ_GUI_ROW_REMOVE
align:GUI_ALIGN_CENTER];
1148 [gui
setText:DESC(@"oolite-oxzmanager-update-list")
forRow:OXZ_GUI_ROW_UPDATE
align:GUI_ALIGN_CENTER];
1150 [gui
setText:DESC(@"oolite-oxzmanager-update-all")
forRow:OXZ_GUI_ROW_UPDATE_ALL
align:GUI_ALIGN_CENTER];
1151 [gui
setKey:@"_UPDATE_ALL"
forRow:OXZ_GUI_ROW_UPDATE_ALL];
1157 [gui
setTitle:DESC(@"oolite-oxzmanager-title-downloading")];
1159 [gui
addLongText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-progress-@-is-@-of-@"),_currentDownloadName,[
self humanSize:_downloadProgress],[
self humanSize:_downloadExpected]]
startingAtRow:OXZ_GUI_ROW_PROGRESS
align:GUI_ALIGN_LEFT];
1163 [gui
setText:DESC(@"oolite-oxzmanager-cancel")
forRow:OXZ_GUI_ROW_CANCEL
align:GUI_ALIGN_CENTER];
1168 [gui
setTitle:DESC(@"oolite-oxzmanager-title-dependencies")];
1170 [gui
setText:DESC(@"oolite-oxzmanager-dependencies-decision")
forRow:OXZ_GUI_ROW_PROGRESS
align:GUI_ALIGN_LEFT];
1175 [gui
setText:DESC(@"oolite-oxzmanager-dependencies-yes-all")
forRow:OXZ_GUI_ROW_INSTALLED
align:GUI_ALIGN_CENTER];
1176 [gui
setKey:@"_PROCEED_ALL"
forRow:OXZ_GUI_ROW_INSTALLED];
1178 [gui
setText:DESC(@"oolite-oxzmanager-dependencies-yes")
forRow:OXZ_GUI_ROW_PROCEED
align:GUI_ALIGN_CENTER];
1181 [gui
setText:DESC(@"oolite-oxzmanager-dependencies-no")
forRow:OXZ_GUI_ROW_CANCEL
align:GUI_ALIGN_CENTER];
1187 [gui
setText:DESC(@"oolite-oxzmanager-acknowledge")
forRow:OXZ_GUI_ROW_UPDATE
align:GUI_ALIGN_CENTER];
1194 [gui
addLongText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-progress-done-%u-%u"),[_oxzList count],[[
self managedOXZs] count]]
startingAtRow:OXZ_GUI_ROW_PROGRESS
align:GUI_ALIGN_LEFT];
1202 [gui
setText:DESC(@"oolite-oxzmanager-acknowledge")
forRow:OXZ_GUI_ROW_UPDATE
align:GUI_ALIGN_CENTER];
1208 NSDictionary *manifest = [_filteredList oo_dictionaryAtIndex:_item];
1209 NSString *title = [manifest oo_stringForKey:kOOManifestTitle];
1210 NSString *version = [manifest oo_stringForKey:kOOManifestVersion];
1211 NSString *identifier = [manifest oo_stringForKey:kOOManifestIdentifier];
1212 [gui
setTitle:DESC(@"oolite-oxzmanager-title-extract")];
1213 [gui
setText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-infopage-title-@-version-@"),
1223 NSString *path = [
self extractionBasePathForIdentifier:identifier andVersion:version];
1224 if ([[NSFileManager defaultManager] fileExistsAtPath:path])
1226 [gui
addLongText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-extract-@-already-exists"), path]
1229 [gui
setText:DESC(@"oolite-oxzmanager-extract-unavailable")
forRow:OXZ_GUI_ROW_PROCEED
align:GUI_ALIGN_CENTER];
1234 [gui
addLongText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-extract-to-@"), path]
1237 [gui
setText:DESC(@"oolite-oxzmanager-extract-proceed")
forRow:OXZ_GUI_ROW_PROCEED
align:GUI_ALIGN_CENTER];
1241 [gui
setText:DESC(@"oolite-oxzmanager-extract-cancel")
forRow:OXZ_GUI_ROW_CANCEL
align:GUI_ALIGN_CENTER];
1248 [gui
setText:DESC(@"oolite-oxzmanager-acknowledge")
forRow:OXZ_GUI_ROW_UPDATE
align:GUI_ALIGN_CENTER];
1257 [gui
setTitle:DESC(@"oolite-oxzmanager-title-install")];
1258 [
self setFilteredList:[
self applyCurrentFilter:_oxzList]];
1259 startRow = [
self showInstallOptions];
1263 [gui
setTitle:DESC(@"oolite-oxzmanager-title-installed")];
1264 [
self setFilteredList:[
self applyCurrentFilter:[
self managedOXZs]]];
1265 startRow = [
self showInstallOptions];
1269 [gui
setTitle:DESC(@"oolite-oxzmanager-title-remove")];
1270 [
self setFilteredList:[
self applyCurrentFilter:[
self managedOXZs]]];
1271 startRow = [
self showRemoveOptions];
1277 [gui
setText:DESC(@"oolite-oxzmanager-exit-restart")
forRow:OXZ_GUI_ROW_EXIT
align:GUI_ALIGN_CENTER];
1281 [gui
setText:DESC(@"oolite-oxzmanager-exit")
forRow:OXZ_GUI_ROW_EXIT
align:GUI_ALIGN_CENTER];
1301- (BOOL) isRestarting
1308 [UNIVERSE reinitAndShowDemo:YES];
1321- (void) processSelection
1328 [
self cancelUpdate];
1329 [_dependencyStack removeAllObjects];
1330 _downloadAllDependencies = NO;
1338 [PLAYER setGuiToIntroFirstGo:YES];
1339 if (_oxzList !=
nil)
1359 [_dependencyStack removeAllObjects];
1360 _downloadAllDependencies = NO;
1366 [_dependencyStack removeAllObjects];
1367 _downloadAllDependencies = NO;
1373 [
self cancelUpdate];
1381 [
self updateManifests];
1392 _downloadAllDependencies = YES;
1393 [
self installOXZ:_item];
1404 [
self installOXZ:_item];
1412 [
self setProgressStatus:[
self extractOXZ:_item]];
1423 [
self updateAllOXZ];
1427 [
self processOptionsPrev];
1432 [
self processOptionsNext];
1440 [
self removeOXZ:item];
1445 [
self installOXZ:item];
1450 [
self installOXZ:item];
1459- (BOOL) isAcceptingTextInput
1465- (BOOL) isAcceptingGUIInput
1467 return !_interfaceShowingOXZDetail;
1471- (void) processTextInput:(NSString *)input
1473 if ([
self validateFilter:input])
1475 if ([input length] > 0)
1477 [
self setFilter:input];
1486- (void) refreshTextInput:(NSString *)input
1489 [gui
setText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-text-prompt-@"), input]
forRow:OXZ_GUI_ROW_INPUT
align:GUI_ALIGN_LEFT];
1490 if ([
self validateFilter:input])
1501- (void) processFilterKey
1503 if (_interfaceShowingOXZDetail)
1505 _interfaceShowingOXZDetail = NO;
1510 [[UNIVERSE gameView] resetTypedString];
1517- (void) processShowInfoKey
1523 if (_interfaceShowingOXZDetail)
1525 _interfaceShowingOXZDetail = NO;
1530 [
self showOptionsUpdate];
1545 NSDictionary *manifest = [_filteredList oo_dictionaryAtIndex:_item];
1546 _interfaceShowingOXZDetail = YES;
1549 [gui
setTitle:DESC(@"oolite-oxzmanager-title-infopage")];
1552 [gui
setText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-infopage-title-@-version-@"),
1553 [manifest oo_stringForKey:kOOManifestTitle],
1554 [manifest oo_stringForKey:kOOManifestVersion]]
1558 [gui
setText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-infopage-author-@"),
1559 [manifest oo_stringForKey:kOOManifestAuthor]]
1563 [gui
addLongText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-infopage-license-@"),
1564 [manifest oo_stringForKey:kOOManifestLicense]]
1568 [gui
addLongText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-infopage-tags-@"),[[manifest oo_arrayForKey:kOOManifestTags] componentsJoinedByString: @", "]]
1571 [gui
addLongText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-infopage-description-@"),[manifest oo_stringForKey:kOOManifestDescription]]
1575 NSString *infoURLString = [manifest oo_stringForKey:kOOManifestInformationURL];
1576 [gui
setText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-infopage-infourl-@"),
1580 [[UNIVERSE gameView] stringToClipboard:infoURLString];
1583 [gui
setText:OOExpand(DESC(@"oolite-oxzmanager-infopage-return"))
forRow:27
align:GUI_ALIGN_CENTER];
1591- (void) processExtractKey
1613- (BOOL) installOXZ:(NSUInteger)item
1615 NSArray *picklist = _filteredList;
1617 if ([picklist
count] <= item)
1621 NSDictionary *manifest = [picklist objectAtIndex:item];
1630 NSString *url = [manifest objectForKey:kOOManifestDownloadURL];
1636 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
1644 [
self setProgressStatus:@""];
1645 return [
self beginDownload:request];
1649- (BOOL) updateAllOXZ
1651 [_dependencyStack removeAllObjects];
1652 _downloadAllDependencies = YES;
1653 [
self setFilteredList:_oxzList];
1654 NSDictionary *manifest =
nil;
1656 foreach (manifest,_oxzList)
1661 [_dependencyStack addObject:manifest];
1664 NSDictionary *first = [_dependencyStack anyObject];
1665 NSString* identifier = [first oo_stringForKey:kOOManifestRelationIdentifier];
1666 NSUInteger item = NSUIntegerMax;
1667 NSDictionary *availableDownload =
nil;
1668 foreach (availableDownload, _oxzList)
1672 item = [_oxzList indexOfObject:availableDownload];
1676 return [
self installOXZ:item];
1680- (NSArray *) installOptions
1682 NSUInteger start = _offset;
1683 if (start >= [_filteredList
count])
1689 if (end > [_filteredList
count])
1691 end = [_filteredList count];
1693 return [_filteredList subarrayWithRange:NSMakeRange(start,end-start)];
1701 NSArray *options = [
self installOptions];
1702 NSUInteger optCount = [_filteredList count];
1712 [gui
setArray:[NSArray arrayWithObjects:DESC(@"oolite-oxzmanager-heading-category"),
1713 DESC(@"oolite-oxzmanager-heading-title"),
1714 DESC(@"oolite-oxzmanager-heading-installed"),
1715 DESC(@"oolite-oxzmanager-heading-downloadable"),
1716 nil]
forRow:OXZ_GUI_ROW_LISTHEAD];
1721 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-back"), @"",@"",@" <-- ", nil]
forRow:OXZ_GUI_ROW_LISTPREV];
1733 if (_offset + 10 < optCount)
1736 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-more"), @"",@"",@" --> ", nil]
forRow:OXZ_GUI_ROW_LISTNEXT];
1763 NSDictionary *manifest =
nil;
1764 BOOL oxzLineSelected = NO;
1766 foreach (manifest, options)
1769 NSString *localPath = [[[
self installPath] stringByAppendingPathComponent:[manifest oo_stringForKey:kOOManifestIdentifier]] stringByAppendingPathExtension:@"oxz"];
1770 if (installed ==
nil)
1773 installed =
OODictionaryFromFile([localPath stringByAppendingPathComponent:
@"manifest.plist"]);
1778 if ([[NSFileManager defaultManager] fileExistsAtPath:localPath])
1781 installed =
OODictionaryFromFile([localPath stringByAppendingPathComponent:
@"manifest.plist"]);
1793 NSString *installedVersion =
DESC(
@"oolite-oxzmanager-version-none");
1794 if (installed !=
nil)
1796 installedVersion = [installed oo_stringForKey:kOOManifestVersion defaultValue:DESC(@"oolite-oxzmanager-version-none")];
1801 [gui
setArray:[NSArray arrayWithObjects:
1802 [manifest oo_stringForKey:kOOManifestCategory defaultValue:DESC(@"oolite-oxzmanager-missing-field")],
1803 [manifest oo_stringForKey:kOOManifestTitle defaultValue:DESC(@"oolite-oxzmanager-missing-field")],
1805 [manifest oo_stringForKey:kOOManifestAvailableVersion defaultValue:[manifest oo_stringForKey:kOOManifestVersion defaultValue:DESC(@"oolite-oxzmanager-version-none")]],
1808 [gui
setKey:[manifest oo_stringForKey:kOOManifestIdentifier]
forRow:row];
1812 if (row == [gui selectedRow])
1814 oxzLineSelected = YES;
1816 [gui
setText:[
self installStatusForManifest:manifest]
forRow:OXZ_GUI_ROW_LISTSTATUS];
1819 [gui
addLongText:[[[manifest oo_stringForKey:kOOManifestDescription] componentsSeparatedByString:@"\n"] oo_stringAtIndex:0]
startingAtRow:OXZ_GUI_ROW_LISTDESC
align:GUI_ALIGN_LEFT];
1821 NSString *infoUrl = [manifest oo_stringForKey:kOOManifestInformationURL];
1824 [gui
setArray:[NSArray arrayWithObjects:DESC(@"oolite-oxzmanager-infoline-url"),infoUrl,nil]
forRow:OXZ_GUI_ROW_LISTINFO1];
1826 NSUInteger
size = [manifest oo_unsignedIntForKey:kOOManifestFileSize defaultValue:0];
1827 NSString *updatedDesc =
nil;
1829 NSUInteger timestamp = [manifest oo_unsignedIntegerForKey:kOOManifestUploadDate defaultValue:0];
1833 NSDate *updated = [NSDate dateWithTimeIntervalSince1970:timestamp];
1836 updatedDesc = [[[updated description] componentsSeparatedByString:@" "] oo_stringAtIndex:0];
1838 [gui
setArray:[NSArray arrayWithObjects:DESC(@"oolite-oxzmanager-infoline-size"),[
self humanSize:size],DESC(@"oolite-oxzmanager-infoline-date"),updatedDesc,nil]
forRow:OXZ_GUI_ROW_LISTINFO2];
1843 [gui
setArray:[NSArray arrayWithObjects:DESC(@"oolite-oxzmanager-infoline-size"),[
self humanSize:size],nil]
forRow:OXZ_GUI_ROW_LISTINFO2];
1853 if (!oxzLineSelected)
1873- (BOOL) removeOXZ:(NSUInteger)item
1875 NSArray *remList = _filteredList;
1876 if ([remList
count] <= item)
1878 OOLog(
kOOOXZDebugLog,
@"Unable to remove item %lu as only %lu in list", (
unsigned long)item, (
unsigned long)[remList
count]);
1881 NSString *
filename = [[remList objectAtIndex:item] oo_stringForKey:kOOManifestFilePath];
1884 OOLog(
kOOOXZDebugLog,
@"Unable to remove item %lu as filename not found", (
unsigned long)item);
1888 if (![[NSFileManager defaultManager] oo_removeItemAtPath:
filename])
1901- (NSArray *) removeOptions
1903 NSArray *remList = _filteredList;
1904 if ([remList
count] == 0)
1908 NSUInteger start = _offset;
1909 if (start >= [remList
count])
1915 if (end > [remList
count])
1917 end = [remList count];
1919 return [remList subarrayWithRange:NSMakeRange(start,end-start)];
1927 NSArray *options = [
self removeOptions];
1941 [gui
setArray:[NSArray arrayWithObjects:DESC(@"oolite-oxzmanager-heading-category"),
1942 DESC(@"oolite-oxzmanager-heading-title"),
1943 DESC(@"oolite-oxzmanager-heading-version"),
1944 nil]
forRow:OXZ_GUI_ROW_LISTHEAD];
1948 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-back"), @"",@" <-- ", nil]
forRow:OXZ_GUI_ROW_LISTPREV];
1963 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-more"), @"",@" --> ", nil]
forRow:OXZ_GUI_ROW_LISTNEXT];
1991 NSDictionary *manifest =
nil;
1992 BOOL oxzSelected = NO;
1994 foreach (manifest, options)
1997 [gui
setArray:[NSArray arrayWithObjects:
1998 [manifest oo_stringForKey:kOOManifestCategory defaultValue:DESC(@"oolite-oxzmanager-missing-field")],
1999 [manifest oo_stringForKey:kOOManifestTitle defaultValue:DESC(@"oolite-oxzmanager-missing-field")],
2000 [manifest oo_stringForKey:kOOManifestVersion defaultValue:DESC(@"oolite-oxzmanager-missing-field")],
2002 NSString *identifier = [manifest oo_stringForKey:kOOManifestIdentifier];
2007 if (row == [gui selectedRow])
2009 [gui
setText:[
self installStatusForManifest:manifest]
forRow:OXZ_GUI_ROW_LISTSTATUS];
2012 [gui
addLongText:[[[manifest oo_stringForKey:kOOManifestDescription] componentsSeparatedByString:@"\n"] oo_stringAtIndex:0]
startingAtRow:OXZ_GUI_ROW_LISTDESC
align:GUI_ALIGN_LEFT];
2028- (void) showOptionsUpdate
2033 [
self setFilteredList:[
self applyCurrentFilter:_oxzList]];
2034 [
self showInstallOptions];
2038 [
self setFilteredList:[
self applyCurrentFilter:[
self managedOXZs]]];
2039 [
self showInstallOptions];
2043 [
self setFilteredList:[
self applyCurrentFilter:[
self managedOXZs]]];
2044 [
self showRemoveOptions];
2050- (void) showOptionsPrev
2057 [
self processSelection];
2063- (void) processOptionsPrev
2073 [
self showOptionsUpdate];
2077- (void) processOptionsNext
2083 [
self showOptionsUpdate];
2088- (void) showOptionsNext
2095 [
self processSelection];
2101- (NSString *) extractOXZ:(NSUInteger)item
2103 NSFileManager *fmgr = [NSFileManager defaultManager];
2104 NSMutableString *extractionLog = [[NSMutableString alloc] init];
2105 NSDictionary *manifest = [_filteredList oo_dictionaryAtIndex:item];
2106 NSString *version = [manifest oo_stringForKey:kOOManifestVersion];
2107 NSString *identifier = [manifest oo_stringForKey:kOOManifestIdentifier];
2108 NSString *path = [
self extractionBasePathForIdentifier:identifier andVersion:version];
2114 NSString *oxzfile = [manifest oo_stringForKey:kOOManifestFilePath];
2115 if (![fmgr fileExistsAtPath:oxzfile])
2118 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-no-original")];
2119 return [extractionLog autorelease];
2121 const char* zipname = [oxzfile UTF8String];
2127 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-bad-original")];
2128 return [extractionLog autorelease];
2131 if ([fmgr fileExistsAtPath:path])
2134 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-main-exists")];
2136 return [extractionLog autorelease];
2138 if (![fmgr oo_createDirectoryAtPath:path attributes:
nil])
2141 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-main-unmakeable")];
2143 return [extractionLog autorelease];
2145 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-main-created")];
2146 NSUInteger counter = 0;
2147 char rawComponentName[512];
2155 rawComponentName, 512,
2158 NSString *componentName = [NSString stringWithUTF8String:rawComponentName];
2159 if ([componentName hasSuffix:
@"/"])
2162 if (![fmgr oo_createDirectoryAtPath:[path stringByAppendingPathComponent:componentName] attributes:
nil])
2165 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-sub-failed")];
2178 NSString *folder = [[path stringByAppendingPathComponent:componentName] stringByDeletingLastPathComponent];
2179 if ([folder length] > 0 && ![fmgr fileExistsAtPath:folder] && ![fmgr oo_createDirectoryAtPath:folder attributes:
nil])
2182 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-sub-failed")];
2191 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
2192 NSData *tmp = [NSData oo_dataWithOXZFile:[oxzfile stringByAppendingPathComponent:componentName]];
2196 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-sub-failed")];
2203 if (![tmp writeToFile:[path stringByAppendingPathComponent:componentName] atomically:YES])
2206 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-sub-failed")];
2226 [extractionLog appendFormat:DESC(@"oolite-oxzmanager-extract-log-num-u-extracted"),counter];
2227 [extractionLog appendFormat:DESC(@"oolite-oxzmanager-extract-log-extracted-to-@"),path];
2230 return [extractionLog autorelease];
2236- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
2240 _downloadExpected = [response expectedContentLength];
2241 _downloadProgress = 0;
2243 [[NSFileManager defaultManager] createFileAtPath:[
self downloadPath] contents:nil attributes:nil];
2244 _fileWriter = [[NSFileHandle fileHandleForWritingAtPath:[
self downloadPath]] retain];
2245 if (_fileWriter ==
nil)
2249 [
self cancelUpdate];
2254- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
2257 [_fileWriter seekToEndOfFile];
2258 [_fileWriter writeData:data];
2259 _downloadProgress += [data length];
2277 [[NSRunLoop currentRunLoop] limitDateForMode:NSDefaultRunLoopMode];
2282- (void)connectionDidFinishLoading:(NSURLConnection *)connection
2286 [_fileWriter synchronizeFile];
2287 [_fileWriter closeFile];
2292 if (![
self processDownloadedManifests])
2299 if (![
self processDownloadedOXZ])
2306 OOLog(
kOOOXZErrorLog,
@"Error: download completed in unexpected state %d. This is an internal error - please report it.",_interfaceState);
2312- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
2316 [_fileWriter closeFile];
2327NSComparisonResult
oxzSort(
id m1,
id m2,
void *context)
2329 NSComparisonResult result = [[m1 oo_stringForKey:kOOManifestCategory defaultValue:@"zz"] localizedCompare:[m2 oo_stringForKey:kOOManifestCategory defaultValue:@"zz"]];
2330 if (result == NSOrderedSame)
2332 result = [[m1 oo_stringForKey:kOOManifestTitle defaultValue:@"zz"] localizedCompare:[m2 oo_stringForKey:kOOManifestTitle defaultValue:@"zz"]];
2333 if (result == NSOrderedSame)
2335 result = [[m2 oo_stringForKey:kOOManifestVersion defaultValue:@"0"] localizedCompare:[m1 oo_stringForKey:kOOManifestVersion defaultValue:@"0"]];
OOGUITabStop OOGUITabSettings[GUI_MAX_COLUMNS]
static OODebugMonitor * sSingleton
#define OOLog(class, format,...)
static NSString *const kOOManifestAvailableVersion
static NSString *const kOOManifestRelationIdentifier
static NSString *const kOOManifestIdentifier
static NSString *const kOOManifestVersion
static NSString *const kOOManifestFilePath
@ OXZ_STATE_PICK_INSTALLED
static NSString *const kOOOXZFilterDays
static NSString *const kOOOXZErrorLog
static NSString *const kOOOXZFilterTag
static NSString *const kOOOXZFilterKeyword
@ OXZ_INSTALLABLE_DEPENDENCIES
@ OXZ_INSTALLABLE_CONFLICTS
@ OXZ_UNINSTALLABLE_VERSION
@ OXZ_UNINSTALLABLE_ALREADY
@ OXZ_UNINSTALLABLE_NOREMOTE
@ OXZ_UNINSTALLABLE_MANUAL
static NSString *const kOOOXZManifestCache
static NSString *const kOOOXZFilterUpdates
static NSString *const kOOOXZFilterAll
static NSString *const kOOOXZFilterInstallable
static NSString *const kOOOXZTmpPlistPath
static NSString *const kOOOXZFilterAuthor
NSComparisonResult oxzSort(id m1, id m2, void *context)
static NSString *const kOOOXZDataURL
static NSString *const kOOOXZTmpPath
static NSString *const kOOOXZDataConfig
static OOOXZManager * sSingleton
static NSString *const kOOOXZDebugLog
@ OXZ_GUI_ROW_FILTERCURRENT
NSDictionary * OODictionaryFromFile(NSString *path)
NSArray * ComponentsFromVersionString(NSString *string)
NSComparisonResult CompareVersions(NSArray *version1, NSArray *version2)
BOOL setSelectedRow:(OOGUIRow row)
OOGUIRow addLongText:startingAtRow:align:(NSString *str,[startingAtRow] OOGUIRow row,[align] OOGUIAlignment alignment)
void setText:forRow:(NSString *str,[forRow] OOGUIRow row)
void setText:forRow:align:(NSString *str,[forRow] OOGUIRow row,[align] OOGUIAlignment alignment)
void clearAndKeepBackground:(BOOL keepBackground)
void setSelectableRange:(NSRange range)
void setColor:forRow:(OOColor *color,[forRow] OOGUIRow row)
void setTitle:(NSString *str)
void setTabStops:(OOGUITabSettings stops)
void setArray:forRow:(NSArray *arr,[forRow] OOGUIRow row)
void setKey:forRow:(NSString *str,[forRow] OOGUIRow row)
NSString * cacheDirectoryPathCreatingIfNecessary:(BOOL create)
OOCacheManager * sharedCache()
void resetManifestKnowledgeForOXZManager()
NSDictionary * manifestForIdentifier:(NSString *identifier)
NSArray * userRootPaths()
int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)
int ZEXPORT unzGoToFirstFile(unzFile file)
unzFile ZEXPORT unzOpen64(const void *path)
int ZEXPORT unzGoToNextFile(unzFile file)
int ZEXPORT unzClose(unzFile file)