python-xbox 0.1.0rc0__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 (63) hide show
  1. python_xbox-0.1.0rc0.dist-info/METADATA +213 -0
  2. python_xbox-0.1.0rc0.dist-info/RECORD +63 -0
  3. python_xbox-0.1.0rc0.dist-info/WHEEL +4 -0
  4. python_xbox-0.1.0rc0.dist-info/entry_points.txt +6 -0
  5. python_xbox-0.1.0rc0.dist-info/licenses/LICENSE +19 -0
  6. webapi/__init__.py +4 -0
  7. webapi/api/__init__.py +0 -0
  8. webapi/api/client.py +166 -0
  9. webapi/api/language.py +70 -0
  10. webapi/api/provider/__init__.py +0 -0
  11. webapi/api/provider/account/__init__.py +71 -0
  12. webapi/api/provider/account/models.py +11 -0
  13. webapi/api/provider/achievements/__init__.py +164 -0
  14. webapi/api/provider/achievements/models.py +133 -0
  15. webapi/api/provider/baseprovider.py +16 -0
  16. webapi/api/provider/catalog/__init__.py +88 -0
  17. webapi/api/provider/catalog/const.py +15 -0
  18. webapi/api/provider/catalog/models.py +428 -0
  19. webapi/api/provider/cqs/__init__.py +85 -0
  20. webapi/api/provider/cqs/models.py +59 -0
  21. webapi/api/provider/gameclips/__init__.py +167 -0
  22. webapi/api/provider/gameclips/models.py +59 -0
  23. webapi/api/provider/lists/__init__.py +71 -0
  24. webapi/api/provider/lists/models.py +35 -0
  25. webapi/api/provider/mediahub/__init__.py +64 -0
  26. webapi/api/provider/mediahub/models.py +84 -0
  27. webapi/api/provider/message/__init__.py +135 -0
  28. webapi/api/provider/message/models.py +96 -0
  29. webapi/api/provider/people/__init__.py +193 -0
  30. webapi/api/provider/people/models.py +252 -0
  31. webapi/api/provider/presence/__init__.py +112 -0
  32. webapi/api/provider/presence/models.py +54 -0
  33. webapi/api/provider/profile/__init__.py +142 -0
  34. webapi/api/provider/profile/models.py +48 -0
  35. webapi/api/provider/ratelimitedprovider.py +77 -0
  36. webapi/api/provider/screenshots/__init__.py +167 -0
  37. webapi/api/provider/screenshots/models.py +56 -0
  38. webapi/api/provider/smartglass/__init__.py +399 -0
  39. webapi/api/provider/smartglass/models.py +187 -0
  40. webapi/api/provider/titlehub/__init__.py +141 -0
  41. webapi/api/provider/titlehub/models.py +106 -0
  42. webapi/api/provider/usersearch/__init__.py +29 -0
  43. webapi/api/provider/usersearch/models.py +19 -0
  44. webapi/api/provider/userstats/__init__.py +166 -0
  45. webapi/api/provider/userstats/models.py +46 -0
  46. webapi/authentication/__init__.py +0 -0
  47. webapi/authentication/manager.py +162 -0
  48. webapi/authentication/models.py +163 -0
  49. webapi/authentication/xal.py +348 -0
  50. webapi/common/__init__.py +0 -0
  51. webapi/common/exceptions.py +57 -0
  52. webapi/common/filetimes.py +97 -0
  53. webapi/common/models.py +34 -0
  54. webapi/common/ratelimits/__init__.py +269 -0
  55. webapi/common/ratelimits/models.py +23 -0
  56. webapi/common/request_signer.py +189 -0
  57. webapi/common/signed_session.py +54 -0
  58. webapi/scripts/__init__.py +15 -0
  59. webapi/scripts/authenticate.py +159 -0
  60. webapi/scripts/change_gamertag.py +111 -0
  61. webapi/scripts/friends.py +80 -0
  62. webapi/scripts/search.py +43 -0
  63. webapi/scripts/xal.py +113 -0
