Merge branch 'master' into emergency

This commit is contained in:
王邈 2017-08-02 16:22:59 +08:00
commit c3270c97e4
97 changed files with 4938 additions and 330 deletions

5
.gitignore vendored
View File

@ -3,6 +3,11 @@
/Gemfile.lock
/.jekyll-metadata
/static/tunasync.json
/static/isoinfo.json
/static/tunet.json
/static/js/vue.js
/_site
/deploy.sh
/.sass-cache/
.bundle
vendor

18
Dockerfile.build Normal file
View File

@ -0,0 +1,18 @@
FROM ruby:2.3
RUN mkdir /data
WORKDIR /data
RUN apt-get update && apt-get -y install nodejs
COPY Gemfile /data/
RUN gem install bundler
RUN bundle install
# Fix https://github.com/babel/ruby-babel-transpiler/issues/294
RUN sed -i 's/@context ||= ExecJS.compile("var self = this; " + File.read(script_path))/@context ||= ExecJS.compile("var self = this; " + File.read(script_path, :encoding => "UTF-8"))/' /usr/local/bundle/gems/babel-transpiler-0.7.0/lib/babel/transpiler.rb
ENV LANG en_US.UTF-8
CMD ["jekyll", "build"]

14
Dockerfile.dev Normal file
View File

