Skip to content

Commit

Permalink
feat: remote page preview rules
Browse files Browse the repository at this point in the history
  • Loading branch information
LiuYi0526 committed May 5, 2024
2 parents 3663986 + a950991 commit bee7c51
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 11 deletions.
20 changes: 10 additions & 10 deletions TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@
import android.text.style.ImageSpan;
import android.text.style.URLSpan;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;
import android.util.Property;
import android.util.SparseArray;
Expand All @@ -100,7 +99,6 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.EditorInfo;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
Expand Down Expand Up @@ -169,13 +167,11 @@
import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.NotificationsController;
import org.telegram.messenger.PushListenerController;
import org.telegram.messenger.R;
import org.telegram.messenger.SecretChatHelper;
import org.telegram.messenger.SendMessagesHelper;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.TranslateController;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
Expand Down Expand Up @@ -274,7 +270,6 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
Expand All @@ -290,6 +285,7 @@
import tw.nekomimi.nekogram.NekoConfig;
import tw.nekomimi.nekogram.NekoXConfig;
import tw.nekomimi.nekogram.helpers.remote.EmojiHelper;
import tw.nekomimi.nekogram.helpers.remote.PagePreviewRulesHelper;
import tw.nekomimi.nekogram.parts.MessageTransKt;
import tw.nekomimi.nekogram.parts.PollTransUpdatesKt;
import tw.nekomimi.nekogram.settings.NekoSettingsActivity;
Expand All @@ -302,7 +298,6 @@
import tw.nekomimi.nekogram.utils.PGPUtil;
import tw.nekomimi.nekogram.utils.ProxyUtil;
import tw.nekomimi.nekogram.utils.TelegramUtil;
import tw.nekomimi.nekogram.utils.VibrateUtil;
import xyz.nextalone.nagram.NaConfig;
import xyz.nextalone.nagram.helper.DoubleTap;
import xyz.nextalone.nagram.helper.MessageHelper;
Expand Down Expand Up @@ -13375,10 +13370,15 @@ public void searchLinks(final CharSequence charSequence, final boolean force) {
}

