diff --git a/.gitignore b/.gitignore index 83c08fba63f2be651b4dbee75798abfe6c694147..f8b7c8fff694053401fdc44ac33cda425cd5e353 100644 --- a/.gitignore +++ b/.gitignore @@ -27,9 +27,9 @@ out smash/smash.log smash/smash/smash.log - +#coverage info .coverage smash/htmlcov/ -run-coverage.bat +run-coverage.sh media diff --git a/requirements.txt b/requirements.txt index d974c761791eccf6fc3aa8daf93c13a73fe9128d..566c95d432192607aea1152756c2624615cbaad3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,4 +14,4 @@ pyexcel-xls==0.5.0 pyexcel==0.5.3 pycurl==7.43.0 django-stronghold==0.2.9 - +timeout-decorator==0.4.0 diff --git a/smash/web/forms/study_subject_forms.py b/smash/web/forms/study_subject_forms.py index 7101e6bbeec368de1979c6f901b033b9f96cd8b4..44afb25786f47a3d43e6a7f56a9ea1387ccbdab6 100644 --- a/smash/web/forms/study_subject_forms.py +++ b/smash/web/forms/study_subject_forms.py @@ -19,7 +19,7 @@ class StudySubjectForm(ModelForm): required=False ) - referral_letter = forms.FileField(label='Select a file', widget=SecuredFileWidget(), required=False) + referral_letter = forms.FileField(label='Referral letter', widget=SecuredFileWidget(), required=False) voucher_types = forms.ModelMultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple, diff --git a/smash/web/models/constants.py b/smash/web/models/constants.py index 865f10ccf3c1c1e17f102a0cdca273c34cdc1014..ad7354a0bda27a3c369369e0425657fa6499e708 100644 --- a/smash/web/models/constants.py +++ b/smash/web/models/constants.py @@ -81,6 +81,9 @@ WEEKDAY_CHOICES = ( REDCAP_TOKEN_CONFIGURATION_TYPE = "REDCAP_TOKEN_CONFIGURATION_TYPE" REDCAP_BASE_URL_CONFIGURATION_TYPE = "REDCAP_BASE_URL_CONFIGURATION_TYPE" +# timeout job after 15 minutes +CRON_JOB_TIMEOUT = 15 * 60 + COUNTRY_OTHER_ID = 1 COUNTRY_AFGHANISTAN_ID = 2 diff --git a/smash/web/redcap_connector.py b/smash/web/redcap_connector.py index 9055a1f2ee06ae0c5452a3378b9ea4bb0e25edea..7d448fc63de628c8e6ff6b870f9ac2e84afd59ea 100644 --- a/smash/web/redcap_connector.py +++ b/smash/web/redcap_connector.py @@ -5,11 +5,12 @@ import logging import pycurl import certifi +import timeout_decorator from django_cron import CronJobBase, Schedule from web.models import ConfigurationItem, StudySubject, Language from web.models.constants import REDCAP_TOKEN_CONFIGURATION_TYPE, \ - REDCAP_BASE_URL_CONFIGURATION_TYPE + REDCAP_BASE_URL_CONFIGURATION_TYPE, CRON_JOB_TIMEOUT from web.models.inconsistent_subject import InconsistentField, InconsistentSubject from web.models.missing_subject import MissingSubject @@ -322,6 +323,7 @@ class RedCapRefreshJob(CronJobBase): schedule = Schedule(run_every_mins=RUN_EVERY_MINUTES) code = 'web.red_cap_hourly_refresh' # a unique code + @timeout_decorator.timeout(CRON_JOB_TIMEOUT) def do(self): connector = RedcapConnector() if connector.is_valid(): diff --git a/smash/web/smash_email.py b/smash/web/smash_email.py index 882c39b4b732561dc34d779ba487d2f5913d66ef..32f3bb5e79b6915d235e25b8bff40dddcafa23fb 100644 --- a/smash/web/smash_email.py +++ b/smash/web/smash_email.py @@ -3,6 +3,7 @@ import logging from django.conf import settings +from django.core import mail from django.core.mail import EmailMessage logger = logging.getLogger(__name__) @@ -26,5 +27,7 @@ class EmailSender(object): cc=cc_recipients ) message.content_subtype = "html" + print "mails sent: " + str(len(mail.outbox)) message.send() + print "mails sent: " + str(len(mail.outbox)) logger.info('Email sent. Subject: ' + subject + "; Recipients: " + recipients) diff --git a/smash/web/tests/view/test_KitRequestEmailSendJob.py b/smash/web/tests/view/test_KitRequestEmailSendJob.py index f6e58798c859a092c2481fb824cab461a3fb7d08..9959087201c359cb02141f5dedf0f390449e27e9 100644 --- a/smash/web/tests/view/test_KitRequestEmailSendJob.py +++ b/smash/web/tests/view/test_KitRequestEmailSendJob.py @@ -37,5 +37,6 @@ class KitRequestEmailSendJobTests(LoggedInTestCase): status = job.do() self.assertEqual("mail sent", status) + print len(mail.outbox) self.assertEqual(1, len(mail.outbox)) self.assertEqual(workers_count, Worker.objects.all().count()) diff --git a/smash/web/views/kit.py b/smash/web/views/kit.py index 7c8875662f27ed77399d44984546684d94da1127..6448b09851f0412154b567ce5b077241b7448cd2 100644 --- a/smash/web/views/kit.py +++ b/smash/web/views/kit.py @@ -6,6 +6,7 @@ import platform import time import pytz +import timeout_decorator from django.contrib import messages from django.utils.dateparse import parse_datetime from django_cron import CronJobBase, Schedule @@ -14,7 +15,7 @@ from django_cron.models import CronJobLog from notifications import get_filter_locations, get_today_midnight_date from web.models import ConfigurationItem, Language, Worker from web.models.constants import KIT_EMAIL_HOUR_CONFIGURATION_TYPE, \ - KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_TYPE + KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_TYPE, CRON_JOB_TIMEOUT from web.models.constants import KIT_RECIPIENT_EMAIL_CONFIGURATION_TYPE from . import wrap_response from ..forms import KitRequestForm @@ -140,6 +141,7 @@ class KitRequestEmailSendJob(CronJobBase): schedule = Schedule(run_every_mins=RUN_EVERY_MINUTES) code = 'web.kit_request_weekly_email' # a unique code + @timeout_decorator.timeout(CRON_JOB_TIMEOUT) def do(self): now = datetime.datetime.utcnow() hour = int(ConfigurationItem.objects.get( diff --git a/smash/web/views/voucher.py b/smash/web/views/voucher.py index 3124cc302b93ea9e7329ee427a2e27e5394a7184..5323427791e0d480e0c4b485327d0d103e0d966d 100644 --- a/smash/web/views/voucher.py +++ b/smash/web/views/voucher.py @@ -1,6 +1,7 @@ # coding=utf-8 import logging +import timeout_decorator from django.contrib.messages.views import SuccessMessageMixin from django.urls import reverse_lazy from django.views.generic import CreateView @@ -11,7 +12,7 @@ from django_cron import CronJobBase, Schedule from web.views.notifications import get_today_midnight_date from web.forms import VoucherForm from web.models import Voucher, StudySubject, MailTemplate -from web.models.constants import GLOBAL_STUDY_ID, VOUCHER_STATUS_NEW, VOUCHER_STATUS_EXPIRED +from web.models.constants import GLOBAL_STUDY_ID, VOUCHER_STATUS_NEW, VOUCHER_STATUS_EXPIRED, CRON_JOB_TIMEOUT from . import WrappedView logger = logging.getLogger(__name__) @@ -80,6 +81,7 @@ class ExpireVouchersJob(CronJobBase): code = 'web.voucher_expiry_job' # a unique code # noinspection PyMethodMayBeStatic + @timeout_decorator.timeout(CRON_JOB_TIMEOUT) def do(self): due_date = get_today_midnight_date() vouchers = Voucher.objects.filter(status=VOUCHER_STATUS_NEW, expiry_date__lte=due_date)