X-Git-Url: https://git.ktnx.net/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fnet%2Fktnx%2Fmobileledger%2Fasync%2FRetrieveTransactionsTask.java;h=0b751b4c6d7df0c94174973ec7a2e449352c9dc9;hb=HEAD;hp=88c3ee8300e1da0efe1020854b80429a70c84fdb;hpb=673119deb3dfcb78b6f6259213c8db34b7aa36c9;p=mobile-ledger.git diff --git a/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java b/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java index 88c3ee83..0b751b4c 100644 --- a/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java +++ b/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java @@ -18,27 +18,20 @@ package net.ktnx.mobileledger.async; import android.annotation.SuppressLint; -import android.database.sqlite.SQLiteDatabase; -import android.os.AsyncTask; import android.os.OperationCanceledException; import androidx.annotation.NonNull; -import androidx.room.Transaction; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.RuntimeJsonMappingException; -import net.ktnx.mobileledger.App; import net.ktnx.mobileledger.dao.AccountDAO; -import net.ktnx.mobileledger.dao.AccountValueDAO; -import net.ktnx.mobileledger.dao.TransactionAccountDAO; import net.ktnx.mobileledger.dao.TransactionDAO; import net.ktnx.mobileledger.db.Account; import net.ktnx.mobileledger.db.AccountWithAmounts; import net.ktnx.mobileledger.db.DB; import net.ktnx.mobileledger.db.Option; import net.ktnx.mobileledger.db.Profile; -import net.ktnx.mobileledger.db.TransactionAccount; import net.ktnx.mobileledger.db.TransactionWithAccounts; import net.ktnx.mobileledger.err.HTTPException; import net.ktnx.mobileledger.json.API; @@ -49,9 +42,7 @@ import net.ktnx.mobileledger.model.Data; import net.ktnx.mobileledger.model.LedgerAccount; import net.ktnx.mobileledger.model.LedgerTransaction; import net.ktnx.mobileledger.model.LedgerTransactionAccount; -import net.ktnx.mobileledger.ui.MainModel; import net.ktnx.mobileledger.utils.Logger; -import net.ktnx.mobileledger.utils.MLDB; import net.ktnx.mobileledger.utils.NetworkUtil; import java.io.BufferedReader; @@ -74,8 +65,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -public class RetrieveTransactionsTask extends - AsyncTask { +public class RetrieveTransactionsTask extends Thread { private static final int MATCHING_TRANSACTIONS_LIMIT = 150; private static final Pattern reComment = Pattern.compile("^\\s*;"); private static final Pattern reTransactionStart = Pattern.compile( @@ -89,16 +79,15 @@ public class RetrieveTransactionsTask extends private static final Pattern reEnd = Pattern.compile("\\bid=\"addmodal\""); private static final Pattern reDecimalPoint = Pattern.compile("\\.\\d\\d?$"); private static final Pattern reDecimalComma = Pattern.compile(",\\d\\d?$"); + private static final String TAG = "RTT"; // %3A is '=' private final Pattern reAccountName = Pattern.compile("/register\\?q=inacct%3A([a-zA-Z0-9%]+)\""); private final Pattern reAccountValue = Pattern.compile( "\\s*([-+]?[\\d.,]+)(?:\\s+(\\S+))?"); - private final MainModel mainModel; private final Profile profile; private int expectedPostingsCount = -1; - public RetrieveTransactionsTask(@NonNull MainModel mainModel, @NonNull Profile profile) { - this.mainModel = mainModel; + public RetrieveTransactionsTask(@NonNull Profile profile) { this.profile = profile; } private static void L(String msg) { @@ -131,25 +120,19 @@ public class RetrieveTransactionsTask extends return null; } } - @Override - protected void onProgressUpdate(Progress... values) { - super.onProgressUpdate(values); - Data.backgroundTaskProgress.postValue(values[0]); + private void publishProgress(Progress progress) { + Data.backgroundTaskProgress.postValue(progress); } - @Override - protected void onPostExecute(Result result) { - super.onPostExecute(result); + private void finish(Result result) { Progress progress = new Progress(); progress.setState(ProgressState.FINISHED); progress.setError(result.error); - onProgressUpdate(progress); + publishProgress(progress); } - @Override - protected void onCancelled() { - super.onCancelled(); + private void cancel() { Progress progress = new Progress(); progress.setState(ProgressState.FINISHED); - onProgressUpdate(progress); + publishProgress(progress); } private void retrieveTransactionListLegacy(List accounts, List transactions) @@ -437,7 +420,6 @@ public class RetrieveTransactionsTask extends throw new HTTPException(http.getResponseCode(), http.getResponseMessage()); } publishProgress(Progress.indeterminate()); - SQLiteDatabase db = App.getDatabase(); ArrayList list = new ArrayList<>(); HashMap map = new HashMap<>(); throwIfCancelled(); @@ -457,6 +439,10 @@ public class RetrieveTransactionsTask extends list.add(acc); } throwIfCancelled(); + + Logger.warn("accounts", + String.format(Locale.US, "Got %d accounts using protocol %s", list.size(), + version.getDescription())); } return list; @@ -484,9 +470,9 @@ public class RetrieveTransactionsTask extends return retrieveTransactionListForVersion(ver); } catch (Exception e) { - Logger.debug("json", - String.format(Locale.US, "Error during account list retrieval using API %s", - ver.getDescription())); + Logger.debug("json", String.format(Locale.US, + "Error during transaction list retrieval using API %s", + ver.getDescription()), e); } } @@ -540,9 +526,13 @@ public class RetrieveTransactionsTask extends } throwIfCancelled(); + + Logger.warn("transactions", + String.format(Locale.US, "Got %d transactions using protocol %s", trList.size(), + apiVersion.getDescription())); } - // json interface returns transactions if file order and the rest of the machinery + // json interface returns transactions in file order and the rest of the machinery // expects them in reverse chronological order Collections.sort(trList, (o1, o2) -> { int res = o2.getDate() @@ -556,7 +546,7 @@ public class RetrieveTransactionsTask extends @SuppressLint("DefaultLocale") @Override - protected Result doInBackground(Void... params) { + public void run() { Data.backgroundTaskStarted(); List accounts; List transactions; @@ -577,96 +567,47 @@ public class RetrieveTransactionsTask extends retrieveTransactionListLegacy(accounts, transactions); } - storeAccountsAndTransactions(accounts, transactions); + new AccountAndTransactionListSaver(accounts, transactions).start(); - mainModel.updateDisplayedTransactionsFromWeb(transactions); + Data.lastUpdateDate.postValue(new Date()); - return new Result(accounts, transactions); + finish(new Result(null)); } catch (MalformedURLException e) { e.printStackTrace(); - return new Result("Invalid server URL"); + finish(new Result("Invalid server URL")); } catch (HTTPException e) { e.printStackTrace(); - return new Result( - String.format("HTTP error %d: %s", e.getResponseCode(), e.getMessage())); + finish(new Result( + String.format("HTTP error %d: %s", e.getResponseCode(), e.getMessage()))); } catch (IOException e) { e.printStackTrace(); - return new Result(e.getLocalizedMessage()); + finish(new Result(e.getLocalizedMessage())); } catch (RuntimeJsonMappingException e) { e.printStackTrace(); - return new Result(Result.ERR_JSON_PARSER_ERROR); + finish(new Result(Result.ERR_JSON_PARSER_ERROR)); } catch (ParseException e) { e.printStackTrace(); - return new Result("Network error"); + finish(new Result("Network error")); } catch (OperationCanceledException e) { - e.printStackTrace(); - return new Result("Operation cancelled"); + Logger.debug("RTT", "Retrieval was cancelled", e); + finish(new Result(null)); } catch (ApiNotSupportedException e) { e.printStackTrace(); - return new Result("Server version not supported"); + finish(new Result("Server version not supported")); } finally { Data.backgroundTaskFinished(); } } - @Transaction - private void storeAccountsAndTransactions(List accounts, - List transactions) { - AccountDAO accDao = DB.get() - .getAccountDAO(); - TransactionDAO trDao = DB.get() - .getTransactionDAO(); - TransactionAccountDAO trAccDao = DB.get() - .getTransactionAccountDAO(); - AccountValueDAO valDao = DB.get() - .getAccountValueDAO(); - - final List list = new ArrayList<>(); - for (LedgerAccount acc : accounts) { - final AccountWithAmounts a = acc.toDBOWithAmounts(); - Account existing = accDao.getByNameSync(profile.getId(), acc.getName()); - if (existing != null) { - a.account.setExpanded(existing.isExpanded()); - a.account.setAmountsExpanded(existing.isAmountsExpanded()); - a.account.setId( - existing.getId()); // not strictly needed, but since we have it anyway... - } - - list.add(a); - } - accDao.storeAccountsSync(list, profile.getId()); - - long trGen = trDao.getGenerationSync(profile.getId()); - for (LedgerTransaction tr : transactions) { - TransactionWithAccounts tran = tr.toDBO(); - tran.transaction.setGeneration(trGen); - tran.transaction.setProfileId(profile.getId()); - - tran.transaction.setId(trDao.insertSync(tran.transaction)); - - for (TransactionAccount trAcc : tran.accounts) { - trAcc.setGeneration(trGen); - trAcc.setTransactionId(tran.transaction.getId()); - trAcc.setId(trAccDao.insertSync(trAcc)); - } - } - - trDao.purgeOldTransactionsSync(profile.getId(), trGen); - - DB.get() - .getOptionDAO() - .insertSync(new Option(profile.getId(), MLDB.OPT_LAST_SCRAPE, - String.valueOf((new Date()).getTime()))); - } public void throwIfCancelled() { - if (isCancelled()) + if (isInterrupted()) throw new OperationCanceledException(null); } private enum ParserState { @@ -762,4 +703,55 @@ public class RetrieveTransactionsTask extends this.transactions = transactions; } } + + private class AccountAndTransactionListSaver extends Thread { + private final List accounts; + private final List transactions; + public AccountAndTransactionListSaver(List accounts, + List transactions) { + this.accounts = accounts; + this.transactions = transactions; + } + @Override + public void run() { + AccountDAO accDao = DB.get() + .getAccountDAO(); + TransactionDAO trDao = DB.get() + .getTransactionDAO(); + + Logger.debug(TAG, "Preparing account list"); + final List list = new ArrayList<>(); + for (LedgerAccount acc : accounts) { + final AccountWithAmounts a = acc.toDBOWithAmounts(); + Account existing = accDao.getByNameSync(profile.getId(), acc.getName()); + if (existing != null) { + a.account.setExpanded(existing.isExpanded()); + a.account.setAmountsExpanded(existing.isAmountsExpanded()); + a.account.setId(existing.getId()); // not strictly needed, but since we have it + // anyway... + } + + list.add(a); + } + Logger.debug(TAG, "Account list prepared. Storing"); + accDao.storeAccountsSync(list, profile.getId()); + Logger.debug(TAG, "Account list stored"); + + Logger.debug(TAG, "Preparing transaction list"); + final List tranList = new ArrayList<>(); + + for (LedgerTransaction tr : transactions) + tranList.add(tr.toDBO()); + + Logger.debug(TAG, "Storing transaction list"); + trDao.storeTransactionsSync(tranList, profile.getId()); + + Logger.debug(TAG, "Transactions stored"); + + DB.get() + .getOptionDAO() + .insertSync(new Option(profile.getId(), Option.OPT_LAST_SCRAPE, + String.valueOf((new Date()).getTime()))); + } + } }