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,
+ };
+}