From 6e7663cdfa36248e759d71540bcd07a219e6c098 Mon Sep 17 00:00:00 2001 From: Austin Metka Date: Wed, 22 Feb 2023 13:12:11 -0500 Subject: [PATCH] Unzip when complete - > Add James Morton PR updates to this repo --- .../com/eko/RNBackgroundDownloaderModule.java | 85 +++++++++++++++++++ ios/RNBackgroundDownloader.m | 35 +++++--- react-native-background-downloader.podspec | 1 + 3 files changed, 109 insertions(+), 12 deletions(-) diff --git a/android/src/main/java/com/eko/RNBackgroundDownloaderModule.java b/android/src/main/java/com/eko/RNBackgroundDownloaderModule.java index d772c86c..56cd03f0 100644 --- a/android/src/main/java/com/eko/RNBackgroundDownloaderModule.java +++ b/android/src/main/java/com/eko/RNBackgroundDownloaderModule.java @@ -1,8 +1,10 @@ package com.eko; import android.annotation.SuppressLint; +import android.os.AsyncTask; import android.util.Log; + import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; @@ -31,8 +33,10 @@ import org.jetbrains.annotations.NotNull; +import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; @@ -41,6 +45,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import javax.annotation.Nullable; @@ -343,6 +349,49 @@ public void onCompleted(Download download) { params.putString("location", config.destination); ee.emit("downloadComplete", params); + final String filePath = download.getFile(); + final String taskId = config.id; + Log.d(getName(), "success callback!"); + + new Thread(new Runnable() { + @Override + public void run() { + try { + File downloadedZipFile = new File(filePath); + Log.d(getName(), "About to unzip: " + filePath + " (" + downloadedZipFile.exists() + ")"); + + File tempZipFile = new File(filePath + "_todelete"); + if (tempZipFile.exists()) { + boolean deleteResult = tempZipFile.delete(); + + if (!deleteResult) { + throw new Exception("File not deleted"); + } + } + boolean renameResult = downloadedZipFile.renameTo(tempZipFile); + if (!renameResult) { + throw new Exception("File not renamed"); + } + unzip(tempZipFile, downloadedZipFile); + boolean deleteResult = tempZipFile.delete(); + + if (!deleteResult) { + Log.d(getName(), "Temp zip file not deleted"); + } + + WritableMap params = Arguments.createMap(); + params.putString("id", taskId); + ee.emit("downloadComplete", params); + } catch(Exception e) { + e.printStackTrace(); + + WritableMap params = Arguments.createMap(); + params.putString("id", taskId); + params.putInt("errorcode", -1); + ee.emit("downloadFailed", params); + } + } + }).start(); } removeFromMaps(download.getId()); @@ -484,4 +533,40 @@ public void onDownloadBlockUpdated(Download download, DownloadBlock downloadBloc @Override public void onStarted(Download download, List list, int i) { } + + + private void unzip(File zipFile, File targetDirectory) throws IOException { + ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile))); + + try { + ZipEntry ze; + int count; + byte[] buffer = new byte[8192]; + + while ((ze = zis.getNextEntry()) != null) { + File file = new File(targetDirectory, ze.getName()); + File dir = ze.isDirectory() ? file : file.getParentFile(); + + if (!dir.isDirectory() && !dir.mkdirs()) { + throw new FileNotFoundException("Failed to ensure directory: " + dir.getAbsolutePath()); + } + + if (ze.isDirectory()) { + continue; + } + + FileOutputStream fout = new FileOutputStream(file); + + try { + while ((count = zis.read(buffer)) != -1) { + fout.write(buffer, 0, count); + } + } finally { + fout.close(); + } + } + } finally { + zis.close(); + } + } } diff --git a/ios/RNBackgroundDownloader.m b/ios/RNBackgroundDownloader.m index 0d25d202..40aefbce 100644 --- a/ios/RNBackgroundDownloader.m +++ b/ios/RNBackgroundDownloader.m @@ -8,6 +8,7 @@ // #import "RNBackgroundDownloader.h" #import "RNBGDTaskConfig.h" +#import "SSZipArchive.h" #define ID_TO_CONFIG_MAP_KEY @"com.eko.bgdownloadidmap" @@ -324,18 +325,28 @@ - (void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSe @synchronized (sharedLock) { RNBGDTaskConfig *taskConfig = taskToConfigMap[@(downloadTask.taskIdentifier)]; if (taskConfig != nil) { - NSError *error = [self getServerError:downloadTask]; - if (error == nil) { - [self saveDownloadedFile:taskConfig downloadURL:location error:&error]; - } - if (self.bridge) { - if (error == nil) { - NSDictionary *responseHeaders = ((NSHTTPURLResponse *)downloadTask.response).allHeaderFields; - [self sendEventWithName:@"downloadComplete" body:@{@"id": taskConfig.id, @"headers": responseHeaders, @"location": taskConfig.destination}]; - } else { - [self sendEventWithName:@"downloadFailed" body:@{@"id": taskConfig.id, @"error": [error localizedDescription]}]; + // NSError *error = [self getServerError:downloadTask]; + // if (error == nil) { + // [self saveDownloadedFile:taskConfig downloadURL:location error:&error]; + // } + // if (self.bridge) { + // if (error == nil) { + // NSDictionary *responseHeaders = ((NSHTTPURLResponse *)downloadTask.response).allHeaderFields; + // [self sendEventWithName:@"downloadComplete" body:@{@"id": taskConfig.id, @"headers": responseHeaders, @"location": taskConfig.destination}]; + // } else { + // [self sendEventWithName:@"downloadFailed" body:@{@"id": taskConfig.id, @"error": [error localizedDescription]}]; + // } + // } + [SSZipArchive unzipFileAtPath:location.path toDestination:taskCofig.destination progressHandler:^(NSString *entry, unz_file_info zipInfo, long entryNumber, long total) { + } completionHandler:^(NSString *path, BOOL succeeded, NSError * _Nullable error) { + if (self.bridge) { + if (succeeded && error == nil) { + [self sendEventWithName:@"downloadComplete" body:@{@"id": taskCofig.id}]; + } else { + [self sendEventWithName:@"downloadFailed" body:@{@"id": taskCofig.id, @"error": [error localizedDescription]}]; + } } - } + }]; [self removeTaskFromMap:downloadTask]; } } @@ -427,4 +438,4 @@ - (id)deserialize: (NSData *)data { return [NSKeyedUnarchiver unarchiveObjectWithData:data]; } -@end +@end \ No newline at end of file diff --git a/react-native-background-downloader.podspec b/react-native-background-downloader.podspec index ef456726..8c0b2d44 100644 --- a/react-native-background-downloader.podspec +++ b/react-native-background-downloader.podspec @@ -14,4 +14,5 @@ Pod::Spec.new do |s| s.requires_arc = true s.dependency 'React-Core' + s.dependency 'SSZipArchive', '2.2.3' end