extract data processing logic

This commit is contained in:
Miao Wang 2024-04-15 12:33:27 +08:00
parent bc4593151f
commit 295d055537
4 changed files with 133 additions and 114 deletions

View File

@ -25,7 +25,7 @@
href="{{url}}" title="{{description}}"
{% endraw %}{% else %}{% raw %}
data-bs-toggle="popover" data-bs-trigger="hover" data-bs-placement="right"
:data-bs-content="mir.description" :href="getURL(mir)" :aria-label="mir.name + ', ' + mir.description"
:data-bs-content="mir.description" :href="mir.url" :aria-label="mir.name + ', ' + mir.description"
v-with-popover
{% endraw %}{% endif %}
>

View File

@ -6,41 +6,18 @@ import BootStrapPopover from "bootstrap/js/dist/popover";
import SearchBox from "./SearchBox.vue";
import UpdateField from "./UpdateField.vue";
import { useMirrorList } from "../lib/mirrorList";
import processingHandlers from "../lib/mirrorListDataProcessing";
const new_mirrors = Object.fromEntries(
globalOptions.new_mirrors.map((x) => [x, true]),
);
const unlisted = globalOptions.unlisted_mirrors;
const forceHelp = Object.fromEntries(
globalOptions.force_redirect_help_mirrors.map((m) => [m, true]),
);
const descriptions = Object.fromEntries(
globalOptions.mirror_desc.map((m) => [m.name, m.desc]),
);
const { unlistedMirrors: unlisted, genMainMirrorList } =
processingHandlers(globalOptions);
const rawMirrorList = useMirrorList(unlisted);
const mirrorList = computed(() => {
return rawMirrorList.value
.filter((d) => !(d.status == "disabled"))
.map((d) => ({
...d,
url: forceHelp[d.name] ? HelpPages[d.name] : d.url,
help_url: HelpPages[d.name],
is_new: Boolean(new_mirrors[d.name]),
description: descriptions[d.name],
github_release: d.url && d.url.startsWith("/github-release/"),
}));
return genMainMirrorList(rawMirrorList.value, HelpPages);
});
const filter = ref("");
const getURL = (mir) => {
if (mir.url !== undefined) {
return mir.url;
}
return `/${mir.name}/`;
};
const filteredMirrorList = computed(() => {
var filterText = filter.value.toLowerCase();
return mirrorList.value.filter((m) => {

View File

@ -1,9 +1,9 @@
import { TUNASYNC_JSON_PATH } from "../lib/consts";
import { options as globalOptions } from "virtual:jekyll-data";
import { ref, onMounted, nextTick } from "vue";
import { format as TimeAgoFormat } from "timeago.js";
import processingHandlers from "../lib/mirrorListDataProcessing";
const label_map = globalOptions.label_map;
const { postProcessStatusData } = processingHandlers(globalOptions);
export const useMirrorList = (additional = []) => {
const mirrorList = ref([]);
@ -16,10 +16,7 @@ export const useMirrorList = (additional = []) => {
try {
const res = await fetch(TUNASYNC_JSON_PATH);
const status_data = await res.json();
const processed = status_data
.concat(additional)
.map((d) => processMirrorItem(d));
mirrorList.value = sortAndUniqMirrors(processLinkItem(processed));
mirrorList.value = postProcessStatusData(status_data, additional);
} catch (e) {
throw e;
} finally {
@ -43,83 +40,3 @@ export const useMirrorList = (additional = []) => {
return mirrorList;
};
const processLinkItem = (mirrors) => {
var processed = [];
for (let d of mirrors) {
if (d.link_to === undefined) {
processed.push(d);
continue;
}
for (const target of mirrors) {
if (d.link_to === target.name) {
d.status = target.status;
d.label = target.label;
d.upstream = target.upstream;
d.show_status = target.show_status;
d.last_update = target.last_update;
d.last_update_ago = target.last_update_ago;
d.last_ended = target.last_ended;
d.last_ended_ago = target.last_ended_ago;
d.last_schedule = target.last_schedule;
d.last_schedule_ago = target.last_schedule_ago;
processed.push(d);
break;
}
}
}
return processed;
};
const stringifyTime = (ts) => {
const date = new Date(ts * 1000);
let str = "";
let ago = "";
if (date.getFullYear() > 2000) {
str =
`${("000" + date.getFullYear()).slice(-4)}-${("0" + (date.getMonth() + 1)).slice(-2)}-${("0" + date.getDate()).slice(-2)}` +
` ${("0" + date.getHours()).slice(-2)}:${("0" + date.getMinutes()).slice(-2)}`;
ago = TimeAgoFormat(date);
} else {
str = "0000-00-00 00:00";
ago = "Never";
}
return [str, ago];
};
const processMirrorItem = (d) => {
if (d.is_master === undefined) {
d.is_master = true;
}
if (d.link_to !== undefined) {
return d;
}
d.label = label_map[d.status];
d.show_status = d.status != "success";
// Strip the second component of last_update
[d.last_update, d.last_update_ago] = stringifyTime(d.last_update_ts);
[d.last_ended, d.last_ended_ago] = stringifyTime(d.last_ended_ts);
[d.last_started, d.last_started_ago] = stringifyTime(d.last_started_ts);
[d.next_schedule, d.next_schedule_ago] = stringifyTime(d.next_schedule_ts);
return d;
};
const sortAndUniqMirrors = (mirs) => {
mirs.sort((a, b) => {
return a.name < b.name ? -1 : 1;
});
return mirs.reduce((acc, cur) => {
if (acc.length > 1 && acc[acc.length - 1].name == cur.name) {
if (acc[acc.length - 1].last_update_ts && cur.last_update_ts) {
if (acc[acc.length - 1].last_update_ts < cur.last_update_ts) {
acc[acc.length - 1] = cur;
}
} else if (cur.last_update_ts) {
acc[acc.length - 1] = cur;
}
} else {
acc.push(cur);
}
return acc;
}, []);
};

View File

@ -0,0 +1,125 @@
import { format as TimeAgoFormat } from "timeago.js";
export default function (globalOptions) {
const label_map = globalOptions.label_map;
const new_mirrors = Object.fromEntries(
globalOptions.new_mirrors.map((x) => [x, true]),
);
const unlisted = globalOptions.unlisted_mirrors;
const forceHelp = Object.fromEntries(
globalOptions.force_redirect_help_mirrors.map((m) => [m, true]),
);
const descriptions = Object.fromEntries(
globalOptions.mirror_desc.map((m) => [m.name, m.desc]),
);
const processLinkItem = (mirrors) => {
var processed = [];
for (let d of mirrors) {
if (d.link_to === undefined) {
processed.push(d);
continue;
}
for (const target of mirrors) {
if (d.link_to === target.name) {
d.status = target.status;
d.label = target.label;
d.upstream = target.upstream;
d.show_status = target.show_status;
d.last_update = target.last_update;
d.last_update_ago = target.last_update_ago;
d.last_ended = target.last_ended;
d.last_ended_ago = target.last_ended_ago;
d.last_schedule = target.last_schedule;
d.last_schedule_ago = target.last_schedule_ago;
processed.push(d);
break;
}
}
}
return processed;
};
const stringifyTime = (ts) => {
const date = new Date(ts * 1000);
let str = "";
let ago = "";
if (date.getFullYear() > 2000) {
str =
`${("000" + date.getFullYear()).slice(-4)}-${("0" + (date.getMonth() + 1)).slice(-2)}-${("0" + date.getDate()).slice(-2)}` +
` ${("0" + date.getHours()).slice(-2)}:${("0" + date.getMinutes()).slice(-2)}`;
ago = TimeAgoFormat(date);
} else {
str = "0000-00-00 00:00";
ago = "Never";
}
return [str, ago];
};
const processMirrorItem = (d) => {
if (d.is_master === undefined) {
d.is_master = true;
}
if (d.link_to !== undefined) {
return d;
}
d.label = label_map[d.status];
d.show_status = d.status != "success";
// Strip the second component of last_update
[d.last_update, d.last_update_ago] = stringifyTime(d.last_update_ts);
[d.last_ended, d.last_ended_ago] = stringifyTime(d.last_ended_ts);
[d.last_started, d.last_started_ago] = stringifyTime(d.last_started_ts);
[d.next_schedule, d.next_schedule_ago] = stringifyTime(d.next_schedule_ts);
return d;
};
const sortAndUniqMirrors = (mirs) => {
mirs.sort((a, b) => {
return a.name < b.name ? -1 : 1;
});
return mirs.reduce((acc, cur) => {
if (acc.length > 1 && acc[acc.length - 1].name == cur.name) {
if (acc[acc.length - 1].last_update_ts && cur.last_update_ts) {
if (acc[acc.length - 1].last_update_ts < cur.last_update_ts) {
acc[acc.length - 1] = cur;
}
} else if (cur.last_update_ts) {
acc[acc.length - 1] = cur;
}
} else {
acc.push(cur);
}
return acc;
}, []);
};
const postProcessStatusData = (status_data, additional) => {
const processed = status_data
.concat(additional)
.map((d) => processMirrorItem(d));
return sortAndUniqMirrors(processLinkItem(processed));
};
const genMainMirrorList = (status_data, helpPages) => {
return status_data
.filter((d) => !(d.status == "disabled"))
.map((d) => ({
...d,
url: forceHelp[d.name]
? helpPages[d.name]
: d.url
? d.url
: `/${d.name}/`,
help_url: helpPages[d.name],
is_new: Boolean(new_mirrors[d.name]),
description: descriptions[d.name],
github_release: d.url && d.url.startsWith("/github-release/"),
}));
};
return {
postProcessStatusData,
unlistedMirrors: unlisted,
genMainMirrorList,
};
}