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
@@ -0,0 +1,221 @@
1
+ from calagoapi.utils.model import Model
2
+
3
+
4
+ class ApiKey(Model):
5
+ '''
6
+ An API key of the current account.
7
+
8
+ The secret key is only known right after creation (`getKey()`).
9
+
10
+ Example:
11
+ api_key = panel.account.createApiKey('backup-bot', server_permissions=['backup.*'])
12
+ print(api_key.getKey()) # store it now, it is never shown again
13
+ '''
14
+ def __init__(self, panel, data: dict, key: str = None):
15
+ super().__init__(panel, data)
16
+ self.key = key
17
+
18
+ def getName(self) -> str:
19
+ '''Returns the key name.'''
20
+ return self.data.get('name')
21
+
22
+ def getKey(self) -> str:
23
+ '''Returns the full secret key. Only available right after creation or recreate().'''
24
+ return self.key
25
+
26
+ def getKeyStart(self) -> str:
27
+ '''Returns the first characters of the key, for identification.'''
28
+ return self.data.get('key_start')
29
+
30
+ def getAllowedIPs(self) -> list:
31
+ '''Returns the IPs allowed to use the key. Empty means all.'''
32
+ return self.data.get('allowed_ips', [])
33
+
34
+ def getUserPermissions(self) -> list:
35
+ '''Returns the account permissions of the key.'''
36
+ return self.data.get('user_permissions', [])
37
+
38
+ def getAdminPermissions(self) -> list:
39
+ '''Returns the admin permissions of the key.'''
40
+ return self.data.get('admin_permissions', [])
41
+
42
+ def getServerPermissions(self) -> list:
43
+ '''Returns the server permissions of the key.'''
44
+ return self.data.get('server_permissions', [])
45
+
46
+ def getLastUsed(self) -> str:
47
+ '''Returns when the key was last used.'''
48
+ return self.data.get('last_used')
49
+
50
+ def getExpires(self) -> str:
51
+ '''Returns when the key expires, or None.'''
52
+ return self.data.get('expires')
53
+
54
+ def isEnabled(self) -> bool:
55
+ '''Returns True if the key is enabled.'''
56
+ return bool(self.data.get('enabled'))
57
+
58
+ def update(self, **fields) -> 'ApiKey':
59
+ '''
60
+ Changes the key. Fields: name, enabled, allowed_ips, user_permissions,
61
+ admin_permissions, server_permissions, expires.
62
+ '''
63
+ allowed_ips = fields.pop('allowed_ips', self.getAllowedIPs())
64
+ self.panel.api.account.updateApiKey(self.getUUID(), allowed_ips, **fields)
65
+ return self._update({'allowed_ips': allowed_ips, **fields})
66
+
67
+ def rename(self, name: str) -> 'ApiKey':
68
+ '''Renames the key.'''
69
+ return self.update(name=name)
70
+
71
+ def enable(self) -> 'ApiKey':
72
+ '''Enables the key.'''
73
+ return self.update(enabled=True)
74
+
75
+ def disable(self) -> 'ApiKey':
76
+ '''Disables the key.'''
77
+ return self.update(enabled=False)
78
+
79
+ def recreate(self) -> str:
80
+ '''Generates a new secret for the key and returns it.'''
81
+ self.key = self.panel.api.account.recreateApiKey(self.getUUID())
82
+ return self.key
83
+
84
+ def duplicate(self, name: str) -> 'ApiKey':
85
+ '''Creates a copy with the same permissions. The copy holds its new secret.'''
86
+ result = self.panel.api.account.duplicateApiKey(self.getUUID(), name)
87
+ return ApiKey(self.panel, result['api_key'], result.get('key'))
88
+
89
+ def delete(self) -> None:
90
+ '''Deletes the key.'''
91
+ return self.panel.api.account.deleteApiKey(self.getUUID())
92
+
93
+
94
+ class SshKey(Model):
95
+ '''An SSH public key used for SFTP login.'''
96
+ def getName(self) -> str:
97
+ '''Returns the key name.'''
98
+ return self.data.get('name')
99
+
100
+ def getFingerprint(self) -> str:
101
+ '''Returns the key fingerprint.'''
102
+ return self.data.get('fingerprint')
103
+
104
+ def rename(self, name: str) -> 'SshKey':
105
+ '''Renames the key.'''
106
+ self.panel.api.account.updateSshKey(self.getUUID(), name)
107
+ return self._update({'name': name})
108
+
109
+ def delete(self) -> None:
110
+ '''Deletes the key.'''
111
+ return self.panel.api.account.deleteSshKey(self.getUUID())
112
+
113
+
114
+ class SecurityKey(Model):
115
+ '''A WebAuthn security key / passkey.'''
116
+ def getName(self) -> str:
117
+ '''Returns the key name.'''
118
+ return self.data.get('name')
119
+
120
+ def getCredentialId(self) -> str:
121
+ '''Returns the WebAuthn credential id.'''
122
+ return self.data.get('credential_id')
123
+
124
+ def getLastUsed(self) -> str:
125
+ '''Returns when the key was last used.'''
126
+ return self.data.get('last_used')
127
+
128
+ def rename(self, name: str) -> 'SecurityKey':
129
+ '''Renames the key.'''
130
+ self.panel.api.account.updateSecurityKey(self.getUUID(), name)
131
+ return self._update({'name': name})
132
+
133
+ def delete(self, password: str = None) -> None:
134
+ '''Deletes the key.'''
135
+ return self.panel.api.account.deleteSecurityKey(self.getUUID(), password)
136
+
137
+
138
+ class Session(Model):
139
+ '''A logged-in browser session.'''
140
+ def __repr__(self):
141
+ return f'<Session {self.getIP()!r}>'
142
+
143
+ def getIP(self) -> str:
144
+ '''Returns the IP address.'''
145
+ return self.data.get('ip')
146
+
147
+ def getUserAgent(self) -> str:
148
+ '''Returns the browser user agent.'''
149
+ return self.data.get('user_agent')
150
+
151
+ def getLastUsed(self) -> str:
152
+ '''Returns when the session was last used.'''
153
+ return self.data.get('last_used')
154
+
155
+ def isCurrent(self) -> bool:
156
+ '''Returns True for the session making this request.'''
157
+ return bool(self.data.get('is_using'))
158
+
159
+ def delete(self) -> None:
160
+ '''Logs the session out.'''
161
+ return self.panel.api.account.deleteSession(self.getUUID())
162
+
163
+
164
+ class OAuthLink(Model):
165
+ '''An external account (Discord, GitHub, ...) linked for login.'''
166
+ def __repr__(self):
167
+ return f'<OAuthLink {self.getIdentifier()!r}>'
168
+
169
+ def getProvider(self) -> dict:
170
+ '''Returns the OAuth provider.'''
171
+ return self.data.get('oauth_provider')
172
+
173
+ def getIdentifier(self) -> str:
174
+ '''Returns the external account id.'''
175
+ return self.data.get('identifier')
176
+
177
+ def getLastUsed(self) -> str:
178
+ '''Returns when the link was last used to log in.'''
179
+ return self.data.get('last_used')
180
+
181
+ def delete(self) -> None:
182
+ '''Unlinks the account.'''
183
+ return self.panel.api.account.deleteOauthLink(self.getUUID())
184
+
185
+
186
+ class CommandSnippet(Model):
187
+ '''
188
+ A saved console command, shown on matching servers.
189
+
190
+ Example:
191
+ snippet = panel.account.createCommandSnippet('Day', 'time set day')
192
+ '''
193
+ def getName(self) -> str:
194
+ '''Returns the snippet name.'''
195
+ return self.data.get('name')
196
+
197
+ def getCommand(self) -> str:
198
+ '''Returns the command.'''
199
+ return self.data.get('command')
200
+
201
+ def getEggs(self) -> list:
202
+ '''Returns the eggs the snippet applies to. Empty means all.'''
203
+ return self.data.get('eggs', [])
204
+
205
+ def update(self, name: str = None, command: str = None, eggs: list = None) -> 'CommandSnippet':
206
+ '''Changes the snippet.'''
207
+ name = name or self.getName()
208
+ self.panel.api.account.updateCommandSnippet(self.getUUID(), name, command, eggs)
209
+ return self._update({'name': name, 'command': command, 'eggs': eggs})
210
+
211
+ def duplicate(self, name: str) -> 'CommandSnippet':
212
+ '''Copies the snippet.'''
213
+ return CommandSnippet(self.panel, self.panel.api.account.duplicateCommandSnippet(self.getUUID(), name))
214
+
215
+ def runOn(self, server) -> None:
216
+ '''Sends the command to a server.'''
217
+ return server.sendCommand(self.getCommand())
218
+
219
+ def delete(self) -> None:
220
+ '''Deletes the snippet.'''
221
+ return self.panel.api.account.deleteCommandSnippet(self.getUUID())
@@ -0,0 +1,48 @@
1
+ from calagoapi.utils.resource import AdminResource, AdminManager
2
+ from .resources import (
3
+ Location,
4
+ Nest,
5
+ Egg,
6
+ EggVariable,
7
+ Mount,
8
+ Device,
9
+ Role,
10
+ Announcement,
11
+ OAuthProvider,
12
+ DatabaseHost,
13
+ DatabaseAgentHost,
14
+ DatabaseAgentTemplate,
15
+ BackupConfiguration,
16
+ BackupPolicy,
17
+ EggRepository,
18
+ EggConfiguration,
19
+ SubdomainDomain,
20
+ )
21
+ from .admin import Admin, SystemManager, EmailManager, ExtensionManager, AssetManager
22
+
23
+ __all__ = [
24
+ 'Admin',
25
+ 'AdminResource',
26
+ 'AdminManager',
27
+ 'SystemManager',
28
+ 'EmailManager',
29
+ 'ExtensionManager',
30
+ 'AssetManager',
31
+ 'Location',
32
+ 'Nest',
33
+ 'Egg',
34
+ 'EggVariable',
35
+ 'Mount',
36
+ 'Device',
37
+ 'Role',
38
+ 'Announcement',
39
+ 'OAuthProvider',
40
+ 'DatabaseHost',
41
+ 'DatabaseAgentHost',
42
+ 'DatabaseAgentTemplate',
43
+ 'BackupConfiguration',
44
+ 'BackupPolicy',
45
+ 'EggRepository',
46
+ 'EggConfiguration',
47
+ 'SubdomainDomain',
48
+ ]
@@ -0,0 +1,341 @@
1
+ import os
2
+
3
+ from calagoapi.admin.managers import (
4
+ LocationManager,
5
+ NestManager,
6
+ MountManager,
7
+ DeviceManager,
8
+ RoleManager,
9
+ AnnouncementManager,
10
+ OAuthProviderManager,
11
+ DatabaseHostManager,
12
+ DatabaseAgentHostManager,
13
+ DatabaseAgentTemplateManager,
14
+ BackupConfigurationManager,
15
+ BackupPolicyManager,
16
+ EggRepositoryManager,
17
+ EggConfigurationManager,
18
+ SubdomainDomainManager,
19
+ )
20
+ from calagoapi.nodes import NodeManager
21
+ from calagoapi.servers.admin import AdminServerManager
22
+ from calagoapi.users import UserManager, Activity
23
+ from calagoapi.utils.model import idOf
24
+
25
+
26
+ class SystemManager:
27
+ '''
28
+ Panel health, updates and diagnostics, available as `panel.admin.system`.
29
+
30
+ Example:
31
+ overview = panel.admin.system.getOverview()
32
+ print(overview['version'])
33
+ if panel.admin.system.getUpdates():
34
+ print('An update is available')
35
+ '''
36
+ def __init__(self, panel):
37
+ self.panel = panel
38
+ self.api = panel.api.admin
39
+
40
+ def getOverview(self) -> dict:
41
+ '''Returns panel version, CPU, memory, cache and database information.'''
42
+ return self.api.system('overview')
43
+
44
+ def getHealth(self) -> dict:
45
+ '''Returns time sync and pending migration information.'''
46
+ return self.api.system('health/general')
47
+
48
+ def getNodeHealth(self, page: int = None, per_page: int = None) -> dict:
49
+ '''Returns nodes whose clock is out of sync or that cannot be reached.'''
50
+ return self.api.system('health/nodes', params={'page': page, 'per_page': per_page})
51
+
52
+ def getTelemetry(self) -> dict:
53
+ '''Returns the anonymous telemetry the panel would send.'''
54
+ return self.api.system('telemetry')['telemetry']
55
+
56
+ def getUpdates(self) -> dict:
57
+ '''Returns available panel update information.'''
58
+ return self.api.system('updates')['update_information']
59
+
60
+ def recheckUpdates(self) -> dict:
61
+ '''Checks for updates now.'''
62
+ return self.api.system('updates/recheck', 'POST')['update_information']
63
+
64
+ def getUpdateHistory(self) -> dict:
65
+ '''Returns the panel version history.'''
66
+ return self.api.system('updates/history')['version_history']
67
+
68
+ def getOutdatedNodes(self, page: int = None, per_page: int = None) -> dict:
69
+ '''Returns nodes running an outdated daemon.'''
70
+ return self.api.system('updates/nodes', params={'page': page, 'per_page': per_page})
71
+
72
+ def getOutdatedDatabaseAgentHosts(self, page: int = None, per_page: int = None) -> dict:
73
+ '''Returns database agent hosts running an outdated agent.'''
74
+ return self.api.system('updates/database-agent-hosts', params={'page': page, 'per_page': per_page})
75
+
76
+ def isDebugEnabled(self) -> bool:
77
+ '''Returns True if debug logging is enabled.'''
78
+ return bool(self.api.system('debug').get('enabled'))
79
+
80
+ def setDebug(self, enabled: bool) -> None:
81
+ '''Turns debug logging on or off.'''
82
+ return self.api.system('debug', 'POST', json={'enabled': enabled})
83
+
84
+
85
+ class EmailManager:
86
+ '''
87
+ Email templates and variables, available as `panel.admin.email`.
88
+
89
+ Example:
90
+ panel.admin.email.sendTestEmail('me@example.com')
91
+ panel.admin.email.updateTemplate('password_reset', subject='Reset your password')
92
+ '''
93
+ def __init__(self, panel):
94
+ self.panel = panel
95
+ self.api = panel.api.admin
96
+
97
+ def sendTestEmail(self, email: str) -> None:
98
+ '''Sends a test email using the current mail settings.'''
99
+ return self.api.sendTestEmail(email)
100
+
101
+ def getTemplates(self) -> list:
102
+ '''Returns every email template.'''
103
+ return self.api.emailTemplates()
104
+
105
+ def getTemplate(self, identifier: str) -> dict:
106
+ '''Returns one email template.'''
107
+ return self.api.emailTemplate(identifier)
108
+
109
+ def updateTemplate(self, identifier: str, subject: str = None, content: str = None, enabled: bool = None) -> None:
110
+ '''Changes an email template.'''
111
+ return self.api.updateEmailTemplate(identifier, subject, content, enabled)
112
+
113
+ def getTemplateVariables(self, identifier: str) -> list:
114
+ '''Returns variables defined for one template.'''
115
+ return self.api.emailVariables(identifier)
116
+
117
+ def createTemplateVariable(self, identifier: str, name: str, value: str, value_translations: dict = None) -> None:
118
+ '''Defines a variable for one template.'''
119
+ return self.api.createEmailVariable(name, value, value_translations, identifier)
120
+
121
+ def updateTemplateVariable(self, identifier: str, name: str, value: str = None, value_translations: dict = None) -> None:
122
+ '''Changes a template variable.'''
123
+ return self.api.updateEmailVariable(name, value, value_translations, identifier)
124
+
125
+ def deleteTemplateVariable(self, identifier: str, name: str) -> None:
126
+ '''Deletes a template variable.'''
127
+ return self.api.deleteEmailVariable(name, identifier)
128
+
129
+ def getVariables(self) -> list:
130
+ '''Returns global email variables.'''
131
+ return self.api.emailVariables()
132
+
133
+ def createVariable(self, name: str, value: str, value_translations: dict = None) -> None:
134
+ '''Defines a global email variable.'''
135
+ return self.api.createEmailVariable(name, value, value_translations)
136
+
137
+ def updateVariable(self, name: str, value: str = None, value_translations: dict = None) -> None:
138
+ '''Changes a global email variable.'''
139
+ return self.api.updateEmailVariable(name, value, value_translations)
140
+
141
+ def deleteVariable(self, name: str) -> None:
142
+ '''Deletes a global email variable.'''
143
+ return self.api.deleteEmailVariable(name)
144
+
145
+
146
+ class ExtensionManager:
147
+ '''
148
+ Panel extensions, available as `panel.admin.extensions`.
149
+
150
+ Example:
151
+ for extension in panel.admin.extensions.getExtensions():
152
+ print(extension['identifier'])
153
+ panel.admin.extensions.disable('dev.0x7d8.subdomainmanager')
154
+ panel.admin.extensions.restart()
155
+ '''
156
+ VERSION_CHANGER = 'dev.0x7d8.minecraftversionchanger'
157
+
158
+ def __init__(self, panel):
159
+ self.panel = panel
160
+ self.api = panel.api.admin
161
+
162
+ def getInfo(self) -> dict:
163
+ '''Returns installed, disabled and pending extensions.'''
164
+ return self.api.extensions()
165
+
166
+ def getExtensions(self) -> list:
167
+ '''Returns installed extensions.'''
168
+ return self.getInfo().get('extensions', [])
169
+
170
+ def setEnabled(self, extension: str, enabled: bool) -> bool:
171
+ '''Enables or disables an extension. Returns True if a restart is needed.'''
172
+ return self.api.setExtensionEnabled(extension, enabled)
173
+
174
+ def enable(self, extension: str) -> bool:
175
+ '''Enables an extension.'''
176
+ return self.setEnabled(extension, True)
177
+
178
+ def disable(self, extension: str) -> bool:
179
+ '''Disables an extension.'''
180
+ return self.setEnabled(extension, False)
181
+
182
+ def getStatus(self) -> dict:
183
+ '''Returns build status, running version and pending changes.'''
184
+ return self.api.manageExtensions('status')
185
+
186
+ def install(self, file, accept_license: bool = False) -> dict:
187
+ '''
188
+ Uploads and installs an extension package.
189
+
190
+ Args:
191
+ file: Local path or bytes of the extension archive.
192
+ accept_license: Accept the extension's license.
193
+ '''
194
+ if isinstance(file, (str, os.PathLike)):
195
+ with open(file, 'rb') as f:
196
+ file = f.read()
197
+ return self.api.manageExtensions('add', 'PUT', params={'accept_license': accept_license}, data=file,
198
+ headers={'Content-Type': 'application/octet-stream'})
199
+
200
+ def remove(self, extension: str, remove_migrations: bool = False) -> None:
201
+ '''Uninstalls an extension.'''
202
+ return self.api.removeExtension(extension, remove_migrations)
203
+
204
+ def rebuild(self, force: bool = False) -> str:
205
+ '''Rebuilds the panel with the current extensions. Returns the build id.'''
206
+ return self.api.manageExtensions('rebuild', 'POST', params={'force': force})['build_id']
207
+
208
+ def cancelRebuild(self, build_id: str = None) -> str:
209
+ '''Cancels a running rebuild.'''
210
+ return self.api.manageExtensions('rebuild/cancel', 'POST', params={'build_id': build_id})['build_id']
211
+
212
+ def getBuildLogs(self, build_id: str = None, from_offset: int = None) -> dict:
213
+ '''Returns build output (offset, data, eof).'''
214
+ return self.api.manageExtensions('logs', params={'build_id': build_id, 'from_offset': from_offset})
215
+
216
+ def restart(self) -> None:
217
+ '''Restarts the panel to apply extension changes.'''
218
+ return self.api.manageExtensions('restart', 'POST')
219
+
220
+ # Minecraft Version Changer
221
+ def getVersionChangerSettings(self) -> dict:
222
+ '''Returns the Minecraft Version Changer settings.'''
223
+ return self.api.extension(self.VERSION_CHANGER, 'settings')['settings']
224
+
225
+ def updateVersionChangerSettings(self, **settings) -> None:
226
+ '''Changes Minecraft Version Changer settings (mcjars_url, mcjars_api_key, type_egg_assignments, ...).'''
227
+ return self.api.extension(self.VERSION_CHANGER, 'settings', 'PUT', json=settings)
228
+
229
+ def getVersionChangerStatistics(self) -> dict:
230
+ '''Returns install statistics by server type and version.'''
231
+ return self.api.extension(self.VERSION_CHANGER, 'statistics/total')
232
+
233
+ def getVersionChangerDefaultOrder(self) -> list:
234
+ '''Returns the default order of server types in the version picker.'''
235
+ return self.api.extension(self.VERSION_CHANGER, 'default-order')['mcjars_type_order']
236
+
237
+
238
+ class AssetManager:
239
+ '''
240
+ Panel assets (logos, images), available as `panel.admin.assets`.
241
+
242
+ Example:
243
+ panel.admin.assets.upload('logo.png', directory='branding')
244
+ '''
245
+ def __init__(self, panel):
246
+ self.panel = panel
247
+ self.api = panel.api.admin
248
+
249
+ def getAssets(self, directory: str = None, page: int = None, per_page: int = None):
250
+ '''Lists assets.'''
251
+ return self.api.assets(directory, page, per_page)
252
+
253
+ def upload(self, file, directory: str = None, content_type: str = 'application/octet-stream') -> list:
254
+ '''Uploads an asset from a local path or bytes.'''
255
+ if isinstance(file, (str, os.PathLike)):
256
+ with open(file, 'rb') as f:
257
+ file = f.read()
258
+ return self.api.uploadAsset(file, directory, content_type)
259
+
260
+ def search(self, query: str, directory: str = None, per_page: int = None) -> list:
261
+ '''Searches assets by name.'''
262
+ return self.api.searchAssets(query, directory, per_page)
263
+
264
+ def delete(self, names: list) -> int:
265
+ '''Deletes assets by name. Returns how many were deleted.'''
266
+ return self.api.deleteAssets(names)
267
+
268
+
269
+ class Admin:
270
+ '''
271
+ Panel administration, available as `panel.admin`. Requires an API key with admin permissions.
272
+
273
+ Managers:
274
+ users, servers, nodes, locations, nests, mounts, devices, roles,
275
+ announcements, oauth, database_hosts, database_agent_hosts,
276
+ database_templates, backup_configurations, backup_policies,
277
+ egg_repositories, egg_configurations, subdomain_domains,
278
+ system, email, extensions, assets
279
+
280
+ Example:
281
+ for node in panel.admin.nodes.getNodes():
282
+ print(node.getName(), node.isInMaintenance())
283
+
284
+ user = panel.admin.users.createUser('steve', 'steve@example.com')
285
+ panel.admin.servers.deployServer('Steve SMP', user, paper_egg, locations=[eu])
286
+ '''
287
+ def __init__(self, panel):
288
+ self.panel = panel
289
+ self.api = panel.api.admin
290
+
291
+ self.users = UserManager(panel)
292
+ self.servers = AdminServerManager(panel)
293
+ self.nodes = NodeManager(panel)
294
+ self.locations = LocationManager(panel)
295
+ self.nests = NestManager(panel)
296
+ self.mounts = MountManager(panel)
297
+ self.devices = DeviceManager(panel)
298
+ self.roles = RoleManager(panel)
299
+ self.announcements = AnnouncementManager(panel)
300
+ self.oauth = OAuthProviderManager(panel)
301
+ self.database_hosts = DatabaseHostManager(panel)
302
+ self.database_agent_hosts = DatabaseAgentHostManager(panel)
303
+ self.database_templates = DatabaseAgentTemplateManager(panel)
304
+ self.backup_configurations = BackupConfigurationManager(panel)
305
+ self.backup_policies = BackupPolicyManager(panel)
306
+ self.egg_repositories = EggRepositoryManager(panel)
307
+ self.egg_configurations = EggConfigurationManager(panel)
308
+ self.subdomain_domains = SubdomainDomainManager(panel)
309
+
310
+ self.system = SystemManager(panel)
311
+ self.email = EmailManager(panel)
312
+ self.extensions = ExtensionManager(panel)
313
+ self.assets = AssetManager(panel)
314
+
315
+ def getSettings(self) -> dict:
316
+ '''Returns the panel settings.'''
317
+ return self.api.settings()
318
+
319
+ def updateSettings(self, **sections) -> None:
320
+ '''
321
+ Changes panel settings. Pass whole sections, e.g. app, server, user,
322
+ activity, ratelimits, webauthn, mail_mode, captcha_provider.
323
+
324
+ Example:
325
+ settings = panel.admin.getSettings()
326
+ settings['app']['name'] = 'My Hosting'
327
+ panel.admin.updateSettings(app=settings['app'])
328
+ '''
329
+ return self.api.updateSettings(**sections)
330
+
331
+ def getActivity(self, search: str = None, user=None, page: int = 1, per_page: int = 50):
332
+ '''Returns the panel-wide admin activity log.'''
333
+ return self.api.activity(idOf(user), search, page, per_page).map(lambda data: Activity(self.panel, data))
334
+
335
+ def getStats(self) -> dict:
336
+ '''Returns panel statistics (users, servers, nodes, ...).'''
337
+ return self.api.generalStats()
338
+
339
+ def getBackupStats(self) -> dict:
340
+ '''Returns backup statistics for today, this week, this month and all time.'''
341
+ return self.api.backupStats()