0
0
mirror of https://github.com/TrianguloY/UrlChecker.git synced 2024-09-19 20:02:16 +02:00

PatternCatalog editor (needs testing)

This commit is contained in:
TrianguloY 2022-07-20 13:54:35 +02:00
parent 3e638ed344
commit efa4812698
8 changed files with 151 additions and 50 deletions

View File

@ -40,14 +40,11 @@ public class MainDialog extends Activity {
private int updating = 0;
/**
* A module changed the url
*
* @param urlData the new url and its data
* @param providerModule which module changed it (null if first change)
* A module (null if first change) want to set a new url. Return true if set, false if not.
*/
public void onNewUrl(UrlData urlData, AModuleDialog providerModule) {
public boolean onNewUrl(UrlData urlData, AModuleDialog providerModule) {
// test and mark recursion
if (updating > MAX_UPDATES) return;
if (updating > MAX_UPDATES) return false;
if (urlData.disableUpdates) updating = MAX_UPDATES;
updating++;
int updating_current = updating;
@ -66,9 +63,10 @@ public class MainDialog extends Activity {
e.printStackTrace();
AndroidUtils.assertError("Exception in onNewUrl for module " + (providerModule == null ? "-none-" : providerModule.getClass().getName()));
}
if (updating_current != updating) return;
if (updating_current != updating) return true;
}
updating = 0;
return true;
}
/**

View File

@ -51,8 +51,8 @@ public abstract class AModuleDialog implements Fragment {
*
* @param url new url
*/
protected final void setUrl(String url) {
setUrl(new UrlData(url));
protected final boolean setUrl(String url) {
return setUrl(new UrlData(url));
}
/**
@ -60,8 +60,8 @@ public abstract class AModuleDialog implements Fragment {
*
* @param urlData new url and data
*/
protected final void setUrl(UrlData urlData) {
dialog.onNewUrl(urlData, this);
protected final boolean setUrl(UrlData urlData) {
return dialog.onNewUrl(urlData, this);
}
}

View File

@ -87,18 +87,6 @@ public class ClearUrlCatalog {
return "{\"providers\":{}}";
}
/**
* Converts a string into a json object, returns empty on failure
*/
public static JSONObject toJson(String content) {
try {
return new JSONObject(content);
} catch (JSONException e) {
// invalid catalog, return empty
return new JSONObject();
}
}
/**
* Parses and returns the providers from the catalog
* Returns a list of pairs: [(rule,data),...]
@ -108,7 +96,7 @@ public class ClearUrlCatalog {
// prepare
List<Pair<String, JSONObject>> rules = new ArrayList<>();
ClearUrlCatalog clearUrlCatalog = new ClearUrlCatalog(cntx);
JSONObject json = toJson(clearUrlCatalog.getCatalog());
JSONObject json = JavaUtilities.toJson(clearUrlCatalog.getCatalog());
// extract and merge each provider
for (String provider : JavaUtilities.toList(json.keys())) {
@ -134,7 +122,7 @@ public class ClearUrlCatalog {
if (merge) {
try {
// replace only the top objects
JSONObject merged = toJson(getCatalog());
JSONObject merged = JavaUtilities.toJson(getCatalog());
for (String key : JavaUtilities.toList(rules.keys())) {
merged.put(key, rules.getJSONObject(key));
}
@ -181,7 +169,7 @@ public class ClearUrlCatalog {
* Show the rules editor dialog
*/
public void showEditor() {
JsonEditor.show(toJson(getCatalog()), toJson(getBuiltIn()), R.string.mClear_editor, cntx, content -> {
JsonEditor.show(JavaUtilities.toJson(getCatalog()), JavaUtilities.toJson(getBuiltIn()), R.string.mClear_editor, cntx, content -> {
if (setRules(content, false)) {
// saved data, close dialog
return true;

View File

@ -1,39 +1,81 @@
package com.trianguloy.urlchecker.modules.companions;
import android.app.Activity;
import android.content.Context;
import com.trianguloy.urlchecker.R;
import com.trianguloy.urlchecker.dialogs.JsonEditor;
import com.trianguloy.urlchecker.utilities.StreamUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.FileOutputStream;
import java.io.IOException;
public class PatternCatalog {
public static JSONObject getBuiltIn(Activity cntx) {
private static final String fileName = "patterns";
private final Activity cntx;
public PatternCatalog(Activity cntx) {
this.cntx = cntx;
}
public JSONObject getCatalog() {
// get the updated file first
try {
return new JSONObject(StreamUtils.inputStream2String(cntx.openFileInput(fileName)));
} catch (IOException | JSONException ignored) {
}
// no updated file or can't read, use built-in one
return getBuiltIn();
}
public void clear() {
cntx.deleteFile(fileName);
}
public boolean save(JSONObject content) {
// the same, already saved
if (content.equals(getCatalog())) return true;
// same as builtin (maybe a reset?), clear custom
if (content.equals(getBuiltIn())) {
clear();
return true;
}
// store
try (FileOutputStream fos = cntx.openFileOutput(fileName, Context.MODE_PRIVATE)) {
fos.write(content.toString().getBytes(StreamUtils.UTF_8));
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public JSONObject getBuiltIn() {
try {
return new JSONObject()
.put(cntx.getString(R.string.mPttrn_ascii), new JSONObject()
.put("regex", ".*[^\\p{ASCII}].*")
.put("enabled", true)
.put("automatic", false)
)
.put(cntx.getString(R.string.mPttrn_http), new JSONObject()
.put("regex", "^http://(.*)")
.put("replacement", "https://$1")
.put("enabled", true)
.put("automatic", true)
)
.put(cntx.getString(R.string.mPttrn_noSchemeHttp), new JSONObject()
.put("regex", "^(?!.*:).*")
.put("replacement", "http://$0")
.put("enabled", true)
.put("automatic", true)
)
.put(cntx.getString(R.string.mPttrn_noSchemeHttps), new JSONObject()
.put("regex", "^(?!.*:).*")
.put("replacement", "https://$0")
.put("enabled", true)
.put("automatic", false)
)
;
} catch (JSONException e) {
@ -42,4 +84,8 @@ public class PatternCatalog {
}
}
public void showEditor() {
JsonEditor.show(getCatalog(), getBuiltIn(), R.string.mPttrn_editor, cntx, this::save);
}
}

View File

@ -1,5 +1,6 @@
package com.trianguloy.urlchecker.modules.list;
import android.app.Activity;
import android.util.Pair;
import android.view.View;
import android.widget.Button;
@ -12,7 +13,6 @@ import com.trianguloy.urlchecker.dialogs.MainDialog;
import com.trianguloy.urlchecker.modules.AModuleConfig;
import com.trianguloy.urlchecker.modules.AModuleData;
import com.trianguloy.urlchecker.modules.AModuleDialog;
import com.trianguloy.urlchecker.modules.DescriptionConfig;
import com.trianguloy.urlchecker.modules.companions.PatternCatalog;
import com.trianguloy.urlchecker.url.UrlData;
import com.trianguloy.urlchecker.utilities.AndroidUtils;
@ -46,7 +46,36 @@ public class PatternModule extends AModuleData {
@Override
public AModuleConfig getConfig(ConfigActivity cntx) {
return new DescriptionConfig(R.string.mPttrn_desc);
return new PatternConfig(cntx);
}
}
class PatternConfig extends AModuleConfig implements View.OnClickListener {
private final PatternCatalog catalog;
public PatternConfig(Activity cntx) {
catalog = new PatternCatalog(cntx);
}
@Override
public boolean canBeEnabled() {
return true;
}
@Override
public int getLayoutId() {
return R.layout.config_patterns;
}
@Override
public void onInitialize(View views) {
views.findViewById(R.id.button).setOnClickListener(this);
}
@Override
public void onClick(View view) {
catalog.showEditor();
}
}
@ -55,8 +84,11 @@ class PatternDialog extends AModuleDialog implements View.OnClickListener {
private TextView txt_pattern;
private LinearLayout box;
private final PatternCatalog catalog;
public PatternDialog(MainDialog dialog) {
super(dialog);
catalog = new PatternCatalog(dialog);
}
@Override
@ -76,22 +108,26 @@ class PatternDialog extends AModuleDialog implements View.OnClickListener {
String url = urlData.url;
// for each pattern
JSONObject patterns = PatternCatalog.getBuiltIn(getActivity());
JSONObject patterns = catalog.getCatalog();
for (String pattern : JavaUtilities.toList(patterns.keys())) {
JSONObject data = patterns.optJSONObject(pattern);
if (data == null) continue;
if (!data.optBoolean("enabled")) continue;
String regex = data.optString("regex", "(?!)");
if (url.matches(regex)) {
String replacement = data.has("replacement") ? data.optString("replacement") : null;
if (replacement != null) {
replacement = url.replaceAll(regex, replacement);
if (data.optBoolean("automatic")) {
setUrl(replacement);
return;
try {
JSONObject data = patterns.optJSONObject(pattern);
if (data == null) continue;
if (!data.optBoolean("enabled", true)) continue;
String regex = data.optString("regex", "(?!)");
if (url.matches(regex)) {
String replacement = data.has("replacement") ? data.optString("replacement") : null;
if (replacement != null) {
replacement = url.replaceAll(regex, replacement);
if (data.optBoolean("automatic")
&& setUrl(replacement)) {
return;
}
messages.add(Pair.create(pattern, replacement));
}
}
messages.add(Pair.create(pattern, replacement));
} catch (Exception e) {
e.printStackTrace();
}
}

View File

@ -1,5 +1,8 @@
package com.trianguloy.urlchecker.utilities;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@ -20,4 +23,16 @@ public class JavaUtilities {
}
return list;
}
/**
* Converts a string into a json object, returns empty on failure
*/
public static JSONObject toJson(String content) {
try {
return new JSONObject(content);
} catch (JSONException e) {
// invalid catalog, return empty
return new JSONObject();
}
}
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/mPttrn_desc" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/mClear_edit" />
</LinearLayout>

View File

@ -41,6 +41,7 @@ Translation help from: Tiago Carmo, Ilithy, Idris."</string>
<string name="mPttrn_noSchemeHttp">Missing http scheme.</string>
<string name="mPttrn_noSchemeHttps">Missing https scheme.</string>
<string name="mPttrn_ok">No issues found</string>
<string name="mPttrn_editor">Here you can edit or add new pattern rules. Note: if you edit the rules, app updates will not add new rules (if any).</string>
<string name="mOpen_name"><![CDATA[Open & Share]]></string>
<string name="mOpen_desc">"Contains the following buttons (left to right):