@ -0,0 +1,14 @@
FROM alpine:3.3
MAINTAINER Xuanwo <xuanwo.cn@gmail.com>
RUN apk add --update \
nodejs ruby ruby-dev ruby-rdoc ruby-irb ruby-io-console ruby-nokogiri \
gcc libc-dev libffi-dev zlib-dev libxml2-dev libxslt-dev build-base \
&& rm -rf /var/cache/apk/*
RUN gem sources --add http://gems.ruby-china.org/ --remove https://rubygems.org/
RUN gem install bundler
RUN bundle config build.nokogiri --use-system-libraries
VOLUME /src
WORKDIR /src
EXPOSE 4000
CMD bundle install && jekyll server -H 0.0.0.0

View File

@ -1,3 +1,3 @@
source 'https://ruby.taobao.org'
source 'https://mirrors.tuna.tsinghua.edu.cn/rubygems/'
gem 'github-pages'
gem 'jekyll-babel'

View File

@ -1,19 +1,58 @@
# TUNA mirrors 主页
## 运行 Demo
## 运行 Demo
### 直接编译
本站使用 Jekyll 编写,并使用 babel 编译 ECMAScript6因此必须安装 ruby >= 2.0 和 nodejs.
### For Centos
1.安装 nodejs
```
yum install nodejs
```
2.安装 ruby 2.2.4 and rubygems
Step 1: Install Required Packages
```
yum install gcc-c++ patch readline readline-devel zlib zlib-devel
yum install libyaml-devel libffi-devel openssl-devel make
yum install bzip2 autoconf automake libtool bison iconv-devel sqlite-devel
```
Step 2: Compile ruby 2.2.4 source code
```
weget -c https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.4.tar.gz
```
Step 3: Install rubygems
```
wget -c https://rubygems.org/rubygems/rubygems-2.4.8.tgz
ruby setup.rb
```
3. 安装 bundle 和 build
```
gem install bundle
gem install build
```
4. Fork mirrors source code
```
bundle install
jekyll build
```
### Build In Docker
```
cd mirror-web
docker build -t builden -f Dockerfile.build .
docker run -it -v /path/to/mirror-web/:/data builden
```
为正常运行,一些动态数据文件需要下载
```
wget https://mirrors.tuna.tsinghua.edu.cn/static/tunasync.json -O static/tunasync.json
wget https://mirrors.tuna.tsinghua.edu.cn/static/tunet.json -O static/tunet.json
wget https://mirrors.tuna.tsinghua.edu.cn/static/isoinfo.json -O static/isoinfo.json
```
之后 `jekyll serve` 即可运行 demo.
@ -38,39 +77,8 @@ wget https://mirrors.tuna.tsinghua.edu.cn/static/tunet.json -O static/tunet.json
### 特殊用法
#### 表单选择
例如 <http://mirrors.tuna.tsinghua.edu.cn/help/gitlab-ce/> 中,通过表单选择操作系统和版本号,生成对应配置文件的代码为:
```html
<form class="form-inline">
<div class="form-group">
<label>你的Debian/Ubuntu版本: </label>
<select class="form-control release-select" data-template="#apt-template" data-target="#apt-content">
<option data-os="debian" data-release="wheezy">Debian 7 (Wheezy)</option>
<option data-os="debian" data-release="jessie" selected>Debian 8 (Jessie)</option>
<option data-os="ubuntu" data-release="trusty">Ubuntu 14.04 LTS</option>
</select>
</div>
</form>
<p></p>
<pre>
<code id="apt-content">
</code>
</pre>
{% raw %}
<script id="apt-template" type="x-tmpl-markup">
deb https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/{{os_name}} {{release_name}} main
</script>
{% endraw %}
```
`<form>`包含的内容即为表单, `select`标签的`data-template`和`data-target`属性分别指定配置文件模板和 placeholder 的 id
`option`标签为选项,`data-os` 和 `data-release` 分别指定操作系统名称和版本号。
`code#apt-content`部分是占位符,`{% raw %}{% endraw %}`包含的部分是配置文件模板,通过 `{% raw %}` 标记防止被 jekyll 转义。
模板使用 [Markup.js](https://github.com/adammark/Markup.js/) 语法,可使用 `{{os_name}}``{{release_name}}` 两个变量,
对应于`option`中的操作系统和版本号设定。
例如 <http://mirrors.tuna.tsinghua.edu.cn/help/tensorflow/> 中,通过表单选择操作系统和版本号,建议直接使用 Vue.js

View File

@ -6,10 +6,11 @@
# 'jekyll serve'. If you change this file, please restart the server process.
# Site settings
title: 清华大学 TUNA 镜像源
brand: TUNA mirrors
title: 清华大学开源软件镜像站
brand: Tsinghua Open Source Mirrors
baseurl: "" # the subpath of your site, e.g. /blog
permalink: "/:categories/:title/"
url: "https://mirrors.tuna.tsinghua.edu.cn"
# Build settings
highlighter: rouge
@ -24,11 +25,24 @@ sass:
gems:
- jekyll-babel
- jekyll-sitemap
exclude: [Gemfile, Gemfile.lock, README.md, gen_robot.sh]
babel_js_extensions: 'es6'
exclude: [Gemfile, Gemfile.lock, README.md, gen_robot.sh, vendor, geninfo/, gen_robot.sh, gen_desc.py, Dockerfile*]
# Content Related
new_mirrors: [openwrt, mongodb, anaconda, packman, gnu, osmc]
issue: 由于同步脚本出错,执行了类似 rm -rf / 的操作……
backtime: 2016-04-03 20:00
new_mirrors:
- adobe-fonts
- tinycorelinux
- zabbix
- lineage-rom
- lineageOS
- llvm
- clojars
# vim: ts=2 sts=2 sw=2 expandtab

498
_data/mirror_desc.json Normal file
View File

@ -0,0 +1,498 @@
[
{
"name": "AOSP",
"desc": "Android 操作系统源代码"
},
{
"name": "AUR",
"desc": "Arch Linux 用户软件库"
},
{
"name": "Bananian",
"desc": "为 Banana Pi 制作的,基于官方 Debian 仓库的发行版镜像和软件包仓库"
},
{
"name": "CRAN",
"desc": "R 语言的可执行文件、源代码和说明文件,也收录了各种用户撰写的软件包"
},
{
"name": "CTAN",
"desc": "TeX 的各种发行版、软件包和文档"
},
{
"name": "CocoaPods",
"desc": "Objective-C 和 Swift 的依赖管理器"
},
{
"name": "ELK",
"desc": "现已更名为 Elastic Stack仅保留用作向后兼容"
},
{
"name": "HHVM",
"desc": "Facebook 开发的高性能 PHP 语言虚拟机"
},
{
"name": "Homebrew",
"desc": " Homebrew 的 formula 索引的镜像,二进制预编译包的镜像请见 homebrew-bottles"
},
{
"name": "NetBSD",
"desc": "NetBSD 的安装镜像和部分系统源码"
},
{
"name": "OpenBSD",
"desc": "OpenBSD 的安装镜像和官方软件包仓库"
},
{
"name": "adobe-fonts",
"desc": "Adobe 公司的开源字体"
},
{
"name": "alpine",
"desc": "Alpine Linux 的安装镜像和官方软件包仓库"
},
{
"name": "anaconda",
"desc": "用于科学计算的 Python 发行版"
},
{
"name": "antergos",
"desc": "基于 Arch Linux 的使用 GNOME 3 的发行版,曾用名 Cinnarch"
},
{
"name": "anthon",
"desc": "Anthon Linux (安同 Linux)的安装镜像和官方软件包仓库"
},
{
"name": "aosp-monthly",
"desc": "AOSP 镜像每月打包"
},
{
"name": "apache",
"desc": "Apache 基金会赞助的各个项目"
},
{
"name": "arch4edu",
"desc": "用于 Arch Linux 的一系列科研、教学所需工具"
},
{
"name": "archlinux",
"desc": "Arch Linux 的安装镜像和官方软件包仓库"
},
{
"name": "archlinuxarm",
"desc": "用于 arm 平台的 Arch Linux 镜像和软件包仓库"
},
{
"name": "archlinuxcn",
"desc": "由 Arch Linux 中文社区驱动的非官方用户仓库,包含中文用户常用软件、工具、字体/美化包等"
},
{
"name": "bananian",
"desc": "用于 Banana Pi 的 Debian 操作系统"
},
{
"name": "bioconductor",
"desc": ""
},
{
"name": "bjlx",
"desc": "北京龙芯 & Debian 俱乐部 的公开软件源"
},
{
"name": "blackarch",
"desc": "用于安全评估的基于 Arch Linux 的轻量级发行版"
},
{
"name": "centos",
"desc": "CentOS 的安装镜像和官方软件包仓库"
},
{
"name": "ceph",
"desc": "高性能对象存储和文件系统"
},
{
"name": "chakra",
"desc": "专注于 Qt 与 KDE 软件的 Linux 发行版"
},
{
"name": "chromiumos",
"desc": "Google Chrome OS的开放源代码开发版本"
},
{
"name": "ctex",
"desc": "旧版 CTEX 安装镜像存档"
},
{
"name": "cygwin",
"desc": "Cygwin 官方软件包仓库"
},
{
"name": "debian",
"desc": "Debian Linux 的官方软件包仓库"
},
{
"name": "debian-cd",
"desc": "Debian Linux 的安装镜像"
},
{
"name": "debian-multimedia",
"desc": ""
},
{
"name": "debian-nonfree",
"desc": ""
},
{
"name": "debian-security",
"desc": "Debian Linux 的安全更新"
},
{
"name": "deepin",
"desc": "Deepin Linux 的官方软件包仓库"
},
{
"name": "deepin-cd",
"desc": "Deeping Linux 的安装镜像"
},
{
"name": "dell",
"desc": "Dell 服务器管理工具"
},
{
"name": "docker",
"desc": "Debian/Ubuntu/Fedora/CentOS/RHEL 的 docker 软件包"
},
{
"name": "dotdeb",
"desc": "用于 Debian 服务器的额外镜像源"
},
{
"name": "elasticstack",
"desc": "ELK 系列数据分析工具5.x 之后改名为 Elastic Stack"
},
{
"name": "elpa",
"desc": "Emacs 内建包管理器 package.el 的软件源"
},
{
"name": "elrepo",
"desc": "RHEL 及其变体的 RPM 软件包仓库"
},
{
"name": "elvish",
"desc": "TUNA 前会长 xiaq 开发的革命性 Shell"
},
{
"name": "epel",
"desc": "企业版 Linux 附加软件包"
},
{
"name": "erlang-solutions",
"desc": ""
},
{
"name": "fedora",
"desc": "Fedora Linux 的安装镜像和官方软件包仓库"
},
{
"name": "gentoo",
"desc": "Gentoo Linux 的 Stage 3 镜像"
},
{
"name": "gentoo-portage",
"desc": "Gentoo Linux 的 Portage 包管理器镜像源"
},
{
"name": "git-repo",
"desc": "Google 开发的项目依赖下载工具 repo 的镜像"
},
{
"name": "gitlab-ce",
"desc": "Gitlab 社区版"
},
{
"name": "gitlab-ci-multi-runner",
"desc": "GitLab 持续集成框架"
},
{
"name": "gnu",
"desc": "GNU项目的软件包源代码、文档和部分平台的二进制文件"
},
{
"name": "grafana",
"desc": "开源的数据可视化工具"
},
{
"name": "hackage",
"desc": "Haskell 社区的中心软件包仓库"
},
{
"name": "homebrew",
"desc": "Homebrew 的软件包描述文件"
},
{
"name": "homebrew-bottles",
"desc": "预编译的 Homebrew 软件包"
},
{
"name": "infinality-bundle",
"desc": "Arch Linux 的字体渲染软件包"
},
{
"name": "influxdata",
"desc": "时间序列数据平台"
},
{
"name": "ius",
"desc": "为企业版 LInux 提供最新软件包的镜像源"
},
{
"name": "jenkins",
"desc": "用 Java 编写的持续集成框架"
},
{
"name": "kali",
"desc": "Kali Linux 的官方软件包仓库"
},
{
"name": "kali-images",
"desc": "Kali Linux 的安装镜像"
},
{
"name": "kali-security",
"desc": "Kali Linux 的安全更新"
},
{
"name": "kernel",
"desc": "各个版本的Linux 内核源代码"
},
{
"name": "kodi",
"desc": "开源的多媒体播放器,原名 XBMC"
},
{
"name": "lineage-rom",
"desc": "最大的社区Android发行版之一Lineage的ROM"
},
{
"name": "lineageOS",
"desc": "最大的社区Android发行版之一Lineage的源代码"
},
{
"name": "linux-stable.git",
"desc": "Linux 内核源代码的 Git 仓库, 稳定版分支"
},
{
"name": "linux.git",
"desc": "Linux 内核源代码的 Git 仓库"
},
{
"name": "linuxmint",
"desc": "Linux Mint 的官方软件源"
},
{
"name": "linuxmint-cd",
"desc": "Linux Mint 的安装镜像"
},
{
"name": "loongson",
"desc": "用于龙芯电脑的软件包"
},
{
"name": "lxc-images",
"desc": "Linux 容器的镜像"
},
{
"name": "macports",
"desc": "macOS 的一个开源软件包管理系统"
},
{
"name": "mageia",
"desc": "Mageia Linux 衍生于Mandriva Linux的安装镜像和官方软件包仓库"
},
{
"name": "manjaro",
"desc": "Manjaro Linux 的官方软件源"
},
{
"name": "manjaro-cd",
"desc": "Manjanro Linux 的安装镜像"
},
{
"name": "mariadb",
"desc": "衍生于 MySQL 的开源关系数据库"
},
{
"name": "mongodb",
"desc": "开源的跨平台 NoSQL 文档型数据库"
},
{
"name": "msys2",
"desc": "用于编译原生 Windows 程序的类 Linux 开发环境"
},
{
"name": "mysql",
"desc": "MySQL 安装包及各种工具下载"
},
{
"name": "neurodebian",
"desc": "用于神经科学研究的 Debian 软件包源"
},
{
"name": "nodesource",
"desc": "为 Debian, Ubuntu, Fedora, RHEL 等发行版提供预编译的 nodejs 和 npm 等软件包"
},
{
"name": "opensuse",
"desc": "openSUSE 的安装镜像和官方软件包仓库"
},
{
"name": "openwrt",
"desc": "OpenWrt 软件包镜像源仅包含Chaos Calmer版本"
},
{
"name": "osmc",
"desc": "免费、开源的媒体中心解决方案"
},
{
"name": "packman",
"desc": "为 Debian、Fedora、openSUSE、Ubuntu 提供额外和过期软件包的仓库"
},
{
"name": "parrot",
"desc": "Parrot Linux专注于安全审计的 Linux 发行版)的安装奖项和官方软件源"
},
{
"name": "percona",
"desc": "开源的数据库解决方案,详见 http://www.percona.com"
},
{
"name": "postgresql",
"desc": "著名的开源关系型数据库 PostgreSQL 的镜像"
},
{
"name": "puppy",
"desc": "为家用电脑设计的轻量级 Linux 发行版"
},
{
"name": "pybombs",
"desc": "为 GNU Radio 设计的编译管理系统"
},
{
"name": "pypi",
"desc": "Python 软件包索引源"
},
{
"name": "qt",
"desc": "跨平台软件开发库 Qt 的源码、开发工具、文档等"
},
{
"name": "raspbian",
"desc": "为 Raspberry Pi 编译的 Debian"
},
{
"name": "redhat",
"desc": "Red Hat Enterprise Linux 官方软件源"
},
{
"name": "remi",
"desc": "包含最新版本 PHP 和 MySQL 的第三方 yum 源"
},
{
"name": "repo-ck",
"desc": "repo-ck 是 Arch 的非官方仓库,内有包含 ck 补丁、BFS 调度器等"
},
{
"name": "repoforge",
"desc": "Repoforge 是 RHEL 系统下的软件仓库,拥有 10000 多个软件包,被认为是最安全、最稳定的一个软件仓库"
},
{
"name": "ros",
"desc": "ROS (Robot Operating System) 提供一系列程序库和工具以帮助软件开发者创建机器人应用软件"
},
{
"name": "rpmfusion",
"desc": "RPM Fusion 提供了一些 Fedora Project 和 Red Hat 不包含的软件"
},
{
"name": "rubygems",
"desc": "Ruby 的一个包管理器"
},
{
"name": "sagemath",
"desc": "构建在 NumPy, SciPy 等工具之上的开源数学软件系统"
},
{
"name": "saltstack",
"desc": "基于 python 的配置管理与运维自动化工具"
},
{
"name": "slackware",
"desc": "Linux 发行版 Slackware 的源代码和官方软件包仓库"
},
{
"name": "slackwarearm",
"desc": "用于 ARM 设备的 Slackware 发行版源代码和官方软件包仓库"
},
{
"name": "stackage",
"desc": "Haskell 项目管理器 stack 所需的元数据与 ghc 安装包的镜像"
},
{
"name": "steamos",
"desc": "Valve 开发的基于 Debian 的操作系统,包含安装镜像和官方软件包仓库"
},
{
"name": "tensorflow",
"desc": "采用数据流图、用于数值计算的开源深度学习框架 TensorFlow"
},
{
"name": "termux",
"desc": " 运行在 Android 上的终端模拟器 Termux 的官方软件包仓库"
},
{
"name": "tinycorelinux",
"desc": ""
},
{
"name": "ubuntu",
"desc": "流行的 Linux 发行版 Ubuntu 的安装镜像和官方软件包仓库"
},
{
"name": "ubuntu-cdimage",
"desc": "Ubuntu 及 Ubuntu 衍生版各版本安装镜像"
},
{
"name": "ubuntu-cloud-images",
"desc": "适用于公有云的 Ubuntu 安装镜像"
},
{
"name": "ubuntu-ports",
"desc": "armhf, arm64 以及 powerpc 等平台的 Ubuntu 软件仓库"
},
{
"name": "ubuntu-releases",
"desc": "包含近几年发行的 Ubuntu 的镜像"
},
{
"name": "videolan-ftp",
"desc": "简称VLC是一款自由、开源的跨平台多媒体播放器及框架可播放大多数多媒体文件"
},
{
"name": "virtualbox",
"desc": "Oracle 的开源的 x86 架构虚拟机"
},
{
"name": "weave",
"desc": "Google 开发的物联网IoT设备通信平台"
},
{
"name": "zabbix",
"desc": ""
},
{
"name": "llvm",
"desc": "LLVM 编译器套件的多个 git repo 的镜像"
}
]

View File

@ -1,7 +1,35 @@
<div id="footerwrap">
<div class="container">
<p class="text-center">
2011-2016 Tsinghua University TUNA Association
</p>
<div class="row">
<div class="col-lg-4 col-md-4">
<p>本站由清华大学信息化技术中心支持创办,由清华大学 TUNA 协会运行维护。</p>
<p>清华大学 TUNA 协会,全名清华大学学生网络与开源软件协会,是由清华大学热爱网络技术和开源软件极客组成的学生技术社团。</p>
<p>本站相关源码可在 <a href="https://github.com/tuna/tunasync"><em>这里(镜像管理器)</em></a><a href="https://github.com/tuna/mirror-web"><em>这里(镜像站网页)</em></a> 获取。</p>
</div>
<div class="col-lg-4 col-md-4">
<h4>Contact Us</h4>
<div>
<ul class="social">
<li>
<a href="https://groups.google.com/forum/#!forum/tuna-general"><i class="fa fa-envelope"></i> Mailing List</a>
</li>
<li>
IRC: <a href="https://webchat.freenode.net/?channels=%23tuna">#tuna at freenode</a>
</li>
<li>
<a href="https://github.com/tuna/"><i class="fa fa-github"></i> GitHub </a>
</li>
<li>
<a href="http://weibo.com/u/5402274706"><i class="fa fa-weibo"></i> 新浪微博</a>
</li>
</ul>
</div>
</div>
<div class="col-lg-4 col-md-4" align="center">
<img class="img-responsive" style="margin-top:5%" src="/static/img/logo-white.png" />
</div>
</div><!--/row -->
</div><!--/container -->
</div><!--/footerwrap -->

View File

@ -2,16 +2,20 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="清华大学开源镜像站致力于为国内和校内用户提供高质量的开源软件镜像、Linux镜像源服务帮助用户更方便地获取开源软件。本镜像站由清华大学TUNA团队负责维护。">
<meta name="description" content="清华大学开源软件镜像站致力于为国内和校内用户提供高质量的开源软件镜像、Linux镜像源服务帮助用户更方便地获取开源软件。本镜像站由清华大学TUNA团队负责维护。">
<meta name="keywords" content="镜像站,镜像源,Linux,软件源,开源">
<meta name="author" content="TUNA">
<link rel="shortcut icon" href="/static/img/favicon.png">
<title>清华大学 TUNA 镜像源</title>
<title>清华大学开源软件镜像站 | Tsinghua Open Source Mirror</title>
<link rel="stylesheet" href="/static/css/bootstrap.css">
<link rel="stylesheet" href="/static/css/bootstrap-select.min.css">
<link rel="stylesheet" href="/static/css/font-awesome.min.css" >
<link rel="stylesheet" href="/static/css/style.css">
<link rel="stylesheet" href="/static/css/spinkit.css">
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<script src="/static/js/bootstrap-select.min.js"></script>
<script src="/static/js/vue.min.js"></script>
<script src="/static/js/markup.min.js"></script>
<script src="/static/js/webfont.js"></script>
</head>

View File

@ -7,7 +7,7 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/"><img src="/static/img/logo-small.png" alt=""/> 清华大学 TUNA 镜像源</a>
<a class="navbar-brand" href="/"><img src="/static/img/logo-small.png" alt=""/> 清华大学开源软件镜像站</a>
</div>
<div class="navbar-collapse collapse navbar-right">
<ul class="nav navbar-nav">

View File

@ -22,7 +22,7 @@
<label>选择帮助条目: </label>
<select class="form-control" id="help-select">
{% for h in help_pages %}
<option data-help-url="{{h.url}}">{{h.mirrorid}}</option>
<option data-help-url="{{h.url}}"{% if h.mirrorid == page.mirrorid%} selected{%endif%}>{{h.mirrorid}}</option>
{% endfor %}
</select>
</div>

View File

@ -0,0 +1,31 @@
---
layout: help
category: help
mirrorid: CocoaPods
---
## CocoaPods 镜像使用帮助
CocoaPods 是一个 Cocoa 和 Cocoa Touch 框架的依赖管理器,具体原理和 Homebrew 有点类似,都是从 GitHub 下载索引,然后根据索引下载依赖的源代码。
对于旧版的 CocoaPods 可以使用如下方法使用 tuna 的镜像:
```
$ pod repo remove master
$ pod repo add master https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git
$ pod repo update
```
新版的 CocoaPods 不允许用`pod repo add`直接添加master库了但是依然可以
```
$ cd ~/.cocoapods/repos
$ pod repo remove master
$ git clone https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git master
```
最后进入自己的工程,在自己工程的`podFile`第一行加上:
```
source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'
```

View File

@ -0,0 +1,48 @@
---
layout: help
category: help
mirrorid: anaconda
---
## Anaconda 镜像使用帮助
Anaconda 是一个用于科学计算的 Python 发行版,支持 Linux, Mac, Windows, 包含了众多流行的科学计算、数据分析的 Python 包。
Anaconda 安装包可以到 <https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/> 下载。
TUNA 还提供了 Anaconda 仓库的镜像,运行以下命令:
```
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --set show_channel_urls yes
```
即可添加 Anaconda Python 免费仓库。
运行 `conda install numpy` 测试一下吧。
## Miniconda 镜像使用帮助
Miniconda 是一个 Anaconda 的轻量级替代,默认只包含了 python 和 conda但是可以通过 pip 和 conda 来安装所需要的包。
Miniconda 安装包可以到 <https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/> 下载。
## Conda 三方源
当前tuna还维护了一些anaconda三方源。
### Conda Forge
```
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
```
### msys2
```
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/
```
### 其他三方源
对于conda的其他三方源如有需要请在[这个issue](https://github.com/tuna/issues/issues/112)中提出请求,我们会综合考虑多方因素来酌情增减。

View File

@ -10,9 +10,16 @@ permalink: /help/AOSP/
**注意: 本镜像是 AOSP 镜像Android SDK因版权原因我们不能提供镜像服务。**
参考 Google 教程 <https://source.android.com/source/downloading.html>
`https://android.googlesource.com/` 全部使用 `https://aosp.tuna.tsinghua.edu.cn/`
`git://aosp.tuna.tsinghua.edu.cn/aosp/` 代替即可。
`https://android.googlesource.com/` 全部使用 `https://aosp.tuna.tsinghua.edu.cn/` 代替即可。
由于使用 HTTPS 协议更安全,并且更便于我们灵活处理,所以强烈推荐使用 HTTPS 协议同步 AOSP 镜像。
**由于 AOSP 镜像造成CPU/内存负载过重,我们限制了并发数量,因此建议:**
1. sync的时候并发数不宜太高否则会出现 503 错误,即`-j`后面的数字不能太大建议选择4。
2. 请尽量选择流量较小时错峰同步。
- **2016-06-24 : 关闭 git:// 协议,仅支持 HTTPS**
- **2016-04-03 : 删除每月初始化包中的冗余内容,使用方法更新**
- **2015-12-21 : 增加每月初始化包,少量修正文档错误**
- **2015-10-13 : 修复上游替换文档错误**
- **2015-10-13 : 修复次级镜像文档错误**
@ -32,6 +39,34 @@ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
```
或者使用tuna的[git-repo镜像](https://mirrors.tuna.tsinghua.edu.cn/help/git-repo/)
#### 使用每月更新的初始化包
由于首次同步需要下载 24GB 数据,过程中任何网络故障都可能造成同步失败,我们强烈建议您使用初始化包进行初始化。
下载 <https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar>,下载完成后记得根据 checksum.txt 的内容校验一下。
由于所有代码都是从隐藏的 `.repo` 目录中 checkout 出来的,所以我们只保留了 `.repo` 目录,下载后解压
`repo sync` 一遍即可得到完整的目录。
使用方法如下:
```bash
wget https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar # 下载初始化包
tar xf aosp-latest.tar
cd AOSP # 解压得到的 AOSP 工程目录
# 这时 ls 的话什么也看不到,因为只有一个隐藏的 .repo 目录
repo sync # 正常同步一遍即可得到完整目录
# 或 repo sync -l 仅checkout代码
```
此后,每次只需运行 `repo sync` 即可保持同步。
**我们强烈建议您保持每天同步,并尽量选择凌晨等低峰时间**
#### 传统初始化方法
建立工作目录:
```
@ -43,12 +78,10 @@ cd WORKING_DIRECTORY
```
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest
# 或 repo init -u git://aosp.tuna.tsinghua.edu.cn/aosp/platform/manifest
## 如果提示无法连接到 gerrit.googlesource.com可以编辑 ~/bin/repo把 REPO_URL 一行替换成下面的:
REPO_URL = 'https://gerrit-google.tuna.tsinghua.edu.cn/git-repo'
```
**如果提示无法连接到 gerrit.googlesource.com请参照[git-repo的帮助页面](/help/git-repo)的更新一节。**
如果需要某个特定的 Android 版本([列表](https://source.android.com/source/build-numbers.html#source-code-tags-and-builds))
```
@ -62,21 +95,6 @@ repo sync
```
### 使用每月更新的初始化包
由于首次同步需要下载 37GB 数据,过程中任何网络故障都可能造成同步失败,因此你可以选择使用每月更新的初始化包。
首先到 http://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/ 选择合适自己的构建包aosp-latest.tar.xz 经过了 xz 压缩,
相对 aosp-latest.tar 小一些但是解压的时间也要考虑进来27G的压缩包呢(如果CPU核多可以使用pxz解压)
使用方法如下:
```
wget http://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar # 下载初始化包
tar xf aosp-latest.tar
cd AOSP # 解压得到的 AOSP 工程目录
repo sync # 正常同步
```
### 建立次级镜像
@ -94,13 +112,13 @@ repo sync # 正常同步
repo init -u https://aosp.tuna.tsinghua.edu.cn/mirror/manifest --mirror
```
同步源码树:
最后同步源码树:
```
repo sync
```
同步完成后,运行 `git daemon --verbose --export-all --base-path=WORKING_DIR WORKING_DIR` (WORKING_DIR为代码树所在目录) 。
同步完成后,运行 `git daemon --verbose --export-all --base-path=WORKING_DIR WORKING_DIR` (`WORKING_DIR`为代码树所在目录) 。
此后,其他用户使用 `git://ip.to.mirror/` 作为镜像即可。
@ -109,15 +127,14 @@ repo sync
如果你之前已经通过某种途径获得了 AOSP 的源码(或者你只是 init 这一步完成后)
你希望以后通过 TUNA 同步 AOSP 部分的代码,只需要将
`.repo/manifest.xml` 把其中的 aosp 这个 remote 的 fetch 从
`https://android.googlesource.com` 改为 `https://aosp.tuna.tsinghua.edu.cn/`
`git://aosp.tuna.tsinghua.edu.cn/aosp`
`https://android.googlesource.com` 改为 `https://aosp.tuna.tsinghua.edu.cn/`
```diff
<manifest>
<remote name="aosp"
- fetch="https://android.googlesource.com"
+ fetch="https://aosp.tuna.tsinghua.edu.cn" 或 "git://aosp.tuna.tsinghua.edu.cn/aosp"
+ fetch="https://aosp.tuna.tsinghua.edu.cn"
review="android-review.googlesource.com" />
<remote name="github"
@ -133,11 +150,8 @@ url = https://android.googlesource.com/platform/manifest
```
url = https://aosp.tuna.tsinghua.edu.cn/platform/manifest
# 或 url = git://aosp.tuna.tsinghua.edu.cn/aosp/platform/manifest
```
**这个方法也可以用来在同步 Cyanogenmod 代码的时候从 TUNA 同步部分代码**
### FAQ
1. 镜像的是什么?

View File

@ -0,0 +1,26 @@
---
category: help
layout: help
mirrorid: archlinux
---
## Arch Linux 软件仓库镜像使用帮助
编辑 /etc/pacman.d/mirrorlist 在文件的最顶端添加:
```
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch
```
更新软件包缓存:
```
sudo pacman -Syy
```
## Arch Linux Rollback Machine使用帮助
因为 Arch Linux 的软件仓库和 iso 列表是不维护旧版本的,在少数情况下可能会需要安装旧版本的软件或系统,
因此TUNA维护了一个[Arch Linux Rollback Machine](https://arch-archive.tuna.tsinghua.edu.cn/)来满足这种情况。
Arch Linux Rollback Machine的使用方法请参照 [wiki](https://wiki.archlinux.org/index.php/Arch_Linux_Archive)。
**需要注意的是TUNA的Rollback Machine的目录结构与wiki中的目录结构并不相同配置时请自行替代。**

View File

@ -13,14 +13,13 @@ Arch Linux 中文社区仓库 是由 Arch Linux
[点击这里](https://github.com/archlinuxcn/repo) 查看。
*  官方仓库地址:<http://repo.archlinuxcn.org>
*  镜像地址: <http://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/>
*  镜像地址: <https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/>
使用方法:在 `/etc/pacman.conf` 文件末尾添加以下两行:
```
[archlinuxcn]
SigLevel = Optional TrustedOnly
Server = http://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/$arch
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/$arch
```
之后安装 `archlinuxcn-keyring` 包导入 GPG key。

View File

@ -0,0 +1,68 @@
---
category: help
layout: help
mirrorid: bananian
---
## Bananian 镜像使用帮助
[Bananian](https://www.bananian.org/) 是为 [Banana Pi](http://www.banana-pi.org/) 制作的,基于官方 Debian 仓库的发行版,
其内核和 bootloader 为 Banana Pi 做了定制化。
安装镜像可以到 <https://mirrors.tuna.tsinghua.edu.cn/bananian/releases/> 获取。
### 使用 TUNA 镜像作为软件仓库
首先需要信任 Bananian 的 GPG 公钥
```
gpg --recv-keys 24BFF712
gpg --armor --export 24BFF712 | sudo apt-key add -
```
之后添加 Bananian 仓库,运行以下命令即可
<form class="form-inline">
<div class="form-group">
<label>选择你的 Bananian 版本: </label>
<select class="form-control release-select" data-template="#apt-template" data-target="#apt-content">
<option data-release="1604" data-opt='{"debian": "jessie"}' selected>16.04</option>
<option data-release="jessie" data-opt='{"debian": "jessie"}'>15.08</option>
<option data-release="wheezy" data-opt='{"debian": "wheezy"}'>15.04 或更早</option>
</select>
</div>
</form>
{% raw %}
<script id="apt-template" type="x-tmpl-markup">
# 激活 TUNA bananian 镜像
sudo cat > /etc/apt/sources.list.d/bananian.list << EOF
deb http://mirrors.tuna.tsinghua.edu.cn/bananian/packages {{release_name}} main
EOF
# 激活 TUNA debian 镜像
sudo cat > /etc/apt/sources.list << EOF
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ {{debian}} main contrib non-free
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ {{debian}}-backports main contrib non-free
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ {{debian}}-updates main contrib non-free
deb http://mirrors.tuna.tsinghua.edu.cn/debian-security/ {{debian}}/updates main contrib non-free
deb-src http://mirrors.tuna.tsinghua.edu.cn/debian/ {{debian}} main contrib non-free
deb-src http://mirrors.tuna.tsinghua.edu.cn/debian/ {{debian}}-backports main contrib non-free
deb-src http://mirrors.tuna.tsinghua.edu.cn/debian/ {{debian}}-updates main contrib non-free
deb-src http://mirrors.tuna.tsinghua.edu.cn/debian-security/ {{debian}}/updates main contrib non-free
EOF
</script>
{% endraw %}
<p></p>
<pre>
<code id="apt-content">
</code>
</pre>
更新软件包缓存
```
sudo apt-get update
```

View File

@ -0,0 +1,102 @@
---
category: help
layout: help
mirrorid: centos
---
## CentOS 镜像使用帮助
首先备份 CentOS-Base.repo
```
sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
```
之后启用 TUNA 软件仓库, 将以下内容写入 /etc/yum.repos.d/CentOS-Base.repo
<form class="form-inline">
<div class="form-group">
<label>选择你的 CentOS 版本: </label>
<select class="form-control release-select" data-template="#repo-template" data-target="#repo-content">
<option data-release="5">CentOS 5</option>
<option data-release="6">CentOS 6</option>
<option data-release="7" selected>CentOS 7</option>
</select>
</div>
</form>
{% raw %}
<script id="repo-template" type="x-tmpl-markup">
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[base]
name=CentOS-$releasever - Base
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/os/$basearch/
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-{{release_name}}
#released updates
[updates]
name=CentOS-$releasever - Updates
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/updates/$basearch/
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-{{release_name}}
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/extras/$basearch/
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-{{release_name}}
{{if release_name|equals>5}}
#packages used/produced in the build but not released
[addons]
name=CentOS-$releasever - Addons
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/addons/$basearch/
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=addons
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-{{release_name}}
{{/if}}
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/centosplus/$basearch/
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-{{release_name}}
{{if release_name|between>5>6}}
#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/contrib/$basearch/
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=contrib
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-{{release_name}}{{/if}}
</script>
{% endraw %}
<p></p>
<pre>
<code id="repo-content">
</code>
</pre>
更新软件包缓存
```
sudo yum makecache
```

View File

@ -0,0 +1,86 @@
---
layout: help
category: help
mirrorid: chromiumos
permalink: /help/chromiumos/
---
## Chromium OS 镜像使用帮助
> Chromium OS is an open-source project that aims to build an operating system that provides a fast, simple, and more secure computing experience for people who spend most of their time on the web.
#### 准备工作
下载 repo 工具:
```bash
mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
```
或者使用tuna的[git-repo镜像](https://mirrors.tuna.tsinghua.edu.cn/help/git-repo/)
#### 下载代码
建立工作目录:
```
mkdir WORKING_DIRECTORY
cd WORKING_DIRECTORY
```
初始化仓库:
```
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/chromiumos/chromiumos/manifest
```
**注意: 本镜像是 Chromium OS 的 master 分支的镜像,如果使用本镜像下载 Chromium OS 的其他版本很大概率会失败**
**如果提示无法连接到 gerrit.googlesource.com请参照[git-repo的帮助页面](/help/git-repo)的更新一节。**
接着使用编辑器打开`.repo/manifests/_remotes.xml`这个文件,将
```
"https://chromium.googlesource.com"
```
替换为
```
"https://mirrors.tuna.tsinghua.edu.cn/git/chromiumos/"
```
```
"https://android.googlesource.com"
```
替换为
```
"https://aosp.tuna.tsinghua.edu.cn/"
```
```
"https://weave.googlesource.com"
```
替换为
```
"https://mirrors.tuna.tsinghua.edu.cn/git/weave/"
```
即可。
最后同步源码树(以后只需执行这条命令来同步):
```
repo sync
```

View File

@ -0,0 +1,21 @@
---
category: help
layout: help
mirrorid: cygwin
---
Cygwin 镜像使用帮助
==================
<https://cygwin.com> 上下载 [setup-x86.exe](https://cygwin.com/setup-x86.exe) 或 [setup-x86_64.exe](https://cygwin.com/setup-x86_64.exe)。
选择`Install from Internet`, 在"User URL"处输入以下地址注意Cygwin貌似**不支持使用https**。(但由于setup.exe是以https链接分发而镜像文件中又有.sig签名文件所以可以认为http的镜像是安全的)
```
http://mirrors.tuna.tsinghua.edu.cn/cygwin/
```
点击"Add"按钮, 然后选中"http://mirrors.tuna.tsinghua.edu.cn", 点击"下一步"进行安装。
注意,该列表为可多选列表,注意把上面不需要的镜像点掉。

View File

@ -25,14 +25,11 @@ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58
<div class="form-group">
<label>你的Debian/Ubuntu版本: </label>
<select class="form-control release-select" data-template="#apt-template" data-target="#apt-content">
<option data-release="debian-wheezy">Debian Wheezy</option>
<option data-release="debian-jessie" selected>Debian Jessie</option>
<option data-release="debian-stretch">Debian Strech</option>
<option data-release="ubuntu-precise">Ubuntu 12.04 LTS</option>
<option data-release="ubuntu-trusty">Ubuntu 14.04 LTS</option>
<option data-release="ubuntu-utopic">Ubuntu 14.10</option>
<option data-release="ubuntu-vivid">Ubuntu 15.04</option>
<option data-release="ubuntu-wily">Ubuntu 15.10</option>
<option data-os="debian" data-release="wheezy">Debian Wheezy</option>
<option data-os="debian" data-release="jessie" selected>Debian Jessie</option>
<option data-os="ubuntu" data-release="precise">Ubuntu 12.04 LTS</option>
<option data-os="ubuntu" data-release="trusty">Ubuntu 14.04 LTS</option>
<option data-os="ubuntu" data-release="xenial">Ubuntu 16.04 LTS</option>
</select>
</div>
</form>
@ -58,7 +55,7 @@ sudo apt-get install docker-engine
{% raw %}
<script id="apt-template" type="x-tmpl-markup">
echo "deb https://mirrors.tuna.tsinghua.edu.cn/docker/apt/repo {{release_name}} main" | sudo tee /etc/apt/sources.list.d/docker.list
echo "deb {{if os_name|equals>ubuntu}}https{{else}}http{{/if}}://mirrors.tuna.tsinghua.edu.cn/docker/apt/repo {{os_name}}-{{release_name}} main" | sudo tee /etc/apt/sources.list.d/docker.list
</script>
{% endraw %}
@ -70,13 +67,10 @@ echo "deb https://mirrors.tuna.tsinghua.edu.cn/docker/apt/repo {{release_name}}
<div class="form-group">
<label>你的Fedora/CentOS/RHEL版本: </label>
<select class="form-control release-select" data-template="#yum-template" data-target="#yum-content">
<option data-release="centos/6">CentOS 6</option>
<option data-release="centos/7" selected>CentOS 7</option>
<option data-release="centos/6">RHEL 6</option>
<option data-release="centos/7">RHEL 7</option>
<option data-release="fedora/20">Fedora 20</option>
<option data-release="fedora/21">Fedora 21</option>
<option data-release="fedora/22">Fedora 22</option>
<option data-release="centos6">CentOS 6</option>
<option data-release="centos7" selected>CentOS 7</option>
<option data-release="centos6">RHEL 6</option>
<option data-release="centos7">RHEL 7</option>
</select>
</div>
</form>
@ -99,7 +93,7 @@ sudo yum install docker-engine
<script id="yum-template" type="x-tmpl-markup">
[dockerrepo]
name=Docker Repository
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker/yum/repo/main/{{release_name}}
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker/yum/repo/{{release_name}}
enabled=1
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker/yum/gpg

View File

@ -0,0 +1,84 @@
---
category: help
layout: help
mirrorid: elpa
---
ELPA 镜像使用帮助
==================
ELPA 是 Emacs 内建包管理器 `package.el` 的软件源,本镜像支持了常见的 ELPA。
| ELPA | 镜像地址 |
|-------------------|---------------------------------------------|
| [GNU ELPA](http://elpa.gnu.org/) | http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/ |
| [MELPA](https://melpa.org/) | http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/ |
| [MELPA Stable](http://stable.melpa.org/#/) | http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa-stable/ |
| [Marmalade](https://marmalade-repo.org/) | http://mirrors.tuna.tsinghua.edu.cn/elpa/marmalade/ |
| [Org](http://orgmode.org/elpa.html) | http://mirrors.tuna.tsinghua.edu.cn/elpa/org/ |
根据你的需求,设置 package-archives ,比如用 GNU ELPA 和 MELPA
```lisp
(setq package-archives '(("gnu" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
("melpa" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")))
(package-initialize) ;; You might already have this line
```
Spacemacs 用户
--------------
添加下面的代码到`.spacemacs`的`dotspacemacs/user-init()`
```lisp
(setq configuration-layer--elpa-archives
'(("melpa-cn" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")
("org-cn" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/org/")
("gnu-cn" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")))
```
Cask 用户
---------
[Cask](https://github.com/cask/cask) 是一个 Emacs Lisp 的项目管理工具。这里还是以 GNU ELPA 和 MELPA 为例,在添加下面的代码到 Cask
```lisp
(source "gnu" "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
(source "melpa" "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")
```
关于 ELPA 的选择
----------------
(来自[@xuchunyang](https://github.com/xuchunyang))
假如不清楚需要用哪些 ELPA 的话
- `gnu` 一般是必备的,其它的 elpa 中的包会依赖 `gnu` 中的包
- `melpa` 滚动升级,收录了的包的数量最大
- `melpa-stable` 依据源码的 Tag Git升级数量比 `melpa` 少,因为很多包作者根本不打 Tag
- `org` 仅仅为了 `org-plus-contrib` 这一个包org 重度用户使用
- `marmalade` 似乎已经不维护了,个人不推荐
上游
====
本镜像的上游为 <http://elpa.emacs-china.org/>本文档也参考了emacs-china提供的帮助。
URL Bug
=======
各个仓库的URL末尾一定要加`/`,否则会无法拉取,提示`Failed to download melpa archive`。
事实上,末尾没有`/`的话emacs会去尝试取以下链接:
- <http://mirrors.tuna.tsinghua.edu.cn/elpa/melpaarchive-contents>
而正常的链接应该是
- <http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/archive-contents>
这个是emacs自己的bug。在 <https://github.com/melpa/melpa/issues/2139> 中有描述。

View File

@ -0,0 +1,58 @@
---
layout: help
category: help
mirrorid: epel
---
## EPEL 镜像使用帮助
EPEL(Extra Packages for Enterprise Linux)是由Fedora Special Interest Group维护的Enterprise LinuxRHEL、CentOS中经
常用到的包。
下面以CentOS 7为例讲解如何使用tuna的epel镜像。
首先从CentOS Extras这个源[tuna](https://mirrors.tuna.tsinghua.edu.cn/help/centos)也有镜像里安装epel-release
```
yum install epel-release
```
当前tuna已经在epel的官方镜像列表里所以不需要其他配置mirrorlist机制就能让你的服务器就近使用tuna的镜像。如果你想强制
你的服务器使用tuna的镜像可以修改`/etc/yum.repos.d/epel.repo`,将`baseurl`开头的行取消注释(删掉`#`),并注释`mirrorlist`
开头的行(在头部加一个`#`)。
接下来,把这个文件里的`http://download.fedoraproject.org/pub`替换成`https://mirrors.tuna.tsinghua.edu.cn`即可。
修改结果如下
```
[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
[epel-debuginfo]
name=Extra Packages for Enterprise Linux 7 - $basearch - Debug
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch/debug
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-7&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=1
[epel-source]
name=Extra Packages for Enterprise Linux 7 - $basearch - Source
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/SRPMS
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-7&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=1
```
运行 `yum update` 测试一下吧。

View File

@ -0,0 +1,45 @@
---
category: help
layout: help
mirrorid: fedora
---
Fedora 镜像使用帮助
===================
Fedora 的软件源配置文件可以有多个,其中:
系统默认的 `fedora` 仓库配置文件为 `/etc/yum.repos.d/fedora.repo`,系统默认的 `updates` 仓库配置文件为 `/etc/yum.repos.d/fedora-updates.repo` 。将上述两个文件先做个备份分别替换为下面内容即可使用TUNA 的软件源镜像。
**`fedora` 仓库 (/etc/yum.repos.d/fedora.repo)**
```
[fedora]
name=Fedora $releasever - $basearch
failovermethod=priority
baseurl=https://mirrors.tuna.tsinghua.edu.cn/fedora/releases/$releasever/Everything/$basearch/os/
enabled=1
metadata_expire=28d
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
skip_if_unavailable=False
```
**`updates` 仓库 (/etc/yum.repos.d/fedora-updates.repo)**
```
[updates]
name=Fedora $releasever - $basearch - Updates
failovermethod=priority
baseurl=https://mirrors.tuna.tsinghua.edu.cn/fedora/updates/$releasever/$basearch/
enabled=1
gpgcheck=1
metadata_expire=6h
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
skip_if_unavailable=False
```
更新本地缓存
```
sudo dnf makecache
```

View File

@ -0,0 +1,30 @@
---
category: help
layout: help
mirrorid: git-repo
---
## Git Repo 镜像使用帮助
> Repo is a tool that we built on top of Git. Repo helps us manage the many Git repositories, does the uploads to our revision control system, and automates parts of the Android development workflow. Repo is not meant to replace Git, only to make it easier to work with Git in the context of Android. The repo command is an executable Python script that you can put anywhere in your path.
当前repo主要用于同步AOSP、chromium及chromium OS。
### 下载
```
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o repo
chmod +x repo
```
为了方便可以将其拷贝到你的`PATH`里。
### 更新
repo的运行过程中会尝试访问官方的git源更新自己如果想使用tuna的镜像源进行更新可以将如下内容复制到你的`~/.bashrc`里
```
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'
```
并重启终端模拟器。

View File

@ -22,10 +22,12 @@ curl https://packages.gitlab.com/gpg.key 2> /dev/null | sudo apt-key add - &>/de
<div class="form-group">
<label>你的Debian/Ubuntu版本: </label>
<select class="form-control release-select" data-template="#apt-template" data-target="#apt-content">
<option data-os="debian" data-release="wheezy">Debian 7 (Wheezy)</option>
<option data-os="debian" data-release="jessie" selected>Debian 8 (Jessie)</option>
<option data-os="ubuntu" data-release="trusty">Ubuntu 14.04 LTS</option>
</select>
<option data-os="debian" data-release="wheezy">Debian 7 (Wheezy)</option>
<option data-os="debian" data-release="jessie" selected>Debian 8 (Jessie)</option>
<option data-os="debian" data-release="stretch" selected>Debian 9 (Stretch)</option>
<option data-os="ubuntu" data-release="trusty">Ubuntu 14.04 LTS</option>
<option data-os="ubuntu" data-release="xenial">Ubuntu 16.04 LTS</option>
</select>
</div>
</form>
@ -45,48 +47,27 @@ sudo apt-get install gitlab-ce
{% raw %}
<script id="apt-template" type="x-tmpl-markup">
deb https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/{{os_name}} {{release_name}} main
deb {{if os_name|equals>ubuntu}}https{{else}}http{{/if}}://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/{{os_name}} {{release_name}} main
</script>
{%endraw%}
### CentOS/RHEL
### RHEL/CentOS 用户
新建 `/etc/yum.repos.d/gitlab-ce.repo`,内容为
<form class="form-inline">
<div class="form-group">
<label>你的CentOS/RHEL版本: </label>
<select class="form-control release-select" data-template="#yum-template" data-target="#yum-content">
<option data-release="el6">CentOS 6</option>
<option data-release="el7" selected>CentOS 7</option>
<option data-release="el6">RHEL 6</option>
<option data-release="el7">RHEL 7</option>
</select>
</div>
</form>
```
[gitlab-ce]
name=Gitlab CE Repository
baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/
gpgcheck=0
enabled=1
```
<p></p>
<pre>
<code id="yum-content">
</code>
</pre>
再执行
再执行
```
sudo yum makecache
sudo yum install gitlab-ce
sudo yum install gitlab-ce
```
{% raw %}
<script id="yum-template" type="x-tmpl-markup">
[gitlab-ce]
name=gitlab-ce
baseurl=http://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/{{release_name}}
repo_gpgcheck=0
gpgcheck=0
enabled=1
gpgkey=https://packages.gitlab.com/gpg.key
</script>
{% endraw %}

View File

@ -0,0 +1,93 @@
---
category: help
layout: help
mirrorid: gitlab-ci-multi-runner
---
## Gitlab CI Multi Runner 镜像使用帮助
**注意: gitlab-ci-multi-runner 镜像仅支持 x86-64 架构**
### Debian/Ubuntu 用户
首先信任 GitLab 的 GPG 公钥:
```
curl https://packages.gitlab.com/gpg.key 2> /dev/null | sudo apt-key add - &>/dev/null
```
再选择你的 Debian/Ubuntu 版本,文本框中内容写进 `/etc/apt/sources.list.d/gitlab-ci-multi-runner.list`
<form class="form-inline">
<div class="form-group">
<label>你的Debian/Ubuntu版本: </label>
<select class="form-control release-select" data-template="#apt-template" data-target="#apt-content">
<option data-os="debian" data-release="wheezy">Debian 7 (Wheezy)</option>
<option data-os="debian" data-release="jessie" selected>Debian 8 (Jessie)</option>
<option data-os="ubuntu" data-release="trusty">Ubuntu 14.04 LTS</option>
<option data-os="ubuntu" data-release="xenial">Ubuntu 16.04 LTS</option>
</select>
</div>
</form>
<p></p>
<pre>
<code id="apt-content">
</code>
</pre>
安装 gitlab-ci-multi-runner:
```
sudo apt-get update
sudo apt-get install gitlab-ci-multi-runner
```
{% raw %}
<script id="apt-template" type="x-tmpl-markup">
deb {{if os_name|equals>ubuntu}}https{{else}}http{{/if}}://mirrors.tuna.tsinghua.edu.cn/gitlab-ci-multi-runner/{{os_name}} {{release_name}} main
</script>
{%endraw%}
### CentOS/RHEL
新建 `/etc/yum.repos.d/gitlab-ci-multi-runner.repo`,内容为
<form class="form-inline">
<div class="form-group">
<label>你的CentOS/RHEL版本: </label>
<select class="form-control release-select" data-template="#yum-template" data-target="#yum-content">
<option data-release="el6">CentOS 6</option>
<option data-release="el7" selected>CentOS 7</option>
<option data-release="el6">RHEL 6</option>
<option data-release="el7">RHEL 7</option>
</select>
</div>
</form>
<p></p>
<pre>
<code id="yum-content">
</code>
</pre>
再执行
```
sudo yum makecache
sudo yum install gitlab-ci-multi-runner
```
{% raw %}
<script id="yum-template" type="x-tmpl-markup">
[gitlab-ci-multi-runner]
name=gitlab-ci-multi-runner
baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ci-multi-runner/yum/{{release_name}}
repo_gpgcheck=0
gpgcheck=0
enabled=1
gpgkey=https://packages.gitlab.com/gpg.key
</script>
{% endraw %}

View File

@ -16,7 +16,26 @@ cabal update
待生成`~/.cabal/config`之后`Ctrl+C`, 然后进行下一步。
### 已经存在`config`
### Cabal ≥ 1.2.4 (GHC 8.0)
修改 `~/.cabal/config`,加入
```
repository mirrors.tuna.tsinghua.edu.cn
url: http://mirrors.tuna.tsinghua.edu.cn/hackage
```
为了访问速度,可以选择把官方仓库注释掉:
```
repository hackage.haskell.org
url: http://hackage.haskell.org/
-- secure: False
-- root-keys:
-- key-threshold:
```
### Cabal < 1.2.4
修改`~/.cabal/config`, 将此行
@ -40,7 +59,7 @@ remote-repo: mirrors.tuna.tsinghua.edu.cn:http://mirrors.tuna.tsinghua.edu.cn/ha
```yaml
package-indices:
- name: Tsinghua
download-prefix: http://mirrors.tuna.tsinghua.edu.cn/hackage/package/
http: http://mirrors.tuna.tsinghua.edu.cn/hackage/00-index.tar.gz
- name: Tsinghua
download-prefix: http://mirrors.tuna.tsinghua.edu.cn/hackage/package/
http: http://mirrors.tuna.tsinghua.edu.cn/hackage/00-index.tar.gz
```

View File

@ -0,0 +1,20 @@
---
category: help
layout: help
mirrorid: homebrew-bottles
---
## Homebrew-bottles 镜像使用帮助
**注:该镜像是 Homebrew 二进制预编译包的镜像。本镜像站同时提供 Homebrew 的 formula 索引的镜像(即 `brew update` 时所更新内容),请参考 [Homebrew 镜像使用帮助](https://mirrors.tuna.tsinghua.edu.cn/help/homebrew/)。**
### 临时替换
```bash
export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles
```
### 长期替换
```bash
echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles' >> ~/.bash_profile
source ~/.bash_profile
```

View File

@ -6,33 +6,28 @@ mirrorid: homebrew
## Homebrew 镜像使用帮助
**注:该镜像是 Homebrew 的 formula 索引的镜像(即 `brew update` 时所更新内容)。本镜像站同时提供 Homebrew 二进制预编译包的镜像,请参考 [Homebrew bottles 镜像使用帮助](https://mirrors.tuna.tsinghua.edu.cn/help/homebrew-bottles/)。**
### 替换现有上游
```
cd /usr/local
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew.git
cd "$(brew --repo)"
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git
brew update
```
如果速度还是很慢,可以尝试以下操作: 然后重试update。
```
cd ~/tmp
git clone https://mirrors.tuna.tsinghua.edu.cn/git/homebrew.git
rm -rf /usr/local/.git
rm -rf /usr/local/Library
cp -R homebrew/.git /usr/local/
cp -R homebrew/Library /usr/local/
```
### 使用homebrew-science或者homebrew-python
```
cd /usr/local/Library/Taps/homebrew/homebrew-science
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew-science.git
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-science"
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-science.git
cd /usr/local/Library/Taps/homebrew/homebrew-python
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew-python.git
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-python"
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-python.git
brew update
```

View File

@ -0,0 +1,18 @@
---
layout: help
category: help
mirrorid: lineage-rom
permalink: /help/lineage-rom/
---
## Lineage 介绍
Lineage OS 是全球最大的 Android 发行版之一,前身是 Cyanogenmod。
## Lineage rom 镜像使用帮助
正常情况下Lineage会根据你的地址来定向请求到最近的镜像站因此通常情况下不需要手动选择镜像站进行下载直接前往官方的下载网站下载即可。
但是如果你是校内的同学或者因为其他原因希望一定从tuna下载Lineage的rom可以直接访问 <https://mirrors.tuna.tsinghua.edu.cn/lineage-rom/full/> 选择设备代码及时间进行下载,或者在镜像站的主页右边或下方找到"获取下载链接",在 操作系统 -> LineageOS 下找到最新的 rom 进行下载。
zip文件的使用方式请参考lineage的官方文档或自行Google。

View File

@ -0,0 +1,82 @@
---
layout: help
category: help
mirrorid: lineageOS
permalink: /help/lineageOS/
---
## lineageOS 源代码镜像使用帮助
**注意: 本镜像是 lineageOS 源代码的镜像如果是希望下载lineage的rom请访问 <https://mirrors.tuna.tsinghua.edu.cn/help/lineage-rom/>。**
### 过程摘录
下载 repo 工具:
```bash
mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
```
或者使用tuna的[git-repo镜像](https://mirrors.tuna.tsinghua.edu.cn/help/git-repo/)
建立工作目录:
```
mkdir WORKING_DIRECTORY
cd WORKING_DIRECTORY
```
初始化仓库:
```
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/lineageOS/LineageOS/android.git -b cm-14.1
```
(如果已经有从github同步的lineageOS源代码可以从这里直接开始
打开`.repo/manifest.xml`,将
```xml
<remote name="github"
fetch=".."
```
改成
```xml
<remote name="github"
fetch="https://mirrors.tuna.tsinghua.edu.cn/git/lineageOS/"
```
```xml
<remote name="aosp"
fetch="https://android.googlesource.com"
```
改成
```xml
<remote name="aosp"
fetch="https://aosp.tuna.tsinghua.edu.cn"
```
同步源码树(以后只需执行这条命令来同步):
```
repo sync
```
###异常处理
1. 对于有些Lineage的prebuild仓库因为使用了`clone-depth="1"`导致了HTTP协议下同步出现错误`fatal: dumb http transport does not support --depth`,解决的办法如下:
```
sed -i 's/clone-depth="1"//' .repo/manifest.xml
sed -i 's/clone-depth="1"//' .repo/manifests/snippets/cm.xml
```
2. 部分仓库例如`Lineage_framework_base`同步的时候会出现bundle错误这时候可以使用命令`repo sync --no-clone-bundle`进行同步就没有问题了

View File

@ -0,0 +1,28 @@
---
category: help
layout: help
mirrorid: linux-stable.git
---
## Linux Kernel Git Stable 分支镜像使用帮助
如需克隆 linux 代码,使用
```
git clone https://mirrors.tuna.tsinghua.edu.cn/git/linux-stable.git
```
若要将 tuna mirror 加入已有代码库,可在已有仓库中运行
```
git remote add tuna https://mirrors.tuna.tsinghua.edu.cn/git/linux-stable.git
```
或运行
```
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/linux-stable.git
```
将默认上游设置为 TUNA 镜像

View File

@ -14,3 +14,12 @@ LXC 1.0 以上版本增加了 `download` 模版,支持下载定义好的系统
```
# lxc-create -t download -n my-container -- --server mirrors.tuna.tsinghua.edu.cn/lxc-images
```
**LXD/LXC 2.0使用镜像加速的方法**:
创建一个remote链接指向镜像站即可或替换掉默认的images链接。
```
# lxc remote add tuna-images https://mirrors.tuna.tsinghua.edu.cn/lxc-images/ --protocol=simplestreams --public
# lxc image list tuna-images:
```

View File

@ -23,10 +23,9 @@ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
<div class="form-group">
<label>你的Debian/Ubuntu版本: </label>
<select class="form-control release-select" data-template="#apt-template" data-target="#apt-content">
<!--<option data-os="debian" data-release="jessie" selected>Debian 8 (Jessie)</option>-->
<option data-os="debian" data-release="wheezy">Debian 7 (Wheezy)</option>
<option data-os="ubuntu" data-release="trusty" selected>Ubuntu 14.04 LTS</option>
<option data-os="ubuntu" data-release="precise">Ubuntu 12.04 LTS</option>
<option data-os="debian" data-release="wheezy" data-opt='{"repo-name": "main"}'>Debian 7 (Wheezy)</option>
<option data-os="ubuntu" data-release="trusty" data-opt='{"repo-name": "multiverse"}' selected>Ubuntu 14.04 LTS</option>
<option data-os="ubuntu" data-release="precise" data-opt='{"repo-name": "multiverse"}'>Ubuntu 12.04 LTS</option>
</select>
</div>
</form>
@ -39,7 +38,7 @@ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
{% raw %}
<script id="apt-template" type="x-tmpl-markup">
deb http://mirrors.tuna.tsinghua.edu.cn/mongodb/apt/{{os_name}} {{release_name}}/mongodb-org/stable multiverse
deb {{if os_name|equals>ubuntu}}https{{else}}http{{/if}}://mirrors.tuna.tsinghua.edu.cn/mongodb/apt/{{os_name}} {{release_name}}/mongodb-org/stable {{repo-name}}
</script>
{%endraw%}
@ -58,7 +57,7 @@ sudo apt-get install -y mongodb-org
```
[mongodb-org]
name=MongoDB Repository
baseurl=http://mirrors.tuna.tsinghua.edu.cn/mongodb/yum/$releasever/
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mongodb/yum/el$releasever/
gpgcheck=0
enabled=1
```

View File

@ -0,0 +1,45 @@
---
category: help
layout: help
mirrorid: msys2
---
MSYS2 镜像使用帮助
==================
收录架构
--------
* MINGW: i686, x86_64
* MSYS: i686, x86_64
安装
--------------
请访问该镜像目录下的 `distrib/` 目录([x86_64](https://mirrors.tuna.tsinghua.edu.cn/msys2/distrib/x86_64) 、[i686](https://mirrors.tuna.tsinghua.edu.cn/msys2/distrib/i686/)),找到名为 `msys2-<架构>-<日期>.exe` 的文件(如 `msys2-x86_64-20141113.exe`),下载安装即可。
pacman 的配置
-------------
编辑 `/etc/pacman.d/mirrorlist.mingw32` ,在文件开头添加:
```bash
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/i686
```
编辑 `/etc/pacman.d/mirrorlist.mingw64` ,在文件开头添加:
```bash
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/x86_64
```
编辑 `/etc/pacman.d/mirrorlist.msys` ,在文件开头添加:
```bash
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/msys/$arch
```
然后执行 `pacman -Sy` 刷新软件包数据即可。
注: 本Help参考自[USTC镜像](https://lug.ustc.edu.cn/wiki/mirrors/help/msys2)

View File

@ -19,4 +19,4 @@ curl -sL https://deb.nodesource.com/setup | sudo bash -
编辑 `/etc/apt/sources.list.d/nodesource.list`,把
`https://deb.nodesource.com/node/` 替换为
`http://mirrors.tuna.tsinghua.edu.cn/nodesource/deb/` 即可。
`https://mirrors.tuna.tsinghua.edu.cn/nodesource/deb/` 即可。

View File

@ -1,30 +0,0 @@
---
category: help
layout: help
mirrorid: npm
---
NPM 镜像使用帮助
====================
注: TUNA 使用 [sinopia](https://github.com/rlidwka/sinopia/) 提供 npm 访问加速。
临时使用
--------
```
npm install <packagename> --registry https://npm.tuna.tsinghua.edu.cn/
```
默认使用
-------
```
npm set registry https://npm.tuna.tsinghua.edu.cn/
```
或编辑 `~/.npmrc` 添加
```
registry=https://npm.tuna.tsinghua.edu.cn
```

View File

@ -0,0 +1,48 @@
---
category: help
layout: help
mirrorid: pybombs
---
PyBOMBS 镜像使用帮助
===================
[PyBOMBS](http://gnuradio.org/redmine/projects/pybombs/wiki) (Python Build Overlay Managed Bundle System) 是 [GNU Radio](http://gnuradio.org/) 的包管理系统。
从头开始一键安装GNU Radio在Thinkpad X230上实测大约只需要40分钟下载非常快主要的时间就剩编译了。 而且安装的都是最新的版本。
另外PyBOMBS会帮你解决依赖的问题省得每次敲一堆make cmake命令了。
以前自己拖代码回来经常会被重置,而且耗时要几个小时。
**使用示例**
```bash
sudo pip install pybombs
rm -rf ~/.pybombs
pybombs recipes add gr-recipes git+https://mirrors.tuna.tsinghua.edu.cn/pybombs/recipes/gr-recipes.git
pybombs recipes add gr-etcetera git+https://mirrors.tuna.tsinghua.edu.cn/pybombs/recipes/gr-etcetera.git
mkdir gnuradio-prefix
cd gnuradio-prefix
pybombs prefix init
pybombs install gnuradio
. ./setup_env.sh
gnuradio-companion
pybombs install rtl-sdr hackrf bladeRF gr-osmosdr gr-bluetooth gr-ieee-80211
```
**更新**
由于 PyBOMBS 的 recipes 只能通过 git 仓库进行发布。而我们暂时不想维护一个复杂的 git 分支合并历史。所以更新时,需要将 recipe 仓库删除,然后再重新添加回来。(见[讨论](http://lists.gnu.org/archive/html/discuss-gnuradio/2016-06/msg00170.html))
```bash
pybombs recipes remove gr-recipes
pybombs recipes remove gr-etcetera
pybombs recipes add gr-recipes git+https://mirrors.tuna.tsinghua.edu.cn/pybombs/recipes/gr-recipes.git
pybombs recipes add gr-etcetera git+https://mirrors.tuna.tsinghua.edu.cn/pybombs/recipes/gr-etcetera.git
```
- 本镜像使用 <http://github.com/scateu/pybombs-mirror> 脚本进行构建。

View File

@ -18,10 +18,12 @@ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
### 设为默认
修改 `~/.pip/pip.conf` (没有就创建一个) 修改
修改 `~/.config/pip/pip.conf` (Linux), `%APPDATA%\pip\pip.ini` (Windows 10) 或 `$HOME/Library/Application Support/pip/pip.conf` (macOS) (没有就创建一个) 修改
`index-url`至tuna例如
```
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
```
pip 和 pip3 并存时,只需修改 `~/.pip/pip.conf`

View File

@ -18,7 +18,7 @@ mirrorid: repo-ck
```
[repo-ck]
Server = http://mirrors.tuna.tsinghua.edu.cn/repo-ck/$arch
Server = https://mirrors.tuna.tsinghua.edu.cn/repo-ck/$arch
```
再增加 GPG 信任:

View File

@ -17,19 +17,19 @@ sudo yum install --nogpgcheck http://download1.rpmfusion.org/free/fedora/rpmfusi
或者如下直接用 TUNA 镜像中的 rpm 包:
```
sudo yum install --nogpgcheck http://mirrors.tuna.tsinghua.edu.cn/rpmfusion/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm http://mirrors.tuna.tsinghua.edu.cn/rpmfusion/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
sudo yum install --nogpgcheck https://mirrors.tuna.tsinghua.edu.cn/rpmfusion/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://mirrors.tuna.tsinghua.edu.cn/rpmfusion/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
```
注意:没有将当前用户设为管理员的用户,需要将 `sudo CMD` 替换为 `su -c 'CMD'`,并输入 root 密码。
### 修改链接指向 TUNA 镜像
安装成功后,修改 `/etc/yum.repos.d/` 目录下以 `rpmfusion` 开头,以 `.repo` 结尾的文件。具体而言,需要将文件中的 `baseurl=` 开头的行等号后面链接中的 `http://download1.rpmfusion.org/` 替换为 `http://mirrors.tuna.tsinghua.edu.cn/rpmfusion/`,替换后的文件类似如下:
安装成功后,修改 `/etc/yum.repos.d/` 目录下以 `rpmfusion` 开头,以 `.repo` 结尾的文件。具体而言,需要将文件中的 `baseurl=` 开头的行等号后面链接中的 `http://download1.rpmfusion.org/` 替换为 `https://mirrors.tuna.tsinghua.edu.cn/rpmfusion/`,替换后的文件类似如下:
```
[rpmfusion-free]
name=RPM Fusion for Fedora $releasever - Free
baseurl=http://mirrors.tuna.tsinghua.edu.cn/rpmfusion/free/fedora/releases/$releasever/Everything/$basearch/os/
baseurl=https://mirrors.tuna.tsinghua.edu.cn/rpmfusion/free/fedora/releases/$releasever/Everything/$basearch/os/
mirrorlist=http://mirrors.rpmfusion.org/mirrorlist?repo=free-fedora-$releasever&arch=$basearch
enabled=1
metadata_expire=7d
@ -46,7 +46,7 @@ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rpmfusion-free-fedora-$releasever-$ba
[rpmfusion-free-source]
name=RPM Fusion for Fedora $releasever - Free - Source
baseurl=http://mirrors.tuna.tsinghua.edu.cn/rpmfusion/free/fedora/releases/$releasever/Everything/source/SRPMS/
baseurl=https://mirrors.tuna.tsinghua.edu.cn/rpmfusion/free/fedora/releases/$releasever/Everything/source/SRPMS/
mirrorlist=http://mirrors.rpmfusion.org/mirrorlist?repo=free-fedora-source-$releasever&arch=$basearch
enabled=0
metadata_expire=7d

View File

@ -0,0 +1,19 @@
---
category: help
layout: help
mirrorid: stackage
---
## stackage 镜像使用帮助
修改`~/.stack/config.yaml`(在 Windows 下是 `%APPDATA%\stack\config.yaml`, 加上:
```yaml
setup-info: "http://mirrors.tuna.tsinghua.edu.cn/stackage/stack-setup.yaml"
urls:
latest-snapshot: http://mirrors.tuna.tsinghua.edu.cn/stackage/snapshots.json
lts-build-plans: http://mirrors.tuna.tsinghua.edu.cn/stackage/lts-haskell/
nightly-build-plans: http://mirrors.tuna.tsinghua.edu.cn/stackage/stackage-nightly/
```
推荐与 TUNA 的 [Hackage 镜像](https://mirrors.tuna.tsinghua.edu.cn/help/hackage/)配合使用。

View File

@ -0,0 +1,108 @@
---
category: help
layout: help
mirrorid: tensorflow
---
# TensorFlow 镜像使用帮助
请先安装 python 环境,科学计算用途建议安装 [anaconda](/help/anaconda/)。
TensorFlow 安装方法请参考 <https://www.tensorflow.org/get_started>,把 `https://storage.googleapis.com/` 替换为 `https://mirrors.tuna.tsinghua.edu.cn/`
即可。
或直接运行下列命令,一步完成整个安装过程。
{% raw %}
<div id="content-form">
<form class="form-inline">
<div class="form-group">
<label>计算单元: </label>
<select v-model="form.xpu" class="form-control">
<option value="gpu">GPU</option>
<option value="cpu">CPU</option>
</select>
<label>操作系统: </label>
<select v-model="form.os" class="form-control">
<option value="linux">Linux</option>
<option value="mac">Mac OS X</option>
</select>
<label>Python 版本: </label>
<select v-model="form.python" class="form-control">
<template v-if="form.os === 'linux'">
<option :value="py" v-for="py in fileindex.pythons.linux">{{py}}</option>
</template>
<template v-if="form.os == 'mac'">
<option :value="py" v-for="py in fileindex.pythons.mac">{{py}}</option>
</template>
</select>
<label>TensorFlow 版本: </label>
<select v-model="form.tfver" class="form-control">
<option :value="tfver" v-for="tfver in fileindex.versions">{{tfver}}</option>
</select>
</div>
</form>
<p></p>
<pre>
pip install \
-i https://pypi.tuna.tsinghua.edu.cn/simple/ \
https://mirrors.tuna.tsinghua.edu.cn/tensorflow/{{form.os}}/{{form.xpu}}/{{tensorflow}}
</pre>
</div>
<script>
var vue = new Vue({
el: "#content-form",
data: {
form: {
xpu: "gpu",
os: "linux",
python: "",
tfver: ""
},
fileindex: {
pkglist: [],
versions: [],
pythons: {
linux: [],
mac: [],
},
},
},
computed: {
tensorflow () {
var os=this.form.os, xpu=this.form.xpu,
py=this.form.python, tfver=this.form.tfver;
for (var i in this.fileindex.pkglist) {
var pkg = this.fileindex.pkglist[i];
if (pkg.os == os && pkg.xpu == xpu && pkg.python == py && pkg.version == tfver) {
return pkg.filename;
}
}
}
},
watch: {
"form.os": function (newOS) {
var pythons = this.fileindex.pythons[this.form.os];
this.form.python = pythons[0];
},
"fileindex": function (newIdx) {
var pythons = this.fileindex.pythons[this.form.os];
this.form.python = pythons[0];
this.form.tfver = this.fileindex.versions[0];
}
},
created: function() {
var self = this;
$.getJSON('/tensorflow/releases.json', function(data) {
self.fileindex = data;
});
}
});
</script>
{% endraw %}

View File

@ -12,7 +12,7 @@ Termux 是什么
> Termux is a terminal emulator and Linux environment bringing powerful terminal access to Android.
Termux 是运行 Android 上的 terminal。不需要root运行于内部存储不在SD卡上
Termux 是运行 Android 上的 terminal。不需要root运行于内部存储不在SD卡上
自带了一个包管理器,可以安装许多现代化的开发和系统维护工具。比如:
@ -51,7 +51,7 @@ apt edit-sources
```
# The termux repository mirror from TUNA:
deb [arch=all, arm] http://mirrors.tuna.tsinghua.edu.cn/termux stable main
deb [arch=all,arm] http://mirrors.tuna.tsinghua.edu.cn/termux stable main
```
**如果你的android不是arm的CPU上面的[]里的内容会有所区别,参照原来的配置修改一下**
@ -65,4 +65,4 @@ deb [arch=all, arm] http://mirrors.tuna.tsinghua.edu.cn/termux stable main
apt install apt-transport-https
```
之后类似上面的方式配置把url改成`https://mirrors.tuna.tsinghua.edu.cn/termux`。
之后类似上面的配置,但是把url改成`https://mirrors.tuna.tsinghua.edu.cn/termux`。

View File

@ -16,28 +16,32 @@ TUNA 的软件源镜像。
<div class="form-group">
<label>选择你的ubuntu版本: </label>
<select class="form-control release-select" data-template="#apt-template" data-target="#apt-content">
<option data-release="lucid">10.04 LTS</option>
<option data-release="precise">12.04 LTS</option>
<option data-release="trusty" selected>14.04 LTS</option>
<option data-release="utopic">14.10</option>
<option data-release="trusty">14.04 LTS</option>
<option data-release="xenial" selected>16.04 LTS</option>
<option data-release="vivid">15.04</option>
<option data-release="wily">15.10</option>
<option data-release="yakkety">16.10</option>
<option data-release="zesty">17.04</option>
</select>
</div>
</form>
{% raw %}
<script id="apt-template" type="x-tmpl-markup">
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}} main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-backports main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-proposed main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-security main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-updates main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}} main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-backports main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-proposed main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-security main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-updates main multiverse restricted universe
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}} main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}} main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ {{release_name}}-proposed main restricted universe multiverse
</script>
{% endraw %}

View File

@ -0,0 +1,84 @@
---
layout: help
category: help
mirrorid: weave
permalink: /help/weave/
---
## Weave 镜像使用帮助
> Weave is a communications platform that includes the Weave Device SDK and the Weave Server to enable OEM manufactures to connect their devices to Google cloud services.
简单说 Weave 是 Google 开发的物联网通讯平台。TUNA 同步该镜像代码的主要意义在于用于 [chromiumos](/help/chromiumos)的同步,继续看之前请确认你真的需要使用 [weave](https://developers.google.com/weave/) 的源代码。
#### 准备工作
下载 repo 工具:
```bash
mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
```
或者使用tuna的[git-repo镜像](https://mirrors.tuna.tsinghua.edu.cn/help/git-repo/)
#### 下载代码
建立工作目录:
```
mkdir WORKING_DIRECTORY
cd WORKING_DIRECTORY
```
初始化仓库:
```
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/weave/weave/manifest
```
**注意: 本镜像是 Weave 的 master 分支的镜像,如果使用本镜像下载 Weave 的其他版本很大概率会失败**
**如果提示无法连接到 gerrit.googlesource.com请参照[git-repo的帮助页面](/help/git-repo)的更新一节。**
接着使用编辑器打开`.repo/manifests/default.xml`这个文件,将
```
"https://android.googlesource.come"
```
替换为
```
"https://aosp.tuna.tsinghua.edu.cn/"
```
```
"https://weave.googlesource.come"
```
替换为
```
"https://mirrors.tuna.tsinghua.edu.cn/git/weave/"
```
并删除如下几行这几行是非公开的repo因此tuna并没有镜像
```
<project path="libuweave" name="weave/libuweave" />
<project path="cocoapods" name="weave/cocoapods" />
<project path="tests" name="weave/tests" />
```
即可。
最后同步源码树(以后只需执行这条命令来同步):
```
repo sync
```

View File

@ -0,0 +1,107 @@
---
category: help
layout: help
mirrorid: virtualbox
---
# VirtualBox 镜像使用帮助
[Oracle Virtualbox](https://www.virtualbox.org/) VirtualBox 是一款开源虚拟机软件。由德国 Innotek 公司开发Sun Microsystems 公司出品。使用Qt编写在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。采用 GPL 协议开源。
## Microsoft Windows
[点击下载 Windows 最新版](https://mirrors.tuna.tsinghua.edu.cn/virtualbox/virtualbox-Win-latest.exe)
## Macintosh OS X
[点击下载 OS X 最新版](https://mirrors.tuna.tsinghua.edu.cn/virtualbox/virtualbox-osx-latest.dmg)
# Linux
## 通过编译好的二进制包安装
访问该镜像下最新的目录(例如`5.0.24`),找到名为<发行版名称>~<发行代号>~<架构> 的文件。
`virtualbox-5.0_5.0.24-108355~Ubuntu~xenial_i386.deb` 下载安装即可。
目前支持的系统有:
* Ubuntu
* Debian
* Fedora
* openSUSE
* SUSE Linux Enterprise Server
* Oracle Linux / Red Hat Enterprise Linux / CentOS
如果您所使用的发行版不在上述列表之内,请下载通用的`run`文件(例如`VirtualBox-5.0.24-108355-Linux_x86.run`),然后使用 `chmod +x` 给予执行权限后,直接安装即可。
### 通过包管理器安装
#### Debian / Ubuntu 用户
首先信任 Virtualbox 的 GPG 公钥:
对于 Debian 8 和 Ubuntu 16.04 及以上:
```shell
wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add -
```
其他版本
```shell
wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add -
```
再选择你的 Debian/Ubuntu 版本,将文本框中内容写进`/etc/apt/sources.list.d/virtualbox.list`
<form class="form-inline">
<div class="form-group">
<label>你的Debian/Ubuntu版本: </label>
<select class="form-control release-select" data-template="#apt-template" data-target="#apt-content">
<option data-os="debian" data-release="jessie" selected>Debian 8 (Jessie)</option>
<option data-os="debian" data-release="wheezy">Debian 7 (Wheezy)</option>
<option data-os="ubuntu" data-release="xenial">Ubuntu 16.04 LTS</option>
<option data-os="ubuntu" data-release="trusty">Ubuntu 14.04 LTS</option>
</select>
</div>
</form>
<p></p>
<pre>
<code id="apt-content">
</code>
</pre>
{% raw %}
<script id="apt-template" type="x-tmpl-markup">
deb {{if os_name|equals>ubuntu}}https{{else}}http{{/if}}://mirrors.tuna.tsinghua.edu.cn/virtualbox/apt/ {{release_name}} contrib
</script>
{% endraw %}
安装 VirtualBox:
```
sudo apt-get update
sudo apt-get install virtualbox-5.0
```
### RHEL/CentOS 用户
新建 `/etc/yum.repos.d/virtualbox.repo`,内容为
```
[virtualbox]
name=Virtualbox Repository
baseurl=https://mirrors.tuna.tsinghua.edu.cn/virtualbox/rpm/el$releasever/
gpgcheck=0
enabled=1
```
刷新缓存并安装 `virtualbox` 即可。
```
sudo yum makecache
sudo yum install VirtualBox-5.1
```

View File

@ -0,0 +1,77 @@
---
category: help
layout: help
mirrorid: repoforge
---
# Repoforge (原Rpmforge) 镜像使用帮助
[Repoforge](http://repoforge.org/) 是 RHEL 系统下的软件仓库,拥有 10000 多个软件包,被认为是最安全、最稳定的一个软件仓库。
## 添加 Repoforge 仓库
1. 运行 `cat /etc/redhat-release` 获取 EL 版本号(如 EL6, EL7 等)
2. 向系统中添加 Repoforge 的 GPG 公钥:
```
rpm --import https://mirrors.tuna.tsinghua.edu.cn/repoforge/RPM-GPG-KEY.dag.txt
```
3. 运行下列命令:
<form class="form-inline">
<div class="form-group">
<label>选择你的 EL 版本: </label>
<select class="form-control release-select" data-template="#yum-template" data-target="#yum-content">
<option data-release="el7" selected>EL7</option>
<option data-release="el6">EL6</option>
<option data-release="el5">EL5</option>
<option data-release="el4">EL4</option>
<option data-release="el3">EL3</option>
</select>
</div>
</form>
{% raw %}
<script id="yum-template" type="x-tmpl-markup">
sudo cat > /etc/yum.repos.d/rpmforge.repo << EOF
[rpmforge]
name = RHEL $releasever - RPMforge.net - dag
baseurl = https://mirrors.tuna.tsinghua.edu.cn/repoforge/redhat/{{release_name}}/en/$basearch/rpmforge
mirrorlist = http://mirrorlist.repoforge.org/{{release_name}}/mirrors-rpmforge
enabled = 1
protect = 0
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rpmforge-dag
gpgcheck = 1
[rpmforge-extras]
name = RHEL $releasever - RPMforge.net - extras
baseurl = https://mirrors.tuna.tsinghua.edu.cn/repoforge/redhat/{{release_name}}/en/$basearch/extras
mirrorlist = http://mirrorlist.repoforge.org/{{release_name}}/mirrors-rpmforge-extras
enabled = 0
protect = 0
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rpmforge-dag
gpgcheck = 1
[rpmforge-testing]
name = RHEL $releasever - RPMforge.net - testing
baseurl = https://mirrors.tuna.tsinghua.edu.cn/repoforge/redhat/{{release_name}}/en/$basearch/testing
mirrorlist = http://mirrorlist.repoforge.org/{{release_name}}/mirrors-rpmforge-testing
enabled = 0
protect = 0
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rpmforge-dag
gpgcheck = 1
EOF
</script>
{% endraw %}
<p></p>
<pre>
<code id="yum-content">
</code>
</pre>
## 更新软件包缓存
```
sudo yum makecache
```

View File

@ -0,0 +1,19 @@
---
category: help
layout: help
mirrorid: rubygems
---
# Ruby Gems 镜像使用帮助
使用以下命令替换 gems 默认源
```bash
# 添加 TUNA 源并移除默认源
gem sources --add https://mirrors.tuna.tsinghua.edu.cn/rubygems/ --remove https://rubygems.org/
# 列出已有源
gem sources -l
# 应该只有 TUNA 一个
```
或者,编辑 `~/.gemrc`,将 `https://mirrors.tuna.tsinghua.edu.cn/rubygems/` 加到 `sources` 字段。

View File

@ -0,0 +1,19 @@
---
category: help
layout: help
mirrorid: bioconductor
---
[Bioconductor](https://www.bioconductor.org) 镜像使用帮助
===================
Bioconductor 镜像源配置文件之一是 `.Rprofile` (linux 下位于 `~/.Rprofile` )。
在文末添加如下语句:
```
options(BioC_mirror="https://mirrors.tuna.tsinghua.edu.cn/bioconductor")
```
打开R即可使用该 Bioconductor 镜像源安装 Bioconductor 软件包。

View File

@ -0,0 +1,19 @@
---
category: help
layout: help
mirrorid: CRAN
---
[CRAN](https://cran.r-project.org/) 镜像使用帮助
===================
CRAN (The Comprehensive R Archive Network) 镜像源配置文件之一是 `.Rprofile` (linux 下位于 `~/.Rprofile` )。
在文末添加如下语句:
```
options("repos" = c(CRAN="https://mirrors.tuna.tsinghua.edu.cn/CRAN/"))
```
打开R即可使用该 CRAN镜像源安装 R 软件包。

View File

@ -0,0 +1,36 @@
---
category: help
layout: help
mirrorid: llvm
---
## LLVM Git Repos 镜像使用帮助
本镜像镜像了官方的以下仓库:
```
http://llvm.org/git/{llvm,clang,libcxx,lldb,clang-tools-extra,polly,zorg,compiler-rt,libcxxabi,lld,lnt}
```
若需要其他的仓库,可从 [LLVM 官方](http://llvm.org) 或者 [GitHub 镜像](https://github.com/llvm-mirror) 获取。
使用方法:
```
git clone https://mirrors.tuna.tsinghua.edu.cn/git/llvm/{reponame}.git
```
其中`{reponame}`为上述的仓库名称之一。请注意:由于仓库体积均较大,执行`git clone`可能需要较长时间,并且没有进度提示,请耐心等候。
若要将 TUNA mirror 加入已有代码库,可在已有仓库中运行
```
git remote add tuna https://mirrors.tuna.tsinghua.edu.cn/git/llvm/{reponame}.git
```
或运行
```
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/llvm/{reponame}.git
```
将默认上游设置为 TUNA 镜像

View File

@ -0,0 +1,13 @@
---
category: news
layout: news
title: "暂停 OpenWRT Trunk 镜像"
author: Justin Wong
---
由于 OpenWRT Trunk 部分几乎每天都会完全重建,给镜像站带来较大流量压力,经调研后,发现用户很少直接使用未经测试的 Trunk 内容,
因此我们决定暂停 OpenWRT Trunk 镜像。
OpenWRT Release 镜像不受影响。
如有疑问,请到 https://github.com/tuna/issues 提交意见反馈。

View File

@ -0,0 +1,11 @@
---
category: news
layout: news
title: "新增 Bananian 镜像"
author: Justin Wong
---
[Bananian](https://www.bananian.org/) 是为 [Banana Pi](http://www.bananapi.org/) 制作的,基于官方 Debian 仓库的发行版,
其内核和 bootloader 为 Banana Pi 做了定制化。
使用方法请见[Bananian镜像帮助](/help/bananian/)。

View File

@ -0,0 +1,11 @@
---
category: news
layout: news
title: "新增 Alpine, Anaconda 镜像"
author: Justin Wong
---
[Alpine Linux](http://www.alpinelinux.org/) 是一个轻量级 Linux 发行版,具有安全性高、系统体积小等特点,非常适合 docker 等容器使用。
[Anaconda](https://www.continuum.io/why-anaconda) 是一个面向科学计算的 Python 发行版,支持全平台,提供了大量的科学计算、数据分析包,
我们提供了 Anaconda 安装包和仓库镜像。使用方法请见[Anaconda镜像帮助](/help/anaconda/)。

View File

@ -0,0 +1,9 @@
---
category: news
layout: news
title: "Homebrew 镜像结构调整"
author: Justin Wong
---
由于 Homebrew 官方将原 homebrew 拆成了 brew.git 和 homebrew-core.git 两个仓库,我们随官方也做出了结构调整。
配置方法请见[Homebrew镜像使用帮助](/help/homebrew/)。

View File

@ -0,0 +1,12 @@
---
category: news
layout: news
title: "新增 Homebrew-bottles 镜像"
author: Xavier Yao
---
TUNA mirrors 新增 Homebrew-bottles 镜像。
[Homebrew](http://brew.sh) 是 OS X 操作系统最常用的包管理器之一。[Homebrew-bottles](http://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles) 镜像提供了供 Homebrew 使用的预编译二进制软件包。配置方法见 [Homebrew bottles 镜像使用帮助](https://mirrors.tuna.tsinghua.edu.cn/help/homebrew-bottles/)。
本镜像站同时提供 Homebrew 的 formula 索引的镜像(即 `brew update` 时所更新内容),配置方法请参考 [Homebrew 镜像使用帮助](https://mirrors.tuna.tsinghua.edu.cn/help/homebrew/)。

View File

@ -0,0 +1,19 @@
---
category: news
layout: news
title: "新增一系列镜像"
author: Justin Wong
---
新学期开始啦,暑假我们没闲着,新增了以下一大票镜像~
- VirtualBox: 著名开源虚拟机软件 [使用帮助](/help/virtualbox/)
- Dell 服务器管理工具
- grafana: 数据可视化工具
- jenkins: 持续集成工具
- influxdata: 由 Telegraf, InfluxDB, Chronograf, Kapacitor 组成的 TICK 开源时间序列工具栈
- mysql: 常用开源数据库
- parrot: 基于 Debian 的安全操作系统
- rubygems: Ruby 包仓库
祝大家新学期取得新成绩

View File

@ -0,0 +1,18 @@
---
category: news
layout: news
title: "新增 Tensorflow 等一系列镜像"
author: Xavier Yao & Harry Chen
---
TUNA 镜像站新增一系列镜像。
- tensorflow: Google 开发的、采用数据流图data flow graphs、用于数值计算的开源软件库被广泛应用于深度学习等领域。使用方法见 [TensorFlow 镜像使用帮助](/help/tensorflow/)。
- arch4edu: 用于 ArchLinux 的一系列科研、教学所需工具
- ros: 用于开发机器人的工具包
- elvish: TUNA 前会长 [xiaq](https://github.com/xiaq) 开发的革命性 Shell ,详见 [这里](https://elvish.io/)
- HHVM: 由 Facebook 开发的高性能 PHP 虚拟机
- steamos: 不解释,剁手专用
- bjlx: [北京龙芯 & Debian 俱乐部](http://www.bjlx.org.cn/) 的公开源
- loongson: 用于龙芯电脑的软件包
- elasticstack: ELK 系列数据分析工具5.x 之后改名为 elastic stack

View File

@ -0,0 +1,8 @@
---
category: news
layout: news
title: "暂时对 rsync 服务磁盘 I/O 进行限制"
author: Yichuan Gao
---
受近期 [中科大开源软件镜像站故障](https://servers.ustclug.org/2016/11/mirrors-services-outage/) 的影响TUNA Mirrors 流量大幅上升,目前已接近带宽极限,对磁盘阵列的 I/O 产生了较大压力。为了保证阵列正常工作,我们将优先保证 HTTP/HTTPS 服务质量,而在高峰期对 rsync 服务的磁盘 I/O 进行限制。届时以 TUNA 为上游进行 rsync 同步速度将会下降,敬请谅解。如果方便,请尽量选择凌晨错峰同步。恢复时间将会另行通知。

View File

@ -0,0 +1,8 @@
---
category: news
layout: news
title: "不再对 rsync 服务磁盘 I/O 进行限制"
author: Xavier Yao
---
各服务恢复正常。

View File

@ -0,0 +1,8 @@
---
category: news
layout: news
title: "镜像站将于 12/4 10:30 进行停机维护"
author: Harry Chen
---
TUNA 镜像站将于北京时间2016年12月4日上午10时30分进行停机维护届时将暂时停止镜像服务。预计 12:00 前可恢复正常服务。对于给您带来的不便,我们深表歉意。

View File

@ -0,0 +1,12 @@
---
category: news
layout: news
title: "新增 Chromium OS 镜像"
author: Yiqun Hui
---
TUNA 镜像站新增chromium OS源代码镜像。
由于各方面原因该镜像暂时只镜像master分支即只有出现在[这个文件](https://chromium.googlesource.com/chromiumos/manifest/+/master/full.xml)中的项目才会被同步。
使用方法见 [chromium OS 镜像使用帮助](/help/chromiumos/)。

View File

@ -0,0 +1,8 @@
---
category: news
layout: news
title: "镜像站 IPv6 国际链路故障"
author: Harry Chen
---
由于 CERNET 2 的 IPv6 国际链路出现故障TUNA 镜像站的多个镜像同步均失败。在此期间,您可以暂时使用官方镜像列表中的其他镜像站。对于对您带来的不便,我们深表歉意。

View File

@ -0,0 +1,20 @@
---
category: news
layout: news
title: "我们做出了一个艰难的决定"
author: TUNA 镜像站全体运维人员
---
由于 TUNA 镜像站经营不善团长带着女朋友跑了整个组织濒临破产边缘。经第一届金枪鱼全体代表大会讨论研究决定TUNA 名下的 Telegram 群组和镜像站将启用免费使用+付费增值模式。具体收费标准如下:
{: .table}
| 项目 | 会员 | 黄金会员 | 钻石会员 | SVIP | 备注 |
| --- | --- | --- | --- | --- | --- |
| 收费标准 | 免费 | 15元/月 **¥179/年** | 30元/月 **¥359/年** | 50元/月 **¥599/年** | |
| Telegram 发言 | 5条/周 | 30条/周 | 90条/周 | **无限** | 超出部分 1元/条 |
| Telegram 发言置顶 | 无 | 1条/月 | 3条/月 | **10条/月** | 超出部分 10元/条 |
| 镜像源限速 | 100KB/s | 1MB/s | 5MB/s | **不限速** | 需使用专用包管理器`tuna-get``apt-get`等官方包管理器限速100KB/s |
| 包管理器去广告 | 无 | 5s后可跳过 | 可跳过 | **无广告** | |
| 其它特权 | 无 | 无 | **Telegram群红名** | **上线提醒** | |
此标准发布即日起不执行。

View File

@ -0,0 +1,12 @@
---
category: news
layout: news
title: "新增 Lineage 与 Adobe 开源字体镜像"
author: Xavier Yao
---
TUNA 镜像站新增 LineageOS 源代码和 ROM 镜像,及 Adobe 各开源字体镜像。
LineageOS 是一个面向智能手机和平板电脑的自由、开源的 Android 分支。它是深受欢迎的定制 ROM CyanogenMod 的继任者,在 2016 年 12 月 Cyanogen 公司突然宣布停止开发并关闭项目基础设施后复刻而生。ROM 下载方式参见[Lineage ROM下载方式](/help/lineage-rom/),源码下载方式见[Lineage OS源码下载方式](/help/lineageOS/)
Adobe 开源字体包括思源黑体、思源宋体、Source Code Pro等TUNA镜像站提供各字体及其源代码的下载。

View File

@ -0,0 +1,11 @@
---
category: news
layout: news
title: "新增 LLVM 编译器套件 Git 仓库镜像"
author: Harry Chen
---
TUNA 镜像站新增来自 LLVM 编译器套件的多个 Git 仓库镜像。
[LLVM](http://llvm.org) 是著名的开源编译器基础设施由编译器后端llvm、编译器前端clang、调试器lldb、C++运行库libcxx等多个套件组成。
为方便用户获取其源码,我们对官方的大部分仓库进行了镜像。详细说明以及使用方法请参见 [LLVM Git Repos 镜像使用帮助](/help/llvm/)

46
gen_desc.py Executable file
View File

@ -0,0 +1,46 @@
#!/usr/bin/env python3
import json
import urllib.request
from collections import OrderedDict
tunasync = json.loads(
urllib.request
.urlopen("https://mirrors.tuna.tsinghua.edu.cn/static/tunasync.json")
.read()
.decode('utf-8')
)
mirrors = list({t['name'] for t in tunasync})
mirrors.sort()
with open('_data/mirror_desc.json') as f:
descriptions = json.load(f)
descriptions = {
x['name']: x['desc'] for x in descriptions
}
for m in mirrors:
if m not in descriptions:
descriptions[m] = ""
descriptions = sorted(
[
OrderedDict([('name', name), ('desc', desc)])
for name, desc in descriptions.items()
],
key=lambda x: x['name']
)
content = (
json
.dumps(descriptions, indent=2)
.encode('utf-8')
.decode('unicode-escape')
.encode('utf-8')
)
with open('_data/mirror_desc.json', 'wb') as f:
f.write(content)
# vim: ts=4 sw=4 sts=4 expandtab

View File

@ -4,6 +4,7 @@ echo '# robots.txt for https://mirrors.tuna.tsinghua.edu.cn' > robots.txt
echo 'User-agent: *' >> robots.txt
echo '' >> robots.txt
curl -s https://mirrors.tuna.tsinghua.edu.cn/static/tunasync.json | jq -r '.[] | .name' | while read name; do
curl -s https://mirrors.tuna.tsinghua.edu.cn/static/tunasync.json | jq -r '.[] | .name' | uniq | while read name; do
[[ -z ${name} ]] && continue
echo "Disallow: /${name}" >> robots.txt
done

320
geninfo/genisolist.ini Normal file
View File

@ -0,0 +1,320 @@
# This file is the config required by genisolist.py
# This special section named "%main%" defined following variables:
# "root": HTTP root of mirrors. The script will locate the images in it.
# "urlbase": URL of mirrors prepended to image path. We want to use relative
# path, so set it to '/' instead of complete URL.
# "d[N]": For distribution sorting. where N is an positive integer. The value
# is disto name specified in below sections. Lower N makes the distro
# show higher. Default N is 0xFFFF for distro not mentioned.
[%main%]
root = /data/
urlbase = /
d10 = Arch Linux
d20 = Debian
d25 = CentOS
d30 = Fedora
d40 = Ubuntu
d50 = Ubuntu 衍生版
d60 = Deepin
# Sections whose name isn't "%main%" defined a detect rule of image detection.
[archlinux]
# Section name is of no use, the display name is specified in "distro" option.
distro = Arch Linux
# listvers defined how many latest versions to display.
listvers = 1
# "location" specifies globbing pathname of the image. The path is relative to
# the HTTP root (aka "root" in [%main%] section). Not all images match it is
# considered, you can use "pattern" option below to filter.
location = archlinux/iso/latest/archlinux-*.iso
# "pattern" is a regular expression. If the pattern is found in image path
# found by "location", then the image is valid. Group capturing is to extract
# image info from image path name.
pattern = archlinux-(\d+\.\d+\.\d+)-(\w+).iso
# Following 3 options describes image info. "type" and "platform" is optional.
# $1, $2... here will be replaced by the string captured in above "pattern".
# Additionally, $0 will be replaced by the whole string matches the pattern.
# "version" is also used as the key to sort images of the same distro.
version = $1
type = CLI-only
platform = $2
# "key_by" should be used when images of different types or platform have
# different version number, see lineageOS below.
[ubuntu desktop]
distro = Ubuntu
listvers = 4
# If one glob is not enough for locating all images, you can use "location_N"
# to specify more globs. N start from 0 and must a sequence (0,1,2...).
location_0 = ubuntu-releases/[a-z]*/ubuntu-*-desktop-i386.iso
location_1 = ubuntu-releases/[a-z]*/ubuntu-*-desktop-amd64.iso
pattern = ubuntu-([0-9.]+)-desktop-(\w+).iso
version = $1
type = Desktop LiveDVD
platform = $2
[ubuntu server]
distro = Ubuntu
listvers = 4
# If one glob is not enough for locating all images, you can use "location_N"
# to specify more globs. N start from 0 and must a sequence (0,1,2...).
location_0 = ubuntu-releases/[a-z]*/ubuntu-*-server-i386.iso
location_1 = ubuntu-releases/[a-z]*/ubuntu-*-server-amd64.iso
pattern = ubuntu-([0-9.]+)-server-(\w+).iso
version = $1
type = Server
platform = $2
# You can apply multiple rules (sections) for the same distro like following
# four sections. They will be shown in the same submenu on our web page.
[ubuntukylin]
distro = Ubuntu 衍生版
listvers = 1
location_0 = ubuntu-cdimage/ubuntukylin/releases/[a-z]*/release/ubuntukylin-*-desktop-i386.iso
location_1 = ubuntu-cdimage/ubuntukylin/releases/[a-z]*/release/ubuntukylin-*-desktop-amd64.iso
pattern = ubuntukylin-([0-9.]+)-desktop-(\w+).iso
# Just a small trick. Constant string prefix won't affect sorting.
version = Ubuntu Kylin $1
platform = $2
[kubuntu]
distro = Ubuntu 衍生版
listvers = 1
location_0 = ubuntu-cdimage/kubuntu/releases/[a-z]*/release/kubuntu-*-desktop-i386.iso
location_1 = ubuntu-cdimage/kubuntu/releases/[a-z]*/release/kubuntu-*-desktop-amd64.iso
pattern = kubuntu-([0-9.]+)-desktop-(\w+).iso
version = Kubuntu $1
platform = $2
[lubuntu]
distro = Ubuntu 衍生版
listvers = 1
location_0 = ubuntu-cdimage/lubuntu/releases/[a-z]*/release/lubuntu-*-desktop-i386.iso
location_1 = ubuntu-cdimage/lubuntu/releases/[a-z]*/release/lubuntu-*-desktop-amd64.iso
pattern = lubuntu-([0-9.]+)-desktop-(\w+).iso
version = Lubuntu $1
platform = $2
[xubuntu]
distro = Ubuntu 衍生版
listvers = 1
location_0 = ubuntu-cdimage/xubuntu/releases/[a-z]*/release/xubuntu-*-desktop-i386.iso
location_1 = ubuntu-cdimage/xubuntu/releases/[a-z]*/release/xubuntu-*-desktop-amd64.iso
pattern = xubuntu-([0-9.]+)-desktop-(\w+).iso
version = Xubuntu $1
platform = $2
[ubuntu_gnome]
distro = Ubuntu 衍生版
listvers = 1
location_0 = ubuntu-cdimage/ubuntu-gnome/releases/[a-z]*/release/ubuntu-gnome-*-desktop-i386.iso
location_1 = ubuntu-cdimage/ubuntu-gnome/releases/[a-z]*/release/ubuntu-gnome-*-desktop-amd64.iso
pattern = ubuntu-gnome-([0-9.]+)-desktop-(\w+).iso
version = Ubuntu Gnome $1
platform = $2
[ubuntu_mate]
distro = Ubuntu 衍生版
listvers = 1
location_0 = ubuntu-cdimage/ubuntu-mate/releases/[a-z]*/release/ubuntu-mate-*-desktop-i386.iso
location_1 = ubuntu-cdimage/ubuntu-mate/releases/[a-z]*/release/ubuntu-mate-*-desktop-amd64.iso
pattern = ubuntu-mate-([0-9.]+)-desktop-(\w+).iso
version = Ubuntu Mate $1
platform = $2
[debian_cd]
distro = Debian
listvers = 1
location_0 = debian-cd/current/amd64/iso-cd/debian-*-amd64-*-CD-1.iso
location_1 = debian-cd/current/i386/iso-cd/debian-*-i386-*-CD-1.iso
pattern = debian-([0-9.]+)-(\w+)-(\w+)-CD-1.iso
version = $1
type = CD installer with $3
platform = $2
[debian_dvd]
distro = Debian
listvers = 1
location_0 = debian-cd/current/amd64/iso-dvd/debian-*-amd64-DVD-*.iso
location_1 = debian-cd/current/i386/iso-dvd/debian-*-i386-DVD-*.iso
pattern = debian-([0-9.]+)-(\w+)-DVD-(\d).iso
version = $1
type = DVD installer (Part $3)
platform = $2
[debian_live]
distro = Debian
listvers = 1
location_0 = debian-cd/current-live/amd64/iso-hybrid/debian-live-*-amd64-*.iso
location_1 = debian-cd/current-live/i386/iso-hybrid/debian-live-*-i386-*.iso
pattern = debian-live-([0-9.]+)-(\w+)-(\w+).iso
version = $1
type = Live CD with $3
platform = $2
[centos]
distro = CentOS
listvers = 2
location = centos/[0-9].*/isos/*/CentOS-[0-9]*.iso
pattern = CentOS-([0-9.]+)-(\w+)-((bin-)?\w+?)(-[0-9]+|).iso
version = $1
type = $3
platform = $2
[fedora]
distro = Fedora
listvers = 2
location_0 = fedora/releases/[1-9][0-9]/Workstation/*/iso/Fedora-Workstation-Live-*-[1-9][0-9]-*.iso
location_1 = fedora/releases/[1-9][0-9]/Spins/*/iso/Fedora-KDE-Live-*-[1-9][0-9]-*.iso
location_2 = fedora/releases/[1-9][0-9]/Spins/*/iso/Fedora-Xfce-Live-*-[1-9][0-9]-*.iso
pattern = Fedora-(Workstation|KDE|Xfce)-Live-(\w+)-(\d+)-.*\.iso
version = $3
type = $1
platform = $2
[opensuse_leap]
distro = openSUSE
listvers = 3
location_0 = opensuse/distribution/leap/[0-9][0-9].[0-9]/iso/openSUSE-Leap-[0-9][0-9].[0-9]-DVD-*.iso
pattern = openSUSE-Leap-([0-9.]+)-DVD-(\w+).iso
version = $1
platform = $2
[opensuse tumbleweed]
distro = openSUSE
listvers = 1
location_0 = opensuse/tumbleweed/iso/openSUSE-Tumbleweed-DVD-*-Current.iso
location_1 = opensuse/tumbleweed/iso/openSUSE-Tumbleweed-GNOME-Live-*-Current.iso
location_2 = opensuse/tumbleweed/iso/openSUSE-Tumbleweed-KDE-Live-*-Current.iso
pattern = openSUSE-Tumbleweed-(DVD|GNOME-Live|KDE-Live)-(\w+)-Current.iso
version = Tumbleweed
type = $1
platform = $2
[opensuse]
distro = openSUSE
listvers = 1
location_0 = opensuse/distribution/[0-9][0-9].[0-9]/iso/openSUSE-[0-9][0-9].[0-9]-DVD-*.iso
location_1 = opensuse/distribution/[0-9][0-9].[0-9]/iso/openSUSE-[0-9][0-9].[0-9]-GNOME-Live-*.iso
location_2 = opensuse/distribution/[0-9][0-9].[0-9]/iso/openSUSE-[0-9][0-9].[0-9]-KDE-Live-*.iso
pattern = openSUSE-([0-9.]+)-(DVD|GNOME-Live|KDE-Live)-(\w+).iso
version = $1
type = $2
platform = $3
[deepin]
distro = Deepin
listvers = 1
location = deepin-cd/1*/*.iso
pattern = deepin-([0-9.]+)-(\w+).iso
version = $1
platform = $2
[qt5]
distro = Qt 5
listvers = 1
location = qt/official_releases/qt/5.*/5.*/qt-opensource-*
pattern = qt-opensource-(.*?)-([\d.]+).(run|dmg|exe)
platform = $1
version = $2
category = app
[msys2]
distro = MSYS2
listvers = 1
location = msys2/distrib/msys2-*.exe
pattern = msys2-(i686|x86_64)-(latest).exe
platform = Windows
type = $1
version = $2
category = app
[virtualbox]
distro = VirtualBox
listvers = 1
location = virtualbox/virtualbox-*
pattern = virtualbox-(.*?)-(latest).(exe|dmg)
platform = $1
version = $2
category = app
[texlive]
distro = TeX 排版系统
listvers = 1
location = CTAN/systems/texlive/Images/texlive*.iso
pattern = texlive(\d+)-\d+.iso
platform = Windows & Linux
version = TeX Live $1
category = app
[mactex]
distro = TeX 排版系统
listvers = 1
location = CTAN/systems/mac/mactex/mactex-*.pkg
pattern = mactex-(\d+).pkg
platform = macOS
version = MacTeX $1
category = app
[miktex]
distro = TeX 排版系统
listvers = 1
location = CTAN/systems/win32/miktex/setup/basic-miktex-*
pattern = basic-miktex-((\d+.)+\d+)(|-)*(x64)*.exe
platform = Windows
type = $4
version = MikTeX $1
category = app
[anaconda3]
distro = Conda
listvers = 1
location = anaconda/archive/Anaconda*
pattern = (Anaconda3)-(\d+.\d+.\d+)-(Windows|Linux|MacOSX)-(x86_64|x86).\w+
platform = $3
type = $4
version = $1 $2
category = app
[anaconda2]
distro = Conda
listvers = 1
location = anaconda/archive/Anaconda*
pattern = (Anaconda2)-(\d+.\d+.\d+)-(Windows|Linux|MacOSX)-(x86_64|x86).\w+
platform = $3
type = $4
version = $1 $2
category = app
[miniconda3]
distro = Conda
listvers = 1
location = anaconda/miniconda/Miniconda*
pattern = (Miniconda3)-(\d+.\d+.\d+)-(Windows|Linux|MacOSX)-(x86_64|x86).\w+
platform = $3
type = $4
version = $1 $2
category = app
[miniconda2]
distro = Conda
listvers = 1
location = anaconda/miniconda/Miniconda*
pattern = (Miniconda2)-(\d+.\d+.\d+)-(Windows|Linux|MacOSX)-(x86_64|x86).\w+
platform = $3
type = $4
version = $1 $2
category = app
[lineageos]
distro = LineageOS
listvers = 1
location = lineage-rom/full/*/*/*.zip
pattern = lineage-([0-9.]+)-(\d+)-nightly-(\w+)-signed.zip
platform = $3
type = $1
version = $2
key_by = $1 $3

