Initial commit: new history

This commit is contained in:
king
2025-06-30 21:59:46 +08:00
commit cd32a8c7e5
1945 changed files with 111356 additions and 0 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,180 @@
var myhead = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1"
}
getlist()
async function getlist() {
let Return_list = await get_list()
let app_List = Return_list[0]
let all_num = Return_list[1]
let app_lin_num = app_List.length
while (all_num > app_lin_num) {
let id = app_List.slice(-1)[0].id
app_List = await get_page_id_last(app_List, id)
app_lin_num = app_List.length
}
$("Video").data = app_List;
$("Video").endRefreshing()
}
async function get_list() {
let resp = await $http.request({
method: "GET",
url: "https://mergeek.com/free/apps",
timeout: 30,
header: myhead,
})
if (resp.data && resp.data != "") {
let data = resp.data
let html = data.replace(/\n|\s|\r/g, '')
let all_num = data.match(/<p>(.*?)个/)[1]//获取限免数
all_num = Number(all_num)
let arr = html.match(/<divclass="svq-article-col"(.*?)<\/div><\/article><\/div>/g)
var data_list = []
for (const i in arr) {
let jj = arr[i].match(/class="meta-category__link">(.*?)<\/a>/)
if (jj != null) {
data_list.push({
img: {
src: arr[i].match(/<imgalt=''src='(.*?)'class='avataravatar-60photoavatar-img'/)[1],
},
id: arr[i].match(/<divclass="svq-article-col"data-guid="(.*?)"/)[1],
url: "https://mergeek.com" + await getApp_id('https://mergeek.com/' + arr[i].match(/<divclass="friendlyWrap"><ahref="\/(.*?)"><\/a><\/div>/)[1]),
link: arr[i].match(/class="meta-category__link">(.*?)<\/a>/)[1],
present_price: arr[i].match(/>([A-Z]{4})<\/div><\/div><\/div><divclass="friendlyWrap"/)[1],
pm: {
text: arr[i].match(/data-fancybox="gallery-23"data-caption="(.*?)">/)[1],
},
})
}
}
console.log("限免列表:" + JSON.stringify(data_list));
console.log("限免数量:" + all_num);
return [data_list, all_num];
}
}
async function get_page_id_last(app_List, id) {
let resp = await $http.request({
method: "GET",
url: `https://mergeek.com/free/apps?last_id=${id}`,
timeout: 30,
header: {
"X-Requested-With": "XMLHttpRequest",
},
})
if (resp.data.data && resp.data.data.apps != "") {
for (const i in resp.data.data.apps) {
app_List.push({
img: {
src: resp.data.data.apps[i].icon
},
id: resp.data.data.apps[i].id,
url: "https://apps.apple.com/cn/app/hibido-pro-todo-calendar-note/id" + resp.data.data.apps[i].appstore_id,
link: resp.data.data.apps[i].classifications,
present_price: resp.data.data.apps[i].present_price,
pm: {
text: resp.data.data.apps[i].name
},
})
}
return app_List
}
}
async function getApp_id(url) {
let resp = await $http.request({
method: "GET",
url: url,
timeout: 30,
header: myhead,
})
if (resp.data && resp.data != "") {
let arr = resp.data.replace(/\n|\s|\r/g, '')
// console.log(arr)
return arr.match(/<divclass="downloadMenu"><divclass="downloadMenuItem"><ahref="(.*?)"target="_top">跳转<\/a><\/div>/)[1]
}
}
var changeList = [{"name": "每日限免", "id": "1"}]
$ui.render({
props: {
title: "app每日限免"
},
views: [
{
type: "menu",
props: {
id: "menu",
items: changeList.map(function (item) {
return item.name
})
},
layout: (make, view) => {
make.left.top.right.equalTo(0)
make.height.equalTo(50)
},
events: {
changed: function (sender) {
$cache.set("type", changeList[sender.index].id)
}
}
},
{
type: "matrix",
props: {
id: "Video",
itemHeight: 185,//整个方格高度
columns: 3,
spacing: 7,
reorder: true,
info: 'dd',
template: [{
type: "image",
props: {
id: "img",
radius: 30,
},
layout: (make, view) => {
make.centerX.equalTo(view.super)
make.height.equalTo(110)
make.width.equalTo(110)
}
},
{
type: "label",
props: {
id: "pm",
align: $align.center,
lines: 0,
font: $font("bold", 15),
},
layout: (make, view) => {
make.top.equalTo($("img").bottom).equalTo(0)//offset偏移量
make.right.left.inset(0)
}
}
]
},
layout: (make, view) => {
make.top.equalTo($("menu").bottom)
make.bottom.left.right.inset(0)
},
events: {
didSelect: function (sender, indexPath, data) {
$app.openURL(data.url)
}
}
},
]
})

