app/src/main/java/com/bedrock/padder/helper/FileHelper.java
package com.bedrock.padder.helper;
import android.app.Activity;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import com.afollestad.materialdialogs.MaterialDialog;
import com.bedrock.padder.R;
import com.bedrock.padder.model.preset.Preset;
import com.bedrock.padder.model.preset.PresetSchema;
import com.google.gson.Gson;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static com.bedrock.padder.activity.MainActivity.isPresetChanged;
import static com.bedrock.padder.activity.MainActivity.isPresetDownloading;
public class FileHelper {
public static String PRESET_LOCATION = "http://file.berict.com/tapad/presets";
public static String PROJECT_LOCATION_PRESETS = Environment.getExternalStorageDirectory().getPath() + "/Tapad/presets";
private AnimateHelper anim = new AnimateHelper();
private String TAG = "FileHelper";
private Decompress decompress;
public String getStringFromFile(String fileLocation) {
try {
FileInputStream inputStream = new FileInputStream(new File(fileLocation));
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
inputStream.close();
inputStreamReader.close();
bufferedReader.close();
return stringBuilder.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public boolean deleteRecursive(File fileOrDirectory) {
boolean recursive = true;
if (fileOrDirectory.isDirectory())
if (fileOrDirectory.listFiles() != null && fileOrDirectory.listFiles().length > 0)
for (File child : fileOrDirectory.listFiles())
recursive = deleteRecursive(child);
Log.d(TAG, "Deleted : " + fileOrDirectory.toString());
return fileOrDirectory.delete() && recursive;
}
public void unzip(String zipLocation, String targetLocation, String presetName, View parentView, Activity activity, Runnable onFinish) {
decompress = new Decompress(zipLocation, targetLocation, presetName, parentView, activity, onFinish);
decompress.execute();
}
public void unzip(String zipLocation, String targetLocation, String presetName, Activity activity, Runnable onFinish) {
decompress = new Decompress(zipLocation, targetLocation, presetName, null, activity, onFinish);
decompress.execute();
}
public void cancelDecompress() {
if (decompress != null) {
decompress.cancel(true);
} else {
Log.e(TAG, "Decompress is not initialized");
}
}
private boolean isPresetExists(String presetName) {
// preset exist
return new File(PROJECT_LOCATION_PRESETS + "/" + presetName).exists(); // folder check
}
public long getAvailableExternalMemorySize() {
return new File(PROJECT_LOCATION_PRESETS).getFreeSpace();
}
public boolean isPresetAvailable(Preset preset) {
// with sound count check
if (preset != null) {
String presetName = preset.getTag();
// preset available
File folderSound = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/sounds");
File folderTiming = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/timing");
File folderAbout = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/about");
File fileJson = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/about/json");
File fileAlbum = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/about/album_art");
File fileIcon = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/about/artist_icon");
File fileImage = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/about/artist_image");
if (folderSound.listFiles() != null) {
Log.d(TAG, "SoundCountPreset = " + preset.getSoundCount() + ", SoundCountFound = " + folderSound.listFiles().length);
} else {
Log.e(TAG, "Preset [" + preset.getTag() + "] is not available.");
return false;
}
boolean available = folderSound.isDirectory() && folderSound.exists() &&
preset.getSoundCount() == folderSound.listFiles().length &&
folderTiming.isDirectory() && folderTiming.exists() &&
folderAbout.isDirectory() && folderAbout.exists() &&
fileJson.exists() &&
fileAlbum.exists() &&
fileIcon.exists() &&
fileImage.exists();
if (available) {
Log.i(TAG, "Preset [" + preset.getTag() + "] is available.");
}
return available;
} else {
Log.e(TAG, "Preset is null.");
return false;
}
}
public boolean isPresetAvailable(String presetName) {
if (presetName != null) {
// preset available
File folderSound = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/sounds");
File folderTiming = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/timing");
File folderAbout = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/about");
File fileJson = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/about/json");
File fileAlbum = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/about/album_art");
File fileIcon = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/about/artist_icon");
File fileImage = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/about/artist_image");
// should be 100%
return folderSound.isDirectory() && folderSound.exists() &&
folderTiming.isDirectory() && folderTiming.exists() &&
folderAbout.isDirectory() && folderAbout.exists() &&
fileJson.exists() &&
fileAlbum.exists() &&
fileIcon.exists() &&
fileImage.exists();
} else {
return false;
}
}
public boolean isPresetMetadataAvailable(String presetName) {
if (presetName != null) {
File fileJson = new File(PROJECT_LOCATION_PRESETS + "/" + presetName + "/about/json");
// should be 100%
return fileJson.exists();
} else {
return false;
}
}
public PresetSchema getPresetSchemaFromMetadata(String presetName, Gson gson) {
if (presetName != null) {
PresetSchema preset = gson.fromJson(
this.getStringFromFile(PROJECT_LOCATION_PRESETS + "/" + presetName + "/about/json"),
PresetSchema.class
);
preset.getPreset().setTag(presetName);
return preset;
} else {
return null;
}
}
private class Decompress extends AsyncTask<Void, Void, Integer> {
private String zipLocation;
private String targetLocation;
private String presetName;
private View parentView;
private Activity activity;
private Runnable onFinish;
public Decompress(String zipLocation,
String targetLocation,
String presetName,
View parentView,
Activity activity,
Runnable onFinish) {
this.zipLocation = zipLocation;
this.targetLocation = targetLocation + "/";
this.presetName = presetName;
this.activity = activity;
this.parentView = parentView;
this.onFinish = onFinish;
dirChecker("");
}
@Override
protected void onPreExecute() {
Log.d(TAG, "onPreExecute");
if (new File(zipLocation).length() > getAvailableExternalMemorySize()) {
// no storage
new MaterialDialog.Builder(activity)
.title(R.string.preset_store_download_no_space_dialog_title)
.content(R.string.preset_store_download_no_space_dialog_text)
.contentColorRes(R.color.dark_primary)
.neutralText(R.string.dialog_close)
.dismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
cancelDecompress();
}
})
.show();
}
}
@Override
protected Integer doInBackground(Void... params) {
try {
FileInputStream fileInputStream = new FileInputStream(zipLocation);
ZipInputStream zipInputStream = new ZipInputStream(fileInputStream);
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
String zipName = zipEntry.getName();
Log.d("PresetStore", "Unzipping " + zipName);
if (zipEntry.isDirectory()) {
dirChecker(zipName);
} else {
FileOutputStream fileOutputStream = new FileOutputStream(targetLocation + zipName);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
byte[] buffer = new byte[1024];
int read = 0;
while ((read = zipInputStream.read(buffer)) != -1) {
bufferedOutputStream.write(buffer, 0, read);
}
bufferedOutputStream.close();
zipInputStream.closeEntry();
fileOutputStream.close();
}
}
zipInputStream.close();
Log.d("PresetStore", "Unzipping completed at " + targetLocation);
} catch (Exception e) {
Log.d("PresetStore", "Unzipping failed");
e.printStackTrace();
}
return 0;
// From https://stackoverflow.com/questions/4504291/how-to-speed-up-unzipping-time-in-java-android/4504692#4504692
}
@Override
protected void onProgressUpdate(Void... args) {
}
@Override
protected void onPostExecute(Integer integer) {
Log.d(TAG, "onPostExecute");
super.onPostExecute(integer);
// finished unzipping, delete the original zip file
if (parentView != null) {
// only when downloaded
if (new File(zipLocation).delete()) {
Log.d(TAG, "Successfully removed zip file");
} else {
Log.d(TAG, "Failed to remove zip file");
}
}
if (new File(targetLocation + "/" + presetName).delete()) {
Log.d(TAG, "Successfully removed zip folder");
} else {
Log.d(TAG, "Failed to remove zip folder");
}
File newFolder = new File(targetLocation + "/" + presetName);
File oldFolder = new File(targetLocation + "/preset");
if (oldFolder.renameTo(newFolder)) {
Log.d(TAG, "Successfully rename preset folder");
} else {
Log.d(TAG, "Failed to rename preset folder");
}
// finished downloading preset
isPresetDownloading = false;
isPresetChanged = true;
// refresh the preset adapter actions
Handler handler = new Handler();
handler.postDelayed(onFinish, 200);
if (parentView != null) {
anim.fadeOut(R.id.layout_preset_store_download_installing, 100, 200, parentView, activity);
anim.fadeIn(R.id.layout_preset_store_action_layout, 300, 200, "actionIn", parentView, activity);
}
}
@Override
protected void onCancelled() {
Log.d(TAG, "DownloadPreset cancelled");
if (new File(PROJECT_LOCATION_PRESETS + "/" + presetName).delete()) {
Log.d(TAG, "Successfully removed preset folder");
} else {
Log.d(TAG, "Failed to remove preset folder");
}
isPresetDownloading = false;
super.onCancelled();
}
private void dirChecker(String dir) {
File file = new File(targetLocation + dir);
if (!file.isDirectory()) {
file.mkdirs();
}
}
}
public void copy(String sourceLocation, String targetLocation) {
File sourceFile = new File(sourceLocation);
File destFile = new File(targetLocation);
// move file
if (sourceFile.renameTo(destFile)) {
Log.d(TAG, "File copied from " + sourceFile.getAbsolutePath() + " to " + destFile.getAbsolutePath());
} else {
Log.e(TAG, "Failed to copy from " + sourceFile.getAbsolutePath() + " to " + destFile.getAbsolutePath());
}
}
}