当前位置:   article > 正文

使用raw.gitmirror.com替换raw.githubusercontent.com以解决brew upgrade python@3.12慢的问题

raw.gitmirror

MacOS系统上,升级python3.12时,超级慢,而且最后还失败了。看了日志,发现是用curl从raw.githubusercontent.com上下载Python安装包超时了。

解决方案一:开启VPN工具,穿越围墙

解决方案二:使用raw.gitmirror.com替换raw.githubusercontent.com

穿墙有风险,操作需谨慎,这里我采用的是方案二。

1. 查看curl路径

  1. which curl
  2. # /usr/bin/curl

2. 编写自定义脚本,并赋予执行权限

  1. ln -s `which curl` /usr/local/bin/curl
  2. [ -d ~/.local/bin ] || mkdir -p ~/.local/bin/
  3. cd ~/.local/bin
  4. touch curl
  5. chmod +x curl
  6. # 注:PATH要配置到.bashrc或.zshrc里,别的窗口才能起作用
  7. export PATH=$HOME/.local/bin:$PATH
  8. vi curl
  9. which curl
  10. # ~/.local/bin/curl

3. 脚本内容

  1. #!/usr/bin/env python
  2. import os,sys
  3. origin,target="raw.githubusercontent.com","raw.gitmirror.com"
  4. args=" ".join(repr(i) if " " in i else i for i in sys.argv[1:])
  5. cmd="/usr/bin/{} ".format(sys.argv[0].split('/')[-1])+args.replace(origin,target)
  6. sys.exit(os.system(cmd))

4. 测试效果

curl https://raw.githubusercontent.com/Homebrew/homebrew-core/a775cbd0967da13128293d71fb26431fdedee6fb/Formula/m/mpdecimal.rb

5. 重新执行升级命令(这时候就很快了,不到一分钟就下载完毕,十分钟内就完成升级)

brew upgrade python@3.12

注: wget也可以用类似的方法加速

################# 2024.02.08 补充:

如果有外网服务器,还可以配个中转请求:

1. 本地curl文件内容如下(需export JUMPER_IP='<服务器IP地址>')

  1. #!/usr/bin/env python
  2. import os
  3. import sys
  4. try:
  5. from typing import List # NOQA:F401
  6. except ImportError:
  7. pass
  8. def gen_cmd(sys_argv):
  9. # type: (List[str]) -> str
  10. args = []
  11. scheme = "https://"
  12. origin, target = "raw.githubusercontent.com", "raw.gitmirror.com"
  13. domains = ("objects.githubusercontent.com", "github.com")
  14. redirect = os.getenv("JUMPER_IP")
  15. host = "http://{}:9337/".format(redirect)
  16. for i in sys_argv[1:]:
  17. if i.startswith(scheme):
  18. j = i[len(scheme) :]
  19. if j.startswith(origin):
  20. i = i.replace(origin, target)
  21. elif redirect:
  22. for domain in domains:
  23. if j.startswith(domain):
  24. i = host + j
  25. break
  26. elif " " in i:
  27. i = repr(i)
  28. args.append(i)
  29. tool = "/usr/local/bin/" + sys_argv[0].split("/")[-1]
  30. cmd = tool + " " + " ".join(args)
  31. return cmd
  32. def main():
  33. # type: () -> int
  34. sys_argv = sys.argv
  35. if "--dry" in sys_argv:
  36. sys_argv = [i for i in sys_argv if i != "--dry"]
  37. print("--> " + gen_cmd(sys_argv))
  38. return 0
  39. return os.system(gen_cmd(sys_argv))
  40. if __name__ == "__main__":
  41. sys.exit(main())

