├── .github └── workflows │ ├── main.yml │ └── update_status.yml ├── README.md ├── new └── README.md ├── proxies.txt ├── verify-url.py └── whitelist.json /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Sync README to docusaurus-yuanshen Repo 2 | 3 | on: 4 | workflow_call: 5 | secrets: 6 | API_TOKEN_GITHUB: 7 | required: true 8 | workflow_dispatch: 9 | 10 | jobs: 11 | sync: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout source repo 15 | uses: actions/checkout@v4 16 | with: 17 | ref: 'main' 18 | 19 | - name: Push README to docusaurus-yuanshen repo 20 | env: 21 | API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }} # 设置一个secret 22 | if: ${{ github.repository == 'cokice/List-of-genshin-University' && github.ref == 'refs/heads/main' }} 23 | run: | 24 | git config --global user.name 'howen' 25 | git config --global user.email 'howen.huang@qq.com' 26 | 27 | # Clone the destination repo 28 | git clone https://x-access-token:$API_TOKEN_GITHUB@github.com/cokice/docusaurus-yuanshen.git 29 | 30 | cd docusaurus-yuanshen 31 | git checkout main # 切换到main分支 32 | git pull origin main # 拉取最新的更改 33 | cp ../README.md docs/README.md # Copy the updated README 34 | git add docs/README.md 35 | git commit --allow-empty -m "Update README from List-of-genshin-University" 36 | git push origin main 37 | -------------------------------------------------------------------------------- /.github/workflows/update_status.yml: -------------------------------------------------------------------------------- 1 | name: Update Status 2 | run-name: Update Status 3 | 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | no_skip_edu: 8 | description: 'Do not skip edu domains' 9 | required: true 10 | type: 'boolean' 11 | default: false 12 | count_only: 13 | description: 'Only count the number of domains, do not verify' 14 | required: true 15 | type: 'boolean' 16 | default: false 17 | schedule: 18 | - cron: '30 3/4 * * *' 19 | push: 20 | branches: 21 | - main 22 | paths: 23 | - 'README.md' 24 | - '.github/workflows/update_status.yml' 25 | - 'verify-url.py' 26 | - 'new/**' 27 | - 'whitelist.json' 28 | 29 | permissions: 30 | contents: write 31 | 32 | concurrency: 33 | group: ${{ github.workflow }} 34 | cancel-in-progress: true 35 | 36 | jobs: 37 | update_status: 38 | name: Update Status 39 | runs-on: ubuntu-latest 40 | if: ${{ github.repository == 'cokice/List-of-genshin-University' }} 41 | steps: 42 | - name: Checkout repository 43 | uses: actions/checkout@v4 44 | with: 45 | fetch-depth: 0 46 | 47 | - name: Set up Python 48 | uses: actions/setup-python@v5 49 | with: 50 | python-version: '3.11' 51 | 52 | - name: Install dependencies 53 | run: | 54 | python -m pip install --upgrade pip 55 | pip install dnspython requests pypinyin 56 | 57 | - name: Prepare Proxy 58 | run: | 59 | echo -e "${{ secrets.PROXY }}" >> proxies.txt 60 | 61 | - name: Update status 62 | run: python3 verify-url.py 63 | id: update_status 64 | env: 65 | NO_SKIP_EDU: ${{ github.event.inputs.no_skip_edu == true && '1' || '0' }} 66 | COUNT_ONLY: ${{ github.event.inputs.count_only == true && '1' || '0' }} 67 | 68 | - name: Revert Proxy 69 | run: | 70 | git checkout proxies.txt 71 | 72 | - name: Commit and push 73 | uses: actions4git/add-commit-push@v1 74 | with: 75 | commit-message: ${{ steps.update_status.outputs.commit_message }} 76 | continue-on-error: true 77 | 78 | push_to_website: 79 | name: Push to website 80 | uses: ./.github/workflows/main.yml 81 | needs: update_status 82 | if: ${{ github.repository == 'cokice/List-of-genshin-University' }} 83 | secrets: 84 | API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }} 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 原神高校联盟 2 | 3 | 4 | 欢迎来到原神高校联盟项目!这个项目旨在收集和整理全国各地的原神相关高校名单(目前有257个高校)(其中89个有效),提供一个校园集聚地。 5 | 6 | 非高校也可添加哟~ 7 | 8 | 喜欢本项目的话可以在[GitHub](https://github.com/cokice/List-of-genshin-University)内点个star。 9 | **该名单由学校名称字母顺序排列** 10 | 11 | ## 如何提交 12 | :::caution 13 | **一定要在云厂商购买域名后配置相应的解析和跳转才能挂到此站点,且要经过测试能在浏览器正常访问该域名,否则无法上架到此站点** 14 | ::: 15 | 1. **进入项目**: 点击右上角[GitHub](https://github.com/cokice/List-of-genshin-University) 16 | 2. **Fork 这个仓库**: 在页面右上角找到并点击 "Fork" 按钮,将这个项目复制到你的GitHub账户下。 17 | 3. **克隆仓库**: 克隆你刚刚fork的仓库到你的本地计算机上。 18 | 4. **创建新的分支**: 基于你要做的修改创建一个新的分支。 19 | 5. **添加域名**: 在你的分支里的new文件夹里,按照其中README的指示添加你的域名。 20 | 6. **发起 Pull Request**: 在GitHub上发起一个Pull Request请求,将你的修改合并进原仓库。在发起Pull Request之前,请确保你的修改是准确无误的,并且已经过了测试。 21 | 7. **不会github操作的小伙伴直接填写问卷提交信息[原神高校信息收集](https://wj.qq.com/s2/14161038/95a1/)要确保你已经注册了域名并实现跳转** 22 | 8. **其他问题:邮箱howen.huang@qq.com** 23 | 24 | **格式要求:你的学校名字+你设置好的域名 同时确保你的链接经过他人点击测试可以访问的** 25 | 26 | **例: 哈佛大学 www.原神大学.com** 27 | 28 | 29 | ## 高校名单(2025-06-03 23:46 UTC+8) 30 | 31 | 32 | 状态说明: 33 | - :white_check_mark: 经服务器验证可成功访问、跳转,并显示跳转方式。 34 | - :question: 经服务器验证域名可访问但是不能成功跳转,并显示错误原因。此状态视为域名有效。 35 | - :warning: 表格中的链接直接指向对应高校而不是经过域名跳转。此状态视为域名无效。 36 | - :x: 服务器无法访问对应地址,并显示错误原因。此处为站长提供常见原因及解决方案: 37 | - `NXDOMAIN` 域名不可解析(请注册域名并设置完解析再来吧!) 38 | - `Connection error` 服务器不可访问。这种情况可能由于检测服务器导致,并不一定说明服务器无效。(可以尝试换一个服务器) 39 | - `(数字)` HTTP状态码无效(请检查服务器设置) 40 | 41 | 由于网络波动,状态仅供参考。如果使用了CloudFlare服务商作为中间代理,此处可能也会显示不可访问。 42 | 43 | | 网站 | 大学 | 状态 | 44 | | --- | --- | --- | 45 | | [universityofgenshin.com](https://universityofgenshin.com) | University of Melbourne | :x: Connection error | 46 | | [澳洲原神大学.com](https://澳洲原神大学.com) | University of Melbourne | :x: NXDOMAIN | 47 | | [加拿大原神大专.com](https://加拿大原神大专.com) | University of Ottawa | :white_check_mark: Redirect 307 | 48 | | [ugensh.in](https://ugensh.in) | University of Sydney | :x: NXDOMAIN | 49 | | [安徽原神大学.icu](https://安徽原神大学.icu) | 安徽大学 | :white_check_mark: | 50 | | [澳门原神大学.cn](http://澳门原神大学.cn) | 澳门城市大学 | :x: NXDOMAIN | 51 | | [原神科技大学.com](https://原神科技大学.com) | 澳门科技大学 | :white_check_mark: Redirect 301 | 52 | | [澳门原神大学.com](http://澳门原神大学.com) | 澳门理工大学 | :x: NXDOMAIN | 53 | | [北方原神大学.top](https://北方原神大学.top) | 北方工业大学 | :x: NXDOMAIN | 54 | | [pku.原神.org](http://pku.原神.org) | 北京大学 | :white_check_mark: Redirect 301 | 55 | | [暂时不能给你明确的答复.com](http://暂时不能给你明确的答复.com) | 北京大学信息科学技术学院 | :x: Connection error | 56 | | [原神风之翼技术大学.fontlos.com](https://原神风之翼技术大学.fontlos.com) | 北京航空航天大学 | :white_check_mark: Redirect 301 | 57 | | [北京原神大学.cn](http://www.北京原神大学.cn) | 北京化工大学 | :white_check_mark: Redirect 301 | 58 | | [北京原神大学.com](http://www.北京原神大学.com) | 北京交通大学 | :x: NXDOMAIN | 59 | | [北京原神大学.net](https://北京原神大学.net) | 北京交通大学 | :white_check_mark: Redirect 302 | 60 | | [北京原神大专.com](https://www.北京原神大专.com) | 北京理工大学 | :x: NXDOMAIN | 61 | | [原神师范大学.com](http://www.原神师范大学.com) | 北京师范大学 | :x: NXDOMAIN | 62 | | [提瓦特高等师范学院.com](http://提瓦特高等师范学院.com) | 北京师范大学 | :x: NXDOMAIN | 63 | | [广东原神学院.com](https://广东原神学院.com) | 北京师范大学-香港浸会大学联合国际学院 | :white_check_mark: CNAME | 64 | | [提瓦特初等师范学院.xyz](http://www.提瓦特初等师范学院.xyz) | 北京师范学院 | :x: Connection error | 65 | | [北京原神第八中学.com](http://www.北京原神第八中学.com) | 北京市第八中学 | :x: NXDOMAIN | 66 | | [中关村原神中学.com](http://中关村原神中学.com) | 北京市中关村中学 | :x: NXDOMAIN | 67 | | [中国原神学院.com](http://www.中国原神学院.com) | 北京信息科技大学 | :white_check_mark: | 68 | | [提瓦特超自然现象研究院.tech](http://提瓦特超自然现象研究院.tech) | 北京邮电大学 | :x: NXDOMAIN | 69 | | [长春原神大学.com](http://www.长春原神大学.com) | 长春理工大学 | :white_check_mark: Redirect 301 | 70 | | [玩原神不如玩.csu.st](http://玩原神不如玩.csu.st/) | 长沙理工大学 | :x: Connection error | 71 | | [s.csu.st/玩原神导致的](https://s.csu.st/%E7%8E%A9%E5%8E%9F%E7%A5%9E%E5%AF%BC%E8%87%B4%E7%9A%84) | 长沙理工大学 | :white_check_mark: CNAME | 72 | | [苏州原神学院.com](http://www.苏州原神学院.com) | 常熟理工学院 | :x: NXDOMAIN | 73 | | [常州原神大学.com](http://www.常州原神大学.com) | 常州大学 | :x: NXDOMAIN | 74 | | [湖南原神大专.top](http://湖南原神大专.top) | 郴州职业技术学院 | :x: NXDOMAIN | 75 | | [重庆原神大学.online](https://重庆原神大学.online) | 重庆航天职业技术学院 | :x: NXDOMAIN | 76 | | [原神学校.com](http://原神学校.com) | 重庆市第八中学 | :x: NXDOMAIN | 77 | | [原神第一中学.xyz](http://www.原神第一中学.xyz) | 重庆市第一中学校 | :white_check_mark: | 78 | | [www.cqyuanshenjgxx.nyaneko.uk](https://www.cqyuanshenjgxx.nyaneko.uk/.com) | 重庆市风景园林技工学校 | :x: NXDOMAIN | 79 | | [重庆原神技工学校.top](https://www.重庆原神技工学校.top) | 重庆市风景园林技工学校 | :white_check_mark: Redirect 301 | 80 | | [不玩原神.fun](https://www.不玩原神.fun) | 重庆水利水电职业技术学院 | :x: NXDOMAIN | 81 | | [cqupt.原友聚集地.top](http://cqupt.原友聚集地.top) | 重庆邮电大学 | :white_check_mark: Redirect 308 | 82 | | [op.wiki](https://www.op.wiki) | 重庆邮电大学 | :white_check_mark: Redirect 301 | 83 | | [大连理工大学原神学院.cn](http://大连理工大学原神学院.cn) | 大连理工大学城市学院 | :x: NXDOMAIN | 84 | | [民族原神大学.cn](http://www.民族原神大学.cn) | 大连民族大学 | :x: NXDOMAIN | 85 | | [电子原神大学.com](http://www.电子原神大学.com) | 电子科技大学 | :white_check_mark: Redirect 302 | 86 | | [原神财经大学.com](https://原神财经大学.com) | 东北财经大学 | :x: NXDOMAIN | 87 | | [原神分校.com](http://原神分校.com) | 东北大学秦皇岛分校 | :x: NXDOMAIN | 88 | | [提瓦特林业大学.site](https://提瓦特林业大学.site) | 东北林业大学 | :white_check_mark: | 89 | | [原神农业大学.honkai.top](http://原神农业大学.honkai.top) | 东北农业大学 | :x: NXDOMAIN | 90 | | [广东原神大学.com](http://www.广东原神大学.com) | 东莞理工学院 | :white_check_mark: Redirect 301 | 91 | | [原神启动大学.top](http://www.原神启动大学.top) | 东华理工大学 | :x: NXDOMAIN | 92 | | [原神启动大学.com](https://原神启动大学.com/) | 东南大学 | :white_check_mark: Redirect 301 | 93 | | [美国原神学院.com](http://美国原神学院.com) | 俄亥俄州立大学 | :white_check_mark: Redirect 301 | 94 | | [seniorhigh.提瓦特超自然现象研究院.tech](http://www.seniorhigh.提瓦特超自然现象研究院.tech) | 福州第十中学 | :x: NXDOMAIN | 95 | | [兰州原神中学.lolicon.xin](http://兰州原神中学.lolicon.xin) | 甘肃省兰州第一中学 | :white_check_mark: Redirect 301 | 96 | | [www.gslzyz.cn](https://www.gslzyz.cn) | 甘肃省兰州第一中学 | :white_check_mark: | 97 | | [原神大专.com](http://www.原神大专.com) | 广东财贸职业学院 | :white_check_mark: Redirect 302 | 98 | | [广州原神大学.com](http://www.广州原神大学.com) | 广东技术师范大学 | :x: NXDOMAIN | 99 | | [清远原神大学.top](http://www.清远原神大学.top) | 广东科贸职业学院 | :x: NXDOMAIN | 100 | | [广轻原神大学.com](http://www.广轻原神大学.com) | 广东轻工职业技术学院 | :x: NXDOMAIN | 101 | | [原神.org](https://www.原神.org) | 广东药科大学 | :white_check_mark: Redirect 302 | 102 | | [广西原神大学.cn](http://广西原神大学.cn) | 广西安全工程职业技术学院 | :x: NXDOMAIN | 103 | | [世界原神大学.com](http://www.世界原神大学.com) | 广西大学 | :white_check_mark: Redirect 301 | 104 | | [广西原神职业技术学院.com](https://www.广西原神职业技术学院.com/) | 广西民族大学相思湖学院 | :x: NXDOMAIN | 105 | | [米哈游师范大学.com](https://米哈游师范大学.com) | 广西师范大学 | :x: NXDOMAIN | 106 | | [原神医科大学.com](http://www.原神医科大学.com) | 广西医科大学 | :x: NXDOMAIN | 107 | | [广州原神大学.icu](https://广州原神大学.icu) | 广州南洋理工职业学院 | :x: NXDOMAIN | 108 | | [原神启动.space](https://www.原神启动.space) | 广州商学院 | :x: NXDOMAIN | 109 | | [原神理工大学.icu](http://www.原神理工大学.icu) | 桂林理工大学南宁分校 | :x: NXDOMAIN | 110 | | [黑龙江原神大学.com](http://www.黑龙江原神大学.com) | 哈尔滨工程大学 | :x: NXDOMAIN | 111 | | [哈尔滨原神大学.com](http://哈尔滨原神大学.com) | 哈尔滨工程大学 | :white_check_mark: Redirect 308 | 112 | | [提瓦特工业大学.com](http://提瓦特工业大学.com) | 哈尔滨工业大学 | :white_check_mark: Redirect 301 | 113 | | [提瓦特大专.com](http://www.提瓦特大专.com) | 哈尔滨商业大学 | :x: NXDOMAIN | 114 | | [玩原神玩傻了.top](http://玩原神玩傻了.top) | 海口实验中学 | :x: NXDOMAIN | 115 | | [原神医科大学.cn](http://www.原神医科大学.cn) | 海南医科大学 | :white_check_mark: CNAME | 116 | | [原神高级中学.org](https://www.原神高级中学.org) | 杭州高级中学 | :x: NXDOMAIN | 117 | | [河北原神大学.com](https://河北原神大学.com) | 河北科技大学 | :x: NXDOMAIN | 118 | | [原神科技学院.lol](https://www.原神科技学院.lol) | 河北农业大学现代科技学院 | :white_check_mark: Redirect 301 | 119 | | [河北原神大专.com](https://河北原神大专.com) | 河北师范大学 | :x: NXDOMAIN | 120 | | [中国原神中学.com](http://中国原神中学.com) | 合肥八中 | :x: Connection error | 121 | | [合肥原神大学.com](http://www.合肥原神大学.com) | 合肥学院 | :x: NXDOMAIN | 122 | | [河南原神大学.net](http://河南原神大学.net) | 河南大学 | :white_check_mark: CNAME | 123 | | [开封原神师专.fun](https://www.开封原神师专.fun) | 河南大学 | :x: NXDOMAIN | 124 | | [湖北原神大学.xyz](http://湖北原神大学.xyz) | 湖北大学 | :x: NXDOMAIN | 125 | | [湖北原神大学.xyz](http://湖北原神大学.xyz/原神联合学院) | 湖北大学曼城联合学院 | :x: NXDOMAIN | 126 | | [原神民族大学.com](http://www.原神民族大学.com) | 湖北民族大学 | :x: NXDOMAIN | 127 | | [原神汽砖.fun](http://www.原神汽砖.fun) | 湖北汽车工业学院 | :x: NXDOMAIN | 128 | | [原神带专.com](https://原神带专.com) | 湖北水利水电职业技术学院 | :x: NXDOMAIN | 129 | | [我要玩原神.com](http://www.我要玩原神.com) | 湖北中医药大学 | :x: NXDOMAIN | 130 | | [湖南原神大学.cn](http://湖南原神大学.cn) | 湖南理工学院 | :x: NXDOMAIN | 131 | | [原来你也玩原神.com](https://www.原来你也玩原神.com) | 华北科技学院 | :x: NXDOMAIN | 132 | | [华东原神大学.online](http://华东原神大学.online) | 华东师范大学 | :x: NXDOMAIN | 133 | | [上海原神大学.com](http://上海原神大学.com) | 华东师范大学 | :white_check_mark: Redirect 301 | 134 | | [原神蒸发大学.com](http://www.原神蒸发大学.com) | 华东政法大学 | :x: NXDOMAIN | 135 | | [华南原神大学.com](http://www.华南原神大学.com) | 华南理工大学 | :white_check_mark: Redirect 301 | 136 | | [华中原神大学.com](https://华中原神大学.com/) | 华中科技大学 | :white_check_mark: Redirect 308 | 137 | | [华中原神大学.cn](http://www.华中原神大学.cn/) | 华中师范大学 | :x: NXDOMAIN | 138 | | [中国原神大专.top](http://中国原神大专.top) | 淮阴师范学院 | :x: NXDOMAIN | 139 | | [原神学院.com](http://www.原神学院.com) | 黄淮学院 | :white_check_mark: Redirect 301 | 140 | | [东北原神大学.com](http://www.东北原神大学.com) | 吉林大学 | :x: NXDOMAIN | 141 | | [吉林大学.com](https://www.吉林大学.com) | 吉林大学 | :white_check_mark: Redirect 302 | 142 | | [广东原神公益大学.com](http://www.广东原神公益大学.com) | 暨南大学 | :x: NXDOMAIN | 143 | | [加州原神工业大学.club](https://加州原神工业大学.club) | 加州大学伯克利分校 | :x: NXDOMAIN | 144 | | [加利福尼亚原神大学.com](http://www.加利福尼亚原神大学.com) | 加州大学圣克鲁兹分校 | :x: NXDOMAIN | 145 | | [加州原神大学.com](http://加州原神大学.com) | 加州大学圣塔芭芭拉分校 | :white_check_mark: Redirect 301 | 146 | | [江苏原神大学.com](http://www.江苏原神大学.com) | 江苏大学 | :x: NXDOMAIN | 147 | | [江苏省响水中学.02.gold](http://江苏省响水中学.02.gold) | 江苏省响水中学 | :x: NXDOMAIN | 148 | | [云响中.02.gold](http://云响中.02.gold) | 江苏省响水中学 | :x: NXDOMAIN | 149 | | [江西原神大学.com](http://www.江西原神大学.com) | 江西财经大学 | :x: NXDOMAIN | 150 | | [江西原神大专.com](http://www.江西原神大专.com) | 江西理工大学 | :x: NXDOMAIN | 151 | | [原神中医药大学.fun](https://原神中医药大学.fun) | 江西中医药大学 | :x: NXDOMAIN | 152 | | [胶州市最爱玩原神的中学](https://www.胶州市最爱玩原神的中学.com) | 胶州市阜安中学 | :x: NXDOMAIN | 153 | | [金陵原神学院.com](https://金陵原神学院.com) | 金陵科技学院 | :white_check_mark: Redirect 301 | 154 | | [景德镇原神大学.com](http://www.景德镇原神大学.com) | 景德镇学院 | :x: NXDOMAIN | 155 | | [江西原神带砖.top](http://www.江西原神带砖.top/) | 井冈山大学 | :x: NXDOMAIN | 156 | | [北京原神学校.com](https://北京原神学校.com) | 景山学校远洋分校 | :x: NXDOMAIN | 157 | | [澳大利亚原神大学.com](http://www.澳大利亚原神大学.com) | 昆士兰大学 | :x: NXDOMAIN | 158 | | [原神怎么你了.top](http://原神怎么你了.top) | 兰州大学 | :x: NXDOMAIN | 159 | | [原神アジア太平洋大学.jp](http://原神アジア太平洋大学.jp) | 立命館アジア太平洋大学 | :x: NXDOMAIN | 160 | | [原神工程技术大学.com](https://www.原神工程技术大学.com) | 辽宁工程技术大学 | :x: NXDOMAIN | 161 | | [玩绝区零玩的.com](http://玩绝区零玩的.com) | 辽宁科技大学 | :white_check_mark: Redirect 301 | 162 | | [中国原神.com](http://中国原神.com) | 辽宁科技大学 | :white_check_mark: Meta Refresh | 163 | | [璃月石化大学.icu](http://www.璃月石化大学.icu) | 辽宁石油化工大学 | :x: NXDOMAIN | 164 | | [辽宁原神大学.icu](http://www.辽宁原神大学.icu) | 辽宁石油化工大学 | :x: NXDOMAIN | 165 | | [提瓦特现代原神学院.cn](http://提瓦特现代原神学院.cn) | 辽宁现代服务职业学院 | :white_check_mark: Redirect 301 | 166 | | [伦敦原神大学.com](http://伦敦原神大学.com) | 伦敦帝国理工学院 | :white_check_mark: Redirect 301 | 167 | | [罗定原神中学.top](http://罗定原神中学.top) | 罗定实验中学 | :x: NXDOMAIN | 168 | | [洛阳崩坏师范大学.com](https://www.洛阳崩坏师范大学.com) | 洛阳师范学院 | :x: NXDOMAIN | 169 | | [洛阳原神大学.com](http://www.洛阳原神大学.com) | 洛阳职业技术学院 | :x: NXDOMAIN | 170 | | [原神理工学院.com](https://www.原神理工学院.com) | 麻省理工学院 | :x: NXDOMAIN | 171 | | [崩坏星穹铁道.com](https://崩坏星穹铁道.com) | 南昌大学 | :white_check_mark: Redirect 301 | 172 | | [阿卡林原神大学.top](http://www.阿卡林原神大学.top) | 南昌航空大学 | :x: NXDOMAIN | 173 | | [南京原神大学.com](http://www.南京原神大学.com) | 南京大学 | :white_check_mark: Redirect 301 | 174 | | [南京浦口原神中专.xyz](http://www.南京浦口原神中专.xyz) | 南京工业大学 | :x: NXDOMAIN | 175 | | [玄武区原神大学.xyz](http://玄武区原神大学.xyz) | 南京林业大学 | :x: NXDOMAIN | 176 | | [南京原神大学.vip](http://www.南京原神大学.vip) | 南京农业大学 | :x: NXDOMAIN | 177 | | [原神师范大学.live](http://www.原神师范大学.live) | 南京师范大学 | :x: NXDOMAIN | 178 | | [南京星穹铁道职业技术学院.xyz](http://南京星穹铁道职业技术学院.xyz) | 南京铁道职业技术学院 | :x: NXDOMAIN | 179 | | [原神师范学院.top](http://原神师范学院.top) | 南京晓庄学院 | :x: NXDOMAIN | 180 | | [原神工程大学.com](http://www.原神工程大学.com) | 南京信息工程大学 | :x: NXDOMAIN | 181 | | [南京原神工程大学.fun](http://南京原神工程大学.fun) | 南京信息工程大学 | :x: NXDOMAIN | 182 | | [南京原神大学.cn](http://南京原神大学.cn) | 南京邮电大学 | :x: NXDOMAIN | 183 | | [原神启动.club](http://www.原神启动.club) | 南开大学 | :x: NXDOMAIN | 184 | | [nku.天津原神大学.icu](https://nku.天津原神大学.icu) | 南开大学 | :x: NXDOMAIN | 185 | | [genshin.university](http://www.genshin.university) | 南通大学 | :x: NXDOMAIN | 186 | | [原神农业大学.com](http://原神农业大学.com/) | 内蒙古农业大学 | :white_check_mark: CNAME | 187 | | [诺丁汉原神大学.xyz](https://诺丁汉原神大学.xyz) | 宁波诺丁汉大学 | :white_check_mark: Redirect 301 | 188 | | [美国原神大学.com](http://美国原神大学.com) | 纽约大学 | :white_check_mark: Redirect 301 | 189 | | [提瓦特中学.top](http://提瓦特中学.top) | 平遥中学 | :x: NXDOMAIN | 190 | | [countygenshinschool.111111.eu.org](https://countygenshinschool.111111.eu.org) | 前郭尔罗斯蒙古族自治县第三中学 | :white_check_mark: Redirect 308 | 191 | | [青岛城市学院原神.club](https://www.青岛城市学院原神.club) | 青岛城市学院 | :white_check_mark: Redirect 301 | 192 | | [提瓦特第五十八中学.click](http://提瓦特第五十八中学.click) | 青岛第五十八中学 | :question: Connection error | 193 | | [青岛原神大学.com](http://青岛原神大学.com) | 青岛科技大学 | :x: NXDOMAIN | 194 | | [tsinghua.原神.org](https://tsinghua.原神.org) | 清华大学 | :white_check_mark: Redirect 302 | 195 | | [原神启动中学.cn](http://原神启动中学.cn) | 人大附中ICC | :x: NXDOMAIN | 196 | | [提瓦特大学.com](http://www.提瓦特大学.com) | 山东大学 | :x: NXDOMAIN | 197 | | [国立原神大学.com](http://国立原神大学.com) | 山东大学 | :white_check_mark: Redirect 301 | 198 | | [genshin.school](https://genshin.school/) | 山东大学 | :white_check_mark: Redirect 302 | 199 | | [原神医科大学.top](http://原神医科大学.top) | 山东第一医科大学 | :x: NXDOMAIN | 200 | | [原神启动.store](http://原神启动.store) | 汕头大学 | :x: NXDOMAIN | 201 | | [汕头原神学院.com](https://汕头原神学院.com) | 汕头职业技术学院 | :x: NXDOMAIN | 202 | | [上海原神大学.top](http://上海原神大学.top) | 上海大学 | :x: NXDOMAIN | 203 | | [上海第二原神大学.top](http://www.上海第二原神大学.top) | 上海第二工业大学 | :white_check_mark: Redirect 302 | 204 | | [原神电力大学.com](http://www.原神电力大学.com) | 上海电力大学 | :x: NXDOMAIN | 205 | | [上海原神大学.net](http://上海原神大学.net) | 上海海事大学 | :x: NXDOMAIN | 206 | | [上海op大学.com](https://www.上海op大学.com) | 上海海洋大学 | :white_check_mark: Redirect 302 | 207 | | [上海原批大学.com](http://www.上海原批大学.com) | 上海建桥学院 | :x: NXDOMAIN | 208 | | [上海原神大学.cn](http://上海原神大学.cn) | 上海交通大学 | :white_check_mark: Redirect 301 | 209 | | [上海原神大学附属中学.top](https://上海原神大学附属中学.top) | 上海交通大学附属中学 | :white_check_mark: Redirect 301 | 210 | | [上海原神学院.net](http://上海原神学院.net) | 上海立达学院 | :x: NXDOMAIN | 211 | | [原神.ltd](http://原神.ltd) | 上海立达学院 | :x: NXDOMAIN | 212 | | [上海市原神中学.xyz](http://www.上海市原神中学.xyz) | 上海市控江中学 | :x: NXDOMAIN | 213 | | [深圳原神大学.com](http://深圳原神大学.com) | 深圳大学 | :x: NXDOMAIN | 214 | | [原神高级中学.lol](https://原神高级中学.lol) | 深圳市高级中学 | :white_check_mark: Redirect 301 | 215 | | [深圳原神高级中学.fun](http://深圳原神高级中学.fun) | 深圳盐田高级中学 | :x: NXDOMAIN | 216 | | [匹诺康尼工业大学.com](https://www.匹诺康尼工业大学.com) | 沈阳工业大学 | :white_check_mark: Redirect 301 | 217 | | [沈阳原神大学.com](http://www.沈阳原神大学.com) | 沈阳理工大学 | :white_check_mark: Redirect 301 | 218 | | [原神民族学院.com](http://www.原神民族学院.cn) | 四川民族学院 | :x: NXDOMAIN | 219 | | [原神民族学院.cn](http://www.原神民族学院.cn/) | 四川民族学院 | :x: NXDOMAIN | 220 | | [原神农业大学.cn](https://www.原神农业大学.cn) | 四川农业大学 | :white_check_mark: | 221 | | [苏州原神大学.cn](https://苏州原神大学.cn) | 苏州城市学院 | :x: NXDOMAIN | 222 | | [苏州原神大学.top](http://苏州原神大学.top) | 苏州大学 | :x: NXDOMAIN | 223 | | [中国原神大学.com](https://www.中国原神大学.com) | 苏州工艺美术职业技术学院 | :white_check_mark: Redirect 301 | 224 | | [usts.原友聚集地.top](http://usts.原友聚集地.top) | 苏州科技大学 | :white_check_mark: Meta Refresh | 225 | | [世界原神中学.com](https://世界原神中学.com/) | 苏州中学 | :white_check_mark: Redirect 301 | 226 | | [浙江原神职业技术学院.com](https://浙江原神职业技术学院.com) | 随机跳转至部分浙江省内高职院校官网 | :x: NXDOMAIN | 227 | | [西北原神大学.com](http://www.西北原神大学.com) | 塔里木大学 | :white_check_mark: | 228 | | [原神科技大专.com](http://www.原神科技大专.com) | 太原科技大学 | :x: NXDOMAIN | 229 | | [原神理工大学.com](http://原神理工大学.com) | 太原理工大学 | :x: NXDOMAIN | 230 | | [tju.天津原神大学.icu](https://tju.天津原神大学.icu) | 天津大学 | :x: NXDOMAIN | 231 | | [天津原神大学.top](https://天津原神大学.top) | 天津理工大学 | :white_check_mark: Redirect 301 | 232 | | [原神商学院.top](http://原神商学院.top) | 天津商业大学 | :x: 404 | 233 | | [原神师范大学.online](http://www.原神师范大学.online) | 天津师范大学 | :x: NXDOMAIN | 234 | | [玩原神考上的.cn](https://玩原神考上的.cn) | 天津医科大学临床医学院 | :x: NXDOMAIN | 235 | | [威海原神大学.cn](http://www.威海原神大学.cn) | 威海海洋职业学院 | :white_check_mark: Redirect 302 | 236 | | [无锡原神职业技术学院.xyz](http://无锡原神职业技术学院.xyz) | 无锡商业职业技术学院 | :x: NXDOMAIN | 237 | | [武汉原神大学.com](https://www.武汉原神大学.com) | 武汉纺织大学 | :x: NXDOMAIN | 238 | | [武汉原神大专.com](http://www.武汉原神大专.com) | 武汉工程大学 | :white_check_mark: Redirect 302 | 239 | | [武汉原神大学.site](http://武汉原神大学.site) | 武汉工程大学 | :x: NXDOMAIN | 240 | | [武汉原神大学.org](http://www.武汉原神大学.org) | 武汉科技大学 | :x: NXDOMAIN | 241 | | [武汉原神大学.fun](http://www.武汉原神大学.fun) | 武汉理工大学 | :x: NXDOMAIN | 242 | | [江门原神大学.com](http://www.江门原神大学.com) | 五邑大学 | :x: NXDOMAIN | 243 | | [原神职业技术学院.com](http://www.原神职业技术学院.com) | 五邑大学 | :white_check_mark: Redirect 308 | 244 | | [西安电子科技大学.com](http://www.西安电子科技大学.com) | 西安电子科技大学 | :x: NXDOMAIN | 245 | | [西安原神大学.com](http://www.西安原神大学.com) | 西安电子科技大学 | :x: NXDOMAIN | 246 | | [原批大学.com](https://原批大学.com) | 西安电子科技大学 | :x: NXDOMAIN | 247 | | [gaoxinyizhong.dpdns.org](http://www.gaoxinyizhong.dpdns.org) | 西安高新第一中学 | :white_check_mark: Redirect 308 | 248 | | [西安原神大学.icu](http://西安原神大学.icu) | 西安交通大学 | :white_check_mark: | 249 | | [长安原神大学.com](http://www.长安原神大学.com) | 西安科技大学 | :x: NXDOMAIN | 250 | | [原神涉外办事处.com](http://www.原神涉外办事处.com) | 西安外事学院 | :x: NXDOMAIN | 251 | | [原神工业大学.icu](http://原神工业大学.icu) | 西北工业大学 | :x: NXDOMAIN | 252 | | [中国原神大学.org](http://中国原神大学.org) | 西南科技大学 | :x: NXDOMAIN | 253 | | [厦门原神大学.com](http://www.厦门原神大学.com) | 厦门大学 | :x: NXDOMAIN | 254 | | [厦门原神高中.com](https://厦门原神高中.com/) | 厦门市华师希平双语学校 | :white_check_mark: Redirect 302 | 255 | | [厦门原神学校.com](https://厦门原神学校.com/) | 厦门市华师希平双语学校/厦门外国语学校 | :white_check_mark: | 256 | | [原神师范大学.cn](http://www.原神师范大学.cn) | 信阳师范大学 | :white_check_mark: Redirect 301 | 257 | | [璃月师范大学.com](http://www.璃月师范大学.com/) | 许昌学院 | :x: NXDOMAIN | 258 | | [原神大学.love](http://www.原神大学.love) | 燕山大学 | :x: NXDOMAIN | 259 | | [原神工学院.icu](https://www.原神工学院.icu) | 盐城工学院 | :x: NXDOMAIN | 260 | | [四川原神大学.com](http://四川原神大学.com) | 宜宾学院 | :x: NXDOMAIN | 261 | | [genshinedu.com](https://genshinedu.com/) | 宜宾学院 | :white_check_mark: | 262 | | [英国皇家原神学院.com](http://www.英国皇家原神学院.com/) | 英国皇家艺术学院 | :x: NXDOMAIN | 263 | | [op.武汉原神大学.site](http://op.武汉原神大学.site) | 原神 | :x: NXDOMAIN | 264 | | [tjut.top](http://tjut.top) | 原神 | :white_check_mark: Redirect 301 | 265 | | [中国科学技术大学.com](http://中国科学技术大学.com) | 原神 | :white_check_mark: Redirect 302 | 266 | | [美国原神大学.top](http://美国原神大学.top) | 约翰斯·霍普金斯大学 | :x: NXDOMAIN | 267 | | [云南原神大学.com](http://云南原神大学.com) | 云南财经大学 | :x: NXDOMAIN | 268 | | [云南大学.cn](http://云原神.cn) | 云南大学 | :white_check_mark: Redirect 301 | 269 | | [云原神.cn](http://云原神.cn) | 云南大学 | :white_check_mark: Redirect 301 | 270 | | [庆云顶.top](https://庆云顶.top) | 云南大学 | :white_check_mark: Redirect 301 | 271 | | [长垣原神大学.icu](https://长垣原神大学.icu/) | 长垣市烹饪职业技术学院 | :white_check_mark: Redirect 301 | 272 | | [原神怎么你了.com](http://www.原神怎么你了.com) | 浙江财经大学东方学院 | :x: NXDOMAIN | 273 | | [东方原神大学.com](https://www.东方原神大学.com) | 浙江大学 | :x: Connection error | 274 | | [全球某原神大学.com](http://www.全球某原神大学.com) | 浙江工商大学 | :x: NXDOMAIN | 275 | | [不玩原神导致的.com](https://不玩原神导致的.com/) | 浙江工商大学 | :x: NXDOMAIN | 276 | | [浙江原神大专.icu](https://www.浙江原神大专.icu) | 浙江经济职业技术学院 | :x: NXDOMAIN | 277 | | [浙江原神大学.icu](http://浙江原神大学.icu/) | 浙江科技大学 | :x: NXDOMAIN | 278 | | [提瓦特科技大学.com](http://www.提瓦特科技大学.com) | 浙江科技学院 | :white_check_mark: Redirect 301 | 279 | | [浙江原批大学.com](http://浙江原批大学.com) | 浙江理工大学 | :x: NXDOMAIN | 280 | | [浙江原神大学.cn](https://浙江原神大学.cn) | 浙江理工大学 | :x: NXDOMAIN | 281 | | [临安原神大学.xyz](http://临安原神大学.xyz) | 浙江农林大学 | :x: NXDOMAIN | 282 | | [原神枫丹水利大学.fun](http://原神枫丹水利大学.fun) | 浙江水利水电学院 | :x: NXDOMAIN | 283 | | [浙江原神大学.com](http://www.浙江原神大学.com) | 浙江万里学院 | :white_check_mark: Redirect 301 | 284 | | [河南原神大学.com](http://www.河南原神大学.com) | 郑州轻工业大学 | :white_check_mark: Redirect 301 | 285 | | [山西原神大学.com](http://www.山西原神大学.com) | 中北大学 | :x: NXDOMAIN | 286 | | [人民原神第一校.fun](https://人民原神第一校.fun) | 中北大学 | :white_check_mark: Redirect 301 | 287 | | [国立原神大学.top](http://国立原神大学.top) | 中国海洋大学 | :x: NXDOMAIN | 288 | | [中国op大学.com](http://中国op大学.com) | 中国海洋大学 | :white_check_mark: Redirect 301 | 289 | | [原神学院.icu](http://www.原神学院.icu) | 中国计量大学现代科技学院 | :white_check_mark: Redirect 301 | 290 | | [玩原神玩的.com](http://玩原神玩的.com) | 中国科学技术大学 | :white_check_mark: Redirect 301 | 291 | | [提瓦特美术学院.online](https://提瓦特美术学院.online) | 中国美术学院 | :x: NXDOMAIN | 292 | | [中国原神学院.icu](http://中国原神学院.icu) | 中国民用航空飞行学院 | :x: NXDOMAIN | 293 | | [中国原神大学.cc](https://www.中国原神大学.cc) | 中国石油大学华东 | :white_check_mark: Redirect 302 | 294 | | [原神消防学院.com](http://原神消防学院.com) | 中国消防救援学院 | :x: NXDOMAIN | 295 | | [原神高级中学.com](http://www.原神高级中学.com) | 中国药科大学 | :x: NXDOMAIN | 296 | | [原神高级中学.com](http://原神高级中学.com) | 中国药科大学 | :x: NXDOMAIN | 297 | | [长沙原神大学.com](http://长沙原神大学.com) | 中南林业科技大学 | :x: NXDOMAIN | 298 | | [原神螺蛳粉职业技术学院.com](https://www.原神螺蛳粉职业技术学院.com) | 中南林业科技大学 | :x: NXDOMAIN | 299 | | [原神林业科技大学.com](https://原神林业科技大学.com) | 中南林业科技大学 | :x: NXDOMAIN | 300 | | [原神启动.com](https://原神启动.com) | 中南林业科技大学 | :white_check_mark: Redirect 301 | 301 | | [原神教育.shop](https://www.原神教育.shop) | 中央民族大学 | :x: NXDOMAIN | 302 | 303 | 304 | 305 | ## 联系方式 306 | 如果你有任何问题,可以通过发起Issue或者直接联系项目维护者。 307 | -------------------------------------------------------------------------------- /new/README.md: -------------------------------------------------------------------------------- 1 | # 收录申请目录 2 | 3 | 在这个目录里创建以`.add.md`结尾的文件,内容格式: 4 | ``` 5 | | [域名](完整链接) | 学校名称 | 6 | ``` 7 | 每行一个,**格式不符合的行会自动忽略**。 8 | 下一次刷新状态时,所有符合以上格式的行会被添加到列表,同时**文件将会被删除** 9 | -------------------------------------------------------------------------------- /proxies.txt: -------------------------------------------------------------------------------- 1 | # Add proxies to be used when testing links 2 | -------------------------------------------------------------------------------- /verify-url.py: -------------------------------------------------------------------------------- 1 | import concurrent.futures 2 | import datetime 3 | import dns.resolver 4 | import functools 5 | import idna 6 | import io 7 | import json 8 | import os 9 | import pypinyin 10 | import pypinyin.contrib.tone_convert 11 | import pypinyin.style 12 | import re 13 | import requests 14 | import subprocess 15 | import sys 16 | import threading 17 | import traceback 18 | import warnings 19 | 20 | 21 | print_lock = threading.Lock() 22 | 23 | 24 | def stack_func_stdout(func): 25 | @functools.wraps(func) 26 | def wrapper(*args, **kwargs): 27 | temp_stdout = io.StringIO() 28 | kwargs["file"] = temp_stdout 29 | try: 30 | ret = func(*args, **kwargs) 31 | except Exception as e: 32 | with print_lock: 33 | print("-" * 20, "Error occurred:", file=sys.stdout, flush=True) 34 | print(traceback.format_exc(), file=sys.stderr, flush=True) 35 | print("-" * 20, "Output:", file=sys.stdout, flush=True) 36 | print(temp_stdout.getvalue(), end="", file=sys.stdout, flush=True) 37 | sys.exit(1) 38 | with print_lock: 39 | print(temp_stdout.getvalue(), end="", file=sys.stdout, flush=True) 40 | return ret 41 | 42 | return wrapper 43 | 44 | 45 | def resub_concurrent(pattern, repl, string, count=0, flags=0, thread_count=16): 46 | assert callable(repl) 47 | pool = concurrent.futures.ThreadPoolExecutor(thread_count) 48 | futures = [] 49 | replaced = 0 50 | while string and (count == 0 or replaced < count): 51 | m = re.search(pattern, string, flags) 52 | if m: 53 | if m.start() == 0: 54 | futures.append(pool.submit(repl, m)) 55 | string = string[m.end() :] 56 | replaced += 1 57 | else: 58 | futures.append(string[: m.start()]) 59 | futures.append(pool.submit(repl, m)) 60 | string = string[m.end() :] 61 | replaced += 1 62 | else: 63 | futures.append(string) 64 | break 65 | out = "" 66 | for future in futures: 67 | if isinstance(future, str): 68 | out += future 69 | else: 70 | out += future.result() 71 | return out 72 | 73 | 74 | warnings.filterwarnings("ignore", category=requests.packages.urllib3.exceptions.InsecureRequestWarning) 75 | sys.setrecursionlimit(64) 76 | 77 | # Whitelist json file, contains an array of regex strings 78 | with open("whitelist.json", mode="rt", encoding="utf8") as f: 79 | whitelist = json.load(f) 80 | 81 | resolver = dns.resolver.Resolver() 82 | resolver.nameservers += ["114.114.114.114", "8.8.8.8"] 83 | 84 | header = { 85 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0" 86 | } 87 | 88 | # Get proxies 89 | with open("proxies.txt", "rt", encoding="utf-8") as f: 90 | proxies = list(i for i in map(str.strip, f.read().splitlines()) if i and not i.startswith("#")) 91 | proxies = [None] + list(map(lambda x: {"http": x, "https": x}, proxies)) 92 | 93 | # Get the list 94 | with open("README.md", "rt", encoding="utf-8") as f: 95 | md_content = f.read() 96 | 97 | # Disable retry 98 | s = requests.Session() 99 | a = requests.adapters.HTTPAdapter(max_retries=2) 100 | s.mount("http://", a) 101 | s.mount("https://", a) 102 | 103 | 104 | # Print in red 105 | def print_error(*s, **kwargs): 106 | if "end" in kwargs: 107 | end = kwargs["end"] 108 | del kwargs["end"] 109 | else: 110 | end = "\n" 111 | if "flush" in kwargs: 112 | del kwargs["flush"] 113 | print("\033[31m", end="", flush=True, **kwargs) 114 | if s: 115 | print(*s, end="", flush=True, **kwargs) 116 | else: 117 | print("Error", end="", flush=True, **kwargs) 118 | print("\033[0m", end=end, flush=True, **kwargs) 119 | 120 | 121 | # Print in green 122 | def print_success(*s, **kwargs): 123 | if "end" in kwargs: 124 | end = kwargs["end"] 125 | del kwargs["end"] 126 | else: 127 | end = "\n" 128 | if "flush" in kwargs: 129 | del kwargs["flush"] 130 | print("\033[32m", end="", flush=True, **kwargs) 131 | if s: 132 | print(*s, end="", flush=True, **kwargs) 133 | else: 134 | print("Success", end="", flush=True, **kwargs) 135 | print("\033[0m", end=end, flush=True, **kwargs) 136 | 137 | 138 | @stack_func_stdout 139 | def replace_table_row(m: re.Match, file=sys.stdout): 140 | print(file=file) 141 | url = m.group(2) 142 | if not re.match(r"https?://", url): 143 | url = "http://" + url 144 | url_split = url.split("/") 145 | url_split[2] = idna.decode(url_split[2]) 146 | url = "/".join(url_split) 147 | successes = {0: [], 1: [], 2: []} 148 | try: 149 | success, method = check_url(url, file=file) 150 | except Exception: 151 | success = 0 152 | method = "Other Error" 153 | print("\n", end="", flush=True, file=file) 154 | print_error(traceback.format_exc(), flush=True, file=file) 155 | if success == 1: 156 | if method[0] == "Unknown": 157 | method = ("", None) 158 | elif method[0] == "EDU Domain": 159 | return f"| [{m.group(1)}]({url}) | {m.group(3)} | :warning: {method[0]} |" 160 | suggestion_removed = re.sub(r"\*.*?\*", "", m.group(3)) 161 | return f"| [{m.group(1)}]({url}) | {suggestion_removed} | :white_check_mark: {method[0]} |" 162 | else: 163 | successes[success].append((url, method)) 164 | print_error("Failed, trying other possible URLs", file=file) 165 | for new_url in get_other_possible_url(url): 166 | try: 167 | success, method1 = check_url(new_url, file=file) 168 | except Exception: 169 | success = 0 170 | method1 = "Other Error" 171 | print("\n", end="", flush=True, file=file) 172 | print_error(traceback.format_exc(), flush=True, file=file) 173 | if success == 1: 174 | if method1[0] == "Unknown": 175 | method1 = ("", None) 176 | suggestion_removed = re.sub(r"\*.*?\*", "", m.group(3)) 177 | return f"| [{m.group(1)}]({new_url}) | {suggestion_removed} | :white_check_mark: {method1[0]} |" 178 | successes[success].append((new_url, method1)) 179 | if successes[2]: 180 | if sum(1 for i in successes[2] if i[1] == "NXDOMAIN") != len(successes[2]): 181 | i = 0 182 | while successes[2][i][1] == "NXDOMAIN": 183 | i += 1 184 | return f"| [{m.group(1)}]({successes[2][i][0]}) | {m.group(3)} | :question: {successes[2][i][1]} |" 185 | return f"| [{m.group(1)}]({url}) | {m.group(3)} | :x: {method} |" 186 | 187 | 188 | # Try to remove or add https and www. 189 | def get_other_possible_url(url): 190 | assert re.match(r"https?://", url) 191 | new_urls = [] 192 | if re.match(r"https?://www\.", url): 193 | new_urls.append(re.sub(r"https?://www\.", "http://", url)) 194 | new_urls.append(re.sub(r"https?://www\.", "https://", url)) 195 | if url.startswith("https://"): 196 | new_urls.append("http://" + url[8:]) 197 | else: 198 | new_urls.append("https://" + url[7:]) 199 | else: 200 | new_urls.append(re.sub(r"https?://", "http://www.", url)) 201 | new_urls.append(re.sub(r"https?://", "https://www.", url)) 202 | if url.startswith("https://"): 203 | new_urls.append("http://" + url[8:]) 204 | else: 205 | new_urls.append("https://" + url[7:]) 206 | return sorted(new_urls, reverse=True) 207 | 208 | 209 | def get_domain(url): 210 | if not re.match(r"https?://", url): 211 | url = "http://" + url 212 | return url.split("/")[2] 213 | 214 | 215 | def check_whitelist(url): 216 | for i in whitelist: 217 | if re.search(i, url): 218 | return True 219 | return False 220 | 221 | 222 | def check_url(url, ignore_ssl=False, file=sys.stdout): 223 | global proxies, resolver 224 | print(f"Checking [{url}]...", end=" ", flush=True, file=file) 225 | method = ("", None) 226 | if check_whitelist(get_domain(url)) and os.environ.get("NO_SKIP_EDU") not in {"1", "true", "True", "yes"}: 227 | print_success("Found in whitelist, skipped", file=file) 228 | return 1, ("EDU Domain", None) 229 | error = "Unknown error" 230 | try: 231 | res = resolver.resolve(get_domain(url), "CNAME") 232 | print(f"CNAME to [{res[0].target.to_text()[:-1]}]", end=" ", flush=True, file=file) 233 | method = ("CNAME", res[0].target.to_text()[:-1]) 234 | except dns.resolver.NoAnswer: 235 | pass 236 | except dns.resolver.NXDOMAIN: 237 | print("CNAME NXDOMAIN", end=" ", flush=True, file=file) 238 | except Exception: 239 | print("DNS CNAME error", end=" ", flush=True, file=file) 240 | error = "DNS CNAME error" 241 | if not method[0]: 242 | try: 243 | res = resolver.resolve(get_domain(url), "A") 244 | print(f"A to [{res[0].address}]", end=" ", flush=True, file=file) 245 | method = ("Unknown", res[0].address) 246 | except dns.resolver.NoAnswer: 247 | print("A NXDOMAIN", end=" ", flush=True, file=file) 248 | error = "NXDOMAIN" 249 | except dns.resolver.NXDOMAIN: 250 | print("DNS A error", end=" ", flush=True, file=file) 251 | error = "NXDOMAIN" 252 | except Exception: 253 | print("DNS A error", end=" ", flush=True, file=file) 254 | error = "DNS error" 255 | if method[0]: 256 | for idx, p in enumerate(proxies): 257 | try: 258 | if p is not None: 259 | print(f" -- Using proxy {idx}...", end=" ", flush=True, file=file) 260 | r = s.get(url, allow_redirects=False, timeout=3, verify=not ignore_ssl, proxies=p, headers=header) 261 | if not 200 <= r.status_code < 400: 262 | print_error(f"Failed with status code {r.status_code}", file=file) 263 | error = str(r.status_code) 264 | return 0, error 265 | elif 300 <= r.status_code < 400: 266 | target = r.headers["Location"] 267 | if not re.match(r"https?://", target): 268 | if target.startswith("/"): 269 | target = "/".join(url.split("/")[:3]) + target 270 | elif url.split("#")[0].split("?")[0].endswith("/"): 271 | target = url.split("#")[0].split("?")[0] + target 272 | else: 273 | target = "/".join(url.split("#")[0].split("?")[0].split("/")[:-1]) + "/" + target 274 | print(f"Redirect to [{target}] with status code {r.status_code}", file=file) 275 | print("-- Checking redirect...", end=" ", flush=True, file=file) 276 | success, submethod = check_url(target, file=file) 277 | if method[0] == "CNAME" and (get_domain(url) in target or get_domain(target) in url): 278 | method = (submethod[0], method[1]) 279 | if success != 1: 280 | return 2, submethod 281 | method = (f"Redirect {r.status_code}", target) 282 | elif 'http-equiv="refresh"' in r.text: 283 | target = re.search(r'content="\d+; *(?:url=)?(.*?)"', r.text, re.I).group(1) 284 | if not re.match(r"https?://", target): 285 | if target.startswith("/"): 286 | target = "/".join(url.split("/")[:3]) + target 287 | elif url.split("#")[0].split("?")[0].endswith("/"): 288 | target = url.split("#")[0].split("?")[0] + target 289 | else: 290 | target = "/".join(url.split("#")[0].split("?")[0].split("/")[:-1]) + "/" + target 291 | print(f"Redirect with meta refresh to [{target}]", file=file) 292 | print("-- Checking redirect...", end=" ", flush=True, file=file) 293 | success, submethod = check_url(target, file=file) 294 | if method[0] == "CNAME": 295 | method = (submethod[0], method[1]) 296 | if success != 1: 297 | return 2, submethod 298 | method = ("Meta Refresh", target) 299 | elif method[0] == "CNAME": 300 | print_success("CNAME Success", file=file) 301 | else: 302 | print_success("Unknown redirect method or no redirect", file=file) 303 | return 1, method 304 | except requests.exceptions.SSLError as e: 305 | if ignore_ssl: 306 | print_error(f"Failed with exception {e.__class__.__name__}", file=file) 307 | return 0, e.__class__.__name__ 308 | if traceback.extract_stack()[-2].name == "check_url": 309 | print("\r-- Checking redirect... ", end="", flush=True, file=file) 310 | else: 311 | print("\r", end="", flush=True) 312 | print_error("SSLError, retrying without SSL...", end=" ", flush=True, file=file) 313 | return check_url(url, True, file=file) 314 | except requests.exceptions.RequestException as e: 315 | print_error(f"Failed with exception {e.__class__.__name__}", file=file) 316 | error = "Connection error" 317 | else: 318 | print_error(file=file) 319 | return 0, error 320 | return 0, error 321 | 322 | 323 | @pypinyin.style.register("tone_with_original") 324 | def tone_with_original(pinyin, han, **kwargs): 325 | return [pypinyin.contrib.tone_convert.to_tone3(pinyin), han] 326 | 327 | 328 | def handle_no_pinyin(s): 329 | if sum(1 for i in s if 65 <= ord(i) <= 90 or 97 <= ord(i) <= 122) == 0: 330 | return [[[i]] for i in s] 331 | return [[["", i]] for i in s] 332 | 333 | 334 | def reshape_pinyin(l): 335 | o = [] 336 | first = [] 337 | second = [] 338 | for i in l: 339 | if len(i[0]) == 1 or i[0][0] == "": 340 | if first: 341 | o.append(first) 342 | o.append(second) 343 | first = [] 344 | second = [] 345 | o.append(i[0]) 346 | else: 347 | first.append(i[0][0]) 348 | second.append(i[0][1]) 349 | if first: 350 | o.append(first) 351 | o.append(second) 352 | return o 353 | 354 | 355 | def sort_key(s): 356 | m = re.match(r"\| *\[(.*?)\]\((?P.*?)\) *\| *(?P.*?) *\|.*", s) 357 | return [ 358 | reshape_pinyin(pypinyin.pinyin(m["name"], style="tone_with_original", errors=handle_no_pinyin)), 359 | reshape_pinyin(pypinyin.pinyin(m["link"], style="tone_with_original", errors=handle_no_pinyin)), 360 | ] 361 | 362 | 363 | # Detect new merged PR 364 | new = [] 365 | remove_pending = [] 366 | co_authors = set() 367 | for i in os.listdir("new"): 368 | if not i.endswith(".add.md"): 369 | continue 370 | with open(os.path.join("new", i), "rt", encoding="utf-8") as f: 371 | add_content = f.read() 372 | while m := re.search(r"\| *\[(.*?)\]\((.*?)\) *\| *(.*?) *\|.*", add_content): 373 | new.append(replace_table_row(m)) 374 | add_content = add_content[m.end() :] 375 | l = subprocess.check_output(["git", "log", os.path.join("new", i)]).decode() 376 | for k in re.findall(r"(?:(?:Author|Co-authored-by|Signed-off-by): )(.*? <.*?>)", l): 377 | if "[bot]" in k: 378 | break 379 | co_authors.add(k) 380 | remove_pending.append(os.path.join("new", i)) 381 | 382 | 383 | if not "COUNT_ONLY" in os.environ or os.environ["COUNT_ONLY"] not in ("1", "true", "True"): 384 | md_out = resub_concurrent(r"\| *\[(.*?)\]\((.*?)\) *\| *(.*?) *\|.*", replace_table_row, md_content) 385 | print("Sorting...") 386 | m = re.match( 387 | r"(?P
.*?)(?P(\| *\[[^\n]*?\]\([^\n]*?\) *\|[^\n]*?\|[^\n]*?\|\n?)+)(?P
.*)", 388 | md_out, 389 | re.DOTALL, 390 | ) 391 | table = m["table"].splitlines(False) + new 392 | md_out = m["header"] + "\n".join(sorted(set(table), key=sort_key)) + "\n" + m["footer"] 393 | else: 394 | md_out = md_content 395 | md_out = re.sub(r"目前有\d+", "目前有%d" % len(re.findall(r"\| *\[(.*?)\]\((.*?)\) *\| *(.*?) *\|.*", md_out)), md_out) 396 | md_out = re.sub( 397 | r"其中\d+个有效", 398 | "其中%d个有效" % len(re.findall(r"\| *\[(.*?)\]\((.*?)\) *\| *(.*?) *\|.*(:white_check_mark:|:question:)", md_out)), 399 | md_out, 400 | ) 401 | now = datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=8))).strftime("%Y-%m-%d %H:%M UTC+8") 402 | md_out = re.sub(r"\d{4}-\d{2}-\d{2}.*?(?=))", now, md_out, count=1) 403 | with open("README.md", "wt", encoding="utf-8") as f: 404 | f.write(md_out) 405 | 406 | # Detect GitHub Actions 407 | if "GITHUB_ACTIONS" in os.environ and os.environ["GITHUB_ACTIONS"] == "true": 408 | print("::group::Output Markdown") 409 | print(md_out) 410 | print("::endgroup::") 411 | else: 412 | print("-" * 20, "Output Markdown") 413 | print(md_out) 414 | 415 | # Generate commit message 416 | commit_message = f"Update Status ({now})\n\n\n" 417 | for i in co_authors: 418 | commit_message += f"Co-authored-by: {i}\n" 419 | print("Commit message:", commit_message) 420 | delimiter = "EOF" 421 | while delimiter in commit_message: 422 | delimiter += "EOF" 423 | os.system(f'echo "commit_message<<{delimiter}" >> "$GITHUB_OUTPUT"') 424 | for i in commit_message.splitlines(False): 425 | os.system(f'echo "{i}" >> "$GITHUB_OUTPUT"') 426 | os.system(f'echo "{delimiter}" >> "$GITHUB_OUTPUT"') 427 | 428 | for i in remove_pending: 429 | os.remove(i) 430 | -------------------------------------------------------------------------------- /whitelist.json: -------------------------------------------------------------------------------- 1 | [ 2 | "\\.edu(\\.[a-zA-Z0-9]+)*$", 3 | "hfbz\\.com", 4 | "sz\\.gov\\.cn" 5 | ] --------------------------------------------------------------------------------