Skip to content

Commit

Permalink
#204 fix for zip plain files
Browse files Browse the repository at this point in the history
  • Loading branch information
plrthink committed Jul 4, 2020
1 parent 770789e commit cf57a2b
Show file tree
Hide file tree
Showing 9 changed files with 575 additions and 263 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"extends": [
"@react-native-community"
"@react-native-community",
"prettier"
]
}
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import { MainBundlePath, DocumentDirectoryPath } from 'react-native-fs'

## API

**`zip(source: string, target: string): Promise<string>`**
**`zip(source: string | string[], target: string): Promise<string>`**

> zip source to target
Expand All @@ -68,7 +68,7 @@ zip(sourcePath, targetPath)
})
```

**`zipWithPassword(source: string, target: string, password: string, encryptionType: string): Promise<string>`**
**`zipWithPassword(source: string | string[], target: string, password: string, encryptionType: string): Promise<string>`**

> zip source to target
Expand Down
111 changes: 69 additions & 42 deletions android/src/main/java/com/rnziparchive/RNZipArchiveModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.modules.core.DeviceEventManagerModule;

import java.io.BufferedInputStream;
Expand Down Expand Up @@ -324,23 +325,33 @@ public void onCopyProgress(long bytesRead) {
}

@ReactMethod
public void zip(String fileOrDirectory, String destDirectory, Promise promise) {
try{

ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
public void zipFiles(final ReadableArray files, final String destDirectory, final Promise promise) {
zip(files.toArrayList(), destDirectory, promise);
}

processZip(fileOrDirectory, destDirectory, parameters, promise);
@ReactMethod
public void zipFolder(final String folder, final String destFile, final Promise promise) {
ArrayList<Object> folderAsArrayList = new ArrayList<>();
folderAsArrayList.add(folder);
zip(folderAsArrayList, destFile, promise);
}

} catch (Exception ex) {
promise.reject(null, ex.getMessage());
return;
}
@ReactMethod
public void zipFilesWithPassword(final ReadableArray files, final String destFile, final String password,
String encryptionMethod, Promise promise) {
zipWithPassword(files.toArrayList(), destFile, password, encryptionMethod, promise);
}


@ReactMethod
public void zipWithPassword(String fileOrDirectory, String destDirectory, String password,
public void zipFolderWithPassword(final String folder, final String destFile, final String password,
String encryptionMethod, Promise promise) {
ArrayList<Object> folderAsArrayList = new ArrayList<>();
folderAsArrayList.add(folder);
zipWithPassword(folderAsArrayList, destFile, password, encryptionMethod, promise);
}

private void zipWithPassword(final ArrayList<Object> filesOrDirectory, final String destFile, final String password,
String encryptionMethod, Promise promise) {
try{

Expand Down Expand Up @@ -373,7 +384,7 @@ public void zipWithPassword(String fileOrDirectory, String destDirectory, String
promise.reject(null, "Password is empty");
}

processZip(fileOrDirectory, destDirectory, parameters, promise);
processZip(filesOrDirectory, destFile, parameters, promise);

} catch (Exception ex) {
promise.reject(null, ex.getMessage());
Expand All @@ -382,51 +393,67 @@ public void zipWithPassword(String fileOrDirectory, String destDirectory, String

}

private void processZip(final String fileOrDirectory, final String destDirectory, final ZipParameters parameters, final Promise promise) {
private void zip(final ArrayList<Object> filesOrDirectory, final String destFile, final Promise promise) {
try{

ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);

processZip(filesOrDirectory, destFile, parameters, promise);

} catch (Exception ex) {
promise.reject(null, ex.getMessage());
return;
}
}

private void processZip(final ArrayList<Object> entries, final String destFile, final ZipParameters parameters, final Promise promise) {
new Thread(new Runnable() {
@Override
public void run() {
try {
net.lingala.zip4j.core.ZipFile zipFile = new net.lingala.zip4j.core.ZipFile(destDirectory);

updateProgress(0, 100, destDirectory);
net.lingala.zip4j.core.ZipFile zipFile = new net.lingala.zip4j.core.ZipFile(destFile);

File f = new File(fileOrDirectory);
updateProgress(0, 100, destFile);

int totalFiles = 0;
int fileCounter = 0;

if (f.exists()) {
if (f.isDirectory()) {
for (int i = 0; i < entries.size(); i++) {
File f = new File(entries.get(i).toString());

List<File> files = Arrays.asList(f.listFiles());
if (f.exists()) {
if (f.isDirectory()) {

totalFiles = files.size();
for (int i = 0; i < files.size(); i++) {
if (files.get(i).isDirectory()) {
zipFile.addFolder(files.get(i).getAbsolutePath(), parameters);
}
else {
zipFile.addFile(files.get(i), parameters);
List<File> files = Arrays.asList(f.listFiles());

totalFiles += files.size();
for (int j = 0; j < files.size(); j++) {
if (files.get(j).isDirectory()) {
zipFile.addFolder(files.get(j).getAbsolutePath(), parameters);
}
else {
zipFile.addFile(files.get(j), parameters);
}
fileCounter += 1;
updateProgress(fileCounter, totalFiles, destFile);
}

} else {
totalFiles += 1;
zipFile.addFile(f, parameters);
fileCounter += 1;
updateProgress(fileCounter, totalFiles, destDirectory);
updateProgress(fileCounter, totalFiles, destFile);
}

} else {
totalFiles = 1;
zipFile.addFile(f, parameters);
fileCounter += 1;
updateProgress(fileCounter, totalFiles, destDirectory);
}
}
else {
promise.reject(null, "File or folder does not exist");
}

updateProgress(1, 1, destDirectory); // force 100%
promise.resolve(destDirectory);
else {
promise.reject(null, "File or folder does not exist");
}

updateProgress(1, 1, destFile); // force 100%
promise.resolve(destFile);
}
} catch (Exception ex) {
promise.reject(null, ex.getMessage());
return;
Expand Down
4 changes: 2 additions & 2 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ declare module 'react-native-zip-archive' {
}
import { NativeEventSubscription } from 'react-native';
export function isPasswordProtected(source: string): Promise<boolean>;
export function zip(source: string, target: string): Promise<string>;
export function zipWithPassword(source: string, target: string, password: string, encryptionMethod?: encryptionMethods): Promise<string>;
export function zip(source: string | [string], target: string): Promise<string>;
export function zipWithPassword(source: string | [string], target: string, password: string, encryptionMethod?: encryptionMethods): Promise<string>;
export function unzip(source: string, target: string, charset?: string): Promise<string>;
export function unzipWithPassword(assetPath: string, target: string, password: string): Promise<string>;
export function unzipAssets(assetPath: string, target: string): Promise<string>;
Expand Down
31 changes: 20 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ const RNZipArchive = NativeModules.RNZipArchive;

const rnzaEmitter = new NativeEventEmitter(RNZipArchive);

const normalizeFilePath = path =>
const normalizeFilePath = (path) =>
path.startsWith("file://") ? path.slice(7) : path;

export const unzip = (source, target, charset = "UTF-8") => {
return RNZipArchive.unzip(normalizeFilePath(source), target, charset);
};
export const isPasswordProtected = source => {
export const isPasswordProtected = (source) => {
return RNZipArchive.isPasswordProtected(normalizeFilePath(source)).then(
isEncrypted => !!isEncrypted
(isEncrypted) => !!isEncrypted
);
};

Expand All @@ -32,16 +32,25 @@ export const zipWithPassword = (
password,
encryptionMethod = ""
) => {
return RNZipArchive.zipWithPassword(
normalizeFilePath(source),
target,
password,
encryptionMethod
);
return Array.isArray(source)
? RNZipArchive.zipFilesWithPassword(
source.map(normalizeFilePath),
target,
password,
encryptionMethod
)
: RNZipArchive.zipFolderWithPassword(
normalizeFilePath(source),
target,
password,
encryptionMethod
);
};

export const zip = (source, target) => {
return RNZipArchive.zip(normalizeFilePath(source), target);
return Array.isArray(source)
? RNZipArchive.zipFiles(source.map(normalizeFilePath), target)
: RNZipArchive.zipFolder(normalizeFilePath(source), target);
};

export const unzipAssets = (source, target) => {
Expand All @@ -52,6 +61,6 @@ export const unzipAssets = (source, target) => {
return RNZipArchive.unzipAssets(normalizeFilePath(source), target);
};

export const subscribe = callback => {
export const subscribe = (callback) => {
return rnzaEmitter.addListener("zipArchiveProgressEvent", callback);
};
54 changes: 52 additions & 2 deletions ios/RNZipArchive.m
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ @implementation RNZipArchive
}
}

RCT_EXPORT_METHOD(zip:(NSString *)from
RCT_EXPORT_METHOD(zipFolder:(NSString *)from
destinationPath:(NSString *)destinationPath
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
Expand All @@ -90,6 +90,7 @@ @implementation RNZipArchive

BOOL success;
[self setProgressHandler];

success = [SSZipArchive createZipFileAtPath:destinationPath withContentsOfDirectory:from keepParentDirectory:NO withPassword:nil andProgressHandler:self.progressHandler];

self.progress = 1.0;
Expand All @@ -103,8 +104,32 @@ @implementation RNZipArchive
}
}

RCT_EXPORT_METHOD(zipFiles:(NSArray<NSString *> *)from
destinationPath:(NSString *)destinationPath
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
self.progress = 0.0;
self.processedFilePath = @"";
[self zipArchiveProgressEvent:0 total:1]; // force 0%

BOOL success;
[self setProgressHandler];

success = [SSZipArchive createZipFileAtPath:destinationPath withFilesAtPaths:from];

self.progress = 1.0;
[self zipArchiveProgressEvent:1 total:1]; // force 100%

if (success) {
resolve(destinationPath);
} else {
NSError *error = nil;
reject(@"zip_error", @"unable to zip", error);
}
}


RCT_EXPORT_METHOD(zipWithPassword:(NSString *)from
RCT_EXPORT_METHOD(zipFolderWithPassword:(NSString *)from
destinationPath:(NSString *)destinationPath
password:(NSString *)password
encryptionType:(NSString *)encryptionType
Expand All @@ -129,6 +154,31 @@ @implementation RNZipArchive
}
}

RCT_EXPORT_METHOD(zipFilesWithPassword:(NSArray<NSString *> *)from
destinationPath:(NSString *)destinationPath
password:(NSString *)password
encryptionType:(NSString *)encryptionType
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
self.progress = 0.0;
self.processedFilePath = @"";
[self zipArchiveProgressEvent:0 total:1]; // force 0%

BOOL success;
[self setProgressHandler];
success = [SSZipArchive createZipFileAtPath:destinationPath withFilesAtPaths:from withPassword:password];

self.progress = 1.0;
[self zipArchiveProgressEvent:1 total:1]; // force 100%

if (success) {
resolve(destinationPath);
} else {
NSError *error = nil;
reject(@"zip_error", @"unable to zip", error);
}
}

- (dispatch_queue_t)methodQueue {
return dispatch_queue_create("com.mockingbot.ReactNative.ZipArchiveQueue", DISPATCH_QUEUE_SERIAL);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"lint:js": "eslint index.js"
"lint": "eslint index.js"
},
"repository": {
"type": "git",
Expand All @@ -25,7 +25,7 @@
"license": "MIT",
"devDependencies": {
"@babel/core": "*",
"@react-native-community/eslint-config": "^0.0.5",
"@react-native-community/eslint-config": "^2.0.0",
"eslint": "^6.7.2",
"react": "^16.8.6",
"react-native": "^0.60.0"
Expand Down
Loading

0 comments on commit cf57a2b

Please sign in to comment.