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.
Files changed (71) hide show
  1. calagoapi/__init__.py +190 -0
  2. calagoapi/account/__init__.py +14 -0
  3. calagoapi/account/account.py +292 -0
  4. calagoapi/account/auth.py +72 -0
  5. calagoapi/account/models.py +221 -0
  6. calagoapi/admin/__init__.py +48 -0
  7. calagoapi/admin/admin.py +341 -0
  8. calagoapi/admin/managers.py +490 -0
  9. calagoapi/admin/resources.py +970 -0
  10. calagoapi/aio/__init__.py +9 -0
  11. calagoapi/aio/console.py +289 -0
  12. calagoapi/aio/panel.py +176 -0
  13. calagoapi/api/__init__.py +63 -0
  14. calagoapi/api/account.py +195 -0
  15. calagoapi/api/admin.py +402 -0
  16. calagoapi/api/attachments.py +27 -0
  17. calagoapi/api/auth.py +52 -0
  18. calagoapi/api/backups.py +99 -0
  19. calagoapi/api/client.py +198 -0
  20. calagoapi/api/databases.py +217 -0
  21. calagoapi/api/files.py +210 -0
  22. calagoapi/api/network.py +84 -0
  23. calagoapi/api/public.py +13 -0
  24. calagoapi/api/schedules.py +79 -0
  25. calagoapi/api/servers.py +114 -0
  26. calagoapi/api/users.py +27 -0
  27. calagoapi/api/versions.py +29 -0
  28. calagoapi/backups/__init__.py +8 -0
  29. calagoapi/backups/backup.py +292 -0
  30. calagoapi/backups/manager.py +177 -0
  31. calagoapi/console/__init__.py +6 -0
  32. calagoapi/console/console.py +392 -0
  33. calagoapi/databases/__init__.py +12 -0
  34. calagoapi/databases/database.py +445 -0
  35. calagoapi/databases/explorer.py +159 -0
  36. calagoapi/databases/manager.py +122 -0
  37. calagoapi/files/__init__.py +9 -0
  38. calagoapi/files/file.py +196 -0
  39. calagoapi/files/manager.py +437 -0
  40. calagoapi/network/__init__.py +8 -0
  41. calagoapi/network/allocation.py +99 -0
  42. calagoapi/network/manager.py +132 -0
  43. calagoapi/nodes/__init__.py +6 -0
  44. calagoapi/nodes/node.py +477 -0
  45. calagoapi/panel.py +162 -0
  46. calagoapi/schedules/__init__.py +14 -0
  47. calagoapi/schedules/builders.py +461 -0
  48. calagoapi/schedules/manager.py +107 -0
  49. calagoapi/schedules/schedule.py +214 -0
  50. calagoapi/servers/__init__.py +13 -0
  51. calagoapi/servers/admin.py +430 -0
  52. calagoapi/servers/generic.py +785 -0
  53. calagoapi/servers/manager.py +167 -0
  54. calagoapi/servers/minecraft.py +207 -0
  55. calagoapi/tunnels/__init__.py +5 -0
  56. calagoapi/tunnels/tunnel.py +112 -0
  57. calagoapi/users/__init__.py +11 -0
  58. calagoapi/users/activity.py +45 -0
  59. calagoapi/users/subuser.py +127 -0
  60. calagoapi/users/user.py +267 -0
  61. calagoapi/utils/__init__.py +43 -0
  62. calagoapi/utils/convert.py +113 -0
  63. calagoapi/utils/exceptions.py +72 -0
  64. calagoapi/utils/model.py +142 -0
  65. calagoapi/utils/resource.py +100 -0
  66. calagoapi/utils/time.py +68 -0
  67. calagoapi-1.0.dev1.dist-info/METADATA +266 -0
  68. calagoapi-1.0.dev1.dist-info/RECORD +71 -0
  69. calagoapi-1.0.dev1.dist-info/WHEEL +5 -0
  70. calagoapi-1.0.dev1.dist-info/licenses/LICENSE +674 -0
  71. 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}'))
@@ -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})
@@ -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
+ )
@@ -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
+ })
@@ -0,0 +1,8 @@
1
+ from .backup import Backup, BackupGroup
2
+ from .manager import BackupManager
3
+
4
+ __all__ = [
5
+ 'Backup',
6
+ 'BackupGroup',
7
+ 'BackupManager',
8
+ ]