@@ -0,0 +1,399 @@
1
+ """
2
+ SmartGlass - Control Registered Devices
3
+ """
4
+
5
+ from typing import List, Optional
6
+ from uuid import uuid4
7
+
8
+ from httpx import Response
9
+
10
+ from xbox.webapi.api.provider.baseprovider import BaseProvider
11
+ from xbox.webapi.api.provider.smartglass.models import (
12
+ CommandResponse,
13
+ GuideTab,
14
+ InputKeyType,
15
+ InstalledPackagesList,
16
+ OperationStatusResponse,
17
+ SmartglassConsoleList,
18
+ SmartglassConsoleStatus,
19
+ StorageDevicesList,
20
+ VolumeDirection,
21
+ )
22
+
23
+
24
+ class SmartglassProvider(BaseProvider):
25
+ SG_URL = "https://xccs.xboxlive.com"
26
+ HEADERS_SG = {
27
+ "x-xbl-contract-version": "4",
28
+ "skillplatform": "RemoteManagement",
29
+ }
30
+
31
+ def __init__(self, client):
32
+ """
33
+ Initialize Baseclass, create smartglass session id
34
+
35
+ Args: Instance of XBL client
36
+ """
37
+ super().__init__(client)
38
+ self._smartglass_session_id = str(uuid4())
39
+
40
+ async def get_console_list(
41
+ self, include_storage_devices: bool = True, **kwargs
42
+ ) -> SmartglassConsoleList:
43
+ """
44
+ Get Console list
45
+
46
+ Args:
47
+ include_storage_devices: Include a list of storage devices in the response
48
+
49
+ Returns: Console List
50
+ """
51
+ params = {
52
+ "queryCurrentDevice": "false",
53
+ "includeStorageDevices": str(include_storage_devices).lower(),
54
+ }
55
+ resp = await self._fetch_list("devices", params, **kwargs)
56
+ return SmartglassConsoleList(**resp.json())
57
+
58
+ async def get_installed_apps(
59
+ self, device_id: Optional[str] = None, **kwargs
60
+ ) -> InstalledPackagesList:
61
+ """
62
+ Get Installed Apps
63
+
64
+ Args:
65
+ device_id: ID of console (from console list)
66
+
67
+ Returns: Installed Apps
68
+ """
69
+ params = {}
70
+ if device_id:
71
+ params["deviceId"] = device_id
72
+ resp = await self._fetch_list("installedApps", params, **kwargs)
73
+ return InstalledPackagesList(**resp.json())
74
+
75
+ async def get_storage_devices(self, device_id: str, **kwargs) -> StorageDevicesList:
76
+ """
77
+ Get Installed Apps
78
+
79
+ Args:
80
+ device_id: ID of console (from console list)
81
+
82
+ Returns: Storage Devices list
83
+ """
84
+ params = {"deviceId": device_id}
85
+ resp = await self._fetch_list("storageDevices", params, **kwargs)
86
+ return StorageDevicesList(**resp.json())
87
+
88
+ async def get_console_status(
89
+ self, device_id: str, **kwargs
90
+ ) -> SmartglassConsoleStatus:
91
+ """
92
+ Get Console Status
93
+
94
+ Args:
95
+ device_id: ID of console (from console list)
96
+
97
+ Returns: Console Status
98
+ """
99
+ url = f"{self.SG_URL}/consoles/{device_id}"
100
+ resp = await self.client.session.get(url, headers=self.HEADERS_SG, **kwargs)
101
+ resp.raise_for_status()
102
+ return SmartglassConsoleStatus(**resp.json())
103
+
104
+ async def get_op_status(
105
+ self, device_id: str, op_id: str, **kwargs
106
+ ) -> OperationStatusResponse:
107
+ """
108
+ Get Operation Status
109
+
110
+ Args:
111
+ device_id: ID of console (from console list)
112
+ op_id: Operation ID (from previous command)
113
+
114
+ Returns: Operation Status
115
+ """
116
+ url = f"{self.SG_URL}/opStatus"
117
+ headers = {
118
+ "x-xbl-contract-version": "3",
119
+ "x-xbl-opId": op_id,
120
+ "x-xbl-deviceId": device_id,
121
+ }
122
+ resp = await self.client.session.get(url, headers=headers, **kwargs)
123
+ resp.raise_for_status()
124
+ return OperationStatusResponse(**resp.json())
125
+
126
+ async def wake_up(self, device_id: str, **kwargs) -> CommandResponse:
127
+ """
128
+ Wake Up Console
129
+
130
+ Args:
131
+ device_id: ID of console (from console list)
132
+
133
+ Returns: Command Response
134
+ """
135
+ return await self._send_one_shot_command(device_id, "Power", "WakeUp", **kwargs)
136
+
137
+ async def turn_off(self, device_id: str, **kwargs) -> CommandResponse:
138
+ """
139
+ Turn Off Console
140
+
141
+ Args:
142
+ device_id: ID of console (from console list)
143
+
144
+ Returns: Command Response
145
+ """
146
+ return await self._send_one_shot_command(
147
+ device_id, "Power", "TurnOff", **kwargs
148
+ )
149
+
150
+ async def reboot(self, device_id: str, **kwargs) -> CommandResponse:
151
+ """
152
+ Reboot Console
153
+
154
+ Args:
155
+ device_id: ID of console (from console list)
156
+
157
+ Returns: Command Response
158
+ """
159
+ return await self._send_one_shot_command(device_id, "Power", "Reboot", **kwargs)
160
+
161
+ async def mute(self, device_id: str, **kwargs) -> CommandResponse:
162
+ """
163
+ Mute
164
+
165
+ Args:
166
+ device_id: ID of console (from console list)
167
+
168
+ Returns: Command Response
169
+ """
170
+ return await self._send_one_shot_command(device_id, "Audio", "Mute", **kwargs)
171
+
172
+ async def unmute(self, device_id: str, **kwargs) -> CommandResponse:
173
+ """
174
+ Unmute
175
+
176
+ Args:
177
+ device_id: ID of console (from console list)
178
+
179
+ Returns: Command Response
180
+ """
181
+ return await self._send_one_shot_command(device_id, "Audio", "Unmute", **kwargs)
182
+
183
+ async def volume(
184
+ self, device_id: str, direction: VolumeDirection, amount: int = 1, **kwargs
185
+ ) -> CommandResponse:
186
+ """
187
+ Adjust Volume
188
+
189
+ Args:
190
+ device_id: ID of console (from console list)
191
+
192
+ Returns: Command Response
193
+ """
194
+ params = [{"direction": direction.value, "amount": str(amount)}]
195
+ return await self._send_one_shot_command(
196
+ device_id, "Audio", "Volume", params, **kwargs
197
+ )
198
+
199
+ async def play(self, device_id: str, **kwargs) -> CommandResponse:
200
+ """
201
+ Play (media controls)
202
+
203
+ Args:
204
+ device_id: ID of console (from console list)
205
+
206
+ Returns: Command Response
207
+ """
208
+ return await self._send_one_shot_command(device_id, "Media", "Play", **kwargs)
209
+
210
+ async def pause(self, device_id: str, **kwargs) -> CommandResponse:
211
+ """
212
+ Pause (media controls)
213
+
214
+ Args:
215
+ device_id: ID of console (from console list)
216
+
217
+ Returns: Command Response
218
+ """
219
+ return await self._send_one_shot_command(device_id, "Media", "Pause", **kwargs)
220
+
221
+ async def previous(self, device_id: str, **kwargs) -> CommandResponse:
222
+ """
223
+ Previous (media controls)
224
+
225
+ Args:
226
+ device_id: ID of console (from console list)
227
+
228
+ Returns: Command Response
229
+ """
230
+ return await self._send_one_shot_command(
231
+ device_id, "Media", "Previous", **kwargs
232
+ )
233
+
234
+ async def next(self, device_id: str, **kwargs) -> CommandResponse:
235
+ """
236
+ Next (media controls)
237
+
238
+ Args:
239
+ device_id: ID of console (from console list)
240
+
241
+ Returns: Command Response
242
+ """
243
+ return await self._send_one_shot_command(device_id, "Media", "Next", **kwargs)
244
+
245
+ async def go_home(self, device_id: str, **kwargs) -> CommandResponse:
246
+ """
247
+ Go Home
248
+
249
+ Args:
250
+ device_id: ID of console (from console list)
251
+
252
+ Returns: Command Response
253
+ """
254
+ return await self._send_one_shot_command(device_id, "Shell", "GoHome", **kwargs)
255
+
256
+ async def go_back(self, device_id: str, **kwargs) -> CommandResponse:
257
+ """
258
+ Go Back
259
+
260
+ Args:
261
+ device_id: ID of console (from console list)
262
+
263
+ Returns:
264
+ :class:`SmartglassConsoleStatus`: Command Response
265
+ """
266
+ return await self._send_one_shot_command(device_id, "Shell", "GoBack", **kwargs)
267
+
268
+ async def show_guide_tab(
269
+ self, device_id: str, tab: GuideTab = GuideTab.Guide, **kwargs
270
+ ) -> CommandResponse:
271
+ """
272
+ Show Guide Tab
273
+
274
+ Args:
275
+ device_id: ID of console (from console list)
276
+
277
+ Returns: Command Response
278
+ """
279
+ params = [{"tabName": tab.value}]
280
+ return await self._send_one_shot_command(
281
+ device_id, "Shell", "ShowGuideTab", params, **kwargs
282
+ )
283
+
284
+ async def press_button(
285
+ self, device_id: str, button: InputKeyType, **kwargs
286
+ ) -> CommandResponse:
287
+ """
288
+ Press Button
289
+
290
+ Args:
291
+ device_id: ID of console (from console list)
292
+
293
+ Returns: Command Response
294
+ """
295
+ params = [{"keyType": button.value}]
296
+ return await self._send_one_shot_command(
297
+ device_id, "Shell", "InjectKey", params, **kwargs
298
+ )
299
+
300
+ async def insert_text(self, device_id: str, text: str, **kwargs) -> CommandResponse:
301
+ """
302
+ Insert Text
303
+
304
+ Args:
305
+ device_id: ID of console (from console list)
306
+
307
+ Returns: Command Response
308
+ """
309
+ params = [{"replacementString": text}]
310
+ return await self._send_one_shot_command(
311
+ device_id, "Shell", "InjectString", params, **kwargs
312
+ )
313
+
314
+ async def launch_app(
315
+ self, device_id: str, one_store_product_id: str, **kwargs
316
+ ) -> CommandResponse:
317
+ """
318
+ Launch Application
319
+
320
+ Args:
321
+ device_id: ID of console (from console list)
322
+ one_store_product_id: OneStoreProductID for the app to launch
323
+
324
+ Returns: Command Response
325
+ """
326
+ params = [{"oneStoreProductId": one_store_product_id}]
327
+ return await self._send_one_shot_command(
328
+ device_id,
329
+ "Shell",
330
+ "ActivateApplicationWithOneStoreProductId",
331
+ params,
332
+ **kwargs,
333
+ )
334
+
335
+ async def show_tv_guide(self, device_id: str, **kwargs) -> CommandResponse:
336
+ """
337
+ Show TV Guide
338
+
339
+ Args:
340
+ device_id: ID of console (from console list)
341
+
342
+ Returns: Command Response
343
+ """
344
+ return await self._send_one_shot_command(device_id, "TV", "ShowGuide", **kwargs)
345
+
346
+ async def _fetch_list(
347
+ self, list_name: str, params: Optional[dict] = None, **kwargs
348
+ ) -> Response:
349
+ """
350
+ Fetch arbitrary list
351
+
352
+ Args:
353
+ list_name: name of list
354
+ params: query params
355
+
356
+ Returns:
357
+ :class:`httpx.Response`: HTTP Response
358
+ """
359
+ url = f"{self.SG_URL}/lists/{list_name}"
360
+ resp = await self.client.session.get(
361
+ url, params=params, headers=self.HEADERS_SG, **kwargs
362
+ )
363
+ resp.raise_for_status()
364
+ return resp
365
+
366
+ async def _send_one_shot_command(
367
+ self,
368
+ device_id: str,
369
+ command_type: str,
370
+ command: str,
371
+ params: Optional[List[dict]] = None,
372
+ **kwargs,
373
+ ) -> CommandResponse:
374
+ """
375
+ Send One Shot command to console
376
+
377
+ Args:
378
+ device_id: ID of console (from console list)
379
+ type: type of command
380
+ command: name of command
381
+ params: command parameters
382
+
383
+ Returns: Command Response
384
+ """
385
+ url = f"{self.SG_URL}/commands"
386
+ body = {
387
+ "destination": "Xbox",
388
+ "type": command_type,
389
+ "command": command,
390
+ "sessionId": self._smartglass_session_id,
391
+ "sourceId": "com.microsoft.smartglass",
392
+ "parameters": params or [{}],
393
+ "linkedXboxId": device_id,
394
+ }
395
+ resp = await self.client.session.post(
396
+ url, json=body, headers=self.HEADERS_SG, **kwargs
397
+ )
398
+ resp.raise_for_status()
399
+ return CommandResponse(**resp.json())
@@ -0,0 +1,187 @@
1
+ from datetime import datetime
2
+ from enum import Enum
3
+ from typing import List, Optional
4
+
5
+ from xbox.webapi.common.models import CamelCaseModel
6
+
7
+ # Responses
8
+
9
+
10
+ class ConsoleType(str, Enum):
11
+ XboxOne = "XboxOne"
12
+ XboxOneS = "XboxOneS"
13
+ XboxOneSDigital = "XboxOneSDigital"
14
+ XboxOneX = "XboxOneX"
15
+ XboxSeriesS = "XboxSeriesS"
16
+ XboxSeriesX = "XboxSeriesX"
17
+
18
+
19
+ class PowerState(str, Enum):
20
+ Unknown = "Unknown"
21
+ On = "On"
22
+ Off = "Off"
23
+ ConnectedStandby = "ConnectedStandby"
24
+ SystemUpdate = "SystemUpdate"
25
+
26
+
27
+ class PlaybackState(str, Enum):
28
+ Unknown = "Unknown"
29
+ Playing = "Playing"
30
+ Paused = "Paused"
31
+ Stopped = "Stopped"
32
+
33
+
34
+ class ErrorCode(str, Enum):
35
+ OK = "OK"
36
+ CurrentConsoleNotFound = "CurrentConsoleNotFound"
37
+ RemoteManagementDisabled = "RemoteManagementDisabled"
38
+ XboxDataNotFound = "XboxDataNotFound"
39
+ XboxNotPaired = "XboxNotPaired"
40
+
41
+
42
+ class OpStatus(str, Enum):
43
+ Paused = "Paused"
44
+ OffConsoleError = "OffConsoleError"
45
+ Pending = "Pending"
46
+ TimedOut = "TimedOut"
47
+ Error = "Error"
48
+ Succeeded = "Succeeded"
49
+
50
+
51
+ class SmartglassApiStatus(CamelCaseModel):
52
+ error_code: str
53
+ error_message: Optional[str] = None
54
+
55
+
56
+ class StorageDevice(CamelCaseModel):
57
+ storage_device_id: str
58
+ storage_device_name: str
59
+ is_default: bool
60
+ total_space_bytes: float
61
+ free_space_bytes: float
62
+
63
+
64
+ class SmartglassConsole(CamelCaseModel):
65
+ id: str
66
+ name: str
67
+ console_type: ConsoleType
68
+ power_state: PowerState
69
+ console_streaming_enabled: bool
70
+ digital_assistant_remote_control_enabled: bool
71
+ remote_management_enabled: bool
72
+ storage_devices: Optional[List[StorageDevice]] = None
73
+
74
+
75
+ class SmartglassConsoleList(CamelCaseModel):
76
+ agent_user_id: Optional[str] = None
77
+ result: List[SmartglassConsole]
78
+ status: SmartglassApiStatus
79
+
80
+
81
+ class SmartglassConsoleStatus(CamelCaseModel):
82
+ power_state: PowerState
83
+ console_streaming_enabled: bool
84
+ digital_assistant_remote_control_enabled: bool
85
+ remote_management_enabled: bool
86
+ focus_app_aumid: str
87
+ is_tv_configured: bool
88
+ login_state: Optional[str] = None
89
+ playback_state: PlaybackState
90
+ power_state: PowerState
91
+ storage_devices: Optional[List[StorageDevice]] = None
92
+ status: SmartglassApiStatus
93
+
94
+
95
+ class InstalledPackage(CamelCaseModel):
96
+ one_store_product_id: Optional[str] = None
97
+ title_id: int
98
+ aumid: Optional[str] = None
99
+ last_active_time: Optional[datetime] = None
100
+ is_game: bool
101
+ name: Optional[str] = None
102
+ content_type: str
103
+ instance_id: str
104
+ storage_device_id: str
105
+ unique_id: str
106
+ legacy_product_id: Optional[str] = None
107
+ version: int
108
+ size_in_bytes: int
109
+ install_time: datetime
110
+ update_time: Optional[datetime] = None
111
+ parent_id: Optional[str] = None
112
+
113
+
114
+ class InstalledPackagesList(CamelCaseModel):
115
+ result: List[InstalledPackage]
116
+ status: SmartglassApiStatus
117
+ agent_user_id: Optional[str] = None
118
+
119
+
120
+ class StorageDevicesList(CamelCaseModel):
121
+ device_id: str
122
+ result: List[StorageDevice]
123
+ status: SmartglassApiStatus
124
+
125
+
126
+ class OpStatusNode(CamelCaseModel):
127
+ operation_status: OpStatus
128
+ op_id: str
129
+ originating_session_id: str
130
+ command: str
131
+ succeeded: bool
132
+ console_status_code: Optional[int] = None
133
+ xccs_error_code: Optional[ErrorCode] = None
134
+ h_result: Optional[int] = None
135
+ message: Optional[str] = None
136
+
137
+
138
+ class OperationStatusResponse(CamelCaseModel):
139
+ op_status_list: List[OpStatusNode]
140
+ status: SmartglassApiStatus
141
+
142
+
143
+ class CommandDestination(CamelCaseModel):
144
+ id: str
145
+ name: str
146
+ power_state: PowerState
147
+ remote_management_enabled: bool
148
+ console_streaming_enabled: bool
149
+ console_type: ConsoleType
150
+ wireless_warning: Optional[str] = None
151
+ out_of_home_warning: Optional[str] = None
152
+
153
+
154
+ class CommandResponse(CamelCaseModel):
155
+ result: Optional[str] = None
156
+ ui_text: Optional[str] = None
157
+ destination: CommandDestination
158
+ user_info: Optional[str] = None
159
+ op_id: str
160
+ status: SmartglassApiStatus
161
+
162
+
163
+ # Requests
164
+
165
+
166
+ class VolumeDirection(str, Enum):
167
+ Up = "Up"
168
+ Down = "Down"
169
+
170
+
171
+ class InputKeyType(str, Enum):
172
+ Guide = "Guide"
173
+ Menu = "Menu"
174
+ View = "View"
175
+ A = "A"
176
+ B = "B"
177
+ X = "X"
178
+ Y = "Y"
179
+ Up = "Up"
180
+ Down = "Down"
181
+ Left = "Left"
182
+ Right = "Right"
183
+ Nexus = "Nexus"
184
+
185
+
186
+ class GuideTab(str, Enum):
187
+ Guide = "Guide"