157
geninfo/genisolist.py Executable file
View File

@ -0,0 +1,157 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import re
import glob
import json
import logging
from urllib.parse import urljoin
from distutils.version import LooseVersion
from configparser import ConfigParser
logger = logging.getLogger(__name__)
CONFIG_FILE = os.path.join(os.path.dirname(__file__), 'genisolist.ini')
def getPlatformPriority(platform):
platform = platform.lower()
if platform in ['amd64', 'x86_64', '64bit']:
return 100
elif platform in ['i386', 'i486', 'i586', 'i686', 'x86', '32bit']:
return 90
else:
return 0
def renderTemplate(template, result):
group_count = len(result.groups()) + 1
for i in range(group_count):
template = template.replace("$%d" % i, result.group(i) or "")
return template
def parseSection(items):
items = dict(items)
if 'location' in items:
locations = [items['location']]
else:
locations = []
i = 0
while ("location_%d" % i) in items:
locations.append(items["location_%d" % i])
i += 1
pattern = items.get("pattern", "")
prog = re.compile(pattern)
images = []
images = {}
for location in locations:
logger.debug("[GLOB] %s", location)
for imagepath in glob.glob(location):
logger.debug("[FILE] %s", imagepath)
result = prog.search(imagepath)
if not(result):
logger.debug("[MATCH] None")
continue
else:
logger.debug("[MATCH] %r", result.groups())
imageinfo = {"filepath": imagepath, "distro": items["distro"]}
for prop in ("version", "type", "platform", "category"):
imageinfo[prop] = renderTemplate(items.get(prop, ""), result)
logger.debug("[JSON] %r", imageinfo)
key = renderTemplate(items.get("key_by", ""), result)
if key not in images:
images[key] = []
images[key].append(imageinfo)
for image_group in images.values():
image_group.sort(key=lambda k: (LooseVersion(k['version']),
getPlatformPriority(k['platform']),
k['type']),
reverse=True)
i = 0
versions = set()
listvers = int(items.get('listvers', 0xFF))
for image in image_group:
versions.add(image['version'])
if len(versions) <= listvers:
yield image
else:
break
def getDetail(image_info, urlbase):
url = urljoin(urlbase, image_info['filepath'])
desc = "%s (%s%s)" % (
image_info['version'],
image_info['platform'],
", %s" % image_info['type'] if image_info['type'] else ''
)
category = image_info.get('category', 'os') or "os"
return (desc, url, category)
def getJsonOutput(url_dict, prio={}):
raw = []
for distro in url_dict:
raw.append({
"distro": distro,
"category": list({c for _, _, c in url_dict[distro]})[0],
"urls": [
{"name": name, "url": url} for name, url, _ in url_dict[distro]
]
})
raw.sort(key=lambda d: prio.get(d["distro"], 0xFFFF))
return json.dumps(raw)
def getImageList():
ini = ConfigParser()
if not(ini.read(CONFIG_FILE)):
raise Exception("%s not found!" % CONFIG_FILE)
root = ini.get("%main%", 'root')
urlbase = ini.get("%main%", 'urlbase')
prior = {}
for (name, value) in ini.items("%main%"):
if re.match("d\d+$", name):
prior[value] = int(name[1:])
oldcwd = os.getcwd()
os.chdir(root)
url_dict = {}
for section in ini.sections():
if section == "%main%":
continue
for image in parseSection(ini.items(section)):
if not image['distro'] in url_dict:
url_dict[image['distro']] = []
url_dict[image['distro']].append(
getDetail(image, urlbase)
)
os.chdir(oldcwd)
return getJsonOutput(url_dict, prior)
if __name__ == "__main__":
import sys
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
print(getImageList())

