Repository files navigation

MirrorZ

Your next MirrorS is not MirrorS, nor MirrorSes, it's MirrorZ.

A final site for Mirror sites.

Demo

https://mirrorz.org and https://mirrors.cernet.edu.cn/list

Also legacy webpages (for w3m and noscript users) are provided in https://mirrorz.org/_/ and https://mirrors.cernet.edu.cn/_/

A speed test script oh-my-mirrorz.py is also provided. See README for more info.

Intro

Mirror sites are heterogeneous. It is hard for a single mirror to provide all mirrors, so differences occur.

For end users, this is not a good experience as they need to search for available mirrors.

To make things easy, MirrorZ is intended to include all mirrorS, so a unified interface is needed.

Data Format v1.7

A mirrorz.json in the following format describes all the data of one mirror site in MirrorZ.

{
"version": 1.7,
"site": {
"url": "https://example.org",
"logo": "https://example.org/img/logo.svg",
"logo_darkmode": "https://example.org/img/logo-white.svg",
"abbr": "EXAMPLE",
"name": "样例镜像站",
"homepage": "https://blog.example.org",
"issue": "https://github.com/example/issues",
"request": "https://github.com/example/mirror-request",
"email": "admin@example.com",
"group": "QQ: 10086 and/or Telegram @something",
"disk": "may be any string showing usage of disk, e.g. usage",
"note": "may be any string; like speed limit or connection limit",
"big": "/speedtest/1000mb.bin",
"disable": false
},
"info": [
{
"distro": "Debian",
"category": "os",
"urls": [
{
"name": "10.7.0 (amd64, CD installer with xfce)",
"url": "/debian-cd/current/amd64/iso-cd/debian-10.7.0-amd64-xfce-CD-1.iso"
}
]
}
],
"mirrors": [
{
"cname": "AOSP",
"desc": "Android 操作系统源代码",
"url": "/AOSP",
"status": "S",
"help": "/help/AOSP/",
"upstream": "https://android.googlesource.com/mirror/manifest",
"size": "596G",
"disable": false
},
{
"cname": "AUR",
"desc": "Arch Linux 用户软件库",
"url": "https://aur.tuna.tsinghua.edu.cn",
"status": "S1612195849X1612196849N",
"help": "/help/AUR/",
"upstream": "https://aur.archlinux.org/"
}
]
}

Notes

  • version is optional for version 1.x
    • previous versions of this protocol could be found in git history; protocols in v1.x are back-ward compatible
  • site provides the global info about one mirror site
    • only site.url and site.abbr are mandatory
    • site.logo should not be of format ico. Also, at least 64x64 resolution is required
    • site.logo_darkmode is used when browser uses dark mode. Note that it should be set only after site.logo is set
    • site.url should not end with slash /
    • site.big should be a valid url to a big file, used by oh-my-mirrorz.py for speed testing
    • site.disable is a boolean value, indicating whether the site is available for service. Its default value is false. If true, this site will be marked as disabled in mirrorz webpage, and mirrorz-302 will not redirect to the site
  • info is used for category view
    • all field of info is mandatory
    • info may be left empty as []
    • the name of info.distro should be agreed and have a mapping, maintained in cname.json
  • mirrors is used for list view
    • the name of mirrors.cname should be agreed and have a mapping, maintained in cname.json
    • mirrors.desc may differ for each mirror site since there are excludes for some mirror site
    • mirrors.desc may be empty
    • if mirrors.url begins with a slash /, it should be appended to site.url to form a full url
    • mirrors.url should not end with slash /
    • mirrors.status is a concat of strings of pattern [A-Z](\d+)?. Only one main status is allowed; the number of auxiliary status is not limited.
      • S1600000000: successful. (optional) last successful ended unix timestamp
      • D1600000000: pending. (optional) pending to sync unix timestamp
      • Y1600000000: syncing. (optional) start to sync unix timestamp
      • F1600000000: failed. (optional) last attempt to sync unix timestamp
      • P1600000000: paused. (optional) the unix timestamp sync stopped
      • C: reverse proxy with cache
      • R: reverse proxy without cache
      • U: unknown
      • X1600000000: (auxiliary) next scheduled sync unix timestamp
      • N1600000000: (auxiliary) new mirror. (optional) unix timestamp the repo added
      • O1600000000: (auxiliary) old successful timestamp, used only when it is syncing or failed
    • mirrors.help may be empty, or the same rule as mirrors.url
    • mirrors.upstream, mirrors.size, mirrors.disable may be empty

Developing and Contributing

Repo organization

This repo depends on other repos in this organization to provide full functionality; However, they are not submodules as we need to bump submodules whenever there is an update, which is painful. We just use the latest version of each repo when building.

For full preparation of all the repos, you should refer to the Prepare steps in Github Actions.

Note that yarn mirrorz_env prepares for https://mirrorz.org. When you are debugging, it is recommended to use yarn dev_env and yarn debug_build, which builds the site for http://localhost:1234. Other env like cngi_env and cernet_env prepares for other sites that mirrorz maintain.

Frontend

HTML/CSS

One may use

yarn --frozen-lockfile
yarn start

to start a local server. It is often convenient for debugging frontend features like html/css since auto-reload is provided by parcel.

Parser, local new static files

To debug one src/parser with new site json in static/json/site, use

yarn --frozen-lockfile
yarn half_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Legacy pages

To use static files, 404 redirection (emulate Github pages) and legacy pages, one may use

yarn --frozen-lockfile
yarn full_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Deployment

For dynamic web page part, only

yarn build

is required.

However if one also wants to deploy the static web page, one may use

yarn build
yarn legacy_build

Note that legacy_build has dependencies on files yarn build has made.

Meanwhile, to generate the complete oh-my-mirrorz.py, one should use the following command

yarn ohmymirrorz_build

If one want all parts, one can use the following command to accomplish all the steps above

yarn full_build

Misc

Currently *.json is ignored in .gitignore (not ignored in /static). If one wants to commit a json file, they should use git add -f.

Contributing

Other contributing guidelines are maintained in https://github.com/mirrorz-org/org/

About

Pods Docs

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

