mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-05 10:49:24 +02:00
more experiments with SynchroniserService
This commit is contained in:
parent
7d840b81af
commit
ce4ab7866c
5 changed files with 124 additions and 26 deletions
|
@ -345,7 +345,7 @@ public class ApiServerImplementation extends ApiInterface.Stub implements Api, A
|
|||
}
|
||||
|
||||
public String getBookHash() {
|
||||
final UID uid = BookUtil.createSHA256Uid(getReader().Model.Book.File);
|
||||
final UID uid = BookUtil.createUid(getReader().Model.Book.File, "SHA-256");
|
||||
return uid != null ? uid.Id : null;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,33 +19,63 @@
|
|||
|
||||
package org.geometerplus.android.fbreader.synchroniser;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
import org.geometerplus.zlibrary.core.network.*;
|
||||
import org.geometerplus.fbreader.book.*;
|
||||
import org.geometerplus.android.fbreader.libraryService.BookCollectionShadow;
|
||||
|
||||
public class SynchroniserService extends Service implements Runnable {
|
||||
public class SynchroniserService extends Service implements IBookCollection.Listener, Runnable {
|
||||
private final BookCollectionShadow myCollection = new BookCollectionShadow();
|
||||
private volatile Thread mySynchronizationThread;
|
||||
|
||||
private final List<Book> myQueue = Collections.synchronizedList(new LinkedList<Book>());
|
||||
private final Set<Book> myProcessed = new HashSet<Book>();
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
myCollection.bindToService(this, this);
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addBook(Book book) {
|
||||
if (!myProcessed.contains(book) && book.File.getPhysicalFile() != null) {
|
||||
myQueue.add(book);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public synchronized void run() {
|
||||
System.err.println("SYNCHRONIZER BINDED TO LIBRARY");
|
||||
synchronized(this) {
|
||||
myCollection.addListener(this);
|
||||
if (mySynchronizationThread == null) {
|
||||
mySynchronizationThread = new Thread() {
|
||||
public void run() {
|
||||
System.err.println("HELLO THREAD");
|
||||
try {
|
||||
mySynchronizationThread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
for (BookQuery q = new BookQuery(new Filter.Empty(), 20);; q = q.next()) {
|
||||
final List<Book> books = myCollection.books(q);
|
||||
if (books.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
for (Book b : books) {
|
||||
addBook(b);
|
||||
}
|
||||
}
|
||||
while (!myQueue.isEmpty()) {
|
||||
final Book book = myQueue.remove(0);
|
||||
if (myProcessed.contains(book)) {
|
||||
continue;
|
||||
}
|
||||
myProcessed.add(book);
|
||||
System.err.println("Processing " + book.getTitle() + " [" + book.File.getPath() + "]");
|
||||
uploadBookToServer(book);
|
||||
}
|
||||
System.err.println("BYE-BYE THREAD");
|
||||
mySynchronizationThread = null;
|
||||
|
@ -55,12 +85,80 @@ public class SynchroniserService extends Service implements Runnable {
|
|||
mySynchronizationThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
private static String toJSON(Object object) {
|
||||
final StringWriter writer = new StringWriter();
|
||||
try {
|
||||
JSONValue.writeJSONString(object, writer);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("JSON serialization failed", e);
|
||||
}
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
private static abstract class Request extends ZLNetworkRequest {
|
||||
private final static String BASE_URL = "https://books.fbreader.org/app/";
|
||||
|
||||
Request(String app, Object data) {
|
||||
super(BASE_URL + app, toJSON(data), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleStream(InputStream stream, int length) throws IOException, ZLNetworkException {
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
buffer.append(line);
|
||||
}
|
||||
processResponse(JSONValue.parse(buffer.toString()));
|
||||
}
|
||||
|
||||
final void perform() {
|
||||
try {
|
||||
ZLNetworkManager.Instance().perform(this);
|
||||
} catch (ZLNetworkException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void processResponse(Object response);
|
||||
}
|
||||
|
||||
private void uploadBookToServer(Book book) {
|
||||
final UID uid = BookUtil.createUid(book.File.getPhysicalFile(), "SHA-1");
|
||||
if (uid == null) {
|
||||
System.err.println("Failed: SHA-1 checksum not computed");
|
||||
return;
|
||||
}
|
||||
System.err.println("SHA-1: " + uid.Id);
|
||||
new Request("books.by.hash", Collections.singletonMap("sha1", uid.Id)) {
|
||||
public void processResponse(Object response) {
|
||||
System.err.println("RESPONSE = " + response);
|
||||
}
|
||||
}.perform();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
myCollection.removeListener(this);
|
||||
myCollection.unbind();
|
||||
System.err.println("SYNCHRONIZER UNBINDED FROM LIBRARY");
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBookEvent(BookEvent event, Book book) {
|
||||
switch (event) {
|
||||
default:
|
||||
break;
|
||||
case Added:
|
||||
addBook(book);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBuildEvent(IBookCollection.Status status) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,11 +78,11 @@ public abstract class BookUtil {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static UID createSHA256Uid(ZLFile file) {
|
||||
public static UID createUid(ZLFile file, String algorithm) {
|
||||
InputStream stream = null;
|
||||
|
||||
try {
|
||||
final MessageDigest hash = MessageDigest.getInstance("SHA-256");
|
||||
final MessageDigest hash = MessageDigest.getInstance(algorithm);
|
||||
stream = file.getInputStream();
|
||||
|
||||
final byte[] buffer = new byte[2048];
|
||||
|
@ -98,7 +98,7 @@ public abstract class BookUtil {
|
|||
for (byte b : hash.digest()) {
|
||||
f.format("%02X", b & 0xFF);
|
||||
}
|
||||
return new UID("SHA-256", f.toString());
|
||||
return new UID(algorithm, f.toString());
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
|
|
|
@ -78,7 +78,7 @@ public class NativeFormatPlugin extends FormatPlugin {
|
|||
synchronized public void readUids(Book book) throws BookReadingException {
|
||||
readUidsNative(book);
|
||||
if (book.uids().isEmpty()) {
|
||||
book.addUid(BookUtil.createSHA256Uid(book.File));
|
||||
book.addUid(BookUtil.createUid(book.File, "SHA-256"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ public class MobipocketPlugin extends JavaFormatPlugin {
|
|||
@Override
|
||||
public void readUids(Book book) throws BookReadingException {
|
||||
if (book.uids().isEmpty()) {
|
||||
book.addUid(BookUtil.createSHA256Uid(book.File));
|
||||
book.addUid(BookUtil.createUid(book.File, "SHA-256"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue