diff --git a/src/org/geometerplus/android/fbreader/libraryService/BookCollectionShadow.java b/src/org/geometerplus/android/fbreader/libraryService/BookCollectionShadow.java index 624005972..7df00b873 100644 --- a/src/org/geometerplus/android/fbreader/libraryService/BookCollectionShadow.java +++ b/src/org/geometerplus/android/fbreader/libraryService/BookCollectionShadow.java @@ -322,6 +322,17 @@ public class BookCollectionShadow extends AbstractBookCollection implements Serv return Collections.emptyList(); } + public String getHash(Book book) { + if (myInterface == null) { + return null; + } + try { + return myInterface.getHash(SerializerUtil.serialize(book)); + } catch (RemoteException e) { + return null; + } + } + public synchronized ZLTextPosition getStoredPosition(long bookId) { if (myInterface == null) { return null; diff --git a/src/org/geometerplus/android/fbreader/libraryService/LibraryInterface.aidl b/src/org/geometerplus/android/fbreader/libraryService/LibraryInterface.aidl index b3b99fb78..c8907fe23 100644 --- a/src/org/geometerplus/android/fbreader/libraryService/LibraryInterface.aidl +++ b/src/org/geometerplus/android/fbreader/libraryService/LibraryInterface.aidl @@ -52,4 +52,6 @@ interface LibraryInterface { void saveHighlightingStyle(in String style); void rescan(in String path); + + String getHash(in String book); } diff --git a/src/org/geometerplus/android/fbreader/libraryService/LibraryService.java b/src/org/geometerplus/android/fbreader/libraryService/LibraryService.java index fb3878699..b2e8052c4 100644 --- a/src/org/geometerplus/android/fbreader/libraryService/LibraryService.java +++ b/src/org/geometerplus/android/fbreader/libraryService/LibraryService.java @@ -320,6 +320,10 @@ public class LibraryService extends Service { public void rescan(String path) { myCollection.rescan(path); } + + public String getHash(String book) { + return myCollection.getHash(SerializerUtil.deserializeBook(book)); + } } private volatile LibraryImplementation myLibrary; diff --git a/src/org/geometerplus/android/fbreader/libraryService/SQLiteBooksDatabase.java b/src/org/geometerplus/android/fbreader/libraryService/SQLiteBooksDatabase.java index 8a9d4939f..7380ce6aa 100644 --- a/src/org/geometerplus/android/fbreader/libraryService/SQLiteBooksDatabase.java +++ b/src/org/geometerplus/android/fbreader/libraryService/SQLiteBooksDatabase.java @@ -23,8 +23,7 @@ import java.util.*; import java.math.BigDecimal; import android.content.Context; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteStatement; +import android.database.sqlite.*; import android.database.SQLException; import android.database.Cursor; @@ -975,14 +974,29 @@ final class SQLiteBooksDatabase extends BooksDatabase { return progress; } - //@Override - String getHash(long bookId, long lastModified) { + @Override + protected String getHash(long bookId, long lastModified) { final SQLiteStatement statement = get( - "SELECT hash FROM BookHash WHERE bookId=? AND timestamp>?" + "SELECT hash FROM BookHash WHERE book_id=? AND timestamp>?" ); statement.bindLong(1, bookId); statement.bindLong(2, lastModified); - return statement.simpleQueryForString(); + try { + return statement.simpleQueryForString(); + } catch (SQLiteDoneException e) { + return null; + } + } + + @Override + protected void setHash(long bookId, String hash) { + final SQLiteStatement statement = get( + "INSERT OR REPLACE INTO BookHash (book_id,timestamp,hash) VALUES (?,?,?)" + ); + statement.bindLong(1, bookId); + statement.bindLong(2, System.currentTimeMillis()); + statement.bindString(3, hash); + statement.executeInsert(); } @Override diff --git a/src/org/geometerplus/android/fbreader/synchroniser/SynchroniserService.java b/src/org/geometerplus/android/fbreader/synchroniser/SynchroniserService.java index 59b6e2f44..1e18f80fe 100644 --- a/src/org/geometerplus/android/fbreader/synchroniser/SynchroniserService.java +++ b/src/org/geometerplus/android/fbreader/synchroniser/SynchroniserService.java @@ -97,7 +97,7 @@ public class SynchroniserService extends Service implements IBookCollection.List } myProcessed.add(book); System.err.println("Processing " + book.getTitle() + " [" + book.File.getPath() + "]"); - uploadBookToServer(book.File.getPhysicalFile()); + uploadBookToServer(book); } } finally { System.err.println("BYE-BYE THREAD"); @@ -164,19 +164,23 @@ public class SynchroniserService extends Service implements IBookCollection.List } } - private void uploadBookToServer(ZLPhysicalFile file) { - final UID uid = BookUtil.createUid(file, "SHA-1"); - if (uid == null) { - System.err.println("Failed: SHA-1 checksum not computed"); + private void uploadBookToServer(Book book) { + final ZLPhysicalFile file = book.File.getPhysicalFile(); + if (file == null) { return; } - if (myHashesFromServer.contains(uid.Id.toLowerCase())) { + final String hash = myCollection.getHash(book); + if (hash == null) { + System.err.println("Failed: checksum not computed"); + return; + } + if (myHashesFromServer.contains(hash)) { System.err.println("HASH ALREADY IN THE TABLE"); return; } final Map result = new HashMap(); final PostRequest verificationRequest = - new PostRequest("books.by.hash", Collections.singletonMap("sha1", uid.Id)) { + new PostRequest("books.by.hash", Collections.singletonMap("sha1", hash)) { @Override public void processResponse(Object response) { result.put("result", response); diff --git a/src/org/geometerplus/fbreader/book/BookCollection.java b/src/org/geometerplus/fbreader/book/BookCollection.java index c279748e0..f1dd14e8a 100644 --- a/src/org/geometerplus/fbreader/book/BookCollection.java +++ b/src/org/geometerplus/fbreader/book/BookCollection.java @@ -711,4 +711,22 @@ public class BookCollection extends AbstractBookCollection { myDatabase.saveStyle(style); fireBookEvent(BookEvent.BookmarkStyleChanged, null); } + + public String getHash(Book book) { + final ZLPhysicalFile file = book.File.getPhysicalFile(); + if (file == null) { + return null; + } + String hash = myDatabase.getHash(book.getId(), file.javaFile().lastModified()); + System.err.println("HASH FOR " + book + " FROM DB = " + hash); + if (hash == null) { + final UID uid = BookUtil.createUid(file, "SHA-1"); + if (uid == null) { + return null; + } + hash = uid.Id.toLowerCase(); + myDatabase.setHash(book.getId(), hash); + } + return hash; + } } diff --git a/src/org/geometerplus/fbreader/book/BooksDatabase.java b/src/org/geometerplus/fbreader/book/BooksDatabase.java index 2d9b1a3ec..eadcde2b3 100644 --- a/src/org/geometerplus/fbreader/book/BooksDatabase.java +++ b/src/org/geometerplus/fbreader/book/BooksDatabase.java @@ -126,4 +126,7 @@ public abstract class BooksDatabase { protected abstract Collection loadVisitedHyperlinks(long bookId); protected abstract void addVisitedHyperlink(long bookId, String hyperlinkId); + + protected abstract String getHash(long bookId, long lastModified); + protected abstract void setHash(long bookId, String hash); } diff --git a/src/org/geometerplus/fbreader/book/IBookCollection.java b/src/org/geometerplus/fbreader/book/IBookCollection.java index 810b85bfb..a1bcb4f96 100644 --- a/src/org/geometerplus/fbreader/book/IBookCollection.java +++ b/src/org/geometerplus/fbreader/book/IBookCollection.java @@ -73,6 +73,8 @@ public interface IBookCollection { boolean saveBook(Book book); void removeBook(Book book, boolean deleteFromDisk); + String getHash(Book book); + ZLTextPosition getStoredPosition(long bookId); void storePosition(long bookId, ZLTextPosition position);