package net.ktnx.mobileledger.async;
import android.annotation.SuppressLint;
-import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.OperationCanceledException;
import net.ktnx.mobileledger.model.LedgerAccount;
import net.ktnx.mobileledger.model.LedgerTransaction;
import net.ktnx.mobileledger.model.LedgerTransactionAccount;
+import net.ktnx.mobileledger.model.MobileLedgerProfile;
import net.ktnx.mobileledger.ui.activity.MainActivity;
import net.ktnx.mobileledger.utils.MLDB;
import net.ktnx.mobileledger.utils.NetworkUtil;
import java.util.regex.Pattern;
-public class RetrieveTransactionsTask extends
- AsyncTask<RetrieveTransactionsTask.Params, RetrieveTransactionsTask.Progress, Void> {
+public class RetrieveTransactionsTask
+ extends AsyncTask<Void, RetrieveTransactionsTask.Progress, Void> {
public static final int MATCHING_TRANSACTIONS_LIMIT = 50;
private static final Pattern transactionStartPattern = Pattern.compile("<tr class=\"title\" " +
- "id=\"transaction-(\\d+)\"><td class=\"date\"[^\\\"]*>([\\d.-]+)</td>");
+ "id=\"transaction-(\\d+)\"><td class=\"date\"[^\"]*>([\\d.-]+)</td>");
private static final Pattern transactionDescriptionPattern =
Pattern.compile("<tr class=\"posting\" title=\"(\\S+)\\s(.+)");
private static final Pattern transactionDetailsPattern =
private static final Pattern endPattern = Pattern.compile("\\bid=\"addmodal\"");
protected WeakReference<MainActivity> contextRef;
protected int error;
- // %3A is '='
- private Pattern ledger_title_re = Pattern.compile("<h1>([^<]+)</h1>");
Pattern account_name_re = Pattern.compile("/register\\?q=inacct%3A([a-zA-Z0-9%]+)\"");
Pattern account_value_re = Pattern.compile(
"<span class=\"[^\"]*\\bamount\\b[^\"]*\">\\s*([-+]?[\\d.,]+)(?:\\s+(\\S+))?</span>");
Pattern tr_end_re = Pattern.compile("</tr>");
Pattern descriptions_line_re = Pattern.compile("\\bdescriptionsSuggester\\s*=\\s*new\\b");
Pattern description_items_re = Pattern.compile("\"value\":\"([^\"]+)\"");
+ // %3A is '='
private boolean success;
public RetrieveTransactionsTask(WeakReference<MainActivity> contextRef) {
this.contextRef = contextRef;
}
@SuppressLint("DefaultLocale")
@Override
- protected Void doInBackground(Params... params) {
+ protected Void doInBackground(Void... params) {
+ MobileLedgerProfile profile = Data.profile.get();
Progress progress = new Progress();
int maxTransactionId = Progress.INDETERMINATE;
success = false;
LedgerAccount lastAccount = null;
Data.backgroundTaskCount.incrementAndGet();
try {
- HttpURLConnection http =
- NetworkUtil.prepare_connection(params[0].getBackendPref(), "journal");
+ HttpURLConnection http = NetworkUtil.prepare_connection("journal");
http.setAllowUserInteraction(false);
publishProgress(progress);
MainActivity ctx = getContext();
state = ParserState.EXPECTING_ACCOUNT_AMOUNT;
L("→ expecting account amount");
}
- else if (ledgerTitle == null) {
- m = ledger_title_re.matcher(line);
- if (m.find()) {
- ledgerTitle = m.group(1);
- Data.ledgerTitle.set(ledgerTitle);
- }
- }
break;
case EXPECTING_ACCOUNT_AMOUNT:
EXPECTING_TRANSACTION_DESCRIPTION, EXPECTING_TRANSACTION_DETAILS
}
- public static class Params {
- private SharedPreferences backendPref;
-
- public Params(SharedPreferences backendPref) {
- this.backendPref = backendPref;
- }
- SharedPreferences getBackendPref() {
- return backendPref;
- }
- }
-
public class Progress {
public static final int INDETERMINATE = -1;
private int progress;
/*
- * Copyright © 2018 Damyan Ivanov.
+ * Copyright © 2019 Damyan Ivanov.
* This file is part of Mobile-Ledger.
* Mobile-Ledger is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
task_callback = callback;
}
private boolean send_ok() throws IOException {
- HttpURLConnection http = NetworkUtil.prepare_connection(pref, "add");
+ HttpURLConnection http = NetworkUtil.prepare_connection("add");
http.setRequestMethod("POST");
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
http.setRequestProperty("Accept", "*/*");
public static ObservableValue<List<String>> descriptions = new ObservableValue<>();
public static ObservableAtomicInteger backgroundTaskCount = new ObservableAtomicInteger(0);
public static ObservableValue<Date> lastUpdateDate = new ObservableValue<>();
- public static ObservableValue<String> ledgerTitle = new ObservableValue<>();
+ public static ObservableValue<MobileLedgerProfile> profile = new ObservableValue<>();
}
package net.ktnx.mobileledger.ui.activity;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.os.Build;
import android.os.Bundle;
-import android.preference.PreferenceManager;
import android.support.annotation.ColorInt;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import net.ktnx.mobileledger.async.RetrieveTransactionsTask;
import net.ktnx.mobileledger.model.Data;
import net.ktnx.mobileledger.model.LedgerAccount;
+import net.ktnx.mobileledger.model.MobileLedgerProfile;
import net.ktnx.mobileledger.ui.MobileLedgerListFragment;
import net.ktnx.mobileledger.ui.account_summary.AccountSummaryFragment;
import net.ktnx.mobileledger.ui.transaction_list.TransactionListFragment;
import java.util.Date;
import java.util.Observable;
import java.util.Observer;
+import java.util.UUID;
public class MainActivity extends AppCompatActivity {
public MobileLedgerListFragment currentFragment = null;
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
+ Data.profile.addObserver(new Observer() {
+ @Override
+ public void update(Observable o, Object arg) {
+ MobileLedgerProfile profile = Data.profile.get();
+ runOnUiThread(() -> {
+ if (profile == null) toolbar.setSubtitle("");
+ else toolbar.setSubtitle(profile.getName());
+ });
+ }
+ });
+
+ String profileUUID = MLDB.get_option_value(MLDB.OPT_PROFILE_UUID, null);
+ if (profileUUID == null) {
+ SharedPreferences backend = getSharedPreferences("backend", MODE_PRIVATE);
+ Log.d("profiles", "Migrating from preferences to profiles");
+ // migration to multiple profiles
+ profileUUID = UUID.randomUUID().toString();
+ MobileLedgerProfile profile = new MobileLedgerProfile(profileUUID, "default",
+ backend.getString("backend_url", ""),
+ backend.getBoolean("backend_use_http_auth", false),
+ backend.getString("backend_auth_user", null),
+ backend.getString("backend_auth_password", null));
+ profile.storeInDB();
+ SharedPreferences.Editor editor = backend.edit();
+ editor.clear();
+ editor.apply();
+ Data.profile.set(profile);
+ MLDB.set_option_value(MLDB.OPT_PROFILE_UUID, profileUUID);
+ }
+ else {
+ MobileLedgerProfile profile = MobileLedgerProfile.loadUUIDFromDB(profileUUID);
+ Data.profile.set(profile);
+ }
+
drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle =
new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open,
});
}
});
-
- Data.ledgerTitle.addObserver(new Observer() {
- @Override
- public void update(Observable o, Object arg) {
- runOnUiThread(() -> {
- String title = Data.ledgerTitle.get();
- if (title == null) toolbar.setSubtitle("");
- else toolbar.setSubtitle(title);
- });
- }
- });
}
public void fab_new_transaction_clicked(View view) {
Intent intent = new Intent(this, NewTransactionActivity.class);
public void scheduleTransactionListRetrieval() {
retrieveTransactionsTask = new RetrieveTransactionsTask(new WeakReference<>(this));
- RetrieveTransactionsTask.Params params = new RetrieveTransactionsTask.Params(
- PreferenceManager.getDefaultSharedPreferences(this));
-
- retrieveTransactionsTask.execute(params);
+ retrieveTransactionsTask.execute();
bTransactionListCancelDownload.setEnabled(true);
}
public void onStopTransactionRefreshClick(View view) {
import android.widget.FilterQueryProvider;
import android.widget.SimpleCursorAdapter;
+import org.jetbrains.annotations.NonNls;
+
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
public static final String DESCRIPTION_HISTORY_TABLE = "description_history";
public static final String OPT_TRANSACTION_LIST_STAMP = "transaction_list_last_update";
public static final String OPT_LAST_REFRESH = "last_refresh";
+ @NonNls
+ public static final String OPT_PROFILE_UUID = "profile_uuid";
private static MobileLedgerDatabase helperForReading, helperForWriting;
private static Application context;
private static void checkState() {
/*
- * Copyright © 2018 Damyan Ivanov.
+ * Copyright © 2019 Damyan Ivanov.
* This file is part of Mobile-Ledger.
* Mobile-Ledger is free software: you can distribute it and/or modify it
* under the term of the GNU General Public License as published by
package net.ktnx.mobileledger.utils;
-import android.content.SharedPreferences;
import android.util.Base64;
import android.util.Log;
+import net.ktnx.mobileledger.model.Data;
+import net.ktnx.mobileledger.model.MobileLedgerProfile;
+
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
public final class NetworkUtil {
private static final int thirtySeconds = 30000;
- public static HttpURLConnection prepare_connection(SharedPreferences pref, String path) throws
- IOException {
- final String backend_url = pref.getString("backend_url", "");
- final boolean use_auth = pref.getBoolean("backend_use_http_auth", false);
- Log.d("network", "Connecting to "+backend_url + "/" + path);
- HttpURLConnection http = (HttpURLConnection) new URL(backend_url + "/" + path).openConnection();
+ public static HttpURLConnection prepare_connection(String path) throws IOException {
+ MobileLedgerProfile profile = Data.profile.get();
+ final String backend_url = profile.getUrl();
+ final boolean use_auth = profile.isUseAuthentication();
+ Log.d("network", "Connecting to " + backend_url + "/" + path);
+ HttpURLConnection http =
+ (HttpURLConnection) new URL(backend_url + "/" + path).openConnection();
if (use_auth) {
- final String auth_user = pref.getString("backend_auth_user", "");
- final String auth_password = pref.getString("backend_auth_password", "");
- final byte[] bytes = (String.format("%s:%s", auth_user, auth_password)).getBytes("UTF-8");
+ final String auth_user = profile.getAuthUserName();
+ final String auth_password = profile.getAuthPassword();
+ final byte[] bytes =
+ (String.format("%s:%s", auth_user, auth_password)).getBytes("UTF-8");
final String value = Base64.encodeToString(bytes, Base64.DEFAULT);
http.setRequestProperty("Authorization", "Basic " + value);
}