python-xbox 0.1.0__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 (64) hide show
  1. python_xbox-0.1.0.dist-info/METADATA +217 -0
  2. python_xbox-0.1.0.dist-info/RECORD +64 -0
  3. python_xbox-0.1.0.dist-info/WHEEL +4 -0
  4. python_xbox-0.1.0.dist-info/entry_points.txt +6 -0
  5. python_xbox-0.1.0.dist-info/licenses/LICENSE +20 -0
  6. pythonxbox/__init__.py +4 -0
  7. pythonxbox/api/__init__.py +0 -0
  8. pythonxbox/api/client.py +166 -0
  9. pythonxbox/api/language.py +76 -0
  10. pythonxbox/api/provider/__init__.py +0 -0
  11. pythonxbox/api/provider/account/__init__.py +73 -0
  12. pythonxbox/api/provider/account/models.py +11 -0
  13. pythonxbox/api/provider/achievements/__init__.py +164 -0
  14. pythonxbox/api/provider/achievements/models.py +133 -0
  15. pythonxbox/api/provider/baseprovider.py +22 -0
  16. pythonxbox/api/provider/catalog/__init__.py +86 -0
  17. pythonxbox/api/provider/catalog/const.py +15 -0
  18. pythonxbox/api/provider/catalog/models.py +428 -0
  19. pythonxbox/api/provider/cqs/__init__.py +85 -0
  20. pythonxbox/api/provider/cqs/models.py +59 -0
  21. pythonxbox/api/provider/gameclips/__init__.py +167 -0
  22. pythonxbox/api/provider/gameclips/models.py +58 -0
  23. pythonxbox/api/provider/lists/__init__.py +71 -0
  24. pythonxbox/api/provider/lists/models.py +33 -0
  25. pythonxbox/api/provider/mediahub/__init__.py +64 -0
  26. pythonxbox/api/provider/mediahub/models.py +82 -0
  27. pythonxbox/api/provider/message/__init__.py +135 -0
  28. pythonxbox/api/provider/message/models.py +96 -0
  29. pythonxbox/api/provider/people/__init__.py +193 -0
  30. pythonxbox/api/provider/people/models.py +252 -0
  31. pythonxbox/api/provider/presence/__init__.py +110 -0
  32. pythonxbox/api/provider/presence/models.py +53 -0
  33. pythonxbox/api/provider/profile/__init__.py +140 -0
  34. pythonxbox/api/provider/profile/models.py +47 -0
  35. pythonxbox/api/provider/ratelimitedprovider.py +79 -0
  36. pythonxbox/api/provider/screenshots/__init__.py +167 -0
  37. pythonxbox/api/provider/screenshots/models.py +56 -0
  38. pythonxbox/api/provider/smartglass/__init__.py +402 -0
  39. pythonxbox/api/provider/smartglass/models.py +186 -0
  40. pythonxbox/api/provider/titlehub/__init__.py +143 -0
  41. pythonxbox/api/provider/titlehub/models.py +106 -0
  42. pythonxbox/api/provider/usersearch/__init__.py +29 -0
  43. pythonxbox/api/provider/usersearch/models.py +17 -0
  44. pythonxbox/api/provider/userstats/__init__.py +164 -0
  45. pythonxbox/api/provider/userstats/models.py +44 -0
  46. pythonxbox/authentication/__init__.py +0 -0
  47. pythonxbox/authentication/manager.py +161 -0
  48. pythonxbox/authentication/models.py +162 -0
  49. pythonxbox/authentication/xal.py +348 -0
  50. pythonxbox/common/__init__.py +0 -0
  51. pythonxbox/common/exceptions.py +59 -0
  52. pythonxbox/common/filetimes.py +81 -0
  53. pythonxbox/common/models.py +34 -0
  54. pythonxbox/common/ratelimits/__init__.py +268 -0
  55. pythonxbox/common/ratelimits/models.py +23 -0
  56. pythonxbox/common/request_signer.py +190 -0
  57. pythonxbox/common/signed_session.py +60 -0
  58. pythonxbox/py.typed +0 -0
  59. pythonxbox/scripts/__init__.py +15 -0
  60. pythonxbox/scripts/authenticate.py +159 -0
  61. pythonxbox/scripts/change_gamertag.py +111 -0
  62. pythonxbox/scripts/friends.py +80 -0
  63. pythonxbox/scripts/search.py +43 -0
  64. pythonxbox/scripts/xal.py +113 -0
