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.
- freenub-0.1.0/LICENSE +27 -0
- freenub-0.1.0/PKG-INFO +104 -0
- freenub-0.1.0/README.md +70 -0
- freenub-0.1.0/pubnub/__init__.py +21 -0
- freenub-0.1.0/pubnub/builders.py +69 -0
- freenub-0.1.0/pubnub/callbacks.py +47 -0
- freenub-0.1.0/pubnub/crypto.py +125 -0
- freenub-0.1.0/pubnub/crypto_core.py +11 -0
- freenub-0.1.0/pubnub/dtos.py +29 -0
- freenub-0.1.0/pubnub/endpoints/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/access/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/access/audit.py +80 -0
- freenub-0.1.0/pubnub/endpoints/access/grant.py +183 -0
- freenub-0.1.0/pubnub/endpoints/access/grant_token.py +129 -0
- freenub-0.1.0/pubnub/endpoints/access/revoke_token.py +46 -0
- freenub-0.1.0/pubnub/endpoints/channel_groups/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/channel_groups/add_channel_to_channel_group.py +68 -0
- freenub-0.1.0/pubnub/endpoints/channel_groups/list_channels_in_channel_group.py +59 -0
- freenub-0.1.0/pubnub/endpoints/channel_groups/remove_channel_from_channel_group.py +68 -0
- freenub-0.1.0/pubnub/endpoints/channel_groups/remove_channel_group.py +56 -0
- freenub-0.1.0/pubnub/endpoints/endpoint.py +334 -0
- freenub-0.1.0/pubnub/endpoints/entities/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/entities/endpoint.py +239 -0
- freenub-0.1.0/pubnub/endpoints/entities/membership/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/entities/membership/add_memberships.py +110 -0
- freenub-0.1.0/pubnub/endpoints/entities/membership/fetch_memberships.py +76 -0
- freenub-0.1.0/pubnub/endpoints/entities/membership/remove_memberships.py +103 -0
- freenub-0.1.0/pubnub/endpoints/entities/membership/update_memberships.py +110 -0
- freenub-0.1.0/pubnub/endpoints/entities/space/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/entities/space/create_space.py +78 -0
- freenub-0.1.0/pubnub/endpoints/entities/space/fetch_space.py +37 -0
- freenub-0.1.0/pubnub/endpoints/entities/space/fetch_spaces.py +32 -0
- freenub-0.1.0/pubnub/endpoints/entities/space/remove_space.py +32 -0
- freenub-0.1.0/pubnub/endpoints/entities/space/update_space.py +77 -0
- freenub-0.1.0/pubnub/endpoints/entities/user/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/entities/user/create_user.py +83 -0
- freenub-0.1.0/pubnub/endpoints/entities/user/fetch_user.py +37 -0
- freenub-0.1.0/pubnub/endpoints/entities/user/fetch_users.py +31 -0
- freenub-0.1.0/pubnub/endpoints/entities/user/remove_user.py +32 -0
- freenub-0.1.0/pubnub/endpoints/entities/user/update_user.py +83 -0
- freenub-0.1.0/pubnub/endpoints/fetch_messages.py +181 -0
- freenub-0.1.0/pubnub/endpoints/file_operations/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/file_operations/delete_file.py +53 -0
- freenub-0.1.0/pubnub/endpoints/file_operations/download_file.py +88 -0
- freenub-0.1.0/pubnub/endpoints/file_operations/download_file_asyncio.py +26 -0
- freenub-0.1.0/pubnub/endpoints/file_operations/fetch_upload_details.py +50 -0
- freenub-0.1.0/pubnub/endpoints/file_operations/file_based_endpoint.py +17 -0
- freenub-0.1.0/pubnub/endpoints/file_operations/get_file_url.py +71 -0
- freenub-0.1.0/pubnub/endpoints/file_operations/list_files.py +39 -0
- freenub-0.1.0/pubnub/endpoints/file_operations/publish_file_message.py +107 -0
- freenub-0.1.0/pubnub/endpoints/file_operations/send_file.py +154 -0
- freenub-0.1.0/pubnub/endpoints/file_operations/send_file_asyncio.py +60 -0
- freenub-0.1.0/pubnub/endpoints/history.py +115 -0
- freenub-0.1.0/pubnub/endpoints/history_delete.py +67 -0
- freenub-0.1.0/pubnub/endpoints/message_actions/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/message_actions/add_message_action.py +85 -0
- freenub-0.1.0/pubnub/endpoints/message_actions/get_message_actions.py +88 -0
- freenub-0.1.0/pubnub/endpoints/message_actions/remove_message_action.py +79 -0
- freenub-0.1.0/pubnub/endpoints/message_count.py +68 -0
- freenub-0.1.0/pubnub/endpoints/mixins.py +33 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/channel/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/channel/get_all_channels.py +31 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/channel/get_channel.py +37 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/channel/remove_channel.py +35 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/channel/set_channel.py +61 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/members/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/members/get_channel_members.py +47 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/members/manage_channel_members.py +74 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/members/remove_channel_members.py +65 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/members/set_channel_members.py +63 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/memberships/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/memberships/get_memberships.py +47 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/memberships/manage_memberships.py +75 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/memberships/remove_memberships.py +63 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/memberships/set_memberships.py +63 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/objects_endpoint.py +214 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/uuid/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/uuid/get_all_uuid.py +31 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/uuid/get_uuid.py +37 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/uuid/remove_uuid.py +32 -0
- freenub-0.1.0/pubnub/endpoints/objects_v2/uuid/set_uuid.py +73 -0
- freenub-0.1.0/pubnub/endpoints/presence/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/presence/get_state.py +80 -0
- freenub-0.1.0/pubnub/endpoints/presence/heartbeat.py +79 -0
- freenub-0.1.0/pubnub/endpoints/presence/here_now.py +79 -0
- freenub-0.1.0/pubnub/endpoints/presence/leave.py +78 -0
- freenub-0.1.0/pubnub/endpoints/presence/set_state.py +103 -0
- freenub-0.1.0/pubnub/endpoints/presence/where_now.py +52 -0
- freenub-0.1.0/pubnub/endpoints/pubsub/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/pubsub/fire.py +147 -0
- freenub-0.1.0/pubnub/endpoints/pubsub/publish.py +177 -0
- freenub-0.1.0/pubnub/endpoints/pubsub/subscribe.py +102 -0
- freenub-0.1.0/pubnub/endpoints/push/__init__.py +0 -0
- freenub-0.1.0/pubnub/endpoints/push/add_channels_to_push.py +111 -0
- freenub-0.1.0/pubnub/endpoints/push/list_push_provisions.py +103 -0
- freenub-0.1.0/pubnub/endpoints/push/remove_channels_from_push.py +109 -0
- freenub-0.1.0/pubnub/endpoints/push/remove_device.py +100 -0
- freenub-0.1.0/pubnub/endpoints/signal.py +60 -0
- freenub-0.1.0/pubnub/endpoints/time.py +37 -0
- freenub-0.1.0/pubnub/enums.py +174 -0
- freenub-0.1.0/pubnub/errors.py +67 -0
- freenub-0.1.0/pubnub/event_engine/__init__.py +0 -0
- freenub-0.1.0/pubnub/event_engine/dispatcher.py +44 -0
- freenub-0.1.0/pubnub/event_engine/manage_effects.py +326 -0
- freenub-0.1.0/pubnub/event_engine/models/__init__.py +0 -0
- freenub-0.1.0/pubnub/event_engine/models/effects.py +100 -0
- freenub-0.1.0/pubnub/event_engine/models/events.py +109 -0
- freenub-0.1.0/pubnub/event_engine/models/states.py +544 -0
- freenub-0.1.0/pubnub/event_engine/statemachine.py +117 -0
- freenub-0.1.0/pubnub/exceptions.py +20 -0
- freenub-0.1.0/pubnub/features.py +20 -0
- freenub-0.1.0/pubnub/managers.py +575 -0
- freenub-0.1.0/pubnub/models/__init__.py +0 -0
- freenub-0.1.0/pubnub/models/consumer/__init__.py +0 -0
- freenub-0.1.0/pubnub/models/consumer/access_manager.py +222 -0
- freenub-0.1.0/pubnub/models/consumer/channel_group.py +21 -0
- freenub-0.1.0/pubnub/models/consumer/common.py +23 -0
- freenub-0.1.0/pubnub/models/consumer/entities/__init__.py +0 -0
- freenub-0.1.0/pubnub/models/consumer/entities/membership.py +31 -0
- freenub-0.1.0/pubnub/models/consumer/entities/page.py +37 -0
- freenub-0.1.0/pubnub/models/consumer/entities/result.py +16 -0
- freenub-0.1.0/pubnub/models/consumer/entities/space.py +47 -0
- freenub-0.1.0/pubnub/models/consumer/entities/user.py +47 -0
- freenub-0.1.0/pubnub/models/consumer/file.py +60 -0
- freenub-0.1.0/pubnub/models/consumer/history.py +128 -0
- freenub-0.1.0/pubnub/models/consumer/message_actions.py +50 -0
- freenub-0.1.0/pubnub/models/consumer/message_count.py +12 -0
- freenub-0.1.0/pubnub/models/consumer/objects_v2/__init__.py +0 -0
- freenub-0.1.0/pubnub/models/consumer/objects_v2/channel.py +47 -0
- freenub-0.1.0/pubnub/models/consumer/objects_v2/channel_members.py +76 -0
- freenub-0.1.0/pubnub/models/consumer/objects_v2/memberships.py +88 -0
- freenub-0.1.0/pubnub/models/consumer/objects_v2/page.py +38 -0
- freenub-0.1.0/pubnub/models/consumer/objects_v2/sort.py +44 -0
- freenub-0.1.0/pubnub/models/consumer/objects_v2/uuid.py +47 -0
- freenub-0.1.0/pubnub/models/consumer/pn_error_data.py +7 -0
- freenub-0.1.0/pubnub/models/consumer/presence.py +161 -0
- freenub-0.1.0/pubnub/models/consumer/pubsub.py +138 -0
- freenub-0.1.0/pubnub/models/consumer/push.py +23 -0
- freenub-0.1.0/pubnub/models/consumer/signal.py +12 -0
- freenub-0.1.0/pubnub/models/consumer/time.py +20 -0
- freenub-0.1.0/pubnub/models/consumer/v3/__init__.py +0 -0
- freenub-0.1.0/pubnub/models/consumer/v3/access_manager.py +28 -0
- freenub-0.1.0/pubnub/models/consumer/v3/channel.py +44 -0
- freenub-0.1.0/pubnub/models/consumer/v3/group.py +24 -0
- freenub-0.1.0/pubnub/models/consumer/v3/pn_resource.py +45 -0
- freenub-0.1.0/pubnub/models/consumer/v3/space.py +48 -0
- freenub-0.1.0/pubnub/models/consumer/v3/user.py +48 -0
- freenub-0.1.0/pubnub/models/consumer/v3/uuid.py +28 -0
- freenub-0.1.0/pubnub/models/server/__init__.py +0 -0
- freenub-0.1.0/pubnub/models/server/subscribe.py +111 -0
- freenub-0.1.0/pubnub/models/subscription_item.py +7 -0
- freenub-0.1.0/pubnub/pnconfiguration.py +155 -0
- freenub-0.1.0/pubnub/pubnub.py +514 -0
- freenub-0.1.0/pubnub/pubnub_asyncio.py +813 -0
- freenub-0.1.0/pubnub/pubnub_core.py +713 -0
- freenub-0.1.0/pubnub/request_handlers/__init__.py +0 -0
- freenub-0.1.0/pubnub/request_handlers/base.py +20 -0
- freenub-0.1.0/pubnub/request_handlers/requests_handler.py +371 -0
- freenub-0.1.0/pubnub/structures.py +120 -0
- freenub-0.1.0/pubnub/utils.py +331 -0
- freenub-0.1.0/pubnub/workers.py +187 -0
- 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&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
|
+
|
freenub-0.1.0/README.md
ADDED
|
@@ -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&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,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"
|