calagoapi-version-changer 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- calagoapi_version_changer-1.0.0/PKG-INFO +91 -0
- calagoapi_version_changer-1.0.0/README.md +71 -0
- calagoapi_version_changer-1.0.0/calagoapi_version_changer/__init__.py +14 -0
- calagoapi_version_changer-1.0.0/calagoapi_version_changer/api.py +53 -0
- calagoapi_version_changer-1.0.0/calagoapi_version_changer/extension.py +204 -0
- calagoapi_version_changer-1.0.0/calagoapi_version_changer.egg-info/PKG-INFO +91 -0
- calagoapi_version_changer-1.0.0/calagoapi_version_changer.egg-info/SOURCES.txt +12 -0
- calagoapi_version_changer-1.0.0/calagoapi_version_changer.egg-info/dependency_links.txt +1 -0
- calagoapi_version_changer-1.0.0/calagoapi_version_changer.egg-info/entry_points.txt +2 -0
- calagoapi_version_changer-1.0.0/calagoapi_version_changer.egg-info/requires.txt +1 -0
- calagoapi_version_changer-1.0.0/calagoapi_version_changer.egg-info/top_level.txt +1 -0
- calagoapi_version_changer-1.0.0/pyproject.toml +52 -0
- calagoapi_version_changer-1.0.0/setup.cfg +4 -0
- calagoapi_version_changer-1.0.0/tests/test_version_changer.py +174 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: calagoapi-version-changer
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: CalagoAPI extension for the Calagopus Minecraft Version Changer: list and install Paper, Purpur, Fabric, Forge, ... builds.
|
|
5
|
+
Author: iFamished
|
|
6
|
+
License: GPL-3.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/HungerNet/CalagoAPI
|
|
8
|
+
Project-URL: Documentation, https://github.com/HungerNet/CalagoAPI/tree/main/docs/learning/first_party_extensions.md
|
|
9
|
+
Project-URL: Source, https://github.com/HungerNet/CalagoAPI/tree/main/src/extensions/calagoapi-version-changer
|
|
10
|
+
Keywords: calagopus,calagoapi,minecraft,version-changer,paper,fabric,extension
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Topic :: Games/Entertainment
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: calagoapi>=1.0.dev2
|
|
20
|
+
|
|
21
|
+
# calagoapi-version-changer
|
|
22
|
+
|
|
23
|
+
A [CalagoAPI](https://github.com/HungerNet/CalagoAPI) extension for the Calagopus
|
|
24
|
+
**Minecraft Version Changer** panel extension: list server types, versions and
|
|
25
|
+
builds, and install any Paper, Purpur, Fabric, Forge, ... build.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install calagoapi calagoapi-version-changer
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from calagoapi import Panel
|
|
33
|
+
from calagoapi.extensions import enable
|
|
34
|
+
|
|
35
|
+
enable('version_changer')
|
|
36
|
+
|
|
37
|
+
panel = Panel(url='https://panel.example.com', api_key='...')
|
|
38
|
+
server = panel.servers.getMinecraftServer('abc123')
|
|
39
|
+
|
|
40
|
+
print(server.installedVersion) # installed build, or None
|
|
41
|
+
builds = server.getBuilds('PAPER', '1.21.11', page=1, per_page=1)
|
|
42
|
+
server.installVersion(builds[0])
|
|
43
|
+
|
|
44
|
+
if server.isUpToDate() is False:
|
|
45
|
+
server.updateVersion() # newest build of the installed version
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
You never import this package yourself; `enable('version_changer')` finds it
|
|
49
|
+
through its entry point.
|
|
50
|
+
|
|
51
|
+
## What it adds
|
|
52
|
+
|
|
53
|
+
`MinecraftServer`:
|
|
54
|
+
|
|
55
|
+
| Member | Kind |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| `getInstalledVersion()` | method, `{'build': ..., 'latest': ...}` or None |
|
|
58
|
+
| `installedVersion` | property, the installed build or None |
|
|
59
|
+
| `isUpToDate()` | method |
|
|
60
|
+
| `getVersionTypes()` | method |
|
|
61
|
+
| `getVersions(type, search=None, page=None, per_page=None)` | method |
|
|
62
|
+
| `getBuilds(type, version, search=None, page=None, per_page=None)` | method |
|
|
63
|
+
| `installVersion(build, truncate_directory=False, accept_eula=True)` | method |
|
|
64
|
+
| `updateVersion(truncate_directory=False)` | method |
|
|
65
|
+
|
|
66
|
+
`panel.admin.extensions` (admin API key): `getVersionChangerSettings()`,
|
|
67
|
+
`updateVersionChangerSettings(**settings)`, `getVersionChangerStatistics()`,
|
|
68
|
+
`getVersionChangerDefaultOrder()`.
|
|
69
|
+
|
|
70
|
+
## Configuration
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
enable('version_changer', config={
|
|
74
|
+
'auto_backup': True, # back up before every installVersion()
|
|
75
|
+
'backup_name': 'Before version change',
|
|
76
|
+
'backup_timeout': 3600, # seconds to wait for that backup
|
|
77
|
+
})
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Namespace mode
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
enable('version_changer', mode='namespace')
|
|
84
|
+
server.version_changer.installVersion(build)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Compatibility
|
|
88
|
+
|
|
89
|
+
Before this package existed, these methods were built into `MinecraftServer`.
|
|
90
|
+
The built-in versions still work but emit an `ExtensionDeprecationWarning`;
|
|
91
|
+
enabling the extension replaces them.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# calagoapi-version-changer
|
|
2
|
+
|
|
3
|
+
A [CalagoAPI](https://github.com/HungerNet/CalagoAPI) extension for the Calagopus
|
|
4
|
+
**Minecraft Version Changer** panel extension: list server types, versions and
|
|
5
|
+
builds, and install any Paper, Purpur, Fabric, Forge, ... build.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install calagoapi calagoapi-version-changer
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
from calagoapi import Panel
|
|
13
|
+
from calagoapi.extensions import enable
|
|
14
|
+
|
|
15
|
+
enable('version_changer')
|
|
16
|
+
|
|
17
|
+
panel = Panel(url='https://panel.example.com', api_key='...')
|
|
18
|
+
server = panel.servers.getMinecraftServer('abc123')
|
|
19
|
+
|
|
20
|
+
print(server.installedVersion) # installed build, or None
|
|
21
|
+
builds = server.getBuilds('PAPER', '1.21.11', page=1, per_page=1)
|
|
22
|
+
server.installVersion(builds[0])
|
|
23
|
+
|
|
24
|
+
if server.isUpToDate() is False:
|
|
25
|
+
server.updateVersion() # newest build of the installed version
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
You never import this package yourself; `enable('version_changer')` finds it
|
|
29
|
+
through its entry point.
|
|
30
|
+
|
|
31
|
+
## What it adds
|
|
32
|
+
|
|
33
|
+
`MinecraftServer`:
|
|
34
|
+
|
|
35
|
+
| Member | Kind |
|
|
36
|
+
| --- | --- |
|
|
37
|
+
| `getInstalledVersion()` | method, `{'build': ..., 'latest': ...}` or None |
|
|
38
|
+
| `installedVersion` | property, the installed build or None |
|
|
39
|
+
| `isUpToDate()` | method |
|
|
40
|
+
| `getVersionTypes()` | method |
|
|
41
|
+
| `getVersions(type, search=None, page=None, per_page=None)` | method |
|
|
42
|
+
| `getBuilds(type, version, search=None, page=None, per_page=None)` | method |
|
|
43
|
+
| `installVersion(build, truncate_directory=False, accept_eula=True)` | method |
|
|
44
|
+
| `updateVersion(truncate_directory=False)` | method |
|
|
45
|
+
|
|
46
|
+
`panel.admin.extensions` (admin API key): `getVersionChangerSettings()`,
|
|
47
|
+
`updateVersionChangerSettings(**settings)`, `getVersionChangerStatistics()`,
|
|
48
|
+
`getVersionChangerDefaultOrder()`.
|
|
49
|
+
|
|
50
|
+
## Configuration
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
enable('version_changer', config={
|
|
54
|
+
'auto_backup': True, # back up before every installVersion()
|
|
55
|
+
'backup_name': 'Before version change',
|
|
56
|
+
'backup_timeout': 3600, # seconds to wait for that backup
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Namespace mode
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
enable('version_changer', mode='namespace')
|
|
64
|
+
server.version_changer.installVersion(build)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Compatibility
|
|
68
|
+
|
|
69
|
+
Before this package existed, these methods were built into `MinecraftServer`.
|
|
70
|
+
The built-in versions still work but emit an `ExtensionDeprecationWarning`;
|
|
71
|
+
enabling the extension replaces them.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'''
|
|
2
|
+
calagoapi-version-changer: the Calagopus Minecraft Version Changer for CalagoAPI.
|
|
3
|
+
|
|
4
|
+
You do not need to import this package. Install it and enable it by id:
|
|
5
|
+
|
|
6
|
+
from calagoapi.extensions import enable
|
|
7
|
+
enable('version_changer')
|
|
8
|
+
'''
|
|
9
|
+
from importlib.metadata import version as _pkg_version, PackageNotFoundError
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
__version__ = _pkg_version('calagoapi-version-changer')
|
|
13
|
+
except PackageNotFoundError:
|
|
14
|
+
__version__ = '0.0.0'
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from calagoapi.api.client import segment
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# Calagopus Minecraft Version Changer panel extension (dev.0x7d8.minecraftversionchanger)
|
|
5
|
+
PANEL_EXTENSION = 'dev.0x7d8.minecraftversionchanger'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class VersionChangerAPI:
|
|
9
|
+
'''
|
|
10
|
+
HTTP calls of the Calagopus Minecraft Version Changer. Uses the panel's client,
|
|
11
|
+
so authentication, retries and errors behave like the rest of CalagoAPI.
|
|
12
|
+
'''
|
|
13
|
+
def __init__(self, client):
|
|
14
|
+
self.client = client
|
|
15
|
+
|
|
16
|
+
def _path(self, server_id, suffix=''):
|
|
17
|
+
return f'/api/client/servers/{server_id}/minecraft/versions{suffix}'
|
|
18
|
+
|
|
19
|
+
# client endpoints
|
|
20
|
+
def installed(self, server_id):
|
|
21
|
+
return self.client.get(self._path(server_id, '/installed'))['build']
|
|
22
|
+
|
|
23
|
+
def types(self, server_id):
|
|
24
|
+
return self.client.get(self._path(server_id, '/types'))['types']
|
|
25
|
+
|
|
26
|
+
def versions(self, server_id, type, search=None, page=None, per_page=None):
|
|
27
|
+
return self.client.list(self._path(server_id, f'/types/{segment(type)}'), 'versions', {'search': search}, page, per_page)
|
|
28
|
+
|
|
29
|
+
def builds(self, server_id, type, version, search=None, page=None, per_page=None):
|
|
30
|
+
return self.client.list(self._path(server_id, f'/types/{segment(type)}/{segment(version)}'), 'builds', {'search': search}, page, per_page)
|
|
31
|
+
|
|
32
|
+
def install(self, server_id, build_uuid, truncate_directory=False, accept_eula=True):
|
|
33
|
+
return self.client.post(self._path(server_id, '/install'), json={
|
|
34
|
+
'build_uuid': build_uuid,
|
|
35
|
+
'truncate_directory': truncate_directory,
|
|
36
|
+
'accept_eula': accept_eula,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
# admin endpoints
|
|
40
|
+
def _admin(self, suffix, method='GET', json=None):
|
|
41
|
+
return self.client.request(method, f'/api/admin/extensions/{PANEL_EXTENSION}/{suffix}', json=json)
|
|
42
|
+
|
|
43
|
+
def settings(self):
|
|
44
|
+
return self._admin('settings')['settings']
|
|
45
|
+
|
|
46
|
+
def updateSettings(self, settings):
|
|
47
|
+
return self._admin('settings', 'PUT', json=settings)
|
|
48
|
+
|
|
49
|
+
def statistics(self):
|
|
50
|
+
return self._admin('statistics/total')
|
|
51
|
+
|
|
52
|
+
def defaultOrder(self):
|
|
53
|
+
return self._admin('default-order')['mcjars_type_order']
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
'''
|
|
2
|
+
The Calagopus Minecraft Version Changer as a CalagoAPI extension.
|
|
3
|
+
|
|
4
|
+
from calagoapi.extensions import enable
|
|
5
|
+
|
|
6
|
+
enable('version_changer')
|
|
7
|
+
build = server.getBuilds('PAPER', '1.21.11', page=1, per_page=1)[0]
|
|
8
|
+
server.installVersion(build)
|
|
9
|
+
print(server.installedVersion['name'])
|
|
10
|
+
'''
|
|
11
|
+
from calagoapi import MinecraftServer
|
|
12
|
+
from calagoapi.admin.admin import ExtensionManager
|
|
13
|
+
from calagoapi.extensions import (
|
|
14
|
+
ConfigurationError,
|
|
15
|
+
Extension,
|
|
16
|
+
ExtensionMetadata,
|
|
17
|
+
method,
|
|
18
|
+
property_extension,
|
|
19
|
+
)
|
|
20
|
+
from calagoapi.utils.exceptions import InvalidActionError
|
|
21
|
+
from calagoapi.utils.model import idOf
|
|
22
|
+
|
|
23
|
+
from calagoapi_version_changer import __version__
|
|
24
|
+
from calagoapi_version_changer.api import VersionChangerAPI
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _api(obj) -> VersionChangerAPI:
|
|
28
|
+
return VersionChangerAPI(obj.panel.client)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# MinecraftServer methods
|
|
32
|
+
@method(MinecraftServer)
|
|
33
|
+
def getInstalledVersion(self) -> dict:
|
|
34
|
+
'''
|
|
35
|
+
Returns what the Version Changer knows about the installed build:
|
|
36
|
+
`{'build': {...}, 'latest': {...}}`, or None if the server was not installed with it.
|
|
37
|
+
|
|
38
|
+
Example:
|
|
39
|
+
info = server.getInstalledVersion()
|
|
40
|
+
if info:
|
|
41
|
+
print(info['build']['name'], 'latest:', info['latest']['name'])
|
|
42
|
+
'''
|
|
43
|
+
return _api(self).installed(self.server_id)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@property_extension(MinecraftServer)
|
|
47
|
+
def installedVersion(self) -> dict:
|
|
48
|
+
'''
|
|
49
|
+
The installed build (type, name, version_id, ...), or None. Makes a request each
|
|
50
|
+
time it is read; in async code prefer `await server.getInstalledVersion()`.
|
|
51
|
+
|
|
52
|
+
Example:
|
|
53
|
+
print(server.installedVersion['name'])
|
|
54
|
+
'''
|
|
55
|
+
installed = getInstalledVersion(self)
|
|
56
|
+
return installed.get('build') if installed else None
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@method(MinecraftServer)
|
|
60
|
+
def isUpToDate(self) -> bool:
|
|
61
|
+
'''
|
|
62
|
+
Returns True if the installed build is the newest build of its version, None if unknown.
|
|
63
|
+
|
|
64
|
+
Example:
|
|
65
|
+
if server.isUpToDate() is False:
|
|
66
|
+
server.updateVersion()
|
|
67
|
+
'''
|
|
68
|
+
installed = getInstalledVersion(self)
|
|
69
|
+
if not installed or not installed.get('build') or not installed.get('latest'):
|
|
70
|
+
return None
|
|
71
|
+
return installed['build'].get('uuid') == installed['latest'].get('uuid')
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@method(MinecraftServer)
|
|
75
|
+
def getVersionTypes(self) -> dict:
|
|
76
|
+
'''Returns the available server types (PAPER, PURPUR, FABRIC, VANILLA, ...).'''
|
|
77
|
+
return _api(self).types(self.server_id)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@method(MinecraftServer)
|
|
81
|
+
def getVersions(self, type: str, search: str = None, page: int = None, per_page: int = None):
|
|
82
|
+
'''
|
|
83
|
+
Returns the Minecraft versions available for a server type.
|
|
84
|
+
|
|
85
|
+
Example:
|
|
86
|
+
server.getVersions('PAPER', page=1, per_page=10)
|
|
87
|
+
'''
|
|
88
|
+
return _api(self).versions(self.server_id, type, search, page, per_page)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@method(MinecraftServer)
|
|
92
|
+
def getBuilds(self, type: str, version: str, search: str = None, page: int = None, per_page: int = None):
|
|
93
|
+
'''
|
|
94
|
+
Returns the builds of a version, newest first.
|
|
95
|
+
|
|
96
|
+
Example:
|
|
97
|
+
latest = server.getBuilds('PAPER', '1.21.11', page=1, per_page=1)[0]
|
|
98
|
+
'''
|
|
99
|
+
return _api(self).builds(self.server_id, type, version, search, page, per_page)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@method(MinecraftServer)
|
|
103
|
+
def installVersion(self, build, truncate_directory: bool = False, accept_eula: bool = True) -> None:
|
|
104
|
+
'''
|
|
105
|
+
Installs a server build.
|
|
106
|
+
|
|
107
|
+
With `auto_backup` enabled in the extension config, a backup is made first and
|
|
108
|
+
the install only starts once it succeeded.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
build: Build dict from getBuilds() or build UUID.
|
|
112
|
+
truncate_directory: Delete every file first.
|
|
113
|
+
accept_eula: Accept the Minecraft EULA.
|
|
114
|
+
|
|
115
|
+
Example:
|
|
116
|
+
latest = server.getBuilds('PAPER', '1.21.11', page=1, per_page=1)[0]
|
|
117
|
+
server.installVersion(latest)
|
|
118
|
+
'''
|
|
119
|
+
config = VersionChangerExtension.get().config
|
|
120
|
+
build_id = build.get('uuid') if isinstance(build, dict) else idOf(build)
|
|
121
|
+
if config['auto_backup']:
|
|
122
|
+
backup = self.backups.createBackup(name=config['backup_name'])
|
|
123
|
+
backup.waitUntilComplete(timeout=config['backup_timeout'])
|
|
124
|
+
if not backup.isSuccessful():
|
|
125
|
+
raise InvalidActionError(f'The backup before installing {build_id} failed; nothing was installed.')
|
|
126
|
+
return _api(self).install(self.server_id, build_id, truncate_directory, accept_eula)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@method(MinecraftServer)
|
|
130
|
+
def updateVersion(self, truncate_directory: bool = False) -> bool:
|
|
131
|
+
'''
|
|
132
|
+
Installs the newest build of the installed version. Returns False if already up to date.
|
|
133
|
+
|
|
134
|
+
Example:
|
|
135
|
+
server.updateVersion()
|
|
136
|
+
'''
|
|
137
|
+
# sibling members are called directly so this works in direct and namespace mode
|
|
138
|
+
installed = getInstalledVersion(self)
|
|
139
|
+
if not installed or not installed.get('latest'):
|
|
140
|
+
raise InvalidActionError('The installed version is unknown, use installVersion() instead.')
|
|
141
|
+
if isUpToDate(self):
|
|
142
|
+
return False
|
|
143
|
+
installVersion(self, installed['latest'], truncate_directory=truncate_directory)
|
|
144
|
+
return True
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
# panel.admin.extensions methods (admin API key required)
|
|
148
|
+
@method(ExtensionManager)
|
|
149
|
+
def getVersionChangerSettings(self) -> dict:
|
|
150
|
+
'''Returns the Minecraft Version Changer settings.'''
|
|
151
|
+
return _api(self).settings()
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@method(ExtensionManager)
|
|
155
|
+
def updateVersionChangerSettings(self, **settings) -> None:
|
|
156
|
+
'''Changes Version Changer settings (mcjars_url, mcjars_api_key, type_egg_assignments, ...).'''
|
|
157
|
+
return _api(self).updateSettings(settings)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@method(ExtensionManager)
|
|
161
|
+
def getVersionChangerStatistics(self) -> dict:
|
|
162
|
+
'''Returns install statistics by server type and version.'''
|
|
163
|
+
return _api(self).statistics()
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@method(ExtensionManager)
|
|
167
|
+
def getVersionChangerDefaultOrder(self) -> list:
|
|
168
|
+
'''Returns the default order of server types in the version picker.'''
|
|
169
|
+
return _api(self).defaultOrder()
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class VersionChangerExtension(Extension):
|
|
173
|
+
'''
|
|
174
|
+
Calagopus Minecraft Version Changer: list and install Paper, Purpur, Fabric,
|
|
175
|
+
Forge, ... builds on Minecraft servers.
|
|
176
|
+
|
|
177
|
+
Config:
|
|
178
|
+
auto_backup: Make a backup before every installVersion() (default False).
|
|
179
|
+
backup_name: Name of that backup.
|
|
180
|
+
backup_timeout: Seconds to wait for the backup.
|
|
181
|
+
'''
|
|
182
|
+
extension_id = 'version_changer'
|
|
183
|
+
aliases = ['minecraft_version_changer']
|
|
184
|
+
metadata = ExtensionMetadata(
|
|
185
|
+
author='iFamished',
|
|
186
|
+
version=__version__,
|
|
187
|
+
schema=1,
|
|
188
|
+
description='Calagopus Minecraft Version Changer for CalagoAPI',
|
|
189
|
+
package='calagoapi-version-changer',
|
|
190
|
+
homepage='https://github.com/HungerNet/CalagoAPI',
|
|
191
|
+
)
|
|
192
|
+
default_mode = 'direct'
|
|
193
|
+
default_config = {
|
|
194
|
+
'auto_backup': False,
|
|
195
|
+
'backup_name': 'Before version change',
|
|
196
|
+
'backup_timeout': 3600,
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
def validate_config(self, config):
|
|
200
|
+
if not isinstance(config['auto_backup'], bool):
|
|
201
|
+
raise ConfigurationError('version_changer: auto_backup must be True or False')
|
|
202
|
+
if not isinstance(config['backup_timeout'], (int, float)) or config['backup_timeout'] <= 0:
|
|
203
|
+
raise ConfigurationError('version_changer: backup_timeout must be a positive number of seconds')
|
|
204
|
+
return config
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: calagoapi-version-changer
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: CalagoAPI extension for the Calagopus Minecraft Version Changer: list and install Paper, Purpur, Fabric, Forge, ... builds.
|
|
5
|
+
Author: iFamished
|
|
6
|
+
License: GPL-3.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/HungerNet/CalagoAPI
|
|
8
|
+
Project-URL: Documentation, https://github.com/HungerNet/CalagoAPI/tree/main/docs/learning/first_party_extensions.md
|
|
9
|
+
Project-URL: Source, https://github.com/HungerNet/CalagoAPI/tree/main/src/extensions/calagoapi-version-changer
|
|
10
|
+
Keywords: calagopus,calagoapi,minecraft,version-changer,paper,fabric,extension
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Topic :: Games/Entertainment
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: calagoapi>=1.0.dev2
|
|
20
|
+
|
|
21
|
+
# calagoapi-version-changer
|
|
22
|
+
|
|
23
|
+
A [CalagoAPI](https://github.com/HungerNet/CalagoAPI) extension for the Calagopus
|
|
24
|
+
**Minecraft Version Changer** panel extension: list server types, versions and
|
|
25
|
+
builds, and install any Paper, Purpur, Fabric, Forge, ... build.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install calagoapi calagoapi-version-changer
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from calagoapi import Panel
|
|
33
|
+
from calagoapi.extensions import enable
|
|
34
|
+
|
|
35
|
+
enable('version_changer')
|
|
36
|
+
|
|
37
|
+
panel = Panel(url='https://panel.example.com', api_key='...')
|
|
38
|
+
server = panel.servers.getMinecraftServer('abc123')
|
|
39
|
+
|
|
40
|
+
print(server.installedVersion) # installed build, or None
|
|
41
|
+
builds = server.getBuilds('PAPER', '1.21.11', page=1, per_page=1)
|
|
42
|
+
server.installVersion(builds[0])
|
|
43
|
+
|
|
44
|
+
if server.isUpToDate() is False:
|
|
45
|
+
server.updateVersion() # newest build of the installed version
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
You never import this package yourself; `enable('version_changer')` finds it
|
|
49
|
+
through its entry point.
|
|
50
|
+
|
|
51
|
+
## What it adds
|
|
52
|
+
|
|
53
|
+
`MinecraftServer`:
|
|
54
|
+
|
|
55
|
+
| Member | Kind |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| `getInstalledVersion()` | method, `{'build': ..., 'latest': ...}` or None |
|
|
58
|
+
| `installedVersion` | property, the installed build or None |
|
|
59
|
+
| `isUpToDate()` | method |
|
|
60
|
+
| `getVersionTypes()` | method |
|
|
61
|
+
| `getVersions(type, search=None, page=None, per_page=None)` | method |
|
|
62
|
+
| `getBuilds(type, version, search=None, page=None, per_page=None)` | method |
|
|
63
|
+
| `installVersion(build, truncate_directory=False, accept_eula=True)` | method |
|
|
64
|
+
| `updateVersion(truncate_directory=False)` | method |
|
|
65
|
+
|
|
66
|
+
`panel.admin.extensions` (admin API key): `getVersionChangerSettings()`,
|
|
67
|
+
`updateVersionChangerSettings(**settings)`, `getVersionChangerStatistics()`,
|
|
68
|
+
`getVersionChangerDefaultOrder()`.
|
|
69
|
+
|
|
70
|
+
## Configuration
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
enable('version_changer', config={
|
|
74
|
+
'auto_backup': True, # back up before every installVersion()
|
|
75
|
+
'backup_name': 'Before version change',
|
|
76
|
+
'backup_timeout': 3600, # seconds to wait for that backup
|
|
77
|
+
})
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Namespace mode
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
enable('version_changer', mode='namespace')
|
|
84
|
+
server.version_changer.installVersion(build)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Compatibility
|
|
88
|
+
|
|
89
|
+
Before this package existed, these methods were built into `MinecraftServer`.
|
|
90
|
+
The built-in versions still work but emit an `ExtensionDeprecationWarning`;
|
|
91
|
+
enabling the extension replaces them.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
calagoapi_version_changer/__init__.py
|
|
4
|
+
calagoapi_version_changer/api.py
|
|
5
|
+
calagoapi_version_changer/extension.py
|
|
6
|
+
calagoapi_version_changer.egg-info/PKG-INFO
|
|
7
|
+
calagoapi_version_changer.egg-info/SOURCES.txt
|
|
8
|
+
calagoapi_version_changer.egg-info/dependency_links.txt
|
|
9
|
+
calagoapi_version_changer.egg-info/entry_points.txt
|
|
10
|
+
calagoapi_version_changer.egg-info/requires.txt
|
|
11
|
+
calagoapi_version_changer.egg-info/top_level.txt
|
|
12
|
+
tests/test_version_changer.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
calagoapi>=1.0.dev2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
calagoapi_version_changer
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = [
|
|
3
|
+
"setuptools>=69",
|
|
4
|
+
"wheel",
|
|
5
|
+
]
|
|
6
|
+
build-backend = "setuptools.build_meta"
|
|
7
|
+
|
|
8
|
+
[project]
|
|
9
|
+
name = "calagoapi-version-changer"
|
|
10
|
+
version = "1.0.0"
|
|
11
|
+
description = "CalagoAPI extension for the Calagopus Minecraft Version Changer: list and install Paper, Purpur, Fabric, Forge, ... builds."
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.9"
|
|
14
|
+
authors = [
|
|
15
|
+
{ name = "iFamished" },
|
|
16
|
+
]
|
|
17
|
+
keywords = [
|
|
18
|
+
"calagopus",
|
|
19
|
+
"calagoapi",
|
|
20
|
+
"minecraft",
|
|
21
|
+
"version-changer",
|
|
22
|
+
"paper",
|
|
23
|
+
"fabric",
|
|
24
|
+
"extension",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"calagoapi>=1.0.dev2",
|
|
28
|
+
]
|
|
29
|
+
classifiers = [
|
|
30
|
+
"Programming Language :: Python :: 3",
|
|
31
|
+
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
|
32
|
+
"Operating System :: OS Independent",
|
|
33
|
+
"Development Status :: 4 - Beta",
|
|
34
|
+
"Intended Audience :: Developers",
|
|
35
|
+
"Topic :: Games/Entertainment",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[project.license]
|
|
39
|
+
text = "GPL-3.0"
|
|
40
|
+
|
|
41
|
+
[project.urls]
|
|
42
|
+
Homepage = "https://github.com/HungerNet/CalagoAPI"
|
|
43
|
+
Documentation = "https://github.com/HungerNet/CalagoAPI/tree/main/docs/learning/first_party_extensions.md"
|
|
44
|
+
Source = "https://github.com/HungerNet/CalagoAPI/tree/main/src/extensions/calagoapi-version-changer"
|
|
45
|
+
|
|
46
|
+
[project.entry-points.calagoapi]
|
|
47
|
+
version_changer = "calagoapi_version_changer.extension:VersionChangerExtension"
|
|
48
|
+
|
|
49
|
+
[tool.setuptools]
|
|
50
|
+
packages = [
|
|
51
|
+
"calagoapi_version_changer",
|
|
52
|
+
]
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import importlib.metadata
|
|
3
|
+
import warnings
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from calagoapi import AsyncPanel, MinecraftServer
|
|
8
|
+
from calagoapi.admin.admin import ExtensionManager
|
|
9
|
+
from calagoapi.extensions import ExtensionDeprecationWarning, ExtensionNamespace
|
|
10
|
+
|
|
11
|
+
from calagoapi_version_changer.extension import VersionChangerExtension, installVersion
|
|
12
|
+
from contract import BASE, UUID
|
|
13
|
+
|
|
14
|
+
VERSION_ENDPOINTS = {
|
|
15
|
+
('GET', '/api/client/servers/{server}/minecraft/versions/installed'),
|
|
16
|
+
('GET', '/api/client/servers/{server}/minecraft/versions/types'),
|
|
17
|
+
('GET', '/api/client/servers/{server}/minecraft/versions/types/{type}'),
|
|
18
|
+
('GET', '/api/client/servers/{server}/minecraft/versions/types/{type}/{version}'),
|
|
19
|
+
('POST', '/api/client/servers/{server}/minecraft/versions/install'),
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
ADMIN_ENDPOINTS = {
|
|
23
|
+
('GET', '/api/admin/extensions/dev.0x7d8.minecraftversionchanger/settings'),
|
|
24
|
+
('PUT', '/api/admin/extensions/dev.0x7d8.minecraftversionchanger/settings'),
|
|
25
|
+
('GET', '/api/admin/extensions/dev.0x7d8.minecraftversionchanger/statistics/total'),
|
|
26
|
+
('GET', '/api/admin/extensions/dev.0x7d8.minecraftversionchanger/default-order'),
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_builtins_are_deprecated_until_enabled(panel, fake, extensions):
|
|
31
|
+
server = panel.servers.getMinecraftServer(UUID)
|
|
32
|
+
with pytest.warns(ExtensionDeprecationWarning, match='calagoapi-version-changer'):
|
|
33
|
+
server.installVersion({'uuid': UUID})
|
|
34
|
+
|
|
35
|
+
extensions.register(VersionChangerExtension)
|
|
36
|
+
extensions.enable('version_changer')
|
|
37
|
+
|
|
38
|
+
# the object created before enable() now uses the extension, without warnings
|
|
39
|
+
assert MinecraftServer.installVersion is installVersion
|
|
40
|
+
with warnings.catch_warnings():
|
|
41
|
+
warnings.simplefilter('error')
|
|
42
|
+
server.installVersion({'uuid': UUID})
|
|
43
|
+
assert extensions.owner_of(MinecraftServer, 'installVersion') == 'version_changer'
|
|
44
|
+
replaced = [r for r in extensions.registrations(owner='version_changer') if r.replaced is not None]
|
|
45
|
+
assert {r.name for r in replaced} == {
|
|
46
|
+
'getInstalledVersion', 'getVersionTypes', 'getVersions', 'getBuilds', 'installVersion',
|
|
47
|
+
'getVersionChangerSettings', 'updateVersionChangerSettings', 'getVersionChangerStatistics',
|
|
48
|
+
'getVersionChangerDefaultOrder',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_every_endpoint_matches_the_spec(panel, fake, extensions):
|
|
53
|
+
extensions.register(VersionChangerExtension)
|
|
54
|
+
extensions.enable('version_changer')
|
|
55
|
+
server = panel.servers.getMinecraftServer(UUID)
|
|
56
|
+
|
|
57
|
+
with warnings.catch_warnings():
|
|
58
|
+
warnings.simplefilter('error', ExtensionDeprecationWarning)
|
|
59
|
+
assert isinstance(server.getInstalledVersion(), dict)
|
|
60
|
+
assert server.installedVersion['uuid'] == UUID
|
|
61
|
+
assert server.isUpToDate() is True
|
|
62
|
+
assert server.updateVersion() is False
|
|
63
|
+
server.getVersionTypes()
|
|
64
|
+
server.getVersions('PAPER', page=1, per_page=5)
|
|
65
|
+
builds = server.getBuilds('PAPER', '1.21.11', page=1, per_page=1)
|
|
66
|
+
server.installVersion(builds[0], truncate_directory=True)
|
|
67
|
+
server.installVersion(UUID)
|
|
68
|
+
|
|
69
|
+
admin = panel.admin.extensions
|
|
70
|
+
admin.getVersionChangerSettings()
|
|
71
|
+
admin.updateVersionChangerSettings(mcjars_url='https://mcjars.app')
|
|
72
|
+
admin.getVersionChangerStatistics()
|
|
73
|
+
admin.getVersionChangerDefaultOrder()
|
|
74
|
+
|
|
75
|
+
assert not fake.violations, '\n'.join(fake.violations)
|
|
76
|
+
assert VERSION_ENDPOINTS | ADMIN_ENDPOINTS <= fake.hit
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def test_auto_backup(panel, fake, extensions, monkeypatch):
|
|
80
|
+
from calagoapi.backups.backup import Backup
|
|
81
|
+
monkeypatch.setattr(Backup, 'waitUntilComplete', lambda self, timeout=3600, interval=5: self)
|
|
82
|
+
monkeypatch.setattr(Backup, 'isSuccessful', lambda self: True)
|
|
83
|
+
|
|
84
|
+
extensions.register(VersionChangerExtension)
|
|
85
|
+
extensions.enable('version_changer', config={'auto_backup': True, 'backup_name': 'pre-update'})
|
|
86
|
+
server = panel.servers.getMinecraftServer(UUID)
|
|
87
|
+
server.installVersion(UUID)
|
|
88
|
+
assert ('POST', '/api/client/servers/{server}/backups') in fake.hit
|
|
89
|
+
assert ('POST', '/api/client/servers/{server}/minecraft/versions/install') in fake.hit
|
|
90
|
+
assert not fake.violations
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_failed_backup_prevents_install(panel, fake, extensions, monkeypatch):
|
|
94
|
+
from calagoapi import InvalidActionError
|
|
95
|
+
from calagoapi.backups.backup import Backup
|
|
96
|
+
monkeypatch.setattr(Backup, 'waitUntilComplete', lambda self, timeout=3600, interval=5: self)
|
|
97
|
+
monkeypatch.setattr(Backup, 'isSuccessful', lambda self: False)
|
|
98
|
+
|
|
99
|
+
extensions.register(VersionChangerExtension)
|
|
100
|
+
extensions.enable('version_changer', config={'auto_backup': True})
|
|
101
|
+
with pytest.raises(InvalidActionError, match='nothing was installed'):
|
|
102
|
+
panel.servers.getMinecraftServer(UUID).installVersion(UUID)
|
|
103
|
+
assert ('POST', '/api/client/servers/{server}/minecraft/versions/install') not in fake.hit
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def test_namespace_mode_keeps_builtins(panel, fake, extensions):
|
|
107
|
+
extensions.register(VersionChangerExtension)
|
|
108
|
+
extensions.enable('version_changer', mode='namespace')
|
|
109
|
+
server = panel.servers.getMinecraftServer(UUID)
|
|
110
|
+
|
|
111
|
+
assert isinstance(server.version_changer, ExtensionNamespace)
|
|
112
|
+
with warnings.catch_warnings():
|
|
113
|
+
warnings.simplefilter('error')
|
|
114
|
+
server.version_changer.installVersion(UUID)
|
|
115
|
+
assert server.version_changer.installedVersion['uuid'] == UUID
|
|
116
|
+
panel.admin.extensions.version_changer.getVersionChangerStatistics()
|
|
117
|
+
# the deprecated built-in is untouched in namespace mode
|
|
118
|
+
with pytest.warns(ExtensionDeprecationWarning):
|
|
119
|
+
server.installVersion(UUID)
|
|
120
|
+
assert not fake.violations
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def test_invalid_config(extensions):
|
|
124
|
+
from calagoapi.extensions import ConfigurationError
|
|
125
|
+
extensions.register(VersionChangerExtension)
|
|
126
|
+
with pytest.raises(ConfigurationError, match='auto_backup'):
|
|
127
|
+
extensions.enable('version_changer', config={'auto_backup': 'yes'})
|
|
128
|
+
with pytest.raises(ConfigurationError, match='Unknown config'):
|
|
129
|
+
extensions.enable('version_changer', config={'autobackup': True})
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def test_alias(extensions):
|
|
133
|
+
extensions.register(VersionChangerExtension)
|
|
134
|
+
assert extensions.enable('minecraft_version_changer') is extensions.get('version_changer')
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def test_async(fake, extensions):
|
|
138
|
+
extensions.register(VersionChangerExtension)
|
|
139
|
+
extensions.enable('version_changer')
|
|
140
|
+
|
|
141
|
+
async def main():
|
|
142
|
+
async with AsyncPanel(url=BASE, api_key='c7sp_test') as panel:
|
|
143
|
+
server = await panel.servers.getMinecraftServer(UUID)
|
|
144
|
+
with warnings.catch_warnings():
|
|
145
|
+
warnings.simplefilter('error', ExtensionDeprecationWarning)
|
|
146
|
+
await server.installVersion({'uuid': UUID})
|
|
147
|
+
builds = await server.getBuilds('PAPER', '1.21.11', page=1, per_page=1)
|
|
148
|
+
assert builds[0]['uuid'] == UUID
|
|
149
|
+
assert (await server.getInstalledVersion())['build']['uuid'] == UUID
|
|
150
|
+
|
|
151
|
+
fake.reset()
|
|
152
|
+
asyncio.run(main())
|
|
153
|
+
assert not fake.violations
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def test_reset_restores_builtins(extensions):
|
|
157
|
+
builtin = MinecraftServer.__dict__['installVersion']
|
|
158
|
+
extensions.register(VersionChangerExtension)
|
|
159
|
+
extensions.enable('version_changer')
|
|
160
|
+
assert MinecraftServer.__dict__['installVersion'] is installVersion
|
|
161
|
+
assert ExtensionManager.__dict__['getVersionChangerSettings'].__module__ == 'calagoapi_version_changer.extension'
|
|
162
|
+
extensions._reset_for_tests()
|
|
163
|
+
assert MinecraftServer.__dict__['installVersion'] is builtin
|
|
164
|
+
assert 'installedVersion' not in MinecraftServer.__dict__
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def test_entry_point_is_published():
|
|
168
|
+
try:
|
|
169
|
+
importlib.metadata.distribution('calagoapi-version-changer')
|
|
170
|
+
except importlib.metadata.PackageNotFoundError:
|
|
171
|
+
pytest.skip('calagoapi-version-changer is not pip-installed')
|
|
172
|
+
from calagoapi.extensions import ExtensionRegistry
|
|
173
|
+
registry = ExtensionRegistry()
|
|
174
|
+
assert registry.get_class('version_changer') is VersionChangerExtension
|