Oolite
Loading...
Searching...
No Matches
OOOXZManager(NSURLConnectionDataDelegate) Category Reference

Instance Methods

(NSString *) - manifestPath
 
(NSString *) - downloadPath
 
(NSString *) - extractionBasePathForIdentifier:andVersion:
 
(NSString *) - dataURL
 
(NSString *) - humanSize:
 
(BOOL) - ensureInstallPath
 
(BOOL) - beginDownload:
 
(BOOL) - processDownloadedManifests
 
(BOOL) - processDownloadedOXZ
 
(OXZInstallableState- installableState:
 
(OOColor *) - colorForManifest:
 
(NSString *) - installStatusForManifest:
 
(BOOL) - validateFilter:
 
(void) - setOXZList:
 
(void) - setFilteredList:
 
(NSArray *) - applyCurrentFilter:
 
(void) - setCurrentDownload:withLabel:
 
(void) - setProgressStatus:
 
(BOOL) - installOXZ:
 
(BOOL) - updateAllOXZ
 
(BOOL) - removeOXZ:
 
(NSArray *) - installOptions
 
(NSArray *) - removeOptions
 
(NSString *) - extractOXZ:
 
(void) - connection:didFailWithError:
 
(void) - connection:didReceiveResponse:
 
(void) - connection:didReceiveData:
 
(void) - connectionDidFinishLoading:
 

Detailed Description

Definition at line 125 of file OOOXZManager.m.

Method Documentation

◆ applyCurrentFilter:

- (NSArray *) applyCurrentFilter: (NSArray *)  list

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

413 :(NSArray *)list
414{
415 SEL filterSelector = @selector(applyFilterByNoFilter:);
416 NSString *parameter = nil;
417 if ([_currentFilter isEqualToString:kOOOXZFilterUpdates])
418 {
419 filterSelector = @selector(applyFilterByUpdateRequired:);
420 }
421 else if ([_currentFilter isEqualToString:kOOOXZFilterInstallable])
422 {
423 filterSelector = @selector(applyFilterByInstallable:);
424 }
425 else if ([_currentFilter hasPrefix:kOOOXZFilterKeyword])
426 {
427 filterSelector = @selector(applyFilterByKeyword:keyword:);
428 parameter = [_currentFilter substringFromIndex:[kOOOXZFilterKeyword length]];
429 }
430 else if ([_currentFilter hasPrefix:kOOOXZFilterAuthor])
431 {
432 filterSelector = @selector(applyFilterByAuthor:author:);
433 parameter = [_currentFilter substringFromIndex:[kOOOXZFilterAuthor length]];
434 }
435 else if ([_currentFilter hasPrefix:kOOOXZFilterDays])
436 {
437 filterSelector = @selector(applyFilterByDays:days:);
438 parameter = [_currentFilter substringFromIndex:[kOOOXZFilterDays length]];
439 }
440 else if ([_currentFilter hasPrefix:kOOOXZFilterTag])
441 {
442 filterSelector = @selector(applyFilterByTag:tag:);
443 parameter = [_currentFilter substringFromIndex:[kOOOXZFilterTag length]];
444 }
445 else if ([_currentFilter hasPrefix:kOOOXZFilterCategory])
446 {
447 filterSelector = @selector(applyFilterByCategory:category:);
448 parameter = [_currentFilter substringFromIndex:[kOOOXZFilterCategory length]];
449 }
450
451 NSMutableArray *filteredList = [NSMutableArray arrayWithCapacity:[list count]];
452 NSDictionary *manifest = nil;
453 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[self class] instanceMethodSignatureForSelector:filterSelector]];
454 [invocation setSelector:filterSelector];
455 [invocation setTarget:self];
456 if (parameter != nil)
457 {
458 [invocation setArgument:&parameter atIndex:3];
459 }
460
461 foreach (manifest, list)
462 {
463 [invocation setArgument:&manifest atIndex:2];
464 [invocation invoke];
465 BOOL filterAccepted = NO;
466 [invocation getReturnValue:&filterAccepted];
467 if (filterAccepted)
468 {
469 [filteredList addObject:manifest];
470 }
471 }
472 // any bad filter that gets this far is also treated as '*'
473 // so don't need to explicitly test for '*' or ''
474 return [[filteredList copy] autorelease];
475}
static NSString *const kOOOXZFilterDays
static NSString *const kOOOXZFilterTag
static NSString *const kOOOXZFilterKeyword
static NSString *const kOOOXZFilterUpdates
static NSString *const kOOOXZFilterCategory
static NSString *const kOOOXZFilterInstallable
static NSString *const kOOOXZFilterAuthor
return nil

◆ beginDownload:

- (BOOL) beginDownload: (NSMutableURLRequest *)  request

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

638 :(NSMutableURLRequest *)request
639{
640 NSString *userAgent = [NSString stringWithFormat:@"Oolite/%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]];
641 [request setValue:userAgent forHTTPHeaderField:@"User-Agent"];
642 [request setHTTPShouldHandleCookies:NO];
643 NSURLConnection *download = [[NSURLConnection alloc] initWithRequest:request delegate:self];
644 if (download)
645 {
646 _downloadProgress = 0;
647 _downloadExpected = 0;
648 NSString *label = DESC(@"oolite-oxzmanager-download-label-list");
649 if (_interfaceState != OXZ_STATE_UPDATING)
650 {
651 NSDictionary *expectedManifest = nil;
652 expectedManifest = [_filteredList objectAtIndex:_item];
653
654 label = [expectedManifest oo_stringForKey:kOOManifestTitle defaultValue:DESC(@"oolite-oxzmanager-download-label-oxz")];
655 }
656
657 [self setCurrentDownload:download withLabel:label]; // retains it
658 [download release];
659 OOLog(kOOOXZDebugLog,@"Download request received, using %@ and downloading to %@",[request URL],[self downloadPath]);
660 return YES;
661 }
662 else
663 {
664 OOLog(kOOOXZErrorLog,@"Unable to start downloading file at %@",[request URL]);
665 _downloadStatus = OXZ_DOWNLOAD_ERROR;
666 return NO;
667 }
668}
#define OOLog(class, format,...)
Definition OOLogging.h:88
@ OXZ_STATE_UPDATING
@ OXZ_DOWNLOAD_ERROR
static NSString *const kOOOXZErrorLog
static NSString *const kOOOXZDebugLog
#define DESC(key)
Definition Universe.h:848

◆ colorForManifest:

- (OOColor *) colorForManifest: (NSDictionary *)  manifest

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

1103 :(NSDictionary *)manifest
1104{
1105 switch ([self installableState:manifest])
1106 {
1108 return [OOColor yellowColor];
1110 return [OOColor cyanColor];
1112 return [OOColor orangeColor];
1114 return [OOColor brownColor];
1116 return [OOColor whiteColor];
1118 return [OOColor redColor];
1120 return [OOColor grayColor];
1122 return [OOColor blueColor];
1123 }
1124 return [OOColor yellowColor]; // never
1125}
@ OXZ_INSTALLABLE_UPDATE
@ OXZ_INSTALLABLE_DEPENDENCIES
@ OXZ_INSTALLABLE_CONFLICTS
@ OXZ_INSTALLABLE_OKAY
@ OXZ_UNINSTALLABLE_VERSION
@ OXZ_UNINSTALLABLE_ALREADY
@ OXZ_UNINSTALLABLE_NOREMOTE
@ OXZ_UNINSTALLABLE_MANUAL
OOColor * cyanColor()
Definition OOColor.m:286
OOColor * orangeColor()
Definition OOColor.m:304
OOColor * redColor()
Definition OOColor.m:268
OOColor * blueColor()
Definition OOColor.m:280
OOColor * grayColor()
Definition OOColor.m:262
OOColor * whiteColor()
Definition OOColor.m:256
OOColor * brownColor()
Definition OOColor.m:316
OOColor * yellowColor()
Definition OOColor.m:292

◆ connection:didFailWithError:

- (void) connection: (NSURLConnection *)  connection
didFailWithError: (NSError *)  error 

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

2393 :(NSURLConnection *)connection didFailWithError:(NSError *)error
2394{
2395 _downloadStatus = OXZ_DOWNLOAD_ERROR;
2396 OOLog(kOOOXZErrorLog,@"Error downloading file: %@",[error description]);
2397 [_fileWriter closeFile];
2398 DESTROY(_fileWriter);
2399 DESTROY(_currentDownload);
2400}
#define DESTROY(x)
Definition OOCocoa.h:75

◆ connection:didReceiveData:

- (void) connection: (NSURLConnection *)  connection
didReceiveData: (NSData *)  data 

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

2335 :(NSURLConnection *)connection didReceiveData:(NSData *)data
2336{
2337 OOLog(kOOOXZDebugLog,@"Downloaded %llu bytes",[data length]);
2338 [_fileWriter seekToEndOfFile];
2339 [_fileWriter writeData:data];
2340 _downloadProgress += [data length];
2341 [self gui]; // update GUI
2342#if OOLITE_WINDOWS
2343 /* Irritating fix to issue https://github.com/OoliteProject/oolite/issues/95
2344 *
2345 * The problem is that on MINGW, GNUStep makes all socket streams
2346 * blocking, which causes problems with the run loop. Calling this
2347 * method of the run loop forces it to execute all already
2348 * scheduled items with a time in the past, before any more items
2349 * are placed on it, which means that the main game update gets a
2350 * chance to run.
2351 *
2352 * This stops the interface freezing - and Oolite appearing to
2353 * have stopped responding to the OS - when downloading large
2354 * (>20Mb) OXZ files.
2355 *
2356 * CIM 6 July 2014
2357 */
2358 [[NSRunLoop currentRunLoop] limitDateForMode:NSDefaultRunLoopMode];
2359#endif
2360}

◆ connection:didReceiveResponse:

- (void) connection: (NSURLConnection *)  connection
didReceiveResponse: (NSURLResponse *)  response 

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

2317 :(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
2318{
2319 _downloadStatus = OXZ_DOWNLOAD_RECEIVING;
2320 OOLog(kOOOXZDebugLog, @"%@", @"Download receiving");
2321 _downloadExpected = [response expectedContentLength];
2322 _downloadProgress = 0;
2323 DESTROY(_fileWriter);
2324 [[NSFileManager defaultManager] createFileAtPath:[self downloadPath] contents:nil attributes:nil];
2325 _fileWriter = [[NSFileHandle fileHandleForWritingAtPath:[self downloadPath]] retain];
2326 if (_fileWriter == nil)
2327 {
2328 // file system is full or read-only or something
2329 OOLog(kOOOXZErrorLog, @"%@", @"Unable to create download file");
2330 [self cancelUpdate];
2331 }
2332}
@ OXZ_DOWNLOAD_RECEIVING

◆ connectionDidFinishLoading:

- (void) connectionDidFinishLoading: (NSURLConnection *)  connection

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

2363 :(NSURLConnection *)connection
2364{
2365 _downloadStatus = OXZ_DOWNLOAD_COMPLETE;
2366 OOLog(kOOOXZDebugLog, @"%@", @"Download complete");
2367 [_fileWriter synchronizeFile];
2368 [_fileWriter closeFile];
2369 DESTROY(_fileWriter);
2370 DESTROY(_currentDownload);
2371 if (_interfaceState == OXZ_STATE_UPDATING)
2372 {
2373 if (![self processDownloadedManifests])
2374 {
2375 _downloadStatus = OXZ_DOWNLOAD_ERROR;
2376 }
2377 }
2378 else if (_interfaceState == OXZ_STATE_INSTALLING)
2379 {
2380 if (![self processDownloadedOXZ])
2381 {
2382 _downloadStatus = OXZ_DOWNLOAD_ERROR;
2383 }
2384 }
2385 else
2386 {
2387 OOLog(kOOOXZErrorLog,@"Error: download completed in unexpected state %d. This is an internal error - please report it.",_interfaceState);
2388 _downloadStatus = OXZ_DOWNLOAD_ERROR;
2389 }
2390}
@ OXZ_STATE_INSTALLING
@ OXZ_DOWNLOAD_COMPLETE

◆ dataURL

- (NSString *) dataURL

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

355{
356 /* Not expected to be set in general, but might be useful for some users */
357 NSString *url = [[NSUserDefaults standardUserDefaults] stringForKey:kOOOXZDataConfig];
358 if (url != nil)
359 {
360 return url;
361 }
362 return kOOOXZDataURL;
363}
static NSString *const kOOOXZDataURL

◆ downloadPath

- (NSString *) downloadPath

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

342{
343 if (_interfaceState == OXZ_STATE_UPDATING)
344 {
345 return [[[OOCacheManager sharedCache] cacheDirectoryPathCreatingIfNecessary:YES] stringByAppendingPathComponent:kOOOXZTmpPlistPath];
346 }
347 else
348 {
349 return [[[OOCacheManager sharedCache] cacheDirectoryPathCreatingIfNecessary:YES] stringByAppendingPathComponent:kOOOXZTmpPath];
350 }
351}
NSString * cacheDirectoryPathCreatingIfNecessary:(BOOL create)
OOCacheManager * sharedCache()

◆ ensureInstallPath

- (BOOL) ensureInstallPath

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

307{
308 BOOL exists, directory;
309 NSFileManager *fmgr = [NSFileManager defaultManager];
310 NSString *path = [self installPath];
311
312 exists = [fmgr fileExistsAtPath:path isDirectory:&directory];
313
314 if (exists && !directory)
315 {
316 OOLog(kOOOXZErrorLog, @"Expected %@ to be a folder, but it is a file.", path);
317 return NO;
318 }
319 if (!exists)
320 {
321 if (![fmgr oo_createDirectoryAtPath:path attributes:nil])
322 {
323 OOLog(kOOOXZErrorLog, @"Could not create folder %@.", path);
324 return NO;
325 }
326 }
327
328 return YES;
329}

◆ extractionBasePathForIdentifier:andVersion:

- (NSString *) extractionBasePathForIdentifier: (NSString *)  identifier
andVersion: (NSString *)  version 

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

296 :(NSString *)identifier andVersion:(NSString *)version
297{
298 NSString *basePath = [[ResourceManager userRootPaths] lastObject];
299 NSString *rawMainDir = [NSString stringWithFormat:@"%@-%@.off",identifier,version];
300
301 NSCharacterSet *blacklist = [NSCharacterSet characterSetWithCharactersInString:@"'#%^&{}[]/~|\\?<,:\" "];
302 return [[[basePath stringByAppendingPathComponent:[[rawMainDir componentsSeparatedByCharactersInSet:blacklist] componentsJoinedByString:@""]] retain] autorelease];
303}
NSArray * userRootPaths()

◆ extractOXZ:

- (NSString *) extractOXZ: (NSUInteger)  item

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

2182 :(NSUInteger)item
2183{
2184 NSFileManager *fmgr = [NSFileManager defaultManager];
2185 NSMutableString *extractionLog = [[NSMutableString alloc] init];
2186 NSDictionary *manifest = [_filteredList oo_dictionaryAtIndex:item];
2187 NSString *version = [manifest oo_stringForKey:kOOManifestVersion];
2188 NSString *identifier = [manifest oo_stringForKey:kOOManifestIdentifier];
2189 NSString *path = [self extractionBasePathForIdentifier:identifier andVersion:version];
2190
2191 // OXZ errors should really never happen unless someone is messing
2192 // directly with the managed folder while Oolite is running, but
2193 // it's possible.
2194
2195 NSString *oxzfile = [manifest oo_stringForKey:kOOManifestFilePath];
2196 if (![fmgr fileExistsAtPath:oxzfile])
2197 {
2198 OOLog(kOOOXZErrorLog,@"OXZ %@ could not be found",oxzfile);
2199 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-no-original")];
2200 return [extractionLog autorelease];
2201 }
2202 const char* zipname = [oxzfile UTF8String];
2203 unzFile uf = NULL;
2204 uf = unzOpen64(zipname);
2205 if (uf == NULL)
2206 {
2207 OOLog(kOOOXZErrorLog,@"Could not open .oxz at %@ as zip file",path);
2208 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-bad-original")];
2209 return [extractionLog autorelease];
2210 }
2211
2212 if ([fmgr fileExistsAtPath:path])
2213 {
2214 OOLog(kOOOXZErrorLog,@"Path %@ already exists",path);
2215 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-main-exists")];
2216 unzClose(uf);
2217 return [extractionLog autorelease];
2218 }
2219 if (![fmgr oo_createDirectoryAtPath:path attributes:nil])
2220 {
2221 OOLog(kOOOXZErrorLog,@"Path %@ could not be created",path);
2222 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-main-unmakeable")];
2223 unzClose(uf);
2224 return [extractionLog autorelease];
2225 }
2226 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-main-created")];
2227 NSUInteger counter = 0;
2228 char rawComponentName[512];
2229 BOOL error = NO;
2230 unz_file_info64 file_info = {0};
2231 if (unzGoToFirstFile(uf) == UNZ_OK)
2232 {
2233 do
2234 {
2235 unzGetCurrentFileInfo64(uf, &file_info,
2236 rawComponentName, 512,
2237 NULL, 0,
2238 NULL, 0);
2239 NSString *componentName = [NSString stringWithUTF8String:rawComponentName];
2240 if ([componentName hasSuffix:@"/"])
2241 {
2242 // folder
2243 if (![fmgr oo_createDirectoryAtPath:[path stringByAppendingPathComponent:componentName] attributes:nil])
2244 {
2245 OOLog(kOOOXZErrorLog,@"Subpath %@ could not be created",componentName);
2246 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-sub-failed")];
2247 error = YES;
2248 break;
2249 }
2250 else
2251 {
2252 OOLog(kOOOXZDebugLog,@"Subpath %@ created OK",componentName);
2253 }
2254 }
2255 else
2256 {
2257 // file
2258 // usually folder must now exist, but just in case...
2259 NSString *folder = [[path stringByAppendingPathComponent:componentName] stringByDeletingLastPathComponent];
2260 if ([folder length] > 0 && ![fmgr fileExistsAtPath:folder] && ![fmgr oo_createDirectoryAtPath:folder attributes:nil])
2261 {
2262 OOLog(kOOOXZErrorLog,@"Subpath %@ could not be created",folder);
2263 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-sub-failed")];
2264 error = YES;
2265 break;
2266 }
2267
2268
2269 // This is less efficient in memory use than just
2270 // streaming out of the ZIP file onto disk
2271 // but it makes error handling easier
2272 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
2273 NSData *tmp = [NSData oo_dataWithOXZFile:[oxzfile stringByAppendingPathComponent:componentName]];
2274 if (tmp == nil)
2275 {
2276 OOLog(kOOOXZErrorLog,@"Sub file %@ could not be extracted from the OXZ",componentName);
2277 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-sub-failed")];
2278 error = YES;
2279 [pool release];
2280 break;
2281 }
2282 else
2283 {
2284 if (![tmp writeToFile:[path stringByAppendingPathComponent:componentName] atomically:YES])
2285 {
2286 OOLog(kOOOXZErrorLog,@"Sub file %@ could not be created",componentName);
2287 [extractionLog appendString:DESC(@"oolite-oxzmanager-extract-log-sub-failed")];
2288 error = YES;
2289 [pool release];
2290 break;
2291 }
2292 else
2293 {
2294 ++counter;
2295 }
2296 }
2297 [pool release];
2298
2299 }
2300 }
2301 while (unzGoToNextFile(uf) == UNZ_OK);
2302 }
2303 unzClose(uf);
2304
2305 if (!error)
2306 {
2307 [extractionLog appendFormat:DESC(@"oolite-oxzmanager-extract-log-num-u-extracted"),counter];
2308 [extractionLog appendFormat:DESC(@"oolite-oxzmanager-extract-log-extracted-to-@"),path];
2309 }
2310
2311 return [extractionLog autorelease];
2312}
int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)
Definition unzip.c:1130
int ZEXPORT unzGoToFirstFile(unzFile file)
Definition unzip.c:1184
unzFile ZEXPORT unzOpen64(const void *path)
Definition unzip.c:801
int ZEXPORT unzGoToNextFile(unzFile file)
Definition unzip.c:1205
int ZEXPORT unzClose(unzFile file)
Definition unzip.c:811
voidp unzFile
Definition unzip.h:70
#define UNZ_OK
Definition unzip.h:74

◆ humanSize:

- (NSString *) humanSize: (NSUInteger)  bytes

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

366 :(NSUInteger)bytes
367{
368 if (bytes == 0)
369 {
370 return DESC(@"oolite-oxzmanager-missing-field");
371 }
372 else if (bytes < 1024)
373 {
374 return @"<1 kB";
375 }
376 else if (bytes < 1024*1024)
377 {
378 return [NSString stringWithFormat:@"%llu kB",bytes>>10];
379 }
380 else
381 {
382 return [NSString stringWithFormat:@"%.2f MB",((float)(bytes>>10))/1024];
383 }
384}

◆ installableState:

- (OXZInstallableState) installableState: (NSDictionary *)  manifest

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

1036 :(NSDictionary *)manifest
1037{
1038 NSString *title = [manifest oo_stringForKey:kOOManifestTitle defaultValue:nil];
1039 NSString *identifier = [manifest oo_stringForKey:kOOManifestIdentifier defaultValue:nil];
1040 /* Check Oolite version */
1041 if (![ResourceManager checkVersionCompatibility:manifest forOXP:title])
1042 {
1044 }
1045 /* Check for current automated install */
1046 NSDictionary *installed = [self installedManifestForIdentifier:identifier];
1047 if (installed == nil)
1048 {
1049 // check for manual install
1050 installed = [ResourceManager manifestForIdentifier:identifier];
1051 }
1052
1053 if (installed != nil)
1054 {
1055 if (![[installed oo_stringForKey:kOOManifestFilePath] hasPrefix:[self installPath]])
1056 {
1057 // installed manually
1059 }
1060 if ([[installed oo_stringForKey:kOOManifestVersion] isEqualToString:[manifest oo_stringForKey:kOOManifestAvailableVersion defaultValue:[manifest oo_stringForKey:kOOManifestVersion]]]
1061 && [[NSFileManager defaultManager] fileExistsAtPath:[installed oo_stringForKey:kOOManifestFilePath]])
1062 {
1063 // installed this exact version already, and haven't
1064 // uninstalled it since entering the manager, and it's
1065 // still available
1067 }
1068 else if ([installed oo_stringForKey:kOOManifestAvailableVersion defaultValue:nil] == nil)
1069 {
1070 // installed, but no remote copy is indexed any more
1072 }
1073 }
1074 /* Check for dependencies being met */
1075 if ([ResourceManager manifestHasConflicts:manifest logErrors:NO])
1076 {
1078 }
1079 if (installed != nil)
1080 {
1081 NSString *availableVersion = [manifest oo_stringForKey:kOOManifestAvailableVersion];
1082 if (availableVersion == nil)
1083 {
1084 availableVersion = [manifest oo_stringForKey:kOOManifestVersion];
1085 }
1086 NSString *installedVersion = [installed oo_stringForKey:kOOManifestVersion];
1087 OOLog(@"version.debug",@"%@ mv:%@ mav:%@",identifier,installedVersion,availableVersion);
1088 if (CompareVersions(ComponentsFromVersionString(installedVersion),ComponentsFromVersionString(availableVersion)) == NSOrderedDescending)
1089 {
1090 // the installed copy is more recent than the server copy
1092 }
1094 }
1095 if ([ResourceManager manifestHasMissingDependencies:manifest logErrors:NO])
1096 {
1098 }
1099 return OXZ_INSTALLABLE_OKAY;
1100}
static NSString *const kOOManifestAvailableVersion
static NSString *const kOOManifestVersion
static NSString *const kOOManifestFilePath
return self
NSArray * ComponentsFromVersionString(NSString *string)
NSComparisonResult CompareVersions(NSArray *version1, NSArray *version2)
NSDictionary * manifestForIdentifier:(NSString *identifier)

◆ installOptions

- (NSArray *) installOptions

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

1762{
1763 NSUInteger start = _offset;
1764 if (start >= [_filteredList count])
1765 {
1766 start = 0;
1767 _offset = 0;
1768 }
1769 NSUInteger end = start + OXZ_GUI_NUM_LISTROWS;
1770 if (end > [_filteredList count])
1771 {
1772 end = [_filteredList count];
1773 }
1774 return [_filteredList subarrayWithRange:NSMakeRange(start,end-start)];
1775}
@ OXZ_GUI_NUM_LISTROWS
unsigned count

◆ installOXZ:

- (BOOL) installOXZ: (NSUInteger)  item

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

1694 :(NSUInteger)item
1695{
1696 NSArray *picklist = _filteredList;
1697
1698 if ([picklist count] <= item)
1699 {
1700 return NO;
1701 }
1702 NSDictionary *manifest = [picklist objectAtIndex:item];
1703 _item = item;
1704
1705 if ([self installableState:manifest] >= OXZ_UNINSTALLABLE_ALREADY)
1706 {
1707 OOLog(kOOOXZDebugLog,@"Cannot install %@",manifest);
1708 // can't be installed on this version of Oolite, or already is installed
1709 return NO;
1710 }
1711 NSString *url = [manifest objectForKey:kOOManifestDownloadURL];
1712 if (url == nil)
1713 {
1714 OOLog(kOOOXZErrorLog, @"%@", @"Manifest does not have a download URL - cannot install");
1715 return NO;
1716 }
1717 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
1718 if (_downloadStatus != OXZ_DOWNLOAD_NONE)
1719 {
1720 return NO;
1721 }
1722 _downloadStatus = OXZ_DOWNLOAD_STARTED;
1723 _interfaceState = OXZ_STATE_INSTALLING;
1724
1725 [self setProgressStatus:@""];
1726 return [self beginDownload:request];
1727}
@ OXZ_DOWNLOAD_STARTED
@ OXZ_DOWNLOAD_NONE

◆ installStatusForManifest:

- (NSString *) installStatusForManifest: (NSDictionary *)  manifest

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

1128 :(NSDictionary *)manifest
1129{
1130 switch ([self installableState:manifest])
1131 {
1133 return DESC(@"oolite-oxzmanager-installable-okay");
1135 return DESC(@"oolite-oxzmanager-installable-update");
1137 return DESC(@"oolite-oxzmanager-installable-depend");
1139 return DESC(@"oolite-oxzmanager-installable-conflicts");
1141 return DESC(@"oolite-oxzmanager-installable-already");
1143 return DESC(@"oolite-oxzmanager-installable-manual");
1145 return DESC(@"oolite-oxzmanager-installable-version");
1147 return DESC(@"oolite-oxzmanager-installable-noremote");
1148 }
1149 return nil; // never
1150}

◆ manifestPath

- (NSString *) manifestPath

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

333{
334 return [[[OOCacheManager sharedCache] cacheDirectoryPathCreatingIfNecessary:YES] stringByAppendingPathComponent:kOOOXZManifestCache];
335}

◆ processDownloadedManifests

- (BOOL) processDownloadedManifests

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

761{
762 if (_downloadStatus != OXZ_DOWNLOAD_COMPLETE)
763 {
764 return NO;
765 }
766 [self setOXZList:OOArrayFromFile([self downloadPath])];
767 if (_oxzList != nil)
768 {
769 [_oxzList writeToFile:[self manifestPath] atomically:YES];
770 // and clean up the temp file
771 [[NSFileManager defaultManager] oo_removeItemAtPath:[self downloadPath]];
772 // invalidate the managed list
773 DESTROY(_managedList);
774 _interfaceState = OXZ_STATE_TASKDONE;
775 [self gui];
776 return YES;
777 }
778 else
779 {
780 _downloadStatus = OXZ_DOWNLOAD_ERROR;
781 OOLog(kOOOXZErrorLog,@"Downloaded manifest was not a valid plist, has been left in %@",[self downloadPath]);
782 // revert to the old one
783 [self setOXZList:OOArrayFromFile([self manifestPath])];
784 _interfaceState = OXZ_STATE_TASKDONE;
785 [self gui];
786 return NO;
787 }
788}
@ OXZ_STATE_TASKDONE

◆ processDownloadedOXZ

- (BOOL) processDownloadedOXZ

If downloadedManifest is in _dependencyStack, remove it Get downloadedManifest requires_oxp list Add entries ones to _dependencyStack If _dependencyStack has contents, update _progressStatus ...and start the download of the 'first' item in _dependencyStack ...which isn't already installed (_dependencyStack is unordered ...so 'first' isn't really defined)

...if the item in _dependencyStack is not findable (e.g. wrong ...version) then stop here.

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

792{
793 if (_downloadStatus != OXZ_DOWNLOAD_COMPLETE)
794 {
795 return NO;
796 }
797
798 NSDictionary *downloadedManifest = OODictionaryFromFile([[self downloadPath] stringByAppendingPathComponent:@"manifest.plist"]);
799 if (downloadedManifest == nil)
800 {
801 _downloadStatus = OXZ_DOWNLOAD_ERROR;
802 OOLog(kOOOXZErrorLog,@"Downloaded OXZ does not contain a manifest.plist, has been left in %@",[self downloadPath]);
803 _interfaceState = OXZ_STATE_TASKDONE;
804 [self gui];
805 return NO;
806 }
807 NSDictionary *expectedManifest = nil;
808 expectedManifest = [_filteredList objectAtIndex:_item];
809
810 if (expectedManifest == nil ||
811 (![[downloadedManifest oo_stringForKey:kOOManifestIdentifier] isEqualToString:[expectedManifest oo_stringForKey:kOOManifestIdentifier]]) ||
812 (![[downloadedManifest oo_stringForKey:kOOManifestVersion] isEqualToString:[expectedManifest oo_stringForKey:kOOManifestAvailableVersion defaultValue:[expectedManifest oo_stringForKey:kOOManifestVersion]]])
813 )
814 {
815 _downloadStatus = OXZ_DOWNLOAD_ERROR;
816 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.");
817 _interfaceState = OXZ_STATE_TASKDONE;
818 [self gui];
819 return NO;
820 }
821 // this appears to be the OXZ we expected
822 // filename is going to be identifier.oxz
823 NSString *filename = [[downloadedManifest oo_stringForKey:kOOManifestIdentifier] stringByAppendingString:@".oxz"];
824
825 if (![self ensureInstallPath])
826 {
827 _downloadStatus = OXZ_DOWNLOAD_ERROR;
828 OOLog(kOOOXZErrorLog, @"%@", @"Unable to create installation folder.");
829 _interfaceState = OXZ_STATE_TASKDONE;
830 [self gui];
831 return NO;
832 }
833
834 // delete filename if it exists from OXZ folder
835 NSString *destination = [[self installPath] stringByAppendingPathComponent:filename];
836 [[NSFileManager defaultManager] oo_removeItemAtPath:destination];
837
838 // move the temp file on to it
839 if (![[NSFileManager defaultManager] oo_moveItemAtPath:[self downloadPath] toPath:destination])
840 {
841 _downloadStatus = OXZ_DOWNLOAD_ERROR;
842 OOLog(kOOOXZErrorLog, @"%@", @"Downloaded OXZ could not be installed.");
843 _interfaceState = OXZ_STATE_TASKDONE;
844 [self gui];
845 return NO;
846 }
847 _changesMade = YES;
848 DESTROY(_managedList); // will need updating
849 // do this now to cope with circular dependencies on download
851
864 NSArray *requires = [downloadedManifest oo_arrayForKey:kOOManifestRequiresOXPs defaultValue:nil];
865 if (requires == nil)
866 {
867 // just in case the requirements are only specified in the online copy
868 requires = [expectedManifest oo_arrayForKey:kOOManifestRequiresOXPs defaultValue:nil];
869 }
870 NSDictionary *requirement = nil;
871 NSMutableString *progress = [NSMutableString stringWithCapacity:2048];
872 OOLog(kOOOXZDebugLog,@"Dependency stack has %llu elements",[_dependencyStack count]);
873
874 if ([_dependencyStack count] > 0)
875 {
876 // will remove as iterate, so create a temp copy to iterate over
877 NSSet *tempStack = [NSSet setWithSet:_dependencyStack];
878 foreach (requirement, tempStack)
879 {
880 OOLog(kOOOXZDebugLog,@"Dependency stack: checking %@",[requirement oo_stringForKey:kOOManifestRelationIdentifier]);
881 if (![ResourceManager manifest:downloadedManifest HasUnmetDependency:requirement logErrors:NO]
882 && requires != nil && [requires containsObject:requirement])
883 {
884 // it was unmet, but now it's met
885 [progress appendFormat:DESC(@"oolite-oxzmanager-progress-now-has-@"),[requirement oo_stringForKey:kOOManifestRelationDescription defaultValue:[requirement oo_stringForKey:kOOManifestRelationIdentifier]]];
886 [_dependencyStack removeObject:requirement];
887 OOLog(kOOOXZDebugLog, @"%@", @"Dependency stack: requirement met");
888 } else if ([[requirement oo_stringForKey:kOOManifestRelationIdentifier] isEqualToString:[downloadedManifest oo_stringForKey:kOOManifestIdentifier]]) {
889 // remove the requirement for the just downloaded OXP
890 [_dependencyStack removeObject:requirement];
891 }
892 }
893 }
894 if (requires != nil)
895 {
896 foreach (requirement, requires)
897 {
898 if ([ResourceManager manifest:downloadedManifest HasUnmetDependency:requirement logErrors:NO])
899 {
900 OOLog(kOOOXZDebugLog,@"Dependency stack: adding %@",[requirement oo_stringForKey:kOOManifestRelationIdentifier]);
901 [_dependencyStack addObject:requirement];
902 [progress appendFormat:DESC(@"oolite-oxzmanager-progress-requires-@"),[requirement oo_stringForKey:kOOManifestRelationDescription defaultValue:[requirement oo_stringForKey:kOOManifestRelationIdentifier]]];
903 }
904 }
905 }
906 if ([_dependencyStack count] > 0)
907 {
908 // get an object from the requirements list, and download it
909 // if it can be found
910 BOOL undownloadedRequirement = NO;
911 NSDictionary *availableDownload = nil;
912 BOOL foundDownload = NO;
913 NSUInteger index = 0;
914 NSString *needsIdentifier = nil;
915
916 do
917 {
918 undownloadedRequirement = YES;
919 requirement = [_dependencyStack anyObject];
920 OOLog(kOOOXZDebugLog,@"Dependency stack: next is %@",[requirement oo_stringForKey:kOOManifestRelationIdentifier]);
921
922 if (!_downloadAllDependencies)
923 {
924 [progress appendString:DESC(@"oolite-oxzmanager-progress-get-required")];
925 }
926 needsIdentifier = [requirement oo_stringForKey:kOOManifestRelationIdentifier];
927
928 foreach (availableDownload, _oxzList)
929 {
930 if ([[availableDownload oo_stringForKey:kOOManifestIdentifier] isEqualToString:needsIdentifier])
931 {
932 if ([ResourceManager matchVersions:requirement withVersion:[availableDownload oo_stringForKey:kOOManifestVersion]])
933 {
934 OOLog(kOOOXZDebugLog, @"%@", @"Dependency stack: found download for next item");
935 foundDownload = YES;
936 index = [_oxzList indexOfObject:availableDownload];
937 break;
938 }
939 }
940 }
941
942 if (foundDownload)
943 {
944 if ([self installableState:[_oxzList objectAtIndex:index]] == OXZ_UNINSTALLABLE_ALREADY)
945 {
946 OOLog(kOOOXZDebugLog,@"Dependency stack: %@ is downloaded but not yet loadable, removing from list.",[requirement oo_stringForKey:kOOManifestRelationIdentifier]);
947 // then this has already been downloaded, but
948 // can't be configured yet presumably because
949 // another dependency is still to be loaded
950 [_dependencyStack removeObject:requirement];
951 if ([_dependencyStack count] > 0)
952 {
953 // try again
954 undownloadedRequirement = NO;
955 }
956 else
957 {
958 // this case should probably never happen
959 // is handled below just in case
960 foundDownload = NO;
961 }
962 }
963 }
964 }
965 while (!undownloadedRequirement);
966
967 if (foundDownload)
968 {
969 // must clear filters entirely at this point
970 [self setFilteredList:_oxzList];
971 // then download that item
972 _downloadStatus = OXZ_DOWNLOAD_NONE;
973 if (_downloadAllDependencies)
974 {
975 OOLog(kOOOXZDebugLog,@"Dependency stack: installing %llu from list",index);
976 if (![self installOXZ:index]) {
977 // if a required dependency is somehow uninstallable
978 // e.g. required+maximum version don't match this Oolite
979 [progress appendFormat:DESC(@"oolite-oxzmanager-progress-required-@-not-found"),[requirement oo_stringForKey:kOOManifestRelationDescription defaultValue:[requirement oo_stringForKey:kOOManifestRelationIdentifier]]];
980 [self setProgressStatus:progress];
981 OOLog(kOOOXZErrorLog,@"OXZ dependency %@ could not be found for automatic download.",needsIdentifier);
982 _downloadStatus = OXZ_DOWNLOAD_ERROR;
983 OOLog(kOOOXZErrorLog, @"%@", @"Downloaded OXZ could not be installed.");
984 _interfaceState = OXZ_STATE_TASKDONE;
985 [self gui];
986 return NO;
987 }
988 }
989 else
990 {
991 _interfaceState = OXZ_STATE_DEPENDENCIES;
992 _item = index;
993 }
994 [self setProgressStatus:progress];
995 [self gui];
996 return YES;
997 }
998 // this is probably always the case, see above
999 else if ([_dependencyStack count] > 0)
1000 {
1001 [progress appendFormat:DESC(@"oolite-oxzmanager-progress-required-@-not-found"),[requirement oo_stringForKey:kOOManifestRelationDescription defaultValue:[requirement oo_stringForKey:kOOManifestRelationIdentifier]]];
1002 [self setProgressStatus:progress];
1003 OOLog(kOOOXZErrorLog,@"OXZ dependency %@ could not be found for automatic download.",needsIdentifier);
1004 _downloadStatus = OXZ_DOWNLOAD_ERROR;
1005 OOLog(kOOOXZErrorLog, @"%@", @"Downloaded OXZ could not be installed.");
1006 _interfaceState = OXZ_STATE_TASKDONE;
1007 [self gui];
1008 return NO;
1009 }
1010 }
1011
1012 [self setProgressStatus:@""];
1013 _interfaceState = OXZ_STATE_TASKDONE;
1014 [_dependencyStack removeAllObjects]; // just in case
1015 _downloadAllDependencies = NO;
1016 [self gui];
1017 return YES;
1018}
static NSString *const kOOManifestRelationIdentifier
static NSString *const kOOManifestIdentifier
@ OXZ_STATE_DEPENDENCIES
NSDictionary * OODictionaryFromFile(NSString *path)
void resetManifestKnowledgeForOXZManager()
const char * filename
Definition ioapi.h:133

◆ removeOptions

- (NSArray *) removeOptions

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

1983{
1984 NSArray *remList = _filteredList;
1985 if ([remList count] == 0)
1986 {
1987 return nil;
1988 }
1989 NSUInteger start = _offset;
1990 if (start >= [remList count])
1991 {
1992 start = 0;
1993 _offset = 0;
1994 }
1995 NSUInteger end = start + OXZ_GUI_NUM_LISTROWS;
1996 if (end > [remList count])
1997 {
1998 end = [remList count];
1999 }
2000 return [remList subarrayWithRange:NSMakeRange(start,end-start)];
2001}

◆ removeOXZ:

- (BOOL) removeOXZ: (NSUInteger)  item

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

1954 :(NSUInteger)item
1955{
1956 NSArray *remList = _filteredList;
1957 if ([remList count] <= item)
1958 {
1959 OOLog(kOOOXZDebugLog, @"Unable to remove item %lu as only %lu in list", (unsigned long)item, (unsigned long)[remList count]);
1960 return NO;
1961 }
1962 NSString *filename = [[remList objectAtIndex:item] oo_stringForKey:kOOManifestFilePath];
1963 if (filename == nil)
1964 {
1965 OOLog(kOOOXZDebugLog, @"Unable to remove item %lu as filename not found", (unsigned long)item);
1966 return NO;
1967 }
1968
1969 if (![[NSFileManager defaultManager] oo_removeItemAtPath:filename])
1970 {
1971 OOLog(kOOOXZErrorLog, @"Unable to remove file %@", filename);
1972 return NO;
1973 }
1974 _changesMade = YES;
1975 DESTROY(_managedList); // will need updating
1976 _interfaceState = OXZ_STATE_REMOVING;
1977 [self gui];
1978 return YES;
1979}
@ OXZ_STATE_REMOVING

◆ setCurrentDownload:withLabel:

- (void) setCurrentDownload: (NSURLConnection *)  download
withLabel: (NSString *)  label 

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

605 :(NSURLConnection *)download withLabel:(NSString *)label
606{
607 if (_currentDownload != nil)
608 {
609 [_currentDownload cancel]; // releases via delegate
610 }
611 _currentDownload = [download retain];
612 DESTROY(_currentDownloadName);
613 _currentDownloadName = [label copy];
614}

◆ setFilteredList:

- (void) setFilteredList: (NSArray *)  list

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

399 :(NSArray *)list
400{
401 DESTROY(_filteredList);
402 _filteredList = [list copy]; // copy retains
403}

◆ setOXZList:

- (void) setOXZList: (NSArray *)  list

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

387 :(NSArray *)list
388{
389 DESTROY(_oxzList);
390 if (list != nil)
391 {
392 _oxzList = [[list sortedArrayUsingFunction:oxzSort context:NULL] retain];
393 // needed for update to available versions
394 DESTROY(_managedList);
395 }
396}

◆ setProgressStatus:

- (void) setProgressStatus: (NSString *)  newStatus

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

617 :(NSString *)new
618{
619 DESTROY(_progressStatus);
620 _progressStatus = [new copy];
621}

◆ updateAllOXZ

- (BOOL) updateAllOXZ

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

1731{
1732 [_dependencyStack removeAllObjects];
1733 _downloadAllDependencies = YES;
1734 [self setFilteredList:_oxzList];
1735 NSDictionary *manifest = nil;
1736
1737 foreach (manifest,_oxzList)
1738 {
1739 if ([self installableState:manifest] == OXZ_INSTALLABLE_UPDATE)
1740 {
1741 OOLog(kOOOXZDebugLog, @"Queuing in for update: %@", manifest);
1742 [_dependencyStack addObject:manifest];
1743 }
1744 }
1745 NSDictionary *first = [_dependencyStack anyObject];
1746 NSString* identifier = [first oo_stringForKey:kOOManifestRelationIdentifier];
1747 NSUInteger item = NSUIntegerMax;
1748 NSDictionary *availableDownload = nil;
1749 foreach (availableDownload, _oxzList)
1750 {
1751 if ([[availableDownload oo_stringForKey:kOOManifestIdentifier] isEqualToString:identifier])
1752 {
1753 item = [_oxzList indexOfObject:availableDownload];
1754 break;
1755 }
1756 }
1757 return [self installOXZ:item];
1758}

◆ validateFilter:

- (BOOL) validateFilter: (NSString *)  input

Extends class OOOXZManager.

Definition at line 2408 of file OOOXZManager.m.

584 :(NSString *)input
585{
586 NSString *filter = [input lowercaseString];
587 if (([filter length] == 0) // empty is valid
588 || ([filter isEqualToString:kOOOXZFilterAll])
589 || ([filter isEqualToString:kOOOXZFilterUpdates])
590 || ([filter isEqualToString:kOOOXZFilterInstallable])
591 || ([filter hasPrefix:kOOOXZFilterKeyword] && [filter length] > [kOOOXZFilterKeyword length])
592 || ([filter hasPrefix:kOOOXZFilterAuthor] && [filter length] > [kOOOXZFilterAuthor length])
593 || ([filter hasPrefix:kOOOXZFilterDays] && [[filter substringFromIndex:[kOOOXZFilterDays length]] intValue] > 0)
594 || ([filter hasPrefix:kOOOXZFilterTag] && [filter length] > [kOOOXZFilterTag length])
595 || ([filter hasPrefix:kOOOXZFilterCategory] && [filter length] > [kOOOXZFilterCategory length])
596 )
597 {
598 return YES;
599 }
600
601 return NO;
602}

The documentation for this category was generated from the following file: