mirror of
https://github.com/MinimalBible/MinimalBible
synced 2024-11-24 17:08:18 -05:00
Download and search indexes
Search currently not yielding results, but everything surrounding it appears to be working.
This commit is contained in:
parent
902b91776d
commit
3721ef5ee0
@ -7,6 +7,7 @@ import org.bspeice.minimalbible.Injector;
|
|||||||
import org.bspeice.minimalbible.activity.downloader.DownloadPrefs;
|
import org.bspeice.minimalbible.activity.downloader.DownloadPrefs;
|
||||||
import org.bspeice.minimalbible.activity.downloader.manager.BookManager;
|
import org.bspeice.minimalbible.activity.downloader.manager.BookManager;
|
||||||
import org.bspeice.minimalbible.activity.downloader.manager.DLProgressEvent;
|
import org.bspeice.minimalbible.activity.downloader.manager.DLProgressEvent;
|
||||||
|
import org.bspeice.minimalbible.activity.downloader.manager.MBIndexManager;
|
||||||
import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager;
|
import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager;
|
||||||
import org.crosswire.common.progress.JobManager;
|
import org.crosswire.common.progress.JobManager;
|
||||||
import org.crosswire.common.progress.Progress;
|
import org.crosswire.common.progress.Progress;
|
||||||
@ -19,6 +20,8 @@ import org.crosswire.jsword.book.Books;
|
|||||||
import org.crosswire.jsword.book.BooksEvent;
|
import org.crosswire.jsword.book.BooksEvent;
|
||||||
import org.crosswire.jsword.book.install.InstallManager;
|
import org.crosswire.jsword.book.install.InstallManager;
|
||||||
import org.crosswire.jsword.book.install.Installer;
|
import org.crosswire.jsword.book.install.Installer;
|
||||||
|
import org.crosswire.jsword.index.IndexManager;
|
||||||
|
import org.crosswire.jsword.index.IndexManagerFactory;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -93,9 +96,9 @@ public class BookManagerTest implements Injector {
|
|||||||
.subscribe(new Action1<DLProgressEvent>() {
|
.subscribe(new Action1<DLProgressEvent>() {
|
||||||
@Override
|
@Override
|
||||||
public void call(DLProgressEvent dlProgressEvent) {
|
public void call(DLProgressEvent dlProgressEvent) {
|
||||||
System.out.println(dlProgressEvent.getAverageProgress());
|
System.out.println(dlProgressEvent.getProgress());
|
||||||
if (dlProgressEvent.getB().getInitials().equals(toInstall.getInitials())
|
if (dlProgressEvent.getB().getInitials().equals(toInstall.getInitials())
|
||||||
&& dlProgressEvent.getAverageProgress() == DLProgressEvent.PROGRESS_COMPLETE) {
|
&& dlProgressEvent.getProgress() == DLProgressEvent.PROGRESS_COMPLETE) {
|
||||||
signal.set(true);
|
signal.set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,7 +115,7 @@ public class BookManagerTest implements Injector {
|
|||||||
@Test
|
@Test
|
||||||
public void testJobIdMatch() {
|
public void testJobIdMatch() {
|
||||||
final Book toInstall = installableBooks().toBlocking().first();
|
final Book toInstall = installableBooks().toBlocking().first();
|
||||||
final String jobName = bookManager.getJobNames(toInstall).get(0);
|
final String jobName = bookManager.getJobName(toInstall);
|
||||||
final AtomicBoolean jobNameMatch = new AtomicBoolean(false);
|
final AtomicBoolean jobNameMatch = new AtomicBoolean(false);
|
||||||
|
|
||||||
JobManager.addWorkListener(new WorkListener() {
|
JobManager.addWorkListener(new WorkListener() {
|
||||||
@ -160,7 +163,12 @@ public class BookManagerTest implements Injector {
|
|||||||
|
|
||||||
bookManager.getInstalledBooksList().add(mockBook);
|
bookManager.getInstalledBooksList().add(mockBook);
|
||||||
assertTrue(bookManager.getInstalledBooksList().contains(mockBook));
|
assertTrue(bookManager.getInstalledBooksList().contains(mockBook));
|
||||||
|
try {
|
||||||
bookManager.removeBook(mockBook, secondMockBook);
|
bookManager.removeBook(mockBook, secondMockBook);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// Nasty NPE shows up when testing because the index
|
||||||
|
// isn't installed. Suppressing here.
|
||||||
|
}
|
||||||
assertFalse(bookManager.getInstalledBooksList().contains(mockBook));
|
assertFalse(bookManager.getInstalledBooksList().contains(mockBook));
|
||||||
verify(driver, times(1)).delete(secondMockBook);
|
verify(driver, times(1)).delete(secondMockBook);
|
||||||
}
|
}
|
||||||
@ -173,14 +181,12 @@ public class BookManagerTest implements Injector {
|
|||||||
public void testWorkProgressedCorrectProgress() {
|
public void testWorkProgressedCorrectProgress() {
|
||||||
Book mockBook = mock(Book.class);
|
Book mockBook = mock(Book.class);
|
||||||
when(mockBook.getInitials()).thenReturn("mockBook");
|
when(mockBook.getInitials()).thenReturn("mockBook");
|
||||||
String bookJobName = bookManager.getJobNames(mockBook).get(0);
|
String bookJobName = bookManager.getJobName(mockBook);
|
||||||
bookManager.getInProgressJobNames().put(bookJobName, mockBook);
|
bookManager.getInProgressJobNames().put(bookJobName, mockBook);
|
||||||
|
|
||||||
// Percent to degrees
|
// Percent to degrees
|
||||||
final int workDone = 50; // 50%
|
final int workDone = 50; // 50%
|
||||||
// There are two jobs, each comprising 180 degrees.
|
final int circularProgress = 180;
|
||||||
// Since we are simulating one job being 50% complete, that's 90 degrees
|
|
||||||
final int circularProgress = 90;
|
|
||||||
WorkEvent ev = mock(WorkEvent.class);
|
WorkEvent ev = mock(WorkEvent.class);
|
||||||
Progress p = mock(Progress.class);
|
Progress p = mock(Progress.class);
|
||||||
|
|
||||||
@ -266,11 +272,25 @@ public class BookManagerTest implements Injector {
|
|||||||
return PublishSubject.create();
|
return PublishSubject.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
IndexManager indexManager() {
|
||||||
|
return IndexManagerFactory.getIndexManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
MBIndexManager mbIndexManager(IndexManager indexManager,
|
||||||
|
PublishSubject<DLProgressEvent> events) {
|
||||||
|
return new MBIndexManager(events, indexManager);
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
BookManager bookDownloadManager(Books installed, RefreshManager rm,
|
BookManager bookDownloadManager(Books installed, RefreshManager rm,
|
||||||
PublishSubject<DLProgressEvent> eventPublisher) {
|
PublishSubject<DLProgressEvent> eventPublisher,
|
||||||
return new BookManager(installed, rm, eventPublisher);
|
MBIndexManager manager) {
|
||||||
|
return new BookManager(installed, rm, eventPublisher, manager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,7 +12,7 @@ class DLProgressEventSpek : Spek() {{
|
|||||||
|
|
||||||
given("a DLProgressEvent created with 50% progress and a mock book") {
|
given("a DLProgressEvent created with 50% progress and a mock book") {
|
||||||
val mockBook = mock(javaClass<Book>())
|
val mockBook = mock(javaClass<Book>())
|
||||||
val dlEvent = DLProgressEvent(50, 50, mockBook)
|
val dlEvent = DLProgressEvent(50, mockBook)
|
||||||
|
|
||||||
on("getting the progress in degrees") {
|
on("getting the progress in degrees") {
|
||||||
val progressDegrees = dlEvent.toCircular()
|
val progressDegrees = dlEvent.toCircular()
|
||||||
|
@ -1,18 +1,26 @@
|
|||||||
package org.bspeice.minimalbible;
|
package org.bspeice.minimalbible;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.bspeice.minimalbible.activity.viewer.BibleViewerPreferences;
|
||||||
|
import org.bspeice.minimalbible.service.manager.BookManager;
|
||||||
import org.crosswire.jsword.book.Book;
|
import org.crosswire.jsword.book.Book;
|
||||||
import org.crosswire.jsword.book.Books;
|
import org.crosswire.jsword.book.Books;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
|
import de.devland.esperandro.Esperandro;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
|
import rx.functions.Action1;
|
||||||
import rx.functions.Func1;
|
import rx.functions.Func1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,7 +34,8 @@ public class MinimalBibleModules {
|
|||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides @Singleton
|
@Provides
|
||||||
|
@Singleton
|
||||||
Application provideApplication() {
|
Application provideApplication() {
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
@ -34,6 +43,7 @@ public class MinimalBibleModules {
|
|||||||
/**
|
/**
|
||||||
* Provide a list of book names that are known bad. This can be because they trigger NPE,
|
* Provide a list of book names that are known bad. This can be because they trigger NPE,
|
||||||
* or are just missing lots of content, etc.
|
* or are just missing lots of content, etc.
|
||||||
|
*
|
||||||
* @return the list of books (by name) to ignore
|
* @return the list of books (by name) to ignore
|
||||||
*/
|
*/
|
||||||
@Provides
|
@Provides
|
||||||
@ -80,4 +90,64 @@ public class MinimalBibleModules {
|
|||||||
})
|
})
|
||||||
.toList().toBlocking().first();
|
.toList().toBlocking().first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
BibleViewerPreferences providePrefs() {
|
||||||
|
return Esperandro.getPreferences(BibleViewerPreferences.class, app);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Named("MainBook")
|
||||||
|
Book provideMainBook(BookManager bookManager, final BibleViewerPreferences prefs) {
|
||||||
|
final AtomicReference<Book> mBook = new AtomicReference<Book>(null);
|
||||||
|
bookManager.getInstalledBooks()
|
||||||
|
.first(new Func1<Book, Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean call(Book book) {
|
||||||
|
return book.getInitials().equals(prefs.defaultBookInitials());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.subscribe(new Action1<Book>() {
|
||||||
|
@Override
|
||||||
|
public void call(Book book) {
|
||||||
|
mBook.set(book);
|
||||||
|
}
|
||||||
|
}, new Action1<Throwable>() {
|
||||||
|
@Override
|
||||||
|
public void call(Throwable throwable) {
|
||||||
|
Log.d("BibleViewerModules", throwable.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (mBook.get() == null) {
|
||||||
|
try {
|
||||||
|
Book fallback;
|
||||||
|
fallback = bookManager.getInstalledBooks()
|
||||||
|
.onErrorReturn(new Func1<Throwable, Book>() {
|
||||||
|
@Override
|
||||||
|
public Book call(Throwable throwable) {
|
||||||
|
// If there's no book installed, we can't select the main one...
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.toBlocking().first();
|
||||||
|
|
||||||
|
prefs.defaultBookInitials(fallback.getName());
|
||||||
|
return fallback;
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
// If no books are installed, there's really nothing we can do...
|
||||||
|
Log.d("BibleViewerModules", "No books are installed, so can't select a main book.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return mBook.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
BookManager bookManager(List<String> exclude) {
|
||||||
|
return new BookManager(exclude);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ import rx.functions.Func1;
|
|||||||
import rx.subjects.PublishSubject;
|
import rx.subjects.PublishSubject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by bspeice on 5/20/14.
|
* Created by bspeice on 5/20/14.
|
||||||
*/
|
*/
|
||||||
public class BookItemHolder {
|
public class BookItemHolder {
|
||||||
|
|
||||||
// TODO: The holder should register and unregister itself for DownloadProgress events
|
// TODO: The holder should register and unregister itself for DownloadProgress events
|
||||||
@ -46,7 +46,8 @@ public class BookItemHolder {
|
|||||||
ProgressWheel downloadProgress;
|
ProgressWheel downloadProgress;
|
||||||
@Inject
|
@Inject
|
||||||
BookManager bookManager;
|
BookManager bookManager;
|
||||||
@Inject @Named("DownloadActivityContext")
|
@Inject
|
||||||
|
@Named("DownloadActivityContext")
|
||||||
Context ctx;
|
Context ctx;
|
||||||
@Inject
|
@Inject
|
||||||
PublishSubject<DLProgressEvent> downloadProgressEvents;
|
PublishSubject<DLProgressEvent> downloadProgressEvents;
|
||||||
@ -65,7 +66,7 @@ public class BookItemHolder {
|
|||||||
itemName.setText(b.getName());
|
itemName.setText(b.getName());
|
||||||
DLProgressEvent dlProgressEvent = bookManager.getDownloadProgress(b);
|
DLProgressEvent dlProgressEvent = bookManager.getDownloadProgress(b);
|
||||||
if (dlProgressEvent != null) {
|
if (dlProgressEvent != null) {
|
||||||
displayProgress(dlProgressEvent.toCircular());
|
displayProgress(dlProgressEvent);
|
||||||
} else if (bookManager.isInstalled(b)) {
|
} else if (bookManager.isInstalled(b)) {
|
||||||
displayInstalled();
|
displayInstalled();
|
||||||
}
|
}
|
||||||
@ -82,7 +83,7 @@ public class BookItemHolder {
|
|||||||
.subscribe(new Action1<DLProgressEvent>() {
|
.subscribe(new Action1<DLProgressEvent>() {
|
||||||
@Override
|
@Override
|
||||||
public void call(DLProgressEvent event) {
|
public void call(DLProgressEvent event) {
|
||||||
BookItemHolder.this.displayProgress(event.toCircular());
|
BookItemHolder.this.displayProgress(event);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -109,33 +110,31 @@ public class BookItemHolder {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the current progress of this download
|
* Display the current progress of this download
|
||||||
* @param progress The progress out of 360 (degrees of a circle)
|
*
|
||||||
|
* @param event The event we need to display progress for
|
||||||
*/
|
*/
|
||||||
private void displayProgress(int progress) {
|
private void displayProgress(DLProgressEvent event) {
|
||||||
|
|
||||||
int downloadView;
|
int downloadView = downloadProgress.getId();
|
||||||
|
int progress = event.getProgress();
|
||||||
|
int circular = event.toCircular();
|
||||||
|
|
||||||
if (progress == DLProgressEvent.PROGRESS_BEGINNING) {
|
if (progress == DLProgressEvent.PROGRESS_BEGINNING) {
|
||||||
// Download starting
|
// Download starting
|
||||||
downloadView = downloadProgress.getId();
|
|
||||||
|
|
||||||
isDownloaded.setVisibility(View.GONE);
|
isDownloaded.setVisibility(View.GONE);
|
||||||
downloadProgress.setVisibility(View.VISIBLE);
|
downloadProgress.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
downloadProgress.spin();
|
downloadProgress.spin();
|
||||||
} else if (progress < 360) {
|
} else if (progress < DLProgressEvent.PROGRESS_COMPLETE) {
|
||||||
// Download in progress
|
// Download in progress
|
||||||
downloadView = downloadProgress.getId();
|
|
||||||
|
|
||||||
isDownloaded.setVisibility(View.GONE);
|
isDownloaded.setVisibility(View.GONE);
|
||||||
downloadProgress.setVisibility(View.VISIBLE);
|
downloadProgress.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
downloadProgress.stopSpinning();
|
downloadProgress.stopSpinning();
|
||||||
downloadProgress.setProgress(progress);
|
downloadProgress.setProgress(circular);
|
||||||
} else {
|
} else {
|
||||||
// Download complete
|
// Download complete
|
||||||
subscription.unsubscribe();
|
subscription.unsubscribe();
|
||||||
downloadView = downloadProgress.getId();
|
|
||||||
|
|
||||||
isDownloaded.setVisibility(View.VISIBLE);
|
isDownloaded.setVisibility(View.VISIBLE);
|
||||||
downloadProgress.setVisibility(View.GONE);
|
downloadProgress.setVisibility(View.GONE);
|
||||||
|
@ -8,11 +8,15 @@ import org.bspeice.minimalbible.MinimalBibleModules;
|
|||||||
import org.bspeice.minimalbible.activity.downloader.manager.BookManager;
|
import org.bspeice.minimalbible.activity.downloader.manager.BookManager;
|
||||||
import org.bspeice.minimalbible.activity.downloader.manager.DLProgressEvent;
|
import org.bspeice.minimalbible.activity.downloader.manager.DLProgressEvent;
|
||||||
import org.bspeice.minimalbible.activity.downloader.manager.LocaleManager;
|
import org.bspeice.minimalbible.activity.downloader.manager.LocaleManager;
|
||||||
|
import org.bspeice.minimalbible.activity.downloader.manager.MBIndexManager;
|
||||||
import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager;
|
import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager;
|
||||||
import org.crosswire.jsword.book.BookCategory;
|
import org.crosswire.jsword.book.BookCategory;
|
||||||
import org.crosswire.jsword.book.Books;
|
import org.crosswire.jsword.book.Books;
|
||||||
import org.crosswire.jsword.book.install.InstallManager;
|
import org.crosswire.jsword.book.install.InstallManager;
|
||||||
import org.crosswire.jsword.book.install.Installer;
|
import org.crosswire.jsword.book.install.Installer;
|
||||||
|
import org.crosswire.jsword.index.IndexManager;
|
||||||
|
import org.crosswire.jsword.index.IndexManagerFactory;
|
||||||
|
import org.crosswire.jsword.index.IndexPolicyAdapter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -88,8 +92,9 @@ public class DownloadActivityModules {
|
|||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
BookManager provideBookDownloadManager(Books installedBooks, RefreshManager rm,
|
BookManager provideBookDownloadManager(Books installedBooks, RefreshManager rm,
|
||||||
PublishSubject<DLProgressEvent> progressEvents) {
|
PublishSubject<DLProgressEvent> progressEvents,
|
||||||
return new BookManager(installedBooks, rm, progressEvents);
|
MBIndexManager mbIndexManager) {
|
||||||
|
return new BookManager(installedBooks, rm, progressEvents, mbIndexManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@ -123,4 +128,17 @@ public class DownloadActivityModules {
|
|||||||
LocaleManager provideLocaleManager(RefreshManager refreshManager) {
|
LocaleManager provideLocaleManager(RefreshManager refreshManager) {
|
||||||
return new LocaleManager(refreshManager);
|
return new LocaleManager(refreshManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
IndexManager indexManager() {
|
||||||
|
IndexManager manager = IndexManagerFactory.getIndexManager();
|
||||||
|
manager.setIndexPolicy(new IndexPolicyAdapter());
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
MBIndexManager mbIndexManager(PublishSubject<DLProgressEvent> downloadEvents,
|
||||||
|
IndexManager indexManager) {
|
||||||
|
return new MBIndexManager(downloadEvents, indexManager);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,9 @@ import org.bspeice.minimalbible.MinimalBible;
|
|||||||
import org.bspeice.minimalbible.OGHolder;
|
import org.bspeice.minimalbible.OGHolder;
|
||||||
import org.bspeice.minimalbible.R;
|
import org.bspeice.minimalbible.R;
|
||||||
import org.bspeice.minimalbible.activity.BaseActivity;
|
import org.bspeice.minimalbible.activity.BaseActivity;
|
||||||
|
import org.crosswire.jsword.passage.Verse;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -65,6 +68,7 @@ public class BasicSearch extends BaseActivity
|
|||||||
|
|
||||||
String query = intent.getStringExtra(SearchManager.QUERY);
|
String query = intent.getStringExtra(SearchManager.QUERY);
|
||||||
Toast.makeText(this, "Searching for: " + query, Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "Searching for: " + query, Toast.LENGTH_SHORT).show();
|
||||||
searchProvider.basicTextSearch(query);
|
List<Verse> results = searchProvider.basicTextSearch(query);
|
||||||
|
Toast.makeText(this, "Found results: " + results.size(), Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package org.bspeice.minimalbible.activity.search;
|
package org.bspeice.minimalbible.activity.search;
|
||||||
|
|
||||||
import org.bspeice.minimalbible.MinimalBibleModules;
|
import org.bspeice.minimalbible.MinimalBibleModules;
|
||||||
|
import org.crosswire.jsword.book.Book;
|
||||||
|
import org.crosswire.jsword.index.IndexManager;
|
||||||
|
import org.crosswire.jsword.index.IndexManagerFactory;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
@ -12,7 +17,13 @@ import dagger.Provides;
|
|||||||
public class SearchModules {
|
public class SearchModules {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
SearchProvider searchProvider() {
|
SearchProvider searchProvider(@Named("MainBook") Book book,
|
||||||
return new SearchProvider();
|
IndexManager indexManager) {
|
||||||
|
return new SearchProvider(book, indexManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
IndexManager jswordIndexManager() {
|
||||||
|
return IndexManagerFactory.getIndexManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,11 @@
|
|||||||
package org.bspeice.minimalbible.activity.viewer;
|
package org.bspeice.minimalbible.activity.viewer;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.bspeice.minimalbible.MinimalBibleModules;
|
import org.bspeice.minimalbible.MinimalBibleModules;
|
||||||
import org.bspeice.minimalbible.service.manager.BookManager;
|
|
||||||
import org.crosswire.jsword.book.Book;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
import de.devland.esperandro.Esperandro;
|
|
||||||
import rx.functions.Action1;
|
|
||||||
import rx.functions.Func1;
|
|
||||||
import rx.subjects.PublishSubject;
|
import rx.subjects.PublishSubject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,65 +25,6 @@ public class BibleViewerModules {
|
|||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
BibleViewerPreferences providePrefs() {
|
|
||||||
return Esperandro.getPreferences(BibleViewerPreferences.class, activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Named("MainBook")
|
|
||||||
Book provideMainBook(BookManager bookManager, final BibleViewerPreferences prefs) {
|
|
||||||
final AtomicReference<Book> mBook = new AtomicReference<Book>(null);
|
|
||||||
bookManager.getInstalledBooks()
|
|
||||||
.first(new Func1<Book, Boolean>() {
|
|
||||||
@Override
|
|
||||||
public Boolean call(Book book) {
|
|
||||||
return book.getInitials().equals(prefs.defaultBookInitials());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.subscribe(new Action1<Book>() {
|
|
||||||
@Override
|
|
||||||
public void call(Book book) {
|
|
||||||
mBook.set(book);
|
|
||||||
}
|
|
||||||
}, new Action1<Throwable>() {
|
|
||||||
@Override
|
|
||||||
public void call(Throwable throwable) {
|
|
||||||
Log.d("BibleViewerModules", throwable.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (mBook.get() == null) {
|
|
||||||
try {
|
|
||||||
Book fallback;
|
|
||||||
fallback = bookManager.getInstalledBooks()
|
|
||||||
.onErrorReturn(new Func1<Throwable, Book>() {
|
|
||||||
@Override
|
|
||||||
public Book call(Throwable throwable) {
|
|
||||||
// If there's no book installed, we can't select the main one...
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.toBlocking().first();
|
|
||||||
|
|
||||||
prefs.defaultBookInitials(fallback.getName());
|
|
||||||
return fallback;
|
|
||||||
} catch (NoSuchElementException e) {
|
|
||||||
// If no books are installed, there's really nothing we can do...
|
|
||||||
Log.d("BibleViewerModules", "No books are installed, so can't select a main book.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return mBook.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
BookManager bookManager(List<String> exclude) {
|
|
||||||
return new BookManager(exclude);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
|
12
app/src/main/kotlin/org/bspeice/minimalbible/CommonUtil.kt
Normal file
12
app/src/main/kotlin/org/bspeice/minimalbible/CommonUtil.kt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package org.bspeice.minimalbible
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Massive credit over here:
|
||||||
|
* http://blog.omalley.id.au/2013/07/27/null-handling-in-kotlin.html
|
||||||
|
*
|
||||||
|
* The trick is that a non-nullable upper bound is placed on an optional
|
||||||
|
* nullable object - effectively, you get the real object or throw an exception.
|
||||||
|
*/
|
||||||
|
public fun <T : Any> T?.orError(message: String): T {
|
||||||
|
return if (this == null) throw IllegalArgumentException(message) else this
|
||||||
|
}
|
@ -12,7 +12,6 @@ import rx.Observable;
|
|||||||
import rx.schedulers.Schedulers;
|
import rx.schedulers.Schedulers;
|
||||||
import rx.subjects.PublishSubject;
|
import rx.subjects.PublishSubject;
|
||||||
import org.crosswire.jsword.book.BookException
|
import org.crosswire.jsword.book.BookException
|
||||||
import org.crosswire.jsword.util.IndexDownloader
|
|
||||||
import org.crosswire.common.progress.Progress
|
import org.crosswire.common.progress.Progress
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,7 +21,8 @@ import org.crosswire.common.progress.Progress
|
|||||||
*/
|
*/
|
||||||
class BookManager(private val installedBooks: Books,
|
class BookManager(private val installedBooks: Books,
|
||||||
val rM: RefreshManager,
|
val rM: RefreshManager,
|
||||||
val downloadEvents: PublishSubject<DLProgressEvent>) :
|
val downloadEvents: PublishSubject<DLProgressEvent>,
|
||||||
|
val indexManager: MBIndexManager) :
|
||||||
WorkListener, BooksListener {
|
WorkListener, BooksListener {
|
||||||
|
|
||||||
private val bookJobNamePrefix = Progress.INSTALL_BOOK.substringBeforeLast("%s")
|
private val bookJobNamePrefix = Progress.INSTALL_BOOK.substringBeforeLast("%s")
|
||||||
@ -56,8 +56,7 @@ class BookManager(private val installedBooks: Books,
|
|||||||
* @param b The book to predict the download job name of
|
* @param b The book to predict the download job name of
|
||||||
* @return The name of the job that will/is download/ing this book
|
* @return The name of the job that will/is download/ing this book
|
||||||
*/
|
*/
|
||||||
fun getJobNames(b: Book) = listOf("${bookJobNamePrefix}${b.getInitials()}",
|
fun getJobName(b: Book) = "${bookJobNamePrefix}${b.getInitials()}"
|
||||||
"${indexJobNamePrefix}${b.getInitials()}")
|
|
||||||
|
|
||||||
fun downloadBook(b: Book) {
|
fun downloadBook(b: Book) {
|
||||||
// First, look up where the Book came from
|
// First, look up where the Book came from
|
||||||
@ -68,23 +67,14 @@ class BookManager(private val installedBooks: Books,
|
|||||||
// thread is closed when the install event is done
|
// thread is closed when the install event is done
|
||||||
installerObs
|
installerObs
|
||||||
.observeOn(Schedulers.newThread())
|
.observeOn(Schedulers.newThread())
|
||||||
.subscribe {
|
|
||||||
// Download the actual book
|
// Download the actual book
|
||||||
it subscribe { it install b }
|
.subscribe { it subscribe { it install b } }
|
||||||
}
|
|
||||||
|
|
||||||
installerObs
|
|
||||||
.observeOn(Schedulers.newThread())
|
|
||||||
.subscribe {
|
|
||||||
// Download the book index
|
|
||||||
it subscribe { IndexDownloader.downloadIndex(b, it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then notify everyone that we're starting
|
// Then notify everyone that we're starting
|
||||||
downloadEvents onNext DLProgressEvent.beginningEvent(b)
|
downloadEvents onNext DLProgressEvent.beginningEvent(b)
|
||||||
|
|
||||||
// Finally register the jobs in progress
|
// Finally register the jobs in progress
|
||||||
getJobNames(b).forEach { this.inProgressJobNames[it] = b }
|
inProgressJobNames[getJobName(b)] = b
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,6 +101,10 @@ class BookManager(private val installedBooks: Books,
|
|||||||
try {
|
try {
|
||||||
b.getDriver() delete realBook
|
b.getDriver() delete realBook
|
||||||
installedBooksList remove b
|
installedBooksList remove b
|
||||||
|
// Order matters for the test suite as this line will trigger NPE during testing
|
||||||
|
// In production, doesn't make a difference, so leave this below the
|
||||||
|
// installedBooksList remove
|
||||||
|
indexManager removeIndex realBook
|
||||||
return true
|
return true
|
||||||
} catch (e: BookException) {
|
} catch (e: BookException) {
|
||||||
// Log.e("InstalledManager",
|
// Log.e("InstalledManager",
|
||||||
@ -128,22 +122,26 @@ class BookManager(private val installedBooks: Books,
|
|||||||
|
|
||||||
fun isInstalled(b: Book) = installedBooksList contains b
|
fun isInstalled(b: Book) = installedBooksList contains b
|
||||||
|
|
||||||
// TODO: I have a strange feeling I can simplify this further...
|
/**
|
||||||
|
* This method gets called as progress continues on downloading a book.
|
||||||
|
* To be honest, I don't know that there's any contract about what thread
|
||||||
|
* this is called on.
|
||||||
|
* By any means, if the job hasn't been registered as in progress,
|
||||||
|
* don't emit an event - we don't know what book we're operating on.
|
||||||
|
*/
|
||||||
override fun workProgressed(ev: WorkEvent) {
|
override fun workProgressed(ev: WorkEvent) {
|
||||||
val job = ev.getJob()
|
val job = ev.getJob()
|
||||||
|
val book = inProgressJobNames[job.getJobID()]
|
||||||
|
|
||||||
|
if (book == null)
|
||||||
|
return
|
||||||
|
|
||||||
val book = inProgressJobNames[job.getJobID()] as Book
|
|
||||||
val oldEvent = inProgressDownloads[book] ?: DLProgressEvent.beginningEvent(book)
|
val oldEvent = inProgressDownloads[book] ?: DLProgressEvent.beginningEvent(book)
|
||||||
|
val newEvent = oldEvent.copy(progress = job.getWork())
|
||||||
var newEvent: DLProgressEvent
|
|
||||||
if (job.getJobID().contains(bookJobNamePrefix))
|
|
||||||
newEvent = oldEvent.copy(bookProgress = job.getWork())
|
|
||||||
else
|
|
||||||
newEvent = oldEvent.copy(indexProgress = job.getWork())
|
|
||||||
|
|
||||||
downloadEvents onNext newEvent
|
downloadEvents onNext newEvent
|
||||||
|
|
||||||
if (newEvent.averageProgress == DLProgressEvent.PROGRESS_COMPLETE) {
|
if (newEvent.progress == DLProgressEvent.PROGRESS_COMPLETE) {
|
||||||
inProgressDownloads remove inProgressJobNames[job.getJobID()]
|
inProgressDownloads remove inProgressJobNames[job.getJobID()]
|
||||||
inProgressJobNames remove job.getJobID()
|
inProgressJobNames remove job.getJobID()
|
||||||
} else
|
} else
|
||||||
|
@ -5,8 +5,7 @@ import org.crosswire.jsword.book.Book
|
|||||||
/**
|
/**
|
||||||
* Created by bspeice on 11/11/14.
|
* Created by bspeice on 11/11/14.
|
||||||
*/
|
*/
|
||||||
data class DLProgressEvent(val bookProgress: Int,
|
data class DLProgressEvent(val progress: Int,
|
||||||
val indexProgress: Int,
|
|
||||||
val b: Book) {
|
val b: Book) {
|
||||||
class object {
|
class object {
|
||||||
val PROGRESS_COMPLETE = 100
|
val PROGRESS_COMPLETE = 100
|
||||||
@ -16,12 +15,8 @@ data class DLProgressEvent(val bookProgress: Int,
|
|||||||
* Build a DLProgressEvent that is just beginning
|
* Build a DLProgressEvent that is just beginning
|
||||||
* Mostly just a nice shorthand
|
* Mostly just a nice shorthand
|
||||||
*/
|
*/
|
||||||
fun beginningEvent(b: Book) = DLProgressEvent(DLProgressEvent.PROGRESS_BEGINNING,
|
fun beginningEvent(b: Book) = DLProgressEvent(DLProgressEvent.PROGRESS_BEGINNING, b)
|
||||||
DLProgressEvent.PROGRESS_BEGINNING, b)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val averageProgress: Int
|
fun toCircular() = (progress.toFloat() * 360 / 100).toInt()
|
||||||
get() = (bookProgress + indexProgress) / 2
|
|
||||||
|
|
||||||
fun toCircular() = (averageProgress.toFloat() * 360 / 100).toInt()
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
package org.bspeice.minimalbible.activity.downloader.manager
|
||||||
|
|
||||||
|
import org.crosswire.jsword.index.IndexManager
|
||||||
|
import rx.subjects.PublishSubject
|
||||||
|
import org.crosswire.jsword.book.Book
|
||||||
|
import rx.Observable
|
||||||
|
import rx.schedulers.Schedulers
|
||||||
|
import android.util.Log
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There's already an IndexManager, that's why the funky name
|
||||||
|
*/
|
||||||
|
class MBIndexManager(val downloadEvents: PublishSubject<DLProgressEvent>,
|
||||||
|
val indexManager: IndexManager) {
|
||||||
|
|
||||||
|
val subscription = downloadEvents subscribe { handleDlEvent(it) }
|
||||||
|
|
||||||
|
fun handleDlEvent(event: DLProgressEvent): Unit =
|
||||||
|
if (event.progress == DLProgressEvent.PROGRESS_COMPLETE) {
|
||||||
|
subscription.unsubscribe()
|
||||||
|
buildIndex(event.b)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun buildIndex(b: Book) {
|
||||||
|
Observable.just(b)
|
||||||
|
.observeOn(Schedulers.computation())
|
||||||
|
.subscribe {
|
||||||
|
try {
|
||||||
|
Log.d("MBIndexManager", "Beginning index status: ${b.getIndexStatus()}")
|
||||||
|
indexManager scheduleIndexCreation b
|
||||||
|
Log.d("MBIndexManager", "Ending index status: ${b.getIndexStatus()}")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("MBIndexManager", "Exception building index: ${e}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.d("MBIndexManager", "Building index for ${b.getInitials()}")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeIndex(b: Book) = indexManager.deleteIndex(b)
|
||||||
|
}
|
@ -1,14 +1,36 @@
|
|||||||
package org.bspeice.minimalbible.activity.search
|
package org.bspeice.minimalbible.activity.search
|
||||||
|
|
||||||
import org.crosswire.jsword.passage.Verse
|
import org.crosswire.jsword.passage.Verse
|
||||||
|
import org.crosswire.jsword.index.search.SearchType
|
||||||
|
import org.crosswire.jsword.book.Book
|
||||||
|
import android.util.Log
|
||||||
|
import org.crosswire.jsword.index.IndexManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the entry point for handling the actual bible search. Likely will support
|
* This is the entry point for handling the actual bible search. Likely will support
|
||||||
* an "advanced" search in the future, but for now, basicTextSearch is what you get.
|
* an "advanced" search in the future, but for now, basicTextSearch is what you get.
|
||||||
*/
|
*/
|
||||||
class SearchProvider() {
|
class SearchProvider(val b: Book, val indexManager: IndexManager) {
|
||||||
|
|
||||||
|
val defaultSearchType = SearchType.ANY_WORDS
|
||||||
|
|
||||||
[suppress("UNUSED_PARAMETER")]
|
[suppress("UNUSED_PARAMETER")]
|
||||||
public fun basicTextSearch(text: String): List<Verse> =
|
public fun basicTextSearch(text: String): List<Verse> {
|
||||||
listOf()
|
if (!isSearchAvailable()) {
|
||||||
|
Log.w("SearchProvider", "Search unavailable, index status of ${b.getInitials()}: ${b.getIndexStatus()}")
|
||||||
|
return listOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
val searchText = defaultSearchType.decorate(text)
|
||||||
|
val results = b.find(searchText)
|
||||||
|
return results.map { it as Verse }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to check if the index is available - because it doesn't
|
||||||
|
* seem to register itself properly in the book metadata
|
||||||
|
*/
|
||||||
|
public fun isSearchAvailable(): Boolean =
|
||||||
|
indexManager.isIndexed(b)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user