-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathupdater.py
152 lines (138 loc) · 5.87 KB
/
updater.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
from pathlib import Path
import os, sys, shutil
import urllib.request
import hashlib
import zipfile, tempfile
import re
class WebConnection():
def __init__(self, url):
self.url = url
self.__access()
def __access(self):
self.response = urllib.request.urlopen(self.url)
def download_to(self, file):
file.write(self.response.read())
# Working update code for reference.
# def update_wrapper(branch="master"):
# repo = "bedrock-server-wrapper"
# url = f"https://github.com/TommyCox/{repo}/archive/{branch}.zip"
# types_to_update = (".py")
# destination_dir = Path.cwd()
# try:
# print(f"Connecting to {url}")
# files = WebConnection(url)
# with tempfile.TemporaryFile() as newfile:
# print("Downloading files.")
# files.download_to(newfile)
# #TODO: Do version checking, checksums, or whatever here.
# print("Unzipping archive...")
# with zipfile.ZipFile(newfile) as zipped:
# for zipinfo in zipped.infolist():
# if zipinfo.filename.endswith(types_to_update):
# print(f"Found file '{zipinfo.filename}'")
# prefix = f"{repo}-{branch}/"
# zipinfo.filename = zipinfo.filename.replace(prefix, "" , 1)
# print(f"Extracting as {zipinfo.filename}")
# zipped.extract(zipinfo, destination_dir)
# except urllib.error.HTTPError as http_error:
# print(f"HTTP Error: {http_error}")
# return False
# return True
class Updater():
def connect(self):
try:
return WebConnection(self.url)
except urllib.error.HTTPError as http_error:
print(f"HTTP Error: {http_error}")
return None
def unzip(self, downloaded_file):
with zipfile.ZipFile(downloaded_file) as zipped:
for zipinfo in zipped.infolist():
if self.extract_this(zipinfo):
zipped.extract(zipinfo, self.destination_dir)
# These are files to preserve when updating.
PROTECTED_SERVER_FILES = ["server.properties", "permissions.json", "whitelist.json"]
class ServerUpdater(Updater):
def __init__(self, server_dir = "minecraft_server", overwrite_all = False, locale = "en-us"):
self.destination_dir = Path(server_dir)
self.url = f"https://minecraft.net/{locale}/download/server/bedrock"
self.overwrite_all = overwrite_all
def extract_this(self, zipinfo):
# Check for special files that we don't want to overwrite.
if not self.overwrite_all:
if zipinfo.filename in PROTECTED_SERVER_FILES:
return not Path(self.destination_dir, zipinfo.filename).is_file()
return True
def update(self, force = False):
# Connect to minecraft.net
connection = self.connect()
if connection is None:
return False
platform = "win" if sys.platform == "win32" else "linux" if sys.platform == "linux" else None
assert platform, "Unsupported platform detected."
pattern = fR"https://minecraft\.azureedge\.net/bin-{platform}/bedrock-server-([\d\.]+)\.zip"
match = re.search(pattern, connection.response.read().decode())
if match:
print(f"Found download link:{match.group(0)}")
print(f"Version is: {match.group(1)}")
self.url = match.group(0)
new_version = match.group(1)
else:
return False
version_file_path = self.destination_dir / "server_version.txt"
if not force:
# Check version. Stop if already current.
try:
with open(version_file_path, "r") as ver_file:
version = ver_file.read()
if (version == new_version):
print(f"New Version ({new_version}) is the same as Current Version.")
return True
except FileNotFoundError:
pass
# Connect to download link.
connection = self.connect()
if connection is None:
print("Error connecting to download link.")
return False
# Download & extract files.
with tempfile.TemporaryFile() as newfile:
connection.download_to(newfile)
self.unzip(newfile)
with open(version_file_path, "w") as ver_file:
print("Writing new version number.")
ver_file.write(new_version)
# TODO: Support renaming executable if name was changed?
return True
class WrapperUpdater(Updater):
def __init__(self, branch = "master", repo = "bedrock-server-wrapper", user = "TommyCox"):
self.destination_dir = Path.cwd()
self.repo = repo
self.branch = branch
self.url = f"https://github.com/{user}/{repo}/archive/{branch}.zip"
self.types_to_update = (".py")
def extract_this(self, zipinfo):
# Make modifications to extraction.
prefix = f"{self.repo}-{self.branch}/"
zipinfo.filename = zipinfo.filename.replace(prefix, "" , 1)
# Return boolean for extraction conditions.
return zipinfo.filename.endswith(self.types_to_update)
def update(self):
connection = self.connect()
if connection is None:
return False
with tempfile.TemporaryFile() as newfile:
connection.download_to(newfile)
#TODO: Do version checking, checksums, or whatever here.
self.unzip(newfile)
# Erase pycache.
try:
shutil.rmtree(self.destination_dir / "__pycache__")
except FileNotFoundError as error:
print(f"Failed to remove pycache:\n\t{error}")
return True
if __name__ == "__main__":
print("Downloading wrapper!")
updater = WrapperUpdater(branch="dev-updater")
updater.update()
print("Download complete!")