MirrorZ

Your next MirrorS is not MirrorS, nor MirrorSes, it's MirrorZ.

A final site for Mirror sites.

Demo

https://mirrorz.org and https://mirrors.cernet.edu.cn/list

Also legacy webpages (for w3m and noscript users) are provided in https://mirrorz.org/_/ and https://mirrors.cernet.edu.cn/_/

A speed test script oh-my-mirrorz.py is also provided. See README for more info.

Intro

Mirror sites are heterogeneous. It is hard for a single mirror to provide all mirrors, so differences occur.

For end users, this is not a good experience as they need to search for available mirrors.

To make things easy, MirrorZ is intended to include all mirrorS, so a unified interface is needed.

Data Format v1.7

A mirrorz.json in the following format describes all the data of one mirror site in MirrorZ.

{
"version": 1.7,
"site": {
"url": "https://example.org",
"logo": "https://example.org/img/logo.svg",
"logo_darkmode": "https://example.org/img/logo-white.svg",
"abbr": "EXAMPLE",
"name": "样例镜像站",
"homepage": "https://blog.example.org",
"issue": "https://github.com/example/issues",
"request": "https://github.com/example/mirror-request",
"email": "admin@example.com",
"group": "QQ: 10086 and/or Telegram @something",
"disk": "may be any string showing usage of disk, e.g. usage",
"note": "may be any string; like speed limit or connection limit",
"big": "/speedtest/1000mb.bin",
"disable": false
},
"info": [
{
"distro": "Debian",
"category": "os",
"urls": [
{
"name": "10.7.0 (amd64, CD installer with xfce)",
"url": "/debian-cd/current/amd64/iso-cd/debian-10.7.0-amd64-xfce-CD-1.iso"
}
]
}
],
"mirrors": [
{
"cname": "AOSP",
"desc": "Android 操作系统源代码",
"url": "/AOSP",
"status": "S",
"help": "/help/AOSP/",
"upstream": "https://android.googlesource.com/mirror/manifest",
"size": "596G",
"disable": false
},
{
"cname": "AUR",
"desc": "Arch Linux 用户软件库",
"url": "https://aur.tuna.tsinghua.edu.cn",
"status": "S1612195849X1612196849N",
"help": "/help/AUR/",
"upstream": "https://aur.archlinux.org/"
}
]
}

Notes

  • version is optional for version 1.x
    • previous versions of this protocol could be found in git history; protocols in v1.x are back-ward compatible
  • site provides the global info about one mirror site
    • only site.url and site.abbr are mandatory
    • site.logo should not be of format ico. Also, at least 64x64 resolution is required
    • site.logo_darkmode is used when browser uses dark mode. Note that it should be set only after site.logo is set
    • site.url should not end with slash /
    • site.big should be a valid url to a big file, used by oh-my-mirrorz.py for speed testing
    • site.disable is a boolean value, indicating whether the site is available for service. Its default value is false. If true, this site will be marked as disabled in mirrorz webpage, and mirrorz-302 will not redirect to the site
  • info is used for category view
    • all field of info is mandatory
    • info may be left empty as []
    • the name of info.distro should be agreed and have a mapping, maintained in cname.json
  • mirrors is used for list view
    • the name of mirrors.cname should be agreed and have a mapping, maintained in cname.json
    • mirrors.desc may differ for each mirror site since there are excludes for some mirror site
    • mirrors.desc may be empty
    • if mirrors.url begins with a slash /, it should be appended to site.url to form a full url
    • mirrors.url should not end with slash /
    • mirrors.status is a concat of strings of pattern [A-Z](\d+)?. Only one main status is allowed; the number of auxiliary status is not limited.
      • S1600000000: successful. (optional) last successful ended unix timestamp
      • D1600000000: pending. (optional) pending to sync unix timestamp
      • Y1600000000: syncing. (optional) start to sync unix timestamp
      • F1600000000: failed. (optional) last attempt to sync unix timestamp
      • P1600000000: paused. (optional) the unix timestamp sync stopped
      • C: reverse proxy with cache
      • R: reverse proxy without cache
      • U: unknown
      • X1600000000: (auxiliary) next scheduled sync unix timestamp
      • N1600000000: (auxiliary) new mirror. (optional) unix timestamp the repo added
      • O1600000000: (auxiliary) old successful timestamp, used only when it is syncing or failed
    • mirrors.help may be empty, or the same rule as mirrors.url
    • mirrors.upstream, mirrors.size, mirrors.disable may be empty

Developing and Contributing

Repo organization

This repo depends on other repos in this organization to provide full functionality; However, they are not submodules as we need to bump submodules whenever there is an update, which is painful. We just use the latest version of each repo when building.

For full preparation of all the repos, you should refer to the Prepare steps in Github Actions.

Note that yarn mirrorz_env prepares for https://mirrorz.org. When you are debugging, it is recommended to use yarn dev_env and yarn debug_build, which builds the site for http://localhost:1234. Other env like cngi_env and cernet_env prepares for other sites that mirrorz maintain.

Frontend

HTML/CSS

One may use

yarn --frozen-lockfile
yarn start

to start a local server. It is often convenient for debugging frontend features like html/css since auto-reload is provided by parcel.

Parser, local new static files

To debug one src/parser with new site json in static/json/site, use

yarn --frozen-lockfile
yarn half_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Legacy pages

To use static files, 404 redirection (emulate Github pages) and legacy pages, one may use

yarn --frozen-lockfile
yarn full_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Deployment

For dynamic web page part, only

yarn build

is required.

However if one also wants to deploy the static web page, one may use

yarn build
yarn legacy_build

Note that legacy_build has dependencies on files yarn build has made.

Meanwhile, to generate the complete oh-my-mirrorz.py, one should use the following command

yarn ohmymirrorz_build

If one want all parts, one can use the following command to accomplish all the steps above

yarn full_build

Misc

Currently *.json is ignored in .gitignore (not ignored in /static). If one wants to commit a json file, they should use git add -f.

Contributing

Other contributing guidelines are maintained in https://github.com/mirrorz-org/org/

About

Pods Docs

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