final TLRPC.TL_messages_getWebPagePreview req = new TLRPC.TL_messages_getWebPagePreview();
if (textToCheck instanceof String) {
req.message = (String) textToCheck;
} else {
req.message = textToCheck.toString();
// na: page preview rules
try {
req.message = PagePreviewRulesHelper.getInstance().doRegex(textToCheck);
} catch (Exception ignored) {
if (textToCheck instanceof String) {
req.message = (String) textToCheck;
} else {
req.message = textToCheck.toString();
}
}
if (foundWebPage != null && req.message.equals(foundWebPage.displayedText)) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@
import tw.nekomimi.nekogram.InternalUpdater;
import tw.nekomimi.nekogram.helpers.SettingsHelper;
import tw.nekomimi.nekogram.helpers.remote.EmojiHelper;
import tw.nekomimi.nekogram.helpers.remote.PagePreviewRulesHelper;
import tw.nekomimi.nekogram.helpers.remote.PeerColorHelper;
import tw.nekomimi.nekogram.helpers.remote.UpdateHelper;
import tw.nekomimi.nekogram.helpers.remote.WallpaperHelper;
Expand Down Expand Up @@ -1061,6 +1062,7 @@ public void onViewDetachedFromWindow(View v) {
EmojiHelper.getInstance().checkEmojiPacks();
WallpaperHelper.getInstance().checkWallPaper();
PeerColorHelper.getInstance().checkPeerColor();
PagePreviewRulesHelper.getInstance().checkPagePreviewRules();
BackupAgent.requestBackup(this);

RestrictedLanguagesSelectActivity.checkRestrictedLanguages(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
package tw.nekomimi.nekogram.helpers.remote;

import android.text.TextUtils;
import android.util.Base64;

import org.json.JSONException;
import org.json.JSONObject;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.tgnet.AbstractSerializedData;
import org.telegram.tgnet.SerializedData;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PagePreviewRulesHelper extends BaseRemoteHelper {
private static final String PAGE_PREVIEW_TAG = "pagepreview";
private static volatile PagePreviewRulesHelper Instance;
private final ArrayList<DomainInfo> domains = new ArrayList<>();
private final HashMap<String, DomainInfo> domainsMap = new HashMap<>();
private boolean loading = false;

public static PagePreviewRulesHelper getInstance() {
PagePreviewRulesHelper localInstance = Instance;
if (localInstance == null) {
synchronized (PagePreviewRulesHelper.class) {
localInstance = Instance;
if (localInstance == null) {
Instance = localInstance = new PagePreviewRulesHelper();
}
return localInstance;
}
}
return localInstance;
}

@Override
protected void onError(String text, Delegate delegate) {

}

@Override
protected String getTag() {
return PAGE_PREVIEW_TAG;
}

@Override
protected void onLoadSuccess(ArrayList<JSONObject> responses, Delegate delegate) {
var tag = getTag();
var json = responses.size() > 0 ? responses.get(0) : null;
if (json == null) {
preferences.edit()
.remove(tag + "_update_time")
.remove(tag)
.apply();
return;
}

try {
ArrayList<DomainInfo> domainInfo = new ArrayList<>();
var array = json.getJSONArray("domains");

for (int i = 0; i < array.length(); i++) {
var obj = array.getJSONObject(i);
String domain = obj.getString("domain");
var rules = obj.getJSONArray("rules");
ArrayList<DomainRule> domainRules = new ArrayList<>();
for (int j = 0; j < rules.length(); j++) {
var obj1 = rules.getJSONObject(j);
var rule = new DomainRule(
obj1.getString("regex"),
obj1.getString("replace")
);
domainRules.add(rule);
}
var info = new DomainInfo(
domain,
domainRules
);
domainInfo.add(info);
}

domains.clear();
domains.addAll(domainInfo);
domainsMap.clear();
for (DomainInfo info : domains) {
domainsMap.put(info.domain, info);
}
savePagePreviewRules();
} catch (JSONException e) {
FileLog.e(e);
}
}

public void loadPagePreviewRules() {
var tag = getTag();
String list = preferences.getString(tag, "");
domains.clear();
domainsMap.clear();
if (!TextUtils.isEmpty(list)) {
byte[] bytes = Base64.decode(list, Base64.DEFAULT);
SerializedData data = new SerializedData(bytes);
int count = data.readInt32(false);
for (int a = 0; a < count; a++) {
DomainInfo info = DomainInfo.deserialize(data);
domains.add(info);
domainsMap.put(info.domain, info);
}
data.cleanup();
}
}

public void savePagePreviewRules() {
var tag = getTag();
SerializedData serializedData = new SerializedData();
serializedData.writeInt32(domains.size());
for (DomainInfo info : domains) {
info.serializeToStream(serializedData);
}
preferences.edit()
.putLong(tag + "_update_time", System.currentTimeMillis())
.putString(tag, Base64.encodeToString(serializedData.toByteArray(), Base64.NO_WRAP | Base64.NO_PADDING))
.apply();
serializedData.cleanup();
}

public boolean needUpdate() {
var tag = getTag();
long oldTime = preferences.getLong(tag + "_update_time", 0L);
long nowTime = System.currentTimeMillis();
int TTL = 15 * 60;
return oldTime + TTL <= nowTime;
}

public void checkPagePreviewRules() {
if (loading) {
return;
}
loading = true;
loadPagePreviewRules();
if (needUpdate()) {
load();
}
loading = false;
}

public String doRegex(CharSequence textToCheck) {
String oldUrl;
if (textToCheck instanceof String) {
oldUrl = (String) textToCheck;
} else {
oldUrl = textToCheck.toString();
}
String host = AndroidUtilities.getHostAuthority(oldUrl.toLowerCase());
DomainInfo info = domainsMap.get(host);
if (info == null) {
return oldUrl;
}
for (DomainRule rule : info.rules) {
Pattern regex = rule.getRegexPattern();
Matcher matcher = regex.matcher(oldUrl);
if (matcher.find()) {
oldUrl = matcher.replaceAll(rule.replace);
}
}
return oldUrl;
}

public static class DomainRule {
public String regex;
public String replace;

public DomainRule() {}

public DomainRule(String regex, String replace) {
this.regex = regex;
this.replace = replace;
}

public Pattern getRegexPattern() {
return Pattern.compile(regex);
}

public static DomainRule deserialize(AbstractSerializedData stream) {
DomainRule domainRule = new DomainRule();
domainRule.regex = stream.readString(false);
domainRule.replace = stream.readString(false);
return domainRule;
}

public void serializeToStream(AbstractSerializedData serializedData) {
serializedData.writeString(regex);
serializedData.writeString(replace);
}
}

public static class DomainInfo {
public String domain;
public ArrayList<DomainRule> rules;

public DomainInfo() {}

public DomainInfo(String domain, ArrayList<DomainRule> rules) {
this.domain = domain;
this.rules = rules;
}

public static DomainInfo deserialize(AbstractSerializedData stream) {
DomainInfo domainInfo = new DomainInfo();
domainInfo.domain = stream.readString(false);
int count = stream.readInt32(false);
ArrayList<DomainRule> rules = new ArrayList<>();
for (int a = 0; a < count; a++) {
DomainRule rule = DomainRule.deserialize(stream);
rules.add(rule);
}
domainInfo.rules = rules;
return domainInfo;
}

public void serializeToStream(AbstractSerializedData serializedData) {
serializedData.writeString(domain);
serializedData.writeInt32(rules.size());
for (DomainRule rule : rules) {
rule.serializeToStream(serializedData);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ protected void onLoadSuccess(ArrayList<JSONObject> responses, Delegate delegate)
savePeerColorInfo();
} catch (JSONException e) {
FileLog.e(e);
delegate.onTLResponse(null, e.getLocalizedMessage());
}
}

Expand Down

0 comments on commit bee7c51

Please sign in to comment.