2. 服务器上的app.py文件如下:

  1. #!/usr/bin/env python
  2. import re
  3. # pip install httpx orjson loguru sanic gunicorn 'uvicorn[standard]'
  4. from httpx import AsyncClient
  5. from loguru import logger
  6. from orjson import dumps, loads
  7. from sanic import Sanic, raw
  8. app = Sanic("Jumper", dumps=dumps, loads=loads)
  9. @app.route("", methods=["GET", "POST", "PUT", "PATCH", "DELETE"])
  10. async def index(request):
  11. return raw(b"Welcome. Example>> http :8000/http.127.0.0.1:9000/home")
  12. @app.route("/<full:path>", methods=["GET", "POST", "PUT", "PATCH", "DELETE"])
  13. async def handler(request, full: str):
  14. host, url = full.lstrip("/"), ""
  15. if m := re.search(r"(https?)[^0-9a-zA-Z]+(.+)", host):
  16. scheme, host = m.groups()
  17. else:
  18. scheme = "https"
  19. try:
  20. domain, url = host.split("/", 1)
  21. except ValueError:
  22. domain = host
  23. base_url = scheme + "://" + domain
  24. target_path = url
  25. if qs := request.query_string:
  26. target_path += "?" + qs
  27. if not target_path:
  28. target_path = base_url
  29. if not target_path.startswith("/") and not target_path.startswith("http"):
  30. target_path = "/" + target_path
  31. logger.debug(f"{base_url=}; {target_path=}")
  32. async with AsyncClient(
  33. base_url=base_url, follow_redirects=True, timeout=20
  34. ) as client:
  35. method, body = request.method, request.body
  36. r = await client.request(method, target_path, content=body)
  37. if r.status_code == 302 and (next_url := r.headers.get("location")):
  38. r = await client.request(method, next_url, content=body)
  39. return raw(r.content, status=r.status_code)
  40. if __name__ == "__main__": # pragma: no cover
  41. app.run(debug=True, host="0.0.0.0")

3. 后台启动服务:

gunicorn app:app --bind 0.0.0.0:9337 --worker-class uvicorn.workers.UvicornWorker --daemon

4. 本地brew对应的install文件修改如下:

  1. cd $(brew --prefix)/Homebrew/Library/Homebrew
  2. grep -rn Downloading *.rb
  3. # download_strategy.rb:426:
  4. vi download_strategy.rb # 给download的url增加前缀
  5. git diff

增加这几行:

  1. if (domain = Homebrew::EnvConfig.artifact_domain)
  2. url = url.sub(%r{^https?://#{GitHubPackages::URL_DOMAIN}/}o, "#{domain.chomp("/")}/")
  3. + elsif url.start_with?("https://cdn.")
  4. + puts "Leave #{url} to be itself."
  5. + elsif !url.start_with?("https://mirrors.")
  6. + url = "http://your-server-ip-or-domain/" + url
  7. end
  8. ohai "Downloading #{url}"

 即除了mirrors和cdn开头的域名,全都使用自建域名加速

  1. elsif url.start_with?("https://cdn.")
  2. puts "Leave #{url} to be itself."
  3. elsif !url.start_with?("https://mirrors.")
  4. url = "https://your.domain.com/" + url

################################

2024.03.06 补充

步骤4可以用如下Python脚本来实现:

  1. #!/usr/bin/env python
  2. """
  3. This script is used to improve download speed for `brew install`
  4. Usage::
  5. $ python pad_brew_download_url.py
  6. """
  7. import os
  8. import subprocess
  9. HOST = "https://xxx.com/" # 外网服务器对应的host(域名或IP地址)
  10. PAD = """
  11. elsif url.start_with?("https://cdn.")
  12. puts "Leave #{url} to be itself."
  13. elsif !url.start_with?("https://mirrors.")
  14. url = "%s" + url
  15. """
  16. def capture_output(cmd):
  17. # type: (str) -> str
  18. try:
  19. r = subprocess.run(cmd, shell=True, capture_output=True)
  20. except (TypeError, AttributeError): # For python<=3.6
  21. with os.popen(cmd) as p:
  22. return p.read().strip()
  23. else:
  24. return r.stdout.decode().strip()
  25. def main():
  26. # type: () -> None
  27. brew_root = capture_output("brew --prefix")
  28. folder = "Homebrew/Library/Homebrew"
  29. name = "download_strategy.rb"
  30. file = os.path.join(brew_root, folder, name)
  31. with open(file) as f:
  32. text = f.read()
  33. if HOST in text:
  34. print("{} already in {}\nNothing to do!".format(HOST, file))
  35. return
  36. s = ' end\n\n ohai "Downloading #{url}"'
  37. pad = PAD % HOST
  38. new_text = text.replace(s, pad.lstrip("\n") + s)
  39. with open(file, "w") as f:
  40. f.write(new_text)
  41. print("Insert {} into {}".format(pad, file))
  42. if __name__ == "__main__":
  43. main()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/946791
推荐阅读
相关标签
  

闽ICP备14008679号