View File

@ -0,0 +1,79 @@
/**
* 作者fmz200修改自Toperlock的oil_price.js
* 作用:定时查询油价
* 定时QX导入订阅 https://raw.githubusercontent.com/fmz200/wool_scripts/main/boxjs/fmz200_gallery.json
* 更新2023-06-08 20:30
* 使用搭配BoxJS随时更改地区 https://raw.githubusercontent.com/fmz200/wool_scripts/main/boxjs/fmz200.boxjs.json
* [task_local]
* 0 8 * * * https://raw.githubusercontent.com/fmz200/wool_scripts/main/QuantumultX/scripts/oil_price.js, tag=今日油价, img-url=https://raw.githubusercontent.com/fmz200/wool_scripts/main/icons/apps/oil.png, enabled=true
*/
// 默认重庆
var region = $prefs.valueForKey('oil_price_region') || "chongqing";
const query_addr = `http://m.qiyoujiage.com/${region}.shtml`;
const myRequest = {
url: query_addr,
headers: {
'referer': 'http://m.qiyoujiage.com/',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
}
};
$task.fetch(myRequest).then(response => {
console.log(`油价查询开始:${region}`);
const data = response.body;
const reg_price = /<dl>[\s\S]+?<dt>(.*油)<\/dt>[\s\S]+?<dd>(.*)\(元\)<\/dd>/gm;
var prices = [];
var m = null;
while ((m = reg_price.exec(data)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === reg_price.lastIndex) {
reg_price.lastIndex++;
}
prices.push({
name: m[1],
value: `${m[2]} 元/L`
});
}
var adjust_date = '';
var adjust_trend = '';
var adjust_value = '';
const reg_adjust_tips = /<div class="tishi"> <span>(.*)<\/span><br\/>([\s\S]+?)<br\/>/;
const adjust_tips_match = data.match(reg_adjust_tips);
if (adjust_tips_match && adjust_tips_match.length === 3) {
adjust_date = adjust_tips_match[1].split('价')[1].slice(0, -2);
adjust_value = adjust_tips_match[2];
adjust_trend = (adjust_value.indexOf('下调') > -1 || adjust_value.indexOf('下跌') > -1) ? '↓' : '↑';
const adjust_value_re = /([\d\.]+)元\/升-([\d\.]+)元\/升/;
const adjust_value_re2 = /[\d\.]+元\/吨/;
const adjust_value_match = adjust_value.match(adjust_value_re);
if (adjust_value_match && adjust_value_match.length === 3) {
adjust_value = `${adjust_value_match[1]}-${adjust_value_match[2]}元/L`;
} else {
const adjust_value_match2 = adjust_value.match(adjust_value_re2);
if (adjust_value_match2) {
adjust_value = adjust_value_match2[0];
}
}
}
const friendly_tips = `下次${adjust_date}预计\t${adjust_trend} ${adjust_value}`;
if (prices.length !== 4) {
console.log(`解析油价信息失败, URL=${query_addr}`);
$notify("油价查询", "解析失败", "请检查脚本或反馈给开发者");
$done({});
} else {
const content = `${prices[0].name}\t\t\t${prices[0].value}\n${prices[1].name}\t\t\t${prices[1].value}\n${prices[2].name}\t\t\t${prices[2].value}\n${prices[3].name}\t\t\t${prices[3].value}`;
$notify("油价查询", `${friendly_tips}`, content);
console.log(`油价查询结果:\n${content}`);
$done({});
}
}, reason => {
console.log(`查询油价信息失败, URL=${query_addr}`);
$notify("油价查询", "请求失败", "请检查网络或反馈给开发者");
$done({});
});

View File

