├── .DS_Store
├── .env-example
├── .flake8
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── dependabot.yml
└── workflows
│ ├── pythonapp.yml
│ └── pythonpublish.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── MANIFEST.in
├── README.md
├── codecov.yml
├── craft
├── description
├── makefile
├── pyproject.toml
├── pytest.ini
├── requirements.txt
├── setup.cfg
├── setup.py
├── src
├── __init__.py
└── socketio_driver
│ ├── __init__.py
│ ├── communicator.py
│ ├── config
│ └── socketio.py
│ ├── controllers
│ └── BroadcastController.py
│ ├── drivers
│ ├── __init__.py
│ └── socket_driver.py
│ ├── facades
│ ├── __init__.py
│ ├── communicator.py
│ └── communicator.pyi
│ ├── models
│ └── socket_client.py
│ └── providers
│ ├── __init__.py
│ └── socket_provider.py
├── tests
├── __init__.py
├── integrations
│ ├── Kernel.py
│ ├── app
│ │ ├── __init__.py
│ │ ├── controllers
│ │ │ ├── WelcomeController.py
│ │ │ └── __init__.py
│ │ ├── middlewares
│ │ │ └── VerifyCsrfToken.py
│ │ └── models
│ │ │ └── User.py
│ ├── config
│ │ ├── __init__.py
│ │ ├── application.py
│ │ ├── auth.py
│ │ ├── broadcast.py
│ │ ├── cache.py
│ │ ├── database.py
│ │ ├── exceptions.py
│ │ ├── filesystem.py
│ │ ├── mail.py
│ │ ├── notification.py
│ │ ├── providers.py
│ │ ├── queue.py
│ │ └── session.py
│ ├── databases
│ │ ├── migrations
│ │ │ ├── 2021_01_09_033202_create_password_reset_table.py
│ │ │ ├── 2021_01_09_043202_create_users_table.py
│ │ │ └── 2022_04_21_110158_create_audit_logs_table.py
│ │ └── seeds
│ │ │ ├── __init__.py
│ │ │ ├── database_seeder.py
│ │ │ └── user_table_seeder.py
│ ├── resources
│ │ ├── css
│ │ │ └── app.css
│ │ └── js
│ │ │ ├── app.js
│ │ │ └── bootstrap.js
│ ├── routes
│ │ └── web.py
│ ├── storage
│ │ ├── .gitignore
│ │ └── public
│ │ │ ├── favicon.ico
│ │ │ ├── logo.png
│ │ │ └── robots.txt
│ └── templates
│ │ ├── __init__.py
│ │ ├── base.html
│ │ ├── maintenance.html
│ │ └── welcome.html
└── unit
│ ├── __init__.py
│ └── test_package.py
└── wsgi.py
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/.DS_Store
--------------------------------------------------------------------------------
/.env-example:
--------------------------------------------------------------------------------
1 | APP_DEBUG=True
2 | APP_ENV=development
3 | APP_KEY=plyUWY8iZnEH9_8WrVjl-LS3B8aRtHK9UAB35fGAq0M=
4 | DB_CONFIG_PATH=tests/integrations/config/database
5 | DB_CONNECTION=sqlite
6 |
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | per-file-ignores = __init__.py:F401
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | # Maintain dependencies for GitHub Actions
4 | - package-ecosystem: "github-actions"
5 | directory: "/"
6 | schedule:
7 | interval: "weekly"
8 |
9 | # Maintain dependencies for cookiecutter repo
10 | - package-ecosystem: "pip"
11 | directory: "/"
12 | schedule:
13 | interval: "weekly"
14 | # Allow up to 10 open pull requests for pip dependencies
15 | open-pull-requests-limit: 10
16 |
--------------------------------------------------------------------------------
/.github/workflows/pythonapp.yml:
--------------------------------------------------------------------------------
1 | name: Test Application
2 |
3 | on:
4 | pull_request:
5 | branches: [master]
6 |
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 | strategy:
11 | matrix:
12 | python-version: ["3.7", "3.8", "3.9", "3.10"]
13 | name: Python ${{ matrix.python-version }}
14 | steps:
15 | - uses: actions/checkout@v4
16 | - name: Set up Python ${{ matrix.python-version }}
17 | uses: actions/setup-python@v4
18 | with:
19 | python-version: ${{ matrix.python-version }}
20 | - name: Install dependencies
21 | run: |
22 | make init
23 | - name: Test with pytest and Build coverage
24 | run: |
25 | make coverage
26 | - name: Upload coverage
27 | uses: codecov/codecov-action@v3
28 | with:
29 | token: ${{ secrets.CODECOV_TOKEN }}
30 | fail_ci_if_error: false
31 |
32 | lint:
33 | runs-on: ubuntu-latest
34 | name: Lint
35 | steps:
36 | - uses: actions/checkout@v4
37 | - name: Set up Python 3.8
38 | uses: actions/setup-python@v4
39 | with:
40 | python-version: 3.8
41 | - name: Intall Flake8
42 | run: |
43 | pip install flake8
44 | - name: Lint
45 | run: make lint
46 |
--------------------------------------------------------------------------------
/.github/workflows/pythonpublish.yml:
--------------------------------------------------------------------------------
1 | name: Upload Python Package
2 |
3 | on:
4 | release:
5 | types: [created]
6 |
7 | jobs:
8 | deploy:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v4
12 | - name: Set up Python
13 | uses: actions/setup-python@v4
14 | with:
15 | python-version: "3.x"
16 | - name: Install dependencies
17 | run: |
18 | make init
19 | - name: Publish only packages passing test
20 | run: |
21 | make test
22 | - name: Build and publish
23 | env:
24 | TWINE_USERNAME: __token__
25 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
26 | run: |
27 | make publish
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | venv
2 | .vscode
3 | .idea/
4 | build/
5 | .pypirc
6 | .coverage
7 | coverage.xml
8 | .pytest_*
9 | **/*__pycache__*
10 | **/*.DS_Store*
11 | **.pyc
12 | dist
13 | .env
14 | *.db
15 | src/masonite_masonite_permission.egg-info
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guide
2 |
3 | ## Introduction
4 |
5 | When contributing to this repository, **please first discuss the change you wish to make via issue, email, or any other method with the owners or contributors of this repository** before making a change 😃 . Thank you !
6 |
7 | ## Getting Started
8 |
9 | ### Get the code
10 |
11 | First you should configure your local environment to be able to make changes in this package.
12 |
13 | 1. Fork the `https://github.com/yubarajshrestha/masonite-socketio-driver` repo.
14 | 2. Clone that repo into your computer: `git clone http://github.com/your-username/masonite-socketio-driver.git`.
15 | 3. Checkout the current release branch \(example: `master`\).
16 | 4. Run `git pull origin master` to get the current release version.
17 |
18 | ### Install the environment
19 |
20 | 1. You should create a Python virtual environment with `Python >= 3.6`.
21 | 2. Then install the dependencies and setup the project, in root directory with:
22 |
23 | ```
24 | make init
25 | ```
26 |
27 | **Note:**
28 |
29 | - The package will be locally installed in your venv (with `pip install .`). Meaning that you will be
30 | able to import it from the project contained in the package as if you installed it from PyPi.
31 | - When making changes to your packages you will need to uninstall the package and reinstall it with
32 | `pip uninstall masonite-socketio-driver && pip install .`
33 |
34 | ### Contribute
35 |
36 | - From there simply create:
37 | - a feature branch `feat/my-new-feature`
38 | - a fix branch `fix/my-new-fix`
39 | - Push to your origin repository:
40 | - `git push origin feat/my-new-feature`
41 | - Open a pull request (PR) and follow the PR process below
42 |
43 | 1. You should open an issue before making any pull requests. Not all features will be added to the package and some may be better off as another third party package. It wouldn't be good if you worked on a feature for several days and the pull request gets rejected for reasons that could have been discussed in an issue for several minutes.
44 | 2. Ensure any changes are well commented and any configuration files that are added have a flagpole comment on the variables it's setting.
45 | 3. Update the README.md if installation/configuration or usage has changed.
46 | 4. It's better to add unit tests for the changes you made.
47 | 5. The PR must pass Github CI checks. The PR can be merged in once you have a successful review from a maintainer.
48 | 6. The version will be bumped by the maintainer when merging, so don't edit package version in the PR.
49 |
50 | ### Testing
51 |
52 | - To add unit tests add tests under `tests/` directory, please read about [Masonite
53 | testing](https://docs.masoniteproject.com/useful-features/testing) in the official
54 | documentation
55 |
56 | - To test your package locally in a project, a default Masonite project is available
57 | at root. Just run `python craft serve` and navigate to `localhost:8000/` and
58 | you will see `Hello Package World` in your browser.
59 |
60 | ## Dev Guidelines
61 |
62 | ### Package development
63 |
64 | You should read guidelines on package creation in the [Official Documentation](https://docs.masoniteproject.com/advanced/creating-packages)
65 |
66 | ### Comments
67 |
68 | Comments are a vital part of any repository and should be used where needed. It is important not to overcomment something. If you find you need to constantly add comments, you're code may be too complex. Code should be self documenting \(with clearly defined variable and method names\)
69 |
70 | #### Types of comments to use
71 |
72 | There are 3 main type of comments you should use when developing for Masonite:
73 |
74 | **Module Docstrings**
75 |
76 | All modules should have a docstring at the top of every module file and should look something like:
77 |
78 | ```python
79 | """ This is a module to add support for Billing users """
80 | from masonite.request import Request
81 | ...
82 | ```
83 |
84 | **Method and Function Docstrings**
85 |
86 | All methods and functions should also contain a docstring with a brief description of what the module does
87 |
88 | For example:
89 |
90 | ```python
91 | def some_function(self):
92 | """
93 | This is a function that does x action.
94 | Then give an exmaple of when to use it
95 | """
96 | ... code ...
97 | ```
98 |
99 | **Code Comments**
100 |
101 | If you're code MUST be complex enough that future developers will not understand it, add a `#` comment above it
102 |
103 | For normal code this will look something like:
104 |
105 | ```python
106 | # This code performs a complex task that may not be understood later on
107 | # You can add a second line like this
108 | complex_code = 'value'
109 |
110 | perform_some_complex_task()
111 | ```
112 |
113 | **Flagpole Comments**
114 |
115 | Flag pole comments are a fantastic way to give developers an inside to what is really happening and for now should only be reserved for configuration files. A flag pole comment gets its name from how the comment looks
116 |
117 | ```text
118 | """
119 | |--------------------------------------------------------------------------
120 | | A Heading of The Setting Being Set
121 | |--------------------------------------------------------------------------
122 | |
123 | | A quick description
124 | |
125 | """
126 |
127 | SETTING = "some value"
128 | ```
129 |
130 | It's important to note that there should have exactly 75 `-` above and below the header and have a trailing `|` at the bottom of the comment.
131 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022, Yubaraj Shrestha
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/MANIFEST.in
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## SocketIO Driver
17 |
18 | It's an extra broadcast driver support for SocketIO in masonite 4, it extends default masonite broadcast driver to support SocketIO.
19 |
20 | **Masonite Broadcast Server and Client Library**
21 | - [x] [Broadcast Server](https://github.com/py-package/masonite-broadcast-server)
22 | - [x] [broadcast Client](https://github.com/py-package/masonite-broadcast-client)
23 |
24 | **Setup**
25 |
26 | Install package using pip:
27 |
28 | ```shell
29 | pip install masonite-socketio-driver
30 | ```
31 |
32 | Add provider inside config/providers.py.
33 |
34 | ```python
35 | from socketio_driver.providers import SocketProvider
36 |
37 | PROVIDERS = [
38 | ...,
39 | # Application Providers
40 | SocketProvider,
41 | ]
42 | ```
43 |
44 | **Driver Config**
45 | Add following configuration inside config/broadcast.py after `"pusher": {...},`
46 |
47 | ```python
48 | "pusher": {...},
49 | "socketio": {
50 | "driver": "socketio",
51 | "host": env("BROADCAST_HOST", "localhost"),
52 | "port": env("BROADCAST_PORT", "6379")
53 | },
54 | ```
55 |
56 | Add following keys in `.env`.
57 |
58 | ```shell
59 | BROADCAST_HOST=
60 | BROADCAST_PORT=
61 | ```
62 |
63 | Update the broadcast driver value to `socketio` in `.env`
64 |
65 | ```shell
66 | BROADCAST_DRIVER=socketio
67 | ```
68 |
69 | **Example**
70 |
71 | ```python
72 | # broadcast to given channels
73 |
74 | from masonite.controllers import Controller
75 | from masonite.broadcasting import Broadcast
76 |
77 | class YourController(Controller):
78 |
79 | def your_function(self, broadcast: Broadcast):
80 | broadcast_data = {
81 | "message": "Hello World"
82 | }
83 | broadcast.channel(["channel-name"], "event-name", broadcast_data)
84 | ```
85 |
86 | ```python
87 | # broadcast to selected users/clients
88 |
89 | from masonite.controllers import Controller
90 | from masonite.broadcasting import Broadcast
91 | from socketio_driver.facades import Communicator
92 |
93 | class YourController(Controller):
94 |
95 | def your_function(self, broadcast: Broadcast):
96 | broadcast_data = {
97 | "message": "Hello World"
98 | }
99 | clients = Communicator.clients()
100 | ids = [client.socketID for client in clients]
101 | broadcast.channel(ids, "event-name", broadcast_data)
102 |
103 |
104 | def or_another_function(self, broadcast: Broadcast):
105 | broadcast_data = {
106 | "message": "Hello World"
107 | }
108 | clients = Communicator.clients()
109 | broadcast.driver("socketio").user(clients[0]).send("event-name", broadcast_data)
110 | ```
111 |
112 | **Helpers**
113 |
114 | Facade helpers...
115 |
116 | ```python
117 | from socketio_driver.facades import Communicator
118 | ```
119 |
120 | ```python
121 | # List all clients:
122 | Communicator.clients()
123 | ```
124 | ```python
125 | # Get client by sessionID
126 | Communicator.client(id='client-session-id')
127 | ```
128 | ```python
129 | # Delete all clients
130 | Communicator.delete_all_clients()
131 | ```
132 | ```python
133 | # Delete client by SocketClient instance
134 | Communicator.delete(client)
135 |
136 | ```
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | codecov:
2 | require_ci_to_pass: no
3 |
4 | github_checks: false
5 |
6 | coverage:
7 | precision: 2
8 | round: down
9 | range: "70...100"
10 |
11 | parsers:
12 | gcov:
13 | branch_detection:
14 | conditional: yes
15 | loop: yes
16 | method: no
17 | macro: no
18 |
19 | comment:
20 | layout: "footer"
21 | behavior: default
22 | require_changes: no
23 |
--------------------------------------------------------------------------------
/craft:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """Craft Command.
3 | This module is really used for backup only if the masonite CLI cannot import this for you.
4 | This can be used by running "python craft". This module is not ran when the CLI can
5 | successfully import commands for you.
6 | """
7 |
8 | from wsgi import application
9 |
10 | if __name__ == '__main__':
11 | application.make('commands').run()
12 |
--------------------------------------------------------------------------------
/description:
--------------------------------------------------------------------------------
1 | Unnamed repository; edit this file 'description' to name the repository.
2 |
--------------------------------------------------------------------------------
/makefile:
--------------------------------------------------------------------------------
1 | .PHONY: help
2 | help: ## Show this help
3 | @egrep -h '\s##\s' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
4 |
5 | init: ## Install package dependencies
6 | cp .env-example .env
7 | pip install --upgrade pip
8 | # install test project and package dependencies
9 | pip install -r requirements.txt
10 | # install package and dev dependencies (see setup.py)
11 | pip install '.[dev]'
12 | test: ## Run package tests
13 | python -m pytest tests
14 | ci: ## [CI] Run package tests and lint
15 | make test
16 | make lint
17 | lint: ## Run code linting
18 | python -m flake8 .
19 | format: ## Format code with Black
20 | black src
21 | black tests
22 | coverage: ## Run package tests and upload coverage reports
23 | python -m pytest --cov-report term --cov-report xml --cov=src/masonite/socketio_driver tests
24 | publish: ## Publish package to pypi
25 | python setup.py sdist bdist_wheel
26 | twine upload dist/* --verbose
27 | rm -fr build dist .egg src/socketio_driver.egg-info
28 | pypirc: ## Copy the template .pypirc in the repo to your home directory
29 | cp .pypirc ~/.pypirc
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.black]
2 | line-length = 99
3 | target-version = ['py38']
4 | include = '\.pyi?$'
5 | exclude = '''
6 | /(
7 | \.git
8 | \.github
9 | \.vscode
10 | | \.venv
11 | | docs
12 | | node_modules
13 | | tests/integrations/templates
14 | )/
15 | '''
16 |
17 | [tool.isort]
18 | profile = "black"
19 | multi_line_output = 3
20 | include_trailing_comma = true
--------------------------------------------------------------------------------
/pytest.ini:
--------------------------------------------------------------------------------
1 | [pytest]
2 | filterwarnings =
3 | ignore::DeprecationWarning
4 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | masonite>=4,<5
2 | masonite-orm>=2,<3
3 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [flake8]
2 | exclude =
3 | .git,
4 | .github,
5 | .vscode,
6 | __pycache__,
7 | templates,
8 | node_modules,
9 | venv
10 | max-complexity = 10
11 | max-line-length = 99
12 |
13 | omit =
14 | */config/*
15 | setup.py
16 | */stubs/*
17 | wsgi.py
18 | tests/
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 | with open("README.md", "r", encoding="utf-8") as fh:
4 | long_description = fh.read()
5 |
6 | setup(
7 | name="masonite-socketio-driver",
8 | version='2.1.0',
9 | packages=[
10 | "socketio_driver",
11 | "socketio_driver.facades",
12 | "socketio_driver.models",
13 | "socketio_driver.config",
14 | "socketio_driver.drivers",
15 | "socketio_driver.providers"
16 | ],
17 | package_dir={"": "src"},
18 | description="Socket IO Broadcast Driver for Masonite",
19 | long_description=long_description,
20 | long_description_content_type="text/markdown",
21 | # The project's main homepage.
22 | url="https://github.com/py-package/masonite-socketio-driver",
23 | # Author details
24 | author="Yubaraj Shrestha",
25 | author_email="yubaraj@pypackage.com",
26 | project_urls={
27 | "Bug Tracker": "https://github.com/py-package/masonite-socketio-driver/issues",
28 | },
29 | classifiers=[
30 | # How mature is this project? Common values are
31 | # 3 - Alpha
32 | # 4 - Beta
33 | # 5 - Production/Stable
34 | "Development Status :: 5 - Production/Stable",
35 | # Indicate who your project is intended for
36 | "Intended Audience :: Developers",
37 | "Environment :: Web Environment",
38 | # Pick your license as you wish (should match "license" above)
39 | "License :: OSI Approved :: MIT License",
40 | "Operating System :: OS Independent",
41 | # Specify the Python versions you support here. In particular, ensure
42 | # that you indicate whether you support Python 2, Python 3 or both.
43 | "Programming Language :: Python :: 3.7",
44 | "Programming Language :: Python :: 3.8",
45 | "Programming Language :: Python :: 3.9",
46 | "Topic :: Software Development :: Libraries :: Application Frameworks",
47 | "Topic :: Software Development :: Libraries :: Python Modules",
48 | # List package on masonite packages website
49 | "Framework :: Masonite",
50 | ],
51 | keywords=["masonite", "socket-io", "broadcast", "masonite-socket-io-broadcast-driver"],
52 | install_requires=["masonite>=4.0<5.0", 'socket.io-emitter', 'redis', 'msgpack'],
53 | license="MIT",
54 | extras_require={
55 | "dev": [
56 | "black",
57 | "flake8",
58 | "coverage",
59 | "pytest",
60 | "pytest-cov",
61 | "twine>=1.5.0",
62 | "wheel",
63 | ],
64 | },
65 | package_data={
66 | 'templates/index.html': [],
67 | },
68 | )
69 |
--------------------------------------------------------------------------------
/src/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/src/__init__.py
--------------------------------------------------------------------------------
/src/socketio_driver/__init__.py:
--------------------------------------------------------------------------------
1 | # flake8: noqa: E501
2 | from .providers.socket_provider import SocketProvider
3 |
--------------------------------------------------------------------------------
/src/socketio_driver/communicator.py:
--------------------------------------------------------------------------------
1 | from masonite.configuration import config
2 | import redis
3 | import msgpack
4 | from .models.socket_client import SocketClient
5 | from masonite.auth.Sign import Sign
6 |
7 |
8 | class Communicator:
9 |
10 | EVENT = 2
11 | BINARY_EVENT = 5
12 |
13 | def __init__(self, application):
14 | self.config = config("broadcast").get("broadcasts").get("socketio")
15 | self.application = application
16 |
17 | self._opts = {
18 | "host": self.config.get("host"),
19 | "port": self.config.get("port"),
20 | }
21 |
22 | self._rooms = []
23 | self._flags = {}
24 |
25 | self.uid = "communicator"
26 |
27 | if "client" in self._opts and self._opts["client"] is not None:
28 | self._client = self._opts["client"]
29 | else:
30 | self._client = self._createClient()
31 |
32 | self._key = self._opts.get("key", "socket.io")
33 |
34 | # Limit emission to a certain `room`.
35 | def In(self, *room):
36 | self._rooms.append(room)
37 | return self
38 |
39 | # Limit emission to a certain `room`.
40 | def To(self, *room):
41 | return self.In(room)
42 |
43 | # Limit emission to certain `namespace`.
44 | def Of(self, nsp):
45 | self._flags["nsp"] = nsp
46 | return self
47 |
48 | # Send the packet.
49 | def Emit(self, *args):
50 | packet = {}
51 | extras = {}
52 |
53 | packet["data"] = args
54 | packet["type"] = self.BINARY_EVENT if self._hasBin(args) else self.EVENT
55 |
56 | # set namespace to packet
57 | if "nsp" in self._flags:
58 | packet["nsp"] = self._flags["nsp"]
59 | del self._flags["nsp"]
60 | else:
61 | packet["nsp"] = "/"
62 |
63 | extras["flags"] = self._flags if len(self._flags) > 0 else ""
64 |
65 | rooms = self._getRooms()
66 | extras["rooms"] = rooms if len(rooms) > 0 else ""
67 |
68 | if extras["rooms"]:
69 | for room in rooms:
70 | chn = "#".join((self._key, packet["nsp"], room, ""))
71 | self._client.publish(chn, msgpack.packb([self.uid, packet, extras]))
72 | else:
73 | chn = "#".join((self._key, packet["nsp"], ""))
74 | self._client.publish(chn, msgpack.packb([self.uid, packet, extras]))
75 |
76 | self._flags = {}
77 | self._rooms = []
78 |
79 | # Makes [[1,2],3,[4,[5,6]]] into an iterator of [1,2,3,4,5,6]
80 | def _flatten(self, root):
81 | if isinstance(root, (list, tuple)):
82 | for element in root:
83 | for e in self._flatten(element):
84 | yield e
85 | else:
86 | yield root
87 |
88 | # Get a list of unique rooms
89 | def _getRooms(self):
90 | return list(set(self._flatten(self._rooms)))
91 |
92 | # Not implemented yet
93 | def _hasBin(self, param):
94 | return False
95 |
96 | # Create a redis client from a `host:port` uri string.
97 | def _createClient(self):
98 | if "host" not in self._opts:
99 | raise Exception("Missing redis `host`")
100 | if "port" not in self._opts:
101 | raise Exception("Missing redis `port`")
102 |
103 | kwargs = {
104 | "host": self._opts["host"],
105 | "port": self._opts["port"],
106 | }
107 |
108 | if "password" in self._opts:
109 | kwargs["password"] = self._opts["password"]
110 |
111 | return redis.StrictRedis(**kwargs)
112 |
113 | def pubsub(self):
114 | return self._client.pubsub()
115 |
116 | def clients(self):
117 | client_keys = self._client.keys(pattern="mbroadcast:users:*")
118 | return [self.client(key) for key in client_keys]
119 |
120 | def client(self, id):
121 | client_data = self._client.hmget(
122 | id, "userID", "address", "sessionID", "socketID", "connected", "extra"
123 | )
124 | if client_data is None:
125 | return None
126 |
127 | userID, address, sessionID, socketID, connected, extra = client_data
128 |
129 | userID = userID.decode("utf-8") if userID is not None else None
130 | address = address.decode("utf-8") if address is not None else None
131 | sessionID = sessionID.decode("utf-8") if sessionID is not None else None
132 | socketID = socketID.decode("utf-8") if socketID is not None else None
133 | connected = connected.decode("utf-8") if connected is not None else False
134 | extra = extra.decode("utf-8") if extra is not None else ''
135 | return SocketClient(userID, address, sessionID, socketID, connected == "true", extra)
136 |
137 | def delete_all_clients(self):
138 | keys = self._client.keys(pattern="mbroadcast:users:*")
139 | for key in keys:
140 | self._client.delete(key)
141 |
142 | def delete(self, client: SocketClient):
143 | if client is None:
144 | return False
145 | self._client.delete(f"mbroadcast:users:{client.sessionID}")
146 |
147 | def authenticate(self, channel, socket_id, user_id):
148 | string_to_sign = "%s:%s:%s" % (socket_id, channel, user_id)
149 | auth = Sign().sign(string_to_sign)
150 | return {"auth": auth}
151 |
--------------------------------------------------------------------------------
/src/socketio_driver/config/socketio.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/src/socketio_driver/config/socketio.py
--------------------------------------------------------------------------------
/src/socketio_driver/controllers/BroadcastController.py:
--------------------------------------------------------------------------------
1 | from masonite.controllers import Controller
2 | from masonite.broadcasting import Broadcast
3 | from masonite.request import Request
4 | from masonite.response import Response
5 |
6 |
7 | class BroadcastController(Controller):
8 | def authorize(self, request: Request, broadcast: Broadcast, response: Response):
9 | if not request.user():
10 | return response.json({"message": "unauthorized"}, 204)
11 |
12 | return broadcast.driver("socketio").authorize(
13 | request.input("channel_name"), request.input("socket_id"), request.user().id
14 | )
15 |
--------------------------------------------------------------------------------
/src/socketio_driver/drivers/__init__.py:
--------------------------------------------------------------------------------
1 | # flake8: noqa: E501
2 | from .socket_driver import SocketDriver
3 |
--------------------------------------------------------------------------------
/src/socketio_driver/drivers/socket_driver.py:
--------------------------------------------------------------------------------
1 | from ..models.socket_client import SocketClient
2 |
3 |
4 | class SocketDriver:
5 | def __init__(self, application) -> None:
6 | self.application = application
7 | self.connection = None
8 | self.client: SocketClient = None
9 | self.channels: list = []
10 |
11 | def set_options(self, options):
12 | self.options = options
13 | return self
14 |
15 | def get_connection(self):
16 |
17 | if self.connection:
18 | return self.connection
19 |
20 | self.connection = self.application.make("communicator")
21 |
22 | return self.connection
23 |
24 | def user(self, client: SocketClient):
25 | self.client = client
26 | return self
27 |
28 | def channels(self, channels):
29 | self.channels = channels
30 | return self
31 |
32 | def send(self, event, value):
33 | connection = self.get_connection()
34 | if self.client is not None:
35 | self.channel(self.client.socketID, event, value)
36 | elif len(self.channels) > 0:
37 | for channel in self.channels:
38 | self.channel(channel, event, value)
39 | else:
40 | connection.Emit(event, value)
41 |
42 | self.client = None
43 | self.channels = []
44 |
45 | def channel(self, channel, event, value):
46 | connection = self.get_connection()
47 | return connection.To(channel).Emit(event, value)
48 |
49 | def authorize(self, channel, socket_id, user_id):
50 | return self.get_connection().authenticate(
51 | channel=channel, socket_id=socket_id, user_id=user_id
52 | )
53 |
--------------------------------------------------------------------------------
/src/socketio_driver/facades/__init__.py:
--------------------------------------------------------------------------------
1 | # flake8: noqa: E501
2 | from .communicator import Communicator
3 |
--------------------------------------------------------------------------------
/src/socketio_driver/facades/communicator.py:
--------------------------------------------------------------------------------
1 | from masonite.facades import Facade
2 |
3 |
4 | class Communicator(metaclass=Facade):
5 | key = "communicator"
6 |
--------------------------------------------------------------------------------
/src/socketio_driver/facades/communicator.pyi:
--------------------------------------------------------------------------------
1 | from ..models.socket_client import SocketClient
2 |
3 | class Communicator:
4 | def clients() -> list[SocketClient]:
5 | """Returns a list of all clients."""
6 | ...
7 | def client(id: str) -> SocketClient | None:
8 | """Returns a client by id."""
9 | ...
10 | def delete(id: str) -> bool:
11 | """Deletes a client by id."""
12 | ...
13 | def delete_all_clients() -> None:
14 | """Deletes all clients."""
15 | ...
16 |
--------------------------------------------------------------------------------
/src/socketio_driver/models/socket_client.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 |
3 |
4 | @dataclass
5 | class SocketClient:
6 | userID: str
7 | address: str
8 | sessionID: str
9 | socketID: str
10 | connected: bool
11 | extra: str
12 |
13 | def to_json(self):
14 | return {
15 | "userID": self.userID,
16 | "address": self.address,
17 | "sessionID": self.sessionID,
18 | "socketID": self.socketID,
19 | "connected": self.connected,
20 | "extra": self.extra,
21 | }
22 |
--------------------------------------------------------------------------------
/src/socketio_driver/providers/__init__.py:
--------------------------------------------------------------------------------
1 | # flake8: noqa: E501
2 | from .socket_provider import SocketProvider
3 |
--------------------------------------------------------------------------------
/src/socketio_driver/providers/socket_provider.py:
--------------------------------------------------------------------------------
1 | """ A SocketProvider Service Provider"""
2 |
3 | from masonite.packages import PackageProvider
4 | from ..communicator import Communicator
5 | from ..drivers.socket_driver import SocketDriver
6 |
7 |
8 | class SocketProvider(PackageProvider):
9 | def configure(self):
10 | """Register objects into the Service Container."""
11 | (self.root("socketio_driver").name("socketio").config("config/socketio.py", publish=False))
12 |
13 | def register(self):
14 | super().register()
15 | self.application.bind("communicator", Communicator(self.application))
16 | self.application.make("broadcast").add_driver("socketio", SocketDriver(self.application))
17 |
18 | def boot(self):
19 | """Boots services required by the container."""
20 | pass
21 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/tests/__init__.py
--------------------------------------------------------------------------------
/tests/integrations/Kernel.py:
--------------------------------------------------------------------------------
1 | from masonite.foundation import response_handler
2 | from masonite.storage import StorageCapsule
3 | from masonite.auth import Sign
4 | from masonite.environment import LoadEnvironment
5 | from masonite.utils.structures import load
6 | from masonite.utils.location import base_path
7 | from masonite.middleware import (
8 | SessionMiddleware,
9 | EncryptCookies,
10 | LoadUserMiddleware,
11 | MaintenanceModeMiddleware,
12 | )
13 | from masonite.routes import Route
14 | from masonite.configuration.Configuration import Configuration
15 | from masonite.configuration import config
16 |
17 | from .app.middlewares.VerifyCsrfToken import VerifyCsrfToken
18 |
19 |
20 | class Kernel:
21 |
22 | http_middleware = [MaintenanceModeMiddleware, EncryptCookies]
23 |
24 | route_middleware = {
25 | "web": [SessionMiddleware, LoadUserMiddleware, VerifyCsrfToken],
26 | }
27 |
28 | def __init__(self, app):
29 | self.application = app
30 |
31 | def register(self):
32 | # Register routes
33 | self.load_environment()
34 | self.register_configurations()
35 | self.register_middleware()
36 | self.register_routes()
37 | self.register_database()
38 | self.register_templates()
39 | self.register_storage()
40 |
41 | def load_environment(self):
42 | LoadEnvironment()
43 |
44 | def register_configurations(self):
45 | # load configuration
46 | self.application.bind("config.location", "tests/integrations/config")
47 | configuration = Configuration(self.application)
48 | configuration.load()
49 | self.application.bind("config", configuration)
50 | key = config("application.key")
51 | self.application.bind("key", key)
52 | self.application.bind("sign", Sign(key))
53 | # set locations
54 | self.application.bind("resources.location", "tests/integrations/resources/")
55 | self.application.bind("controllers.location", "tests/integrations/app/controllers")
56 | self.application.bind("jobs.location", "tests/integrations/jobs")
57 | self.application.bind("providers.location", "tests/integrations/providers")
58 | self.application.bind("mailables.location", "tests/integrations/mailables")
59 | self.application.bind("listeners.location", "tests/integrations/listeners")
60 | self.application.bind("validation.location", "tests/integrations/validation")
61 | self.application.bind("notifications.location", "tests/integrations/notifications")
62 | self.application.bind("events.location", "tests/integrations/events")
63 | self.application.bind("tasks.location", "tests/integrations/tasks")
64 | self.application.bind("models.location", "tests/integrations/app/models")
65 | self.application.bind("observers.location", "tests/integrations/models/observers")
66 | self.application.bind("policies.location", "tests/integrations/policies")
67 | self.application.bind("commands.location", "tests/integrations/commands")
68 | self.application.bind("middlewares.location", "tests/integrations/app/middlewares")
69 |
70 | self.application.bind("server.runner", "masonite.commands.ServeCommand.main")
71 |
72 | def register_middleware(self):
73 | self.application.make("middleware").add(self.route_middleware).add(self.http_middleware)
74 |
75 | def register_routes(self):
76 | Route.set_controller_locations(self.application.make("controllers.location"))
77 | self.application.bind("routes.location", "tests/integrations/routes/web")
78 | self.application.make("router").add(
79 | Route.group(
80 | load(self.application.make("routes.location"), "ROUTES"), middleware=["web"]
81 | )
82 | )
83 |
84 | def register_database(self):
85 | from masoniteorm.query import QueryBuilder
86 |
87 | self.application.bind(
88 | "builder",
89 | QueryBuilder(connection_details=config("database.databases")),
90 | )
91 |
92 | self.application.bind("migrations.location", "tests/integrations/databases/migrations")
93 | self.application.bind("seeds.location", "tests/integrations/databases/seeds")
94 |
95 | self.application.bind("resolver", config("database.db"))
96 |
97 | def register_templates(self):
98 | self.application.bind("views.location", "tests/integrations/templates/")
99 |
100 | def register_storage(self):
101 | storage = StorageCapsule()
102 | storage.add_storage_assets(config("filesystem.staticfiles"))
103 | self.application.bind("storage_capsule", storage)
104 |
105 | self.application.set_response_handler(response_handler)
106 | self.application.use_storage_path(base_path("storage"))
107 |
--------------------------------------------------------------------------------
/tests/integrations/app/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/tests/integrations/app/__init__.py
--------------------------------------------------------------------------------
/tests/integrations/app/controllers/WelcomeController.py:
--------------------------------------------------------------------------------
1 | """A WelcomeController Module."""
2 | from masonite.views import View
3 | from masonite.controllers import Controller
4 | from masonite.broadcasting import Broadcast
5 | from src.socketio_driver.facades import Communicator
6 |
7 |
8 | class WelcomeController(Controller):
9 | """WelcomeController Controller Class."""
10 |
11 | def show(self, view: View, broadcast: Broadcast):
12 | return view.render("welcome")
13 |
14 | def users(self):
15 | # Communicator.delete_all_clients()
16 | users = Communicator.clients()
17 |
18 | return {"users": [user.to_json() for user in users]}
19 |
20 | def broadcast(self, view: View, broadcast: Broadcast):
21 | broadcast_data = {"message": "Hello World"}
22 | users = Communicator.clients()
23 | for user in users:
24 | broadcast.driver("socketio").user(user).send("message", user.to_json())
25 |
26 | broadcast.channel(["mbroadcast"], "message", broadcast_data)
27 | return {"hello": "world!"}
28 |
--------------------------------------------------------------------------------
/tests/integrations/app/controllers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/tests/integrations/app/controllers/__init__.py
--------------------------------------------------------------------------------
/tests/integrations/app/middlewares/VerifyCsrfToken.py:
--------------------------------------------------------------------------------
1 | from masonite.middleware import VerifyCsrfToken as Middleware
2 |
3 |
4 | class VerifyCsrfToken(Middleware):
5 |
6 | exempt = []
7 |
--------------------------------------------------------------------------------
/tests/integrations/app/models/User.py:
--------------------------------------------------------------------------------
1 | """User Model."""
2 | from masoniteorm.models import Model
3 | from masoniteorm.scopes import SoftDeletesMixin
4 | from masonite.authentication import Authenticates
5 |
6 |
7 | class User(Model, SoftDeletesMixin, Authenticates):
8 | """User Model."""
9 |
10 | __fillable__ = ["name", "email", "password"]
11 | __hidden__ = ["password"]
12 | __auth__ = "email"
13 |
--------------------------------------------------------------------------------
/tests/integrations/config/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/tests/integrations/config/__init__.py
--------------------------------------------------------------------------------
/tests/integrations/config/application.py:
--------------------------------------------------------------------------------
1 | from masonite.environment import env
2 |
3 |
4 | KEY = env("APP_KEY", "-RkDOqXojJIlsF_I8wWiUq_KRZ0PtGWTOZ676u5HtLg=")
5 |
6 | HASHING = {
7 | "default": env("HASHING_FUNCTION", "bcrypt"),
8 | "bcrypt": {"rounds": 10},
9 | "argon2": {"memory": 1024, "threads": 2, "time": 2},
10 | }
11 |
12 | APP_URL = env("APP_URL", "http://localhost:8000/")
13 |
--------------------------------------------------------------------------------
/tests/integrations/config/auth.py:
--------------------------------------------------------------------------------
1 | from ..app.models.User import User
2 |
3 | GUARDS = {
4 | "default": "web",
5 | "web": {"model": User},
6 | "password_reset_table": "password_resets",
7 | "password_reset_expiration": 1440, # in minutes. 24 hours. None if disabled
8 | }
9 |
--------------------------------------------------------------------------------
/tests/integrations/config/broadcast.py:
--------------------------------------------------------------------------------
1 | from masonite.environment import env
2 |
3 |
4 | BROADCASTS = {
5 | "default": "socketio",
6 | "pusher": {
7 | "driver": "pusher",
8 | "client": env("PUSHER_CLIENT"),
9 | "app_id": env("PUSHER_APP_ID"),
10 | "secret": env("PUSHER_SECRET"),
11 | "cluster": env("PUSHER_CLUSTER"),
12 | "ssl": False,
13 | },
14 | "socketio": {
15 | "driver": "socketio",
16 | "host": env("BROADCAST_HOST", "localhost"),
17 | "port": env("BROADCAST_PORT", "6379"),
18 | },
19 | }
20 |
--------------------------------------------------------------------------------
/tests/integrations/config/cache.py:
--------------------------------------------------------------------------------
1 | # from masonite.environment import env
2 |
3 |
4 | STORES = {
5 | "default": "local",
6 | "local": {
7 | "driver": "file",
8 | "location": "storage/framework/cache"
9 | #
10 | },
11 | "redis": {
12 | "driver": "redis",
13 | "host": "127.0.0.1",
14 | "port": "6379",
15 | "password": "",
16 | "name": "project_name",
17 | },
18 | "memcache": {
19 | "driver": "memcache",
20 | "host": "127.0.0.1",
21 | "port": "11211",
22 | "password": "",
23 | "name": "project_name",
24 | },
25 | }
26 |
--------------------------------------------------------------------------------
/tests/integrations/config/database.py:
--------------------------------------------------------------------------------
1 | from masonite.environment import LoadEnvironment, env
2 | from masoniteorm.connections import ConnectionResolver
3 |
4 | # Loads in the environment variables when this page is imported.
5 | LoadEnvironment()
6 |
7 | """
8 | The connections here don't determine the database but determine the "connection".
9 | They can be named whatever you want.
10 | """
11 | DATABASES = {
12 | "default": env("DB_CONNECTION", "sqlite"),
13 | "sqlite": {
14 | "driver": "sqlite",
15 | "database": env("SQLITE_DB_DATABASE", "masonite.sqlite3"),
16 | "prefix": "",
17 | "log_queries": env("DB_LOG"),
18 | },
19 | "mysql": {
20 | "host": "127.0.0.1",
21 | "driver": "mysql",
22 | "database": "masonite_permission",
23 | "user": "meyubaraj",
24 | "password": "MDB@123#go",
25 | "port": 3306,
26 | "prefix": "",
27 | "grammar": "mysql",
28 | "options": {
29 | "charset": "utf8mb4",
30 | },
31 | "log_queries": env("DB_LOG"),
32 | },
33 | "postgres": {
34 | "host": "127.0.0.1",
35 | "driver": "postgres",
36 | "database": "masonite_permission",
37 | "user": "meyubaraj",
38 | "password": "MDB@123#go",
39 | "port": 5432,
40 | "prefix": "",
41 | "grammar": "postgres",
42 | "log_queries": env("DB_LOG"),
43 | },
44 | "mssql": {
45 | "driver": "mssql",
46 | "host": env("MSSQL_DATABASE_HOST"),
47 | "user": env("MSSQL_DATABASE_USER"),
48 | "password": env("MSSQL_DATABASE_PASSWORD"),
49 | "database": env("MSSQL_DATABASE_DATABASE"),
50 | "port": env("MSSQL_DATABASE_PORT"),
51 | "prefix": "",
52 | "log_queries": env("DB_LOG"),
53 | },
54 | }
55 |
56 | DB = ConnectionResolver().set_connection_details(DATABASES)
57 |
--------------------------------------------------------------------------------
/tests/integrations/config/exceptions.py:
--------------------------------------------------------------------------------
1 | HANDLERS = {"stack_overflow": True, "solutions": True}
2 |
--------------------------------------------------------------------------------
/tests/integrations/config/filesystem.py:
--------------------------------------------------------------------------------
1 | from masonite.environment import env
2 | from masonite.utils.location import base_path
3 |
4 |
5 | DISKS = {
6 | "default": "local",
7 | "local": {"driver": "file", "path": base_path("storage/framework/filesystem")},
8 | "s3": {
9 | "driver": "s3",
10 | "client": env("AWS_CLIENT"),
11 | "secret": env("AWS_SECRET"),
12 | "bucket": env("AWS_BUCKET"),
13 | },
14 | }
15 |
16 | STATICFILES = {
17 | "tests/integrations/storage/static": "static/",
18 | "tests/integrations/storage/compiled": "assets/",
19 | "tests/integrations/storage/public": "/",
20 | }
21 |
--------------------------------------------------------------------------------
/tests/integrations/config/mail.py:
--------------------------------------------------------------------------------
1 | from masonite.environment import env
2 |
3 |
4 | FROM_EMAIL = env("MAIL_FROM", "no-reply@masonite.com")
5 |
6 | DRIVERS = {
7 | "default": env("MAIL_DRIVER", "terminal"),
8 | "smtp": {
9 | "host": env("MAIL_HOST"),
10 | "port": env("MAIL_PORT"),
11 | "username": env("MAIL_USERNAME"),
12 | "password": env("MAIL_PASSWORD"),
13 | "from": FROM_EMAIL,
14 | },
15 | "mailgun": {
16 | "domain": env("MAILGUN_DOMAIN"),
17 | "secret": env("MAILGUN_SECRET"),
18 | "from": FROM_EMAIL,
19 | },
20 | "terminal": {
21 | "from": FROM_EMAIL,
22 | },
23 | }
24 |
--------------------------------------------------------------------------------
/tests/integrations/config/notification.py:
--------------------------------------------------------------------------------
1 | from masonite.environment import env
2 |
3 |
4 | DRIVERS = {
5 | "slack": {
6 | "token": env("SLACK_TOKEN", ""), # used for API mode
7 | "webhook": env("SLACK_WEBHOOK", ""), # used for webhook mode
8 | },
9 | "vonage": {
10 | "key": env("VONAGE_KEY", ""),
11 | "secret": env("VONAGE_SECRET", ""),
12 | "sms_from": env("VONAGE_SMS_FROM", "+33000000000"),
13 | },
14 | "database": {
15 | "connection": "sqlite",
16 | "table": "notifications",
17 | },
18 | }
19 |
20 | DRY = False
21 |
--------------------------------------------------------------------------------
/tests/integrations/config/providers.py:
--------------------------------------------------------------------------------
1 | from masonite.providers import (
2 | RouteProvider,
3 | FrameworkProvider,
4 | ViewProvider,
5 | WhitenoiseProvider,
6 | ExceptionProvider,
7 | MailProvider,
8 | SessionProvider,
9 | QueueProvider,
10 | CacheProvider,
11 | EventProvider,
12 | StorageProvider,
13 | HelpersProvider,
14 | BroadcastProvider,
15 | AuthenticationProvider,
16 | AuthorizationProvider,
17 | HashServiceProvider,
18 | ORMProvider,
19 | )
20 |
21 |
22 | from masonite.scheduling.providers import ScheduleProvider
23 | from masonite.notification.providers import NotificationProvider
24 | from masonite.validation.providers import ValidationProvider
25 |
26 | from src.socketio_driver.providers import SocketProvider
27 |
28 | PROVIDERS = [
29 | FrameworkProvider,
30 | HelpersProvider,
31 | RouteProvider,
32 | ViewProvider,
33 | WhitenoiseProvider,
34 | ExceptionProvider,
35 | MailProvider,
36 | NotificationProvider,
37 | SessionProvider,
38 | CacheProvider,
39 | QueueProvider,
40 | ScheduleProvider,
41 | EventProvider,
42 | StorageProvider,
43 | BroadcastProvider,
44 | HashServiceProvider,
45 | AuthenticationProvider,
46 | ValidationProvider,
47 | AuthorizationProvider,
48 | ORMProvider,
49 | SocketProvider,
50 | ]
51 |
--------------------------------------------------------------------------------
/tests/integrations/config/queue.py:
--------------------------------------------------------------------------------
1 | # from masonite.environment import env
2 |
3 |
4 | DRIVERS = {
5 | "default": "async",
6 | "database": {
7 | "connection": "sqlite",
8 | "table": "jobs",
9 | "failed_table": "failed_jobs",
10 | "attempts": 3,
11 | "poll": 5,
12 | },
13 | "redis": {
14 | #
15 | },
16 | "amqp": {
17 | "username": "guest",
18 | "password": "guest",
19 | "port": "5672",
20 | "vhost": "",
21 | "host": "localhost",
22 | "channel": "default",
23 | "queue": "masonite4",
24 | },
25 | "async": {
26 | "blocking": True,
27 | "callback": "handle",
28 | "mode": "threading",
29 | "workers": 1,
30 | },
31 | }
32 |
--------------------------------------------------------------------------------
/tests/integrations/config/session.py:
--------------------------------------------------------------------------------
1 | # from masonite.environment import env
2 |
3 |
4 | DRIVERS = {
5 | "default": "cookie",
6 | "cookie": {},
7 | }
8 |
--------------------------------------------------------------------------------
/tests/integrations/databases/migrations/2021_01_09_033202_create_password_reset_table.py:
--------------------------------------------------------------------------------
1 | from masoniteorm.migrations import Migration
2 |
3 |
4 | class CreatePasswordResetTable(Migration):
5 | def up(self):
6 | """Run the migrations."""
7 | with self.schema.create("password_resets") as table:
8 | table.string("email").unique()
9 | table.string("token")
10 | table.datetime("expires_at").nullable()
11 | table.datetime("created_at")
12 |
13 | def down(self):
14 | """Revert the migrations."""
15 | self.schema.drop("password_resets")
16 |
--------------------------------------------------------------------------------
/tests/integrations/databases/migrations/2021_01_09_043202_create_users_table.py:
--------------------------------------------------------------------------------
1 | from masoniteorm.migrations import Migration
2 |
3 |
4 | class CreateUsersTable(Migration):
5 | def up(self):
6 | """Run the migrations."""
7 | with self.schema.create("users") as table:
8 | table.increments("id")
9 | table.string("name")
10 | table.string("email").unique()
11 | table.string("password")
12 | table.string("second_password").nullable()
13 | table.string("remember_token").nullable()
14 | table.string("phone").nullable()
15 | table.timestamp("verified_at").nullable()
16 | table.timestamps()
17 | table.soft_deletes()
18 |
19 | def down(self):
20 | """Revert the migrations."""
21 | self.schema.drop("users")
22 |
--------------------------------------------------------------------------------
/tests/integrations/databases/migrations/2022_04_21_110158_create_audit_logs_table.py:
--------------------------------------------------------------------------------
1 | """CreateAuditLogsTable Migration."""
2 |
3 | from masoniteorm.migrations import Migration
4 |
5 |
6 | class CreateAuditLogsTable(Migration):
7 | def up(self):
8 | """
9 | Run the migrations.
10 | """
11 | with self.schema.create("audit_logs") as table:
12 | table.increments("id")
13 | table.integer("editor_id").unsigned().nullable()
14 | table.integer("model_id").unsigned()
15 | table.string("model_name")
16 | table.string("action")
17 | table.json("columns").default("{}")
18 | table.json("old_value").default("{}")
19 | table.json("new_value").default("{}")
20 | table.timestamps()
21 |
22 | def down(self):
23 | """
24 | Revert the migrations.
25 | """
26 | self.schema.drop("audit_logs")
27 |
--------------------------------------------------------------------------------
/tests/integrations/databases/seeds/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/tests/integrations/databases/seeds/__init__.py
--------------------------------------------------------------------------------
/tests/integrations/databases/seeds/database_seeder.py:
--------------------------------------------------------------------------------
1 | """Base Database Seeder Module."""
2 | from masoniteorm.seeds import Seeder
3 |
4 | from .user_table_seeder import UserTableSeeder
5 |
6 |
7 | class DatabaseSeeder(Seeder):
8 | def run(self):
9 | """Run the database seeds."""
10 | self.call(UserTableSeeder)
11 |
--------------------------------------------------------------------------------
/tests/integrations/databases/seeds/user_table_seeder.py:
--------------------------------------------------------------------------------
1 | """UserTableSeeder Seeder."""
2 | from masoniteorm.seeds import Seeder
3 | from masonite.facades import Hash
4 |
5 | from tests.integrations.app.models.User import User
6 |
7 |
8 | class UserTableSeeder(Seeder):
9 | def run(self):
10 | """Run the database seeds."""
11 | User.create(
12 | {
13 | "name": "Joe",
14 | "email": "user@example.com",
15 | "password": Hash.make("secret"),
16 | "phone": "+123456789",
17 | }
18 | )
19 |
--------------------------------------------------------------------------------
/tests/integrations/resources/css/app.css:
--------------------------------------------------------------------------------
1 | /* Put your CSS here */
2 |
--------------------------------------------------------------------------------
/tests/integrations/resources/js/app.js:
--------------------------------------------------------------------------------
1 |
2 | require("./bootstrap.js")
3 |
--------------------------------------------------------------------------------
/tests/integrations/resources/js/bootstrap.js:
--------------------------------------------------------------------------------
1 | /**
2 | * We'll load the axios HTTP library which allows us to easily issue requests
3 | * to our Masonite back-end. This library automatically handles sending the
4 | * CSRF token as a header based on the value of the "XSRF" token cookie.
5 | */
6 |
7 | window.axios = require('axios');
8 |
9 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
10 |
11 | /**
12 | * Next we will register the CSRF Token as a common header with Axios so that
13 | * all outgoing HTTP requests automatically have it attached. This is just
14 | * a simple convenience so we don't have to attach every token manually.
15 | */
16 |
17 | let token = document.head.querySelector('meta[name="csrf-token"]');
18 |
19 | if (token) {
20 | window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
21 | } else {
22 | console.error('CSRF token not found: https://docs.masoniteproject.com/features/csrf#ajax-vue-axios');
23 | }
24 |
--------------------------------------------------------------------------------
/tests/integrations/routes/web.py:
--------------------------------------------------------------------------------
1 | from masonite.routes import Route
2 |
3 | ROUTES = [
4 | Route.get("/", "WelcomeController@show"),
5 | Route.get("/users", "WelcomeController@users"),
6 | Route.get("/broadcast", "WelcomeController@broadcast"),
7 | ]
8 |
--------------------------------------------------------------------------------
/tests/integrations/storage/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/tests/integrations/storage/.gitignore
--------------------------------------------------------------------------------
/tests/integrations/storage/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/tests/integrations/storage/public/favicon.ico
--------------------------------------------------------------------------------
/tests/integrations/storage/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/tests/integrations/storage/public/logo.png
--------------------------------------------------------------------------------
/tests/integrations/storage/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
--------------------------------------------------------------------------------
/tests/integrations/templates/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/tests/integrations/templates/__init__.py
--------------------------------------------------------------------------------
/tests/integrations/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {% block title %}Masonite 4{% endblock %}
10 |
11 |
12 |
13 | {% block head %}
14 |
15 | {% endblock %}
16 |
17 |
18 |
19 | {% block content %}{% endblock %}
20 | {% block js %}
21 |
22 | {% endblock %}
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tests/integrations/templates/maintenance.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Server Maintenance
9 |
10 |
11 |
12 |
13 | {% block content %}
14 |
15 |
Sorry, this site is currently down for maintenance.
16 |
17 | {% endblock %}
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tests/integrations/templates/welcome.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% block title %}Welcome on Masonite 4{% endblock %}
3 |
4 | {% block content %}
5 |
6 |
7 |
8 |
9 | Test
10 |
11 |
12 |
13 | {% endblock %}
14 |
15 | {% block js %}
16 |
67 | {% endblock %}
--------------------------------------------------------------------------------
/tests/unit/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/py-package/masonite-socketio-driver/3ad5a4fc6347cf1a35c42ba9b58439c33e049a3f/tests/unit/__init__.py
--------------------------------------------------------------------------------
/tests/unit/test_package.py:
--------------------------------------------------------------------------------
1 | from masonite.tests import TestCase
2 |
3 |
4 | class Testmasonite_modules(TestCase):
5 | def test_example(self):
6 | self.assertTrue(True)
7 |
--------------------------------------------------------------------------------
/wsgi.py:
--------------------------------------------------------------------------------
1 | from masonite.foundation import Application, Kernel
2 | from tests.integrations.config.providers import PROVIDERS
3 | from tests.integrations.Kernel import Kernel as ApplicationKernel
4 |
5 |
6 | """Start The Application Instance."""
7 | application = Application("tests/integrations")
8 |
9 | """Now Bind important providers needed to make the framework work."""
10 | application.register_providers(Kernel, ApplicationKernel)
11 |
12 | """Now Bind important application specific providers needed to make the application work."""
13 | application.add_providers(*PROVIDERS)
14 |
--------------------------------------------------------------------------------