MirrorZ

Your next MirrorS is not MirrorS, nor MirrorSes, it's MirrorZ.

A final site for Mirror sites.

Demo

https://mirrorz.org and https://mirrors.cernet.edu.cn/list

Also legacy webpages (for w3m and noscript users) are provided in https://mirrorz.org/_/ and https://mirrors.cernet.edu.cn/_/

A speed test script oh-my-mirrorz.py is also provided. See README for more info.

Intro

Mirror sites are heterogeneous. It is hard for a single mirror to provide all mirrors, so differences occur.

For end users, this is not a good experience as they need to search for available mirrors.

To make things easy, MirrorZ is intended to include all mirrorS, so a unified interface is needed.

Data Format v1.7

A mirrorz.json in the following format describes all the data of one mirror site in MirrorZ.

{
"version": 1.7,
"site": {
"url": "https://example.org",
"logo": "https://example.org/img/logo.svg",
"logo_darkmode": "https://example.org/img/logo-white.svg",
"abbr": "EXAMPLE",
"name": "样例镜像站",
"homepage": "https://blog.example.org",
"issue": "https://github.com/example/issues",
"request": "https://github.com/example/mirror-request",
"email": "admin@example.com",
"group": "QQ: 10086 and/or Telegram @something",
"disk": "may be any string showing usage of disk, e.g. usage",
"note": "may be any string; like speed limit or connection limit",
"big": "/speedtest/1000mb.bin",
"disable": false
},
"info": [
{
"distro": "Debian",
"category": "os",
"urls": [
{
"name": "10.7.0 (amd64, CD installer with xfce)",
"url": "/debian-cd/current/amd64/iso-cd/debian-10.7.0-amd64-xfce-CD-1.iso"
}
]
}
],
"mirrors": [
{
"cname": "AOSP",
"desc": "Android 操作系统源代码",
"url": "/AOSP",
"status": "S",
"help": "/help/AOSP/",
"upstream": "https://android.googlesource.com/mirror/manifest",
"size": "596G",
"disable": false
},
{
"cname": "AUR",
"desc": "Arch Linux 用户软件库",
"url": "https://aur.tuna.tsinghua.edu.cn",
"status": "S1612195849X1612196849N",
"help": "/help/AUR/",
"upstream": "https://aur.archlinux.org/"
}
]
}

Notes

  • version is optional for version 1.x
    • previous versions of this protocol could be found in git history; protocols in v1.x are back-ward compatible
  • site provides the global info about one mirror site
    • only site.url and site.abbr are mandatory
    • site.logo should not be of format ico. Also, at least 64x64 resolution is required
    • site.logo_darkmode is used when browser uses dark mode. Note that it should be set only after site.logo is set
    • site.url should not end with slash /
    • site.big should be a valid url to a big file, used by oh-my-mirrorz.py for speed testing
    • site.disable is a boolean value, indicating whether the site is available for service. Its default value is false. If true, this site will be marked as disabled in mirrorz webpage, and mirrorz-302 will not redirect to the site
  • info is used for category view
    • all field of info is mandatory
    • info may be left empty as []
    • the name of info.distro should be agreed and have a mapping, maintained in cname.json
  • mirrors is used for list view
    • the name of mirrors.cname should be agreed and have a mapping, maintained in cname.json
    • mirrors.desc may differ for each mirror site since there are excludes for some mirror site
    • mirrors.desc may be empty
    • if mirrors.url begins with a slash /, it should be appended to site.url to form a full url
    • mirrors.url should not end with slash /
    • mirrors.status is a concat of strings of pattern [A-Z](\d+)?. Only one main status is allowed; the number of auxiliary status is not limited.
      • S1600000000: successful. (optional) last successful ended unix timestamp
      • D1600000000: pending. (optional) pending to sync unix timestamp
      • Y1600000000: syncing. (optional) start to sync unix timestamp
      • F1600000000: failed. (optional) last attempt to sync unix timestamp
      • P1600000000: paused. (optional) the unix timestamp sync stopped
      • C: reverse proxy with cache
      • R: reverse proxy without cache
      • U: unknown
      • X1600000000: (auxiliary) next scheduled sync unix timestamp
      • N1600000000: (auxiliary) new mirror. (optional) unix timestamp the repo added
      • O1600000000: (auxiliary) old successful timestamp, used only when it is syncing or failed
    • mirrors.help may be empty, or the same rule as mirrors.url
    • mirrors.upstream, mirrors.size, mirrors.disable may be empty

Developing and Contributing

Repo organization

This repo depends on other repos in this organization to provide full functionality; However, they are not submodules as we need to bump submodules whenever there is an update, which is painful. We just use the latest version of each repo when building.

For full preparation of all the repos, you should refer to the Prepare steps in Github Actions.

Note that yarn mirrorz_env prepares for https://mirrorz.org. When you are debugging, it is recommended to use yarn dev_env and yarn debug_build, which builds the site for http://localhost:1234. Other env like cngi_env and cernet_env prepares for other sites that mirrorz maintain.

Frontend

HTML/CSS

One may use

yarn --frozen-lockfile
yarn start

to start a local server. It is often convenient for debugging frontend features like html/css since auto-reload is provided by parcel.

Parser, local new static files

To debug one src/parser with new site json in static/json/site, use

yarn --frozen-lockfile
yarn half_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Legacy pages

To use static files, 404 redirection (emulate Github pages) and legacy pages, one may use

yarn --frozen-lockfile
yarn full_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Deployment

For dynamic web page part, only

yarn build

is required.

However if one also wants to deploy the static web page, one may use

yarn build
yarn legacy_build

Note that legacy_build has dependencies on files yarn build has made.

Meanwhile, to generate the complete oh-my-mirrorz.py, one should use the following command

yarn ohmymirrorz_build

If one want all parts, one can use the following command to accomplish all the steps above

yarn full_build

Misc

Currently *.json is ignored in .gitignore (not ignored in /static). If one wants to commit a json file, they should use git add -f.

Contributing

Other contributing guidelines are maintained in https://github.com/mirrorz-org/org/

About

Pods Docs

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

MirrorZ

Your next MirrorS is not MirrorS, nor MirrorSes, it's MirrorZ.

A final site for Mirror sites.

Demo

https://mirrorz.org and https://mirrors.cernet.edu.cn/list

Also legacy webpages (for w3m and noscript users) are provided in https://mirrorz.org/_/ and https://mirrors.cernet.edu.cn/_/

A speed test script oh-my-mirrorz.py is also provided. See README for more info.

Intro

Mirror sites are heterogeneous. It is hard for a single mirror to provide all mirrors, so differences occur.

For end users, this is not a good experience as they need to search for available mirrors.

To make things easy, MirrorZ is intended to include all mirrorS, so a unified interface is needed.

Data Format v1.7

A mirrorz.json in the following format describes all the data of one mirror site in MirrorZ.

{
"version": 1.7,
"site": {
"url": "https://example.org",
"logo": "https://example.org/img/logo.svg",
"logo_darkmode": "https://example.org/img/logo-white.svg",
"abbr": "EXAMPLE",
"name": "样例镜像站",
"homepage": "https://blog.example.org",
"issue": "https://github.com/example/issues",
"request": "https://github.com/example/mirror-request",
"email": "admin@example.com",
"group": "QQ: 10086 and/or Telegram @something",
"disk": "may be any string showing usage of disk, e.g. usage",
"note": "may be any string; like speed limit or connection limit",
"big": "/speedtest/1000mb.bin",
"disable": false
},
"info": [
{
"distro": "Debian",
"category": "os",
"urls": [
{
"name": "10.7.0 (amd64, CD installer with xfce)",
"url": "/debian-cd/current/amd64/iso-cd/debian-10.7.0-amd64-xfce-CD-1.iso"
}
]
}
],
"mirrors": [
{
"cname": "AOSP",
"desc": "Android 操作系统源代码",
"url": "/AOSP",
"status": "S",
"help": "/help/AOSP/",
"upstream": "https://android.googlesource.com/mirror/manifest",
"size": "596G",
"disable": false
},
{
"cname": "AUR",
"desc": "Arch Linux 用户软件库",
"url": "https://aur.tuna.tsinghua.edu.cn",
"status": "S1612195849X1612196849N",
"help": "/help/AUR/",
"upstream": "https://aur.archlinux.org/"
}
]
}

Notes

  • version is optional for version 1.x
    • previous versions of this protocol could be found in git history; protocols in v1.x are back-ward compatible
  • site provides the global info about one mirror site
    • only site.url and site.abbr are mandatory
    • site.logo should not be of format ico. Also, at least 64x64 resolution is required
    • site.logo_darkmode is used when browser uses dark mode. Note that it should be set only after site.logo is set
    • site.url should not end with slash /
    • site.big should be a valid url to a big file, used by oh-my-mirrorz.py for speed testing
    • site.disable is a boolean value, indicating whether the site is available for service. Its default value is false. If true, this site will be marked as disabled in mirrorz webpage, and mirrorz-302 will not redirect to the site
  • info is used for category view
    • all field of info is mandatory
    • info may be left empty as []
    • the name of info.distro should be agreed and have a mapping, maintained in cname.json
  • mirrors is used for list view
    • the name of mirrors.cname should be agreed and have a mapping, maintained in cname.json
    • mirrors.desc may differ for each mirror site since there are excludes for some mirror site
    • mirrors.desc may be empty
    • if mirrors.url begins with a slash /, it should be appended to site.url to form a full url
    • mirrors.url should not end with slash /
    • mirrors.status is a concat of strings of pattern [A-Z](\d+)?. Only one main status is allowed; the number of auxiliary status is not limited.
      • S1600000000: successful. (optional) last successful ended unix timestamp
      • D1600000000: pending. (optional) pending to sync unix timestamp
      • Y1600000000: syncing. (optional) start to sync unix timestamp
      • F1600000000: failed. (optional) last attempt to sync unix timestamp
      • P1600000000: paused. (optional) the unix timestamp sync stopped
      • C: reverse proxy with cache
      • R: reverse proxy without cache
      • U: unknown
      • X1600000000: (auxiliary) next scheduled sync unix timestamp
      • N1600000000: (auxiliary) new mirror. (optional) unix timestamp the repo added
      • O1600000000: (auxiliary) old successful timestamp, used only when it is syncing or failed
    • mirrors.help may be empty, or the same rule as mirrors.url
    • mirrors.upstream, mirrors.size, mirrors.disable may be empty

Developing and Contributing

Repo organization

This repo depends on other repos in this organization to provide full functionality; However, they are not submodules as we need to bump submodules whenever there is an update, which is painful. We just use the latest version of each repo when building.

For full preparation of all the repos, you should refer to the Prepare steps in Github Actions.

Note that yarn mirrorz_env prepares for https://mirrorz.org. When you are debugging, it is recommended to use yarn dev_env and yarn debug_build, which builds the site for http://localhost:1234. Other env like cngi_env and cernet_env prepares for other sites that mirrorz maintain.

Frontend

HTML/CSS

One may use

yarn --frozen-lockfile
yarn start

to start a local server. It is often convenient for debugging frontend features like html/css since auto-reload is provided by parcel.

Parser, local new static files

To debug one src/parser with new site json in static/json/site, use

yarn --frozen-lockfile
yarn half_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Legacy pages

To use static files, 404 redirection (emulate Github pages) and legacy pages, one may use

yarn --frozen-lockfile
yarn full_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Deployment

For dynamic web page part, only

yarn build

is required.

However if one also wants to deploy the static web page, one may use

yarn build
yarn legacy_build

Note that legacy_build has dependencies on files yarn build has made.

Meanwhile, to generate the complete oh-my-mirrorz.py, one should use the following command

yarn ohmymirrorz_build

If one want all parts, one can use the following command to accomplish all the steps above

yarn full_build

Misc

Currently *.json is ignored in .gitignore (not ignored in /static). If one wants to commit a json file, they should use git add -f.

Contributing

Other contributing guidelines are maintained in https://github.com/mirrorz-org/org/

About

Pods Docs

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

MirrorZ