@ -0,0 +1,96 @@
/**
* auther@fmz200
* 作用因国内很多软件都显示IP地址且部分需要住宅IP才能生效(比如抖音)使用了代理后显示IP未知是因为代理节点是机房的IP所以写个脚本判断当前节点是不是住宅IP
*
* 配置:
* [task_local]
* event-interaction https://raw.githubusercontent.com/fmz200/wool_scripts/main/QuantumultX/scripts/server_info.js, tag=节点详情查询, img-url=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/icon/qure/color/Back.png, enabled=true
* 使用配置好以后长按节点执行脚本如果节点类型的ISP进行大致的判断
* 因为显示详细ISP的网站需要付费ipinfo.io所以只能找个替代的网站www.cz88.net)
*
* http://ip-api.com/json?lang=zh-CN 返回结果:
* {
* "status": "success",
* "country": "新加坡",
* "countryCode": "SG",
* "region": "01",
* "regionName": "Central Singapore",
* "city": "新加坡",
* "zip": "048582",
* "lat": 1.28009,
* "lon": 103.851,
* "timezone": "Asia/Singapore",
* "isp": "Amazon Technologies Inc.",
* "org": "AWS EC2 (ap-southeast-1)",
* "as": "AS16509 Amazon.com, Inc.",
* "query": "13.251.43.8"
* }
**/
let message = "";
get_ip_api();
// 1、先获取当前节点的IP如果能从$environment中取到可以省略这一步
function get_ip_api() {
const url = `http://ip-api.com/json?lang=zh-CN`;
const opts = {
policy: $environment.params
};
const myRequest = {
url: url,
opts: opts,
timeout: 8000
};
$task.fetch(myRequest).then(response => {
console.log(response.statusCode + "--ip-api--\n" + response.body);
if (response.body) fetchIPInfo(response.body);
}, () => {
message = "</br></br>🛑 查询超时";
message = `<p style="text-align: center; font-family: -apple-system; font-size: large; font-weight: bold;">` + message + `</p>`;
$done({"title": " 📍 节点详情查询", "htmlMessage": message});
})
}
// 2、获取到IP后再去查询IP的详细信息
function fetchIPInfo(data) {
const url = `https://www.cz88.net/api/cz88/ip/base?ip=${JSON.parse(data).query}`;
console.log("url=" + url);
const myRequest = {
url: url,
timeout: 8000
};
$task.fetch(myRequest).then(response => {
console.log(response.statusCode + "--cz88--\n" + response.body);
if (response.body) json2info(response.body, data);
$done({"title": " 📍 节点详情查询", "htmlMessage": message});
}, reason => {
console.log(reason.error);
$done();
});
}
// 3、解析数据
function json2info(data1, data) {
console.log("开始解析数据、、、\n");
data1 = JSON.parse(data1).data;
data = JSON.parse(data);
console.log("结束解析数据,开始组装内容、、、\n");
message = "------------------------------";
// 组装每一行内容
message += "</br><b>IP</b>" + data1.ip + "</br>";
message += "</br><b>运营商(isp)</b>" + data1.isp + "</br>";
message += "</br><b>网络类型:</b>" + data1.netWorkType + "</br>";
message += "</br><b>真人概率:</b>" + data1.score + "</br>";
message += "</br><b>位置 : </b>" + data1.countryCode + "-" + data1.country + "-" + data1.province + "-" + data1.city + "-" + data1.districts + "</br>";
message += "</br><b>ZIP</b>" + data.zip + "</br>";
message += "</br><b>经纬度 : </b>" + data.lon + " / " + data.lat + "</br>";
message += "</br><b>时区 : </b>" + data.timezone + "</br>";
message += "------------------------------" + "</br>"
message += "<font color=#6959CD><b>节点</b> ➟ " + $environment.params + "</font>";
message = `<p style="text-align: center; font-family: -apple-system; font-size: large; font-weight: lighter">` + message + `</p>`;
console.log("\n" + message);
}

View File

