1
0
Fork 0
mirror of https://github.com/M66B/FairEmail.git synced 2025-03-15 16:39:37 +00:00

Added auto classify setting

This commit is contained in:
M66B 2021-01-02 22:38:37 +01:00
parent bf1d36ddfc
commit 34f1ae929b
8 changed files with 2387 additions and 13 deletions

File diff suppressed because it is too large Load diff

View file

@ -64,7 +64,7 @@ import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_PASSWORD;
// https://developer.android.com/topic/libraries/architecture/room.html // https://developer.android.com/topic/libraries/architecture/room.html
@Database( @Database(
version = 181, version = 182,
entities = { entities = {
EntityIdentity.class, EntityIdentity.class,
EntityAccount.class, EntityAccount.class,
@ -1781,6 +1781,13 @@ public abstract class DB extends RoomDatabase {
Log.i("DB migration from version " + startVersion + " to " + endVersion); Log.i("DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `rule` ADD COLUMN `last_applied` INTEGER"); db.execSQL("ALTER TABLE `rule` ADD COLUMN `last_applied` INTEGER");
} }
})
.addMigrations(new Migration(181, 182) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
Log.i("DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `folder` ADD COLUMN `auto_classify` INTEGER NOT NULL DEFAULT 0");
}
}); });
} }

View file

@ -282,6 +282,7 @@ public interface DaoFolder {
", unified = :unified" + ", unified = :unified" +
", navigation = :navigation" + ", navigation = :navigation" +
", notify = :notify" + ", notify = :notify" +
", auto_classify = :auto_classify" +
", hide = :hide" + ", hide = :hide" +
", synchronize = :synchronize" + ", synchronize = :synchronize" +
", poll = :poll" + ", poll = :poll" +
@ -293,7 +294,7 @@ public interface DaoFolder {
" WHERE id = :id") " WHERE id = :id")
int setFolderProperties( int setFolderProperties(
long id, String rename, long id, String rename,
String display, Integer color, boolean unified, boolean navigation, boolean notify, boolean hide, String display, Integer color, boolean unified, boolean navigation, boolean notify, boolean auto_classify, boolean hide,
boolean synchronize, boolean poll, int poll_factor, boolean download, boolean synchronize, boolean poll, int poll_factor, boolean download,
int sync_days, int keep_days, boolean auto_delete); int sync_days, int keep_days, boolean auto_delete);

View file

