package com.quran.labs.androidquran.model.bookmark;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v4.content.FileProvider;
import com.quran.labs.androidquran.R;
import com.quran.labs.androidquran.dao.BookmarkData;
import com.quran.labs.androidquran.database.BookmarksDBAdapter;
import java.io.File;
import java.io.IOException;
import javax.inject.Inject;
import io.reactivex.Single;
import io.reactivex.schedulers.Schedulers;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
public class BookmarkImportExportModel {
private static final String FILE_NAME = "quran_android.backup";
private final Context appContext;
private final BookmarkJsonModel jsonModel;
private final BookmarkModel bookmarkModel;
@Inject
BookmarkImportExportModel(Context appContext,
BookmarkJsonModel model, BookmarkModel bookmarkModel) {
this.appContext = appContext;
this.jsonModel = model;
this.bookmarkModel = bookmarkModel;
}
public Single<BookmarkData> readBookmarks(@NonNull final BufferedSource source) {
return Single.defer(() -> Single.just(jsonModel.fromJson(source)))
.subscribeOn(Schedulers.io());
}
public Single<Uri> exportBookmarksObservable() {
return bookmarkModel.getBookmarkDataObservable(BookmarksDBAdapter.SORT_DATE_ADDED)
.flatMap(bookmarkData -> Single.just(exportBookmarks(bookmarkData)))
.subscribeOn(Schedulers.io());
}
@NonNull
private Uri exportBookmarks(BookmarkData data) throws IOException {
// exporting often fails due to the thread being interrupted (when okio sees an interrupted
// thread, it doesn't flush the buffer and instead just throws an exception and returns).
// may revisit this after hearing back about https://github.com/ReactiveX/RxJava/issues/5024.
Thread.interrupted();
File externalFilesDir = new File(appContext.getExternalFilesDir(null), "backups");
if (externalFilesDir.exists() || externalFilesDir.mkdir()) {
File file = new File(externalFilesDir, FILE_NAME);
BufferedSink sink = Okio.buffer(Okio.sink(file));
jsonModel.toJson(sink, data);
sink.close();
return FileProvider.getUriForFile(
appContext, appContext.getString(R.string.file_authority), file);
}
throw new IOException("Unable to write to external files directory.");
}
}