Your next MirrorS is not MirrorS, nor MirrorSes, it's MirrorZ.

A final site for Mirror sites.

Demo

https://mirrorz.org and https://mirrors.cernet.edu.cn/list

Also legacy webpages (for w3m and noscript users) are provided in https://mirrorz.org/_/ and https://mirrors.cernet.edu.cn/_/

A speed test script oh-my-mirrorz.py is also provided. See README for more info.

Intro

Mirror sites are heterogeneous. It is hard for a single mirror to provide all mirrors, so differences occur.

For end users, this is not a good experience as they need to search for available mirrors.

To make things easy, MirrorZ is intended to include all mirrorS, so a unified interface is needed.

Data Format v1.7

A mirrorz.json in the following format describes all the data of one mirror site in MirrorZ.

{
"version": 1.7,
"site": {
"url": "https://example.org",
"logo": "https://example.org/img/logo.svg",
"logo_darkmode": "https://example.org/img/logo-white.svg",
"abbr": "EXAMPLE",
"name": "样例镜像站",
"homepage": "https://blog.example.org",
"issue": "https://github.com/example/issues",
"request": "https://github.com/example/mirror-request",
"email": "admin@example.com",
"group": "QQ: 10086 and/or Telegram @something",
"disk": "may be any string showing usage of disk, e.g. usage",
"note": "may be any string; like speed limit or connection limit",
"big": "/speedtest/1000mb.bin",
"disable": false
},
"info": [
{
"distro": "Debian",
"category": "os",
"urls": [
{
"name": "10.7.0 (amd64, CD installer with xfce)",
"url": "/debian-cd/current/amd64/iso-cd/debian-10.7.0-amd64-xfce-CD-1.iso"
}
]
}
],
"mirrors": [
{
"cname": "AOSP",
"desc": "Android 操作系统源代码",
"url": "/AOSP",
"status": "S",
"help": "/help/AOSP/",
"upstream": "https://android.googlesource.com/mirror/manifest",
"size": "596G",
"disable": false
},
{
"cname": "AUR",
"desc": "Arch Linux 用户软件库",
"url": "https://aur.tuna.tsinghua.edu.cn",
"status": "S1612195849X1612196849N",
"help": "/help/AUR/",
"upstream": "https://aur.archlinux.org/"
}
]
}

Notes

  • version is optional for version 1.x
    • previous versions of this protocol could be found in git history; protocols in v1.x are back-ward compatible
  • site provides the global info about one mirror site
    • only site.url and site.abbr are mandatory
    • site.logo should not be of format ico. Also, at least 64x64 resolution is required
    • site.logo_darkmode is used when browser uses dark mode. Note that it should be set only after site.logo is set
    • site.url should not end with slash /
    • site.big should be a valid url to a big file, used by oh-my-mirrorz.py for speed testing
    • site.disable is a boolean value, indicating whether the site is available for service. Its default value is false. If true, this site will be marked as disabled in mirrorz webpage, and mirrorz-302 will not redirect to the site
  • info is used for category view
    • all field of info is mandatory
    • info may be left empty as []
    • the name of info.distro should be agreed and have a mapping, maintained in cname.json
  • mirrors is used for list view
    • the name of mirrors.cname should be agreed and have a mapping, maintained in cname.json
    • mirrors.desc may differ for each mirror site since there are excludes for some mirror site
    • mirrors.desc may be empty
    • if mirrors.url begins with a slash /, it should be appended to site.url to form a full url
    • mirrors.url should not end with slash /
    • mirrors.status is a concat of strings of pattern [A-Z](\d+)?. Only one main status is allowed; the number of auxiliary status is not limited.
      • S1600000000: successful. (optional) last successful ended unix timestamp
      • D1600000000: pending. (optional) pending to sync unix timestamp
      • Y1600000000: syncing. (optional) start to sync unix timestamp
      • F1600000000: failed. (optional) last attempt to sync unix timestamp
      • P1600000000: paused. (optional) the unix timestamp sync stopped
      • C: reverse proxy with cache
      • R: reverse proxy without cache
      • U: unknown
      • X1600000000: (auxiliary) next scheduled sync unix timestamp
      • N1600000000: (auxiliary) new mirror. (optional) unix timestamp the repo added
      • O1600000000: (auxiliary) old successful timestamp, used only when it is syncing or failed
    • mirrors.help may be empty, or the same rule as mirrors.url
    • mirrors.upstream, mirrors.size, mirrors.disable may be empty

Developing and Contributing

Repo organization

This repo depends on other repos in this organization to provide full functionality; However, they are not submodules as we need to bump submodules whenever there is an update, which is painful. We just use the latest version of each repo when building.

For full preparation of all the repos, you should refer to the Prepare steps in Github Actions.

Note that yarn mirrorz_env prepares for https://mirrorz.org. When you are debugging, it is recommended to use yarn dev_env and yarn debug_build, which builds the site for http://localhost:1234. Other env like cngi_env and cernet_env prepares for other sites that mirrorz maintain.

Frontend

HTML/CSS

One may use

yarn --frozen-lockfile
yarn start

to start a local server. It is often convenient for debugging frontend features like html/css since auto-reload is provided by parcel.

Parser, local new static files

To debug one src/parser with new site json in static/json/site, use

yarn --frozen-lockfile
yarn half_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Legacy pages

To use static files, 404 redirection (emulate Github pages) and legacy pages, one may use

yarn --frozen-lockfile
yarn full_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Deployment

For dynamic web page part, only

yarn build

is required.

However if one also wants to deploy the static web page, one may use

yarn build
yarn legacy_build

Note that legacy_build has dependencies on files yarn build has made.

Meanwhile, to generate the complete oh-my-mirrorz.py, one should use the following command

yarn ohmymirrorz_build

If one want all parts, one can use the following command to accomplish all the steps above

yarn full_build

Misc

Currently *.json is ignored in .gitignore (not ignored in /static). If one wants to commit a json file, they should use git add -f.

Contributing

Other contributing guidelines are maintained in https://github.com/mirrorz-org/org/

About

Pods Docs

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

MirrorZ

