Nafiul Huda commited on
Commit
c504ea2
·
verified ·
1 Parent(s): 5e75d3b

Delete mcapi.py

Browse files
Files changed (1) hide show
  1. mcapi.py +0 -240
mcapi.py DELETED
@@ -1,240 +0,0 @@
1
- """mcapi.py — Paper/Purpur server jars + Java resolution (live APIs, future-proof)."""
2
-
3
- from __future__ import annotations
4
-
5
- import os
6
- import re
7
- import tarfile
8
- import tempfile
9
-
10
- import httpx
11
-
12
- UA = {"User-Agent": "MCPanel/2.0 (HuggingFace Space)"}
13
- PAPER_API = "https://fill.papermc.io/v3/projects/paper"
14
- PURPUR_API = "https://api.purpurmc.org/v2/purpur"
15
- TOOLS_DIR = os.environ.get("SERVER_DIR", "/data") + "/tools"
16
-
17
-
18
- # ---------------------------------------------------------------------------
19
- # Java resolution
20
- # ---------------------------------------------------------------------------
21
-
22
- def _major(java_bin: str) -> int | None:
23
- try:
24
- import subprocess
25
- out = subprocess.check_output([java_bin, "-version"],
26
- stderr=subprocess.STDOUT, timeout=15).decode(errors="replace")
27
- m = re.search(r'version\s+"(\d+)(?:\.(\d+))?', out)
28
- if m:
29
- if int(m.group(1)) == 1:
30
- return int(m.group(2) or 8)
31
- return int(m.group(1))
32
- except Exception:
33
- pass
34
- return None
35
-
36
-
37
- def _find_javas() -> dict:
38
- javas = {}
39
- for root in ("/usr/lib/jvm", "/usr/local/lib/jvm", "/opt/java"):
40
- if not os.path.isdir(root):
41
- continue
42
- for name in sorted(os.listdir(root)):
43
- jp = os.path.join(root, name, "bin", "java")
44
- if os.path.exists(jp):
45
- maj = _major(jp)
46
- if maj:
47
- javas.setdefault(maj, jp)
48
- return javas
49
-
50
-
51
- def installed_java() -> list:
52
- return sorted(_find_javas().keys())
53
-
54
-
55
- def java_min_for_version(version: str) -> int:
56
- v = str(version).strip()
57
- m = re.match(r"^(\d+)(?:\.(\d+))?", v)
58
- if not m:
59
- return 21
60
- major, minor = int(m.group(1)), int(m.group(2) or 0)
61
- if major == 1:
62
- if minor >= 20:
63
- return 21
64
- if minor >= 17:
65
- return 17
66
- return 8
67
- return 25 if major >= 20 else 21
68
-
69
-
70
- def _adoptium_url(major: int) -> list:
71
- base = ("https://api.adoptium.net/v3/binary/latest/{m}/ga/"
72
- "linux/x64/jdk/hotspot/normal/eclipse?project=jdk")
73
- return [base.format(m=major),
74
- f"https://api.adoptium.net/v3/binary/latest/{major}/ga/linux/x64/jdk/hotspot/",
75
- f"https://github.com/adoptium/temurin{major}-binaries/releases/latest/download/"]
76
-
77
-
78
- async def _download_tar(url: str, tmp_path: str) -> bool:
79
- try:
80
- async with httpx.AsyncClient(follow_redirects=True, timeout=httpx.Timeout(1200, connect=40)) as c:
81
- async with c.stream("GET", url, headers=UA) as r:
82
- r.raise_for_status()
83
- with open(tmp_path, "wb") as f:
84
- async for chunk in r.aiter_bytes(256 * 1024):
85
- f.write(chunk)
86
- return True
87
- except Exception:
88
- return False
89
-
90
-
91
- def _provisioned(major: int) -> str | None:
92
- found = _find_javas()
93
- if major in found:
94
- return found[major]
95
- root = os.path.join(TOOLS_DIR, f"jdk-{major}")
96
- for dp, _, files in os.walk(root):
97
- if "java" in files:
98
- return os.path.join(dp, "java")
99
- return None
100
-
101
-
102
- async def ensure_java(major: int) -> str:
103
- have = _find_javas()
104
- if major in have:
105
- return have[major]
106
- existing = _provisioned(major)
107
- if existing:
108
- return existing
109
- dest_dir = os.path.join(TOOLS_DIR, f"jdk-{major}")
110
- os.makedirs(dest_dir, exist_ok=True)
111
- with tempfile.NamedTemporaryFile(suffix=".tar.gz", delete=False) as tmp:
112
- tmp_path = tmp.name
113
- ok = False
114
- for url in _adoptium_url(major):
115
- if await _download_tar(url, tmp_path):
116
- ok = True
117
- break
118
- if ok:
119
- try:
120
- with tarfile.open(tmp_path, "r:gz") as t:
121
- t.extractall(dest_dir, filter="data")
122
- except Exception:
123
- ok = False
124
- os.remove(tmp_path)
125
- found = _provisioned(major)
126
- if found:
127
- return found
128
- # last resort: any java on PATH
129
- return "java"
130
-
131
-
132
- async def resolve_java(jar_name: str, version: str = "") -> str:
133
- min_j = java_min_for_version(version or jar_name)
134
- try:
135
- return await ensure_java(min_j)
136
- except Exception:
137
- return "java"
138
-
139
-
140
- # ---------------------------------------------------------------------------
141
- # Paper (new fill.papermc.io API v3)
142
- # ---------------------------------------------------------------------------
143
-
144
- def paper_catalog() -> list:
145
- """List of {version, java} for all Paper versions."""
146
- with httpx.Client(timeout=20, follow_redirects=True) as c:
147
- r = c.get(f"{PAPER_API}/versions", headers=UA)
148
- r.raise_for_status()
149
- entries = r.json().get("versions", [])
150
- out = []
151
- for e in entries:
152
- v = e.get("version", {})
153
- vid = v.get("id", "")
154
- # keep only stable releases (drop -rc / -pre / -beta / -snapshot)
155
- if "-" in vid:
156
- continue
157
- jm = (v.get("java") or {}).get("version") or {}
158
- out.append({"version": vid, "java": jm.get("minimum")})
159
- return out
160
-
161
-
162
- def paper_latest_build(version: str) -> dict:
163
- with httpx.Client(timeout=20, follow_redirects=True) as c:
164
- r = c.get(f"{PAPER_API}/versions/{version}/builds", headers=UA)
165
- r.raise_for_status()
166
- builds = r.json()
167
- stable = [b for b in builds if b.get("channel") == "STABLE"] or builds
168
- b = stable[0]
169
- dl = (b.get("downloads") or {}).get("server:default", {})
170
- return {
171
- "build": b.get("id"),
172
- "name": dl.get("name") or f"paper-{version}-{b.get('id')}.jar",
173
- "url": dl.get("url"),
174
- "sha256": (dl.get("checksums") or {}).get("sha256"),
175
- "size": dl.get("size"),
176
- }
177
-
178
-
179
- # ---------------------------------------------------------------------------
180
- # Purpur (api.purpurmc.org — still active)
181
- # ---------------------------------------------------------------------------
182
-
183
- def purpur_versions() -> list:
184
- with httpx.Client(timeout=20, follow_redirects=True) as c:
185
- r = c.get(PURPUR_API, headers=UA)
186
- r.raise_for_status()
187
- return r.json().get("versions", [])
188
-
189
-
190
- def purpur_latest_build(version: str) -> dict:
191
- with httpx.Client(timeout=20, follow_redirects=True) as c:
192
- r = c.get(f"{PURPUR_API}/{version}", headers=UA)
193
- r.raise_for_status()
194
- latest = int(r.json().get("builds", {}).get("latest", "1"))
195
- return {
196
- "build": latest,
197
- "name": f"purpur-{version}-{latest}.jar",
198
- "url": f"{PURPUR_API}/{version}/{latest}/download",
199
- "sha256": None,
200
- "size": None,
201
- }
202
-
203
-
204
- # ---------------------------------------------------------------------------
205
- # Combined catalog for the UI
206
- # ---------------------------------------------------------------------------
207
-
208
- def all_versions() -> dict:
209
- paper = []
210
- purpur = []
211
- try:
212
- paper = paper_catalog()
213
- except Exception:
214
- paper = []
215
- try:
216
- purpur = [{"version": v, "java": java_min_for_version(v)} for v in purpur_versions()]
217
- except Exception:
218
- purpur = []
219
- # newest first, keeping the java requirement alongside
220
- p_sorted = sorted(paper, key=lambda x: x["version"], reverse=True)
221
- q_sorted = sorted(purpur, key=lambda x: x["version"], reverse=True)
222
- return {"paper": p_sorted, "purpur": q_sorted}
223
-
224
-
225
- def filename_for(provider: str, version: str, build) -> str:
226
- return f"{provider}-{version}.jar"
227
-
228
-
229
- # ---------------------------------------------------------------------------
230
- # Download
231
- # ---------------------------------------------------------------------------
232
-
233
- async def download_jar(url: str, dest: str) -> None:
234
- """Stream a jar to disk without buffering it all in RAM."""
235
- async with httpx.AsyncClient(follow_redirects=True, timeout=httpx.Timeout(900, connect=30)) as c:
236
- async with c.stream("GET", url, headers=UA) as r:
237
- r.raise_for_status()
238
- with open(dest, "wb") as f:
239
- async for chunk in r.aiter_bytes(256 * 1024):
240
- f.write(chunk)