From 9cc7e1f454164419fe5e8f8d5691beb4d0d40265 Mon Sep 17 00:00:00 2001 From: kanshan Date: Thu, 27 Mar 2025 16:37:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20host=5Follama.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- host_ollama.py | 113 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 host_ollama.py diff --git a/host_ollama.py b/host_ollama.py new file mode 100644 index 0000000..bdabb0f --- /dev/null +++ b/host_ollama.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +""" +Ollama 本地镜像服务器 +功能: +1. 自动检测并Host下载的镜像目录 +2. 提供文件浏览和下载接口 +3. 自动生成友好的下载页面 +""" + +import os +import sys +from http.server import HTTPServer, SimpleHTTPRequestHandler +from pathlib import Path +import threading +import webbrowser + +MIRROR_DIR = "ollama_releases" # 与mirror_ollama.sh保持一致 +PORT = 8000 + +class OllamaRequestHandler(SimpleHTTPRequestHandler): + """自定义请求处理器,增强目录浏览功能""" + + def __init__(self, *args, **kwargs): + super().__init__(*args, directory=MIRROR_DIR, **kwargs) + + def list_directory(self, path): + """生成增强型目录列表页面""" + try: + items = [] + for item in Path(path).iterdir(): + mtime = item.stat().st_mtime + size = item.stat().st_size + items.append((item.name, mtime, size)) + + # 按版本号排序(降序) + items.sort(key=lambda x: x[0], reverse=True) + + # 生成HTML + html = ["Ollama 本地镜像"] + html.append("") + html.append("

Ollama 本地镜像库

") + html.append(f"

当前目录: {path}

") + html.append("") + + for name, mtime, size in items: + human_size = f"{size/1024/1024:.1f} MB" if size > 1024*1024 else f"{size/1024:.1f} KB" + html.append( + f'' + f'' + f'' + ) + + html.append("
文件名大小修改时间
{name}{human_size}{mtime:.0f}
") + self.send_response(200) + self.send_header("Content-type", "text/html; charset=utf-8") + self.end_headers() + self.wfile.write("\n".join(html).encode('utf-8')) + + except Exception as e: + self.send_error(500, f"服务器错误: {str(e)}") + +def start_server(port=PORT): + """启动HTTP服务器""" + server_address = ('', port) + httpd = HTTPServer(server_address, OllamaRequestHandler) + + print(f"\n🎯 Ollama 本地镜像服务已启动") + print(f"👉 访问地址: http://localhost:{port}") + print(f"📁 镜像目录: {os.path.abspath(MIRROR_DIR)}") + print("🛑 按 Ctrl+C 停止服务\n") + + try: + httpd.serve_forever() + except KeyboardInterrupt: + print("\n服务器已停止") + +def ensure_mirror_dir(): + """确保镜像目录存在""" + if not os.path.exists(MIRROR_DIR): + os.makedirs(MIRROR_DIR) + print(f"创建镜像目录: {MIRROR_DIR}") + return False + return True + +def open_browser(): + """自动打开浏览器""" + import time + time.sleep(1) + webbrowser.open(f"http://localhost:{PORT}") + +if __name__ == '__main__': + # 检查并获取端口参数 + port = PORT + if len(sys.argv) > 1: + try: + port = int(sys.argv[1]) + except ValueError: + print("错误: 端口号必须是数字") + sys.exit(1) + + if not ensure_mirror_dir(): + print("⚠️ 注意: 镜像目录为空,请先运行 mirror_ollama.sh 下载文件") + + # 自动打开浏览器 + threading.Thread(target=open_browser, daemon=True).start() + + # 启动服务器 + start_server(port) \ No newline at end of file