@@ -0,0 +1,428 @@
1
+ from datetime import datetime
2
+ from enum import Enum
3
+ from typing import Any
4
+
5
+ from pydantic import Field, field_validator
6
+
7
+ from pythonxbox.common.models import PascalCaseModel
8
+
9
+
10
+ class AlternateIdType(str, Enum):
11
+ LEGACY_XBOX_PRODUCT_ID = "LegacyXboxProductId"
12
+ XBOX_TITLE_ID = "XboxTitleId"
13
+ PACKAGE_FAMILY_NAME = "PackageFamilyName"
14
+
15
+
16
+ class FieldsTemplate(str, Enum):
17
+ BROWSE = "browse"
18
+ DETAILS = "details"
19
+
20
+
21
+ class PlatformType(str, Enum):
22
+ XBOX = "windows.xbox"
23
+ DESKTOP = "windows.desktop"
24
+
25
+
26
+ class Image(PascalCaseModel):
27
+ file_id: str | None = None
28
+ eis_listing_identifier: Any = Field(None, alias="EISListingIdentifier")
29
+ background_color: str | None = None
30
+ caption: str | None = None
31
+ file_size_in_bytes: int
32
+ foreground_color: str | None = None
33
+ height: int
34
+ image_position_info: str | None = None
35
+ image_purpose: str
36
+ unscaled_image_sha256_hash: str | None = Field(
37
+ None, alias="UnscaledImageSHA256Hash"
38
+ )
39
+ uri: str
40
+ width: int
41
+
42
+
43
+ class Video(PascalCaseModel):
44
+ uri: str
45
+ video_purpose: str
46
+ height: int
47
+ width: int
48
+ audio_encoding: str
49
+ video_encoding: str
50
+ video_position_info: str
51
+ caption: str
52
+ file_size_in_bytes: int
53
+ preview_image: Image
54
+ sort_order: int
55
+
56
+
57
+ class SearchTitle(PascalCaseModel):
58
+ search_title_string: str
59
+ search_title_type: str
60
+
61
+
62
+ class ContentRating(PascalCaseModel):
63
+ rating_system: str
64
+ rating_id: str
65
+ rating_descriptors: list[str]
66
+ rating_disclaimers: list
67
+ interactive_elements: list | None = None
68
+
69
+
70
+ class UsageData(PascalCaseModel):
71
+ aggregate_time_span: str
72
+ average_rating: float
73
+ play_count: int | None = None
74
+ rating_count: int
75
+ rental_count: str | None = None
76
+ trial_count: str | None = None
77
+ purchase_count: str | None = None
78
+
79
+
80
+ class ProductProperties(PascalCaseModel):
81
+ attributes: list | None = None
82
+ can_install_to_sd_card: bool | None = Field(None, alias="CanInstallToSDCard")
83
+ category: str | None = None
84
+ sub_category: str | None = None
85
+ categories: list[str] | None = None
86
+ extensions: Any = None
87
+ is_accessible: bool | None = None
88
+ is_line_of_business_app: bool | None = None
89
+ is_published_to_legacy_windows_phone_store: bool | None = None
90
+ is_published_to_legacy_windows_store: bool | None = None
91
+ is_settings_app: bool | None = None
92
+ package_family_name: str | None = None
93
+ package_identity_name: str | None = None
94
+ publisher_certificate_name: str | None = None
95
+ publisher_id: str
96
+ xbox_live_tier: Any = None
97
+ xbox_xpa: Any = Field(None, alias="XboxXPA")
98
+ xbox_cross_gen_set_id: Any = None
99
+ xbox_console_gen_optimized: Any = None
100
+ xbox_console_gen_compatible: Any = None
101
+ xbox_live_gold_required: bool | None = None
102
+ ownership_type: Any = None
103
+ pdp_background_color: str | None = None
104
+ has_add_ons: bool | None = None
105
+ revision_id: str
106
+ product_group_id: str | None = None
107
+ product_group_name: str | None = None
108
+
109
+
110
+ class AlternateId(PascalCaseModel):
111
+ id_type: str
112
+ value: str
113
+
114
+
115
+ class ValidationData(PascalCaseModel):
116
+ passed_validation: bool
117
+ revision_id: str
118
+ validation_result_uri: str | None = None
119
+
120
+
121
+ class FulfillmentData(PascalCaseModel):
122
+ product_id: str
123
+ wu_bundle_id: str | None = None
124
+ wu_category_id: str
125
+ package_family_name: str
126
+ sku_id: str
127
+ content: Any = None
128
+ package_features: Any = None
129
+
130
+
131
+ class HardwareProperties(PascalCaseModel):
132
+ minimum_hardware: list
133
+ recommended_hardware: list
134
+ minimum_processor: Any = None
135
+ recommended_processor: Any = None
136
+ minimum_graphics: Any = None
137
+ recommended_graphics: Any = None
138
+
139
+
140
+ class Application(PascalCaseModel):
141
+ application_id: str
142
+ declaration_order: int
143
+ extensions: list[str]
144
+
145
+
146
+ class FrameworkDependency(PascalCaseModel):
147
+ max_tested: int
148
+ min_version: int
149
+ package_identity: str
150
+
151
+
152
+ class PlatformDependency(PascalCaseModel):
153
+ max_tested: int | None = None
154
+ min_version: int | None = None
155
+ platform_name: str
156
+
157
+
158
+ class Package(PascalCaseModel):
159
+ applications: list[Application] | None = None
160
+ architectures: list[str]
161
+ capabilities: list[str] | None = None
162
+ device_capabilities: list[str] | None = None
163
+ experience_ids: list | None = None
164
+ framework_dependencies: list[FrameworkDependency] | None = None
165
+ hardware_dependencies: list | None = None
166
+ hardware_requirements: list | None = None
167
+ hash: str | None = None
168
+ hash_algorithm: str | None = None
169
+ is_streaming_app: bool | None = None
170
+ languages: list[str] | None = None
171
+ max_download_size_in_bytes: int
172
+ max_install_size_in_bytes: int | None = None
173
+ package_format: str
174
+ package_family_name: str | None = None
175
+ main_package_family_name_for_dlc: Any = None
176
+ package_full_name: str | None = None
177
+ package_id: str
178
+ content_id: str
179
+ key_id: str | None = None
180
+ package_rank: int | None = None
181
+ package_uri: str | None = None
182
+ platform_dependencies: list[PlatformDependency] | None = None
183
+ platform_dependency_xml_blob: str | None = None
184
+ resource_id: str | None = None
185
+ version: str | None = None
186
+ package_download_uris: Any = None
187
+ driver_dependencies: list | None = None
188
+ fulfillment_data: FulfillmentData | None = None
189
+
190
+
191
+ class LegalText(PascalCaseModel):
192
+ additional_license_terms: str
193
+ copyright: str
194
+ copyright_uri: str
195
+ privacy_policy: str
196
+ privacy_policy_uri: str
197
+ tou: str
198
+ tou_uri: str
199
+
200
+
201
+ class SkuLocalizedProperty(PascalCaseModel):
202
+ contributors: list | None = None
203
+ features: list | None = None
204
+ minimum_notes: str | None = None
205
+ recommended_notes: str | None = None
206
+ release_notes: str | None = None
207
+ display_platform_properties: Any = None
208
+ sku_description: str
209
+ sku_title: str
210
+ sku_button_title: str | None = None
211
+ delivery_date_overlay: Any = None
212
+ sku_display_rank: list | None = None
213
+ text_resources: Any = None
214
+ images: list | None = None
215
+ legal_text: LegalText | None = None
216
+ language: str
217
+ markets: list[str]
218
+
219
+
220
+ class SkuMarketProperty(PascalCaseModel):
221
+ first_available_date: datetime | str | None = None
222
+ supported_languages: list[str] | None = None
223
+ package_ids: Any = None
224
+ pi_filter: Any = Field(None, alias="PIFilter")
225
+ markets: list[str]
226
+
227
+
228
+ class SkuProperties(PascalCaseModel):
229
+ early_adopter_enrollment_url: Any = None
230
+ fulfillment_data: FulfillmentData | None = None
231
+ fulfillment_type: str | None = None
232
+ fulfillment_plugin_id: Any = None
233
+ has_third_party_iaps: bool | None = Field(None, alias="HasThirdPartyIAPs")
234
+ last_update_date: datetime | None = None
235
+ hardware_properties: HardwareProperties | None = None
236
+ hardware_requirements: list | None = None
237
+ hardware_warning_list: list | None = None
238
+ installation_terms: str
239
+ packages: list[Package] | None = None
240
+ version_string: str | None = None
241
+ visible_to_b2b_service_ids: list = Field(alias="VisibleToB2BServiceIds")
242
+ xbox_xpa: bool | None = Field(None, alias="XboxXPA")
243
+ bundled_skus: list | None = None
244
+ is_repurchasable: bool
245
+ sku_display_rank: int
246
+ display_physical_store_inventory: Any = None
247
+ additional_identifiers: list
248
+ is_trial: bool
249
+ is_pre_order: bool
250
+ is_bundle: bool
251
+
252
+ @field_validator("last_update_date", mode="before", check_fields=True)
253
+ def validator(x: "SkuProperties") -> "SkuProperties":
254
+ return x or None
255
+
256
+
257
+ class Sku(PascalCaseModel):
258
+ last_modified_date: datetime
259
+ localized_properties: list[SkuLocalizedProperty]
260
+ market_properties: list[SkuMarketProperty]
261
+ product_id: str
262
+ properties: SkuProperties
263
+ sku_a_schema: str
264
+ sku_b_schema: str
265
+ sku_id: str
266
+ sku_type: str
267
+ recurrence_policy: Any = None
268
+ subscription_policy_id: Any = None
269
+
270
+
271
+ class AllowedPlatform(PascalCaseModel):
272
+ max_version: int | None = None
273
+ min_version: int | None = None
274
+ platform_name: str
275
+
276
+
277
+ class ClientConditions(PascalCaseModel):
278
+ allowed_platforms: list[AllowedPlatform]
279
+
280
+
281
+ class Conditions(PascalCaseModel):
282
+ client_conditions: ClientConditions
283
+ end_date: datetime
284
+ resource_set_ids: list[str]
285
+ start_date: datetime
286
+
287
+
288
+ class PIFilter(PascalCaseModel):
289
+ exclusion_properties: list
290
+ inclusion_properties: list
291
+
292
+
293
+ class Price(PascalCaseModel):
294
+ currency_code: str
295
+ is_pi_required: bool = Field(alias="IsPIRequired")
296
+ list_price: float
297
+ msrp: float = Field(alias="MSRP")
298
+ tax_type: str
299
+ wholesale_currency_code: str
300
+
301
+
302
+ class OrderManagementData(PascalCaseModel):
303
+ granted_entitlement_keys: list | None = None
304
+ pi_filter: PIFilter | None = Field(None, alias="PIFilter")
305
+ price: Price
306
+
307
+
308
+ class AvailabilityProperties(PascalCaseModel):
309
+ original_release_date: datetime | None = None
310
+
311
+
312
+ class SatisfyingEntitlementKey(PascalCaseModel):
313
+ entitlement_keys: list[str]
314
+ licensing_key_ids: list[str]
315
+
316
+
317
+ class LicensingData(PascalCaseModel):
318
+ satisfying_entitlement_keys: list[SatisfyingEntitlementKey]
319
+
320
+
321
+ class Availability(PascalCaseModel):
322
+ actions: list[str]
323
+ availability_a_schema: str | None = None
324
+ availability_b_schema: str | None = None
325
+ availability_id: str | None = None
326
+ conditions: Conditions | None = None
327
+ last_modified_date: datetime | None = None
328
+ markets: list[str] | None = None
329
+ order_management_data: OrderManagementData | None = None
330
+ properties: AvailabilityProperties | None = None
331
+ sku_id: str | None = None
332
+ display_rank: int | None = None
333
+ remediation_required: bool | None = None
334
+ licensing_data: LicensingData | None = None
335
+
336
+
337
+ class DisplaySkuAvailability(PascalCaseModel):
338
+ sku: Sku | None = None
339
+ availabilities: list[Availability]
340
+
341
+
342
+ class LocalizedProperty(PascalCaseModel):
343
+ developer_name: str | None = None
344
+ display_platform_properties: Any | None = None
345
+ publisher_name: str | None = None
346
+ publisher_website_uri: str | None = None
347
+ support_uri: str | None = None
348
+ eligibility_properties: Any | None = None
349
+ franchises: list | None = None
350
+ images: list[Image]
351
+ videos: list[Video] | None = None
352
+ product_description: str | None = None
353
+ product_title: str
354
+ short_title: str | None = None
355
+ sort_title: str | None = None
356
+ friendly_title: str | None = None
357
+ short_description: str | None = None
358
+ search_titles: list[SearchTitle] | None = None
359
+ voice_title: str | None = None
360
+ render_group_details: Any | None = None
361
+ product_display_ranks: list | None = None
362
+ interactive_model_config: Any | None = None
363
+ interactive_3d_enabled: bool | None = Field(None, alias="Interactive3DEnabled")
364
+ language: str | None = None
365
+ markets: list[str] | None = None
366
+
367
+
368
+ class MarketProperty(PascalCaseModel):
369
+ original_release_date: datetime | None = None
370
+ original_release_friendly_name: str | None = None
371
+ minimum_user_age: int | None = None
372
+ content_ratings: list[ContentRating] | None = None
373
+ related_products: list | None = None
374
+ usage_data: list[UsageData]
375
+ bundle_config: Any | None = None
376
+ markets: list[str] | None = None
377
+
378
+
379
+ class Product(PascalCaseModel):
380
+ last_modified_date: datetime | None = None
381
+ localized_properties: list[LocalizedProperty]
382
+ market_properties: list[MarketProperty]
383
+ product_a_schema: str | None = None
384
+ product_b_schema: str | None = None
385
+ product_id: str
386
+ properties: ProductProperties | None = None
387
+ alternate_ids: list[AlternateId] | None = None
388
+ domain_data_version: Any | None = None
389
+ ingestion_source: str | None = None
390
+ is_microsoft_product: bool | None = None
391
+ preferred_sku_id: str | None = None
392
+ product_type: str | None = None
393
+ validation_data: ValidationData | None = None
394
+ merchandizing_tags: list | None = None
395
+ part_d: str | None = None
396
+ product_family: str
397
+ schema_version: str | None = None
398
+ product_kind: str
399
+ display_sku_availabilities: list[DisplaySkuAvailability]
400
+
401
+
402
+ class CatalogResponse(PascalCaseModel):
403
+ big_ids: list[str] | None = None
404
+ has_more_pages: bool | None = None
405
+ products: list[Product]
406
+ total_result_count: int | None = None
407
+
408
+
409
+ class SearchProduct(PascalCaseModel):
410
+ background_color: str | None = None
411
+ height: int | None = None
412
+ image_type: str | None = None
413
+ width: int | None = None
414
+ platform_properties: list
415
+ icon: str | None = None
416
+ product_id: str
417
+ type: str
418
+ title: str
419
+
420
+
421
+ class CatalogSearchResult(PascalCaseModel):
422
+ product_family_name: str
423
+ products: list[SearchProduct]
424
+
425
+
426
+ class CatalogSearchResponse(PascalCaseModel):
427
+ results: list[CatalogSearchResult]
428
+ total_result_count: int
@@ -0,0 +1,85 @@
1
+ """
2
+ CQS
3
+
4
+ Used for download stump (TV Streaming) data
5
+ (RemoteTVInput ServiceChannel on Smartglass)
6
+ """
7
+
8
+ from pythonxbox.api.provider.baseprovider import BaseProvider
9
+ from pythonxbox.api.provider.cqs.models import (
10
+ CqsChannelListResponse,
11
+ CqsScheduleResponse,
12
+ )
13
+
14
+
15
+ class CQSProvider(BaseProvider):
16
+ CQS_URL = "https://cqs.xboxlive.com"
17
+ HEADERS_CQS = {
18
+ "Cache-Control": "no-cache",
19
+ "Accept": "application/json",
20
+ "Pragma": "no-cache",
21
+ "x-xbl-client-type": "Companion",
22
+ "x-xbl-client-version": "2.0",
23
+ "x-xbl-contract-version": "1.b",
24
+ "x-xbl-device-type": "WindowsPhone",
25
+ "x-xbl-isautomated-client": "true",
26
+ }
27
+
28
+ async def get_channel_list(
29
+ self, locale_info: str, headend_id: str, **kwargs
30
+ ) -> CqsChannelListResponse:
31
+ """
32
+ Get stump channel list
33
+
34
+ Args:
35
+ locale_info: Locale string (format: "en-US")
36
+ headend_id: Headend id
37
+
38
+ Returns:
39
+ :class:`CqsChannelListResponse`: Channel List Response
40
+ """
41
+ url = self.CQS_URL + f"/epg/{locale_info}/lineups/{headend_id}/channels"
42
+ params = {"desired": "vesper_mobile_lineup"}
43
+ resp = await self.client.session.get(
44
+ url, params=params, headers=self.HEADERS_CQS, **kwargs
45
+ )
46
+ resp.raise_for_status()
47
+ return CqsChannelListResponse(**resp.json())
48
+
49
+ async def get_schedule(
50
+ self,
51
+ locale_info: str,
52
+ headend_id: str,
53
+ start_date: str,
54
+ duration_minutes: int,
55
+ channel_skip: int,
56
+ channel_count: int,
57
+ **kwargs,
58
+ ) -> CqsScheduleResponse:
59
+ """
60
+ Get stump epg data
61
+
62
+ Args:
63
+ locale_info: Locale string (format: "en-US")
64
+ headend_id: Headend id
65
+ start_date: Start date (format: 2016-07-11T21:50:00.000Z)
66
+ duration_minutes: Schedule duration to download
67
+ channel_skip: Count of channels to skip
68
+ channel_count: Count of channels to get data for
69
+
70
+ Returns:
71
+ :class:`CqsScheduleResponse`: Schedule Response
72
+ """
73
+ url = self.CQS_URL + f"/epg/{locale_info}/lineups/{headend_id}/programs"
74
+ params = {
75
+ "startDate": start_date,
76
+ "durationMinutes": duration_minutes,
77
+ "channelSkip": channel_skip,
78
+ "channelCount": channel_count,
79
+ "desired": "vesper_mobile_schedule",
80
+ }
81
+ resp = await self.client.session.get(
82
+ url, params=params, headers=self.HEADERS_CQS, **kwargs
83
+ )
84
+ resp.raise_for_status()
85
+ return CqsScheduleResponse(**resp.json())
@@ -0,0 +1,59 @@
1
+ from typing import Any
2
+
3
+ from pythonxbox.common.models import PascalCaseModel
4
+
5
+
6
+ class Image(PascalCaseModel):
7
+ purpose: str
8
+ resize_uri: str
9
+ fore_color: str
10
+
11
+
12
+ class ListChannel(PascalCaseModel):
13
+ id: str
14
+ channel_id: str
15
+ call_sign: str
16
+ channel_number: str
17
+ start_date: str
18
+ end_date: str
19
+ images: list[Image]
20
+ is_HD: bool | None = None
21
+
22
+
23
+ class CqsChannelListResponse(PascalCaseModel):
24
+ channels: list[ListChannel]
25
+
26
+
27
+ class Genre(PascalCaseModel):
28
+ name: str
29
+
30
+
31
+ class ParentSeries(PascalCaseModel):
32
+ id: str
33
+ name: str
34
+
35
+
36
+ class Program(PascalCaseModel):
37
+ id: str
38
+ media_item_type: str
39
+ start_date: str
40
+ end_date: str
41
+ name: str
42
+ is_repeat: bool
43
+ parental_control: dict[str, Any] | None = None
44
+ genres: list[Genre]
45
+ category_id: int
46
+ description: str | None = None
47
+ parent_series: ParentSeries | None = None
48
+ images: list[Image] | None = None
49
+
50
+
51
+ class ScheduleChannel(PascalCaseModel):
52
+ id: str
53
+ name: str
54
+ images: list[Image]
55
+ programs: list[Program]
56
+
57
+
58
+ class CqsScheduleResponse(PascalCaseModel):
59
+ channels: list[ScheduleChannel]