Your next MirrorS is not MirrorS, nor MirrorSes, it's MirrorZ.

A final site for Mirror sites.

Demo

https://mirrorz.org and https://mirrors.cernet.edu.cn/list

Also legacy webpages (for w3m and noscript users) are provided in https://mirrorz.org/_/ and https://mirrors.cernet.edu.cn/_/

A speed test script oh-my-mirrorz.py is also provided. See README for more info.

Intro

Mirror sites are heterogeneous. It is hard for a single mirror to provide all mirrors, so differences occur.

For end users, this is not a good experience as they need to search for available mirrors.

To make things easy, MirrorZ is intended to include all mirrorS, so a unified interface is needed.

Data Format v1.7

A mirrorz.json in the following format describes all the data of one mirror site in MirrorZ.

{
"version": 1.7,
"site": {
"url": "https://example.org",
"logo": "https://example.org/img/logo.svg",
"logo_darkmode": "https://example.org/img/logo-white.svg",
"abbr": "EXAMPLE",
"name": "样例镜像站",
"homepage": "https://blog.example.org",
"issue": "https://github.com/example/issues",
"request": "https://github.com/example/mirror-request",
"email": "admin@example.com",
"group": "QQ: 10086 and/or Telegram @something",
"disk": "may be any string showing usage of disk, e.g. usage",
"note": "may be any string; like speed limit or connection limit",
"big": "/speedtest/1000mb.bin",
"disable": false
},
"info": [
{
"distro": "Debian",
"category": "os",
"urls": [
{
"name": "10.7.0 (amd64, CD installer with xfce)",
"url": "/debian-cd/current/amd64/iso-cd/debian-10.7.0-amd64-xfce-CD-1.iso"
}
]
}
],
"mirrors": [
{
"cname": "AOSP",
"desc": "Android 操作系统源代码",
"url": "/AOSP",
"status": "S",
"help": "/help/AOSP/",
"upstream": "https://android.googlesource.com/mirror/manifest",
"size": "596G",
"disable": false
},
{
"cname": "AUR",
"desc": "Arch Linux 用户软件库",
"url": "https://aur.tuna.tsinghua.edu.cn",
"status": "S1612195849X1612196849N",
"help": "/help/AUR/",
"upstream": "https://aur.archlinux.org/"
}
]
}

Notes

  • version is optional for version 1.x
    • previous versions of this protocol could be found in git history; protocols in v1.x are back-ward compatible
  • site provides the global info about one mirror site
    • only site.url and site.abbr are mandatory
    • site.logo should not be of format ico. Also, at least 64x64 resolution is required
    • site.logo_darkmode is used when browser uses dark mode. Note that it should be set only after site.logo is set
    • site.url should not end with slash /
    • site.big should be a valid url to a big file, used by oh-my-mirrorz.py for speed testing
    • site.disable is a boolean value, indicating whether the site is available for service. Its default value is false. If true, this site will be marked as disabled in mirrorz webpage, and mirrorz-302 will not redirect to the site
  • info is used for category view
    • all field of info is mandatory
    • info may be left empty as []
    • the name of info.distro should be agreed and have a mapping, maintained in cname.json
  • mirrors is used for list view
    • the name of mirrors.cname should be agreed and have a mapping, maintained in cname.json
    • mirrors.desc may differ for each mirror site since there are excludes for some mirror site
    • mirrors.desc may be empty
    • if mirrors.url begins with a slash /, it should be appended to site.url to form a full url
    • mirrors.url should not end with slash /
    • mirrors.status is a concat of strings of pattern [A-Z](\d+)?. Only one main status is allowed; the number of auxiliary status is not limited.
      • S1600000000: successful. (optional) last successful ended unix timestamp
      • D1600000000: pending. (optional) pending to sync unix timestamp
      • Y1600000000: syncing. (optional) start to sync unix timestamp
      • F1600000000: failed. (optional) last attempt to sync unix timestamp
      • P1600000000: paused. (optional) the unix timestamp sync stopped
      • C: reverse proxy with cache
      • R: reverse proxy without cache
      • U: unknown
      • X1600000000: (auxiliary) next scheduled sync unix timestamp
      • N1600000000: (auxiliary) new mirror. (optional) unix timestamp the repo added
      • O1600000000: (auxiliary) old successful timestamp, used only when it is syncing or failed
    • mirrors.help may be empty, or the same rule as mirrors.url
    • mirrors.upstream, mirrors.size, mirrors.disable may be empty

Developing and Contributing

Repo organization

This repo depends on other repos in this organization to provide full functionality; However, they are not submodules as we need to bump submodules whenever there is an update, which is painful. We just use the latest version of each repo when building.

For full preparation of all the repos, you should refer to the Prepare steps in Github Actions.

Note that yarn mirrorz_env prepares for https://mirrorz.org. When you are debugging, it is recommended to use yarn dev_env and yarn debug_build, which builds the site for http://localhost:1234. Other env like cngi_env and cernet_env prepares for other sites that mirrorz maintain.

Frontend

HTML/CSS

One may use

yarn --frozen-lockfile
yarn start

to start a local server. It is often convenient for debugging frontend features like html/css since auto-reload is provided by parcel.

Parser, local new static files

To debug one src/parser with new site json in static/json/site, use

yarn --frozen-lockfile
yarn half_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Legacy pages

To use static files, 404 redirection (emulate Github pages) and legacy pages, one may use

yarn --frozen-lockfile
yarn full_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Deployment

For dynamic web page part, only

yarn build

is required.

However if one also wants to deploy the static web page, one may use

yarn build
yarn legacy_build

Note that legacy_build has dependencies on files yarn build has made.

Meanwhile, to generate the complete oh-my-mirrorz.py, one should use the following command

yarn ohmymirrorz_build

If one want all parts, one can use the following command to accomplish all the steps above

yarn full_build

Misc

Currently *.json is ignored in .gitignore (not ignored in /static). If one wants to commit a json file, they should use git add -f.

Contributing

Other contributing guidelines are maintained in https://github.com/mirrorz-org/org/

About

Pods Docs

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

MirrorZ

