diff --git a/api/index.py b/api/index.py deleted file mode 100644 index ea585ee..0000000 --- a/api/index.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: UTF-8 -*- -import requests -import re -from http.server import BaseHTTPRequestHandler -import json - -def list_split(items, n): - return [items[i:i + n] for i in range(0, len(items), n)] -def getdata(name): - gitpage = requests.get("https://github.com/" + name) - data = gitpage.text - datadatereg = re.compile(r'data-date="(.*?)" data-level') - datacountreg = re.compile(r'(.*?) contribution') - datadate = datadatereg.findall(data) - datacount = datacountreg.findall(data) - datacount = list(map(int, [0 if i == "No" else i for i in datacount])) - - # 将datadate和datacount按照字典序排序 - sorted_data = sorted(zip(datadate, datacount)) - datadate, datacount = zip(*sorted_data) - - contributions = sum(datacount) - datalist = [] - for index, item in enumerate(datadate): - itemlist = {"date": item, "count": datacount[index]} - datalist.append(itemlist) - datalistsplit = list_split(datalist, 7) - returndata = { - "total": contributions, - "contributions": datalistsplit - } - return returndata -class handler(BaseHTTPRequestHandler): - def do_GET(self): - path = self.path - user = path.split('?')[1] - data = getdata(user) - self.send_response(200) - self.send_header('Access-Control-Allow-Origin', '*') - self.send_header('Content-type', 'application/json') - self.end_headers() - self.wfile.write(json.dumps(data).encode('utf-8')) - return diff --git a/app.py b/app.py new file mode 100644 index 0000000..8f5d035 --- /dev/null +++ b/app.py @@ -0,0 +1,86 @@ +# -*- coding: UTF-8 -*- +# api/index.py - GitHub Contributions API for hexo-filter-gitcalendar + +from flask import Flask, jsonify, request +from flask_cors import CORS +import requests +from datetime import datetime, timedelta + +app = Flask(__name__) +CORS(app) # 允许所有跨域请求 + +def list_split(items, n): + """将列表按每 n 个元素分割成子列表""" + return [items[i:i + n] for i in range(0, len(items), n)] + +def getdata(name): + try: + # 从第三方 API 获取数据(扁平数组) + url = f"https://github-contributions-api.jogruber.de/v4/{name}" + resp = requests.get(url, timeout=10) + resp.raise_for_status() + data = resp.json() + days = data.get("contributions", []) # 扁平数组,每个元素包含 date 和 count + + # 手动计算总贡献数(确保是整数) + total = sum(day.get("count", 0) for day in days) + + # 按7天分割成周 + weekly = list_split(days, 7) + + # 补足到至少53周(前面补空周,日期递减) + while len(weekly) < 53: + # 获取当前第一周的日期 + first_week_start = datetime.strptime(weekly[0][0]["date"], "%Y-%m-%d") + # 计算前一周的日期范围 + prev_week_start = first_week_start - timedelta(weeks=1) + new_week = [] + for i in range(7): + date = prev_week_start + timedelta(days=i) + new_week.append({"date": date.strftime("%Y-%m-%d"), "count": 0}) + weekly.insert(0, new_week) + + # 确保最后一周有7天(后面补空,日期递增) + last_week = weekly[-1] + if len(last_week) < 7: + last_date = datetime.strptime(last_week[-1]["date"], "%Y-%m-%d") + for i in range(1, 7 - len(last_week) + 1): + new_date = last_date + timedelta(days=i) + last_week.append({"date": new_date.strftime("%Y-%m-%d"), "count": 0}) + + # 只取前53周(防止超出) + return { + "total": total, + "contributions": weekly[:53] + } + except Exception as e: + return {"error": str(e)} + +@app.route('/') +def home(): + return jsonify({ + "message": "GitHub Calendar API", + "usage": [ + "/?username - 例如 /?Sunrisepeak", + "/api?username= - 同上", + "/ - 路径参数" + ] + }) + +@app.route('/api', strict_slashes=False) +@app.route('/', strict_slashes=False) +def get_calendar(): + username = request.args.get('username') + if not username: + qs = request.query_string.decode('utf-8') + if qs and '=' not in qs: + username = qs + if not username: + return jsonify({"error": "Missing username"}), 400 + return jsonify(getdata(username)) + +@app.route('/', strict_slashes=False) +def get_calendar_by_path(username): + return jsonify(getdata(username)) + +app = app \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 570b153..93783ee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ -certifi==2020.12.5 -chardet==4.0.0 -idna==2.10 -requests==2.25.1 -urllib3==1.26.2 +flask==3.0.0 +requests==2.31.0 +gunicorn==21.2.0 +flask-cors \ No newline at end of file