├── __init__.py ├── media ├── logo.png └── architecture.png ├── .gitmodules ├── utils.py ├── dashboard_setup.py ├── CODE_OF_CONDUCT.md ├── handler_setup.py ├── gateway_setup.py ├── core_setup.py ├── .gitignore ├── notify_setup.py ├── CONTRIBUTING.md ├── README.md ├── LICENSE └── api_doc.json /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /media/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tata1mg/notifyone/HEAD/media/logo.png -------------------------------------------------------------------------------- /media/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tata1mg/notifyone/HEAD/media/architecture.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "notifyone-gateway"] 2 | path = notifyone-gateway 3 | url = https://github.com/tata1mg/notifyone-gateway 4 | [submodule "notifyone-core"] 5 | path = notifyone-core 6 | url = https://github.com/tata1mg/notifyone-core 7 | [submodule "notifyone-dashboard"] 8 | path = notifyone-dashboard 9 | url = https://github.com/tata1mg/notifyone-dashboard.git 10 | [submodule "notifyone-handler"] 11 | path = notifyone-handler 12 | url = https://github.com/tata1mg/notifyone-handler.git 13 | -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | def extract_values(obj, key): 2 | """Pull all values of specified key from nested JSON.""" 3 | arr = [] 4 | 5 | def extract(obj, arr, key): 6 | """Recursively search for values of key in JSON tree.""" 7 | if isinstance(obj, dict): 8 | for k, v in obj.items(): 9 | if isinstance(v, (dict, list)): 10 | extract(v, arr, key) 11 | elif k == key and v: 12 | arr.append(v) 13 | elif isinstance(obj, list): 14 | for item in obj: 15 | extract(item, arr, key) 16 | return arr 17 | 18 | results = extract(obj, arr, key) 19 | return results -------------------------------------------------------------------------------- /dashboard_setup.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import json 3 | import os 4 | from sys import platform 5 | 6 | 7 | def setup_dashboard(sys_platform, cms_api_endpoint): 8 | print("\nSetting up notifyone-dashboard.....\n") 9 | 10 | os.chdir('notifyone-dashboard') 11 | 12 | _res = subprocess.run(['cp src/config.template.json src/config.json'], shell=True, capture_output=True) 13 | if _res.returncode != 0: 14 | print(str(_res.stderr.decode('utf-8'))) 15 | exit(1) 16 | 17 | with open('./src/config.json', 'r') as c: 18 | _dashboard_config = json.load(c) 19 | _dashboard_port = str(_dashboard_config.get("communicationAppUrlPort") or 8000) 20 | _dashboard_config["serverDomain"] = cms_api_endpoint 21 | # if platform.lower() == 'darwin': 22 | # _dashboard_config["communication"]["serverDomain"] = "http://host.docker.internal:9402" 23 | # _dashboard_config["server"]["base_notification_url"] = "http://host.docker.internal:9402" 24 | with open('./src/config.json', 'w') as f: 25 | json.dump(_dashboard_config, f) 26 | 27 | _stat = subprocess.run(['docker rm --force notifyone-dashboard'], shell=True) 28 | _stat = subprocess.run(["docker image rm notifyone-dashboard"], shell=True) 29 | 30 | _res = subprocess.run(['docker build . --tag notifyone-dashboard --build-arg SERVICE_NAME=notifyone_dashboard --build-arg SYS_PLATFORM={}'.format(sys_platform)], 31 | shell=True, capture_output=True) 32 | if _res.returncode != 0: 33 | print(str(_res.stderr.decode('utf-8'))) 34 | exit(1) 35 | 36 | _res = subprocess.run([ 37 | 'docker run -p ' + _dashboard_port + ':' + _dashboard_port + ' --detach --name notifyone-dashboard notifyone-dashboard'], 38 | shell=True, capture_output=True) 39 | if _res.returncode != 0: 40 | print(str(_res.stderr.decode('utf-8'))) 41 | exit(1) 42 | 43 | print("\nnotifyone-dashboard setup completed\n") 44 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. -------------------------------------------------------------------------------- /handler_setup.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import json 3 | import os 4 | from sys import platform 5 | from utils import extract_values 6 | 7 | def setup_handler(sys_platform): 8 | 9 | print("\nSetting up notifyone-handler.....\n") 10 | 11 | os.chdir('notifyone-handler') 12 | 13 | _res = subprocess.run(['cp config_template.json config.json'], shell=True, capture_output=True) 14 | if _res.returncode != 0: 15 | print(str(_res.stderr.decode('utf-8'))) 16 | exit(1) 17 | 18 | with open('config.json') as c: 19 | _handler_config = json.load(c) 20 | _handler_queue_names = extract_values(_handler_config, "QUEUE_NAME") 21 | _port = str(_handler_config.get("PORT") or 9403) 22 | if platform.lower() == 'darwin': 23 | _handler_config["NOTIFYONE_CORE"]["HOST"] = 'http://host.docker.internal:9402' 24 | _handler_config['SQS_AUTH']['SQS_ENDPOINT_URL'] = 'http://host.docker.internal:4566' 25 | with open('config.json', 'w') as f: 26 | json.dump(_handler_config, f) 27 | elif platform.lower() == "linux": 28 | _handler_config["NOTIFYONE_CORE"]["HOST"] = 'http://notifyone-core:9402' 29 | _handler_config['SQS_AUTH']['SQS_ENDPOINT_URL'] = 'http://localstack-main:4566' 30 | with open('config.json', 'w') as f: 31 | json.dump(_handler_config, f) 32 | 33 | # create local stack queues 34 | for _q in _handler_queue_names: 35 | _res = subprocess.run(["docker exec -i $(docker ps | grep localstack | awk '{print $1}') awslocal sqs create-queue --queue-name " + _q], 36 | shell=True, capture_output=True) 37 | if _res.returncode != 0: 38 | print("\nError in creating queue {}\n".format(_q)) 39 | print(_res.stderr.decode('utf-8')) 40 | else: 41 | pass 42 | 43 | _stat = subprocess.run(['docker rm --force notifyone-handler'], shell=True) 44 | _stat = subprocess.run(["docker image rm notifyone-handler"], shell=True) 45 | 46 | _res = subprocess.run(['docker build . --tag notifyone-handler --build-arg SERVICE_NAME=notifyone_handler --build-arg SYS_PLATFORM={}'.format(sys_platform)], 47 | shell=True, capture_output=True) 48 | if _res.returncode != 0: 49 | print(str(_res.stderr.decode('utf-8'))) 50 | exit(1) 51 | 52 | _res = subprocess.run(['docker run -p ' + _port + ':' + _port + ' --detach --name notifyone-handler notifyone-handler'], 53 | shell=True, capture_output=True) 54 | if _res.returncode != 0: 55 | print(str(_res.stderr.decode('utf-8'))) 56 | exit(1) 57 | 58 | print("\nnotifyone-core setup completed\n") -------------------------------------------------------------------------------- /gateway_setup.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import json 3 | import os 4 | from utils import extract_values 5 | from sys import platform 6 | 7 | 8 | def setup_gateway(sys_platform): 9 | print("\nSetting up notifyone-gateway.....\n") 10 | 11 | os.chdir('notifyone-gateway') 12 | 13 | _res = subprocess.run(['cp config_template.json config.json'], shell=True, capture_output=True) 14 | if _res.returncode != 0: 15 | print(str(_res.stderr.decode('utf-8'))) 16 | exit(1) 17 | 18 | with open('config.json', 'r') as c: 19 | _gateway_config = json.load(c) 20 | _gateway_port = str(_gateway_config.get("PORT") or 9401) 21 | _gateway_queue_names = extract_values(_gateway_config, "QUEUE_NAME") 22 | if platform.lower() == 'darwin': 23 | _gateway_config['NOTIFICATION_SERVICE']['HOST'] = 'http://host.docker.internal:9402' 24 | _gateway_config['TRIGGER_NOTIFICATIONS']['SQS']['SQS_ENDPOINT_URL'] = 'http://host.docker.internal:4566' 25 | with open('config.json', 'w') as f: 26 | json.dump(_gateway_config, f) 27 | elif platform.lower() == "linux": 28 | _gateway_config['NOTIFICATION_SERVICE']['HOST'] = 'http://notifyone-core:9402' 29 | _gateway_config['TRIGGER_NOTIFICATIONS']['SQS']['SQS_ENDPOINT_URL'] = 'http://localstack-main:4566' 30 | with open('config.json', 'w') as f: 31 | json.dump(_gateway_config, f) 32 | 33 | # create local stack queues 34 | for _q in _gateway_queue_names: 35 | _res = subprocess.run(["docker exec -i $(docker ps | grep localstack | awk '{print $1}') awslocal sqs create-queue --queue-name " + _q], 36 | shell=True, capture_output=True) 37 | if _res.returncode != 0: 38 | print("\nError in creating queue {}\n".format(_q)) 39 | print(_res.stderr.decode('utf-8')) 40 | else: 41 | pass 42 | 43 | _stat = subprocess.run(['docker rm --force notifyone-gateway'], shell=True) 44 | _stat = subprocess.run(["docker image rm notifyone-gateway"], shell=True) 45 | 46 | _res = subprocess.run(['docker build . --tag notifyone-gateway --build-arg SERVICE_NAME=notifyone_gateway --build-arg SYS_PLATFORM={}'.format(sys_platform)], 47 | shell=True, capture_output=True) 48 | if _res.returncode != 0: 49 | print(str(_res.stderr.decode('utf-8'))) 50 | exit(1) 51 | 52 | _res = subprocess.run([ 53 | 'docker run -p ' + _gateway_port + ':' + _gateway_port + ' --detach --name notifyone-gateway notifyone-gateway'], 54 | shell=True, capture_output=True) 55 | if _res.returncode != 0: 56 | print(str(_res.stderr.decode('utf-8'))) 57 | exit(1) 58 | 59 | print("\nnotifyone-gateway setup completed\n") -------------------------------------------------------------------------------- /core_setup.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import json 3 | import os 4 | from utils import extract_values 5 | from sys import platform 6 | 7 | def setup_core(sys_platform): 8 | print("\nSetting up notifyone-core....\n") 9 | 10 | os.chdir('notifyone-core') 11 | 12 | _res = subprocess.run(['cp config_template.json config.json'], shell=True, capture_output=True) 13 | if _res.returncode != 0: 14 | print(str(_res.stderr.decode('utf-8'))) 15 | exit(1) 16 | 17 | with open('config.json') as c: 18 | _core_config = json.load(c) 19 | _core_queue_names = extract_values(_core_config, "QUEUE_NAME") 20 | _port = str(_core_config.get("PORT") or 9402) 21 | if platform.lower() == 'darwin': 22 | _core_config['DB_CONNECTIONS']['connections']['default']['credentials']['host'] = 'host.docker.internal' 23 | _core_config['SUBSCRIBE_NOTIFICATION_STATUS_UPDATES']['SQS']['SQS_ENDPOINT_URL'] = 'http://host.docker.internal:4566' 24 | _core_config['DISPATCH_NOTIFICATION_REQUEST']['SQS']['SQS_ENDPOINT_URL'] = 'http://host.docker.internal:4566' 25 | _core_config['NOTIFICATION_REQUEST']['SQS']['SQS_ENDPOINT_URL'] = 'http://host.docker.internal:4566' 26 | _core_config['REDIS_CACHE_HOSTS']['default']['REDIS_HOST'] = 'host.docker.internal' 27 | with open('config.json', 'w') as f: 28 | json.dump(_core_config, f) 29 | elif platform.lower() == "linux": 30 | _core_config['DB_CONNECTIONS']['connections']['default']['credentials']['host'] = 'postgres_notify' 31 | _core_config['SUBSCRIBE_NOTIFICATION_STATUS_UPDATES']['SQS']['SQS_ENDPOINT_URL'] = 'http://localstack-main:4566' 32 | _core_config['DISPATCH_NOTIFICATION_REQUEST']['SQS']['SQS_ENDPOINT_URL'] = 'http://localstack-main:4566' 33 | _core_config['NOTIFICATION_REQUEST']['SQS']['SQS_ENDPOINT_URL'] = 'http://localstack-main:4566' 34 | _core_config['REDIS_CACHE_HOSTS']['default']['REDIS_HOST'] = 'redis_notify' 35 | with open('config.json', 'w') as f: 36 | json.dump(_core_config, f) 37 | 38 | # create local stack queues 39 | for _q in _core_queue_names: 40 | _res = subprocess.run(["docker exec -i $(docker ps | grep localstack | awk '{print $1}') awslocal sqs create-queue --region eu-west-2 --queue-name " + _q], 41 | shell=True, capture_output=True) 42 | if _res.returncode != 0: 43 | print("\nError in creating queue {}\n".format(_q)) 44 | print(_res.stderr.decode('utf-8')) 45 | else: 46 | pass 47 | 48 | _stat = subprocess.run(['docker rm --force notifyone-core'], shell=True) 49 | _stat = subprocess.run(["docker image rm notifyone-core"], shell=True) 50 | 51 | _res = subprocess.run(['docker build . --tag notifyone-core --build-arg SERVICE_NAME=notifyone_core --build-arg SYS_PLATFORM={}'.format(sys_platform)], 52 | shell=True, capture_output=True) 53 | if _res.returncode != 0: 54 | print(str(_res.stderr.decode('utf-8'))) 55 | exit(1) 56 | 57 | _res = subprocess.run(['docker run -p ' + _port + ':' + _port + ' --detach --name notifyone-core notifyone-core'], 58 | shell=True, capture_output=True) 59 | if _res.returncode != 0: 60 | print(str(_res.stderr.decode('utf-8'))) 61 | exit(1) 62 | 63 | _res = subprocess.run(["docker exec -i $(docker ps | grep notifyone-core | awk '{print $1}') python3 database.py upgrade "], 64 | shell=True, capture_output=True) 65 | if _res.returncode != 0: 66 | print("\nError in DB upgrade\n") 67 | print(_res.stderr.decode('utf-8')) 68 | else: 69 | pass 70 | 71 | print("\nnotifyone-core setup completed\n") -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | -------------------------------------------------------------------------------- /notify_setup.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import os 3 | import sys 4 | from sys import platform 5 | from gateway_setup import setup_gateway 6 | from core_setup import setup_core 7 | from handler_setup import setup_handler 8 | from dashboard_setup import setup_dashboard 9 | 10 | sys_platform = sys.argv[1] if len(sys.argv) > 1 else "linux/amd64" 11 | cms_api_endpoint = sys.argv[2] if len(sys.argv) > 2 else "" 12 | 13 | print("Building for system platform - {}".format(sys_platform)) 14 | 15 | _docker_check_res = subprocess.run(['docker info'], shell=True, capture_output=True) 16 | if _docker_check_res.returncode != 0: 17 | print("Either Docker is not installed or not running\n"+(str(_docker_check_res.stderr.decode('utf-8')))) 18 | exit(1) 19 | 20 | 21 | print("\n Setting up Postgres on Docker\n") 22 | _res = subprocess.run(['docker pull postgres:14.5'], shell=True, capture_output=True) 23 | if _res.returncode != 0: 24 | print(str(_res.stderr.decode('utf-8'))) 25 | exit(1) 26 | 27 | _stat = subprocess.run(['docker rm --force postgres_notify'], shell=True) 28 | _res = subprocess.run(["docker run --detach -p5432:5432 -e POSTGRES_PASSWORD='postgres' -e POSTGRES_USER=postgres --name postgres_notify postgres:14.5"], shell=True, capture_output=True) 29 | if _res.returncode != 0: 30 | print(str(_res.stderr.decode('utf-8'))) 31 | exit(1) 32 | 33 | print("\n Setting up Redis on Docker\n") 34 | _stat = subprocess.run(['docker rm --force redis_notify'], shell=True) 35 | _res = subprocess.run(["docker run --detach --name redis_notify -p 6379:6379 -d redis"], shell=True, capture_output=True) 36 | if _res.returncode != 0: 37 | print(str(_res.stderr.decode('utf-8'))) 38 | exit(1) 39 | 40 | 41 | print("\n Setting up localstack\n") 42 | # install localstack 43 | _res = subprocess.run(['localstack --version'], shell=True, capture_output=True) 44 | if _res.returncode != 0: 45 | print("Localstack not installed \n"+(str(_docker_check_res.stderr.decode('utf-8')))) 46 | print("\n installing localstack \n") 47 | _localstack_res = subprocess.run(['python3 -m pip install --force-reinstall localstack'], shell=True, capture_output=True) 48 | if _localstack_res.returncode != 0: 49 | print(str(_localstack_res.stderr.decode('utf-8'))) 50 | exit(1) 51 | else: 52 | pass 53 | else: 54 | pass 55 | 56 | 57 | 58 | _localstack_start_res = subprocess.run(['localstack start -d'], shell=True, capture_output=True) 59 | if _localstack_start_res.returncode != 0: 60 | print(str(_localstack_start_res.stderr.decode('utf-8'))) 61 | exit(1) 62 | else: 63 | pass 64 | 65 | # print("setup aws default region to eu-west-2") 66 | # _res = subprocess.run(["rm /tmp/config"], 67 | # shell=True, capture_output=True) 68 | # _res = subprocess.run(['touch /tmp/config | echo "[default]" >> /tmp/config | echo "region=eu-west-2" >> /tmp/config'], 69 | # shell=True, capture_output=True) 70 | # if _res.returncode != 0: 71 | # print("\nError in creating localstck aws config file\n") 72 | # print(_res.stderr.decode('utf-8')) 73 | # else: 74 | # pass 75 | # _res = subprocess.run( 76 | # ["docker exec -i $(docker ps | grep localstack | awk '{print $1}') mkdir /root/.aws"], 77 | # shell=True, capture_output=True) 78 | # _res = subprocess.run( 79 | # ["docker cp /tmp/config $(docker ps | grep localstack | awk '{print $1}'):/root/.aws/config"], 80 | # shell=True, capture_output=True) 81 | # if _res.returncode != 0: 82 | # print("\nError in copying localstck aws config file to localstack container\n") 83 | # print(_res.stderr.decode('utf-8')) 84 | # else: 85 | # pass 86 | 87 | print("### Init component submodules........") 88 | subprocess.run('git submodule init', shell=True, capture_output=True) 89 | print("### Update component submodules........") 90 | subprocess.run('git submodule update', shell=True, capture_output=True) 91 | 92 | # Pull required python slim image 93 | print("Pull required python slim image - python:3.9.10-slim") 94 | _res = subprocess.run('docker pull --platform="{}" python:3.9.10-slim'.format(sys_platform), shell=True, capture_output=True) 95 | if _res.returncode != 0: 96 | print(str(_res.stderr.decode('utf-8'))) 97 | exit(1) 98 | 99 | # Create a docker network and connect components to the network 100 | if platform == "linux": 101 | subprocess.run('docker network create notifyone-network', shell=True, capture_output=True) 102 | subprocess.run('docker network connect notifyone-network postgres_notify', shell=True, capture_output=True) 103 | subprocess.run('docker network connect notifyone-network redis_notify', shell=True, capture_output=True) 104 | subprocess.run('docker network connect notifyone-network localstack-main', shell=True, capture_output=True) 105 | 106 | setup_gateway(sys_platform) 107 | 108 | os.chdir('../') 109 | 110 | setup_core(sys_platform) 111 | 112 | os.chdir('../') 113 | 114 | setup_handler(sys_platform) 115 | 116 | os.chdir('../') 117 | 118 | setup_dashboard(sys_platform, cms_api_endpoint) 119 | 120 | os.chdir('../') 121 | 122 | if platform == "linux": 123 | subprocess.run('docker network connect notifyone-network notifyone-gateway', shell=True, capture_output=True) 124 | subprocess.run('docker network connect notifyone-network notifyone-core', shell=True, capture_output=True) 125 | subprocess.run('docker network connect notifyone-network notifyone-handler', shell=True, capture_output=True) 126 | subprocess.run('docker network connect notifyone-network notifyone-dashboard', shell=True, capture_output=True) 127 | 128 | _res = subprocess.run(["docker exec -i $(docker ps | grep notifyone-core | awk '{print $1}') python3 database.py upgrade "], 129 | shell=True, capture_output=True) 130 | if _res.returncode != 0: 131 | print("\nError in DB upgrade\n") 132 | print(_res.stderr.decode('utf-8')) 133 | else: 134 | print("\nDB upgrade Successful\n") 135 | 136 | print('##### Congratulations! NotifyOne system setup Completed #####') 137 | print('Service Hosts - \n\t notifyone-dashboard : http://localhost:8001 \n\t notifyone-gateway : http://localhost:9401 \n\t notifyone-core : http://localhost:9402 \n\t notifyone-handler : http://localhost:9403') 138 | print('Create App API documentation - \n\t http://localhost:9402/swagger/#/Apps/post_apps') 139 | print('Create Event API documentation - \n\t http://localhost:9402/swagger/#/Events/post_event_create') 140 | print('Send-Notification API documentation - \n\t http://localhost:9401/swagger/#/event_notification/post_send_notification') 141 | print('Get-Notification-Detail API documentation - \n\t http://localhost:9401/swagger/#/event_notification/get_get_notification') 142 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | *Pull requests, bug reports, and all other forms of contribution are welcomed and highly encouraged!* :octocat: 4 | 5 | ### Contents 6 | 7 | - [Code of Conduct](#code-of-conduct) 8 | - [Asking Questions, Discussing ideas](#asking-questions) 9 | - [Opening an Issue](#opening-an-issue) 10 | - [Feature Requests](#feature-requests) 11 | - [Submitting Pull Requests](#submitting-pull-requests) 12 | - [Writing Commit Messages](#writing-commit-messages) 13 | - [Code Review](#code-review) 14 | - [Coding Style](#coding-style) 15 | 16 | > **This guide serves to set clear expectations for everyone involved with the project so that we can improve it together while also creating a welcoming space for everyone to participate. Following these guidelines will help ensure a positive experience for contributors and maintainers.** 17 | 18 | ## Code of Conduct 19 | 20 | Please review our [Code of Conduct](https://github.com/tata1mg/notifyone/blob/master/CODE_OF_CONDUCT.md). It is in effect at all times. We expect it to be honored by everyone who contributes to this project. 21 | 22 | ## Asking Questions, Discussing ideas 23 | 24 | Please use [GitHub Discussion](https://github.com/tata1mg/notifyone/discussions) to discuss the ideas and ask questions. 25 | 26 | ## Opening an Issue 27 | Please use [GitHub Issues](https://github.com/tata1mg/notifyone/issues) to report issues or request a feature. 28 | 29 | Before [creating an issue](https://help.github.com/en/github/managing-your-work-on-github/creating-an-issue), check if you are using the latest version of the project. If you are not up-to-date, see if updating fixes your issue first. 30 | 31 | ### Bug Reports and Other Issues 32 | 33 | A great way to contribute to the project is to send a detailed issue when you encounter a problem. We always appreciate a well-written, thorough bug report. 34 | 35 | In short, since you are most likely a developer, **provide a ticket that you would like to receive**. 36 | 37 | - **Do not open a duplicate issue!** Search through existing issues to see if your issue has previously been reported. If your issue exists, comment with any additional information you have. You may simply note "I have this problem too", which helps prioritize the most common problems and requests. 38 | 39 | ### Feature Requests 40 | 41 | Feature requests are welcome! While we will consider all requests, we cannot guarantee your request will be accepted. We want to avoid [feature creep](https://en.wikipedia.org/wiki/Feature_creep). Your idea may be great, but also out-of-scope for the project. If accepted, we cannot make any commitments regarding the timeline for implementation and release. However, you are welcome to submit a pull request to help! 42 | 43 | - **Do not open a duplicate feature request.** Search for existing feature requests first. If you find your feature (or one very similar) previously requested, comment on that issue. 44 | - Be precise about the proposed outcome of the feature and how it relates to existing features. Include implementation details if possible. 45 | 46 | ## Submitting Pull Requests 47 | 48 | We **love** pull requests! Before [forking the repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) and [creating a pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/proposing-changes-to-your-work-with-pull-requests) for non-trivial changes, it is usually best to first open an issue to discuss the changes, or discuss your intended approach for solving the problem in the comments for an existing issue. 49 | 50 | *Note: All contributions will be licensed under the project's license.* 51 | 52 | - **Smaller is better.** Submit **one** pull request per bug fix or feature. A pull request should contain isolated changes pertaining to a single bug fix or feature implementation. **Do not** refactor or reformat code that is unrelated to your change. It is better to **submit many small pull requests** rather than a single large one. Enormous pull requests will take enormous amounts of time to review, or may be rejected altogether. 53 | 54 | - **Coordinate bigger changes.** For large and non-trivial changes, open an issue to discuss a strategy with the maintainers. Otherwise, you risk doing a lot of work for nothing! 55 | 56 | - **Prioritize understanding over cleverness.** Write code clearly and concisely. Remember that source code usually gets written once and read often. Ensure the code is clear to the reader. The purpose and logic should be obvious to a reasonably skilled developer, otherwise you should add a comment that explains it. 57 | 58 | - **Follow existing coding style and conventions.** Keep your code consistent with the style, formatting, and conventions in the rest of the code base. 59 | 60 | - **Update the CHANGELOG** for all enhancements and bug fixes. Include the corresponding issue number if one exists, and your GitHub username. (example: "- Fixed crash in profile view. #123 @jessesquires") 61 | 62 | - **Use the repo's default branch.** Branch from and [submit your pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) to the repo's default branch. 63 | 64 | - **[Resolve any merge conflicts](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github)** that occur. 65 | 66 | - **Promptly address any CI failures**. If your pull request fails to build or pass tests, please push another commit to fix it. 67 | 68 | - When writing comments, use properly constructed sentences, including punctuation. 69 | 70 | ## Writing Commit Messages 71 | 72 | Please write a great commit message. 73 | 74 | 1. Limit the subject line to 50 characters 75 | 1. Capitalize the subject line 76 | 1. Do not end the subject line with a period 77 | 1. Use the imperative mood in the subject line (example: "Fix networking issue") 78 | 1. Use the body to explain **why**, *not what and how* (the code shows that!) 79 | 80 | ## Code Review 81 | 82 | - **Review the code, not the author.** Look for and suggest improvements without disparaging or insulting the author. Provide actionable feedback and explain your reasoning. 83 | 84 | - **You are not your code.** When your code is critiqued, questioned, or constructively criticized, remember that you are not your code. Do not take code review personally. 85 | 86 | - **Always do your best.** No one writes bugs on purpose. Do your best, and learn from your mistakes. 87 | 88 | - Kindly note any violations to the guidelines specified in this document. 89 | 90 | ## Coding Style 91 | 92 | Consistency is the most important. Following the existing style, formatting, and naming conventions of the file you are modifying and of the overall project. Failure to do so will result in a prolonged review process that has to focus on updating the superficial aspects of your code, rather than improving its functionality and performance. 93 | 94 | When possible, style and format will be enforced with a linter. 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
5 |
66 |