Your next MirrorS is not MirrorS, nor MirrorSes, it's MirrorZ.

A final site for Mirror sites.

Demo

https://mirrorz.org and https://mirrors.cernet.edu.cn/list

Also legacy webpages (for w3m and noscript users) are provided in https://mirrorz.org/_/ and https://mirrors.cernet.edu.cn/_/

A speed test script oh-my-mirrorz.py is also provided. See README for more info.

Intro

Mirror sites are heterogeneous. It is hard for a single mirror to provide all mirrors, so differences occur.

For end users, this is not a good experience as they need to search for available mirrors.

To make things easy, MirrorZ is intended to include all mirrorS, so a unified interface is needed.

Data Format v1.7

A mirrorz.json in the following format describes all the data of one mirror site in MirrorZ.

{
"version": 1.7,
"site": {
"url": "https://example.org",
"logo": "https://example.org/img/logo.svg",
"logo_darkmode": "https://example.org/img/logo-white.svg",
"abbr": "EXAMPLE",
"name": "样例镜像站",
"homepage": "https://blog.example.org",
"issue": "https://github.com/example/issues",
"request": "https://github.com/example/mirror-request",
"email": "admin@example.com",
"group": "QQ: 10086 and/or Telegram @something",
"disk": "may be any string showing usage of disk, e.g. usage",
"note": "may be any string; like speed limit or connection limit",
"big": "/speedtest/1000mb.bin",
"disable": false
},
"info": [
{
"distro": "Debian",
"category": "os",
"urls": [
{
"name": "10.7.0 (amd64, CD installer with xfce)",
"url": "/debian-cd/current/amd64/iso-cd/debian-10.7.0-amd64-xfce-CD-1.iso"
}
]
}
],
"mirrors": [
{
"cname": "AOSP",
"desc": "Android 操作系统源代码",
"url": "/AOSP",
"status": "S",
"help": "/help/AOSP/",
"upstream": "https://android.googlesource.com/mirror/manifest",
"size": "596G",
"disable": false
},
{
"cname": "AUR",
"desc": "Arch Linux 用户软件库",
"url": "https://aur.tuna.tsinghua.edu.cn",
"status": "S1612195849X1612196849N",
"help": "/help/AUR/",
"upstream": "https://aur.archlinux.org/"
}
]
}

Notes

  • version is optional for version 1.x
    • previous versions of this protocol could be found in git history; protocols in v1.x are back-ward compatible
  • site provides the global info about one mirror site
    • only site.url and site.abbr are mandatory
    • site.logo should not be of format ico. Also, at least 64x64 resolution is required
    • site.logo_darkmode is used when browser uses dark mode. Note that it should be set only after site.logo is set
    • site.url should not end with slash /
    • site.big should be a valid url to a big file, used by oh-my-mirrorz.py for speed testing
    • site.disable is a boolean value, indicating whether the site is available for service. Its default value is false. If true, this site will be marked as disabled in mirrorz webpage, and mirrorz-302 will not redirect to the site
  • info is used for category view
    • all field of info is mandatory
    • info may be left empty as []
    • the name of info.distro should be agreed and have a mapping, maintained in cname.json
  • mirrors is used for list view
    • the name of mirrors.cname should be agreed and have a mapping, maintained in cname.json
    • mirrors.desc may differ for each mirror site since there are excludes for some mirror site
    • mirrors.desc may be empty
    • if mirrors.url begins with a slash /, it should be appended to site.url to form a full url
    • mirrors.url should not end with slash /
    • mirrors.status is a concat of strings of pattern [A-Z](\d+)?. Only one main status is allowed; the number of auxiliary status is not limited.
      • S1600000000: successful. (optional) last successful ended unix timestamp
      • D1600000000: pending. (optional) pending to sync unix timestamp
      • Y1600000000: syncing. (optional) start to sync unix timestamp
      • F1600000000: failed. (optional) last attempt to sync unix timestamp
      • P1600000000: paused. (optional) the unix timestamp sync stopped
      • C: reverse proxy with cache
      • R: reverse proxy without cache
      • U: unknown
      • X1600000000: (auxiliary) next scheduled sync unix timestamp
      • N1600000000: (auxiliary) new mirror. (optional) unix timestamp the repo added
      • O1600000000: (auxiliary) old successful timestamp, used only when it is syncing or failed
    • mirrors.help may be empty, or the same rule as mirrors.url
    • mirrors.upstream, mirrors.size, mirrors.disable may be empty

Developing and Contributing

Repo organization

This repo depends on other repos in this organization to provide full functionality; However, they are not submodules as we need to bump submodules whenever there is an update, which is painful. We just use the latest version of each repo when building.

For full preparation of all the repos, you should refer to the Prepare steps in Github Actions.

Note that yarn mirrorz_env prepares for https://mirrorz.org. When you are debugging, it is recommended to use yarn dev_env and yarn debug_build, which builds the site for http://localhost:1234. Other env like cngi_env and cernet_env prepares for other sites that mirrorz maintain.

Frontend

HTML/CSS

One may use

yarn --frozen-lockfile
yarn start

to start a local server. It is often convenient for debugging frontend features like html/css since auto-reload is provided by parcel.

Parser, local new static files

To debug one src/parser with new site json in static/json/site, use

yarn --frozen-lockfile
yarn half_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Legacy pages

To use static files, 404 redirection (emulate Github pages) and legacy pages, one may use

yarn --frozen-lockfile
yarn full_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Deployment

For dynamic web page part, only

yarn build

is required.

However if one also wants to deploy the static web page, one may use

yarn build
yarn legacy_build

Note that legacy_build has dependencies on files yarn build has made.

Meanwhile, to generate the complete oh-my-mirrorz.py, one should use the following command

yarn ohmymirrorz_build

If one want all parts, one can use the following command to accomplish all the steps above

yarn full_build

Misc

Currently *.json is ignored in .gitignore (not ignored in /static). If one wants to commit a json file, they should use git add -f.

Contributing

Other contributing guidelines are maintained in https://github.com/mirrorz-org/org/

About

Pods Docs

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

MirrorZ

Your next MirrorS is not MirrorS, nor MirrorSes, it's MirrorZ.

