Skip to content

Commit

Permalink
Part two of unifying the rules importer. Adding import text and file …
Browse files Browse the repository at this point in the history
…capability from Switchy to import modal. Closes #286
  • Loading branch information
salarcode committed Mar 5, 2024
1 parent 12f5304 commit a38519f
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 339 deletions.
8 changes: 7 additions & 1 deletion src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,10 @@
"message": "Import Rules"
},
"settingsImportRulesSelectButton": {
"message": "Rule Backup File"
"message": "Rules Backup File"
},
"settingsImportRulesText": {
"message": "Rules Backup Text"
},
"settingsImportRulesFrom": {
"message": "From"
Expand Down Expand Up @@ -545,6 +548,9 @@
"settingsImportRulesFailed": {
"message": "Failed to import the file."
},
"settingsImportRulesTextIsEmpty": {
"message": "Please enter rules in the box"
},
"settingsServerNameRequired": {
"message": "Specify the name of the server!"
},
Expand Down
34 changes: 17 additions & 17 deletions src/core/SubscriptionUpdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { ProxyImporter } from "../lib/ProxyImporter";
import { SettingsOperation } from "./SettingsOperation";
import { RuleImporter } from "../lib/RuleImporter";
import { ProxyEngine } from "./ProxyEngine";
import { ProxyRulesSubscription, ProxyServer, SubscriptionProxyRule, SubscriptionStats } from "./definitions";
import { ImportedProxyRule, ProxyRulesSubscription, ProxyServer, SubscriptionStats } from "./definitions";

export class SubscriptionUpdater {
private static serverSubscriptionTimers: SubscriptionTimerType[] = [{ timerId: null, subscriptionId: null, refreshRate: null }];
Expand Down Expand Up @@ -270,22 +270,22 @@ export class SubscriptionUpdater {
subscription.stats = new SubscriptionStats();
}

RuleImporter.readRulesSubscriptionFromServer(subscription,
function (response: {
success: boolean,
message: string,
result: {
whiteList: SubscriptionProxyRule[],
blackList: SubscriptionProxyRule[]
}
}) {
if (!response) return;

if (response.success) {

subscription.proxyRules = response.result.blackList;
subscription.whitelistRules = response.result.whiteList;
subscription.totalCount = response.result.blackList.length + response.result.whiteList.length;
RuleImporter.readFromServerAndImport(subscription,
(importResult: {
success: boolean;
message: string;
rules: {
whiteList: ImportedProxyRule[];
blackList: ImportedProxyRule[];
};
}) => {
if (!importResult) return;

if (importResult.success) {

subscription.proxyRules = importResult.rules.blackList;
subscription.whitelistRules = importResult.rules.whiteList;
subscription.totalCount = importResult.rules.blackList.length + importResult.rules.whiteList.length;

SubscriptionStats.updateStats(subscription.stats, true);

Expand Down
20 changes: 19 additions & 1 deletion src/core/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,7 @@ export interface IExternalRulesConfig {
applyProxy: SpecialRequestApplyProxyMode;
}

export class ProxyRulesSubscription {
export class ProxyRulesSubscription implements IExternalRulesConfig {
constructor() {
this.id = Utils.getNewUniqueIdString();
}
Expand Down Expand Up @@ -1131,6 +1131,24 @@ export class ProxyRulesSubscription {
}
}

export class ProxyRulesImportFromUI implements IExternalRulesConfig {
url: string;
username: string;
password: string;
obfuscation: string;
format: ExternalRulesFormat;
applyProxy: SpecialRequestApplyProxyMode;

constructor() {
this.url = null;
this.obfuscation = null;
this.format = ExternalRulesFormat.AutoProxy;
this.applyProxy = SpecialRequestApplyProxyMode.CurrentProxy;
this.username = null;
this.password = null;
}
}

export class UpdateInfo {
public updateIsAvailable: boolean = false;
public isBrowserSpecific: boolean = false;
Expand Down
179 changes: 10 additions & 169 deletions src/lib/RuleImporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { Utils } from './Utils';
import { api } from './environment';
import {
IExternalRulesConfig,
ProxyRulesSubscription,
ExternalRulesFormat,
SubscriptionProxyRule,
ProxyRule,
Expand All @@ -29,164 +28,6 @@ import { ProxyEngineSpecialRequests } from '../core/ProxyEngineSpecialRequests';
import * as ruleImporterSwitchyScript from './RuleImporterSwitchy';

export const RuleImporter = {
readRulesSubscriptionFromServer(subscription: ProxyRulesSubscription, success?: Function, fail?: Function) {
/**
* TODO: Remove and replace with generic version
*/
if (!subscription || !subscription.url) {
if (fail) fail();
return;
}
if (!success) throw 'onSuccess callback is mandatory';

function ajaxSuccess(response: any) {
if (!response) if (fail) fail();
RuleImporter.importRulesSubscriptionBatch(
response,
null,
false,
null,
(importResult: {
success: boolean;
message: string;
result: {
whiteList: SubscriptionProxyRule[];
blackList: SubscriptionProxyRule[];
};
}) => {
if (!importResult.success) {
if (fail) fail(importResult);
return;
}
if (success) success(importResult);
},
(error: Error) => {
if (fail) fail(error);
},
subscription,
);
}

if (subscription.applyProxy !== null)
// mark this request as special
ProxyEngineSpecialRequests.setSpecialUrl(subscription.url, subscription.applyProxy);

let fetchRequest = {
method: 'GET',
headers: undefined,
};
if (subscription.username) {
let pass = atob(subscription.password);
fetchRequest.headers =
{
'Authorization': 'Basic ' + btoa(subscription.username + ':' + pass)
};
}
fetch(subscription.url, fetchRequest)
.then((response) => response.text())
.then((result) => {
ajaxSuccess(result);
})
.catch((error) => {
if (fail) fail(error);
});
},
importRulesSubscriptionBatch(
text: string | ArrayBuffer,
file: any,
append: boolean,
currentRules: any[],
success: Function,
fail?: Function,
options?: ProxyRulesSubscription,
) {
/**
* TODO: Remove and replace with generic version
*/
if (!file && !text) {
if (fail) fail();
return;
}

if (text) {
try {
doImport(text as string, options);
} catch (e) {
if (fail) fail(e);
}
} else {
let reader = new FileReader();
reader.onerror = (event) => {
if (fail) fail(event);
};
reader.onload = (event) => {
//let textFile = event.target;
let fileText = reader.result;

try {
doImport(fileText as string, options);
} catch (e) {
if (fail) fail(e);
}
};
reader.readAsText(file);
}
function doImport(text: string, options?: ProxyRulesSubscription) {
if (options.obfuscation.toLowerCase() == 'base64') {
// decode base64
text = Utils.b64DecodeUnicode(text);
}

let rules: {
whiteList: SubscriptionProxyRule[];
blackList: SubscriptionProxyRule[];
};

if (options && options.format == ExternalRulesFormat.AutoProxy) {
if (!externalAppRuleParser.GFWList.detect(text, false)) {
if (fail) fail();
return;
}
rules = externalAppRuleParser.GFWList.parse(text);
} else if (options && options.format == ExternalRulesFormat.SwitchyOmega) {
let switchyRules = externalAppRuleParser.Switchy.parseAndCompile(text);

if (!switchyRules || !switchyRules.compiled) {
if (fail) fail();
return;
}
let blackListRules = externalAppRuleParser.Switchy.convertToSubscriptionProxyRule(switchyRules.compiled);

rules = {
blackList: blackListRules,
whiteList: [],
};
} else {
if (fail) fail();
return;
}

if (append) {
if (!currentRules) currentRules = [];
// TODO:
} else {
// Total of {0} proxy rules and {1} white listed rules are returned.<br>Don't forget to save the changes.
let message = api.i18n
.getMessage('importerImportRulesSuccess')
.replace('{0}', rules.blackList.length)
.replace('{1}', rules.whiteList.length);

if (success) {
// not need for any check, return straight away
success({
success: true,
message: message,
result: rules,
});
}
}
}
},
readFromServerAndImport(rulesConfig: IExternalRulesConfig, success?: Function, fail?: Function) {
if (!rulesConfig || !rulesConfig.url) {
if (fail) fail();
Expand All @@ -203,16 +44,17 @@ export const RuleImporter = {

// ----
RuleImporter.importRulesBatch(
rulesConfig,
response,
null,
false,
null,
(importResult: {
success: boolean;
message: string;
result: {
whiteList: SubscriptionProxyRule[];
blackList: SubscriptionProxyRule[];
rules: {
whiteList: ImportedProxyRule[];
blackList: ImportedProxyRule[];
};
}) => {
if (!importResult.success) {
Expand All @@ -224,7 +66,6 @@ export const RuleImporter = {
(error: Error) => {
if (fail) fail(error);
},
rulesConfig,
);
}

Expand Down Expand Up @@ -253,13 +94,13 @@ export const RuleImporter = {
});
},
importRulesBatch(
rulesConfig: IExternalRulesConfig,
text: string | ArrayBuffer,
file: any,
append: boolean,
currentRules: ProxyRule[],
success: Function,
fail?: Function,
rulesConfig?: IExternalRulesConfig,
fail?: Function
) {
/**
* TODO: Remove and replace with generic version
Expand Down Expand Up @@ -292,8 +133,8 @@ export const RuleImporter = {
};
reader.readAsText(file);
}
function doImport(text: string, rulesConfig?: IExternalRulesConfig) {
if (rulesConfig.obfuscation.toLowerCase() == 'base64') {
function doImport(text: string, rulesConfig: IExternalRulesConfig) {
if (rulesConfig.obfuscation?.toLowerCase() == 'base64') {
// decode base64
text = Utils.b64DecodeUnicode(text);
}
Expand Down Expand Up @@ -368,7 +209,7 @@ export const RuleImporter = {
success({
success: true,
message: message,
result: rules,
rules: rules,
});
}
}
Expand All @@ -384,7 +225,7 @@ export const RuleImporter = {
success({
success: true,
message: message,
result: rules,
rules: rules,
});
}
}
Expand Down
Loading

0 comments on commit a38519f

Please sign in to comment.