]> git.ktnx.net Git - mobile-ledger.git/blobdiff - app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java
more pronounced day/month delimiters in the transaction list
[mobile-ledger.git] / app / src / main / java / net / ktnx / mobileledger / async / RetrieveTransactionsTask.java
index b004ec9a0f1a11e6077f3327c0425365a3b4e443..0b751b4c6d7df0c94174973ec7a2e449352c9dc9 100644 (file)
 package net.ktnx.mobileledger.async;
 
 import android.annotation.SuppressLint;
-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.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;
@@ -47,10 +42,8 @@ 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.NetworkUtil;
-import net.ktnx.mobileledger.utils.Profiler;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -72,8 +65,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 
-public class RetrieveTransactionsTask extends
-        AsyncTask<Void, RetrieveTransactionsTask.Progress, RetrieveTransactionsTask.Result> {
+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(
@@ -93,11 +85,9 @@ public class RetrieveTransactionsTask extends
             Pattern.compile("/register\\?q=inacct%3A([a-zA-Z0-9%]+)\"");
     private final Pattern reAccountValue = Pattern.compile(
             "<span class=\"[^\"]*\\bamount\\b[^\"]*\">\\s*([-+]?[\\d.,]+)(?:\\s+(\\S+))?</span>");
-    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) {
@@ -130,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<LedgerAccount> accounts,
                                                List<LedgerTransaction> transactions)
@@ -455,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;
@@ -482,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);
             }
 
         }
@@ -538,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()
@@ -554,7 +546,7 @@ public class RetrieveTransactionsTask extends
 
     @SuppressLint("DefaultLocale")
     @Override
-    protected Result doInBackground(Void... params) {
+    public void run() {
         Data.backgroundTaskStarted();
         List<LedgerAccount> accounts;
         List<LedgerTransaction> transactions;
@@ -575,112 +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<LedgerAccount> accounts,
-                                              List<LedgerTransaction> transactions) {
-        AccountDAO accDao = DB.get()
-                              .getAccountDAO();
-        TransactionDAO trDao = DB.get()
-                                 .getTransactionDAO();
-        TransactionAccountDAO trAccDao = DB.get()
-                                           .getTransactionAccountDAO();
-        AccountValueDAO valDao = DB.get()
-                                   .getAccountValueDAO();
-
-        Logger.debug(TAG, "Preparing account list");
-        final List<AccountWithAmounts> 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");
-
-        Profiler tranProfiler = new Profiler("transactions");
-        Profiler tranAccProfiler = new Profiler("transaction accounts");
-
-        Logger.debug(TAG, "Storing transactions");
-        long trGen = trDao.getGenerationSync(profile.getId());
-        for (LedgerTransaction tr : transactions) {
-            TransactionWithAccounts tran = tr.toDBO();
-            tran.transaction.setGeneration(trGen);
-            tran.transaction.setProfileId(profile.getId());
-
-            tranProfiler.opStart();
-            tran.transaction.setId(trDao.insertSync(tran.transaction));
-            tranProfiler.opEnd();
-
-            for (TransactionAccount trAcc : tran.accounts) {
-                trAcc.setGeneration(trGen);
-                trAcc.setTransactionId(tran.transaction.getId());
-                tranAccProfiler.opStart();
-                trAcc.setId(trAccDao.insertSync(trAcc));
-                tranAccProfiler.opEnd();
-            }
-        }
-
-        tranProfiler.dumpStats();
-        tranAccProfiler.dumpStats();
-
-        Logger.debug(TAG, "Transactions stored. Purging old");
-        trDao.purgeOldTransactionsSync(profile.getId(), trGen);
-        Logger.debug(TAG, "Old transactions purged");
-
-        DB.get()
-          .getOptionDAO()
-          .insertSync(new Option(profile.getId(), Option.OPT_LAST_SCRAPE,
-                  String.valueOf((new Date()).getTime())));
-    }
     public void throwIfCancelled() {
-        if (isCancelled())
+        if (isInterrupted())
             throw new OperationCanceledException(null);
     }
     private enum ParserState {
@@ -776,4 +703,55 @@ public class RetrieveTransactionsTask extends
             this.transactions = transactions;
         }
     }
+
+    private class AccountAndTransactionListSaver extends Thread {
+        private final List<LedgerAccount> accounts;
+        private final List<LedgerTransaction> transactions;
+        public AccountAndTransactionListSaver(List<LedgerAccount> accounts,
+                                              List<LedgerTransaction> 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<AccountWithAmounts> 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<TransactionWithAccounts> 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())));
+        }
+    }
 }