From 295d055537fcba99124bd4b921928ff5a57225dd Mon Sep 17 00:00:00 2001 From: Miao Wang Date: Mon, 15 Apr 2024 12:33:27 +0800 Subject: [PATCH] extract data processing logic --- _includes/main-mirror-list.html | 2 +- _src/components/MainMirrorList.vue | 31 +------ _src/lib/mirrorList.js | 89 +------------------ _src/lib/mirrorListDataProcessing.js | 125 +++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 114 deletions(-) create mode 100644 _src/lib/mirrorListDataProcessing.js diff --git a/_includes/main-mirror-list.html b/_includes/main-mirror-list.html index c97efd3..0db01bc 100644 --- a/_includes/main-mirror-list.html +++ b/_includes/main-mirror-list.html @@ -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 %} > diff --git a/_src/components/MainMirrorList.vue b/_src/components/MainMirrorList.vue index 1548e60..262d0ad 100644 --- a/_src/components/MainMirrorList.vue +++ b/_src/components/MainMirrorList.vue @@ -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) => { diff --git a/_src/lib/mirrorList.js b/_src/lib/mirrorList.js index 669cb44..4529091 100644 --- a/_src/lib/mirrorList.js +++ b/_src/lib/mirrorList.js @@ -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; - }, []); -}; diff --git a/_src/lib/mirrorListDataProcessing.js b/_src/lib/mirrorListDataProcessing.js new file mode 100644 index 0000000..6f96b8b --- /dev/null +++ b/_src/lib/mirrorListDataProcessing.js @@ -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, + }; +}