mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-24 05:04:50 -04:00
Migrate from to new Model for BookDatabaseEntity
This commit is contained in:
parent
0503d7272b
commit
5b01c30a51
@ -9,20 +9,16 @@ import android.os.Environment;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import java.util.List;
|
||||
import org.kiwix.kiwixmobile.base.BaseActivity;
|
||||
import org.kiwix.kiwixmobile.database.BookDao;
|
||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity;
|
||||
import org.kiwix.kiwixmobile.utils.SplashActivity;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import org.kiwix.kiwixmobile.base.BaseActivity;
|
||||
import org.kiwix.kiwixmobile.database.BookDao;
|
||||
import org.kiwix.kiwixmobile.downloader.model.BookOnDisk;
|
||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity;
|
||||
import org.kiwix.kiwixmobile.utils.SplashActivity;
|
||||
|
||||
import static org.kiwix.kiwixmobile.utils.LanguageUtils.getCurrentLocale;
|
||||
|
||||
@ -90,10 +86,11 @@ public class KiwixErrorActivity extends BaseActivity {
|
||||
}
|
||||
|
||||
if(allowZimsCheckbox.isChecked()) {
|
||||
List<LibraryNetworkEntity.Book> books = bookDao.getBooks();
|
||||
List<BookOnDisk> books = bookDao.getBooks();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(LibraryNetworkEntity.Book book: books) {
|
||||
for (BookOnDisk bookOnDisk : books) {
|
||||
final LibraryNetworkEntity.Book book = bookOnDisk.getBook();
|
||||
String bookString = book.getTitle() +
|
||||
":\nArticles: ["+ book.getArticleCount() +
|
||||
"]\nCreator: [" + book.getCreator() +
|
||||
|
@ -24,9 +24,12 @@ import io.reactivex.Flowable;
|
||||
import io.reactivex.processors.BehaviorProcessor;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import org.kiwix.kiwixmobile.database.entity.BookDatabaseEntity;
|
||||
import org.kiwix.kiwixmobile.downloader.model.BookOnDisk;
|
||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity;
|
||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity.Book;
|
||||
|
||||
import static org.kiwix.kiwixmobile.downloader.ChunkUtils.hasParts;
|
||||
@ -36,7 +39,7 @@ import static org.kiwix.kiwixmobile.downloader.ChunkUtils.hasParts;
|
||||
*/
|
||||
|
||||
public class BookDao extends BaseDao {
|
||||
private final BehaviorProcessor<List<Book>> booksProcessor = BehaviorProcessor.create();
|
||||
private final BehaviorProcessor<List<BookOnDisk>> booksProcessor = BehaviorProcessor.create();
|
||||
|
||||
@Inject
|
||||
public BookDao(KiwixDatabase kiwixDatabase) {
|
||||
@ -48,61 +51,49 @@ public class BookDao extends BaseDao {
|
||||
booksProcessor.onNext(getBooks());
|
||||
}
|
||||
|
||||
public Flowable<List<Book>> books() {
|
||||
public Flowable<List<BookOnDisk>> books() {
|
||||
return booksProcessor;
|
||||
}
|
||||
|
||||
public void setBookDetails(Book book, SquidCursor<BookDatabaseEntity> bookCursor) {
|
||||
book.databaseId = bookCursor.get(BookDatabaseEntity.ID);
|
||||
book.id = bookCursor.get(BookDatabaseEntity.BOOK_ID);
|
||||
book.title = bookCursor.get(BookDatabaseEntity.TITLE);
|
||||
book.description = bookCursor.get(BookDatabaseEntity.DESCRIPTION);
|
||||
book.language = bookCursor.get(BookDatabaseEntity.LANGUAGE);
|
||||
book.creator = bookCursor.get(BookDatabaseEntity.BOOK_CREATOR);
|
||||
book.publisher = bookCursor.get(BookDatabaseEntity.PUBLISHER);
|
||||
book.date = bookCursor.get(BookDatabaseEntity.DATE);
|
||||
book.file = new File(bookCursor.get(BookDatabaseEntity.URL));
|
||||
book.articleCount = bookCursor.get(BookDatabaseEntity.ARTICLE_COUNT);
|
||||
book.mediaCount = bookCursor.get(BookDatabaseEntity.MEDIA_COUNT);
|
||||
book.size = bookCursor.get(BookDatabaseEntity.SIZE);
|
||||
book.favicon = bookCursor.get(BookDatabaseEntity.FAVICON);
|
||||
book.bookName = bookCursor.get(BookDatabaseEntity.NAME);
|
||||
}
|
||||
|
||||
public void setBookDatabaseEntity(Book book, BookDatabaseEntity bookDatabaseEntity) {
|
||||
final String path = book.file.getPath();
|
||||
bookDatabaseEntity.setBookId(book.getId())
|
||||
public void setBookDatabaseEntity(BookOnDisk bookonDisk, BookDatabaseEntity bookDatabaseEntity) {
|
||||
final Book book = bookonDisk.getBook();
|
||||
bookDatabaseEntity
|
||||
.setFilePath(bookonDisk.getFile().getPath())
|
||||
.setBookId(book.getId())
|
||||
.setTitle(book.getTitle())
|
||||
.setDescription(book.getDescription())
|
||||
.setLanguage(book.getLanguage())
|
||||
.setBookCreator(book.getCreator())
|
||||
.setPublisher(book.getPublisher())
|
||||
.setDate(book.getDate())
|
||||
.setUrl(path)
|
||||
.setUrl(book.getUrl())
|
||||
.setArticleCount(book.getArticleCount())
|
||||
.setMediaCount(book.getMediaCount())
|
||||
.setSize(book.getSize())
|
||||
.setFavicon(book.getFavicon())
|
||||
.setName(book.getName());
|
||||
kiwixDatabase.deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(path));
|
||||
kiwixDatabase.persistWithOnConflict(bookDatabaseEntity, TableStatement.ConflictAlgorithm.REPLACE);
|
||||
.setName(book.getName())
|
||||
.setFavicon(book.getFavicon());
|
||||
}
|
||||
|
||||
public List<Book> getBooks() {
|
||||
public List<BookOnDisk> getBooks() {
|
||||
kiwixDatabase.beginTransaction();
|
||||
ArrayList<Book> books = new ArrayList<>();
|
||||
ArrayList<BookOnDisk> books = new ArrayList<>();
|
||||
final BookDatabaseEntity bookDatabaseEntity = new BookDatabaseEntity();
|
||||
try(SquidCursor<BookDatabaseEntity> bookCursor = kiwixDatabase.query(
|
||||
BookDatabaseEntity.class,
|
||||
Query.select())) {
|
||||
while (bookCursor.moveToNext()) {
|
||||
Book book = new Book();
|
||||
setBookDetails(book, bookCursor);
|
||||
if (!hasParts(book.file)) {
|
||||
if (book.file.exists()) {
|
||||
bookDatabaseEntity.readPropertiesFromCursor(bookCursor);
|
||||
final File file = new File(bookDatabaseEntity.getFilePath());
|
||||
BookOnDisk book = new BookOnDisk(
|
||||
bookDatabaseEntity.getId(),
|
||||
toBook(bookDatabaseEntity),
|
||||
file);
|
||||
if (!hasParts(file)) {
|
||||
if (file.exists()) {
|
||||
books.add(book);
|
||||
} else {
|
||||
kiwixDatabase.deleteWhere(BookDatabaseEntity.class,
|
||||
BookDatabaseEntity.URL.eq(book.file));
|
||||
BookDatabaseEntity.FILE_PATH.eq(file.getPath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -112,19 +103,41 @@ public class BookDao extends BaseDao {
|
||||
return books;
|
||||
}
|
||||
|
||||
public void saveBooks(List<Book> books) {
|
||||
public void saveBooks(Collection<BookOnDisk> books) {
|
||||
kiwixDatabase.beginTransaction();
|
||||
for (Book book : books) {
|
||||
for (BookOnDisk book : books) {
|
||||
if (book != null) {
|
||||
BookDatabaseEntity bookDatabaseEntity = new BookDatabaseEntity();
|
||||
setBookDatabaseEntity(book, bookDatabaseEntity);
|
||||
kiwixDatabase.deleteWhere(BookDatabaseEntity.class,
|
||||
BookDatabaseEntity.FILE_PATH.eq(bookDatabaseEntity.getFilePath()));
|
||||
kiwixDatabase.persistWithOnConflict(bookDatabaseEntity,
|
||||
TableStatement.ConflictAlgorithm.REPLACE);
|
||||
}
|
||||
}
|
||||
kiwixDatabase.setTransactionSuccessful();
|
||||
kiwixDatabase.endTransaction();
|
||||
}
|
||||
|
||||
public void deleteBook(String id) {
|
||||
kiwixDatabase.deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.BOOK_ID.eq(id));
|
||||
public void deleteBook(Long id) {
|
||||
kiwixDatabase.deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.ID.eq(id));
|
||||
}
|
||||
|
||||
private LibraryNetworkEntity.Book toBook(BookDatabaseEntity bookDatabaseEntity) {
|
||||
final LibraryNetworkEntity.Book book = new LibraryNetworkEntity.Book();
|
||||
book.id = bookDatabaseEntity.getBookId();
|
||||
book.title = bookDatabaseEntity.getTitle();
|
||||
book.description = bookDatabaseEntity.getDescription();
|
||||
book.language = bookDatabaseEntity.getLanguage();
|
||||
book.creator = bookDatabaseEntity.getBookCreator();
|
||||
book.publisher = bookDatabaseEntity.getPublisher();
|
||||
book.date = bookDatabaseEntity.getDate();
|
||||
book.url = bookDatabaseEntity.getUrl();
|
||||
book.articleCount = bookDatabaseEntity.getArticleCount();
|
||||
book.mediaCount = bookDatabaseEntity.getMediaCount();
|
||||
book.size = bookDatabaseEntity.getSize();
|
||||
book.bookName = bookDatabaseEntity.getName();
|
||||
book.favicon = bookDatabaseEntity.getFavicon();
|
||||
return book;
|
||||
}
|
||||
}
|
||||
|
@ -23,12 +23,9 @@ import com.yahoo.squidb.sql.Query;
|
||||
import com.yahoo.squidb.sql.TableStatement;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.processors.BehaviorProcessor;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import kotlin.collections.ArraysKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.kiwix.kiwixmobile.database.entity.DownloadDatabaseEntity;
|
||||
import org.kiwix.kiwixmobile.downloader.model.DownloadModel;
|
||||
@ -98,7 +95,7 @@ public class DownloadDao extends BaseDao {
|
||||
.setFavIcon(book.getFavicon());
|
||||
}
|
||||
|
||||
private List<DownloadModel> getDownloads() {
|
||||
public List<DownloadModel> getDownloads() {
|
||||
return toList(kiwixDatabase.query(DownloadDatabaseEntity.class, Query.select()));
|
||||
}
|
||||
|
||||
@ -126,7 +123,6 @@ public class DownloadDao extends BaseDao {
|
||||
book.publisher = downloadDatabaseEntity.getPublisher();
|
||||
book.date = downloadDatabaseEntity.getDate();
|
||||
book.url = downloadDatabaseEntity.getUrl();
|
||||
book.file = new File(downloadDatabaseEntity.getUrl());
|
||||
book.articleCount = downloadDatabaseEntity.getArticleCount();
|
||||
book.mediaCount = downloadDatabaseEntity.getMediaCount();
|
||||
book.size = downloadDatabaseEntity.getSize();
|
||||
|
@ -118,7 +118,7 @@ public class KiwixDatabase extends SquidDatabase {
|
||||
tryCreateTable(RecentSearch.TABLE);
|
||||
}
|
||||
if (newVersion >= 12) {
|
||||
tryAddColumn(BookDatabaseEntity.REMOTE_URL);
|
||||
//tryAddColumn(BookDatabaseEntity.REMOTE_URL);
|
||||
}
|
||||
if (newVersion >= 13) {
|
||||
tryAddColumn(BookDatabaseEntity.NAME);
|
||||
|
@ -24,6 +24,8 @@ import com.yahoo.squidb.annotations.TableModelSpec;
|
||||
@TableModelSpec(className = "BookDatabaseEntity", tableName = "book")
|
||||
public class BookDataSource {
|
||||
|
||||
public String filePath;
|
||||
|
||||
public String bookId;
|
||||
|
||||
public String title;
|
||||
@ -39,9 +41,6 @@ public class BookDataSource {
|
||||
public String date;
|
||||
|
||||
public String url;
|
||||
|
||||
public String remoteUrl;
|
||||
|
||||
public String articleCount;
|
||||
|
||||
public String mediaCount;
|
||||
@ -52,6 +51,5 @@ public class BookDataSource {
|
||||
|
||||
public String name;
|
||||
|
||||
public boolean downloaded;
|
||||
|
||||
}
|
||||
|
@ -17,13 +17,10 @@
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.downloader;
|
||||
|
||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity;
|
||||
import org.kiwix.kiwixmobile.utils.StorageUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.kiwix.kiwixmobile.utils.StorageUtils;
|
||||
|
||||
public class ChunkUtils {
|
||||
|
||||
@ -80,14 +77,14 @@ public class ChunkUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static long getCurrentSize(LibraryNetworkEntity.Book book) {
|
||||
long size = 0;
|
||||
File[] files = getAllZimParts(book.file);
|
||||
for (File file : files) {
|
||||
size += file.length();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
//public static long getCurrentSize(LibraryNetworkEntity.Book book) {
|
||||
// long size = 0;
|
||||
// File[] files = getAllZimParts(book.file);
|
||||
// for (File file : files) {
|
||||
// size += file.length();
|
||||
// }
|
||||
// return size;
|
||||
//}
|
||||
|
||||
private static File[] getAllZimParts(File file) {
|
||||
final String baseName = baseNameFromParts(file);
|
||||
|
@ -79,7 +79,7 @@ class DownloadManagerRequester @Inject constructor(
|
||||
Uri.fromFile(
|
||||
File(
|
||||
"${sharedPreferenceUtil.prefStorage}/Kiwix/${
|
||||
StorageUtils.getFileNameFromUrl(uri.toString())
|
||||
StorageUtils.getFileNameFromUrl(urlString)
|
||||
}"
|
||||
)
|
||||
)
|
||||
|
@ -61,14 +61,10 @@ import org.kiwix.kiwixmobile.utils.SharedPreferenceUtil;
|
||||
import org.kiwix.kiwixmobile.utils.StorageUtils;
|
||||
import org.kiwix.kiwixmobile.utils.TestingUtils;
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageActivity;
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.LibraryFragment;
|
||||
|
||||
import static org.kiwix.kiwixmobile.downloader.ChunkUtils.completeChunk;
|
||||
import static org.kiwix.kiwixmobile.downloader.ChunkUtils.completeDownload;
|
||||
import static org.kiwix.kiwixmobile.downloader.ChunkUtils.deleteAllParts;
|
||||
import static org.kiwix.kiwixmobile.downloader.ChunkUtils.getCurrentSize;
|
||||
import static org.kiwix.kiwixmobile.downloader.ChunkUtils.initialChunk;
|
||||
import static org.kiwix.kiwixmobile.downloader.ChunkUtils.isPresent;
|
||||
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;
|
||||
@ -186,7 +182,7 @@ public class DownloadService extends Service {
|
||||
NotificationCompat.Action pause = new NotificationCompat.Action(R.drawable.ic_pause_black_24dp, getString(R.string.download_pause), pausePending);
|
||||
NotificationCompat.Action stop = new NotificationCompat.Action(R.drawable.ic_stop_black_24dp, getString(R.string.download_stop), stopPending);
|
||||
|
||||
if(flags == START_FLAG_REDELIVERY && book.file == null) {
|
||||
if (flags == START_FLAG_REDELIVERY /*&& book.file == null*/) {
|
||||
return START_NOT_STICKY;
|
||||
} else {
|
||||
notification.put(notificationID , new NotificationCompat.Builder(this, ONGOING_DOWNLOAD_CHANNEL_ID)
|
||||
@ -288,13 +284,13 @@ public class DownloadService extends Service {
|
||||
// KIWIX_ROOT + StorageUtils.getFileNameFromUrl(book.getUrl()));
|
||||
//}
|
||||
TestingUtils.bindResource(DownloadService.class);
|
||||
if (book.file != null && isPresent(book.file.getPath())) {
|
||||
// Calculate initial download progress
|
||||
int initial = (int) (getCurrentSize(book) / (Long.valueOf(book.getSize()) * BOOK_SIZE_OFFSET));
|
||||
notification.get(notificationID).setProgress(100, initial, false);
|
||||
updateDownloadFragmentProgress(initial, notificationID, book);
|
||||
notificationManager.notify(notificationID, notification.get(notificationID).build());
|
||||
}
|
||||
//if (book.file != null && isPresent(book.file.getPath())) {
|
||||
// // Calculate initial download progress
|
||||
// int initial = (int) (getCurrentSize(book) / (Long.valueOf(book.getSize()) * BOOK_SIZE_OFFSET));
|
||||
// notification.get(notificationID).setProgress(100, initial, false);
|
||||
// updateDownloadFragmentProgress(initial, notificationID, book);
|
||||
// notificationManager.notify(notificationID, notification.get(notificationID).build());
|
||||
//}
|
||||
kiwixService.getMetaLinks(url)
|
||||
.retryWhen(errors -> errors.flatMap(error -> Observable.timer(5, TimeUnit.SECONDS)))
|
||||
.subscribeOn(AndroidSchedulers.mainThread())
|
||||
@ -307,14 +303,14 @@ public class DownloadService extends Service {
|
||||
notification.get(notificationID).setContentText(getString(R.string.zim_file_downloaded));
|
||||
final Intent target = new Intent(this, KiwixMobileActivity.class);
|
||||
target.putExtra(EXTRA_ZIM_FILE, KIWIX_ROOT + StorageUtils.getFileNameFromUrl(book.getUrl()));
|
||||
File filec = book.file;
|
||||
completeDownload(filec);
|
||||
//File filec = book.file;
|
||||
//completeDownload(filec);
|
||||
target.putExtra(EXTRA_NOTIFICATION_ID, notificationID);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity
|
||||
(getBaseContext(), 0,
|
||||
target, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
book.downloaded = true;
|
||||
bookDao.deleteBook(book.id);
|
||||
//book.downloaded = true;
|
||||
//bookDao.deleteBook(book.id);
|
||||
notification.get(notificationID).setContentIntent(pendingIntent);
|
||||
// notification.get(notificationID).mActions.clear();
|
||||
TestingUtils.unbindResource(DownloadService.class);
|
||||
|
@ -0,0 +1,10 @@
|
||||
package org.kiwix.kiwixmobile.downloader.model
|
||||
|
||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity.Book
|
||||
import java.io.File
|
||||
|
||||
data class BookOnDisk(
|
||||
val databaseId: Long? = null,
|
||||
val book: Book,
|
||||
val file: File
|
||||
)
|
@ -22,16 +22,18 @@ import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity
|
||||
import org.kiwix.kiwixmobile.library.entity.MetaLinkNetworkEntity
|
||||
|
||||
data class DownloadRequest(
|
||||
val uri: Uri,
|
||||
val urlString: String,
|
||||
val title: String,
|
||||
val description: String
|
||||
) {
|
||||
|
||||
val uri get() = Uri.parse(urlString)
|
||||
|
||||
constructor(
|
||||
metaLinkNetworkEntity: MetaLinkNetworkEntity,
|
||||
book: LibraryNetworkEntity.Book
|
||||
) : this(
|
||||
Uri.parse(metaLinkNetworkEntity.relevantUrl.value),
|
||||
metaLinkNetworkEntity.relevantUrl.value,
|
||||
book.title,
|
||||
book.description
|
||||
)
|
||||
|
@ -68,9 +68,8 @@ class DownloadStatus(
|
||||
val uri: String?,
|
||||
val book: Book
|
||||
) {
|
||||
fun toBook() = book.also {
|
||||
book.file = File(Uri.parse(localUri).path)
|
||||
}
|
||||
|
||||
fun toBookOnDisk() = BookOnDisk(book = book, file = File(Uri.parse(localUri).path))
|
||||
|
||||
constructor(
|
||||
cursor: Cursor,
|
||||
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.library.entity;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedList;
|
||||
import org.simpleframework.xml.Attribute;
|
||||
@ -44,9 +43,6 @@ public class LibraryNetworkEntity {
|
||||
|
||||
@Root(name = "book", strict = false)
|
||||
public static class Book implements Serializable{
|
||||
@Attribute(name = "databaseId", required = false)
|
||||
public long databaseId;
|
||||
|
||||
@Attribute(name = "id", required = false)
|
||||
public String id;
|
||||
|
||||
@ -92,12 +88,8 @@ public class LibraryNetworkEntity {
|
||||
@Attribute(name = "tags", required = false)
|
||||
public String tags;
|
||||
|
||||
public boolean downloaded = false;
|
||||
|
||||
public int searchMatches = 0;
|
||||
|
||||
public File file;
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
@ -26,18 +26,19 @@ import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import org.kiwix.kiwixmobile.ZimContentProvider;
|
||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.Collection;
|
||||
import java.util.Vector;
|
||||
|
||||
import eu.mhutti1.utils.storage.StorageDevice;
|
||||
import eu.mhutti1.utils.storage.StorageDeviceUtils;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import org.kiwix.kiwixmobile.ZimContentProvider;
|
||||
import org.kiwix.kiwixmobile.downloader.model.BookOnDisk;
|
||||
import org.kiwix.kiwixmobile.downloader.model.DownloadModel;
|
||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity;
|
||||
import org.kiwix.kiwixmobile.utils.StorageUtils;
|
||||
|
||||
import static org.kiwix.kiwixmobile.utils.Constants.TAG_KIWIX;
|
||||
|
||||
@ -48,13 +49,15 @@ public class FileSearch {
|
||||
|
||||
|
||||
private final Context context;
|
||||
private final List<DownloadModel> downloads;
|
||||
private final ResultListener listener;
|
||||
|
||||
private boolean fileSystemScanCompleted = false;
|
||||
private boolean mediaStoreScanCompleted = false;
|
||||
|
||||
public FileSearch(Context ctx, ResultListener listener) {
|
||||
public FileSearch(Context ctx, List<DownloadModel> downloads, ResultListener listener) {
|
||||
this.context = ctx;
|
||||
this.downloads = downloads;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@ -96,7 +99,6 @@ public class FileSearch {
|
||||
try {
|
||||
while (query.moveToNext()) {
|
||||
File file = new File(query.getString(0));
|
||||
|
||||
if (file.canRead())
|
||||
onFileFound(file.getAbsolutePath());
|
||||
}
|
||||
@ -174,7 +176,7 @@ public class FileSearch {
|
||||
return files.toArray(arr);
|
||||
}
|
||||
|
||||
public static synchronized LibraryNetworkEntity.Book fileToBook(String filePath) {
|
||||
public static synchronized BookOnDisk fileToBookOnDisk(String filePath) {
|
||||
LibraryNetworkEntity.Book book = null;
|
||||
|
||||
if (ZimContentProvider.zimFileName != null) {
|
||||
@ -188,7 +190,6 @@ public class FileSearch {
|
||||
book = new LibraryNetworkEntity.Book();
|
||||
book.title = ZimContentProvider.getZimFileTitle();
|
||||
book.id = ZimContentProvider.getId();
|
||||
book.file = new File(filePath);
|
||||
book.size = String.valueOf(ZimContentProvider.getFileSize());
|
||||
book.favicon = ZimContentProvider.getFavicon();
|
||||
book.creator = ZimContentProvider.getCreator();
|
||||
@ -210,7 +211,7 @@ public class FileSearch {
|
||||
}
|
||||
ZimContentProvider.originalFileName = "";
|
||||
|
||||
return book;
|
||||
return new BookOnDisk(null, book, new File(filePath));
|
||||
}
|
||||
|
||||
// Fill fileList with files found in the specific directory
|
||||
@ -225,14 +226,26 @@ public class FileSearch {
|
||||
|
||||
// Callback that a new file has been found
|
||||
public void onFileFound(String filePath) {
|
||||
LibraryNetworkEntity.Book book = fileToBook(filePath);
|
||||
if (fileIsDownloading(filePath)) {
|
||||
return;
|
||||
}
|
||||
BookOnDisk book = fileToBookOnDisk(filePath);
|
||||
|
||||
if (book != null)
|
||||
listener.onBookFound(book);
|
||||
}
|
||||
|
||||
private boolean fileIsDownloading(String filePath) {
|
||||
for (DownloadModel download : downloads) {
|
||||
if (filePath.endsWith(StorageUtils.getFileNameFromUrl(download.getBook().getUrl()))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public interface ResultListener {
|
||||
void onBookFound(LibraryNetworkEntity.Book book);
|
||||
void onBookFound(BookOnDisk book);
|
||||
|
||||
void onScanCompleted();
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import org.kiwix.kiwixmobile.database.BookDao
|
||||
import org.kiwix.kiwixmobile.database.DownloadDao
|
||||
import org.kiwix.kiwixmobile.database.NetworkLanguageDao
|
||||
import org.kiwix.kiwixmobile.downloader.Downloader
|
||||
import org.kiwix.kiwixmobile.downloader.model.BookOnDisk
|
||||
import org.kiwix.kiwixmobile.downloader.model.DownloadItem
|
||||
import org.kiwix.kiwixmobile.downloader.model.DownloadModel
|
||||
import org.kiwix.kiwixmobile.downloader.model.DownloadState.Successful
|
||||
@ -75,7 +76,7 @@ class ZimManageViewModel @Inject constructor(
|
||||
|
||||
val libraryItems: MutableLiveData<List<LibraryListItem>> = MutableLiveData()
|
||||
val downloadItems: MutableLiveData<List<DownloadItem>> = MutableLiveData()
|
||||
val bookItems: MutableLiveData<List<Book>> = MutableLiveData()
|
||||
val bookItems: MutableLiveData<List<BookOnDisk>> = MutableLiveData()
|
||||
val deviceListIsRefreshing = MutableLiveData<Boolean>()
|
||||
val libraryListIsRefreshing = MutableLiveData<Boolean>()
|
||||
val networkStates = MutableLiveData<NetworkState>()
|
||||
@ -102,7 +103,7 @@ class ZimManageViewModel @Inject constructor(
|
||||
private fun disposables(): Array<Disposable> {
|
||||
val downloads: Flowable<MutableList<DownloadModel>> = downloadDao.downloads()
|
||||
val downloadStatuses = downloadStatuses(downloads)
|
||||
val booksFromDao: Flowable<List<Book>> = books()
|
||||
val booksFromDao = books()
|
||||
val networkLibrary = PublishProcessor.create<LibraryNetworkEntity>()
|
||||
return arrayOf(
|
||||
updateDownloadItems(downloadStatuses),
|
||||
@ -195,7 +196,7 @@ class ZimManageViewModel @Inject constructor(
|
||||
)
|
||||
|
||||
private fun updateLibraryItems(
|
||||
booksFromDao: Flowable<List<Book>>,
|
||||
booksFromDao: Flowable<List<BookOnDisk>>,
|
||||
downloads: Flowable<MutableList<DownloadModel>>,
|
||||
library: Flowable<LibraryNetworkEntity>
|
||||
) = Flowable.combineLatest(
|
||||
@ -288,14 +289,14 @@ class ZimManageViewModel @Inject constructor(
|
||||
) = allLanguages.firstOrNull { it.languageCode == locale.isO3Language }?.active == true
|
||||
|
||||
private fun combineLibrarySources(
|
||||
booksOnFileSystem: List<Book>,
|
||||
booksOnFileSystem: List<BookOnDisk>,
|
||||
activeDownloads: List<DownloadModel>,
|
||||
allLanguages: List<Language>,
|
||||
libraryNetworkEntity: LibraryNetworkEntity,
|
||||
filter: String,
|
||||
fileSystemState: FileSystemState
|
||||
): List<LibraryListItem> {
|
||||
val downloadedBooksIds = booksOnFileSystem.map { it.id }
|
||||
val downloadedBooksIds = booksOnFileSystem.map { it.book.id }
|
||||
val downloadingBookIds = activeDownloads.map { it.book.id }
|
||||
val activeLanguageCodes = allLanguages.filter(Language::active)
|
||||
.map { it.languageCode }
|
||||
@ -355,7 +356,7 @@ class ZimManageViewModel @Inject constructor(
|
||||
private fun toBookItems(books: List<Book>) =
|
||||
books.map { BookItem(it) }.toTypedArray()
|
||||
|
||||
private fun checkFileSystemForBooksOnRequest(booksFromDao: Flowable<List<Book>>) =
|
||||
private fun checkFileSystemForBooksOnRequest(booksFromDao: Flowable<List<BookOnDisk>>) =
|
||||
requestFileSystemCheck
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
@ -363,7 +364,7 @@ class ZimManageViewModel @Inject constructor(
|
||||
.doOnNext { deviceListIsRefreshing.postValue(true) }
|
||||
.switchMap(
|
||||
{
|
||||
updateBookDaoFromFilesystem(booksFromDao)
|
||||
booksFromStorageNotIn(booksFromDao)
|
||||
},
|
||||
1
|
||||
)
|
||||
@ -376,24 +377,23 @@ class ZimManageViewModel @Inject constructor(
|
||||
|
||||
private fun books() = bookDao.books()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.map { it.sortedBy { book -> book.title } }
|
||||
.map { it.sortedBy { book -> book.book.title } }
|
||||
|
||||
private fun updateBookDaoFromFilesystem(booksFromDao: Flowable<List<Book>>) =
|
||||
private fun booksFromStorageNotIn(booksFromDao: Flowable<List<BookOnDisk>>) =
|
||||
storageObserver.booksOnFileSystem
|
||||
.withLatestFrom(
|
||||
booksFromDao,
|
||||
booksFromDao.map { it.map { bookOnDisk -> bookOnDisk.book.id } },
|
||||
BiFunction(this::removeBooksAlreadyInDao)
|
||||
)
|
||||
|
||||
private fun removeBooksAlreadyInDao(
|
||||
booksFromFileSystem: Collection<Book>,
|
||||
booksFromDao: List<Book>
|
||||
): List<Book> {
|
||||
val idsInDao = booksFromDao.map { it.id }
|
||||
return booksFromFileSystem.filterNot { idsInDao.contains(it.id) }
|
||||
}
|
||||
booksFromFileSystem: Collection<BookOnDisk>,
|
||||
idsInDao: List<String>
|
||||
) = booksFromFileSystem.filterNot { idsInDao.contains(it.book.id) }
|
||||
|
||||
private fun updateBookItems(booksFromDao: Flowable<List<Book>>) =
|
||||
private fun updateBookItems(
|
||||
booksFromDao: Flowable<List<BookOnDisk>>
|
||||
) =
|
||||
booksFromDao
|
||||
.subscribe(
|
||||
bookItems::postValue,
|
||||
@ -407,7 +407,7 @@ class ZimManageViewModel @Inject constructor(
|
||||
.map { it.filter { status -> status.state == Successful } }
|
||||
.subscribe(
|
||||
{
|
||||
bookDao.saveBooks(it.map { downloadStatus -> downloadStatus.toBook() })
|
||||
bookDao.saveBooks(it.map { downloadStatus -> downloadStatus.toBookOnDisk() })
|
||||
downloadDao.delete(
|
||||
*it.map { status -> status.downloadId }.toTypedArray()
|
||||
)
|
||||
|
@ -3,37 +3,37 @@ package org.kiwix.kiwixmobile.zim_manager.fileselect_view
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.view.ViewGroup
|
||||
import org.kiwix.kiwixmobile.R.layout
|
||||
import org.kiwix.kiwixmobile.downloader.model.BookOnDisk
|
||||
import org.kiwix.kiwixmobile.extensions.inflate
|
||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity.Book
|
||||
import org.kiwix.kiwixmobile.utils.BookUtils
|
||||
|
||||
class BooksAdapter(
|
||||
class BooksOnDiskAdapter(
|
||||
private val bookUtils: BookUtils,
|
||||
private val onItemClick: (Book) -> Unit,
|
||||
private val onItemLongClick: (Book) -> Unit
|
||||
) : RecyclerView.Adapter<BooksViewHolder>() {
|
||||
private val onItemClick: (BookOnDisk) -> Unit,
|
||||
private val onItemLongClick: (BookOnDisk) -> Unit
|
||||
) : RecyclerView.Adapter<BooksOnDiskViewHolder>() {
|
||||
|
||||
init {
|
||||
setHasStableIds(true)
|
||||
}
|
||||
|
||||
var itemList: List<Book> = mutableListOf()
|
||||
var itemList: List<BookOnDisk> = mutableListOf()
|
||||
set(value) {
|
||||
field = value
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getItemId(position: Int) = itemList[position].databaseId
|
||||
override fun getItemId(position: Int) = itemList[position].databaseId!!
|
||||
|
||||
override fun onCreateViewHolder(
|
||||
parent: ViewGroup,
|
||||
viewType: Int
|
||||
) = BooksViewHolder(parent.inflate(layout.library_item, false), bookUtils)
|
||||
) = BooksOnDiskViewHolder(parent.inflate(layout.library_item, false), bookUtils)
|
||||
|
||||
override fun getItemCount() = itemList.size
|
||||
|
||||
override fun onBindViewHolder(
|
||||
holder: BooksViewHolder,
|
||||
holder: BooksOnDiskViewHolder,
|
||||
position: Int
|
||||
) {
|
||||
holder.bind(itemList[position], onItemClick, onItemLongClick)
|
@ -14,23 +14,24 @@ import kotlinx.android.synthetic.main.library_item.size
|
||||
import kotlinx.android.synthetic.main.library_item.title
|
||||
import org.kiwix.kiwixmobile.KiwixApplication
|
||||
import org.kiwix.kiwixmobile.downloader.model.Base64String
|
||||
import org.kiwix.kiwixmobile.downloader.model.BookOnDisk
|
||||
import org.kiwix.kiwixmobile.extensions.setBitmap
|
||||
import org.kiwix.kiwixmobile.extensions.setTextAndVisibility
|
||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity.Book
|
||||
import org.kiwix.kiwixmobile.utils.BookUtils
|
||||
import org.kiwix.kiwixmobile.utils.NetworkUtils
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.KiloByte
|
||||
|
||||
class BooksViewHolder(
|
||||
class BooksOnDiskViewHolder(
|
||||
override val containerView: View,
|
||||
private val bookUtils: BookUtils
|
||||
) : ViewHolder(containerView),
|
||||
LayoutContainer {
|
||||
fun bind(
|
||||
book: Book,
|
||||
clickAction: (Book) -> Unit,
|
||||
longClickAction: (Book) -> Unit
|
||||
bookOnDisk: BookOnDisk,
|
||||
clickAction: (BookOnDisk) -> Unit,
|
||||
longClickAction: (BookOnDisk) -> Unit
|
||||
) {
|
||||
val book = bookOnDisk.book
|
||||
title.setTextAndVisibility(book.title)
|
||||
description.setTextAndVisibility(book.description)
|
||||
creator.setTextAndVisibility(book.creator)
|
||||
@ -39,15 +40,15 @@ class BooksViewHolder(
|
||||
size.setTextAndVisibility(KiloByte(book.size).humanReadable)
|
||||
language.text = bookUtils.getLanguage(book.getLanguage())
|
||||
fileName.text = NetworkUtils.parseURL(
|
||||
KiwixApplication.getInstance(), book.file.path
|
||||
KiwixApplication.getInstance(), book.url
|
||||
)
|
||||
favicon.setBitmap(Base64String(book.favicon))
|
||||
|
||||
containerView.setOnClickListener {
|
||||
clickAction.invoke(book)
|
||||
clickAction.invoke(bookOnDisk)
|
||||
}
|
||||
containerView.setOnLongClickListener {
|
||||
longClickAction.invoke(book)
|
||||
longClickAction.invoke(bookOnDisk)
|
||||
return@setOnLongClickListener true
|
||||
}
|
||||
}
|
@ -3,7 +3,9 @@ package org.kiwix.kiwixmobile.zim_manager.fileselect_view
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import io.reactivex.processors.PublishProcessor
|
||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity.Book
|
||||
import org.kiwix.kiwixmobile.database.DownloadDao
|
||||
import org.kiwix.kiwixmobile.downloader.model.BookOnDisk
|
||||
import org.kiwix.kiwixmobile.downloader.model.DownloadModel
|
||||
import org.kiwix.kiwixmobile.utils.SharedPreferenceUtil
|
||||
import org.kiwix.kiwixmobile.utils.files.FileSearch
|
||||
import org.kiwix.kiwixmobile.utils.files.FileSearch.ResultListener
|
||||
@ -11,20 +13,21 @@ import javax.inject.Inject
|
||||
|
||||
class StorageObserver @Inject constructor(
|
||||
private val context: Context,
|
||||
private val sharedPreferenceUtil: SharedPreferenceUtil
|
||||
private val sharedPreferenceUtil: SharedPreferenceUtil,
|
||||
private val downloadDao: DownloadDao
|
||||
) {
|
||||
|
||||
private val _booksOnFileSystem = PublishProcessor.create<Collection<Book>>()
|
||||
private val _booksOnFileSystem = PublishProcessor.create<Collection<BookOnDisk>>()
|
||||
val booksOnFileSystem = _booksOnFileSystem.distinctUntilChanged()
|
||||
.doOnSubscribe { scanFiles() }
|
||||
.doOnSubscribe { scanFiles(downloadDao.downloads) }
|
||||
|
||||
private fun scanFiles() {
|
||||
FileSearch(context, object : ResultListener {
|
||||
val foundBooks = mutableSetOf<Book>()
|
||||
private fun scanFiles(downloads: MutableList<DownloadModel>) {
|
||||
FileSearch(context, downloads, object : ResultListener {
|
||||
val foundBooks = mutableSetOf<BookOnDisk>()
|
||||
|
||||
override fun onBookFound(book: Book) {
|
||||
override fun onBookFound(book: BookOnDisk) {
|
||||
foundBooks.add(book)
|
||||
Log.i("Scanner", "File Search: Found Book " + book.title)
|
||||
Log.i("Scanner", "File Search: Found Book " + book.book.title)
|
||||
}
|
||||
|
||||
override fun onScanCompleted() {
|
||||
|
@ -40,8 +40,8 @@ import org.kiwix.kiwixmobile.ZimContentProvider
|
||||
import org.kiwix.kiwixmobile.base.BaseFragment
|
||||
import org.kiwix.kiwixmobile.database.BookDao
|
||||
import org.kiwix.kiwixmobile.di.components.ActivityComponent
|
||||
import org.kiwix.kiwixmobile.downloader.model.BookOnDisk
|
||||
import org.kiwix.kiwixmobile.extensions.toast
|
||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity.Book
|
||||
import org.kiwix.kiwixmobile.utils.BookUtils
|
||||
import org.kiwix.kiwixmobile.utils.Constants.REQUEST_STORAGE_PERMISSION
|
||||
import org.kiwix.kiwixmobile.utils.DialogShower
|
||||
@ -66,8 +66,8 @@ class ZimFileSelectFragment : BaseFragment() {
|
||||
.get(ZimManageViewModel::class.java)
|
||||
}
|
||||
|
||||
private val booksAdapter: BooksAdapter by lazy {
|
||||
BooksAdapter(
|
||||
private val booksOnDiskAdapter: BooksOnDiskAdapter by lazy {
|
||||
BooksOnDiskAdapter(
|
||||
bookUtils, this::open, this::tryToDelete
|
||||
)
|
||||
}
|
||||
@ -92,12 +92,12 @@ class ZimFileSelectFragment : BaseFragment() {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
zim_swiperefresh.setOnRefreshListener(this::requestFileSystemCheck)
|
||||
zimfilelist.run {
|
||||
adapter = booksAdapter
|
||||
adapter = booksOnDiskAdapter
|
||||
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
||||
setHasFixedSize(true)
|
||||
}
|
||||
zimManageViewModel.bookItems.observe(this, Observer {
|
||||
booksAdapter.itemList = it!!
|
||||
booksOnDiskAdapter.itemList = it!!
|
||||
checkEmpty(it)
|
||||
})
|
||||
zimManageViewModel.deviceListIsRefreshing.observe(this, Observer {
|
||||
@ -110,7 +110,7 @@ class ZimFileSelectFragment : BaseFragment() {
|
||||
checkPermissions()
|
||||
}
|
||||
|
||||
private fun checkEmpty(books: List<Book>) {
|
||||
private fun checkEmpty(books: List<BookOnDisk>) {
|
||||
file_management_no_files.visibility =
|
||||
if (books.isEmpty()) View.VISIBLE
|
||||
else View.GONE
|
||||
@ -136,7 +136,7 @@ class ZimFileSelectFragment : BaseFragment() {
|
||||
zimManageViewModel.requestFileSystemCheck.onNext(Unit)
|
||||
}
|
||||
|
||||
private fun open(it: Book) {
|
||||
private fun open(it: BookOnDisk) {
|
||||
ZimContentProvider.canIterate = false
|
||||
if (!it.file.canRead()) {
|
||||
context.toast(string.error_filenotfound)
|
||||
@ -145,7 +145,7 @@ class ZimFileSelectFragment : BaseFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun tryToDelete(it: Book) {
|
||||
private fun tryToDelete(it: BookOnDisk) {
|
||||
dialogShower.show(DeleteZim, {
|
||||
if (deleteSpecificZimFile(it)) {
|
||||
context.toast(string.delete_specific_zim_toast)
|
||||
@ -155,13 +155,13 @@ class ZimFileSelectFragment : BaseFragment() {
|
||||
})
|
||||
}
|
||||
|
||||
private fun deleteSpecificZimFile(book: Book): Boolean {
|
||||
private fun deleteSpecificZimFile(book: BookOnDisk): Boolean {
|
||||
val file = book.file
|
||||
FileUtils.deleteZimFile(file)
|
||||
if (file.exists()) {
|
||||
return false
|
||||
}
|
||||
bookDao.deleteBook(book.id)
|
||||
bookDao.deleteBook(book.databaseId)
|
||||
return true
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ sealed class LibraryViewHolder<T : LibraryListItem>(override val containerView:
|
||||
size.setTextAndVisibility(KiloByte(item.book.size).humanReadable)
|
||||
language.text = bookUtils.getLanguage(item.book.getLanguage())
|
||||
fileName.text = NetworkUtils.parseURL(
|
||||
KiwixApplication.getInstance(), item.book.file?.path ?: ""
|
||||
KiwixApplication.getInstance(), item.book.url
|
||||
)
|
||||
favicon.setBitmap(Base64String(item.book.favicon))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user