diff --git a/app/src/main/java/org/kiwix/kiwixmobile/downloader/ChunkUtils.java b/app/src/main/java/org/kiwix/kiwixmobile/downloader/ChunkUtils.java index 2731e2897..06d4b3923 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/downloader/ChunkUtils.java +++ b/app/src/main/java/org/kiwix/kiwixmobile/downloader/ChunkUtils.java @@ -26,7 +26,7 @@ public class ChunkUtils { public static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz"; public static final String ZIM_EXTENSION = ".zim"; - public static final String PART = ".part"; + public static final String PART = ".part.part"; public static final long CHUNK_SIZE = 1024L * 1024L * 1024L * 2L; public static List getChunks(String url, long contentLength, int notificationID) { @@ -63,7 +63,7 @@ public class ChunkUtils { private static String[] getZimChunkFileNames(String fileName, int count) { if (count == 1) { - return new String[] { fileName + PART}; + return new String[]{fileName + PART}; } int position = fileName.lastIndexOf("."); String baseName = position > 0 ? fileName.substring(0, position) : fileName; diff --git a/app/src/main/java/org/kiwix/kiwixmobile/downloader/DownloadService.java b/app/src/main/java/org/kiwix/kiwixmobile/downloader/DownloadService.java index e9f34225b..7f610d9e2 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/downloader/DownloadService.java +++ b/app/src/main/java/org/kiwix/kiwixmobile/downloader/DownloadService.java @@ -71,6 +71,9 @@ import okhttp3.Request; import okhttp3.Response; import okio.BufferedSource; +import static org.kiwix.kiwixmobile.downloader.ChunkUtils.ALPHABET; +import static org.kiwix.kiwixmobile.downloader.ChunkUtils.PART; +import static org.kiwix.kiwixmobile.downloader.ChunkUtils.ZIM_EXTENSION; import static org.kiwix.kiwixmobile.utils.Constants.EXTRA_BOOK; import static org.kiwix.kiwixmobile.utils.Constants.EXTRA_LIBRARY; import static org.kiwix.kiwixmobile.utils.Constants.EXTRA_NOTIFICATION_ID; @@ -322,6 +325,35 @@ public class DownloadService extends Service { notification.get(notificationID).setContentText(getString(R.string.zim_file_downloaded)); final Intent target = new Intent(DownloadService.this, MainActivity.class); target.putExtra(EXTRA_ZIM_FILE, KIWIX_ROOT + StorageUtils.getFileNameFromUrl(book.getUrl())); + //Remove the extra ".part" from files + String filename = book.file.getPath(); + if (filename.endsWith(ZIM_EXTENSION)) { + filename = filename + PART; + File partFile = new File(filename); + if (partFile.exists()) { + partFile.renameTo(new File(partFile.getPath().replaceAll(".part", ""))); + } + } else { + for (int i = 0; true; i++) { + char first = ALPHABET.charAt(i / 26); + char second = ALPHABET.charAt(i % 26); + String chunkExtension = String.valueOf(first) + second; + filename = book.file.getPath(); + filename = filename.replaceAll(".zim([a-z][a-z]){0,1}$", ".zim"); + filename = filename + chunkExtension + ".part"; + File partFile = new File(filename); + if (partFile.exists()) { + partFile.renameTo(new File(partFile.getPath().replaceAll(".part$", ""))); + } else { + File lastChunkFile = new File(filename + ".part"); + if (lastChunkFile.exists()) { + lastChunkFile.renameTo(new File(partFile.getPath().replaceAll(".part", ""))); + } else { + break; + } + } + } + } target.putExtra(EXTRA_NOTIFICATION_ID, notificationID); PendingIntent pendingIntent = PendingIntent.getActivity (getBaseContext(), 0, @@ -453,7 +485,7 @@ public class DownloadService extends Service { // Create chunk file File file = new File(KIWIX_ROOT, chunk.getFileName()); file.getParentFile().mkdirs(); - File fullFile = new File(file.getPath().substring(0, file.getPath().length() - 5)); + File fullFile = new File(file.getPath().substring(0, file.getPath().length() - PART.length())); long downloaded = Long.parseLong(chunk.getRangeHeader().split("-")[0]); if (fullFile.exists() && fullFile.length() == chunk.getSize()) { @@ -594,16 +626,16 @@ public class DownloadService extends Service { if (downloadStatus.get(chunk.getNotificationID()) == CANCEL) { String path = file.getPath(); Log.i(KIWIX_TAG, "Download Cancelled, deleting file: " + path); - if (path.substring(path.length() - 8).equals("zim.part")) { - path = path.substring(0, path.length() - 5); + if (path.substring(path.length() - (ZIM_EXTENSION + PART).length()).equals(ZIM_EXTENSION + PART)) { + path = path.substring(0, path.length() - PART.length() + 1); FileUtils.deleteZimFile(path); } else { - path = path.substring(0, path.length() - 7) + "aa"; + path = path.substring(0, path.length() - (ZIM_EXTENSION + PART).length() + 2) + "aa"; FileUtils.deleteZimFile(path); } } else { - Log.i(KIWIX_TAG, "Download completed, renaming file ([" + file.getPath() + "] -> .zim)"); - file.renameTo(new File(file.getPath().replace(".part", ""))); + Log.i(KIWIX_TAG, "Download completed, renaming file ([" + file.getPath() + "] -> .zim.part)"); + file.renameTo(new File(file.getPath().replaceAll(".part$", ""))); } // Mark chunk status as downloaded chunk.isDownloaded = true; diff --git a/app/src/main/java/org/kiwix/kiwixmobile/utils/files/FileUtils.java b/app/src/main/java/org/kiwix/kiwixmobile/utils/files/FileUtils.java index e65fbb485..2807eee5d 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/utils/files/FileUtils.java +++ b/app/src/main/java/org/kiwix/kiwixmobile/utils/files/FileUtils.java @@ -27,6 +27,7 @@ import android.provider.DocumentsContract; import android.util.Log; import org.kiwix.kiwixmobile.BuildConfig; +import org.kiwix.kiwixmobile.downloader.ChunkUtils; import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity.Book; import java.io.File; @@ -61,8 +62,8 @@ public class FileUtils { } public static synchronized void deleteZimFile(String path) { - if (path.substring(path.length() - 5).equals(".part")) { - path = path.substring(0, path.length() - 5); + if (path.substring(path.length() - ChunkUtils.PART.length()).equals(ChunkUtils.PART)) { + path = path.substring(0, path.length() - ChunkUtils.PART.length()); } Log.i("kiwix", "Deleting file: " + path); File file = new File(path); @@ -86,10 +87,16 @@ public class FileUtils { } private static synchronized boolean deleteZimFileParts(String path) { - File file = new File(path + ".part"); + File file = new File(path + ChunkUtils.PART); if (file.exists()) { file.delete(); return true; + } else { + File singlePart = new File(path + ".part"); + if (singlePart.exists()) { + singlePart.delete(); + return true; + } } return false; } @@ -206,15 +213,16 @@ public class FileUtils { stream.read(buffer); stream.close(); content = new String(buffer); - } catch (IOException ignored) { } + } catch (IOException ignored) { + } return readCsv(content); } public static List getAllZimParts(Book book) { List files = new ArrayList<>(); - if(book.file.getPath().endsWith(".zim") || book.file.getPath().endsWith(".zim.part")) { - if(book.file.exists()) { + if (book.file.getPath().endsWith(".zim") || book.file.getPath().endsWith(".zim.part")) { + if (book.file.exists()) { files.add(book.file); } else { files.add(new File(book.file + ".part")); @@ -222,12 +230,12 @@ public class FileUtils { return files; } String path = book.file.getPath(); - for(char alphabetFirst = 'a'; alphabetFirst <= 'z'; alphabetFirst++) { - for(char alphabetSecond = 'a'; alphabetSecond <= 'z'; alphabetSecond++) { + for (char alphabetFirst = 'a'; alphabetFirst <= 'z'; alphabetFirst++) { + for (char alphabetSecond = 'a'; alphabetSecond <= 'z'; alphabetSecond++) { path = path.substring(0, path.length() - 2) + alphabetFirst + alphabetSecond; - if(new File(path).exists()) { + if (new File(path).exists()) { files.add(new File(path)); - } else if(new File(path + ".part").exists()) { + } else if (new File(path + ".part").exists()) { files.add(new File(path + ".part")); } else { return files; @@ -267,7 +275,7 @@ public class FileUtils { return false; } - public static String getFileName (String fileName) { + public static String getFileName(String fileName) { if (new File(fileName).exists()) { return fileName; } else if (new File(fileName + ".part").exists()) {