From c2fc57e3a14a110bfeeb68f9d0a488ea12e74ce5 Mon Sep 17 00:00:00 2001 From: Kelvin Jayanoris Date: Sat, 29 Jun 2019 13:15:38 +0300 Subject: [PATCH 1/8] Improve isort configs --- setup.cfg | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 1d03053..3744fe8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -2,4 +2,10 @@ default_section = THIRDPARTY known_first_party = small_small_hr known_django = django -sections = FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRST_PARTY,LOCALFOLDER +known_tests = tests +sections = FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRST_PARTY,TESTS,LOCALFOLDER +multi_line_output = 3 +include_trailing_comma = True +force_grid_wrap = 0 +use_parentheses = True +line_length = 88 From 3bfaf8f3a5e24364298f14be6fa6534aa32adc5d Mon Sep 17 00:00:00 2001 From: Kelvin Jayanoris Date: Sat, 29 Jun 2019 13:16:01 +0300 Subject: [PATCH 2/8] Add flake8 and pycodestyle configs --- setup.cfg | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/setup.cfg b/setup.cfg index 3744fe8..1551443 100644 --- a/setup.cfg +++ b/setup.cfg @@ -9,3 +9,9 @@ include_trailing_comma = True force_grid_wrap = 0 use_parentheses = True line_length = 88 + +[flake8] +max-line-length=90 + +[pycodestyle] +max-line-length=90 From 830255220030f43d0ff577d18db886f1628b5a8a Mon Sep 17 00:00:00 2001 From: Kelvin Jayanoris Date: Sat, 29 Jun 2019 13:17:25 +0300 Subject: [PATCH 3/8] Install pre-commit --- Pipfile | 1 + Pipfile.lock | 79 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/Pipfile b/Pipfile index dfbdc54..317bb09 100644 --- a/Pipfile +++ b/Pipfile @@ -21,3 +21,4 @@ tblib = "*" pylint-django = "*" isort = "*" "pep8" = "*" +pre-commit = "*" diff --git a/Pipfile.lock b/Pipfile.lock index b0c01b8..7f76354 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0354173d6ee77bd122a85597b73a7c45cf3406de5c599cd048a182ad7fdefc41" + "sha256": "e9ad4af4896c4b3cf8eec708441b0c3efc6fb471d09738b8387752d8a6838feb" }, "pipfile-spec": 6, "requires": { @@ -163,6 +163,13 @@ } }, "develop": { + "aspy.yaml": { + "hashes": [ + "sha256:463372c043f70160a9ec950c3f1e4c3a82db5fca01d334b6bc89c7164d744bdc", + "sha256:e7c742382eff2caed61f87a39d13f99109088e5e93f04d76eb8d4b28aa143f45" + ], + "version": "==1.3.0" + }, "astroid": { "hashes": [ "sha256:6560e1e1749f68c64a4b5dee4e091fce798d2f0d84ebe638cf0e0585a343acf4", @@ -177,6 +184,13 @@ ], "version": "==0.1.0" }, + "cfgv": { + "hashes": [ + "sha256:32edbe09de6f4521224b87822103a8c16a614d31a894735f7a5b3bcf0eb3c37e", + "sha256:3bd31385cd2bebddbba8012200aaf15aa208539f1b33973759b4d02fc2148da5" + ], + "version": "==2.0.0" + }, "coverage": { "hashes": [ "sha256:3684fabf6b87a369017756b551cef29e505cb155ddb892a7a29277b978da88b9", @@ -250,6 +264,13 @@ "index": "pypi", "version": "==3.7.7" }, + "identify": { + "hashes": [ + "sha256:0a11379b46d06529795442742a043dc2fa14cd8c995ae81d1febbc5f1c014c87", + "sha256:43a5d24ffdb07bc7e21faf68b08e9f526a1f41f0056073f480291539ef961dfd" + ], + "version": "==1.4.5" + }, "importlib-metadata": { "hashes": [ "sha256:6dfd58dfe281e8d240937776065dd3624ad5469c835248219bd16cf2e12dbeb7", @@ -257,6 +278,14 @@ ], "version": "==0.18" }, + "importlib-resources": { + "hashes": [ + "sha256:6e2783b2538bd5a14678284a3962b0660c715e5a0f10243fd5e00a4b5974f50b", + "sha256:d3279fd0f6f847cced9f7acc19bd3e5df54d34f93a2e7bb5f238f81545787078" + ], + "markers": "python_version < '3.7'", + "version": "==1.0.2" + }, "ipdb": { "hashes": [ "sha256:dce2112557edfe759742ca2d0fee35c59c97b0cc7a05398b791079d78f1519ce" @@ -266,10 +295,10 @@ }, "ipython": { "hashes": [ - "sha256:54c5a8aa1eadd269ac210b96923688ccf01ebb2d0f21c18c3c717909583579a8", - "sha256:e840810029224b56cd0d9e7719dc3b39cf84d577f8ac686547c8ba7a06eeab26" + "sha256:0806894ae78ddb94b530514acc9ab03a928b79374d8630470b439b58383dd7ee", + "sha256:263376e672c7f104fb971c9e1f372441bb34d66dfb7323062f62aa21fa46a377" ], - "version": "==7.5.0" + "version": "==7.6.0" }, "ipython-genutils": { "hashes": [ @@ -280,11 +309,11 @@ }, "isort": { "hashes": [ - "sha256:c40744b6bc5162bbb39c1257fe298b7a393861d50978b565f3ccd9cb9de0182a", - "sha256:f57abacd059dc3bd666258d1efb0377510a89777fda3e3274e3c01f7c03ae22d" + "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", + "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" ], "index": "pypi", - "version": "==4.3.20" + "version": "==4.3.21" }, "jedi": { "hashes": [ @@ -331,6 +360,12 @@ "index": "pypi", "version": "==1.6.0" }, + "nodeenv": { + "hashes": [ + "sha256:ad8259494cf1c9034539f6cced78a1da4840a4b157e23640bc4a0c0546b0cb7a" + ], + "version": "==1.3.3" + }, "packaging": { "hashes": [ "sha256:0c98a5d0be38ed775798ece1b9727178c4469d9c3b4ada66e8e6b7849f8732af", @@ -375,6 +410,14 @@ ], "version": "==0.12.0" }, + "pre-commit": { + "hashes": [ + "sha256:92e406d556190503630fd801958379861c94884693a032ba66629d0351fdccd4", + "sha256:cccc39051bc2457b0c0f7152a411f8e05e3ba2fe1a5613e4ee0833c1c1985ce3" + ], + "index": "pypi", + "version": "==1.17.0" + }, "prompt-toolkit": { "hashes": [ "sha256:11adf3389a996a6d45cc277580d0d53e8a5afd281d0c9ec71b28e6f121463780", @@ -454,6 +497,22 @@ ], "version": "==2019.1" }, + "pyyaml": { + "hashes": [ + "sha256:57acc1d8533cbe51f6662a55434f0dbecfa2b9eaf115bede8f6fd00115a0c0d3", + "sha256:588c94b3d16b76cfed8e0be54932e5729cc185caffaa5a451e7ad2f7ed8b4043", + "sha256:68c8dd247f29f9a0d09375c9c6b8fdc64b60810ebf07ba4cdd64ceee3a58c7b7", + "sha256:70d9818f1c9cd5c48bb87804f2efc8692f1023dac7f1a1a5c61d454043c1d265", + "sha256:86a93cccd50f8c125286e637328ff4eef108400dd7089b46a7be3445eecfa391", + "sha256:a0f329125a926876f647c9fa0ef32801587a12328b4a3c741270464e3e4fa778", + "sha256:a3c252ab0fa1bb0d5a3f6449a4826732f3eb6c0270925548cac342bc9b22c225", + "sha256:b4bb4d3f5e232425e25dda21c070ce05168a786ac9eda43768ab7f3ac2770955", + "sha256:cd0618c5ba5bda5f4039b9398bb7fb6a317bb8298218c3de25c47c4740e4b95e", + "sha256:ceacb9e5f8474dcf45b940578591c7f3d960e82f926c707788a570b51ba59190", + "sha256:fe6a88094b64132c4bb3b631412e90032e8cfe9745a58370462240b8cb7553cd" + ], + "version": "==5.1.1" + }, "six": { "hashes": [ "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", @@ -485,11 +544,11 @@ }, "tox": { "hashes": [ - "sha256:2316d3f56339173c6d45e600dabcfac6fbed7fff82a7d35f4107152e9191a766", - "sha256:66d9ccf81b383ab1edc1619410223eec0e046178304728797a850302092ed975" + "sha256:45a265e953368fb372cca3eac33b69fdb1b1453e5b114be231c84fc3dfadceed", + "sha256:f5cb0b5b8d14f2100982b0981c750d840228180a348e6bad355aa38e949fbc3f" ], "index": "pypi", - "version": "==3.13.0" + "version": "==3.13.1" }, "traitlets": { "hashes": [ From 9c6de3664de1e6902896fdc94c11f68f29307597 Mon Sep 17 00:00:00 2001 From: Kelvin Jayanoris Date: Sat, 29 Jun 2019 13:20:07 +0300 Subject: [PATCH 4/8] Add notes on contribution --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index c03c009..c7c668d 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,16 @@ Employees who are allowed overtime can log in and record overtime hours. This i Admins can download overtime hours reports for a particular period. +## Contribution + +All contributions are welcome. + +To set up the project: + +1. Clone this repo +2. `pipenv sync --dev` +3. `pre-commit install` + ## Testing ```sh From e7cfdadbcf18f1790286b896e6786c276231ffc5 Mon Sep 17 00:00:00 2001 From: Kelvin Jayanoris Date: Sat, 29 Jun 2019 13:20:27 +0300 Subject: [PATCH 5/8] Add pre-commit config --- .pre-commit-config.yaml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..9f6120e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,31 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.2.3 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: flake8 + + - repo: https://github.com/pre-commit/mirrors-isort + rev: v4.3.20 + hooks: + - id: isort + + - repo: https://github.com/python/black + rev: 19.3b0 + hooks: + - id: black + language_version: python3.6 + + - repo: local + hooks: + - id: pylint + name: PyLint + entry: python -m pylint.__main__ --load-plugins pylint_django --rcfile=.pylintrc + language: system + files: \.py$ + + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v0.701 + hooks: + - id: mypy From 809f8d85c97bc74c4d35f5c88e79dcefbcca9c41 Mon Sep 17 00:00:00 2001 From: Kelvin Jayanoris Date: Sat, 29 Jun 2019 13:33:35 +0300 Subject: [PATCH 6/8] Install mypy --- Pipfile | 1 + Pipfile.lock | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Pipfile b/Pipfile index 317bb09..c44eecb 100644 --- a/Pipfile +++ b/Pipfile @@ -22,3 +22,4 @@ pylint-django = "*" isort = "*" "pep8" = "*" pre-commit = "*" +mypy = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 7f76354..b882437 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "e9ad4af4896c4b3cf8eec708441b0c3efc6fb471d09738b8387752d8a6838feb" + "sha256": "9ad77237dad8d2e33349141a49bf2de9e790e1f46983045549662a20fbe7b82f" }, "pipfile-spec": 6, "requires": { @@ -360,6 +360,30 @@ "index": "pypi", "version": "==1.6.0" }, + "mypy": { + "hashes": [ + "sha256:12d18bd7fc642c5d54b1bb62dde813a7e2ab79b32ee11ff206ac387c68fc2ad4", + "sha256:23e24bc1683a36f39dee67d8ac74ea414654642eee26d420bada95b8ee8c9095", + "sha256:2b38e64c52a8968df4ebcae0ddba4a54eb94d184695dd4e54e14509a9389b78c", + "sha256:3d4f551466a76e278187ec3a5b26cfb50f72f6760b749aa00ac69a6f9c99898d", + "sha256:53d5dacb8d844e50be698830509aa592b093547e7ab90aee63eb23db61109007", + "sha256:56f981d246010ba21cac6b2455eaecfaf68fc8a5663d865b26c8e579c36f751d", + "sha256:8c57f6f59f1e8479d9fc6e1bf034353e54626ed64e32394c613afc493a441dc1", + "sha256:bbed4a593d87476b592d52867ef86da2155ccd0becf0c4c02e6567d842e43368", + "sha256:d6ff850e2ba18b2db7704897c8f2f1384478e3b75ad292ec06196bf7794f3a40", + "sha256:e13b1bb8785d7f785e0b88873f1c21cda58ceba9ce1153b58cbfa24b09a111d5", + "sha256:e2b9ee6f648ce72d6741925a47c88c2391168ef973b6f74f17969450c5b1ffdd" + ], + "index": "pypi", + "version": "==0.711" + }, + "mypy-extensions": { + "hashes": [ + "sha256:37e0e956f41369209a3d5f34580150bcacfabaa57b33a15c0b25f4b5725e0812", + "sha256:b16cabe759f55e3409a7d231ebd2841378fb0c27a5d1994719e340e4f429ac3e" + ], + "version": "==0.4.1" + }, "nodeenv": { "hashes": [ "sha256:ad8259494cf1c9034539f6cced78a1da4840a4b157e23640bc4a0c0546b0cb7a" From 5129bee05e92dbc72fa3bcddac7a6c38e6acd1a8 Mon Sep 17 00:00:00 2001 From: Kelvin Jayanoris Date: Sat, 29 Jun 2019 13:36:37 +0300 Subject: [PATCH 7/8] Add template_path param to send_email, also: - Fix pylint issues - Better type hinting --- small_small_hr/emails.py | 111 +++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 45 deletions(-) diff --git a/small_small_hr/emails.py b/small_small_hr/emails.py index ce5937c..b53ec32 100644 --- a/small_small_hr/emails.py +++ b/small_small_hr/emails.py @@ -7,10 +7,19 @@ from django.template.loader import render_to_string from django.utils.translation import ugettext as _ - -def send_email( # pylint: disable=too-many-arguments, too-many-locals - name: str, email: str, subject: str, message: str, obj: object = None, - cc_list: list = None, template: str = 'generic'): +from small_small_hr.models import Leave, OverTime + + +def send_email( # pylint: disable=too-many-arguments,too-many-locals,bad-continuation + name: str, + email: str, + subject: str, + message: str, + obj: object = None, + cc_list: list = None, + template: str = "generic", + template_path: str = "small_small_hr/email", +): """ Sends a generic email @@ -23,24 +32,25 @@ def send_email( # pylint: disable=too-many-arguments, too-many-locals :param template: the template to use """ context = { - 'name': name, - 'subject': subject, - 'message': message, - 'object': obj, - 'SITE': Site.objects.get_current() + "name": name, + "subject": subject, + "message": message, + "object": obj, + "SITE": Site.objects.get_current(), } email_subject = render_to_string( - f'small_small_hr/email/{template}_email_subject.txt', - context).replace('\n', '') + f"{template_path}/{template}_email_subject.txt", context + ).replace("\n", "") email_txt_body = render_to_string( - f'small_small_hr/email/{template}_email_body.txt', context) + f"{template_path}/{template}_email_body.txt", context + ) email_html_body = render_to_string( - f'small_small_hr/email/{template}_email_body.html', context - ).replace('\n', '') + f"{template_path}/{template}_email_body.html", context + ).replace("\n", "") subject = email_subject from_email = settings.DEFAULT_FROM_EMAIL - to_email = f'{name} <{email}>' + to_email = f"{name} <{email}>" text_content = email_txt_body html_content = email_html_body msg = EmailMultiAlternatives(subject, text_content, from_email, [to_email]) @@ -51,19 +61,18 @@ def send_email( # pylint: disable=too-many-arguments, too-many-locals return msg.send(fail_silently=True) -def leave_application_email(leave_obj: object): +def leave_application_email(leave_obj: Leave): """ Sends an email to admins when a leave application is made """ msg = getattr( settings, - 'SSHR_LEAVE_APPLICATION_EMAIL_TXT', - _("There has been a new leave application. Please log in to process " - "it.")) + "SSHR_LEAVE_APPLICATION_EMAIL_TXT", + _("There has been a new leave application. Please log in to process " "it."), + ) subj = getattr( - settings, - 'SSHR_LEAVE_APPLICATION_EMAIL_SUBJ', - _("New Leave Application")) + settings, "SSHR_LEAVE_APPLICATION_EMAIL_SUBJ", _("New Leave Application") + ) admin_emails = settings.SSHR_ADMIN_LEAVE_EMAILS for admin_email in admin_emails: @@ -73,23 +82,28 @@ def leave_application_email(leave_obj: object): subject=subj, message=msg, obj=leave_obj, - template='leave_application' + template="leave_application", ) -def leave_processed_email(leave_obj: object): +def leave_processed_email(leave_obj: Leave): """ Sends an email to admins when a leave application is processed """ if leave_obj.staff.user.email: msg = getattr( - settings, 'SSHR_LEAVE_PROCESSED_EMAIL_TXT', - _(f"You leave application status is " - f"{leave_obj.get_status_display()}. Log in for more info.") + settings, + "SSHR_LEAVE_PROCESSED_EMAIL_TXT", + _( + f"You leave application status is " + f"{leave_obj.get_status_display()}. Log in for more info." + ), ) subj = getattr( - settings, 'SSHR_LEAVE_PROCESSED_EMAIL_SUBJ', - _("Your leave application has been processed")) + settings, + "SSHR_LEAVE_PROCESSED_EMAIL_SUBJ", + _("Your leave application has been processed"), + ) send_email( name=leave_obj.staff.get_name(), @@ -97,23 +111,25 @@ def leave_processed_email(leave_obj: object): subject=subj, message=msg, obj=leave_obj, - cc_list=settings.SSHR_ADMIN_LEAVE_EMAILS + cc_list=settings.SSHR_ADMIN_LEAVE_EMAILS, ) -def overtime_application_email(overtime_obj: object): +def overtime_application_email(overtime_obj: OverTime): """ Sends an email to admins when an overtime application is made """ msg = getattr( settings, - 'SSHR_OVERTIME_APPLICATION_EMAIL_TXT', - _("There has been a new overtime application. Please log in to " - "process it.")) + "SSHR_OVERTIME_APPLICATION_EMAIL_TXT", + _( + "There has been a new overtime application. Please log in to " + "process it." + ), + ) subj = getattr( - settings, - 'SSHR_OVERTIME_APPLICATION_EMAIL_SUBJ', - _("New Overtime Application")) + settings, "SSHR_OVERTIME_APPLICATION_EMAIL_SUBJ", _("New Overtime Application") + ) admin_emails = settings.SSHR_ADMIN_OVERTIME_EMAILS for admin_email in admin_emails: @@ -123,24 +139,29 @@ def overtime_application_email(overtime_obj: object): subject=subj, message=msg, obj=overtime_obj, - template='overtime_application' + template="overtime_application", ) -def overtime_processed_email(overtime_obj: object): +def overtime_processed_email(overtime_obj: OverTime): """ Sends an email to admins when an overtime application is processed """ if overtime_obj.staff.user.email: msg = getattr( - settings, 'SSHR_OVERTIME_PROCESSED_EMAIL_TXT', - _(f"You overtime application status is " - f"{overtime_obj.get_status_display()}. Log in for more info.") + settings, + "SSHR_OVERTIME_PROCESSED_EMAIL_TXT", + _( + f"You overtime application status is " + f"{overtime_obj.get_status_display()}. Log in for more info." + ), ) subj = getattr( - settings, 'SSHR_OVERTIME_PROCESSED_EMAIL_SUBJ', - _("Your overtime application has been processed")) + settings, + "SSHR_OVERTIME_PROCESSED_EMAIL_SUBJ", + _("Your overtime application has been processed"), + ) send_email( name=overtime_obj.staff.get_name(), @@ -148,5 +169,5 @@ def overtime_processed_email(overtime_obj: object): subject=subj, message=msg, obj=overtime_obj, - cc_list=settings.SSHR_ADMIN_OVERTIME_EMAILS + cc_list=settings.SSHR_ADMIN_OVERTIME_EMAILS, ) From 061603422c8852e3d4b3b108cf4540b990bc748e Mon Sep 17 00:00:00 2001 From: Kelvin Jayanoris Date: Sat, 29 Jun 2019 13:39:02 +0300 Subject: [PATCH 8/8] =?UTF-8?q?=E2=86=91=20bump=20to=20version=200.1.8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- small_small_hr/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/small_small_hr/__init__.py b/small_small_hr/__init__.py index c87b37f..3e7bd9f 100644 --- a/small_small_hr/__init__.py +++ b/small_small_hr/__init__.py @@ -1,7 +1,7 @@ """ Main init file for small_small_hr """ -VERSION = (0, 1, 7) -__version__ = '.'.join(str(v) for v in VERSION) +VERSION = (0, 1, 8) +__version__ = ".".join(str(v) for v in VERSION) # pylint: disable=invalid-name -default_app_config = 'small_small_hr.apps.SmallSmallHrConfig' # noqa +default_app_config = "small_small_hr.apps.SmallSmallHrConfig" # noqa