From 55d238b6872f73e013ff9ca46a4920ae23943bc7 Mon Sep 17 00:00:00 2001 From: Nikolay Pultsin Date: Sun, 2 Oct 2011 15:12:40 +0100 Subject: [PATCH] book purchasing (in progress) --- TODO.litres | 2 - assets/resources/application/en.xml | 22 +- .../fbreader/network/BuyBooksActivity.java | 244 +++++++++++------- .../NetworkAuthenticationManager.java | 1 + .../litres/LitResAuthenticationManager.java | 51 ++-- 5 files changed, 190 insertions(+), 130 deletions(-) diff --git a/TODO.litres b/TODO.litres index 9dd59db4d..44ed4c8d4 100644 --- a/TODO.litres +++ b/TODO.litres @@ -1,6 +1,4 @@ -buy book after topup buy book after registration -buy several books buy book after auto-sign-in auto-sign-in do we cache cover images? diff --git a/assets/resources/application/en.xml b/assets/resources/application/en.xml index c7d737197..56b18d081 100644 --- a/assets/resources/application/en.xml +++ b/assets/resources/application/en.xml @@ -129,6 +129,15 @@ + + + + + + + + + @@ -243,6 +252,8 @@ + + @@ -626,6 +637,7 @@ + @@ -665,16 +677,6 @@ - - - - - - - - - - diff --git a/src/org/geometerplus/android/fbreader/network/BuyBooksActivity.java b/src/org/geometerplus/android/fbreader/network/BuyBooksActivity.java index 94b68640e..7e85c289a 100644 --- a/src/org/geometerplus/android/fbreader/network/BuyBooksActivity.java +++ b/src/org/geometerplus/android/fbreader/network/BuyBooksActivity.java @@ -60,13 +60,19 @@ public class BuyBooksActivity extends Activity { activity.startActivity(intent); } + private NetworkLibrary myLibrary; + private INetworkLink myLink; + private List myBooks; + private Money myCost; + private Money myAccount; + @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); Thread.setDefaultUncaughtExceptionHandler(new org.geometerplus.zlibrary.ui.android.library.UncaughtExceptionHandler(this)); setContentView(R.layout.buy_book); - final NetworkLibrary library = NetworkLibrary.Instance(); + myLibrary = NetworkLibrary.Instance(); final List keys = (List)getIntent().getSerializableExtra( @@ -76,25 +82,43 @@ public class BuyBooksActivity extends Activity { finish(); return; } - final List books = new ArrayList(keys.size()); + myBooks = new ArrayList(keys.size()); for (NetworkTree.Key k : keys) { - final NetworkTree tree = library.getTreeByKey(k); + final NetworkTree tree = myLibrary.getTreeByKey(k); if (tree instanceof NetworkBookTree) { - books.add(((NetworkBookTree)tree).Book); + myBooks.add(((NetworkBookTree)tree).Book); } else { finish(); return; } } + myCost = Money.ZERO; + for (NetworkBookItem b : myBooks) { + if (b.getStatus() != NetworkBookItem.Status.CanBePurchased) { + continue; + } + final BookBuyUrlInfo info = b.buyInfo(); + if (info == null || info.Price == null) { + // TODO: error message + finish(); + return; + } + myCost = myCost.add(info.Price); + } // we assume all the books are from the same catalog - final INetworkLink link = books.get(0).Link; - final NetworkAuthenticationManager mgr = link.authenticationManager(); + myLink = myBooks.get(0).Link; + final NetworkAuthenticationManager mgr = myLink.authenticationManager(); if (mgr == null) { finish(); return; } + myAccount = mgr.currentAccount(); + setupUI(); + } + + private void setupUI() { final ZLResource dialogResource = ZLResource.resource("dialog"); final ZLResource buttonResource = dialogResource.getResource("button"); @@ -104,39 +128,117 @@ public class BuyBooksActivity extends Activity { final Button cancelButton = (Button)findViewById(R.id.buy_book_buttons).findViewById(R.id.cancel_button); - final Runnable buyRunnable = new Runnable() { - public void run() { - Money cost = Money.ZERO; - System.err.println("cost = " + cost); - try { - final Money account = mgr.currentAccount(); - System.err.println("account = " + account); - if (account != null) { - for (NetworkBookItem b : books) { - final BookBuyUrlInfo info = b.buyInfo(); - if (b.getStatus() != NetworkBookItem.Status.CanBePurchased) { - continue; - } - if (info == null || info.Price == null) { - cost = null; - break; - } - cost = cost.add(info.Price); - System.err.println("cost = " + cost); + final ZLResource resource = ZLResource.resource("buyBook"); + if (myBooks.size() > 1) { + setTitle(resource.getResource("titleSeveralBooks").getValue()); + } else { + setTitle(resource.getResource("title").getValue()); + } + + if (myAccount == null) { + textArea.setText(resource.getResource("noAccountInformation").getValue()); + okButton.setText(buttonResource.getResource("refresh").getValue()); + cancelButton.setText(buttonResource.getResource("cancel").getValue()); + okButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + refreshAccountInformation(); + } + }); + cancelButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + finish(); + } + }); + } else if (myCost.compareTo(myAccount) > 0) { + textArea.setText( + resource.getResource("unsufficientFunds").getValue() + .replace("%0", myCost.toString()) + .replace("%1", myAccount.toString()) + ); + okButton.setText(buttonResource.getResource("pay").getValue()); + cancelButton.setText(buttonResource.getResource("refresh").getValue()); + okButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + TopupMenuActivity.runMenu(BuyBooksActivity.this, myLink, myCost.subtract(myAccount)); + } + }); + cancelButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + refreshAccountInformation(); + } + }); + } else { + okButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + UIUtil.wait("purchaseBook", buyRunnable(), BuyBooksActivity.this); + } + }); + cancelButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + finish(); + } + }); + if (myBooks.size() > 1) { + textArea.setText( + resource.getResource("confirmSeveralBooks").getValue() + .replace("%s", String.valueOf(myBooks.size())) + ); + okButton.setText(buttonResource.getResource("buy").getValue()); + cancelButton.setText(buttonResource.getResource("cancel").getValue()); + } else if (myBooks.get(0).getStatus() == NetworkBookItem.Status.CanBePurchased) { + textArea.setText( + resource.getResource("confirm").getValue().replace("%s", myBooks.get(0).Title) + ); + okButton.setText(buttonResource.getResource("buy").getValue()); + cancelButton.setText(buttonResource.getResource("cancel").getValue()); + } else { + textArea.setText(resource.getResource("alreadyBought").getValue()); + cancelButton.setText(buttonResource.getResource("ok").getValue()); + okButton.setVisibility(View.GONE); + } + } + } + + @Override + protected void onResume() { + super.onResume(); + refreshAccountInformation(); + } + + private void refreshAccountInformation() { + UIUtil.wait( + "updatingAccountInformation", + new Runnable() { + public void run() { + final NetworkAuthenticationManager mgr = myLink.authenticationManager(); + try { + mgr.refreshAccountInformation(); + final Money oldAccount = myAccount; + myAccount = mgr.currentAccount(); + if (myAccount != null && !myAccount.equals(oldAccount)) { + runOnUiThread(new Runnable() { + public void run() { + setupUI(); + } + }); } - cost = cost.subtract(account); - System.err.println("cost = " + cost); - } else { - cost = null; + myLibrary.invalidateVisibility(); + myLibrary.synchronize(); + } catch (ZLNetworkException e) { + // ignore } - System.err.println("cost = " + cost); - if (cost != null && cost.compareTo(Money.ZERO) > 0 && books.size() > 1) { - // we only throw this exception if there are more than 1 book in list - // for 1 book we prefer to send request to server and got an error - throw new ZLNetworkException(NetworkException.ERROR_PURCHASE_NOT_ENOUGH_MONEY); - } - - for (final NetworkBookItem b : books) { + } + }, + this + ); + } + + private Runnable buyRunnable() { + return new Runnable() { + public void run() { + try { + final NetworkAuthenticationManager mgr = myLink.authenticationManager(); + for (final NetworkBookItem b : myBooks) { if (b.getStatus() != NetworkBookItem.Status.CanBePurchased) { continue; } @@ -149,62 +251,24 @@ public class BuyBooksActivity extends Activity { } finish(); } catch (final ZLNetworkException e) { - if (NetworkException.ERROR_PURCHASE_NOT_ENOUGH_MONEY.equals(e.getCode())) { - TopupMenuActivity.runMenu(BuyBooksActivity.this, link, cost); - finish(); - } else { - final ZLResource boxResource = dialogResource.getResource("networkError"); - runOnUiThread(new Runnable() { - public void run() { - new AlertDialog.Builder(BuyBooksActivity.this) - .setTitle(boxResource.getResource("title").getValue()) - .setMessage(e.getMessage()) - .setIcon(0) - .setPositiveButton(buttonResource.getResource("ok").getValue(), null) - .create().show(); - } - }); - } + final ZLResource dialogResource = ZLResource.resource("dialog"); + final ZLResource buttonResource = dialogResource.getResource("button"); + final ZLResource boxResource = dialogResource.getResource("networkError"); + runOnUiThread(new Runnable() { + public void run() { + new AlertDialog.Builder(BuyBooksActivity.this) + .setTitle(boxResource.getResource("title").getValue()) + .setMessage(e.getMessage()) + .setIcon(0) + .setPositiveButton(buttonResource.getResource("ok").getValue(), null) + .create().show(); + } + }); } finally { - library.invalidateVisibility(); - library.synchronize(); + myLibrary.invalidateVisibility(); + myLibrary.synchronize(); } } }; - - okButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - UIUtil.wait("purchaseBook", buyRunnable, BuyBooksActivity.this); - } - }); - cancelButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - finish(); - } - }); - - if (books.size() > 1 || books.get(0).getStatus() == NetworkBookItem.Status.CanBePurchased) { - final ZLResource boxResource = dialogResource.getResource("purchaseConfirmBox"); - if (books.size() == 1) { - setTitle(boxResource.getResource("title").getValue()); - textArea.setText( - boxResource.getResource("message").getValue().replace("%s", books.get(0).Title) - ); - } else { - setTitle(boxResource.getResource("titleSeveralBooks").getValue()); - textArea.setText( - boxResource.getResource("messageSeveralBooks").getValue() - .replace("%s", String.valueOf(books.size())) - ); - } - okButton.setText(buttonResource.getResource("buy").getValue()); - cancelButton.setText(buttonResource.getResource("cancel").getValue()); - } else { - final ZLResource boxResource = dialogResource.getResource("alreadyPurchasedBox"); - setTitle(boxResource.getResource("title").getValue()); - textArea.setText(boxResource.getResource("message").getValue()); - cancelButton.setText(buttonResource.getResource("ok").getValue()); - okButton.setVisibility(View.GONE); - } } } diff --git a/src/org/geometerplus/fbreader/network/authentication/NetworkAuthenticationManager.java b/src/org/geometerplus/fbreader/network/authentication/NetworkAuthenticationManager.java index cafb1d81e..fea825cbc 100644 --- a/src/org/geometerplus/fbreader/network/authentication/NetworkAuthenticationManager.java +++ b/src/org/geometerplus/fbreader/network/authentication/NetworkAuthenticationManager.java @@ -62,6 +62,7 @@ public abstract class NetworkAuthenticationManager { public abstract void authorise(String password) throws ZLNetworkException; public abstract void logOut(); public abstract BookUrlInfo downloadReference(NetworkBookItem book); + public abstract void refreshAccountInformation() throws ZLNetworkException; public final boolean mayBeAuthorised(boolean useNetwork) { try { diff --git a/src/org/geometerplus/fbreader/network/authentication/litres/LitResAuthenticationManager.java b/src/org/geometerplus/fbreader/network/authentication/litres/LitResAuthenticationManager.java index fbd38ef4a..6d927381d 100644 --- a/src/org/geometerplus/fbreader/network/authentication/litres/LitResAuthenticationManager.java +++ b/src/org/geometerplus/fbreader/network/authentication/litres/LitResAuthenticationManager.java @@ -267,7 +267,7 @@ public class LitResAuthenticationManager extends NetworkAuthenticationManager { logOut(false); throw new ZLNetworkException(NetworkException.ERROR_AUTHENTICATION_FAILED); } - networkRequest = loadPurchasedBooks(); + networkRequest = loadPurchasedBooksRequest(); } ZLNetworkException exception = null; @@ -279,7 +279,6 @@ public class LitResAuthenticationManager extends NetworkAuthenticationManager { synchronized (this) { if (exception != null) { - //loadPurchasedBooksOnError(); if (NetworkException.ERROR_AUTHENTICATION_FAILED.equals(exception.getCode())) { logOut(false); } @@ -317,35 +316,41 @@ public class LitResAuthenticationManager extends NetworkAuthenticationManager { return; } - purchasedBooksRequest = loadPurchasedBooks(); - accountRequest = loadAccount(); + purchasedBooksRequest = loadPurchasedBooksRequest(); + accountRequest = loadAccountRequest(); } final LinkedList requests = new LinkedList(); requests.add(purchasedBooksRequest); requests.add(accountRequest); - ZLNetworkException exception = null; try { ZLNetworkManager.Instance().perform(requests); + synchronized (this) { + myInitializedDataSid = sid; + loadPurchasedBooksOnSuccess(purchasedBooksRequest); + myAccount = new Money(((LitResPurchaseXMLReader)accountRequest.Reader).Account, "RUB"); + } } catch (ZLNetworkException e) { - exception = e; - } - - synchronized (this) { - if (exception != null) { + synchronized (this) { myInitializedDataSid = null; loadPurchasedBooksOnError(); - loadAccountOnError(); - throw exception; + myAccount = null; } - myInitializedDataSid = sid; - loadPurchasedBooksOnSuccess(purchasedBooksRequest); - loadAccountOnSuccess(accountRequest); + throw e; } } - private LitResNetworkRequest loadPurchasedBooks() { + @Override + public void refreshAccountInformation() throws ZLNetworkException { + final LitResNetworkRequest accountRequest = loadAccountRequest(); + ZLNetworkManager.Instance().perform(accountRequest); + synchronized (this) { + myAccount = new Money(((LitResPurchaseXMLReader)accountRequest.Reader).Account, "RUB"); + } + } + + private LitResNetworkRequest loadPurchasedBooksRequest() { final String sid = mySidOption.getValue(); final String query = "pages/catalit_browser/"; @@ -376,28 +381,18 @@ public class LitResAuthenticationManager extends NetworkAuthenticationManager { } } - private LitResNetworkRequest loadAccount() { - final String sid = mySidOption.getValue(); + private LitResNetworkRequest loadAccountRequest() { final String query = "pages/purchase_book/"; final LitResNetworkRequest request = new LitResNetworkRequest( LitResUtil.url(Link, query), new LitResPurchaseXMLReader(Link.getSiteName()) ); - request.addPostParameter("sid", sid); + request.addPostParameter("sid", mySidOption.getValue()); request.addPostParameter("art", "0"); return request; } - private void loadAccountOnError() { - myAccount = null; - } - - private void loadAccountOnSuccess(LitResNetworkRequest accountRequest) { - LitResPurchaseXMLReader reader = (LitResPurchaseXMLReader)accountRequest.Reader; - myAccount = new Money(reader.Account, "RUB"); - } - @Override public boolean passwordRecoverySupported() { return true;