A final site for Mirror sites.

Demo

https://mirrorz.org and https://mirrors.cernet.edu.cn/list

Also legacy webpages (for w3m and noscript users) are provided in https://mirrorz.org/_/ and https://mirrors.cernet.edu.cn/_/

A speed test script oh-my-mirrorz.py is also provided. See README for more info.

Intro

Mirror sites are heterogeneous. It is hard for a single mirror to provide all mirrors, so differences occur.

For end users, this is not a good experience as they need to search for available mirrors.

To make things easy, MirrorZ is intended to include all mirrorS, so a unified interface is needed.

Data Format v1.7

A mirrorz.json in the following format describes all the data of one mirror site in MirrorZ.

{
"version": 1.7,
"site": {
"url": "https://example.org",
"logo": "https://example.org/img/logo.svg",
"logo_darkmode": "https://example.org/img/logo-white.svg",
"abbr": "EXAMPLE",
"name": "样例镜像站",
"homepage": "https://blog.example.org",
"issue": "https://github.com/example/issues",
"request": "https://github.com/example/mirror-request",
"email": "admin@example.com",
"group": "QQ: 10086 and/or Telegram @something",
"disk": "may be any string showing usage of disk, e.g. usage",
"note": "may be any string; like speed limit or connection limit",
"big": "/speedtest/1000mb.bin",
"disable": false
},
"info": [
{
"distro": "Debian",
"category": "os",
"urls": [
{
"name": "10.7.0 (amd64, CD installer with xfce)",
"url": "/debian-cd/current/amd64/iso-cd/debian-10.7.0-amd64-xfce-CD-1.iso"
}
]
}
],
"mirrors": [
{
"cname": "AOSP",
"desc": "Android 操作系统源代码",
"url": "/AOSP",
"status": "S",
"help": "/help/AOSP/",
"upstream": "https://android.googlesource.com/mirror/manifest",
"size": "596G",
"disable": false
},
{
"cname": "AUR",
"desc": "Arch Linux 用户软件库",
"url": "https://aur.tuna.tsinghua.edu.cn",
"status": "S1612195849X1612196849N",
"help": "/help/AUR/",
"upstream": "https://aur.archlinux.org/"
}
]
}

Notes

  • version is optional for version 1.x
    • previous versions of this protocol could be found in git history; protocols in v1.x are back-ward compatible
  • site provides the global info about one mirror site
    • only site.url and site.abbr are mandatory
    • site.logo should not be of format ico. Also, at least 64x64 resolution is required
    • site.logo_darkmode is used when browser uses dark mode. Note that it should be set only after site.logo is set
    • site.url should not end with slash /
    • site.big should be a valid url to a big file, used by oh-my-mirrorz.py for speed testing
    • site.disable is a boolean value, indicating whether the site is available for service. Its default value is false. If true, this site will be marked as disabled in mirrorz webpage, and mirrorz-302 will not redirect to the site
  • info is used for category view
    • all field of info is mandatory
    • info may be left empty as []
    • the name of info.distro should be agreed and have a mapping, maintained in cname.json
  • mirrors is used for list view
    • the name of mirrors.cname should be agreed and have a mapping, maintained in cname.json
    • mirrors.desc may differ for each mirror site since there are excludes for some mirror site
    • mirrors.desc may be empty
    • if mirrors.url begins with a slash /, it should be appended to site.url to form a full url
    • mirrors.url should not end with slash /
    • mirrors.status is a concat of strings of pattern [A-Z](\d+)?. Only one main status is allowed; the number of auxiliary status is not limited.
      • S1600000000: successful. (optional) last successful ended unix timestamp
      • D1600000000: pending. (optional) pending to sync unix timestamp
      • Y1600000000: syncing. (optional) start to sync unix timestamp
      • F1600000000: failed. (optional) last attempt to sync unix timestamp
      • P1600000000: paused. (optional) the unix timestamp sync stopped
      • C: reverse proxy with cache
      • R: reverse proxy without cache
      • U: unknown
      • X1600000000: (auxiliary) next scheduled sync unix timestamp
      • N1600000000: (auxiliary) new mirror. (optional) unix timestamp the repo added
      • O1600000000: (auxiliary) old successful timestamp, used only when it is syncing or failed
    • mirrors.help may be empty, or the same rule as mirrors.url
    • mirrors.upstream, mirrors.size, mirrors.disable may be empty

Developing and Contributing

Repo organization

This repo depends on other repos in this organization to provide full functionality; However, they are not submodules as we need to bump submodules whenever there is an update, which is painful. We just use the latest version of each repo when building.

For full preparation of all the repos, you should refer to the Prepare steps in Github Actions.

Note that yarn mirrorz_env prepares for https://mirrorz.org. When you are debugging, it is recommended to use yarn dev_env and yarn debug_build, which builds the site for http://localhost:1234. Other env like cngi_env and cernet_env prepares for other sites that mirrorz maintain.

Frontend

HTML/CSS

One may use

yarn --frozen-lockfile
yarn start

to start a local server. It is often convenient for debugging frontend features like html/css since auto-reload is provided by parcel.

Parser, local new static files

To debug one src/parser with new site json in static/json/site, use

yarn --frozen-lockfile
yarn half_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Legacy pages

To use static files, 404 redirection (emulate Github pages) and legacy pages, one may use

yarn --frozen-lockfile
yarn full_start

to start a local server. Python3 is required in this case. Note there is no auto-reload feature.

Deployment

For dynamic web page part, only

yarn build

is required.

However if one also wants to deploy the static web page, one may use

yarn build
yarn legacy_build

Note that legacy_build has dependencies on files yarn build has made.

Meanwhile, to generate the complete oh-my-mirrorz.py, one should use the following command

yarn ohmymirrorz_build

If one want all parts, one can use the following command to accomplish all the steps above

yarn full_build

Misc

Currently *.json is ignored in .gitignore (not ignored in /static). If one wants to commit a json file, they should use git add -f.

Contributing

Other contributing guidelines are maintained in https://github.com/mirrorz-org/org/

About

Pods Docs

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages