freenub 0.1.0__tar.gz

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 (163) hide show
  1. freenub-0.1.0/LICENSE +27 -0
  2. freenub-0.1.0/PKG-INFO +104 -0
  3. freenub-0.1.0/README.md +70 -0
  4. freenub-0.1.0/pubnub/__init__.py +21 -0
  5. freenub-0.1.0/pubnub/builders.py +69 -0
  6. freenub-0.1.0/pubnub/callbacks.py +47 -0
  7. freenub-0.1.0/pubnub/crypto.py +125 -0
  8. freenub-0.1.0/pubnub/crypto_core.py +11 -0
  9. freenub-0.1.0/pubnub/dtos.py +29 -0
  10. freenub-0.1.0/pubnub/endpoints/__init__.py +0 -0
  11. freenub-0.1.0/pubnub/endpoints/access/__init__.py +0 -0
  12. freenub-0.1.0/pubnub/endpoints/access/audit.py +80 -0
  13. freenub-0.1.0/pubnub/endpoints/access/grant.py +183 -0
  14. freenub-0.1.0/pubnub/endpoints/access/grant_token.py +129 -0
  15. freenub-0.1.0/pubnub/endpoints/access/revoke_token.py +46 -0
  16. freenub-0.1.0/pubnub/endpoints/channel_groups/__init__.py +0 -0
  17. freenub-0.1.0/pubnub/endpoints/channel_groups/add_channel_to_channel_group.py +68 -0
  18. freenub-0.1.0/pubnub/endpoints/channel_groups/list_channels_in_channel_group.py +59 -0
  19. freenub-0.1.0/pubnub/endpoints/channel_groups/remove_channel_from_channel_group.py +68 -0
  20. freenub-0.1.0/pubnub/endpoints/channel_groups/remove_channel_group.py +56 -0
  21. freenub-0.1.0/pubnub/endpoints/endpoint.py +334 -0
  22. freenub-0.1.0/pubnub/endpoints/entities/__init__.py +0 -0
  23. freenub-0.1.0/pubnub/endpoints/entities/endpoint.py +239 -0
  24. freenub-0.1.0/pubnub/endpoints/entities/membership/__init__.py +0 -0
  25. freenub-0.1.0/pubnub/endpoints/entities/membership/add_memberships.py +110 -0
  26. freenub-0.1.0/pubnub/endpoints/entities/membership/fetch_memberships.py +76 -0
  27. freenub-0.1.0/pubnub/endpoints/entities/membership/remove_memberships.py +103 -0
  28. freenub-0.1.0/pubnub/endpoints/entities/membership/update_memberships.py +110 -0
  29. freenub-0.1.0/pubnub/endpoints/entities/space/__init__.py +0 -0
  30. freenub-0.1.0/pubnub/endpoints/entities/space/create_space.py +78 -0
  31. freenub-0.1.0/pubnub/endpoints/entities/space/fetch_space.py +37 -0
  32. freenub-0.1.0/pubnub/endpoints/entities/space/fetch_spaces.py +32 -0
  33. freenub-0.1.0/pubnub/endpoints/entities/space/remove_space.py +32 -0
  34. freenub-0.1.0/pubnub/endpoints/entities/space/update_space.py +77 -0
  35. freenub-0.1.0/pubnub/endpoints/entities/user/__init__.py +0 -0
  36. freenub-0.1.0/pubnub/endpoints/entities/user/create_user.py +83 -0
  37. freenub-0.1.0/pubnub/endpoints/entities/user/fetch_user.py +37 -0
  38. freenub-0.1.0/pubnub/endpoints/entities/user/fetch_users.py +31 -0
  39. freenub-0.1.0/pubnub/endpoints/entities/user/remove_user.py +32 -0
  40. freenub-0.1.0/pubnub/endpoints/entities/user/update_user.py +83 -0
  41. freenub-0.1.0/pubnub/endpoints/fetch_messages.py +181 -0
  42. freenub-0.1.0/pubnub/endpoints/file_operations/__init__.py +0 -0
  43. freenub-0.1.0/pubnub/endpoints/file_operations/delete_file.py +53 -0
  44. freenub-0.1.0/pubnub/endpoints/file_operations/download_file.py +88 -0
  45. freenub-0.1.0/pubnub/endpoints/file_operations/download_file_asyncio.py +26 -0
  46. freenub-0.1.0/pubnub/endpoints/file_operations/fetch_upload_details.py +50 -0
  47. freenub-0.1.0/pubnub/endpoints/file_operations/file_based_endpoint.py +17 -0
  48. freenub-0.1.0/pubnub/endpoints/file_operations/get_file_url.py +71 -0
  49. freenub-0.1.0/pubnub/endpoints/file_operations/list_files.py +39 -0
  50. freenub-0.1.0/pubnub/endpoints/file_operations/publish_file_message.py +107 -0
  51. freenub-0.1.0/pubnub/endpoints/file_operations/send_file.py +154 -0
  52. freenub-0.1.0/pubnub/endpoints/file_operations/send_file_asyncio.py +60 -0
  53. freenub-0.1.0/pubnub/endpoints/history.py +115 -0
  54. freenub-0.1.0/pubnub/endpoints/history_delete.py +67 -0
  55. freenub-0.1.0/pubnub/endpoints/message_actions/__init__.py +0 -0
  56. freenub-0.1.0/pubnub/endpoints/message_actions/add_message_action.py +85 -0
  57. freenub-0.1.0/pubnub/endpoints/message_actions/get_message_actions.py +88 -0
  58. freenub-0.1.0/pubnub/endpoints/message_actions/remove_message_action.py +79 -0
  59. freenub-0.1.0/pubnub/endpoints/message_count.py +68 -0
  60. freenub-0.1.0/pubnub/endpoints/mixins.py +33 -0
  61. freenub-0.1.0/pubnub/endpoints/objects_v2/__init__.py +0 -0
  62. freenub-0.1.0/pubnub/endpoints/objects_v2/channel/__init__.py +0 -0
  63. freenub-0.1.0/pubnub/endpoints/objects_v2/channel/get_all_channels.py +31 -0
  64. freenub-0.1.0/pubnub/endpoints/objects_v2/channel/get_channel.py +37 -0
  65. freenub-0.1.0/pubnub/endpoints/objects_v2/channel/remove_channel.py +35 -0
  66. freenub-0.1.0/pubnub/endpoints/objects_v2/channel/set_channel.py +61 -0
  67. freenub-0.1.0/pubnub/endpoints/objects_v2/members/__init__.py +0 -0
  68. freenub-0.1.0/pubnub/endpoints/objects_v2/members/get_channel_members.py +47 -0
  69. freenub-0.1.0/pubnub/endpoints/objects_v2/members/manage_channel_members.py +74 -0
  70. freenub-0.1.0/pubnub/endpoints/objects_v2/members/remove_channel_members.py +65 -0
  71. freenub-0.1.0/pubnub/endpoints/objects_v2/members/set_channel_members.py +63 -0
  72. freenub-0.1.0/pubnub/endpoints/objects_v2/memberships/__init__.py +0 -0
  73. freenub-0.1.0/pubnub/endpoints/objects_v2/memberships/get_memberships.py +47 -0
  74. freenub-0.1.0/pubnub/endpoints/objects_v2/memberships/manage_memberships.py +75 -0
  75. freenub-0.1.0/pubnub/endpoints/objects_v2/memberships/remove_memberships.py +63 -0
  76. freenub-0.1.0/pubnub/endpoints/objects_v2/memberships/set_memberships.py +63 -0
  77. freenub-0.1.0/pubnub/endpoints/objects_v2/objects_endpoint.py +214 -0
  78. freenub-0.1.0/pubnub/endpoints/objects_v2/uuid/__init__.py +0 -0
  79. freenub-0.1.0/pubnub/endpoints/objects_v2/uuid/get_all_uuid.py +31 -0
  80. freenub-0.1.0/pubnub/endpoints/objects_v2/uuid/get_uuid.py +37 -0
  81. freenub-0.1.0/pubnub/endpoints/objects_v2/uuid/remove_uuid.py +32 -0
  82. freenub-0.1.0/pubnub/endpoints/objects_v2/uuid/set_uuid.py +73 -0
  83. freenub-0.1.0/pubnub/endpoints/presence/__init__.py +0 -0
  84. freenub-0.1.0/pubnub/endpoints/presence/get_state.py +80 -0
  85. freenub-0.1.0/pubnub/endpoints/presence/heartbeat.py +79 -0
  86. freenub-0.1.0/pubnub/endpoints/presence/here_now.py +79 -0
  87. freenub-0.1.0/pubnub/endpoints/presence/leave.py +78 -0
  88. freenub-0.1.0/pubnub/endpoints/presence/set_state.py +103 -0
  89. freenub-0.1.0/pubnub/endpoints/presence/where_now.py +52 -0
  90. freenub-0.1.0/pubnub/endpoints/pubsub/__init__.py +0 -0
  91. freenub-0.1.0/pubnub/endpoints/pubsub/fire.py +147 -0
  92. freenub-0.1.0/pubnub/endpoints/pubsub/publish.py +177 -0
  93. freenub-0.1.0/pubnub/endpoints/pubsub/subscribe.py +102 -0
  94. freenub-0.1.0/pubnub/endpoints/push/__init__.py +0 -0
  95. freenub-0.1.0/pubnub/endpoints/push/add_channels_to_push.py +111 -0
  96. freenub-0.1.0/pubnub/endpoints/push/list_push_provisions.py +103 -0
  97. freenub-0.1.0/pubnub/endpoints/push/remove_channels_from_push.py +109 -0
  98. freenub-0.1.0/pubnub/endpoints/push/remove_device.py +100 -0
  99. freenub-0.1.0/pubnub/endpoints/signal.py +60 -0
  100. freenub-0.1.0/pubnub/endpoints/time.py +37 -0
  101. freenub-0.1.0/pubnub/enums.py +174 -0
  102. freenub-0.1.0/pubnub/errors.py +67 -0
  103. freenub-0.1.0/pubnub/event_engine/__init__.py +0 -0
  104. freenub-0.1.0/pubnub/event_engine/dispatcher.py +44 -0
  105. freenub-0.1.0/pubnub/event_engine/manage_effects.py +326 -0
  106. freenub-0.1.0/pubnub/event_engine/models/__init__.py +0 -0
  107. freenub-0.1.0/pubnub/event_engine/models/effects.py +100 -0
  108. freenub-0.1.0/pubnub/event_engine/models/events.py +109 -0
  109. freenub-0.1.0/pubnub/event_engine/models/states.py +544 -0
  110. freenub-0.1.0/pubnub/event_engine/statemachine.py +117 -0
  111. freenub-0.1.0/pubnub/exceptions.py +20 -0
  112. freenub-0.1.0/pubnub/features.py +20 -0
  113. freenub-0.1.0/pubnub/managers.py +575 -0
  114. freenub-0.1.0/pubnub/models/__init__.py +0 -0
  115. freenub-0.1.0/pubnub/models/consumer/__init__.py +0 -0
  116. freenub-0.1.0/pubnub/models/consumer/access_manager.py +222 -0
  117. freenub-0.1.0/pubnub/models/consumer/channel_group.py +21 -0
  118. freenub-0.1.0/pubnub/models/consumer/common.py +23 -0
  119. freenub-0.1.0/pubnub/models/consumer/entities/__init__.py +0 -0
  120. freenub-0.1.0/pubnub/models/consumer/entities/membership.py +31 -0
  121. freenub-0.1.0/pubnub/models/consumer/entities/page.py +37 -0
  122. freenub-0.1.0/pubnub/models/consumer/entities/result.py +16 -0
  123. freenub-0.1.0/pubnub/models/consumer/entities/space.py +47 -0
  124. freenub-0.1.0/pubnub/models/consumer/entities/user.py +47 -0
  125. freenub-0.1.0/pubnub/models/consumer/file.py +60 -0
  126. freenub-0.1.0/pubnub/models/consumer/history.py +128 -0
  127. freenub-0.1.0/pubnub/models/consumer/message_actions.py +50 -0
  128. freenub-0.1.0/pubnub/models/consumer/message_count.py +12 -0
  129. freenub-0.1.0/pubnub/models/consumer/objects_v2/__init__.py +0 -0
  130. freenub-0.1.0/pubnub/models/consumer/objects_v2/channel.py +47 -0
  131. freenub-0.1.0/pubnub/models/consumer/objects_v2/channel_members.py +76 -0
  132. freenub-0.1.0/pubnub/models/consumer/objects_v2/memberships.py +88 -0
  133. freenub-0.1.0/pubnub/models/consumer/objects_v2/page.py +38 -0
  134. freenub-0.1.0/pubnub/models/consumer/objects_v2/sort.py +44 -0
  135. freenub-0.1.0/pubnub/models/consumer/objects_v2/uuid.py +47 -0
  136. freenub-0.1.0/pubnub/models/consumer/pn_error_data.py +7 -0
  137. freenub-0.1.0/pubnub/models/consumer/presence.py +161 -0
  138. freenub-0.1.0/pubnub/models/consumer/pubsub.py +138 -0
  139. freenub-0.1.0/pubnub/models/consumer/push.py +23 -0
  140. freenub-0.1.0/pubnub/models/consumer/signal.py +12 -0
  141. freenub-0.1.0/pubnub/models/consumer/time.py +20 -0
  142. freenub-0.1.0/pubnub/models/consumer/v3/__init__.py +0 -0
  143. freenub-0.1.0/pubnub/models/consumer/v3/access_manager.py +28 -0
  144. freenub-0.1.0/pubnub/models/consumer/v3/channel.py +44 -0
  145. freenub-0.1.0/pubnub/models/consumer/v3/group.py +24 -0
  146. freenub-0.1.0/pubnub/models/consumer/v3/pn_resource.py +45 -0
  147. freenub-0.1.0/pubnub/models/consumer/v3/space.py +48 -0
  148. freenub-0.1.0/pubnub/models/consumer/v3/user.py +48 -0
  149. freenub-0.1.0/pubnub/models/consumer/v3/uuid.py +28 -0
  150. freenub-0.1.0/pubnub/models/server/__init__.py +0 -0
  151. freenub-0.1.0/pubnub/models/server/subscribe.py +111 -0
  152. freenub-0.1.0/pubnub/models/subscription_item.py +7 -0
  153. freenub-0.1.0/pubnub/pnconfiguration.py +155 -0
  154. freenub-0.1.0/pubnub/pubnub.py +514 -0
  155. freenub-0.1.0/pubnub/pubnub_asyncio.py +813 -0
  156. freenub-0.1.0/pubnub/pubnub_core.py +713 -0
  157. freenub-0.1.0/pubnub/request_handlers/__init__.py +0 -0
  158. freenub-0.1.0/pubnub/request_handlers/base.py +20 -0
  159. freenub-0.1.0/pubnub/request_handlers/requests_handler.py +371 -0
  160. freenub-0.1.0/pubnub/structures.py +120 -0
  161. freenub-0.1.0/pubnub/utils.py +331 -0
  162. freenub-0.1.0/pubnub/workers.py +187 -0
  163. freenub-0.1.0/pyproject.toml +148 -0
freenub-0.1.0/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ PubNub Real-time Cloud-Hosted Push API and Push Notification Client Frameworks
2
+ Copyright (c) 2013 PubNub Inc.
3
+ http://www.pubnub.com/
4
+ http://www.pubnub.com/terms
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
23
+
24
+ PubNub Real-time Cloud-Hosted Push API and Push Notification Client Frameworks
25
+ Copyright (c) 2013 PubNub Inc.
26
+ http://www.pubnub.com/
27
+ http://www.pubnub.com/terms
freenub-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,104 @@
1
+ Metadata-Version: 2.1
2
+ Name: freenub
3
+ Version: 0.1.0
4
+ Summary: This is a fork of pubnub when it still had an MIT license
5
+ Home-page: https://github.com/bdraco/freenub
6
+ License: MIT
7
+ Author: J. Nick Koston
8
+ Author-email: nick@koston.org
9
+ Requires-Python: >=3.8,<4.0
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.7
22
+ Classifier: Programming Language :: Python :: Implementation :: CPython
23
+ Classifier: Topic :: Internet :: WWW/HTTP
24
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
+ Requires-Dist: aiohttp (>=3.9.5,<4.0.0)
26
+ Requires-Dist: cbor2 (>=5.6.4,<6.0.0)
27
+ Requires-Dist: pycryptodomex (>=3.3)
28
+ Requires-Dist: requests (>=2.4)
29
+ Project-URL: Bug Tracker, https://github.com/bdraco/freenub/issues
30
+ Project-URL: Changelog, https://github.com/bdraco/freenub/blob/main/CHANGELOG.md
31
+ Project-URL: Repository, https://github.com/bdraco/freenub
32
+ Description-Content-Type: text/markdown
33
+
34
+ # freenub
35
+
36
+ <p align="center">
37
+ <a href="https://github.com/bdraco/freenub/actions/workflows/ci.yml?query=branch%3Amain">
38
+ <img src="https://img.shields.io/github/actions/workflow/status/bdraco/freenub/ci.yml?branch=main&label=CI&logo=github&style=flat-square" alt="CI Status" >
39
+ </a>
40
+ <a href="https://codecov.io/gh/bdraco/freenub">
41
+ <img src="https://img.shields.io/codecov/c/github/bdraco/freenub.svg?logo=codecov&logoColor=fff&style=flat-square" alt="Test coverage percentage">
42
+ </a>
43
+ </p>
44
+ <p align="center">
45
+ <a href="https://python-poetry.org/">
46
+ <img src="https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json" alt="Poetry">
47
+ </a>
48
+ <a href="https://github.com/astral-sh/ruff">
49
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
50
+ </a>
51
+ <a href="https://github.com/pre-commit/pre-commit">
52
+ <img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square" alt="pre-commit">
53
+ </a>
54
+ </p>
55
+ <p align="center">
56
+ <a href="https://pypi.org/project/freenub/">
57
+ <img src="https://img.shields.io/pypi/v/freenub.svg?logo=python&logoColor=fff&style=flat-square" alt="PyPI Version">
58
+ </a>
59
+ <img src="https://img.shields.io/pypi/pyversions/freenub.svg?style=flat-square&logo=python&amp;logoColor=fff" alt="Supported Python versions">
60
+ <img src="https://img.shields.io/pypi/l/freenub.svg?style=flat-square" alt="License">
61
+ </p>
62
+
63
+ ---
64
+
65
+ **Source Code**: <a href="https://github.com/bdraco/freenub" target="_blank">https://github.com/bdraco/freenub </a>
66
+
67
+ ---
68
+
69
+ This is a fork of pubnub when it still had an MIT license
70
+
71
+ ## Installation
72
+
73
+ Install this via pip (or your favourite package manager):
74
+
75
+ `pip install freenub`
76
+
77
+ ## Usage
78
+
79
+ Start by importing it:
80
+
81
+ ```python
82
+ import freenub
83
+ ```
84
+
85
+ ## Contributors ✨
86
+
87
+ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
88
+
89
+ <!-- prettier-ignore-start -->
90
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
91
+ <!-- markdownlint-disable -->
92
+ <!-- markdownlint-enable -->
93
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
94
+ <!-- prettier-ignore-end -->
95
+
96
+ This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
97
+
98
+ ## Credits
99
+
100
+ This package was created with
101
+ [Copier](https://copier.readthedocs.io/) and the
102
+ [browniebroke/pypackage-template](https://github.com/browniebroke/pypackage-template)
103
+ project template.
104
+
@@ -0,0 +1,70 @@
1
+ # freenub
2
+
3
+ <p align="center">
4
+ <a href="https://github.com/bdraco/freenub/actions/workflows/ci.yml?query=branch%3Amain">
5
+ <img src="https://img.shields.io/github/actions/workflow/status/bdraco/freenub/ci.yml?branch=main&label=CI&logo=github&style=flat-square" alt="CI Status" >
6
+ </a>
7
+ <a href="https://codecov.io/gh/bdraco/freenub">
8
+ <img src="https://img.shields.io/codecov/c/github/bdraco/freenub.svg?logo=codecov&logoColor=fff&style=flat-square" alt="Test coverage percentage">
9
+ </a>
10
+ </p>
11
+ <p align="center">
12
+ <a href="https://python-poetry.org/">
13
+ <img src="https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json" alt="Poetry">
14
+ </a>
15
+ <a href="https://github.com/astral-sh/ruff">
16
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
17
+ </a>
18
+ <a href="https://github.com/pre-commit/pre-commit">
19
+ <img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square" alt="pre-commit">
20
+ </a>
21
+ </p>
22
+ <p align="center">
23
+ <a href="https://pypi.org/project/freenub/">
24
+ <img src="https://img.shields.io/pypi/v/freenub.svg?logo=python&logoColor=fff&style=flat-square" alt="PyPI Version">
25
+ </a>
26
+ <img src="https://img.shields.io/pypi/pyversions/freenub.svg?style=flat-square&logo=python&amp;logoColor=fff" alt="Supported Python versions">
27
+ <img src="https://img.shields.io/pypi/l/freenub.svg?style=flat-square" alt="License">
28
+ </p>
29
+
30
+ ---
31
+
32
+ **Source Code**: <a href="https://github.com/bdraco/freenub" target="_blank">https://github.com/bdraco/freenub </a>
33
+
34
+ ---
35
+
36
+ This is a fork of pubnub when it still had an MIT license
37
+
38
+ ## Installation
39
+
40
+ Install this via pip (or your favourite package manager):
41
+
42
+ `pip install freenub`
43
+
44
+ ## Usage
45
+
46
+ Start by importing it:
47
+
48
+ ```python
49
+ import freenub
50
+ ```
51
+
52
+ ## Contributors ✨
53
+
54
+ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
55
+
56
+ <!-- prettier-ignore-start -->
57
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
58
+ <!-- markdownlint-disable -->
59
+ <!-- markdownlint-enable -->
60
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
61
+ <!-- prettier-ignore-end -->
62
+
63
+ This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
64
+
65
+ ## Credits
66
+
67
+ This package was created with
68
+ [Copier](https://copier.readthedocs.io/) and the
69
+ [browniebroke/pypackage-template](https://github.com/browniebroke/pypackage-template)
70
+ project template.
@@ -0,0 +1,21 @@
1
+ import logging
2
+ import os
3
+
4
+ PUBNUB_ROOT = os.path.dirname(os.path.abspath(__file__))
5
+
6
+ __version__ = "0.1.0"
7
+
8
+
9
+ def set_stream_logger(
10
+ name="pubnub", level=logging.ERROR, format_string=None, stream=None
11
+ ):
12
+ if format_string is None:
13
+ format_string = "%(asctime)s %(name)s [%(levelname)s] %(message)s"
14
+
15
+ logger = logging.getLogger(name)
16
+ logger.setLevel(level)
17
+ handler = logging.StreamHandler(stream)
18
+ handler.setLevel(level)
19
+ formatter = logging.Formatter(format_string)
20
+ handler.setFormatter(formatter)
21
+ logger.addHandler(handler)
@@ -0,0 +1,69 @@
1
+ from abc import ABCMeta, abstractmethod
2
+
3
+ from . import utils
4
+ from .dtos import SubscribeOperation, UnsubscribeOperation
5
+
6
+
7
+ class PubSubBuilder:
8
+ __metaclass__ = ABCMeta
9
+
10
+ def __init__(self, subscription_manager):
11
+ self._subscription_manager = subscription_manager
12
+ self._channel_subscriptions = []
13
+ self._channel_group_subscriptions = []
14
+
15
+ # TODO: make the 'channel' alias
16
+ def channels(self, channels_list):
17
+ utils.extend_list(self._channel_subscriptions, channels_list)
18
+
19
+ return self
20
+
21
+ def channel_groups(self, channel_groups_list):
22
+ utils.extend_list(self._channel_group_subscriptions, channel_groups_list)
23
+
24
+ return self
25
+
26
+ @abstractmethod
27
+ def execute(self):
28
+ pass
29
+
30
+
31
+ class SubscribeBuilder(PubSubBuilder):
32
+ def __init__(self, subscription_manager):
33
+ super().__init__(subscription_manager)
34
+ self._presence_enabled = False
35
+ self._timetoken = 0
36
+
37
+ def with_presence(self):
38
+ self._presence_enabled = True
39
+ return self
40
+
41
+ def with_timetoken(self, timetoken):
42
+ self._timetoken = timetoken
43
+ return self
44
+
45
+ def channel_subscriptions(self):
46
+ return self._channel_subscriptions
47
+
48
+ def channel_group_subscriptions(self):
49
+ return self._channel_group_subscriptions
50
+
51
+ def execute(self):
52
+ subscribe_operation = SubscribeOperation(
53
+ channels=self._channel_subscriptions,
54
+ channel_groups=self._channel_group_subscriptions,
55
+ timetoken=self._timetoken,
56
+ presence_enabled=self._presence_enabled,
57
+ )
58
+
59
+ self._subscription_manager.adapt_subscribe_builder(subscribe_operation)
60
+
61
+
62
+ class UnsubscribeBuilder(PubSubBuilder):
63
+ def execute(self):
64
+ unsubscribe_operation = UnsubscribeOperation(
65
+ channels=self._channel_subscriptions,
66
+ channel_groups=self._channel_group_subscriptions,
67
+ )
68
+
69
+ self._subscription_manager.adapt_unsubscribe_builder(unsubscribe_operation)
@@ -0,0 +1,47 @@
1
+ from abc import ABCMeta, abstractmethod
2
+
3
+
4
+ class PNCallback:
5
+ @abstractmethod
6
+ def on_response(self, x, status):
7
+ pass
8
+
9
+
10
+ class SubscribeCallback:
11
+ __metaclass__ = ABCMeta
12
+
13
+ @abstractmethod
14
+ def status(self, pubnub, status):
15
+ pass
16
+
17
+ @abstractmethod
18
+ def message(self, pubnub, message):
19
+ pass
20
+
21
+ @abstractmethod
22
+ def presence(self, pubnub, presence):
23
+ pass
24
+
25
+ def signal(self, pubnub, signal):
26
+ pass
27
+
28
+ def channel(self, pubnub, channel):
29
+ pass
30
+
31
+ def uuid(self, pubnub, uuid):
32
+ pass
33
+
34
+ def membership(self, pubnub, membership):
35
+ pass
36
+
37
+ def message_action(self, pubnub, message_action):
38
+ pass
39
+
40
+ def file(self, pubnub, file_message):
41
+ pass
42
+
43
+
44
+ class ReconnectionCallback:
45
+ @abstractmethod
46
+ def on_reconnect(self):
47
+ pass
@@ -0,0 +1,125 @@
1
+ import hashlib
2
+ import json
3
+ import random
4
+ from base64 import decodebytes, encodebytes
5
+
6
+ from Cryptodome.Cipher import AES
7
+ from Cryptodome.Util.Padding import pad, unpad
8
+
9
+ from pubnub.crypto_core import PubNubCrypto
10
+
11
+ Initial16bytes = "0123456789012345"
12
+
13
+
14
+ class PubNubCryptodome(PubNubCrypto):
15
+ mode = AES.MODE_CBC
16
+ fallback_mode = None
17
+
18
+ def __init__(self, pubnub_config):
19
+ self.pubnub_configuration = pubnub_config
20
+ self.mode = pubnub_config.cipher_mode
21
+ self.fallback_mode = pubnub_config.fallback_cipher_mode
22
+
23
+ def encrypt(self, key, msg, use_random_iv=False):
24
+ secret = self.get_secret(key)
25
+ initialization_vector = self.get_initialization_vector(use_random_iv)
26
+
27
+ cipher = AES.new(
28
+ bytes(secret[0:32], "utf-8"),
29
+ self.mode,
30
+ bytes(initialization_vector, "utf-8"),
31
+ )
32
+ encrypted_message = cipher.encrypt(self.pad(msg.encode("utf-8")))
33
+ msg_with_iv = self.append_random_iv(
34
+ encrypted_message, use_random_iv, bytes(initialization_vector, "utf-8")
35
+ )
36
+
37
+ return encodebytes(msg_with_iv).decode("utf-8").replace("\n", "")
38
+
39
+ def decrypt(self, key, msg, use_random_iv=False):
40
+ secret = self.get_secret(key)
41
+
42
+ decoded_message = decodebytes(msg.encode("utf-8"))
43
+ initialization_vector, extracted_message = self.extract_random_iv(
44
+ decoded_message, use_random_iv
45
+ )
46
+ cipher = AES.new(bytes(secret[0:32], "utf-8"), self.mode, initialization_vector)
47
+ try:
48
+ plain = self.depad((cipher.decrypt(extracted_message)).decode("utf-8"))
49
+ except UnicodeDecodeError as e:
50
+ if not self.fallback_mode:
51
+ raise e
52
+
53
+ cipher = AES.new(
54
+ bytes(secret[0:32], "utf-8"), self.fallback_mode, initialization_vector
55
+ )
56
+ plain = self.depad((cipher.decrypt(extracted_message)).decode("utf-8"))
57
+
58
+ try:
59
+ return json.loads(plain)
60
+ except Exception:
61
+ return plain
62
+
63
+ def append_random_iv(self, message, use_random_iv, initialization_vector):
64
+ if self.pubnub_configuration.use_random_initialization_vector or use_random_iv:
65
+ return initialization_vector + message
66
+ else:
67
+ return message
68
+
69
+ def extract_random_iv(self, message, use_random_iv):
70
+ if self.pubnub_configuration.use_random_initialization_vector or use_random_iv:
71
+ return message[0:16], message[16:]
72
+ else:
73
+ return bytes(Initial16bytes, "utf-8"), message
74
+
75
+ def get_initialization_vector(self, use_random_iv):
76
+ if self.pubnub_configuration.use_random_initialization_vector or use_random_iv:
77
+ return f"{random.randint(0, 9999999999999999):016}"
78
+ else:
79
+ return Initial16bytes
80
+
81
+ def pad(self, msg, block_size=16):
82
+ padding = block_size - (len(msg) % block_size)
83
+ return msg + (chr(padding) * padding).encode("utf-8")
84
+
85
+ def depad(self, msg):
86
+ return msg[0 : -ord(msg[-1])]
87
+
88
+ def get_secret(self, key):
89
+ return hashlib.sha256(key.encode("utf-8")).hexdigest()
90
+
91
+
92
+ class PubNubFileCrypto(PubNubCryptodome):
93
+ def encrypt(self, key, file):
94
+ secret = self.get_secret(key)
95
+ initialization_vector = self.get_initialization_vector(use_random_iv=True)
96
+ cipher = AES.new(
97
+ bytes(secret[0:32], "utf-8"),
98
+ self.mode,
99
+ bytes(initialization_vector, "utf-8"),
100
+ )
101
+ initialization_vector = bytes(initialization_vector, "utf-8")
102
+
103
+ return self.append_random_iv(
104
+ cipher.encrypt(pad(file, 16)),
105
+ use_random_iv=True,
106
+ initialization_vector=initialization_vector,
107
+ )
108
+
109
+ def decrypt(self, key, file):
110
+ secret = self.get_secret(key)
111
+ initialization_vector, extracted_file = self.extract_random_iv(
112
+ file, use_random_iv=True
113
+ )
114
+ try:
115
+ cipher = AES.new(
116
+ bytes(secret[0:32], "utf-8"), self.mode, initialization_vector
117
+ )
118
+ result = unpad(cipher.decrypt(extracted_file), 16)
119
+ except ValueError:
120
+ cipher = AES.new(
121
+ bytes(secret[0:32], "utf-8"), self.fallback_mode, initialization_vector
122
+ )
123
+ result = unpad(cipher.decrypt(extracted_file), 16)
124
+
125
+ return result
@@ -0,0 +1,11 @@
1
+ from abc import abstractmethod
2
+
3
+
4
+ class PubNubCrypto:
5
+ @abstractmethod
6
+ def encrypt(self, key, msg):
7
+ pass
8
+
9
+ @abstractmethod
10
+ def decrypt(self, key, msg):
11
+ pass
@@ -0,0 +1,29 @@
1
+ class SubscribeOperation:
2
+ def __init__(
3
+ self, channels=None, channel_groups=None, presence_enabled=None, timetoken=None
4
+ ):
5
+ assert isinstance(channels, (list, tuple))
6
+ assert isinstance(channel_groups, (list, tuple))
7
+ assert isinstance(presence_enabled, bool)
8
+ assert isinstance(timetoken, int)
9
+
10
+ self.channels = channels
11
+ self.channel_groups = channel_groups
12
+ self.presence_enabled = presence_enabled
13
+ self.timetoken = timetoken
14
+
15
+
16
+ class UnsubscribeOperation:
17
+ def __init__(self, channels=None, channel_groups=None):
18
+ assert isinstance(channels, (list, tuple))
19
+ assert isinstance(channel_groups, (list, tuple))
20
+
21
+ self.channels = channels
22
+ self.channel_groups = channel_groups
23
+
24
+
25
+ class StateOperation:
26
+ def __init__(self, channels=None, channel_groups=None, state=None):
27
+ self.channels = channels
28
+ self.channel_groups = channel_groups
29
+ self.state = state
File without changes
File without changes
@@ -0,0 +1,80 @@
1
+ from pubnub import utils
2
+ from pubnub.endpoints.endpoint import Endpoint
3
+ from pubnub.enums import HttpMethod, PNOperationType
4
+ from pubnub.models.consumer.access_manager import PNAccessManagerAuditResult
5
+
6
+
7
+ class Audit(Endpoint):
8
+ AUDIT_PATH = "/v2/auth/audit/sub-key/%s"
9
+
10
+ def __init__(self, pubnub):
11
+ Endpoint.__init__(self, pubnub)
12
+ self._auth_keys = []
13
+ self._channels = []
14
+ self._groups = []
15
+ self._read = None
16
+ self._write = None
17
+ self._manage = None
18
+ self._ttl = None
19
+
20
+ self._sort_params = True
21
+
22
+ def auth_keys(self, auth_keys):
23
+ utils.extend_list(self._auth_keys, auth_keys)
24
+ return self
25
+
26
+ def channels(self, channels):
27
+ utils.extend_list(self._channels, channels)
28
+ return self
29
+
30
+ def channel_groups(self, channel_groups):
31
+ utils.extend_list(self._groups, channel_groups)
32
+ return self
33
+
34
+ def custom_params(self):
35
+ params = {}
36
+
37
+ if len(self._auth_keys) > 0:
38
+ params["auth"] = utils.join_items_and_encode(self._auth_keys)
39
+
40
+ if len(self._channels) > 0:
41
+ params["channel"] = utils.join_items_and_encode(self._channels)
42
+
43
+ if len(self._groups) > 0:
44
+ params["channel-group"] = utils.join_items_and_encode(self._groups)
45
+
46
+ return params
47
+
48
+ def build_path(self):
49
+ return Audit.AUDIT_PATH % self.pubnub.config.subscribe_key
50
+
51
+ def http_method(self):
52
+ return HttpMethod.GET
53
+
54
+ def validate_params(self):
55
+ self.validate_subscribe_key()
56
+ self.validate_secret_key()
57
+
58
+ def create_response(self, envelope):
59
+ return PNAccessManagerAuditResult.from_json(envelope["payload"])
60
+
61
+ def is_auth_required(self):
62
+ return False
63
+
64
+ def affected_channels(self):
65
+ return self._channels
66
+
67
+ def affected_channels_groups(self):
68
+ return self._groups
69
+
70
+ def request_timeout(self):
71
+ return self.pubnub.config.non_subscribe_request_timeout
72
+
73
+ def connect_timeout(self):
74
+ return self.pubnub.config.connect_timeout
75
+
76
+ def operation_type(self):
77
+ return PNOperationType.PNAccessManagerAudit
78
+
79
+ def name(self):
80
+ return "Grant"