calagoapi 1.0.dev1__py3-none-any.whl
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/__init__.py +190 -0
- calagoapi/account/__init__.py +14 -0
- calagoapi/account/account.py +292 -0
- calagoapi/account/auth.py +72 -0
- calagoapi/account/models.py +221 -0
- calagoapi/admin/__init__.py +48 -0
- calagoapi/admin/admin.py +341 -0
- calagoapi/admin/managers.py +490 -0
- calagoapi/admin/resources.py +970 -0
- calagoapi/aio/__init__.py +9 -0
- calagoapi/aio/console.py +289 -0
- calagoapi/aio/panel.py +176 -0
- calagoapi/api/__init__.py +63 -0
- calagoapi/api/account.py +195 -0
- calagoapi/api/admin.py +402 -0
- calagoapi/api/attachments.py +27 -0
- calagoapi/api/auth.py +52 -0
- calagoapi/api/backups.py +99 -0
- calagoapi/api/client.py +198 -0
- calagoapi/api/databases.py +217 -0
- calagoapi/api/files.py +210 -0
- calagoapi/api/network.py +84 -0
- calagoapi/api/public.py +13 -0
- calagoapi/api/schedules.py +79 -0
- calagoapi/api/servers.py +114 -0
- calagoapi/api/users.py +27 -0
- calagoapi/api/versions.py +29 -0
- calagoapi/backups/__init__.py +8 -0
- calagoapi/backups/backup.py +292 -0
- calagoapi/backups/manager.py +177 -0
- calagoapi/console/__init__.py +6 -0
- calagoapi/console/console.py +392 -0
- calagoapi/databases/__init__.py +12 -0
- calagoapi/databases/database.py +445 -0
- calagoapi/databases/explorer.py +159 -0
- calagoapi/databases/manager.py +122 -0
- calagoapi/files/__init__.py +9 -0
- calagoapi/files/file.py +196 -0
- calagoapi/files/manager.py +437 -0
- calagoapi/network/__init__.py +8 -0
- calagoapi/network/allocation.py +99 -0
- calagoapi/network/manager.py +132 -0
- calagoapi/nodes/__init__.py +6 -0
- calagoapi/nodes/node.py +477 -0
- calagoapi/panel.py +162 -0
- calagoapi/schedules/__init__.py +14 -0
- calagoapi/schedules/builders.py +461 -0
- calagoapi/schedules/manager.py +107 -0
- calagoapi/schedules/schedule.py +214 -0
- calagoapi/servers/__init__.py +13 -0
- calagoapi/servers/admin.py +430 -0
- calagoapi/servers/generic.py +785 -0
- calagoapi/servers/manager.py +167 -0
- calagoapi/servers/minecraft.py +207 -0
- calagoapi/tunnels/__init__.py +5 -0
- calagoapi/tunnels/tunnel.py +112 -0
- calagoapi/users/__init__.py +11 -0
- calagoapi/users/activity.py +45 -0
- calagoapi/users/subuser.py +127 -0
- calagoapi/users/user.py +267 -0
- calagoapi/utils/__init__.py +43 -0
- calagoapi/utils/convert.py +113 -0
- calagoapi/utils/exceptions.py +72 -0
- calagoapi/utils/model.py +142 -0
- calagoapi/utils/resource.py +100 -0
- calagoapi/utils/time.py +68 -0
- calagoapi-1.0.dev1.dist-info/METADATA +266 -0
- calagoapi-1.0.dev1.dist-info/RECORD +71 -0
- calagoapi-1.0.dev1.dist-info/WHEEL +5 -0
- calagoapi-1.0.dev1.dist-info/licenses/LICENSE +674 -0
- calagoapi-1.0.dev1.dist-info/top_level.txt +1 -0
calagoapi/api/files.py
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
|
|
3
|
+
from calagoapi.utils.model import Page
|
|
4
|
+
from calagoapi.utils.exceptions import PanelConnectionError
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Internal Calagopus FilesAPI
|
|
8
|
+
class FilesAPI:
|
|
9
|
+
def __init__(self, client):
|
|
10
|
+
self.client = client
|
|
11
|
+
|
|
12
|
+
def _path(self, server_id, action):
|
|
13
|
+
return f'/api/client/servers/{server_id}/files/{action}'
|
|
14
|
+
|
|
15
|
+
# browsing
|
|
16
|
+
def list(self, server_id, directory='/', sort=None, page=None, per_page=None):
|
|
17
|
+
params = {'directory': directory, 'sort': sort}
|
|
18
|
+
if page is not None:
|
|
19
|
+
params.update(page=page, per_page=per_page or 100)
|
|
20
|
+
result = self.client.get(self._path(server_id, 'list'), params=params)
|
|
21
|
+
entries = result['entries']
|
|
22
|
+
return result, Page(entries['data'], entries['total'], entries['page'], entries['per_page'])
|
|
23
|
+
|
|
24
|
+
items = []
|
|
25
|
+
current = 1
|
|
26
|
+
while True:
|
|
27
|
+
params.update(page=current, per_page=per_page or 500)
|
|
28
|
+
result = self.client.get(self._path(server_id, 'list'), params=params)
|
|
29
|
+
entries = result['entries']
|
|
30
|
+
items.extend(entries['data'])
|
|
31
|
+
if not entries['data'] or len(items) >= entries['total']:
|
|
32
|
+
return result, Page(items, entries['total'], 1, len(items))
|
|
33
|
+
current += 1
|
|
34
|
+
|
|
35
|
+
def stat(self, server_id, files, root='/'):
|
|
36
|
+
return self.client.post(self._path(server_id, 'stat'), json={'root': root, 'files': files})['entries']
|
|
37
|
+
|
|
38
|
+
def search(self, server_id, root='/', path_filter=None, size_filter=None, content_filter=None, match_context=None):
|
|
39
|
+
return self.client.post(self._path(server_id, 'search'), json={
|
|
40
|
+
'root': root,
|
|
41
|
+
'path_filter': path_filter,
|
|
42
|
+
'size_filter': size_filter,
|
|
43
|
+
'content_filter': content_filter,
|
|
44
|
+
'match_context': match_context,
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
def directorySizes(self, server_id, directory='/', depth=None):
|
|
48
|
+
return self.client.get(
|
|
49
|
+
self._path(server_id, 'directory-sizes'),
|
|
50
|
+
params={'directory': directory, 'depth': depth}
|
|
51
|
+
)['directory_sizes']
|
|
52
|
+
|
|
53
|
+
def largestDirectories(self, server_id, directory='/'):
|
|
54
|
+
return self.client.get(
|
|
55
|
+
self._path(server_id, 'largest-directories'),
|
|
56
|
+
params={'directory': directory}
|
|
57
|
+
)['largest_directories']
|
|
58
|
+
|
|
59
|
+
def fingerprint(self, server_id, file, algorithm=None):
|
|
60
|
+
return self.client.get(
|
|
61
|
+
self._path(server_id, 'fingerprint'),
|
|
62
|
+
params={'file': file, 'algorithm': algorithm}
|
|
63
|
+
)['fingerprint']
|
|
64
|
+
|
|
65
|
+
# reading and writing
|
|
66
|
+
def contents(self, server_id, file):
|
|
67
|
+
return self.client.get(self._path(server_id, 'contents'), params={'file': file})
|
|
68
|
+
|
|
69
|
+
def lines(self, server_id, file, start_line=None, end_line=None):
|
|
70
|
+
return self.client.get(
|
|
71
|
+
self._path(server_id, 'lines'),
|
|
72
|
+
params={'file': file, 'start_line': start_line, 'end_line': end_line}
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
def write(self, server_id, file, content):
|
|
76
|
+
return self.client.postText(self._path(server_id, 'write'), content, params={'file': file})
|
|
77
|
+
|
|
78
|
+
def revisions(self, server_id, file):
|
|
79
|
+
return self.client.get(self._path(server_id, 'revisions'), params={'file': file})['revisions']
|
|
80
|
+
|
|
81
|
+
def revision(self, server_id, file, revision_id):
|
|
82
|
+
return self.client.get(self._path(server_id, f'revisions/{revision_id}'), params={'file': file})
|
|
83
|
+
|
|
84
|
+
# transfer
|
|
85
|
+
def downloadUrl(self, server_id, files=None, root='/', directory=None, archive_format=None):
|
|
86
|
+
params = {'root': root, 'directory': directory, 'archive_format': archive_format}
|
|
87
|
+
if files is not None:
|
|
88
|
+
params['files'] = files
|
|
89
|
+
return self.client.get(self._path(server_id, 'download'), params=params)['url']
|
|
90
|
+
|
|
91
|
+
def uploadUrl(self, server_id):
|
|
92
|
+
return self.client.get(self._path(server_id, 'upload'))['url']
|
|
93
|
+
|
|
94
|
+
def upload(self, server_id, directory, files):
|
|
95
|
+
'''`files` is a list of (name, data) tuples'''
|
|
96
|
+
url = self.uploadUrl(server_id)
|
|
97
|
+
payload = [('files', (name, data)) for name, data in files]
|
|
98
|
+
try:
|
|
99
|
+
r = requests.post(
|
|
100
|
+
url,
|
|
101
|
+
params={'directory': directory},
|
|
102
|
+
files=payload,
|
|
103
|
+
verify=self.client.session.verify,
|
|
104
|
+
timeout=max(self.client.timeout, 300),
|
|
105
|
+
)
|
|
106
|
+
except requests.RequestException as e:
|
|
107
|
+
raise PanelConnectionError(f'Upload failed: {e}') from e
|
|
108
|
+
if r.status_code >= 400:
|
|
109
|
+
self.client.raiseError(r)
|
|
110
|
+
return self.client.parse(r)
|
|
111
|
+
|
|
112
|
+
def fetch(self, url, stream=False):
|
|
113
|
+
'''Downloads a signed URL returned by the panel'''
|
|
114
|
+
try:
|
|
115
|
+
r = requests.get(url, verify=self.client.session.verify, timeout=max(self.client.timeout, 300), stream=stream)
|
|
116
|
+
except requests.RequestException as e:
|
|
117
|
+
raise PanelConnectionError(f'Download failed: {e}') from e
|
|
118
|
+
if r.status_code >= 400:
|
|
119
|
+
self.client.raiseError(r)
|
|
120
|
+
return r
|
|
121
|
+
|
|
122
|
+
def pull(self, server_id, url, root='/', name=None, use_header=None, foreground=None):
|
|
123
|
+
return self.client.post(self._path(server_id, 'pull'), json={
|
|
124
|
+
'url': url,
|
|
125
|
+
'root': root,
|
|
126
|
+
'name': name,
|
|
127
|
+
'use_header': use_header,
|
|
128
|
+
'foreground': foreground,
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
def queryPull(self, server_id, url):
|
|
132
|
+
return self.client.post(self._path(server_id, 'pull/query'), json={'url': url})['query_result']
|
|
133
|
+
|
|
134
|
+
# management
|
|
135
|
+
def delete(self, server_id, root, files):
|
|
136
|
+
return self.client.post(self._path(server_id, 'delete'), json={'root': root, 'files': files})
|
|
137
|
+
|
|
138
|
+
def rename(self, server_id, root, files):
|
|
139
|
+
'''`files` is a list of {'from': ..., 'to': ...}'''
|
|
140
|
+
return self.client.put(self._path(server_id, 'rename'), json={'root': root, 'files': files})
|
|
141
|
+
|
|
142
|
+
def copy(self, server_id, path, destination=None, overwrite=None, foreground=None):
|
|
143
|
+
return self.client.post(self._path(server_id, 'copy'), json={
|
|
144
|
+
'path': path,
|
|
145
|
+
'destination': destination,
|
|
146
|
+
'overwrite': overwrite,
|
|
147
|
+
'foreground': foreground,
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
def copyMany(self, server_id, root, files, overwrite=None, foreground=None):
|
|
151
|
+
return self.client.post(self._path(server_id, 'copy-many'), json={
|
|
152
|
+
'root': root,
|
|
153
|
+
'files': files,
|
|
154
|
+
'overwrite': overwrite,
|
|
155
|
+
'foreground': foreground,
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
def copyRemote(self, server_id, root, files, destination, destination_server, foreground=None):
|
|
159
|
+
return self.client.post(self._path(server_id, 'copy-remote'), json={
|
|
160
|
+
'root': root,
|
|
161
|
+
'files': files,
|
|
162
|
+
'destination': destination,
|
|
163
|
+
'destination_server': destination_server,
|
|
164
|
+
'foreground': foreground,
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
def copyRemoteMany(self, server_id, root, files, destination, destination_servers):
|
|
168
|
+
return self.client.post(self._path(server_id, 'copy-remote-many'), json={
|
|
169
|
+
'root': root,
|
|
170
|
+
'files': files,
|
|
171
|
+
'destination': destination,
|
|
172
|
+
'destination_servers': destination_servers,
|
|
173
|
+
})['results']
|
|
174
|
+
|
|
175
|
+
def createDirectory(self, server_id, root, name):
|
|
176
|
+
return self.client.post(self._path(server_id, 'create-directory'), json={'root': root, 'name': name})
|
|
177
|
+
|
|
178
|
+
def createSymlink(self, server_id, root, link, target):
|
|
179
|
+
return self.client.post(self._path(server_id, 'create-symlink'), json={'root': root, 'link': link, 'target': target})
|
|
180
|
+
|
|
181
|
+
def compress(self, server_id, root, files, format='tar_gz', name=None, foreground=None):
|
|
182
|
+
return self.client.post(self._path(server_id, 'compress'), json={
|
|
183
|
+
'root': root,
|
|
184
|
+
'files': files,
|
|
185
|
+
'format': format,
|
|
186
|
+
'name': name,
|
|
187
|
+
'foreground': foreground,
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
def decompress(self, server_id, root, file, foreground=None):
|
|
191
|
+
return self.client.post(self._path(server_id, 'decompress'), json={
|
|
192
|
+
'root': root,
|
|
193
|
+
'file': file,
|
|
194
|
+
'foreground': foreground,
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
def chmod(self, server_id, root, files):
|
|
198
|
+
'''`files` is a list of {'file': ..., 'mode': ..., 'recursive': ...}'''
|
|
199
|
+
return self.client.put(self._path(server_id, 'chmod'), json={'root': root, 'files': files})
|
|
200
|
+
|
|
201
|
+
def sqliteQuery(self, server_id, file, query, rows=None, read_only=None):
|
|
202
|
+
return self.client.post(self._path(server_id, 'sqlite-query'), json={
|
|
203
|
+
'file': file,
|
|
204
|
+
'query': query,
|
|
205
|
+
'rows': rows,
|
|
206
|
+
'read_only': read_only,
|
|
207
|
+
})['results']
|
|
208
|
+
|
|
209
|
+
def cancelOperation(self, server_id, operation_id):
|
|
210
|
+
return self.client.delete(self._path(server_id, f'operations/{operation_id}'))
|
calagoapi/api/network.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Internal Calagopus NetworkAPI (allocations, subdomains, tunnels, firewall)
|
|
2
|
+
class NetworkAPI:
|
|
3
|
+
def __init__(self, client):
|
|
4
|
+
self.client = client
|
|
5
|
+
|
|
6
|
+
def _path(self, server_id, suffix=''):
|
|
7
|
+
return f'/api/client/servers/{server_id}{suffix}'
|
|
8
|
+
|
|
9
|
+
# allocations
|
|
10
|
+
def allocations(self, server_id, search=None, page=None, per_page=None):
|
|
11
|
+
return self.client.list(self._path(server_id, '/allocations'), 'allocations', {'search': search}, page, per_page)
|
|
12
|
+
|
|
13
|
+
def createAllocation(self, server_id):
|
|
14
|
+
return self.client.post(self._path(server_id, '/allocations'))['allocation']
|
|
15
|
+
|
|
16
|
+
def updateAllocation(self, server_id, allocation_id, notes=None, primary=None):
|
|
17
|
+
return self.client.patch(
|
|
18
|
+
self._path(server_id, f'/allocations/{allocation_id}'),
|
|
19
|
+
json={'notes': notes, 'primary': primary}
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
def deleteAllocation(self, server_id, allocation_id):
|
|
23
|
+
return self.client.delete(self._path(server_id, f'/allocations/{allocation_id}'))
|
|
24
|
+
|
|
25
|
+
# subdomains
|
|
26
|
+
def subdomains(self, server_id, search=None, page=None, per_page=None):
|
|
27
|
+
return self.client.list(self._path(server_id, '/subdomains'), 'subdomains', {'search': search}, page, per_page)
|
|
28
|
+
|
|
29
|
+
def subdomainDomains(self, server_id):
|
|
30
|
+
return self.client.get(self._path(server_id, '/subdomains/domains'))['domains']
|
|
31
|
+
|
|
32
|
+
def createSubdomain(self, server_id, domain_uuid, allocation_uuid, subdomain):
|
|
33
|
+
return self.client.post(self._path(server_id, '/subdomains'), json={
|
|
34
|
+
'domain_uuid': domain_uuid,
|
|
35
|
+
'allocation_uuid': allocation_uuid,
|
|
36
|
+
'subdomain': subdomain,
|
|
37
|
+
})['subdomain']
|
|
38
|
+
|
|
39
|
+
def updateSubdomain(self, server_id, subdomain_id, allocation_uuid):
|
|
40
|
+
return self.client.patch(
|
|
41
|
+
self._path(server_id, f'/subdomains/{subdomain_id}'),
|
|
42
|
+
json={'allocation_uuid': allocation_uuid}
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def deleteSubdomain(self, server_id, subdomain_id):
|
|
46
|
+
return self.client.delete(self._path(server_id, f'/subdomains/{subdomain_id}'))
|
|
47
|
+
|
|
48
|
+
# tunnel
|
|
49
|
+
def tunnel(self, server_id):
|
|
50
|
+
return self.client.get(self._path(server_id, '/tunnel'))
|
|
51
|
+
|
|
52
|
+
def createTunnel(self, server_id, name=None):
|
|
53
|
+
return self.client.post(self._path(server_id, '/tunnel'), json={'name': name})['tunnel']
|
|
54
|
+
|
|
55
|
+
def renameTunnel(self, server_id, name):
|
|
56
|
+
return self.client.patch(self._path(server_id, '/tunnel'), json={'name': name})['tunnel']
|
|
57
|
+
|
|
58
|
+
def deleteTunnel(self, server_id):
|
|
59
|
+
return self.client.delete(self._path(server_id, '/tunnel'))
|
|
60
|
+
|
|
61
|
+
def setTunnelPorts(self, server_id, ports):
|
|
62
|
+
return self.client.put(self._path(server_id, '/tunnel/ports'), json={'ports': ports})
|
|
63
|
+
|
|
64
|
+
def tunnelConnectable(self, server_id, search=None, other=None, page=None, per_page=None):
|
|
65
|
+
return self.client.list(
|
|
66
|
+
self._path(server_id, '/tunnel/connections/available'), 'servers',
|
|
67
|
+
{'search': search, 'other': other}, page, per_page
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
def connectTunnel(self, server_id, target_server):
|
|
71
|
+
return self.client.post(self._path(server_id, '/tunnel/connections'), json={'server': target_server})
|
|
72
|
+
|
|
73
|
+
def disconnectTunnel(self, server_id, connection_id, incoming=None):
|
|
74
|
+
return self.client.delete(
|
|
75
|
+
self._path(server_id, f'/tunnel/connections/{connection_id}'),
|
|
76
|
+
params={'incoming': incoming}
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# firewall
|
|
80
|
+
def firewall(self, server_id):
|
|
81
|
+
return self.client.get(self._path(server_id, '/firewall'))
|
|
82
|
+
|
|
83
|
+
def setFirewallRules(self, server_id, rules):
|
|
84
|
+
return self.client.put(self._path(server_id, '/firewall'), json={'rules': rules})
|
calagoapi/api/public.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Internal Calagopus PublicAPI (unauthenticated panel information)
|
|
2
|
+
class PublicAPI:
|
|
3
|
+
def __init__(self, client):
|
|
4
|
+
self.client = client
|
|
5
|
+
|
|
6
|
+
def settings(self):
|
|
7
|
+
return self.client.get('/api/settings')
|
|
8
|
+
|
|
9
|
+
def languages(self):
|
|
10
|
+
return self.client.get('/api/languages')['languages']
|
|
11
|
+
|
|
12
|
+
def announcements(self):
|
|
13
|
+
return self.client.get('/api/announcements')['announcements']
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Internal Calagopus SchedulesAPI
|
|
2
|
+
class SchedulesAPI:
|
|
3
|
+
def __init__(self, client):
|
|
4
|
+
self.client = client
|
|
5
|
+
|
|
6
|
+
def _path(self, server_id, suffix=''):
|
|
7
|
+
return f'/api/client/servers/{server_id}/schedules{suffix}'
|
|
8
|
+
|
|
9
|
+
# schedules
|
|
10
|
+
def list(self, server_id, search=None, page=None, per_page=None):
|
|
11
|
+
return self.client.list(self._path(server_id), 'schedules', {'search': search}, page, per_page)
|
|
12
|
+
|
|
13
|
+
def get(self, server_id, schedule_id):
|
|
14
|
+
return self.client.get(self._path(server_id, f'/{schedule_id}'))['schedule']
|
|
15
|
+
|
|
16
|
+
def create(self, server_id, name, triggers, condition, enabled=True):
|
|
17
|
+
return self.client.post(self._path(server_id), json={
|
|
18
|
+
'name': name,
|
|
19
|
+
'enabled': enabled,
|
|
20
|
+
'triggers': triggers,
|
|
21
|
+
'condition': condition,
|
|
22
|
+
})['schedule']
|
|
23
|
+
|
|
24
|
+
def update(self, server_id, schedule_id, name=None, enabled=None, triggers=None, condition=None):
|
|
25
|
+
return self.client.patch(self._path(server_id, f'/{schedule_id}'), json={
|
|
26
|
+
'name': name,
|
|
27
|
+
'enabled': enabled,
|
|
28
|
+
'triggers': triggers,
|
|
29
|
+
'condition': condition,
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
def delete(self, server_id, schedule_id):
|
|
33
|
+
return self.client.delete(self._path(server_id, f'/{schedule_id}'))
|
|
34
|
+
|
|
35
|
+
def duplicate(self, server_id, schedule_id, name):
|
|
36
|
+
return self.client.post(self._path(server_id, f'/{schedule_id}/duplicate'), json={'name': name})['schedule']
|
|
37
|
+
|
|
38
|
+
def trigger(self, server_id, schedule_id, skip_condition=None):
|
|
39
|
+
return self.client.post(self._path(server_id, f'/{schedule_id}/trigger'), json={'skip_condition': skip_condition})
|
|
40
|
+
|
|
41
|
+
def abort(self, server_id, schedule_id):
|
|
42
|
+
return self.client.post(self._path(server_id, f'/{schedule_id}/abort'))
|
|
43
|
+
|
|
44
|
+
def status(self, server_id, schedule_id):
|
|
45
|
+
return self.client.get(self._path(server_id, f'/{schedule_id}/status'))['status']
|
|
46
|
+
|
|
47
|
+
def export(self, server_id, schedule_id):
|
|
48
|
+
return self.client.get(self._path(server_id, f'/{schedule_id}/export'))
|
|
49
|
+
|
|
50
|
+
def importSchedule(self, server_id, data):
|
|
51
|
+
return self.client.post(self._path(server_id, '/import'), json=data)['schedule']
|
|
52
|
+
|
|
53
|
+
# steps
|
|
54
|
+
def steps(self, server_id, schedule_id):
|
|
55
|
+
return self.client.get(self._path(server_id, f'/{schedule_id}/steps'))['schedule_steps']
|
|
56
|
+
|
|
57
|
+
def createStep(self, server_id, schedule_id, action, order):
|
|
58
|
+
return self.client.post(
|
|
59
|
+
self._path(server_id, f'/{schedule_id}/steps'),
|
|
60
|
+
json={'action': action, 'order': order}
|
|
61
|
+
)['schedule_step']
|
|
62
|
+
|
|
63
|
+
def updateStep(self, server_id, schedule_id, step_id, action=None, order=None):
|
|
64
|
+
return self.client.patch(
|
|
65
|
+
self._path(server_id, f'/{schedule_id}/steps/{step_id}'),
|
|
66
|
+
json={'action': action, 'order': order}
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def deleteStep(self, server_id, schedule_id, step_id):
|
|
70
|
+
return self.client.delete(self._path(server_id, f'/{schedule_id}/steps/{step_id}'))
|
|
71
|
+
|
|
72
|
+
def duplicateStep(self, server_id, schedule_id, step_id):
|
|
73
|
+
return self.client.post(self._path(server_id, f'/{schedule_id}/steps/{step_id}/duplicate'))['schedule_step']
|
|
74
|
+
|
|
75
|
+
def orderSteps(self, server_id, schedule_id, step_order):
|
|
76
|
+
return self.client.put(
|
|
77
|
+
self._path(server_id, f'/{schedule_id}/steps/order'),
|
|
78
|
+
json={'schedule_step_order': step_order}
|
|
79
|
+
)
|
calagoapi/api/servers.py
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Internal Calagopus ServersAPI
|
|
2
|
+
class ServersAPI:
|
|
3
|
+
def __init__(self, client):
|
|
4
|
+
self.client = client
|
|
5
|
+
|
|
6
|
+
# listing
|
|
7
|
+
def list(self, search=None, other=None, page=None, per_page=None):
|
|
8
|
+
return self.client.list('/api/client/servers', 'servers', {'search': search, 'other': other}, page, per_page)
|
|
9
|
+
|
|
10
|
+
def get(self, server_id):
|
|
11
|
+
return self.client.get(f'/api/client/servers/{server_id}')['server']
|
|
12
|
+
|
|
13
|
+
def eggs(self, search=None, page=None, per_page=None):
|
|
14
|
+
return self.client.list('/api/client/servers/eggs', 'nest_eggs', {'search': search}, page, per_page)
|
|
15
|
+
|
|
16
|
+
def eggCommandSnippets(self, egg_id):
|
|
17
|
+
return self.client.get(f'/api/client/servers/eggs/{egg_id}/command-snippets')['command_snippets']
|
|
18
|
+
|
|
19
|
+
def nodeResources(self, node_id):
|
|
20
|
+
return self.client.get(f'/api/client/servers/nodes/{node_id}/resources')['resources']
|
|
21
|
+
|
|
22
|
+
# status and console
|
|
23
|
+
def resources(self, server_id):
|
|
24
|
+
return self.client.get(f'/api/client/servers/{server_id}/resources')['resources']
|
|
25
|
+
|
|
26
|
+
def power(self, server_id, action):
|
|
27
|
+
return self.client.post(f'/api/client/servers/{server_id}/power', json={'action': action})
|
|
28
|
+
|
|
29
|
+
def command(self, server_id, command):
|
|
30
|
+
return self.client.post(f'/api/client/servers/{server_id}/command', json={'command': command})
|
|
31
|
+
|
|
32
|
+
def logs(self, server_id, lines=None):
|
|
33
|
+
return self.client.get(f'/api/client/servers/{server_id}/logs', params={'lines': lines})
|
|
34
|
+
|
|
35
|
+
def websocket(self, server_id):
|
|
36
|
+
return self.client.get(f'/api/client/servers/{server_id}/websocket')
|
|
37
|
+
|
|
38
|
+
def activity(self, server_id, user=None, search=None, page=None, per_page=None):
|
|
39
|
+
return self.client.list(
|
|
40
|
+
f'/api/client/servers/{server_id}/activity', 'activities',
|
|
41
|
+
{'user': user, 'search': search}, page, per_page
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
def announcements(self, server_id):
|
|
45
|
+
return self.client.get(f'/api/client/servers/{server_id}/announcements')['announcements']
|
|
46
|
+
|
|
47
|
+
# settings
|
|
48
|
+
def rename(self, server_id, name=None, description=None):
|
|
49
|
+
return self.client.post(
|
|
50
|
+
f'/api/client/servers/{server_id}/settings/rename',
|
|
51
|
+
json={'name': name, 'description': description}
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
def setTimezone(self, server_id, timezone):
|
|
55
|
+
return self.client.put(f'/api/client/servers/{server_id}/settings/timezone', json={'timezone': timezone})
|
|
56
|
+
|
|
57
|
+
def setAutoKill(self, server_id, enabled, seconds=None):
|
|
58
|
+
payload = {'enabled': enabled}
|
|
59
|
+
if seconds is not None:
|
|
60
|
+
payload['seconds'] = seconds
|
|
61
|
+
return self.client.put(f'/api/client/servers/{server_id}/settings/auto-kill', json=payload)
|
|
62
|
+
|
|
63
|
+
def setAutoStart(self, server_id, behavior):
|
|
64
|
+
return self.client.put(f'/api/client/servers/{server_id}/settings/auto-start', json={'behavior': behavior})
|
|
65
|
+
|
|
66
|
+
def reinstall(self, server_id, truncate_directory=False, start_on_completion=None):
|
|
67
|
+
payload = {'truncate_directory': truncate_directory}
|
|
68
|
+
if start_on_completion is not None:
|
|
69
|
+
payload['start_on_completion'] = start_on_completion
|
|
70
|
+
return self.client.post(f'/api/client/servers/{server_id}/settings/install', json=payload)
|
|
71
|
+
|
|
72
|
+
def cancelInstall(self, server_id):
|
|
73
|
+
return self.client.post(f'/api/client/servers/{server_id}/settings/install/cancel')
|
|
74
|
+
|
|
75
|
+
def unlockInstall(self, server_id):
|
|
76
|
+
return self.client.post(f'/api/client/servers/{server_id}/settings/install/unlock')
|
|
77
|
+
|
|
78
|
+
# startup
|
|
79
|
+
def startupVariables(self, server_id):
|
|
80
|
+
return self.client.get(f'/api/client/servers/{server_id}/startup/variables')['variables']
|
|
81
|
+
|
|
82
|
+
def updateStartupVariables(self, server_id, variables):
|
|
83
|
+
return self.client.put(f'/api/client/servers/{server_id}/startup/variables', json={'variables': variables})
|
|
84
|
+
|
|
85
|
+
def setStartupCommand(self, server_id, command):
|
|
86
|
+
return self.client.put(f'/api/client/servers/{server_id}/startup/command', json={'command': command})
|
|
87
|
+
|
|
88
|
+
def setDockerImage(self, server_id, image):
|
|
89
|
+
return self.client.put(f'/api/client/servers/{server_id}/startup/docker-image', json={'image': image})
|
|
90
|
+
|
|
91
|
+
# server groups
|
|
92
|
+
def groups(self):
|
|
93
|
+
return self.client.get('/api/client/servers/groups')['server_groups']
|
|
94
|
+
|
|
95
|
+
def groupServers(self, group_id, search=None, page=None, per_page=None):
|
|
96
|
+
return self.client.list(f'/api/client/servers/groups/{group_id}', 'servers', {'search': search}, page, per_page)
|
|
97
|
+
|
|
98
|
+
def createGroup(self, name, server_order=None):
|
|
99
|
+
return self.client.post(
|
|
100
|
+
'/api/client/servers/groups',
|
|
101
|
+
json={'name': name, 'server_order': server_order or []}
|
|
102
|
+
)['server_group']
|
|
103
|
+
|
|
104
|
+
def updateGroup(self, group_id, name, server_order=None):
|
|
105
|
+
payload = {'name': name}
|
|
106
|
+
if server_order is not None:
|
|
107
|
+
payload['server_order'] = server_order
|
|
108
|
+
return self.client.patch(f'/api/client/servers/groups/{group_id}', json=payload)
|
|
109
|
+
|
|
110
|
+
def deleteGroup(self, group_id):
|
|
111
|
+
return self.client.delete(f'/api/client/servers/groups/{group_id}')
|
|
112
|
+
|
|
113
|
+
def orderGroups(self, group_order):
|
|
114
|
+
return self.client.put('/api/client/servers/groups/order', json={'server_group_order': group_order})
|
calagoapi/api/users.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Internal Calagopus UsersAPI (server subusers)
|
|
2
|
+
class UsersAPI:
|
|
3
|
+
def __init__(self, client):
|
|
4
|
+
self.client = client
|
|
5
|
+
|
|
6
|
+
def _path(self, server_id, suffix=''):
|
|
7
|
+
return f'/api/client/servers/{server_id}/subusers{suffix}'
|
|
8
|
+
|
|
9
|
+
def list(self, server_id, search=None, page=None, per_page=None):
|
|
10
|
+
return self.client.list(self._path(server_id), 'subusers', {'search': search}, page, per_page)
|
|
11
|
+
|
|
12
|
+
def create(self, server_id, email, permissions, ignored_files=None, captcha=None):
|
|
13
|
+
return self.client.post(self._path(server_id), json={
|
|
14
|
+
'email': email,
|
|
15
|
+
'permissions': permissions,
|
|
16
|
+
'ignored_files': ignored_files or [],
|
|
17
|
+
'captcha': captcha,
|
|
18
|
+
})['subuser']
|
|
19
|
+
|
|
20
|
+
def update(self, server_id, subuser_id, permissions=None, ignored_files=None):
|
|
21
|
+
return self.client.patch(self._path(server_id, f'/{subuser_id}'), json={
|
|
22
|
+
'permissions': permissions,
|
|
23
|
+
'ignored_files': ignored_files,
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
def delete(self, server_id, subuser_id):
|
|
27
|
+
return self.client.delete(self._path(server_id, f'/{subuser_id}'))
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from calagoapi.api.client import segment
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# Internal Calagopus VersionsAPI (Minecraft Version Changer extension)
|
|
5
|
+
class VersionsAPI:
|
|
6
|
+
def __init__(self, client):
|
|
7
|
+
self.client = client
|
|
8
|
+
|
|
9
|
+
def _path(self, server_id, suffix=''):
|
|
10
|
+
return f'/api/client/servers/{server_id}/minecraft/versions{suffix}'
|
|
11
|
+
|
|
12
|
+
def installed(self, server_id):
|
|
13
|
+
return self.client.get(self._path(server_id, '/installed'))['build']
|
|
14
|
+
|
|
15
|
+
def types(self, server_id):
|
|
16
|
+
return self.client.get(self._path(server_id, '/types'))['types']
|
|
17
|
+
|
|
18
|
+
def versions(self, server_id, type, search=None, page=None, per_page=None):
|
|
19
|
+
return self.client.list(self._path(server_id, f'/types/{segment(type)}'), 'versions', {'search': search}, page, per_page)
|
|
20
|
+
|
|
21
|
+
def builds(self, server_id, type, version, search=None, page=None, per_page=None):
|
|
22
|
+
return self.client.list(self._path(server_id, f'/types/{segment(type)}/{segment(version)}'), 'builds', {'search': search}, page, per_page)
|
|
23
|
+
|
|
24
|
+
def install(self, server_id, build_uuid, truncate_directory=False, accept_eula=True):
|
|
25
|
+
return self.client.post(self._path(server_id, '/install'), json={
|
|
26
|
+
'build_uuid': build_uuid,
|
|
27
|
+
'truncate_directory': truncate_directory,
|
|
28
|
+
'accept_eula': accept_eula,
|
|
29
|
+
})
|