Added quick config

This commit is contained in:
M66B 2018-12-29 17:00:10 +00:00
parent 97df7ae400
commit 3d74b93d74
3 changed files with 298 additions and 2 deletions

View File

@ -38,6 +38,7 @@ import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Patterns;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -53,6 +54,9 @@ import android.widget.TextView;
import android.widget.ToggleButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputLayout;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore;
import org.json.JSONArray;
import org.json.JSONObject;
@ -65,8 +69,10 @@ import java.io.OutputStream;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
@ -76,6 +82,9 @@ import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.mail.Folder;
import javax.mail.Session;
import javax.mail.Transport;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -91,6 +100,11 @@ public class FragmentSetup extends FragmentEx {
private ImageButton ibHelp;
private EditText etName;
private EditText etEmail;
private TextInputLayout tilPassword;
private Button btnQuick;
private Button btnAccount;
private TextView tvAccountDone;
private TextView tvNoPrimaryDrafts;
@ -135,6 +149,11 @@ public class FragmentSetup extends FragmentEx {
// Get controls
ibHelp = view.findViewById(R.id.ibHelp);
etName = view.findViewById(R.id.etName);
etEmail = view.findViewById(R.id.etEmail);
tilPassword = view.findViewById(R.id.tilPassword);
btnQuick = view.findViewById(R.id.btnQuick);
btnAccount = view.findViewById(R.id.btnAccount);
tvAccountDone = view.findViewById(R.id.tvAccountDone);
tvNoPrimaryDrafts = view.findViewById(R.id.tvNoPrimaryDrafts);
@ -165,6 +184,216 @@ public class FragmentSetup extends FragmentEx {
}
});
btnQuick.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle args = new Bundle();
args.putString("name", etName.getText().toString());
args.putString("email", etEmail.getText().toString());
args.putString("password", tilPassword.getEditText().getText().toString());
new SimpleTask<Void>() {
@Override
protected void onInit(Bundle args) {
etName.setEnabled(false);
etEmail.setEnabled(false);
tilPassword.setEnabled(false);
btnQuick.setEnabled(false);
}
@Override
protected void onCleanup(Bundle args) {
etName.setEnabled(true);
etEmail.setEnabled(true);
tilPassword.setEnabled(true);
btnQuick.setEnabled(true);
}
@Override
protected Void onLoad(Context context, Bundle args) throws Throwable {
String name = args.getString("name");
String email = args.getString("email");
String password = args.getString("password");
if (TextUtils.isEmpty(name))
throw new IllegalArgumentException(context.getString(R.string.title_no_name));
if (TextUtils.isEmpty(email))
throw new IllegalArgumentException(context.getString(R.string.title_no_email));
if (!Patterns.EMAIL_ADDRESS.matcher(email).matches())
throw new IllegalArgumentException(context.getString(R.string.title_email_invalid));
String domain = email.split("@")[1];
Provider provider = Provider.fromDomain(context, domain);
String user = email; // TODO
Character separator;
long now = new Date().getTime();
List<EntityFolder> folders = new ArrayList<>();
{
Properties props = MessageHelper.getSessionProperties(Helper.AUTH_TYPE_PASSWORD, false);
Session isession = Session.getInstance(props, null);
isession.setDebug(true);
IMAPStore istore = null;
try {
istore = (IMAPStore) isession.getStore(provider.imap_starttls ? "imap" : "imaps");
istore.connect(provider.imap_host, provider.imap_port, user, password);
separator = istore.getDefaultFolder().getSeparator();
boolean drafts = false;
for (Folder ifolder : istore.getDefaultFolder().list("*")) {
String type = null;
boolean selectable = true;
String[] attrs = ((IMAPFolder) ifolder).getAttributes();
Log.i(ifolder.getFullName() + " attrs=" + TextUtils.join(" ", attrs));
for (String attr : attrs) {
if ("\\Noselect".equals(attr) || "\\NonExistent".equals(attr))
selectable = false;
if (attr.startsWith("\\")) {
int index = EntityFolder.SYSTEM_FOLDER_ATTR.indexOf(attr.substring(1));
if (index >= 0) {
type = EntityFolder.SYSTEM_FOLDER_TYPE.get(index);
break;
}
}
}
if (selectable && type != null) {
EntityFolder folder = new EntityFolder();
folder.name = ifolder.getFullName();
folder.type = type;
folder.level = EntityFolder.getLevel(separator, folder.name);
folder.synchronize = EntityFolder.SYSTEM_FOLDER_SYNC.contains(type);
folder.sync_days = EntityFolder.DEFAULT_SYNC;
folder.keep_days = EntityFolder.DEFAULT_KEEP;
folders.add(folder);
if (EntityFolder.DRAFTS.equals(type))
drafts = true;
}
}
if (!drafts)
throw new IllegalArgumentException(context.getString(R.string.title_no_drafts));
} finally {
if (istore != null)
istore.close();
}
}
{
Properties props = MessageHelper.getSessionProperties(Helper.AUTH_TYPE_PASSWORD, false);
Session isession = Session.getInstance(props, null);
isession.setDebug(true);
Transport itransport = isession.getTransport(provider.smtp_starttls ? "smtp" : "smtps");
try {
itransport.connect(provider.smtp_host, provider.smtp_port, user, password);
} finally {
itransport.close();
}
}
DB db = DB.getInstance(context);
try {
db.beginTransaction();
EntityAccount primary = db.account().getPrimaryAccount();
// Create account
EntityAccount account = new EntityAccount();
account.auth_type = Helper.AUTH_TYPE_PASSWORD;
account.host = provider.imap_host;
account.starttls = provider.imap_starttls;
account.insecure = false;
account.port = provider.imap_port;
account.user = user;
account.password = password;
account.name = provider.name;
account.color = null;
account.synchronize = true;
account.primary = (primary == null);
account.notify = false;
account.browse = true;
account.poll_interval = 19;
account.prefix = provider.prefix; // TODO
account.created = now;
account.error = null;
account.last_connected = now;
account.id = db.account().insertAccount(account);
// Create folders
for (EntityFolder folder : folders) {
folder.account = account.id;
folder.id = db.folder().insertFolder(folder);
}
// Create identity
EntityIdentity identity = new EntityIdentity();
identity.name = name;
identity.email = email;
identity.account = account.id;
identity.display = null;
identity.color = null;
identity.signature = null;
identity.auth_type = Helper.AUTH_TYPE_PASSWORD;
identity.host = provider.smtp_host;
identity.starttls = provider.smtp_starttls;
identity.insecure = false;
identity.port = provider.smtp_port;
identity.user = user;
identity.password = password;
identity.synchronize = true;
identity.primary = true;
identity.replyto = null;
identity.bcc = null;
identity.delivery_receipt = false;
identity.read_receipt = false;
identity.store_sent = false;
identity.sent_folder = null;
identity.error = null;
identity.id = db.identity().insertIdentity(identity);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
ServiceSynchronize.reload(context, "quick setup");
return null;
}
@Override
protected void onLoaded(Bundle args, Void data) {
finish();
}
@Override
protected void onException(Bundle args, Throwable ex) {
if (ex instanceof IllegalArgumentException)
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner())
.setMessage(Helper.formatThrowable(ex))
.setPositiveButton(android.R.string.cancel, null)
.create()
.show();
}
}.load(FragmentSetup.this, args);
}
});
btnAccount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

View File

@ -12,7 +12,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- account -->
<ImageButton
android:id="@+id/ibHelp"
@ -22,6 +21,73 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/etName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:autofillHints="name"
android:hint="@string/title_identity_name"
android:inputType="textCapSentences"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ibHelp" />
<EditText
android:id="@+id/etEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:autofillHints="emailAddress"
android:hint="@string/title_identity_email"
android:inputType="textEmailAddress"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etName" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:autofillHints="password"
android:inputType="textPassword"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etEmail"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autofillHints="password"
android:hint="@string/title_setup_password"
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/btnQuick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_setup_quick"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tilPassword" />
<View
android:id="@+id/vSeparatorQuick"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="12dp"
android:background="?attr/colorSeparator"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btnQuick" />
<!-- account -->
<Button
android:id="@+id/btnAccount"
android:layout_width="wrap_content"
@ -30,7 +96,7 @@
android:text="@string/title_setup_account"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toBottomOf="@id/vSeparatorQuick" />
<TextView
android:id="@+id/tvAccount"

View File

@ -85,6 +85,7 @@
<string name="title_setup_password_invalid">Password invalid</string>
<string name="title_setup_exported">Settings exported</string>
<string name="title_setup_imported">Settings imported</string>
<string name="title_setup_quick">Quick config</string>
<string name="title_setup_account">Manage accounts</string>
<string name="title_setup_account_remark">To receive email</string>
<string name="title_setup_identity">Manage identities</string>