View File

@ -9,20 +9,8 @@ permalink: /
<div id="mirrors">
<div class="spacing hidden-xs"></div>
<div class="container">
<div class="row">
<div class="space"></div>
<div class="col-md-12">
<div id="thu-alert" class="alert alert-danger hidden">
<i class="glyphicon glyphicon-exclamation-sign"></i>
<strong>清华用户您好,我们发现您正在通过校外线路访问 mirrors可能是因为您设置了校外的DNS服务器
为避免产生不必要的校外流量,
建议您通过 <a href="https://mirrors-i.tuna.tsinghua.edu.cn/">https://mirrors-i.tuna.tsinghua.edu.cn/</a>
访问和使用 TUNA mirrors 资源。
</strong>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 table-responsive">
<div class="alert text-center" id="cover-alert">
@ -38,53 +26,95 @@ permalink: /
</div>
</div>
<div class="row">
<div class="col-md-3">
<div id="news">
<h4><span class="fa fa-bullhorn"></span> 新闻公告 </h4>
<ul>
{% for news in site.categories.news limit: 3%}
<li><a href="/news/#{{news.slug}}"><strong>{{news.date | date: "%Y-%m-%d"}}</strong> {{news.title}}</a></li>
{% endfor %}
</ul>
<div class="text-right"><a href="/news/"> more <span class="fa fa-angle-double-right"></span> </a></div>
</div>
</div>
<div class="col-md-4">
<div>
<h4> <span class="fa fa-link"></span> 域名选择 </h4>
<ul>
<li><a href="https://mirrors.tuna.tsinghua.edu.cn/">https://mirrors.tuna.tsinghua.edu.cn/</a> 自动选择 </li>
<li><a href="https://mirrors6.tuna.tsinghua.edu.cn/">https://mirrors6.tuna.tsinghua.edu.cn/</a> 只解析 IPv6</li>
<li><a href="https://mirrors4.tuna.tsinghua.edu.cn/">https://mirrors4.tuna.tsinghua.edu.cn/</a> 只解析 IPv4</li>
<li><a href="https://mirrors-i.tuna.tsinghua.edu.cn/">https://mirrors-i.tuna.tsinghua.edu.cn/</a> 只解析清华 IP</li>
</ul>
</div>
</div>
<div class="col-md-3">
<div>
<h4> <span class="fa fa-envelope-o"></span> 联系我们 </h4>
<ul>
<li><strong>订阅邮件列表</strong> <br /> thu-opensource-mirror-admin@googlegroups.com <br /> 第一时间获得镜像站动态</li>
<li><strong>意见反馈</strong> <br /> <a href="https://github.com/tuna/issues">https://github.com/tuna/issues</a></li>
<li><strong>在线交流</strong> <br /> <a href="https://fishroom.tuna.moe/log/tuna/today"> #tuna at freenode </a></li>
</ul>
</div>
</div>
<div class="col-md-2">
<div>
<h4> <span class="fa fa-external-link"></span> 相关链接 </h4>
<ul>
<li><a href="/help/">使用帮助</a></li>
<li><a href="/status/">服务器状态</a></li>
<li><a href="https://tuna.moe/">清华大学 TUNA 协会</a></li>
</ul>
</div>
</div>
<div class="spacing hidden-xs"></div>
<div id="news" class="col-md-3">
<h4><span class="fa fa-bullhorn"></span> 新闻公告 </h4>
<ul>
{% for news in site.categories.news limit: 3%}
<li><a href="/news/#{{news.slug}}"><strong>{{news.date | date: "%Y-%m-%d"}}</strong> {{news.title}}</a></li>
{% endfor %}
</ul>
<div class="text-right"><a href="/news/"> more <span class="fa fa-angle-double-right"></span> </a></div>
</div>
<div class="col-md-4">
<h4> <span class="fa fa-link"></span> 域名选择 </h4>
<ul>
<li><a href="https://mirrors.tuna.tsinghua.edu.cn/">https://mirrors.tuna.tsinghua.edu.cn/</a> 自动选择 </li>
<li><a href="https://mirrors6.tuna.tsinghua.edu.cn/">https://mirrors6.tuna.tsinghua.edu.cn/</a> 只解析 IPv6</li>
<li><a href="https://mirrors4.tuna.tsinghua.edu.cn/">https://mirrors4.tuna.tsinghua.edu.cn/</a> 只解析 IPv4</li>
</ul>
</div>
<div class="col-md-3">
<h4> <span class="fa fa-envelope-o"></span> 联系我们 </h4>
<ul>
<li><strong>意见反馈</strong> <br /> <a href="https://github.com/tuna/issues">https://github.com/tuna/issues</a></li>
<li><strong>发送邮件</strong> <br /> <a id="eib1gieB"></a></li>
<li><strong>在线交流</strong> <br /> <a href="https://fishroom.tuna.moe/log/tuna/today"> #tuna at freenode </a></li>
</ul>
</div>
<div class="col-md-2">
<h4> <span class="fa fa-external-link"></span> 相关链接 </h4>
<ul>
<li><a href="/help/">使用帮助</a></li>
<li><a href="/status/#server-status">服务器状态</a></li>
<li><a href="/status/#syncing-status">同步状态</a></li>
<li><a href="https://tuna.moe/">清华大学 TUNA 协会</a></li>
<li><a href="https://github.com/tuna/tunasync">镜像管理器源码</a></li>
<li><a href="https://github.com/tuna/tunasync-scripts">自定义镜像脚本</a></li>
</ul>
</div>
</div>
</div><!--/container -->
</div><!--/mirrors -->
{% include footer.html %}
<!-- iso download wizard modal -->
<!-- Modal -->
{% raw %}
<div class="modal fade" id="isoModal" tabindex="-1" role="dialog" aria-labelledby="isoModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="isoModalLabel">获取安装镜像</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<ul class="nav nav-tabs">
<li role="presentation" :class="[curCategory === 'os' ? 'active' : '']" @click="switchCategory('os')"><a href="#">操作系统</a></li>
<li role="presentation" :class="[curCategory === 'app' ? 'active' : '']" @click="switchCategory('app')"><a href="#">应用软件</a></li>
</ul>
</div>
<div class="col-md-3">
<ul class="nav nav-pills nav-stacked">
<li v-for="distro in curDistroList" :class="[selected.distro == distro.distro ? 'active' : '']">
<a href="#" @click="switchDistro(distro)">{{ distro.distro }}</a>
</li>
</ul>
</div>
<div class="col-md-9">
<h3>{{selected.distro}}</h3>
<ul>
<template v-for="url in selected.urls">
<li><a :href="url.url">{{url.name}}</a></li>
</template>
</ul>
</div>
</div>
</div>
</div>
</div>
</div><!-- /iso download wizard modal -->
{% endraw %}
</body>
{% raw %}
{% endraw %}
<script src="/static/js/index.js"></script>
<script src="/static/js/browser-update.js"></script>
</html>
<!--
vim: ts=2 sts=2 sw=2 noexpandtab