@ -0,0 +1,63 @@
/**
* @author fmz200
* @function QuanX查询IP信息
* @date 2024-01-31 21:18:00
*/
if ($response.statusCode != 200) {
$done(null);
}
const flags = new Map([["AC", "🇦🇨"], ["AD", "🇦🇩"], ["AE", "🇦🇪"], ["AF", "🇦🇫"], ["AG", "🇦🇬"], ["AI", "🇦🇮"], ["AL", "🇦🇱"], ["AM", "🇦🇲"], ["AO", "🇦🇴"], ["AQ", "🇦🇶"], ["AR", "🇦🇷"], ["AS", "🇦🇸"], ["AT", "🇦🇹"], ["AU", "🇦🇺"], ["AW", "🇦🇼"], ["AX", "🇦🇽"], ["AZ", "🇦🇿"], ["BA", "🇧🇦"], ["BB", "🇧🇧"], ["BD", "🇧🇩"], ["BE", "🇧🇪"], ["BF", "🇧🇫"], ["BG", "🇧🇬"], ["BH", "🇧🇭"], ["BI", "🇧🇮"], ["BJ", "🇧🇯"], ["BM", "🇧🇲"], ["BN", "🇧🇳"], ["BO", "🇧🇴"], ["BR", "🇧🇷"], ["BS", "🇧🇸"], ["BT", "🇧🇹"], ["BV", "🇧🇻"], ["BW", "🇧🇼"], ["BY", "🇧🇾"], ["BZ", "🇧🇿"], ["CA", "🇨🇦"], ["CD", "🇨🇩"], ["CF", "🇨🇫"], ["CG", "🇨🇬"], ["CH", "🇨🇭"], ["CI", "🇨🇮"], ["CK", "🇨🇰"], ["CL", "🇨🇱"], ["CM", "🇨🇲"], ["CN", "🇨🇳"], ["CO", "🇨🇴"], ["CP", "🇨🇵"], ["CR", "🇨🇷"], ["CU", "🇨🇺"], ["CV", "🇨🇻"], ["CW", "🇨🇼"], ["CX", "🇨🇽"], ["CY", "🇨🇾"], ["CZ", "🇨🇿"], ["DE", "🇩🇪"], ["DG", "🇩🇬"], ["DJ", "🇩🇯"], ["DK", "🇩🇰"], ["DM", "🇩🇲"], ["DO", "🇩🇴"], ["DZ", "🇩🇿"], ["EA", "🇪🇦"], ["EC", "🇪🇨"], ["EE", "🇪🇪"], ["EG", "🇪🇬"], ["EH", "🇪🇭"], ["ER", "🇪🇷"], ["ES", "🇪🇸"], ["ET", "🇪🇹"], ["EU", "🇪🇺"], ["FI", "🇫🇮"], ["FJ", "🇫🇯"], ["FK", "🇫🇰"], ["FM", "🇫🇲"], ["FO", "🇫🇴"], ["FR", "🇫🇷"], ["GA", "🇬🇦"], ["GB", "🇬🇧"], ["GD", "🇬🇩"], ["GE", "🇬🇪"], ["GF", "🇬🇫"], ["GH", "🇬🇭"], ["GI", "🇬🇮"], ["GL", "🇬🇱"], ["GM", "🇬🇲"], ["GN", "🇬🇳"], ["GP", "🇬🇵"], ["GR", "🇬🇷"], ["GT", "🇬🇹"], ["GU", "🇬🇺"], ["GW", "🇬🇼"], ["GY", "🇬🇾"], ["HK", "🇭🇰"], ["HN", "🇭🇳"], ["HR", "🇭🇷"], ["HT", "🇭🇹"], ["HU", "🇭🇺"], ["ID", "🇮🇩"], ["IE", "🇮🇪"], ["IL", "🇮🇱"], ["IM", "🇮🇲"], ["IN", "🇮🇳"], ["IR", "🇮🇷"], ["IS", "🇮🇸"], ["IT", "🇮🇹"], ["JM", "🇯🇲"], ["JO", "🇯🇴"], ["JP", "🇯🇵"], ["KE", "🇰🇪"], ["KG", "🇰🇬"], ["KH", "🇰🇭"], ["KI", "🇰🇮"], ["KM", "🇰🇲"], ["KN", "🇰🇳"], ["KP", "🇰🇵"], ["KR", "🇰🇷"], ["KW", "🇰🇼"], ["KY", "🇰🇾"], ["KZ", "🇰🇿"], ["LA", "🇱🇦"], ["LB", "🇱🇧"], ["LC", "🇱🇨"], ["LI", "🇱🇮"], ["LK", "🇱🇰"], ["LR", "🇱🇷"], ["LS", "🇱🇸"], ["LT", "🇱🇹"], ["LU", "🇱🇺"], ["LV", "🇱🇻"], ["LY", "🇱🇾"], ["MA", "🇲🇦"], ["MC", "🇲🇨"], ["MD", "🇲🇩"], ["MG", "🇲🇬"], ["MH", "🇲🇭"], ["MK", "🇲🇰"], ["ML", "🇲🇱"], ["MM", "🇲🇲"], ["MN", "🇲🇳"], ["MO", "🇲🇴"], ["MP", "🇲🇵"], ["MQ", "🇲🇶"], ["MR", "🇲🇷"], ["MS", "🇲🇸"], ["MT", "🇲🇹"], ["MU", "🇲🇺"], ["MV", "🇲🇻"], ["MW", "🇲🇼"], ["MX", "🇲🇽"], ["MY", "🇲🇾"], ["MZ", "🇲🇿"], ["NA", "🇳🇦"], ["NC", "🇳🇨"], ["NE", "🇳🇪"], ["NF", "🇳🇫"], ["NG", "🇳🇬"], ["NI", "🇳🇮"], ["NL", "🇳🇱"], ["NO", "🇳🇴"], ["NP", "🇳🇵"], ["NR", "🇳🇷"], ["NZ", "🇳🇿"], ["OM", "🇴🇲"], ["PA", "🇵🇦"], ["PE", "🇵🇪"], ["PF", "🇵🇫"], ["PG", "🇵🇬"], ["PH", "🇵🇭"], ["PK", "🇵🇰"], ["PL", "🇵🇱"], ["PM", "🇵🇲"], ["PR", "🇵🇷"], ["PS", "🇵🇸"], ["PT", "🇵🇹"], ["PW", "🇵🇼"], ["PY", "🇵🇾"], ["QA", "🇶🇦"], ["RE", "🇷🇪"], ["RO", "🇷🇴"], ["RS", "🇷🇸"], ["RU", "🇷🇺"], ["RW", "🇷🇼"], ["SA", "🇸🇦"], ["SB", "🇸🇧"], ["SC", "🇸🇨"], ["SD", "🇸🇩"], ["SE", "🇸🇪"], ["SG", "🇸🇬"], ["SI", "🇸🇮"], ["SK", "🇸🇰"], ["SL", "🇸🇱"], ["SM", "🇸🇲"], ["SN", "🇸🇳"], ["SR", "🇸🇷"], ["ST", "🇸🇹"], ["SV", "🇸🇻"], ["SY", "🇸🇾"], ["SZ", "🇸🇿"], ["TC", "🇹🇨"], ["TD", "🇹🇩"], ["TG", "🇹🇬"], ["TH", "🇹🇭"], ["TJ", "🇹🇯"], ["TL", "🇹🇱"], ["TM", "🇹🇲"], ["TN", "🇹🇳"], ["TO", "🇹🇴"], ["TR", "🇹🇷"], ["TT", "🇹🇹"], ["TV", "🇹🇻"], ["TW", "🇨🇳"], ["TZ", "🇹🇿"], ["UA", "🇺🇦"], ["UG", "🇺🇬"], ["UK", "🇬🇧"], ["UM", "🇺🇲"], ["US", "🇺🇸"], ["UY", "🇺🇾"], ["UZ", "🇺🇿"], ["VA", "🇻🇦"], ["VC", "🇻🇨"], ["VE", "🇻🇪"], ["VG", "🇻🇬"], ["VI", "🇻🇮"], ["VN", "🇻🇳"], ["VU", "🇻🇺"], ["WS", "🇼🇸"], ["YE", "🇾🇪"], ["YT", "🇾🇹"], ["ZA", "🇿🇦"], ["ZM", "🇿🇲"], ["ZW", "🇿🇼"]]);
const city0 = "未知地区";
const isp0 = "未知服务商";
// 脚本开始
let body = $response.body;
let obj = JSON.parse(body);
const country = country_check(obj['country']);
const city = city_check(obj['city']);
// 展示在顶部开关左边第1行 格式:国旗 国家名 地区名
let title = flags.get(obj['countryCode']) + ' ' + append(country, city);
// 展示在顶部开关左边第2行 格式IP IPS
let subtitle = obj['query'] + ' ' + isp_check(obj['as']);
// 不展示
let ip = obj['query'];
// 长按节点选择“查看节点信息”时的信息
let description = '国家:' + obj['countryCode'] + ' ' + obj['country'] + '\n'
+ '地区:' + obj['region'] + ' ' + city_check(obj['regionName']) + '\n'
+ 'IP' + obj['query'] + '\n'
+ '服务商:' + obj['isp'] + '\n'
+ '经纬度:' + obj['lat'] + ' / ' + obj['lon'] + '\n'
+ '时区:' + obj['timezone'];
$done({title, subtitle, ip, description});
function country_check(para) {
return para || city0;
}
function city_check(para) {
if (!para) return city0;
// 去除所有空格
const paraWithoutSpaces = para.replace(/\s/g, '');
// 使用正则表达式检查是否全是英文字母
if (/^[a-zA-Z]+$/.test(paraWithoutSpaces)) {
return ''; // 如果全是英文字母则返回空
} else {
return para; // 否则返回 para
}
}
function isp_check(para) {
return para || isp0;
}
function area_check(para) {
return para === "中华民国" ? "台湾" : para;
}
function append(country, city) {
return country === city ? country : country + ' ' + city;
}