Added text contains filter rule condition

This commit is contained in:
M66B 2021-12-08 22:46:05 +01:00
parent 1190111069
commit 394134c1e5
10 changed files with 141 additions and 15 deletions

View File

@ -4,6 +4,12 @@
### [Caudipteryx](https://en.wikipedia.org/wiki/Caudipteryx)
### Next version
* Added text contains filter rule condition
* Small improvements and minor bug fixes
* Updated translations
### 1.1784 - 2021-12-08
* Added display option to override widths in original message view

View File

@ -4,6 +4,12 @@
### [Caudipteryx](https://en.wikipedia.org/wiki/Caudipteryx)
### Next version
* Added text contains filter rule condition
* Small improvements and minor bug fixes
* Updated translations
### 1.1784 - 2021-12-08
* Added display option to override widths in original message view

View File

@ -126,6 +126,8 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> {
condition.add(context.getString(R.string.title_rule_subject));
if (jcondition.has("header"))
condition.add(context.getString(R.string.title_rule_header));
if (jcondition.has("body"))
condition.add(context.getString(R.string.title_rule_body));
if (jcondition.has("date"))
condition.add(context.getString(R.string.title_rule_time_abs));
if (jcondition.has("schedule"))
@ -319,7 +321,7 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> {
if (message == null)
continue;
if (rule.matches(context, message, null))
if (rule.matches(context, message, null, null))
if (rule.execute(context, message))
applied++;

View File

@ -2800,6 +2800,7 @@ class Core {
List<Header> headers =
(EntityRule.needsHeaders(rules) ? helper.getAllHeaders() : null);
String body = parts.getHtml(context);
try {
db.beginTransaction();
@ -2819,7 +2820,7 @@ class Core {
attachment.id = db.attachment().insertAttachment(attachment);
}
runRules(context, headers, account, folder, message, rules);
runRules(context, headers, body, account, folder, message, rules);
reportNewMessage(context, account, folder, message);
db.setTransactionSuccessful();
@ -2827,7 +2828,6 @@ class Core {
db.endTransaction();
}
String body = parts.getHtml(context);
File file = message.getFile(context);
Helper.writeText(file, body);
String text = HtmlHelper.getFullText(body);
@ -3656,6 +3656,8 @@ class Core {
List<Header> headers =
(EntityRule.needsHeaders(rules) ? helper.getAllHeaders() : null);
String body =
(EntityRule.needsBody(rules) ? helper.getMessageParts().getHtml(context) : null);
if (message == null) {
Long sent = helper.getSent();
@ -3868,7 +3870,7 @@ class Core {
attachment.id = db.attachment().insertAttachment(attachment);
}
runRules(context, headers, account, folder, message, rules);
runRules(context, headers, body, account, folder, message, rules);
if (message.blocklist != null && message.blocklist) {
boolean use_blocklist = prefs.getBoolean("use_blocklist", false);
@ -3910,7 +3912,7 @@ class Core {
EntityContact.received(context, account, folder, message);
// Download small messages inline
if (download && !message.ui_hide) {
if (body != null || (download && !message.ui_hide)) {
long maxSize;
if (state == null || state.networkState.isUnmetered())
maxSize = MessageHelper.SMALL_MESSAGE_SIZE;
@ -3920,10 +3922,12 @@ class Core {
maxSize = MessageHelper.SMALL_MESSAGE_SIZE;
}
if ((message.size != null && message.size < maxSize) ||
if (body != null ||
(message.size != null && message.size < maxSize) ||
(MessageClassifier.isEnabled(context)) && folder.auto_classify_source)
try {
String body = parts.getHtml(context);
if (body == null)
body = parts.getHtml(context);
File file = message.getFile(context);
Helper.writeText(file, body);
String text = HtmlHelper.getFullText(body);
@ -4078,7 +4082,7 @@ class Core {
db.message().updateMessage(message);
if (process)
runRules(context, headers, account, folder, message, rules);
runRules(context, headers, body, account, folder, message, rules);
db.setTransactionSuccessful();
} finally {
@ -4241,7 +4245,7 @@ class Core {
}
private static void runRules(
Context context, List<Header> headers,
Context context, List<Header> headers, String html,
EntityAccount account, EntityFolder folder, EntityMessage message,
List<EntityRule> rules) {
@ -4254,7 +4258,7 @@ class Core {
try {
boolean executed = false;
for (EntityRule rule : rules)
if (rule.matches(context, message, headers)) {
if (rule.matches(context, message, headers, html)) {
rule.execute(context, message);
executed = true;
if (rule.stop)

View File

@ -128,6 +128,10 @@ public class EntityRule {
return needs(rules, "header");
}
static boolean needsBody(List<EntityRule> rules) {
return needs(rules, "body");
}
private static boolean needs(List<EntityRule> rules, String what) {
for (EntityRule rule : rules)
try {
@ -141,7 +145,7 @@ public class EntityRule {
return false;
}
boolean matches(Context context, EntityMessage message, List<Header> headers) throws MessagingException {
boolean matches(Context context, EntityMessage message, List<Header> headers, String html) throws MessagingException {
try {
JSONObject jcondition = new JSONObject(condition);
@ -297,6 +301,29 @@ public class EntityRule {
}
}
// Body
JSONObject jbody = jcondition.optJSONObject("body");
if (jbody != null) {
String value = jbody.getString("value");
boolean regex = jbody.getBoolean("regex");
if (html == null && message.content) {
File file = message.getFile(context);
try {
html = Helper.readText(file);
} catch (IOException ex) {
Log.e(ex);
}
}
if (html == null)
throw new IllegalArgumentException(context.getString(R.string.title_rule_no_body));
String text = HtmlHelper.getFullText(html);
if (!matches(context, message, value, text, regex))
return false;
}
// Date
JSONObject jdate = jcondition.optJSONObject("date");
if (jdate != null) {
@ -329,6 +356,7 @@ public class EntityRule {
jsubject == null &&
!jcondition.optBoolean("attachments") &&
jheader == null &&
jbody == null &&
jdate == null &&
jschedule == null)
return false;

View File

@ -1070,7 +1070,7 @@ public class FragmentFolders extends FragmentBase {
for (EntityRule rule : rules) {
EntityLog.log(context, "Executing rules evaluating=" + rule.name);
if (rule.matches(context, message, null)) {
if (rule.matches(context, message, null, null)) {
EntityLog.log(context, "Executing rules matches=" + rule.name);
if (rule.execute(context, message)) {
EntityLog.log(context, "Executing rules applied=" + rule.name);

View File

@ -105,6 +105,9 @@ public class FragmentRule extends FragmentBase {
private EditText etHeader;
private CheckBox cbHeader;
private EditText etBody;
private CheckBox cbBody;
private TextView tvDateAfter;
private TextView tvDateBefore;
private Button btnDateAfter;
@ -240,6 +243,9 @@ public class FragmentRule extends FragmentBase {
etHeader = view.findViewById(R.id.etHeader);
cbHeader = view.findViewById(R.id.cbHeader);
etBody = view.findViewById(R.id.etBody);
cbBody = view.findViewById(R.id.cbBody);
tvDateAfter = view.findViewById(R.id.tvDateAfter);
tvDateBefore = view.findViewById(R.id.tvDateBefore);
btnDateAfter = view.findViewById(R.id.btnDateAfter);
@ -877,6 +883,7 @@ public class FragmentRule extends FragmentBase {
JSONObject jrecipient = jcondition.optJSONObject("recipient");
JSONObject jsubject = jcondition.optJSONObject("subject");
JSONObject jheader = jcondition.optJSONObject("header");
JSONObject jbody = jcondition.optJSONObject("body");
JSONObject jdate = jcondition.optJSONObject("date");
JSONObject jschedule = jcondition.optJSONObject("schedule");
@ -905,6 +912,9 @@ public class FragmentRule extends FragmentBase {
etHeader.setText(jheader == null ? null : jheader.getString("value"));
cbHeader.setChecked(jheader != null && jheader.getBoolean("regex"));
etBody.setText(jbody == null ? null : jbody.getString("value"));
cbBody.setChecked(jbody != null && jbody.getBoolean("regex"));
long after = (jdate != null && jdate.has("after") ? jdate.getLong("after") : 0);
long before = (jdate != null && jdate.has("before") ? jdate.getLong("before") : 0);
@ -1118,6 +1128,7 @@ public class FragmentRule extends FragmentBase {
JSONObject jrecipient = jcondition.optJSONObject("recipient");
JSONObject jsubject = jcondition.optJSONObject("subject");
JSONObject jheader = jcondition.optJSONObject("header");
JSONObject jbody = jcondition.optJSONObject("body");
JSONObject jdate = jcondition.optJSONObject("date");
JSONObject jschedule = jcondition.optJSONObject("schedule");
@ -1126,6 +1137,7 @@ public class FragmentRule extends FragmentBase {
jsubject == null &&
!jcondition.optBoolean("attachments") &&
jheader == null &&
jbody == null &&
jdate == null &&
jschedule == null)
throw new IllegalArgumentException(context.getString(R.string.title_rule_condition_missing));
@ -1220,6 +1232,14 @@ public class FragmentRule extends FragmentBase {
jcondition.put("header", jheader);
}
String body = etBody.getText().toString();
if (!TextUtils.isEmpty(body)) {
JSONObject jbody = new JSONObject();
jbody.put("value", body);
jbody.put("regex", cbBody.isChecked());
jcondition.put("body", jbody);
}
Object hafter = tvDateAfter.getTag();
Object hbefore = tvDateBefore.getTag();
@ -1441,7 +1461,7 @@ public class FragmentRule extends FragmentBase {
if (message == null)
continue;
if (rule.matches(context, message, null))
if (rule.matches(context, message, null, null))
if (rule.execute(context, message))
applied++;
@ -1501,7 +1521,7 @@ public class FragmentRule extends FragmentBase {
if (message == null)
continue;
if (rule.matches(context, message, null))
if (rule.matches(context, message, null, null))
matching.add(message);
if (matching.size() >= MAX_CHECK)

View File

@ -408,13 +408,65 @@
app:layout_constraintTop_toBottomOf="@+id/etHeader" />
<View
android:id="@+id/vSeparatorDate"
android:id="@+id/vSeparatorBody"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/colorSeparator"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvAndHeader" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvBody"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/title_rule_body"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintBottom_toBottomOf="@+id/cbBody"
app:layout_constraintEnd_toStartOf="@+id/cbBody"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/cbBody" />
<CheckBox
android:id="@+id/cbBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_rule_regex"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/vSeparatorBody" />
<eu.faircode.email.EditTextPlain
android:id="@+id/etBody"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/title_optional"
android:inputType="text|textNoSuggestions"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbBody" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvAndBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_rule_and"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/etBody" />
<View
android:id="@+id/vSeparatorDate"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/colorSeparator"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvAndBody" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvDate"
android:layout_width="0dp"

View File

@ -1474,6 +1474,7 @@
<string name="title_rule_attachments">Has attachments</string>
<string name="title_rule_mime_type" translatable="false">Mime type</string>
<string name="title_rule_header">Header contains</string>
<string name="title_rule_body">Text contains</string>
<string name="title_rule_time_abs">Absolute time (received) between</string>
<string name="title_rule_time_after">Received after</string>
<string name="title_rule_time_before">Received before</string>
@ -1505,6 +1506,7 @@
<string name="title_rule_check">Check</string>
<string name="title_rule_no_headers">Header conditions cannot be checked</string>
<string name="title_rule_no_body">Message text not available</string>
<string name="title_rule_matched">Matching messages</string>
<string name="title_rule_no_matches">No matching messages</string>

View File

@ -4,6 +4,12 @@
### [Caudipteryx](https://en.wikipedia.org/wiki/Caudipteryx)
### Next version
* Added text contains filter rule condition
* Small improvements and minor bug fixes
* Updated translations
### 1.1784 - 2021-12-08
* Added display option to override widths in original message view