View File

@ -24,7 +24,7 @@ permalink: /news/
<div class="meta">
<span class="fa fa-calendar"></span> {{news.date | date: "%Y-%m-%d"}} <span class="fa fa-user" style="margin-left: 1em"> {{ news.author }}</span>
</div>
<div class="content">{{news.content || markdownify }}</div>
<div class="content">{{news.content | markdownify }}</div>
</article>
<hr />
{% endfor %}

View File

@ -1,3 +1,118 @@
# robots.txt for https://mirrors.tuna.tsinghua.edu.cn
User-agent: *
Disallow: /AOSP
Disallow: /CRAN
Disallow: /CTAN
Disallow: /CocoaPods
Disallow: /ELK
Disallow: /HHVM
Disallow: /NetBSD
Disallow: /OpenBSD
Disallow: /alpine
Disallow: /anaconda
Disallow: /antergos
Disallow: /anthon
Disallow: /aosp-monthly
Disallow: /apache
Disallow: /arch4edu
Disallow: /archlinux
Disallow: /archlinuxarm
Disallow: /archlinuxcn
Disallow: /bananian
Disallow: /bioconductor
Disallow: /bjlx
Disallow: /blackarch
Disallow: /centos
Disallow: /ceph
Disallow: /chakra
Disallow: /chromiumos
Disallow: /ctex
Disallow: /cygwin
Disallow: /debian-cd
Disallow: /debian-multimedia
Disallow: /debian-nonfree
Disallow: /debian-security
Disallow: /debian
Disallow: /deepin-cd
Disallow: /deepin
Disallow: /dell
Disallow: /docker
Disallow: /dotdeb
Disallow: /elasticstack
Disallow: /elpa
Disallow: /elrepo
Disallow: /elvish
Disallow: /epel
Disallow: /erlang-solutions
Disallow: /fedora
Disallow: /gentoo-portage
Disallow: /gentoo
Disallow: /git-repo
Disallow: /gitlab-ce
Disallow: /gitlab-ci-multi-runner
Disallow: /gnu
Disallow: /grafana
Disallow: /hackage
Disallow: /homebrew-bottles
Disallow: /homebrew
Disallow: /infinality-bundle
Disallow: /influxdata
Disallow: /ius
Disallow: /jenkins
Disallow: /kali-images
Disallow: /kali-security
Disallow: /kali
Disallow: /kernel
Disallow: /kodi
Disallow: /linux-stable.git
Disallow: /linux.git
Disallow: /linuxmint-cd
Disallow: /linuxmint
Disallow: /loongson
Disallow: /lxc-images
Disallow: /macports
Disallow: /mageia
Disallow: /manjaro-cd
Disallow: /manjaro
Disallow: /mariadb
Disallow: /mongodb
Disallow: /msys2
Disallow: /mysql
Disallow: /neurodebian
Disallow: /nodesource
Disallow: /opensuse
Disallow: /openwrt
Disallow: /osmc
Disallow: /packman
Disallow: /parrot
Disallow: /percona
Disallow: /postgresql
Disallow: /puppy
Disallow: /pybombs
Disallow: /pypi
Disallow: /qt
Disallow: /raspbian
Disallow: /redhat
Disallow: /remi
Disallow: /repo-ck
Disallow: /repoforge
Disallow: /ros
Disallow: /rpmfusion
Disallow: /rubygems
Disallow: /sagemath
Disallow: /saltstack
Disallow: /slackware
Disallow: /slackwarearm
Disallow: /stackage
Disallow: /steamos
Disallow: /tensorflow
Disallow: /termux
Disallow: /ubuntu-cdimage
Disallow: /ubuntu-cloud-images
Disallow: /ubuntu-ports
Disallow: /ubuntu-releases
Disallow: /ubuntu
Disallow: /videolan-ftp
Disallow: /virtualbox
Disallow: /weave

