Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to unzip rar and 7z formats. #612

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
328 changes: 270 additions & 58 deletions Provenance.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

103 changes: 56 additions & 47 deletions Provenance/Game Library/PVDirectoryWatcher.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//

#import "PVDirectoryWatcher.h"
#import "SSZipArchive.h"
#import "SARUnArchiveANY.h"
#import "PVEmulatorConfiguration.h"
#import "NSDate+NSDate_SignificantDates.h"

Expand Down Expand Up @@ -63,7 +63,9 @@ - (id)initWithPath:(NSString *)path extractionStartedHandler:(PVExtractionStarte
{
for (NSString *file in contents)
{
if ([[file pathExtension] isEqualToString:@"zip"])
if ([[file pathExtension] isEqualToString:@"zip"]
|| [[file pathExtension] isEqualToString:@"rar"]
|| [[file pathExtension] isEqualToString:@"7z"])
{
[self extractArchiveAtPath:file];
}
Expand Down Expand Up @@ -184,7 +186,9 @@ - (void)checkFileProgress:(NSTimer *)timer
unsigned long long currentFilesize = [attributes fileSize];
if (previousFilesize == currentFilesize)
{
if ([[path pathExtension] isEqualToString:@"zip"])
if ([[path pathExtension] isEqualToString:@"zip"]
|| [[path pathExtension] isEqualToString:@"rar"]
|| [[path pathExtension] isEqualToString:@"7z"])
{
dispatch_async(self.serialQueue, ^{
[self extractArchiveAtPath:path];
Expand Down Expand Up @@ -216,53 +220,58 @@ - (void)extractArchiveAtPath:(NSString *)filePath

if (![[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSLog(@"File not found at path for Archive : %@",filePath);
return;
}

NSMutableArray *unzippedFiles = [NSMutableArray array];
[SSZipArchive unzipFileAtPath:filePath
toDestination:self.path
overwrite:YES
password:nil
progressHandler:^(NSString *entry, unz_file_info zipInfo, long entryNumber, long total, unsigned long long fileSize, unsigned long long bytesRead) {
if ([entry length])
{
[unzippedFiles addObject:entry];
}
if (self.extractionUpdatedHandler)
{
dispatch_async(dispatch_get_main_queue(), ^{
self.extractionUpdatedHandler(filePath, entryNumber, total, fileSize, bytesRead);
});
}
}
completionHandler:^(NSString *path, BOOL succeeded, NSError *error) {
if (succeeded)
{
if (self.extractionCompleteHandler)
{
dispatch_async(dispatch_get_main_queue(), ^{
self.extractionCompleteHandler([unzippedFiles copy]);
});
}

NSError *deleteError = nil;
BOOL deleted = [[NSFileManager defaultManager] removeItemAtPath:filePath error:&deleteError];

if (!deleted)
{
DLog(@"Unable to delete file at path %@, because %@", filePath, [error localizedDescription]);
}
}
else
{
DLog(@"Unable to unzip file: %@ because: %@", filePath, [error localizedDescription]);
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:PVArchiveInflationFailedNotification
object:self];
});
}
}];
SARUnArchiveANY *unarchive = [[SARUnArchiveANY alloc]initWithPath:filePath];
unarchive.destinationPath = self.path;
unarchive.completionBlock = ^(NSArray *filePaths){

if (self.extractionCompleteHandler)
{
NSMutableArray *movedFiles = [NSMutableArray array];
NSLog(@"For Archive : %@",filePath);
for (NSString *filename in filePaths) {
NSLog(@"File: %@", filename);
}

NSError *differentError;
for (NSString *file in filePaths) {\
NSString *newPath = [self.path stringByAppendingPathComponent:[file lastPathComponent]];
[[NSFileManager defaultManager] moveItemAtPath:file
toPath:newPath
error:&differentError];
if (!differentError) {
DLog(@"Unable to move file at path %@, because %@", filePath, [differentError localizedDescription]);
} else {
[movedFiles addObject:newPath];
}
}


dispatch_async(dispatch_get_main_queue(), ^{
self.extractionCompleteHandler([movedFiles copy]);
});
}
NSError *deleteError = nil;
BOOL deleted = [[NSFileManager defaultManager] removeItemAtPath:filePath error:&deleteError];

if (!deleted)
{
DLog(@"Unable to delete file at path %@, because %@", filePath, [deleteError localizedDescription]);
}

};
unarchive.failureBlock = ^(){
DLog(@"Unable to unzip file: %@", filePath);
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:PVArchiveInflationFailedNotification
object:self];
});
};
[unarchive decompress];

}

@end
4 changes: 2 additions & 2 deletions Provenance/Provenance-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>683</string>
<string>685</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
Expand All @@ -53,7 +53,7 @@
<key>NSPhotoLibraryUsageDescription</key>
<string>Provenance can set custom artworks from your photos or save screenshots to your photos library.</string>
<key>Revision</key>
<string>439486d</string>
<string>f47caf3</string>
<key>UIFileSharingEnabled</key>
<true/>
<key>UILaunchStoryboardName</key>
Expand Down
39 changes: 39 additions & 0 deletions Provenance/SARUnArchiveANY/SARUnArchiveANY.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// SARUnArchiveANY.h
// SARUnArchiveANY
//
// Created by Saravanan V on 26/04/13.
// Copyright (c) 2013 SARAVANAN. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "SSZipArchive.h"

#define UNIQUE_KEY( x ) NSString * const x = @#x

enum{
SARFileTypeZIP,
SARFileTypeRAR
};

static UNIQUE_KEY( rar );
static UNIQUE_KEY( zip );

typedef void(^Completion)(NSArray *filePaths);
typedef void(^Failure)();

@interface SARUnArchiveANY : NSObject <SSZipArchiveDelegate>{
SSZipArchive *_zipArchive;
NSString *_fileType;
}

@property (nonatomic, strong) NSString *filePath;
@property (nonatomic, strong) NSString *password;
@property (nonatomic, strong) NSString *destinationPath;
@property (nonatomic, copy) Completion completionBlock;
@property (nonatomic, copy) Failure failureBlock;

- (id)initWithPath:(NSString *)path;
- (void)decompress;

@end
205 changes: 205 additions & 0 deletions Provenance/SARUnArchiveANY/SARUnArchiveANY.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
//
// SARUnArchiveANY.m
// SARUnArchiveANY
//
// Created by Saravanan V on 26/04/13.
// Copyright (c) 2013 SARAVANAN. All rights reserved.
//

#import "SARUnArchiveANY.h"
#include "Unrar4IOS.h"
#import "SSZipArchive.h"
#import "LZMAExtractor.h"

@implementation SARUnArchiveANY
@synthesize completionBlock;
@synthesize failureBlock;


#pragma mark - Init Methods
- (id)initWithPath:(NSString *)path {
if ((self = [super init])) {
_filePath = [path copy];
_fileType = [[NSString alloc]init];
}

if (_filePath != nil) {
_destinationPath = [self getDestinationPath];
}
return self;
}

- (id)initWithPath:(NSString *)path andPassword:(NSString*)password{
if ((self = [super init])) {
_filePath = [path copy];
_password = [password copy];
_fileType = [[NSString alloc]init];
}

if (_filePath != nil) {
_destinationPath = [self getDestinationPath];
}
return self;
}

#pragma mark - Helper Methods
- (NSString *)getDestinationPath{
NSArray *derivedPathArr = [_filePath componentsSeparatedByString:@"/"];
NSString *lastObject = [derivedPathArr lastObject];
_fileType = [[lastObject componentsSeparatedByString:@"."] lastObject];
return [_filePath stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"/%@",lastObject] withString:@""];
}


#pragma mark - Decompressing Methods
- (void)decompress{
// NSLog(@"_fileType : %@",_fileType);
if ( [_fileType compare:rar options:NSCaseInsensitiveSearch] == NSOrderedSame ) {
[self rarDecompress];
}
else if ( [_fileType compare:zip options:NSCaseInsensitiveSearch] == NSOrderedSame ) {
[self zipDecompress];
}
else if ( [_fileType compare:@"7z" options:NSCaseInsensitiveSearch] == NSOrderedSame ) {
[self decompress7z];
}
}

- (void)rarDecompress {
NSString *tmpDirname = @"Extract rar";
_destinationPath = [_destinationPath stringByAppendingPathComponent:tmpDirname];
// _filePath = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"rar"];
// NSLog(@"filePath : %@",_filePath);
Unrar4iOS *unrar = [[Unrar4iOS alloc] init];

BOOL ok;
if (self.password != nil && self.password.length > 0) {
@try {
ok = [unrar unrarOpenFile:_filePath withPassword:self.password];
}
@catch(NSException *exception) {
NSLog(@"exception: %@", exception);
}
}
else{
ok = [unrar unrarOpenFile:_filePath];
}

if (ok) {
NSArray *files = [unrar unrarListFiles];
NSMutableArray *filePathsArray = [NSMutableArray array];
for (NSString *filePath in files){
[filePathsArray addObject:[_destinationPath stringByAppendingPathComponent:filePath]];
}

// NSLog(@"_destinationPath : %@",_destinationPath);
BOOL extracted = [unrar unrarFileTo:_destinationPath overWrite:YES];
// NSLog(@"extracted : %d",extracted);

// [self moveFilesToDestinationPathFromCompletePaths:filePathsArray withFilePaths:files];
if ( extracted ) {
if (completionBlock != nil) {
completionBlock(filePathsArray);
}
else{
if (failureBlock != nil) {
failureBlock();
}
}
}
[unrar unrarCloseFile];
}
else{
if (failureBlock != nil) {
failureBlock();
}
[unrar unrarCloseFile];
}

}

- (void)zipDecompress{
NSString *tmpDirname = @"Extract zip";
_destinationPath = [_destinationPath stringByAppendingPathComponent:tmpDirname];
BOOL unzipped = [SSZipArchive unzipFileAtPath:_filePath toDestination:_destinationPath delegate:self];
// NSLog(@"unzipped : %d",unzipped);
NSError *error;
if (self.password != nil && self.password.length > 0) {
unzipped = [SSZipArchive unzipFileAtPath:_filePath toDestination:_destinationPath overwrite:NO password:self.password error:&error delegate:self];
NSLog(@"error: %@", error);
}

if ( !unzipped ) {
failureBlock();
}
}

- (void)decompress7z{
NSString *tmpDirname = @"Extract 7z";
_destinationPath = [_destinationPath stringByAppendingPathComponent:tmpDirname];

NSArray *contents = [LZMAExtractor extract7zArchive:_filePath dirName:_destinationPath preserveDir:YES];

// UnComment below lines to see the path of each file extracted
// for (NSString *entryPath in contents) {
// NSLog(@"entryPath : %@", entryPath);
// }

if (![contents count]) {
failureBlock();
}
else{
completionBlock(contents);
}
}

#pragma mark - SSZipArchive Delegates
- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath WithFilePaths:(NSMutableArray *)filePaths{
// NSLog(@"path : %@",path);
// NSLog(@"unzippedPath : %@",unzippedPath);
completionBlock(filePaths);
}


#pragma mark - Utility Methods
- (NSString *) applicationDocumentsDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}





#pragma mark - Not using these methods now
//Writing this for Unrar4iOS, since it just unrar's(decompresses) the files into the compressed(rar) file's folder path
- (void)moveFilesToDestinationPathFromCompletePaths:(NSArray *)completeFilePathsArray withFilePaths:(NSArray *)filePathsArray{
if ( _destinationPath == [self getDestinationPath] ) {
return;
}
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;

for ( NSString *filePath in completeFilePathsArray ){
int index = [completeFilePathsArray indexOfObject:filePath];
NSString *fileDestinationPath = [_destinationPath stringByAppendingPathComponent:[filePathsArray objectAtIndex:index]];
if([fileManager fileExistsAtPath:fileDestinationPath]){
[fileManager removeItemAtPath:fileDestinationPath error:&error];
}
else{
NSLog(@"filePath : %@",filePath);
if(![fileManager moveItemAtPath:filePath
toPath:fileDestinationPath
error:&error])
{
//TODO: Handle error
NSLog(@"Error: %@", error);
}
}
}

}

@end
Loading