@ -108,6 +108,8 @@ public class EntityFolder extends EntityOrder implements Serializable {
public Boolean navigation = false; public Boolean navigation = false;
@NonNull @NonNull
public Boolean notify = false; public Boolean notify = false;
@NonNull
public Boolean auto_classify = false;
public Integer total; // messages on server public Integer total; // messages on server
public String[] keywords; public String[] keywords;

View file

@ -64,6 +64,7 @@ public class FragmentFolder extends FragmentBase {
private CheckBox cbUnified; private CheckBox cbUnified;
private CheckBox cbNavigation; private CheckBox cbNavigation;
private CheckBox cbNotify; private CheckBox cbNotify;
private CheckBox cbAutoClassify;
private CheckBox cbSynchronize; private CheckBox cbSynchronize;
private CheckBox cbPoll; private CheckBox cbPoll;
private EditText etPoll; private EditText etPoll;
@ -124,6 +125,7 @@ public class FragmentFolder extends FragmentBase {
cbUnified = view.findViewById(R.id.cbUnified); cbUnified = view.findViewById(R.id.cbUnified);
cbNavigation = view.findViewById(R.id.cbNavigation); cbNavigation = view.findViewById(R.id.cbNavigation);
cbNotify = view.findViewById(R.id.cbNotify); cbNotify = view.findViewById(R.id.cbNotify);
cbAutoClassify = view.findViewById(R.id.cbAutoClassify);
cbSynchronize = view.findViewById(R.id.cbSynchronize); cbSynchronize = view.findViewById(R.id.cbSynchronize);
cbPoll = view.findViewById(R.id.cbPoll); cbPoll = view.findViewById(R.id.cbPoll);
etPoll = view.findViewById(R.id.etPoll); etPoll = view.findViewById(R.id.etPoll);
@ -158,6 +160,8 @@ public class FragmentFolder extends FragmentBase {
} }
}); });
cbAutoClassify.setVisibility(MessageClassifier.isEnabled(getContext()) ? View.VISIBLE : View.GONE);
cbSynchronize.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { cbSynchronize.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@ -280,6 +284,7 @@ public class FragmentFolder extends FragmentBase {
cbUnified.setChecked(folder == null ? false : folder.unified); cbUnified.setChecked(folder == null ? false : folder.unified);
cbNavigation.setChecked(folder == null ? false : folder.navigation); cbNavigation.setChecked(folder == null ? false : folder.navigation);
cbNotify.setChecked(folder == null ? false : folder.notify); cbNotify.setChecked(folder == null ? false : folder.notify);
cbAutoClassify.setChecked(folder == null ? false : folder.auto_classify);
cbSynchronize.setChecked(folder == null || folder.synchronize); cbSynchronize.setChecked(folder == null || folder.synchronize);
cbPoll.setChecked(folder == null ? true : folder.poll); cbPoll.setChecked(folder == null ? true : folder.poll);
etPoll.setText(folder == null ? null : Integer.toString(folder.poll_factor)); etPoll.setText(folder == null ? null : Integer.toString(folder.poll_factor));
@ -411,6 +416,7 @@ public class FragmentFolder extends FragmentBase {
args.putBoolean("unified", cbUnified.isChecked()); args.putBoolean("unified", cbUnified.isChecked());
args.putBoolean("navigation", cbNavigation.isChecked()); args.putBoolean("navigation", cbNavigation.isChecked());
args.putBoolean("notify", cbNotify.isChecked()); args.putBoolean("notify", cbNotify.isChecked());
args.putBoolean("auto_classify", cbAutoClassify.isChecked());
args.putBoolean("synchronize", cbSynchronize.isChecked()); args.putBoolean("synchronize", cbSynchronize.isChecked());
args.putBoolean("poll", cbPoll.isChecked()); args.putBoolean("poll", cbPoll.isChecked());
args.putString("factor", etPoll.getText().toString()); args.putString("factor", etPoll.getText().toString());
@ -453,6 +459,7 @@ public class FragmentFolder extends FragmentBase {
boolean unified = args.getBoolean("unified"); boolean unified = args.getBoolean("unified");
boolean navigation = args.getBoolean("navigation"); boolean navigation = args.getBoolean("navigation");
boolean notify = args.getBoolean("notify"); boolean notify = args.getBoolean("notify");
boolean auto_classify = args.getBoolean("auto_classify");
boolean synchronize = args.getBoolean("synchronize"); boolean synchronize = args.getBoolean("synchronize");
boolean poll = args.getBoolean("poll"); boolean poll = args.getBoolean("poll");
String factor = args.getString("factor"); String factor = args.getString("factor");
@ -506,6 +513,8 @@ public class FragmentFolder extends FragmentBase {
return true; return true;
if (!Objects.equals(folder.notify, notify)) if (!Objects.equals(folder.notify, notify))
return true; return true;
if (!Objects.equals(folder.auto_classify, auto_classify))
return true;
if (!Objects.equals(folder.hide, hide)) if (!Objects.equals(folder.hide, hide))
return true; return true;
if (!Objects.equals(folder.synchronize, synchronize)) if (!Objects.equals(folder.synchronize, synchronize))
@ -555,6 +564,7 @@ public class FragmentFolder extends FragmentBase {
create.unified = unified; create.unified = unified;
create.navigation = navigation; create.navigation = navigation;
create.notify = notify; create.notify = notify;
create.auto_classify = auto_classify;
create.hide = hide; create.hide = hide;
create.synchronize = synchronize; create.synchronize = synchronize;
create.poll = poll; create.poll = poll;
@ -578,7 +588,7 @@ public class FragmentFolder extends FragmentBase {
Log.i("Updating folder=" + folder.name); Log.i("Updating folder=" + folder.name);
db.folder().setFolderProperties(id, db.folder().setFolderProperties(id,
folder.name.equals(name) ? null : name, folder.name.equals(name) ? null : name,
display, color, unified, navigation, notify, hide, display, color, unified, navigation, notify, auto_classify, hide,
synchronize, poll, poll_factor, download, synchronize, poll, poll_factor, download,
sync_days, keep_days, auto_delete); sync_days, keep_days, auto_delete);
db.folder().setFolderError(id, null); db.folder().setFolderError(id, null);

View file

@ -48,9 +48,9 @@ public class MessageClassifier {
private static final double COMMON_WORD_FACTOR = 0.75; private static final double COMMON_WORD_FACTOR = 0.75;
private static final double CHANCE_THRESHOLD = 2.0; private static final double CHANCE_THRESHOLD = 2.0;
static String classify(EntityMessage message, boolean added, Context context) { static void classify(EntityMessage message, boolean added, Context context) {
if (!isEnabled(context)) if (!isEnabled(context))
return null; return;
try { try {
load(context); load(context);
@ -62,21 +62,21 @@ public class MessageClassifier {
EntityFolder folder = db.folder().getFolder(message.folder); EntityFolder folder = db.folder().getFolder(message.folder);
if (folder == null) if (folder == null)
return null; return;
EntityAccount account = db.account().getAccount(folder.account); EntityAccount account = db.account().getAccount(folder.account);
if (account == null) if (account == null)
return null; return;
if (!EntityFolder.INBOX.equals(folder.type) && if (!EntityFolder.INBOX.equals(folder.type) &&
!EntityFolder.JUNK.equals(folder.type) && !EntityFolder.JUNK.equals(folder.type) &&
!EntityFolder.USER.equals(folder.type) && !EntityFolder.USER.equals(folder.type) &&
!(EntityFolder.ARCHIVE.equals(folder.type) && !account.isGmail())) !(EntityFolder.ARCHIVE.equals(folder.type) && !account.isGmail()))
return null; return;
File file = message.getFile(context); File file = message.getFile(context);
if (!file.exists()) if (!file.exists())
return null; return;
String text; String text;
try { try {
@ -87,7 +87,7 @@ public class MessageClassifier {
} }
if (TextUtils.isEmpty(text)) if (TextUtils.isEmpty(text))
return null; return;
if (!classMessages.containsKey(account.id)) if (!classMessages.containsKey(account.id))
classMessages.put(account.id, new HashMap<>()); classMessages.put(account.id, new HashMap<>());
@ -106,7 +106,11 @@ public class MessageClassifier {
} }
Log.i("Classifier classify=" + folder.name + " messages=" + classMessages.get(account.id).get(folder.name)); Log.i("Classifier classify=" + folder.name + " messages=" + classMessages.get(account.id).get(folder.name));
return classified; if (classified != null) {
EntityFolder f = db.folder().getFolderByName(account.id, classified);
if (f != null && f.auto_classify && !f.id.equals(folder.id))
EntityOperation.queue(context, message, EntityOperation.MOVE, f.id);
}
} }
private static String classify(long account, String classify, String text, boolean added) { private static String classify(long account, String classify, String text, boolean added) {
@ -295,7 +299,7 @@ public class MessageClassifier {
Log.i("Classifier loaded"); Log.i("Classifier loaded");
} }
private static boolean isEnabled(Context context) { static boolean isEnabled(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean("classify", BuildConfig.DEBUG); return prefs.getBoolean("classify", BuildConfig.DEBUG);
} }

View file

@ -136,6 +136,15 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbNavigation" /> app:layout_constraintTop_toBottomOf="@id/cbNavigation" />
<CheckBox
android:id="@+id/cbAutoClassify"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_auto_classify"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbNotify" />
<CheckBox <CheckBox
android:id="@+id/cbSynchronize" android:id="@+id/cbSynchronize"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -143,7 +152,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:text="@string/title_synchronize_folder" android:text="@string/title_synchronize_folder"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbNotify" /> app:layout_constraintTop_toBottomOf="@id/cbAutoClassify" />
<CheckBox <CheckBox
android:id="@+id/cbPoll" android:id="@+id/cbPoll"

View file

@ -779,6 +779,7 @@
<string name="title_poll_folder">Check periodically instead of continuous synchronize</string> <string name="title_poll_folder">Check periodically instead of continuous synchronize</string>
<string name="title_download_folder">Automatically download message texts and attachments</string> <string name="title_download_folder">Automatically download message texts and attachments</string>
<string name="title_notify_folder">Notify on new messages</string> <string name="title_notify_folder">Notify on new messages</string>
<string name="title_auto_classify" translatable="false">Automatically classify</string>
<string name="title_sync_days">Synchronize messages (days)</string> <string name="title_sync_days">Synchronize messages (days)</string>
<string name="title_sync_days_remark">Increasing this value will increase battery and data usage</string> <string name="title_sync_days_remark">Increasing this value will increase battery and data usage</string>
<string name="title_keep_days">Keep messages (days)</string> <string name="title_keep_days">Keep messages (days)</string>