6
static/css/bootstrap-select.min.css vendored Executable file

File diff suppressed because one or more lines are too long

770
static/css/spinkit.css Normal file
View File

@ -0,0 +1,770 @@
/*
* Usage:
*
<div class="sk-rotating-plane"></div>
*
*/
.sk-rotating-plane {
width: 40px;
height: 40px;
background-color: #333;
margin: 40px auto;
-webkit-animation: sk-rotatePlane 1.2s infinite ease-in-out;
animation: sk-rotatePlane 1.2s infinite ease-in-out; }
@-webkit-keyframes sk-rotatePlane {
0% {
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg);
transform: perspective(120px) rotateX(0deg) rotateY(0deg); }
50% {
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); }
100% {
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); } }
@keyframes sk-rotatePlane {
0% {
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg);
transform: perspective(120px) rotateX(0deg) rotateY(0deg); }
50% {
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); }
100% {
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); } }
/*
* Usage:
*
<div class="sk-double-bounce">
<div class="sk-child sk-double-bounce1"></div>
<div class="sk-child sk-double-bounce2"></div>
</div>
*
*/
.sk-double-bounce {
width: 40px;
height: 40px;
position: relative;
margin: 40px auto; }
.sk-double-bounce .sk-child {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #333;
opacity: 0.6;
position: absolute;
top: 0;
left: 0;
-webkit-animation: sk-doubleBounce 2s infinite ease-in-out;
animation: sk-doubleBounce 2s infinite ease-in-out; }
.sk-double-bounce .sk-double-bounce2 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s; }
@-webkit-keyframes sk-doubleBounce {
0%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
50% {
-webkit-transform: scale(1);
transform: scale(1); } }
@keyframes sk-doubleBounce {
0%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
50% {
-webkit-transform: scale(1);
transform: scale(1); } }
/*
* Usage:
*
<div class="sk-wave">
<div class="sk-rect sk-rect1"></div>
<div class="sk-rect sk-rect2"></div>
<div class="sk-rect sk-rect3"></div>
<div class="sk-rect sk-rect4"></div>
<div class="sk-rect sk-rect5"></div>
</div>
*
*/
.sk-wave {
margin: 40px auto;
width: 50px;
height: 40px;
text-align: center;
font-size: 10px; }
.sk-wave .sk-rect {
background-color: #333;
height: 100%;
width: 6px;
display: inline-block;
-webkit-animation: sk-waveStretchDelay 1.2s infinite ease-in-out;
animation: sk-waveStretchDelay 1.2s infinite ease-in-out; }
.sk-wave .sk-rect1 {
-webkit-animation-delay: -1.2s;
animation-delay: -1.2s; }
.sk-wave .sk-rect2 {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s; }
.sk-wave .sk-rect3 {
-webkit-animation-delay: -1s;
animation-delay: -1s; }
.sk-wave .sk-rect4 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s; }
.sk-wave .sk-rect5 {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s; }
@-webkit-keyframes sk-waveStretchDelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4);
transform: scaleY(0.4); }
20% {
-webkit-transform: scaleY(1);
transform: scaleY(1); } }
@keyframes sk-waveStretchDelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4);
transform: scaleY(0.4); }
20% {
-webkit-transform: scaleY(1);
transform: scaleY(1); } }
/*
* Usage:
*
<div class="sk-wandering-cubes">
<div class="sk-cube sk-cube1"></div>
<div class="sk-cube sk-cube2"></div>
</div>
*
*/
.sk-wandering-cubes {
margin: 40px auto;
width: 40px;
height: 40px;
position: relative; }
.sk-wandering-cubes .sk-cube {
background-color: #333;
width: 10px;
height: 10px;
position: absolute;
top: 0;
left: 0;
-webkit-animation: sk-wanderingCube 1.8s ease-in-out -1.8s infinite both;
animation: sk-wanderingCube 1.8s ease-in-out -1.8s infinite both; }
.sk-wandering-cubes .sk-cube2 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s; }
@-webkit-keyframes sk-wanderingCube {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
25% {
-webkit-transform: translateX(30px) rotate(-90deg) scale(0.5);
transform: translateX(30px) rotate(-90deg) scale(0.5); }
50% {
/* Hack to make FF rotate in the right direction */
-webkit-transform: translateX(30px) translateY(30px) rotate(-179deg);
transform: translateX(30px) translateY(30px) rotate(-179deg); }
50.1% {
-webkit-transform: translateX(30px) translateY(30px) rotate(-180deg);
transform: translateX(30px) translateY(30px) rotate(-180deg); }
75% {
-webkit-transform: translateX(0) translateY(30px) rotate(-270deg) scale(0.5);
transform: translateX(0) translateY(30px) rotate(-270deg) scale(0.5); }
100% {
-webkit-transform: rotate(-360deg);
transform: rotate(-360deg); } }
@keyframes sk-wanderingCube {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
25% {
-webkit-transform: translateX(30px) rotate(-90deg) scale(0.5);
transform: translateX(30px) rotate(-90deg) scale(0.5); }
50% {
/* Hack to make FF rotate in the right direction */
-webkit-transform: translateX(30px) translateY(30px) rotate(-179deg);
transform: translateX(30px) translateY(30px) rotate(-179deg); }
50.1% {
-webkit-transform: translateX(30px) translateY(30px) rotate(-180deg);
transform: translateX(30px) translateY(30px) rotate(-180deg); }
75% {
-webkit-transform: translateX(0) translateY(30px) rotate(-270deg) scale(0.5);
transform: translateX(0) translateY(30px) rotate(-270deg) scale(0.5); }
100% {
-webkit-transform: rotate(-360deg);
transform: rotate(-360deg); } }
/*
* Usage:
*
<div class="sk-spinner sk-spinner-pulse"></div>
*
*/
.sk-spinner-pulse {
width: 40px;
height: 40px;
margin: 40px auto;
background-color: #333;
border-radius: 100%;
-webkit-animation: sk-pulseScaleOut 1s infinite ease-in-out;
animation: sk-pulseScaleOut 1s infinite ease-in-out; }
@-webkit-keyframes sk-pulseScaleOut {
0% {
-webkit-transform: scale(0);
transform: scale(0); }
100% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 0; } }
@keyframes sk-pulseScaleOut {
0% {
-webkit-transform: scale(0);
transform: scale(0); }
100% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 0; } }
/*
* Usage:
*
<div class="sk-chasing-dots">
<div class="sk-child sk-dot1"></div>
<div class="sk-child sk-dot2"></div>
</div>
*
*/
.sk-chasing-dots {
margin: 40px auto;
width: 40px;
height: 40px;
position: relative;
text-align: center;
-webkit-animation: sk-chasingDotsRotate 2s infinite linear;
animation: sk-chasingDotsRotate 2s infinite linear; }
.sk-chasing-dots .sk-child {
width: 60%;
height: 60%;
display: inline-block;
position: absolute;
top: 0;
background-color: #333;
border-radius: 100%;
-webkit-animation: sk-chasingDotsBounce 2s infinite ease-in-out;
animation: sk-chasingDotsBounce 2s infinite ease-in-out; }
.sk-chasing-dots .sk-dot2 {
top: auto;
bottom: 0;
-webkit-animation-delay: -1s;
animation-delay: -1s; }
@-webkit-keyframes sk-chasingDotsRotate {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
@keyframes sk-chasingDotsRotate {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
@-webkit-keyframes sk-chasingDotsBounce {
0%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
50% {
-webkit-transform: scale(1);
transform: scale(1); } }
@keyframes sk-chasingDotsBounce {
0%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
50% {
-webkit-transform: scale(1);
transform: scale(1); } }
/*
* Usage:
*
<div class="sk-three-bounce">
<div class="sk-child sk-bounce1"></div>
<div class="sk-child sk-bounce2"></div>
<div class="sk-child sk-bounce3"></div>
</div>
*
*/
.sk-three-bounce {
margin: 40px auto;
width: 80px;
text-align: center; }
.sk-three-bounce .sk-child {
width: 20px;
height: 20px;
background-color: #333;
border-radius: 100%;
display: inline-block;
-webkit-animation: sk-three-bounce 1.4s ease-in-out 0s infinite both;
animation: sk-three-bounce 1.4s ease-in-out 0s infinite both; }
.sk-three-bounce .sk-bounce1 {
-webkit-animation-delay: -0.32s;
animation-delay: -0.32s; }
.sk-three-bounce .sk-bounce2 {
-webkit-animation-delay: -0.16s;
animation-delay: -0.16s; }
@-webkit-keyframes sk-three-bounce {
0%, 80%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
40% {
-webkit-transform: scale(1);
transform: scale(1); } }
@keyframes sk-three-bounce {
0%, 80%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
40% {
-webkit-transform: scale(1);
transform: scale(1); } }
/*
* Usage:
*
<div class="sk-circle">
<div class="sk-circle1 sk-child"></div>
<div class="sk-circle2 sk-child"></div>
<div class="sk-circle3 sk-child"></div>
<div class="sk-circle4 sk-child"></div>
<div class="sk-circle5 sk-child"></div>
<div class="sk-circle6 sk-child"></div>
<div class="sk-circle7 sk-child"></div>
<div class="sk-circle8 sk-child"></div>
<div class="sk-circle9 sk-child"></div>
<div class="sk-circle10 sk-child"></div>
<div class="sk-circle11 sk-child"></div>
<div class="sk-circle12 sk-child"></div>
</div>
*
*/
.sk-circle {
margin: 40px auto;
width: 40px;
height: 40px;
position: relative; }
.sk-circle .sk-child {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0; }
.sk-circle .sk-child:before {
content: '';
display: block;
margin: 0 auto;
width: 15%;
height: 15%;
background-color: #333;
border-radius: 100%;
-webkit-animation: sk-circleBounceDelay 1.2s infinite ease-in-out both;
animation: sk-circleBounceDelay 1.2s infinite ease-in-out both; }
.sk-circle .sk-circle2 {
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg); }
.sk-circle .sk-circle3 {
-webkit-transform: rotate(60deg);
-ms-transform: rotate(60deg);
transform: rotate(60deg); }
.sk-circle .sk-circle4 {
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg); }
.sk-circle .sk-circle5 {
-webkit-transform: rotate(120deg);
-ms-transform: rotate(120deg);
transform: rotate(120deg); }
.sk-circle .sk-circle6 {
-webkit-transform: rotate(150deg);
-ms-transform: rotate(150deg);
transform: rotate(150deg); }
.sk-circle .sk-circle7 {
-webkit-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg); }
.sk-circle .sk-circle8 {
-webkit-transform: rotate(210deg);
-ms-transform: rotate(210deg);
transform: rotate(210deg); }
.sk-circle .sk-circle9 {
-webkit-transform: rotate(240deg);
-ms-transform: rotate(240deg);
transform: rotate(240deg); }
.sk-circle .sk-circle10 {
-webkit-transform: rotate(270deg);
-ms-transform: rotate(270deg);
transform: rotate(270deg); }
.sk-circle .sk-circle11 {
-webkit-transform: rotate(300deg);
-ms-transform: rotate(300deg);
transform: rotate(300deg); }
.sk-circle .sk-circle12 {
-webkit-transform: rotate(330deg);
-ms-transform: rotate(330deg);
transform: rotate(330deg); }
.sk-circle .sk-circle2:before {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s; }
.sk-circle .sk-circle3:before {
-webkit-animation-delay: -1s;
animation-delay: -1s; }
.sk-circle .sk-circle4:before {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s; }
.sk-circle .sk-circle5:before {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s; }
.sk-circle .sk-circle6:before {
-webkit-animation-delay: -0.7s;
animation-delay: -0.7s; }
.sk-circle .sk-circle7:before {
-webkit-animation-delay: -0.6s;
animation-delay: -0.6s; }
.sk-circle .sk-circle8:before {
-webkit-animation-delay: -0.5s;
animation-delay: -0.5s; }
.sk-circle .sk-circle9:before {
-webkit-animation-delay: -0.4s;
animation-delay: -0.4s; }
.sk-circle .sk-circle10:before {
-webkit-animation-delay: -0.3s;
animation-delay: -0.3s; }
.sk-circle .sk-circle11:before {
-webkit-animation-delay: -0.2s;
animation-delay: -0.2s; }
.sk-circle .sk-circle12:before {
-webkit-animation-delay: -0.1s;
animation-delay: -0.1s; }
@-webkit-keyframes sk-circleBounceDelay {
0%, 80%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
40% {
-webkit-transform: scale(1);
transform: scale(1); } }
@keyframes sk-circleBounceDelay {
0%, 80%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
40% {
-webkit-transform: scale(1);
transform: scale(1); } }
/*
* Usage:
*
<div class="sk-cube-grid">
<div class="sk-cube sk-cube1"></div>
<div class="sk-cube sk-cube2"></div>
<div class="sk-cube sk-cube3"></div>
<div class="sk-cube sk-cube4"></div>
<div class="sk-cube sk-cube5"></div>
<div class="sk-cube sk-cube6"></div>
<div class="sk-cube sk-cube7"></div>
<div class="sk-cube sk-cube8"></div>
<div class="sk-cube sk-cube9"></div>
</div>
*
*/
.sk-cube-grid {
width: 40px;
height: 40px;
margin: 40px auto;
/*
* Spinner positions
* 1 2 3
* 4 5 6
* 7 8 9
*/ }
.sk-cube-grid .sk-cube {
width: 33.33%;
height: 33.33%;
background-color: #333;
float: left;
-webkit-animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out; }
.sk-cube-grid .sk-cube1 {
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s; }
.sk-cube-grid .sk-cube2 {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s; }
.sk-cube-grid .sk-cube3 {
-webkit-animation-delay: 0.4s;
animation-delay: 0.4s; }
.sk-cube-grid .sk-cube4 {
-webkit-animation-delay: 0.1s;
animation-delay: 0.1s; }
.sk-cube-grid .sk-cube5 {
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s; }
.sk-cube-grid .sk-cube6 {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s; }
.sk-cube-grid .sk-cube7 {
-webkit-animation-delay: 0.0s;
animation-delay: 0.0s; }
.sk-cube-grid .sk-cube8 {
-webkit-animation-delay: 0.1s;
animation-delay: 0.1s; }
.sk-cube-grid .sk-cube9 {
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s; }
@-webkit-keyframes sk-cubeGridScaleDelay {
0%, 70%, 100% {
-webkit-transform: scale3D(1, 1, 1);
transform: scale3D(1, 1, 1); }
35% {
-webkit-transform: scale3D(0, 0, 1);
transform: scale3D(0, 0, 1); } }
@keyframes sk-cubeGridScaleDelay {
0%, 70%, 100% {
-webkit-transform: scale3D(1, 1, 1);
transform: scale3D(1, 1, 1); }
35% {
-webkit-transform: scale3D(0, 0, 1);
transform: scale3D(0, 0, 1); } }
/*
* Usage:
*
<div class="sk-fading-circle">
<div class="sk-circle1 sk-circle"></div>
<div class="sk-circle2 sk-circle"></div>
<div class="sk-circle3 sk-circle"></div>
<div class="sk-circle4 sk-circle"></div>
<div class="sk-circle5 sk-circle"></div>
<div class="sk-circle6 sk-circle"></div>
<div class="sk-circle7 sk-circle"></div>
<div class="sk-circle8 sk-circle"></div>
<div class="sk-circle9 sk-circle"></div>
<div class="sk-circle10 sk-circle"></div>
<div class="sk-circle11 sk-circle"></div>
<div class="sk-circle12 sk-circle"></div>
</div>
*
*/
.sk-fading-circle {
margin: 40px auto;
width: 40px;
height: 40px;
position: relative; }
.sk-fading-circle .sk-circle {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0; }
.sk-fading-circle .sk-circle:before {
content: '';
display: block;
margin: 0 auto;
width: 15%;
height: 15%;
background-color: #333;
border-radius: 100%;
-webkit-animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;
animation: sk-circleFadeDelay 1.2s infinite ease-in-out both; }
.sk-fading-circle .sk-circle2 {
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg); }
.sk-fading-circle .sk-circle3 {
-webkit-transform: rotate(60deg);
-ms-transform: rotate(60deg);
transform: rotate(60deg); }
.sk-fading-circle .sk-circle4 {
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg); }
.sk-fading-circle .sk-circle5 {
-webkit-transform: rotate(120deg);
-ms-transform: rotate(120deg);
transform: rotate(120deg); }
.sk-fading-circle .sk-circle6 {
-webkit-transform: rotate(150deg);
-ms-transform: rotate(150deg);
transform: rotate(150deg); }
.sk-fading-circle .sk-circle7 {
-webkit-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg); }
.sk-fading-circle .sk-circle8 {
-webkit-transform: rotate(210deg);
-ms-transform: rotate(210deg);
transform: rotate(210deg); }
.sk-fading-circle .sk-circle9 {
-webkit-transform: rotate(240deg);
-ms-transform: rotate(240deg);
transform: rotate(240deg); }
.sk-fading-circle .sk-circle10 {
-webkit-transform: rotate(270deg);
-ms-transform: rotate(270deg);
transform: rotate(270deg); }
.sk-fading-circle .sk-circle11 {
-webkit-transform: rotate(300deg);
-ms-transform: rotate(300deg);
transform: rotate(300deg); }
.sk-fading-circle .sk-circle12 {
-webkit-transform: rotate(330deg);
-ms-transform: rotate(330deg);
transform: rotate(330deg); }
.sk-fading-circle .sk-circle2:before {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s; }
.sk-fading-circle .sk-circle3:before {
-webkit-animation-delay: -1s;
animation-delay: -1s; }
.sk-fading-circle .sk-circle4:before {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s; }
.sk-fading-circle .sk-circle5:before {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s; }
.sk-fading-circle .sk-circle6:before {
-webkit-animation-delay: -0.7s;
animation-delay: -0.7s; }
.sk-fading-circle .sk-circle7:before {
-webkit-animation-delay: -0.6s;
animation-delay: -0.6s; }
.sk-fading-circle .sk-circle8:before {
-webkit-animation-delay: -0.5s;
animation-delay: -0.5s; }
.sk-fading-circle .sk-circle9:before {
-webkit-animation-delay: -0.4s;
animation-delay: -0.4s; }
.sk-fading-circle .sk-circle10:before {
-webkit-animation-delay: -0.3s;
animation-delay: -0.3s; }
.sk-fading-circle .sk-circle11:before {
-webkit-animation-delay: -0.2s;
animation-delay: -0.2s; }
.sk-fading-circle .sk-circle12:before {
-webkit-animation-delay: -0.1s;
animation-delay: -0.1s; }
@-webkit-keyframes sk-circleFadeDelay {
0%, 39%, 100% {
opacity: 0; }
40% {
opacity: 1; } }
@keyframes sk-circleFadeDelay {
0%, 39%, 100% {
opacity: 0; }
40% {
opacity: 1; } }
/*
* Usage:
*
<div class="sk-folding-cube">
<div class="sk-cube1 sk-cube"></div>
<div class="sk-cube2 sk-cube"></div>
<div class="sk-cube4 sk-cube"></div>
<div class="sk-cube3 sk-cube"></div>
</div>
*
*/
.sk-folding-cube {
margin: 40px auto;
width: 40px;
height: 40px;
position: relative;
-webkit-transform: rotateZ(45deg);
transform: rotateZ(45deg); }
.sk-folding-cube .sk-cube {
float: left;
width: 50%;
height: 50%;
position: relative;
-webkit-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1); }
.sk-folding-cube .sk-cube:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #333;
-webkit-animation: sk-foldCubeAngle 2.4s infinite linear both;
animation: sk-foldCubeAngle 2.4s infinite linear both;
-webkit-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
transform-origin: 100% 100%; }
.sk-folding-cube .sk-cube2 {
-webkit-transform: scale(1.1) rotateZ(90deg);
transform: scale(1.1) rotateZ(90deg); }
.sk-folding-cube .sk-cube3 {
-webkit-transform: scale(1.1) rotateZ(180deg);
transform: scale(1.1) rotateZ(180deg); }
.sk-folding-cube .sk-cube4 {
-webkit-transform: scale(1.1) rotateZ(270deg);
transform: scale(1.1) rotateZ(270deg); }
.sk-folding-cube .sk-cube2:before {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s; }
.sk-folding-cube .sk-cube3:before {
-webkit-animation-delay: 0.6s;
animation-delay: 0.6s; }
.sk-folding-cube .sk-cube4:before {
-webkit-animation-delay: 0.9s;
animation-delay: 0.9s; }
@-webkit-keyframes sk-foldCubeAngle {
0%, 10% {
-webkit-transform: perspective(140px) rotateX(-180deg);
transform: perspective(140px) rotateX(-180deg);
opacity: 0; }
25%, 75% {
-webkit-transform: perspective(140px) rotateX(0deg);
transform: perspective(140px) rotateX(0deg);
opacity: 1; }
90%, 100% {
-webkit-transform: perspective(140px) rotateY(180deg);
transform: perspective(140px) rotateY(180deg);
opacity: 0; } }
@keyframes sk-foldCubeAngle {
0%, 10% {
-webkit-transform: perspective(140px) rotateX(-180deg);
transform: perspective(140px) rotateX(-180deg);
opacity: 0; }
25%, 75% {
-webkit-transform: perspective(140px) rotateX(0deg);
transform: perspective(140px) rotateX(0deg);
opacity: 1; }
90%, 100% {
-webkit-transform: perspective(140px) rotateY(180deg);
transform: perspective(140px) rotateY(180deg);
opacity: 0; } }

