From 97e6c49201320d3c114176fdc4142f6cd542ce26 Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Sun, 10 Jul 2022 19:52:15 +0100 Subject: [PATCH] Initial --- tests/test_main.py => app/__init__.py | 0 app/app.py | 21 ++++++++ app/main.py | 5 +- app/send_page.py | 31 +++++++++++ app/static/msg.png | Bin 0 -> 30753 bytes app/templates/index.html | 71 ++++++++++++++++++++++++++ requirements.txt | 11 ++++ sonar-project.properties | 5 +- tests/__init__.py | 11 ++++ tests/test_app.py | 10 ++++ tests/test_send_page.py | 12 +++++ 11 files changed, 174 insertions(+), 3 deletions(-) rename tests/test_main.py => app/__init__.py (100%) create mode 100644 app/app.py create mode 100644 app/send_page.py create mode 100644 app/static/msg.png create mode 100644 app/templates/index.html create mode 100644 tests/__init__.py create mode 100644 tests/test_app.py create mode 100644 tests/test_send_page.py diff --git a/tests/test_main.py b/app/__init__.py similarity index 100% rename from tests/test_main.py rename to app/__init__.py diff --git a/app/app.py b/app/app.py new file mode 100644 index 0000000..b34e9e5 --- /dev/null +++ b/app/app.py @@ -0,0 +1,21 @@ +#!/usr/local/bin/python3 + +from flask import Flask, render_template, request +from app.send_page import send_page + + +app = Flask(__name__) + +@app.route("/", methods=['GET']) +def index(): + return render_template('index.html', status='') + +@app.route("/", methods=['POST']) +def send(): + result = send_page( + name=request.form.get('name'), + email=request.form.get('email'), + message=request.form.get('message') + ) + status = 'success' if result[0] else 'fail' + return render_template('index.html', status=status) diff --git a/app/main.py b/app/main.py index a6053f8..3596682 100644 --- a/app/main.py +++ b/app/main.py @@ -1,7 +1,10 @@ #!/usr/local/bin/python3 +from app.app import app + + def main(): - # Commands here + app.run() if __name__ == "__main__": diff --git a/app/send_page.py b/app/send_page.py new file mode 100644 index 0000000..2d6beaf --- /dev/null +++ b/app/send_page.py @@ -0,0 +1,31 @@ +#!/usr/local/bin/python3 + +import os +import requests + + +def send_page(name: str, email: str, message: str) -> tuple: + api_url = "https://api.pushover.net/1/messages.json" + api_token = os.getenv('PUSHOVER_API_TOKEN') + user_key = os.getenv('PUSHOVER_USER_KEY') + + full_msg = f"Name: {name}\nEmail: {email}\n\nMessage: {message}" + + payload = { + 'token': api_token, + 'user': user_key, + 'title': f"ePage from {name}", + 'message': full_msg, + 'priority': "1", + 'sound': 'cosmic' + } + + req = requests.post( + api_url, + json=payload, + headers={'Content-Type': 'application/json'} + ) + + if req.status_code == 200 and req.json().get('status') == 1: + return (True, None) + return (False, req.json()) diff --git a/app/static/msg.png b/app/static/msg.png new file mode 100644 index 0000000000000000000000000000000000000000..c39147f36f9ae32e35d847c1a67a046a10bd8962 GIT binary patch literal 30753 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 literal 0 HcmV?d00001 diff --git a/app/templates/index.html b/app/templates/index.html new file mode 100644 index 0000000..90057e6 --- /dev/null +++ b/app/templates/index.html @@ -0,0 +1,71 @@ + + + + + + + + ePage + + + + + + + + + + + + + + {% if status == 'success' %} + + {% elif status == 'fail' %} + + {% endif %} + + +
+
+ + +
+ Please enter your name. +
+
+
+
+ + +
+ Please enter your email address. +
+
+
+
+ + +
+ Please enter your message. +
+
+
+ +
+ + + + diff --git a/requirements.txt b/requirements.txt index e69de29..f84c801 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,11 @@ +certifi==2022.6.15 +charset-normalizer==2.1.0 +click==8.1.3 +Flask==2.1.2 +idna==3.3 +itsdangerous==2.1.2 +Jinja2==3.1.2 +MarkupSafe==2.1.1 +requests==2.28.1 +urllib3==1.26.10 +Werkzeug==2.1.2 diff --git a/sonar-project.properties b/sonar-project.properties index 286b4f0..217bc47 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,8 +1,9 @@ -sonar.projectKey=luketainton_ +sonar.projectKey=luketainton_epage_AYHpcqLKSbMjdyWLhHix sonar.python.version=3.10 sonar.python.coverage.reportPaths=coverage.xml sonar.python.pylint.reportPaths=lintreport.txt sonar.python.xunit.reportPath=testresults.xml sonar.sources=app sonar.tests=tests -sonar.exclusions=,.github/**,.gitignore,CODEOWNERS,CHANGELOG.md,LICENSE.md,README.md,renovate.json,requirements-dev.txt,requirements.txt \ No newline at end of file +sonar.exclusions=.github/**,.gitignore,CODEOWNERS,CHANGELOG.md,LICENSE.md,README.md,renovate.json,requirements-dev.txt,requirements.txt +sonar.coverage.exclusions=app/main.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..7daa129 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 + +import pytest + +from app.app import app + + +@pytest.fixture +def client(): + client = app.test_client() + yield client diff --git a/tests/test_app.py b/tests/test_app.py new file mode 100644 index 0000000..62c0155 --- /dev/null +++ b/tests/test_app.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 + +import pytest + +from tests import client + + +def test_index(client) -> None: + req = client.get('/') + assert req.status_code == 200 and "ePage" in req.text diff --git a/tests/test_send_page.py b/tests/test_send_page.py new file mode 100644 index 0000000..c34b17b --- /dev/null +++ b/tests/test_send_page.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 + +from app.send_page import send_page + + +def test_send_page_no_env() -> None: + result = send_page( + name='Unit Test', + email='none@none.com', + message='Unit Test' + ) + assert result[0] == False and result[1].get('token') == 'invalid'