View File

@ -0,0 +1,35 @@
/*
* Usage:
*
<div class="sk-rotating-plane"></div>
*
*/
.sk-rotating-plane {
width: 40px;
height: 40px;
background-color: #333;
margin: 40px auto;
-webkit-animation: sk-rotatePlane 1.2s infinite ease-in-out;
animation: sk-rotatePlane 1.2s infinite ease-in-out; }
@-webkit-keyframes sk-rotatePlane {
0% {
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg);
transform: perspective(120px) rotateX(0deg) rotateY(0deg); }
50% {
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); }
100% {
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); } }
@keyframes sk-rotatePlane {
0% {
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg);
transform: perspective(120px) rotateX(0deg) rotateY(0deg); }
50% {
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); }
100% {
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); } }

View File

@ -0,0 +1,129 @@
/*
* Usage:
*
<div class="sk-fading-circle">
<div class="sk-circle1 sk-circle"></div>
<div class="sk-circle2 sk-circle"></div>
<div class="sk-circle3 sk-circle"></div>
<div class="sk-circle4 sk-circle"></div>
<div class="sk-circle5 sk-circle"></div>
<div class="sk-circle6 sk-circle"></div>
<div class="sk-circle7 sk-circle"></div>
<div class="sk-circle8 sk-circle"></div>
<div class="sk-circle9 sk-circle"></div>
<div class="sk-circle10 sk-circle"></div>
<div class="sk-circle11 sk-circle"></div>
<div class="sk-circle12 sk-circle"></div>
</div>
*
*/
.sk-fading-circle {
margin: 40px auto;
width: 40px;
height: 40px;
position: relative; }
.sk-fading-circle .sk-circle {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0; }
.sk-fading-circle .sk-circle:before {
content: '';
display: block;
margin: 0 auto;
width: 15%;
height: 15%;
background-color: #333;
border-radius: 100%;
-webkit-animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;
animation: sk-circleFadeDelay 1.2s infinite ease-in-out both; }
.sk-fading-circle .sk-circle2 {
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg); }
.sk-fading-circle .sk-circle3 {
-webkit-transform: rotate(60deg);
-ms-transform: rotate(60deg);
transform: rotate(60deg); }
.sk-fading-circle .sk-circle4 {
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg); }
.sk-fading-circle .sk-circle5 {
-webkit-transform: rotate(120deg);
-ms-transform: rotate(120deg);
transform: rotate(120deg); }
.sk-fading-circle .sk-circle6 {
-webkit-transform: rotate(150deg);
-ms-transform: rotate(150deg);
transform: rotate(150deg); }
.sk-fading-circle .sk-circle7 {
-webkit-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg); }
.sk-fading-circle .sk-circle8 {
-webkit-transform: rotate(210deg);
-ms-transform: rotate(210deg);
transform: rotate(210deg); }
.sk-fading-circle .sk-circle9 {
-webkit-transform: rotate(240deg);
-ms-transform: rotate(240deg);
transform: rotate(240deg); }
.sk-fading-circle .sk-circle10 {
-webkit-transform: rotate(270deg);
-ms-transform: rotate(270deg);
transform: rotate(270deg); }
.sk-fading-circle .sk-circle11 {
-webkit-transform: rotate(300deg);
-ms-transform: rotate(300deg);
transform: rotate(300deg); }
.sk-fading-circle .sk-circle12 {
-webkit-transform: rotate(330deg);
-ms-transform: rotate(330deg);
transform: rotate(330deg); }
.sk-fading-circle .sk-circle2:before {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s; }
.sk-fading-circle .sk-circle3:before {
-webkit-animation-delay: -1s;
animation-delay: -1s; }
.sk-fading-circle .sk-circle4:before {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s; }
.sk-fading-circle .sk-circle5:before {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s; }
.sk-fading-circle .sk-circle6:before {
-webkit-animation-delay: -0.7s;
animation-delay: -0.7s; }
.sk-fading-circle .sk-circle7:before {
-webkit-animation-delay: -0.6s;
animation-delay: -0.6s; }
.sk-fading-circle .sk-circle8:before {
-webkit-animation-delay: -0.5s;
animation-delay: -0.5s; }
.sk-fading-circle .sk-circle9:before {
-webkit-animation-delay: -0.4s;
animation-delay: -0.4s; }
.sk-fading-circle .sk-circle10:before {
-webkit-animation-delay: -0.3s;
animation-delay: -0.3s; }
.sk-fading-circle .sk-circle11:before {
-webkit-animation-delay: -0.2s;
animation-delay: -0.2s; }
.sk-fading-circle .sk-circle12:before {
-webkit-animation-delay: -0.1s;
animation-delay: -0.1s; }
@-webkit-keyframes sk-circleFadeDelay {
0%, 39%, 100% {
opacity: 0; }
40% {
opacity: 1; } }
@keyframes sk-circleFadeDelay {
0%, 39%, 100% {
opacity: 0; }
40% {
opacity: 1; } }

View File

@ -0,0 +1,85 @@
/*
* Usage:
*
<div class="sk-folding-cube">
<div class="sk-cube1 sk-cube"></div>
<div class="sk-cube2 sk-cube"></div>
<div class="sk-cube4 sk-cube"></div>
<div class="sk-cube3 sk-cube"></div>
</div>
*
*/
.sk-folding-cube {
margin: 40px auto;
width: 40px;
height: 40px;
position: relative;
-webkit-transform: rotateZ(45deg);
transform: rotateZ(45deg); }
.sk-folding-cube .sk-cube {
float: left;
width: 50%;
height: 50%;
position: relative;
-webkit-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1); }
.sk-folding-cube .sk-cube:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #333;
-webkit-animation: sk-foldCubeAngle 2.4s infinite linear both;
animation: sk-foldCubeAngle 2.4s infinite linear both;
-webkit-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
transform-origin: 100% 100%; }
.sk-folding-cube .sk-cube2 {
-webkit-transform: scale(1.1) rotateZ(90deg);
transform: scale(1.1) rotateZ(90deg); }
.sk-folding-cube .sk-cube3 {
-webkit-transform: scale(1.1) rotateZ(180deg);
transform: scale(1.1) rotateZ(180deg); }
.sk-folding-cube .sk-cube4 {
-webkit-transform: scale(1.1) rotateZ(270deg);
transform: scale(1.1) rotateZ(270deg); }
.sk-folding-cube .sk-cube2:before {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s; }
.sk-folding-cube .sk-cube3:before {
-webkit-animation-delay: 0.6s;
animation-delay: 0.6s; }
.sk-folding-cube .sk-cube4:before {
-webkit-animation-delay: 0.9s;
animation-delay: 0.9s; }
@-webkit-keyframes sk-foldCubeAngle {
0%, 10% {
-webkit-transform: perspective(140px) rotateX(-180deg);
transform: perspective(140px) rotateX(-180deg);
opacity: 0; }
25%, 75% {
-webkit-transform: perspective(140px) rotateX(0deg);
transform: perspective(140px) rotateX(0deg);
opacity: 1; }
90%, 100% {
-webkit-transform: perspective(140px) rotateY(180deg);
transform: perspective(140px) rotateY(180deg);
opacity: 0; } }
@keyframes sk-foldCubeAngle {
0%, 10% {
-webkit-transform: perspective(140px) rotateX(-180deg);
transform: perspective(140px) rotateX(-180deg);
opacity: 0; }
25%, 75% {
-webkit-transform: perspective(140px) rotateX(0deg);
transform: perspective(140px) rotateX(0deg);
opacity: 1; }
90%, 100% {
-webkit-transform: perspective(140px) rotateY(180deg);
transform: perspective(140px) rotateY(180deg);
opacity: 0; } }

View File

@ -0,0 +1,44 @@
/*
* Usage:
*
<div class="sk-double-bounce">
<div class="sk-child sk-double-bounce1"></div>
<div class="sk-child sk-double-bounce2"></div>
</div>
*
*/
.sk-double-bounce {
width: 40px;
height: 40px;
position: relative;
margin: 40px auto; }
.sk-double-bounce .sk-child {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #333;
opacity: 0.6;
position: absolute;
top: 0;
left: 0;
-webkit-animation: sk-doubleBounce 2s infinite ease-in-out;
animation: sk-doubleBounce 2s infinite ease-in-out; }
.sk-double-bounce .sk-double-bounce2 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s; }
@-webkit-keyframes sk-doubleBounce {
0%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
50% {
-webkit-transform: scale(1);
transform: scale(1); } }
@keyframes sk-doubleBounce {
0%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
50% {
-webkit-transform: scale(1);
transform: scale(1); } }

View File

@ -0,0 +1,56 @@
/*
* Usage:
*
<div class="sk-wave">
<div class="sk-rect sk-rect1"></div>
<div class="sk-rect sk-rect2"></div>
<div class="sk-rect sk-rect3"></div>
<div class="sk-rect sk-rect4"></div>
<div class="sk-rect sk-rect5"></div>
</div>
*
*/
.sk-wave {
margin: 40px auto;
width: 50px;
height: 40px;
text-align: center;
font-size: 10px; }
.sk-wave .sk-rect {
background-color: #333;
height: 100%;
width: 6px;
display: inline-block;
-webkit-animation: sk-waveStretchDelay 1.2s infinite ease-in-out;
animation: sk-waveStretchDelay 1.2s infinite ease-in-out; }
.sk-wave .sk-rect1 {
-webkit-animation-delay: -1.2s;
animation-delay: -1.2s; }
.sk-wave .sk-rect2 {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s; }
.sk-wave .sk-rect3 {
-webkit-animation-delay: -1s;
animation-delay: -1s; }
.sk-wave .sk-rect4 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s; }
.sk-wave .sk-rect5 {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s; }
@-webkit-keyframes sk-waveStretchDelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4);
transform: scaleY(0.4); }
20% {
-webkit-transform: scaleY(1);
transform: scaleY(1); } }
@keyframes sk-waveStretchDelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4);
transform: scaleY(0.4); }
20% {
-webkit-transform: scaleY(1);
transform: scaleY(1); } }

View File

@ -0,0 +1,68 @@
/*
* Usage:
*
<div class="sk-wandering-cubes">
<div class="sk-cube sk-cube1"></div>
<div class="sk-cube sk-cube2"></div>
</div>
*
*/
.sk-wandering-cubes {
margin: 40px auto;
width: 40px;
height: 40px;
position: relative; }
.sk-wandering-cubes .sk-cube {
background-color: #333;
width: 10px;
height: 10px;
position: absolute;
top: 0;
left: 0;
-webkit-animation: sk-wanderingCube 1.8s ease-in-out -1.8s infinite both;
animation: sk-wanderingCube 1.8s ease-in-out -1.8s infinite both; }
.sk-wandering-cubes .sk-cube2 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s; }
@-webkit-keyframes sk-wanderingCube {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
25% {
-webkit-transform: translateX(30px) rotate(-90deg) scale(0.5);
transform: translateX(30px) rotate(-90deg) scale(0.5); }
50% {
/* Hack to make FF rotate in the right direction */
-webkit-transform: translateX(30px) translateY(30px) rotate(-179deg);
transform: translateX(30px) translateY(30px) rotate(-179deg); }
50.1% {
-webkit-transform: translateX(30px) translateY(30px) rotate(-180deg);
transform: translateX(30px) translateY(30px) rotate(-180deg); }
75% {
-webkit-transform: translateX(0) translateY(30px) rotate(-270deg) scale(0.5);
transform: translateX(0) translateY(30px) rotate(-270deg) scale(0.5); }
100% {
-webkit-transform: rotate(-360deg);
transform: rotate(-360deg); } }
@keyframes sk-wanderingCube {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
25% {
-webkit-transform: translateX(30px) rotate(-90deg) scale(0.5);
transform: translateX(30px) rotate(-90deg) scale(0.5); }
50% {
/* Hack to make FF rotate in the right direction */
-webkit-transform: translateX(30px) translateY(30px) rotate(-179deg);
transform: translateX(30px) translateY(30px) rotate(-179deg); }
50.1% {
-webkit-transform: translateX(30px) translateY(30px) rotate(-180deg);
transform: translateX(30px) translateY(30px) rotate(-180deg); }
75% {
-webkit-transform: translateX(0) translateY(30px) rotate(-270deg) scale(0.5);
transform: translateX(0) translateY(30px) rotate(-270deg) scale(0.5); }
100% {
-webkit-transform: rotate(-360deg);
transform: rotate(-360deg); } }

View File

@ -0,0 +1,32 @@
/*
* Usage:
*
<div class="sk-spinner sk-spinner-pulse"></div>
*
*/
.sk-spinner-pulse {
width: 40px;
height: 40px;
margin: 40px auto;
background-color: #333;
border-radius: 100%;
-webkit-animation: sk-pulseScaleOut 1s infinite ease-in-out;
animation: sk-pulseScaleOut 1s infinite ease-in-out; }
@-webkit-keyframes sk-pulseScaleOut {
0% {
-webkit-transform: scale(0);
transform: scale(0); }
100% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 0; } }
@keyframes sk-pulseScaleOut {
0% {
-webkit-transform: scale(0);
transform: scale(0); }
100% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 0; } }

View File

@ -0,0 +1,58 @@
/*
* Usage:
*
<div class="sk-chasing-dots">
<div class="sk-child sk-dot1"></div>
<div class="sk-child sk-dot2"></div>
</div>
*
*/
.sk-chasing-dots {
margin: 40px auto;
width: 40px;
height: 40px;
position: relative;
text-align: center;
-webkit-animation: sk-chasingDotsRotate 2s infinite linear;
animation: sk-chasingDotsRotate 2s infinite linear; }
.sk-chasing-dots .sk-child {
width: 60%;
height: 60%;
display: inline-block;
position: absolute;
top: 0;
background-color: #333;
border-radius: 100%;
-webkit-animation: sk-chasingDotsBounce 2s infinite ease-in-out;
animation: sk-chasingDotsBounce 2s infinite ease-in-out; }
.sk-chasing-dots .sk-dot2 {
top: auto;
bottom: 0;
-webkit-animation-delay: -1s;
animation-delay: -1s; }
@-webkit-keyframes sk-chasingDotsRotate {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
@keyframes sk-chasingDotsRotate {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
@-webkit-keyframes sk-chasingDotsBounce {
0%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
50% {
-webkit-transform: scale(1);
transform: scale(1); } }
@keyframes sk-chasingDotsBounce {
0%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
50% {
-webkit-transform: scale(1);
transform: scale(1); } }

View File

@ -0,0 +1,44 @@
/*
* Usage:
*
<div class="sk-three-bounce">
<div class="sk-child sk-bounce1"></div>
<div class="sk-child sk-bounce2"></div>
<div class="sk-child sk-bounce3"></div>
</div>
*
*/
.sk-three-bounce {
margin: 40px auto;
width: 80px;
text-align: center; }
.sk-three-bounce .sk-child {
width: 20px;
height: 20px;
background-color: #333;
border-radius: 100%;
display: inline-block;
-webkit-animation: sk-three-bounce 1.4s ease-in-out 0s infinite both;
animation: sk-three-bounce 1.4s ease-in-out 0s infinite both; }
.sk-three-bounce .sk-bounce1 {
-webkit-animation-delay: -0.32s;
animation-delay: -0.32s; }
.sk-three-bounce .sk-bounce2 {
-webkit-animation-delay: -0.16s;
animation-delay: -0.16s; }
@-webkit-keyframes sk-three-bounce {
0%, 80%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
40% {
-webkit-transform: scale(1);
transform: scale(1); } }
@keyframes sk-three-bounce {
0%, 80%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
40% {
-webkit-transform: scale(1);
transform: scale(1); } }

View File

@ -0,0 +1,133 @@
/*
* Usage:
*
<div class="sk-circle">
<div class="sk-circle1 sk-child"></div>
<div class="sk-circle2 sk-child"></div>
<div class="sk-circle3 sk-child"></div>
<div class="sk-circle4 sk-child"></div>
<div class="sk-circle5 sk-child"></div>
<div class="sk-circle6 sk-child"></div>
<div class="sk-circle7 sk-child"></div>
<div class="sk-circle8 sk-child"></div>
<div class="sk-circle9 sk-child"></div>
<div class="sk-circle10 sk-child"></div>
<div class="sk-circle11 sk-child"></div>
<div class="sk-circle12 sk-child"></div>
</div>
*
*/
.sk-circle {
margin: 40px auto;
width: 40px;
height: 40px;
position: relative; }
.sk-circle .sk-child {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0; }
.sk-circle .sk-child:before {
content: '';
display: block;
margin: 0 auto;
width: 15%;
height: 15%;
background-color: #333;
border-radius: 100%;
-webkit-animation: sk-circleBounceDelay 1.2s infinite ease-in-out both;
animation: sk-circleBounceDelay 1.2s infinite ease-in-out both; }
.sk-circle .sk-circle2 {
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg); }
.sk-circle .sk-circle3 {
-webkit-transform: rotate(60deg);
-ms-transform: rotate(60deg);
transform: rotate(60deg); }
.sk-circle .sk-circle4 {
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg); }
.sk-circle .sk-circle5 {
-webkit-transform: rotate(120deg);
-ms-transform: rotate(120deg);
transform: rotate(120deg); }
.sk-circle .sk-circle6 {
-webkit-transform: rotate(150deg);
-ms-transform: rotate(150deg);
transform: rotate(150deg); }
.sk-circle .sk-circle7 {
-webkit-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg); }
.sk-circle .sk-circle8 {
-webkit-transform: rotate(210deg);
-ms-transform: rotate(210deg);
transform: rotate(210deg); }
.sk-circle .sk-circle9 {
-webkit-transform: rotate(240deg);
-ms-transform: rotate(240deg);
transform: rotate(240deg); }
.sk-circle .sk-circle10 {
-webkit-transform: rotate(270deg);
-ms-transform: rotate(270deg);
transform: rotate(270deg); }
.sk-circle .sk-circle11 {
-webkit-transform: rotate(300deg);
-ms-transform: rotate(300deg);
transform: rotate(300deg); }
.sk-circle .sk-circle12 {
-webkit-transform: rotate(330deg);
-ms-transform: rotate(330deg);
transform: rotate(330deg); }
.sk-circle .sk-circle2:before {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s; }
.sk-circle .sk-circle3:before {
-webkit-animation-delay: -1s;
animation-delay: -1s; }
.sk-circle .sk-circle4:before {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s; }
.sk-circle .sk-circle5:before {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s; }
.sk-circle .sk-circle6:before {
-webkit-animation-delay: -0.7s;
animation-delay: -0.7s; }
.sk-circle .sk-circle7:before {
-webkit-animation-delay: -0.6s;
animation-delay: -0.6s; }
.sk-circle .sk-circle8:before {
-webkit-animation-delay: -0.5s;
animation-delay: -0.5s; }
.sk-circle .sk-circle9:before {
-webkit-animation-delay: -0.4s;
animation-delay: -0.4s; }
.sk-circle .sk-circle10:before {
-webkit-animation-delay: -0.3s;
animation-delay: -0.3s; }
.sk-circle .sk-circle11:before {
-webkit-animation-delay: -0.2s;
animation-delay: -0.2s; }
.sk-circle .sk-circle12:before {
-webkit-animation-delay: -0.1s;
animation-delay: -0.1s; }
@-webkit-keyframes sk-circleBounceDelay {
0%, 80%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
40% {
-webkit-transform: scale(1);
transform: scale(1); } }
@keyframes sk-circleBounceDelay {
0%, 80%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
40% {
-webkit-transform: scale(1);
transform: scale(1); } }

View File

@ -0,0 +1,76 @@
/*
* Usage:
*
<div class="sk-cube-grid">
<div class="sk-cube sk-cube1"></div>
<div class="sk-cube sk-cube2"></div>
<div class="sk-cube sk-cube3"></div>
<div class="sk-cube sk-cube4"></div>
<div class="sk-cube sk-cube5"></div>
<div class="sk-cube sk-cube6"></div>
<div class="sk-cube sk-cube7"></div>
<div class="sk-cube sk-cube8"></div>
<div class="sk-cube sk-cube9"></div>
</div>
*
*/
.sk-cube-grid {
width: 40px;
height: 40px;
margin: 40px auto;
/*
* Spinner positions
* 1 2 3
* 4 5 6
* 7 8 9
*/ }
.sk-cube-grid .sk-cube {
width: 33.33%;
height: 33.33%;
background-color: #333;
float: left;
-webkit-animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out; }
.sk-cube-grid .sk-cube1 {
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s; }
.sk-cube-grid .sk-cube2 {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s; }
.sk-cube-grid .sk-cube3 {
-webkit-animation-delay: 0.4s;
animation-delay: 0.4s; }
.sk-cube-grid .sk-cube4 {
-webkit-animation-delay: 0.1s;
animation-delay: 0.1s; }
.sk-cube-grid .sk-cube5 {
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s; }
.sk-cube-grid .sk-cube6 {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s; }
.sk-cube-grid .sk-cube7 {
-webkit-animation-delay: 0.0s;
animation-delay: 0.0s; }
.sk-cube-grid .sk-cube8 {
-webkit-animation-delay: 0.1s;
animation-delay: 0.1s; }
.sk-cube-grid .sk-cube9 {
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s; }
@-webkit-keyframes sk-cubeGridScaleDelay {
0%, 70%, 100% {
-webkit-transform: scale3D(1, 1, 1);
transform: scale3D(1, 1, 1); }
35% {
-webkit-transform: scale3D(0, 0, 1);
transform: scale3D(0, 0, 1); } }
@keyframes sk-cubeGridScaleDelay {
0%, 70%, 100% {
-webkit-transform: scale3D(1, 1, 1);
transform: scale3D(1, 1, 1); }
35% {
-webkit-transform: scale3D(0, 0, 1);
transform: scale3D(0, 0, 1); } }

View File

@ -73,7 +73,7 @@ $font_local: 'Heiti SC', 'Hiragino Sans GB', 'STHeiti', 'Source Han Sans CN', 'W
tr:hover {
background-color: #e0f3fc;
}
tr.status-fail {
tr.status-fail, tr.status-failed, tr.status-paused {
background-color: #fff4e3;
}
tr.status-syncing {
@ -92,6 +92,7 @@ $font_local: 'Heiti SC', 'Hiragino Sans GB', 'STHeiti', 'Source Han Sans CN', 'W
}
.label.label-status {
vertical-align: 20%;
margin-left: .5em;
}
.fa-question-circle {
color: #234961;
@ -102,6 +103,31 @@ $font_local: 'Heiti SC', 'Hiragino Sans GB', 'STHeiti', 'Source Han Sans CN', 'W
color: $color_text;
}
}
#download-link {
margin-bottom: 1em;
}
}
#isoModal {
.nav-tabs {
margin-bottom: .5em;
}
}
#status-page {
.thead {
font-weight: bold;
}
#mirror-list {
.status-syncing {
background-color: #e3fffd;
}
:hover {
background-color: #e0f3fc;
}
.status-fail, .status-failed {
background-color: #fff4e3;
}
}
}
#help-page {
@ -115,6 +141,9 @@ $font_local: 'Heiti SC', 'Hiragino Sans GB', 'STHeiti', 'Source Han Sans CN', 'W
color: $color_grey;
}
}
.fa-user {
font-family: #{$font_default}, 'FontAwesome';
}
}
/* Footer */

9
static/js/bootstrap-select.min.js vendored Executable file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
var $buoop = {vs:{i:10,f:-4,o:-4,s:8,c:-4},unsecure:true,api:4};
function $buo_f(){
var e = document.createElement("script");
e.src = "//browser-update.org/update.min.js";
document.body.appendChild(e);
};
try {document.addEventListener("DOMContentLoaded", $buo_f,false)}
catch(e){window.attachEvent("onload", $buo_f)}

View File

@ -6,18 +6,20 @@ $(document).ready(() => {
.addClass("table table-bordered table-striped");
var update_apt_file = (ev) => {
var sel = $(ev.target);
var os_name=sel.find("option:selected").data('os'),
var sel = $(ev.target),
os_name=sel.find("option:selected").data('os'),
release_name=sel.find("option:selected").data('release'),
opt=sel.find('option:selected').data('opt'),
tmpl_selector=sel.data("template"),
target_selector=sel.data("target"),
apt_template = $.trim($(tmpl_selector).text()),
apt_content = Mark.up(
apt_template,
{
os_name: os_name,
release_name: release_name
}
apt_template=$.trim($(tmpl_selector).text()),
tmpl_data=$.extend({}, {
os_name: os_name,
release_name: release_name
}, opt),
apt_content=Mark.up(
apt_template,
tmpl_data
);
$(target_selector).html(apt_content);
};
@ -31,7 +33,6 @@ $(document).ready(() => {
let help_url = $(ev.target).find("option:selected").data('help-url');
window.location = `${window.location.protocol}//${window.location.host}${help_url}`;
});
});
// vim: ts=2 sts=2 sw=2 noexpandtab

View File

@ -1,26 +1,30 @@
---
---
$(document).ready(() => {
var lei3Po8h = ["support", ["tuna", "tsinghua", "edu", "cn"].join(".")].join("@");
$('a#eib1gieB')
.text(lei3Po8h)
.attr('href', atob('bWFpbHRvOgo=') + lei3Po8h);
$('.selectpicker').selectpicker()
var mir_tmpl = $("#template").text(),
label_map = {
'unknown': 'label-default',
'syncing': 'label-info',
'success': 'label-success',
'fail': 'label-warning'
},
'fail': 'label-warning',
'failed': 'label-warning',
'paused': 'label-warning',
},
help_url = {
{% for h in site.categories['help'] %}"{{h.mirrorid}}": "{{h.url}}"{% if forloop.index < forloop.length %},{% endif %}{% endfor %}
},
new_mirrors = {
{% for n in site.new_mirrors %}"{{n}}": true{% if forloop.index < forloop.length %},{% endif %}{% endfor %}
},
unlisted = [
{
'status': 'success',
'last_update': "-",
'name': 'npm',
'upstream': 'https://registry.npmjs.org/'
},
{
'status': 'success',
'last_update': '-',
@ -31,40 +35,146 @@ var mir_tmpl = $("#template").text(),
],
options = {
'AOSP': {
'url': "/help/AOSP/",
'url': "/help/AOSP/"
},
'lineageOS': {
'url': "/help/lineageOS/"
},
'homebrew': {
'url': "/help/homebrew/"
},
'linux.git': {
'url': "/help/linux.git/"
},
'linux-stable.git': {
'url': "/help/linux-stable.git/"
},
'git-repo': {
'url': "/help/git-repo/"
},
'chromiumos': {
'url': "/help/chromiumos/"
},
'weave': {
'url': "/help/weave/"
},
'CocoaPods': {
'url': "/help/CocoaPods/"
},
'llvm': {
'url': "/help/llvm/"
}
};
},
descriptions = {
{% for mir in site.data.mirror_desc %} '{{mir.name}}': '{{mir.desc}}' {% if forloop.index < forloop.length %},{% endif %}{% endfor %}
}
window.refreshMirrorList = () => {
$.getJSON("/static/tunasync.json", (status_data) => {
var mirrors = [], mir_data = $.merge(status_data, unlisted);
mir_data.sort((a, b) => { return a.name < b.name ? -1: 1 });
for(var k in mir_data) {
var d = mir_data[k];
if (options[d['name']] != undefined ) {
d = $.extend(d, options[d['name']]);
var vmMirList = new Vue({
el: "#mirror-list",
data: {
test: "hello",
mirrorList: []
},
created () {
this.refreshMirrorList();
},
updated () {
$('.mirror-item-label').popover();
},
methods: {
getURL (mir) {
if (mir.url !== undefined) {
return mir.url
}
d['label'] = label_map[d['status']];
d['help_url'] = help_url[d['name']];
d['is_new'] = new_mirrors[d['name']];
d['show_status'] = (d.status != "success");
// Strip the second component of last_update
d['last_update'] = d['last_update'].replace(/(\d\d:\d\d):\d\d/, '$1');
mirrors.push(d);
}
var result = Mark.up(mir_tmpl, {mirrors: mirrors});
$('#mirror-list').html(result);
});
setTimeout(refreshMirrorList, 10000);
}
refreshMirrorList();
return `/${mir.name}/`
},
refreshMirrorList () {
var self = this;
$.getJSON("/static/tunasync.json", (status_data) => {
var mirrors = [], mir_data = $.merge(status_data, unlisted);
var mir_uniq = {}; // for deduplication
$.getJSON("/static/tunet.json", (to_alert) => {
if (to_alert) {
$('#thu-alert').removeClass('hidden');
};
mir_data.sort((a, b) => { return a.name < b.name ? -1: 1 });
for(var k in mir_data) {
var d = mir_data[k];
if (d.status == "disabled") {
continue;
}
if (options[d.name] != undefined ) {
d = $.extend(d, options[d.name]);
}
d.label = label_map[d.status];
d.help_url = help_url[d.name];
d.is_new = new_mirrors[d.name];
d.description = descriptions[d.name];
d.show_status = (d.status != "success");
if (d.is_master === undefined) {
d.is_master = true;
}
// Strip the second component of last_update
if (d.last_update_ts) {
let date = new Date(d.last_update_ts * 1000);
if (date.getFullYear() > 2000) {
d.last_update = `${('000'+date.getFullYear()).substr(-4)}-${('0'+(date.getMonth()+1)).substr(-2)}-${('0'+date.getDate()).substr(-2)}` +
` ${('0'+date.getHours()).substr(-2)}:${('0'+date.getMinutes()).substr(-2)}`;
} else {
d.last_update = "0000-00-00 00:00";
}
} else {
d.last_update = d.last_update.replace(/(\d\d:\d\d):\d\d(\s\+\d\d\d\d)?/, '$1');
}
if (d.name in mir_uniq) {
let other = mir_uniq[d.name];
if (other.last_update > d.last_update) {
continue;
}
}
mir_uniq[d.name] = d;
}
for (k in mir_uniq) {
mirrors.push(mir_uniq[k]);
}
self.mirrorList = mirrors;
setTimeout(() => {self.refreshMirrorList()}, 10000);
});
}
}
})
var vmIso = new Vue({
el: "#isoModal",
data: {
distroList: [],
selected: {},
curCategory: "os"
},
created: function () {
var self = this;
$.getJSON("/static/isoinfo.json", function (isoinfo) {
self.distroList = isoinfo;
self.selected = self.curDistroList[0];
if (window.location.hash.match(/#iso-download(\?.*)?/)) {
$('#isoModal').modal();
}
});
},
computed: {
curDistroList () {
return this.distroList
.filter((x)=> x.category === this.curCategory);
}
},
methods: {
switchDistro (distro) {
this.selected = distro;
},
switchCategory (category) {
this.curCategory = category;
this.selected = this.curDistroList[0];
}
}
});
});

45
static/js/status.es6 Normal file
View File

@ -0,0 +1,45 @@
---
---
$(document).ready(() => {
var mir_tmpl = $("#template").text();
$.get("/static/status/disk.json", (d) => {
var used_percent = Math.round(d.used_kb * 100 / d.total_kb);
$('#disk-usage-bar')
.attr("aria-valuenow", used_percent)
.css("width", used_percent + "%")
.html("<strong>" + d.used_readable + " / " + d.total_readable + "</strong>");
});
window.refreshMirrorList = () => {
$.getJSON("/static/tunasync.json", (status_data) => {
var mirrors=[], mir_data=status_data;
mir_data.sort((a, b) => { return a.name < b.name ? -1: 1 });
for(var k in mir_data) {
var d = mir_data[k];
if (d.is_master === undefined) {
d.is_master = true;
}
// Strip the second component of last_update
if (d.last_update_ts) {
let date = new Date(d.last_update_ts * 1000);
if (date.getFullYear() > 2000) {
d.last_update = `${('000'+date.getFullYear()).substr(-4)}-${('0'+(date.getMonth()+1)).substr(-2)}-${('0'+date.getDate()).substr(-2)}` +
` ${('0'+date.getHours()).substr(-2)}:${('0'+date.getMinutes()).substr(-2)}`;
} else {
d.last_update = "0000-00-00 00:00";
}
} else {
d.last_update = d.last_update.replace(/(\d\d:\d\d):\d\d(\s\+\d\d\d\d)?/, '$1');
}
mirrors.push(d);
}
var result = Mark.up(mir_tmpl, {mirrors: mirrors});
$('#mirror-list').html(result);
});
setTimeout(refreshMirrorList, 10000);
};
refreshMirrorList();
});

8
static/js/vue.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ permalink: /status/
<div id="status-page">
<div class="spacing hidden-xs"></div>
<div class="container">
<h3> # 服务器监控 </h3>
<h3 id="server-status"> # 服务器监控 </h3>
<h4> # 网络流量 </h4>
<div class="row">
<div class="col-md-6">
@ -56,20 +56,37 @@ permalink: /status/
</div>
</div>
</div>
<h3 id="syncing-status"># 同步状态</h3>
<div>
<div class="thead row">
<div>
<div class="col-md-2">Name</div>
<div class="col-md-2">Last Update</div>
<div class="col-md-5">Upstream</div>
<div class="col-md-1">Status</div>
<div class="col-md-2">Size</div>
</div>
</div>
<div id="mirror-list">
</div>
</div>
</div><!--/container -->
</div><!--/status -->
{% include footer.html %}
<script>
$(document).ready(function(){
$.get("/static/status/disk.json", function(d){
var used_percent = Math.round(d.used_kb * 100 / d.total_kb);
$('#disk-usage-bar')
.attr("aria-valuenow", used_percent)
.css("width", used_percent + "%")
.html("<strong>" + d.used_readable + " / " + d.total_readable + "</strong>");
});
});
{% raw %}
<script id="template" type="x-tmpl-markup">
{{mirrors}}
<div class="status-{{status}} row">
<div class="col-md-2">{{name}}{{if is_master|falsy}}[slave]{{/if}}</div>
<div class="col-md-2">{{last_update}}</div>
<div class="col-md-5">{{upstream}}</div>
<div class="col-md-1">{{status}}</div>
<div class="col-md-2">{{size}}</div>
</div>
{{/mirrors}}
</script>
{% endraw %}
<script src="/static/js/status.js"></script>
</body>
</html>
<!--