From bee58051fa4f786a6bf6473b88ca191c5b2c58f4 Mon Sep 17 00:00:00 2001 From: Irwan Fathurrahman Date: Thu, 24 Oct 2024 13:49:32 +0700 Subject: [PATCH] Add models and fixtures --- deployment/docker-compose.yml | 1 + deployment/docker/requirements.txt | 3 + deployment/docker/uwsgi.conf | 3 +- django_project/_version.txt | 2 +- .../{gap => core}/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../management/commands/load_fixtures.py | 19 +- django_project/core/settings/base.py | 8 + django_project/core/settings/project.py | 7 +- django_project/gap/fixtures/10.pest.json | 18 + django_project/message/__init__.py | 0 django_project/message/admin.py | 32 ++ django_project/message/apps.py | 25 ++ .../message/fixtures/1.messages.json | 377 ++++++++++++++++++ .../message/migrations/0001_initial.py | 32 ++ django_project/message/migrations/__init__.py | 0 django_project/message/models.py | 68 ++++ django_project/message/translation.py | 17 + django_project/prise/__init__.py | 0 django_project/prise/admin.py | 22 + django_project/prise/apps.py | 27 ++ django_project/prise/fixtures/1.messages.json | 45 +++ .../prise/migrations/0001_initial.py | 25 ++ django_project/prise/migrations/__init__.py | 0 django_project/prise/models.py | 26 ++ django_project/prise/variables.py | 15 + 26 files changed, 759 insertions(+), 13 deletions(-) rename django_project/{gap => core}/management/__init__.py (100%) rename django_project/{gap => core}/management/commands/__init__.py (100%) rename django_project/{gap => core}/management/commands/load_fixtures.py (53%) create mode 100755 django_project/gap/fixtures/10.pest.json create mode 100644 django_project/message/__init__.py create mode 100644 django_project/message/admin.py create mode 100644 django_project/message/apps.py create mode 100755 django_project/message/fixtures/1.messages.json create mode 100644 django_project/message/migrations/0001_initial.py create mode 100644 django_project/message/migrations/__init__.py create mode 100644 django_project/message/models.py create mode 100644 django_project/message/translation.py create mode 100644 django_project/prise/__init__.py create mode 100644 django_project/prise/admin.py create mode 100644 django_project/prise/apps.py create mode 100755 django_project/prise/fixtures/1.messages.json create mode 100644 django_project/prise/migrations/0001_initial.py create mode 100644 django_project/prise/migrations/__init__.py create mode 100644 django_project/prise/models.py create mode 100644 django_project/prise/variables.py diff --git a/deployment/docker-compose.yml b/deployment/docker-compose.yml index 1df57130..5406e188 100644 --- a/deployment/docker-compose.yml +++ b/deployment/docker-compose.yml @@ -76,6 +76,7 @@ services: - django plumber: + image: kartoza/${COMPOSE_PROJECT_NAME:-django_project}_plumber build: context: ../ dockerfile: deployment/plumber/Dockerfile diff --git a/deployment/docker/requirements.txt b/deployment/docker/requirements.txt index 378c97ac..d4224c85 100644 --- a/deployment/docker/requirements.txt +++ b/deployment/docker/requirements.txt @@ -33,6 +33,9 @@ django-cleanup==7.0.0 # Celery result backends for Django. django-celery-results==2.5.0 +# Translation for model field +django-modeltranslation==0.19.10 + # psycopg2 - Python-PostgreSQL Database Adapter # psycopg2-binary==2.9.3 diff --git a/deployment/docker/uwsgi.conf b/deployment/docker/uwsgi.conf index 3ab78073..68541f80 100644 --- a/deployment/docker/uwsgi.conf +++ b/deployment/docker/uwsgi.conf @@ -17,4 +17,5 @@ env = DJANGO_SETTINGS_MODULE=core.settings.prod #uid = 1000 #gid = 1000 memory-report = true -harakiri = 120 \ No newline at end of file +harakiri = 120 + diff --git a/django_project/_version.txt b/django_project/_version.txt index 5c4511c3..7d6b3eb3 100644 --- a/django_project/_version.txt +++ b/django_project/_version.txt @@ -1 +1 @@ -0.0.7 \ No newline at end of file +0.0.8 \ No newline at end of file diff --git a/django_project/gap/management/__init__.py b/django_project/core/management/__init__.py similarity index 100% rename from django_project/gap/management/__init__.py rename to django_project/core/management/__init__.py diff --git a/django_project/gap/management/commands/__init__.py b/django_project/core/management/commands/__init__.py similarity index 100% rename from django_project/gap/management/commands/__init__.py rename to django_project/core/management/commands/__init__.py diff --git a/django_project/gap/management/commands/load_fixtures.py b/django_project/core/management/commands/load_fixtures.py similarity index 53% rename from django_project/gap/management/commands/load_fixtures.py rename to django_project/core/management/commands/load_fixtures.py index 0e350ff0..8561bd30 100644 --- a/django_project/gap/management/commands/load_fixtures.py +++ b/django_project/core/management/commands/load_fixtures.py @@ -8,6 +8,7 @@ import logging import os +from django.conf import settings from django.core.management import call_command from django.core.management.base import BaseCommand @@ -20,18 +21,18 @@ class Command(BaseCommand): """Command to load fixtures.""" help = 'Load all fixtures' - apps = ['gap', 'spw'] def handle(self, *args, **options): """Handle load fixtures.""" - for app in self.apps: + for app in settings.PROJECT_APPS: folder = os.path.join( DJANGO_ROOT, app, 'fixtures' ) - for subdir, dirs, files in os.walk(folder): - files.sort() - for file in files: - if file.endswith('.json'): - logger.info(f"Loading {file}") - print(f"Loading {file}") - call_command('loaddata', file) + if os.path.exists(folder): + for subdir, dirs, files in os.walk(folder): + files.sort() + for file in files: + if file.endswith('.json'): + logger.info(f"Loading {file}") + print(f"Loading {app}/{file}") + call_command('loaddata', file) diff --git a/django_project/core/settings/base.py b/django_project/core/settings/base.py index fd843149..2e15e3a7 100644 --- a/django_project/core/settings/base.py +++ b/django_project/core/settings/base.py @@ -3,6 +3,8 @@ import os +from django.conf.global_settings import gettext_noop + from .utils import absolute_path, ensure_secret_key_file ensure_secret_key_file() @@ -122,6 +124,7 @@ ) INSTALLED_APPS = ( + 'modeltranslation', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -152,3 +155,8 @@ LOGIN_URL = '/account/login/' LOGIN_REDIRECT_URL = '/' + +LANGUAGES = ( + ("en", gettext_noop("English")), + ("sw", gettext_noop("Swahili")), +) diff --git a/django_project/core/settings/project.py b/django_project/core/settings/project.py index 9f9e7f86..b50ff905 100644 --- a/django_project/core/settings/project.py +++ b/django_project/core/settings/project.py @@ -29,13 +29,16 @@ DEBUG = TEMPLATE_DEBUG = False # Extra installed apps -INSTALLED_APPS = INSTALLED_APPS + ( +PROJECT_APPS = ( 'core', 'frontend', 'gap', 'gap_api', - 'spw' + 'spw', + 'prise', + 'message', ) +INSTALLED_APPS = INSTALLED_APPS + PROJECT_APPS TEMPLATES[0]['DIRS'] += [ absolute_path('frontend', 'templates'), diff --git a/django_project/gap/fixtures/10.pest.json b/django_project/gap/fixtures/10.pest.json new file mode 100755 index 00000000..0782cd8d --- /dev/null +++ b/django_project/gap/fixtures/10.pest.json @@ -0,0 +1,18 @@ +[ + { + "model": "gap.pest", + "pk": 1, + "fields": { + "name": "Beanfly", + "description": "Beanfly (On bean)" + } + }, + { + "model": "gap.pest", + "pk": 2, + "fields": { + "name": "Fall Armyworm", + "description": "Fall Armyworm (on maize and other hosts)" + } + } +] \ No newline at end of file diff --git a/django_project/message/__init__.py b/django_project/message/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/django_project/message/admin.py b/django_project/message/admin.py new file mode 100644 index 00000000..3b45f147 --- /dev/null +++ b/django_project/message/admin.py @@ -0,0 +1,32 @@ +# coding=utf-8 +""" +Tomorrow Now GAP. + +.. note:: Message admins +""" + +from django.contrib import admin +from modeltranslation.admin import TranslationAdmin + +from message.models import MessageTemplate + + +@admin.register(MessageTemplate) +class MessageTemplateAdmin(TranslationAdmin): + """Admin page for MessageTemplate.""" + + list_display = ('code', 'application', 'group', 'template') + filter = ('application', 'group') + + class Media: # noqa + js = ( + 'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js', + ( + 'http://ajax.googleapis.com/' + 'ajax/libs/jqueryui/1.10.2/jquery-ui.min.js' + ), + 'modeltranslation/js/tabbed_translation_fields.js', + ) + css = { + 'screen': ('modeltranslation/css/tabbed_translation_fields.css',), + } diff --git a/django_project/message/apps.py b/django_project/message/apps.py new file mode 100644 index 00000000..32f29504 --- /dev/null +++ b/django_project/message/apps.py @@ -0,0 +1,25 @@ +# coding=utf-8 +""" +Tomorrow Now GAP. + +.. note:: Message Config + + A comprehensive framework of messages, + categorized by group and application, + designed to be utilized in a scheduled system for distribution to other + users, sms, or appending to some API or files. +""" + +from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ + + +class MessageConfig(AppConfig): + """App Config for Message.""" + + name = 'message' + verbose_name = _('message') + + def ready(self): + """App ready handler.""" + pass diff --git a/django_project/message/fixtures/1.messages.json b/django_project/message/fixtures/1.messages.json new file mode 100755 index 00000000..cbe457de --- /dev/null +++ b/django_project/message/fixtures/1.messages.json @@ -0,0 +1,377 @@ +[ + { + "model": "message.messagetemplate", + "pk": 1, + "fields": { + "code": "beanfly_1", + "name": "feedback", + "type": "Feedback", + "application": "PRISE", + "group": "Start of Season", + "note": "", + "template": "Welcome to MoA-INFO bean service. Have you seen bean fly on your beans in the past week?\r\nA. Yes\r\nB. No\r\nC. I haven't checked", + "template_en": "Welcome to MoA-INFO bean service. Have you seen bean fly on your beans in the past week?\r\nA. Yes\r\nB. No\r\nC. I haven't checked", + "template_sw": "Karibu kwa huduma ya maharagwe ya MoA-INFO. Je, umemwona nzi wa maharagwe (bean fly) kwa maharagwe yako wiki iliyopita?\r\nA. Ndio\r\nB. La\r\nC. Sijaangalia" + } + }, + { + "model": "message.messagetemplate", + "pk": 2, + "fields": { + "code": "beanfly_2", + "name": "identify", + "type": "Introduction /Advice /Action", + "application": "PRISE", + "group": "Start of Season", + "note": "", + "template": "Bean flies are small black flies. They are 2 mm long and commonly found feeding on leaves and stems. Reply A for more", + "template_en": "Bean flies are small black flies. They are 2 mm long and commonly found feeding on leaves and stems. Reply A for more", + "template_sw": "Nzi wa maharagwe ni wadogo na weusi. Wana urefu wa milimita mbili na hupatikana kwa kawaida wakila majani na shina. Jibu A kujua zaidi" + } + }, + { + "model": "message.messagetemplate", + "pk": 3, + "fields": { + "code": "beanfly_3", + "name": "intro2", + "type": "Warning /Description", + "application": "PRISE", + "group": "Start of Season", + "note": "", + "template": "Bean flies may reach your shamba this season. We are using weather information to predict how bean flies are developing in your area. Reply A for more.", + "template_en": "Bean flies may reach your shamba this season. We are using weather information to predict how bean flies are developing in your area. Reply A for more.", + "template_sw": "Nzi wa maharagwe wanaweza kufikia shamba lako msimu huu. Tunatumia habari ya hali ya hewa kutabiri jinsi wanavyokua katika eneo lako. Jibu A kujua zaidi." + } + }, + { + "model": "message.messagetemplate", + "pk": 4, + "fields": { + "code": "beanfly_4", + "name": "intro3", + "type": "PRISE overview", + "application": "PRISE", + "group": "Start of Season", + "note": "", + "template": "We will send updates over the course of the season, including a message to let you know when is the best time to take action.", + "template_en": "We will send updates over the course of the season, including a message to let you know when is the best time to take action.", + "template_sw": "Tutatuma ushauri zaidi msimu unapoendelea, ikiwemo ujumbe wa kukujulisha wakati bora wa kuchukua hatua." + } + }, + { + "model": "message.messagetemplate", + "pk": 5, + "fields": { + "code": "beanfly_5", + "name": "feedback", + "type": "Feedback", + "application": "PRISE", + "group": "PRISE Time To Action 1 - Beginning of the month", + "note": "", + "template": "Welcome to MoA-INFO bean service. Have you seen bean fly on your beans in the past week?\r\nA. Yes\r\nB. No\r\nC. I haven't checked", + "template_en": "Welcome to MoA-INFO bean service. Have you seen bean fly on your beans in the past week?\r\nA. Yes\r\nB. No\r\nC. I haven't checked", + "template_sw": "Karibu kwa huduma ya maharagwe ya MoA-INFO. Je, umemwona nzi wa maharagwe (bean fly) kwa maharagwe yako wiki iliyopita?\r\nA. Ndio\r\nB. La\r\nC. Sijaangalia" + } + }, + { + "model": "message.messagetemplate", + "pk": 6, + "fields": { + "code": "beanfly_6", + "name": "monitor", + "type": "Introduction", + "application": "PRISE", + "group": "PRISE Time To Action 1 - Beginning of the month", + "note": "", + "template": "Randomly select bean crops per acre to monitor, if 5-10% shows signs of infestation then consider taking action. Reply A for more.", + "template_en": "Randomly select bean crops per acre to monitor, if 5-10% shows signs of infestation then consider taking action. Reply A for more.", + "template_sw": "Chagua bila mpangilio maalum mimea ya maharagwe kwa kila ekari na ichunguze, ikiwa 5-10% inaonyesha dalili za kuathirika fikiria kuchukua hatua. A kujua zaidi." + } + }, + { + "model": "message.messagetemplate", + "pk": 7, + "fields": { + "code": "beanfly_7", + "name": "control 1", + "type": "Context", + "application": "PRISE", + "group": "PRISE Time To Action 1 - Beginning of the month", + "note": "", + "template": "Use neem extract solution (50 ml neem per 15 litres of water and 3 tablespoons of liquid soap) as a spray during early mornings and late evenings.", + "template_en": "Use neem extract solution (50 ml neem per 15 litres of water and 3 tablespoons of liquid soap) as a spray during early mornings and late evenings.", + "template_sw": "Tumia dawa zilizo na mwarobaini (50 ml Mwarobaini kwa lita 15 za maji na vijiko 3 vya sabuni ya maji) nyunyizia wakati wa asubuhi na mapema jioni sana." + } + }, + { + "model": "message.messagetemplate", + "pk": 8, + "fields": { + "code": "beanfly_8", + "name": "bestdate", + "type": "Warning /Description", + "application": "PRISE", + "group": "PRISE Time To Action 1 - Beginning of the month", + "note": "", + "template": "If you planted beans in {{ last_month }} the best time to take action will be {{ day_1 }} to {{ day_2 }} days after planting. Until then use other methods to manage bean fly. A for more", + "template_en": "If you planted beans in {{ last_month }} the best time to take action will be {{ day_1 }} to {{ day_2 }} days after planting. Until then use other methods to manage bean fly. A for more", + "template_sw": "Ikiwa umepanda maharagwe {{ last_month }} ni bora kuchukua hatua siku {{ day_1 }} hadi {{ day_2 }} baada ya kupanda. Hadi wakati huo tumia mbinu zingine kudhibiti mdudu huyu. A kwa zaidi" + } + }, + { + "model": "message.messagetemplate", + "pk": 9, + "fields": { + "code": "beanfly_9", + "name": "bestdate", + "type": "Warning /Description", + "application": "PRISE", + "group": "PRISE Time To Action 1 - Beginning of the month", + "note": "", + "template": "If you planted beans in {{ month }} the best time to take action will be {{ day_1 }} to {{ day_2 }} days after planting. Until then you can use other methods to manage.", + "template_en": "If you planted beans in {{ month }} the best time to take action will be {{ day_1 }} to {{ day_2 }} days after planting. Until then you can use other methods to manage.", + "template_sw": "Ikiwa umepanda maharagwe {{ month }} ni bora wa kuchukua hatua siku {{ day_1 }} hadi {{ day_2 }} baada ya kupanda. Hadi wakati huo unaweza kutumia mbinu zingine." + } + }, + { + "model": "message.messagetemplate", + "pk": 10, + "fields": { + "code": "beanfly_10", + "name": "feedback", + "type": "Warning /Description /Feedback", + "application": "PRISE", + "group": "PRISE Time To Action 2 - Second half of the month", + "note": "", + "template": "It is time to prepare yourself for bean fly! Have you seen bean fly on your beans in the past week?\r\na) Yes\r\nb) No\r\nc) I haven't checked", + "template_en": "It is time to prepare yourself for bean fly! Have you seen bean fly on your beans in the past week?\r\na) Yes\r\nb) No\r\nc) I haven't checked", + "template_sw": "Ni wakati wa kujiandaa kwa nzi wa maharagwe! Je, umemwona nzi wa maharagwe kwenye maharagwe yako wiki iliyopita?\r\na) Ndio\r\nb) La\r\nc) Sijaangalia" + } + }, + { + "model": "message.messagetemplate", + "pk": 11, + "fields": { + "code": "beanfly_11", + "name": "advice1", + "type": "Warning /Description /Action /Advice1", + "application": "PRISE", + "group": "PRISE Time To Action 2 - Second half of the month", + "note": "", + "template": "Based on weather conditions in your area, we will predict the peak bean fly infestation in your area and the best time to take action. Reply A for more.", + "template_en": "Based on weather conditions in your area, we will predict the peak bean fly infestation in your area and the best time to take action. Reply A for more.", + "template_sw": "Kulingana na hali ya hewa katika eneo lako, tutatabiri uvamizi wa juu wa nzi wa maharagwe kwenye eneo lako na wakati bora wa kuchukua hatua. Jibu A kujua zaidi" + } + }, + { + "model": "message.messagetemplate", + "pk": 12, + "fields": { + "code": "beanfly_12", + "name": "bestdate", + "type": "Warning /Description", + "application": "PRISE", + "group": "PRISE Time To Action 2 - Second half of the month", + "note": "", + "template": "If you planted beans in {{ month }} the best time to take action will be {{ day_1 }} to {{ day_2 }} days after planting. Until then you can use other methods to manage.", + "template_en": "If you planted beans in {{ month }} the best time to take action will be {{ day_1 }} to {{ day_2 }} days after planting. Until then you can use other methods to manage.", + "template_sw": "Ikiwa umepanda maharagwe {{ month }} ni bora wa kuchukua hatua siku {{ day_1 }} hadi {{ day_2 }} baada ya kupanda. Hadi wakati huo unaweza kutumia mbinu zingine." + } + }, + { + "model": "message.messagetemplate", + "pk": 13, + "fields": { + "code": "fall_armyworm_1", + "name": "feedback", + "type": "Feedback", + "application": "PRISE", + "group": "Start of Season", + "note": "Feedback question - SMS response collected and data is passed back to the PRISE team", + "template": "Welcome to MoA-INFO Fall Armyworm (FAW) service. Have you seen new Fall Armyworm damage on your maize in the past week?\r\nA. Yes\r\nB. No\r\nC. I haven't checked", + "template_en": "Welcome to MoA-INFO Fall Armyworm (FAW) service. Have you seen new Fall Armyworm damage on your maize in the past week?\r\nA. Yes\r\nB. No\r\nC. I haven't checked", + "template_sw": "Karibu kwa huduma ya MoA-INFO ya Fall Armyworm (FAW). Je, umeona uharibifu mpya wa FAW kwa mahindi yako wiki iliyopita?\r\nA. Ndio \r\nB. La \r\nC. Sijaangalia" + } + }, + { + "model": "message.messagetemplate", + "pk": 14, + "fields": { + "code": "fall_armyworm_2", + "name": "intro1", + "type": "Introduction /Advice /Action", + "application": "PRISE", + "group": "Start of Season", + "note": "", + "template": "Did you know you can use other methods to manage Fall Armyworm before spraying with pesticides? Reply A for more from MoA-INFO.", + "template_en": "Did you know you can use other methods to manage Fall Armyworm before spraying with pesticides? Reply A for more from MoA-INFO.", + "template_sw": "Je, unajua kwamba unaweza kutumia mbinu kadhaa kudhibiti Fall Armyworm (FAW) kabla ya kunyunyiza dawa? Jibu A kwa ushauri zaidi kutoka MoA-INFO." + } + }, + { + "model": "message.messagetemplate", + "pk": 15, + "fields": { + "code": "fall_armyworm_3", + "name": "intro2", + "type": "Warning /Description", + "application": "PRISE", + "group": "Start of Season", + "note": "", + "template": "We use weather information to predict how FAW will develop in your area. We will send you updates on when spraying pesticides should be most effective", + "template_en": "We use weather information to predict how FAW will develop in your area. We will send you updates on when spraying pesticides should be most effective", + "template_sw": "Tunatumia ujumbe wa hali ya anga kutabiri jinsi FAW itakavyokua kwa eneo lako. Tutakutumia ujumbe wa kunyunyuzia dawa wakati unaofaa ili upate matokeo mema" + } + }, + { + "model": "message.messagetemplate", + "pk": 16, + "fields": { + "code": "fall_armyworm_4", + "name": "feedback", + "type": "Feedback", + "application": "PRISE", + "group": "PRISE Time To Action 1 - Beginning of the month", + "note": "Feedback question - SMS response collected and data is passed back to the PRISE team", + "template": "Hello from the MoA-INFO Fall Armyworm service. Have you seen new Fall Armyworm (FAW) damage on your maize in the past week?\r\na) Yes\r\nb) No\r\nc) I haven't checked", + "template_en": "Hello from the MoA-INFO Fall Armyworm service. Have you seen new Fall Armyworm (FAW) damage on your maize in the past week?\r\na) Yes\r\nb) No\r\nc) I haven't checked", + "template_sw": "Karibu kwa huduma ya MoA-INFO ya Fall Armyworm. Je, umeona uharibifu mpya wa mdudu aina ya FAW kwa mahindi yako wiki iliyopita?\r\na) Ndio \r\nb) La \r\nc) Sijaangalia" + } + }, + { + "model": "message.messagetemplate", + "pk": 17, + "fields": { + "code": "fall_armyworm_5", + "name": "spray1", + "type": "Introduction", + "application": "PRISE", + "group": "PRISE Time To Action 1 - Beginning of the month", + "note": "", + "template": "If you spray pesticides, it is most effective when Fall Armyworm are young. Based on your weather conditions, we can predict how FAW will spread. A for more", + "template_en": "If you spray pesticides, it is most effective when Fall Armyworm are young. Based on your weather conditions, we can predict how FAW will spread. A for more", + "template_sw": "Ikiwa unanyunyuzia dawa, ni bora zaidi wadudu wa Fall Armyworm wakiwa wachanga. Kulingana na hali ya anga kwako, tunaweza tabiri jinsi FAW wataenea. A kwa zaidi" + } + }, + { + "model": "message.messagetemplate", + "pk": 18, + "fields": { + "code": "fall_armyworm_6", + "name": "spray2", + "type": "Context", + "application": "PRISE", + "group": "PRISE Time To Action 1 - Beginning of the month", + "note": "", + "template": "If sprayed too early you risk missing the main infestation. If sprayed late, the worms may be too big and hard to kill. Reply A to learn the best time to spray.", + "template_en": "If sprayed too early you risk missing the main infestation. If sprayed late, the worms may be too big and hard to kill. Reply A to learn the best time to spray.", + "template_sw": "Ukinyunyiza mapema una hatari ya kukosa uvamizi mkuu. Ukinyunyiza kuchelewa, viwavi wanaweza kuwa wakubwa na wagumu kuua. Jibu A kujua wakati bora wa kunyunyiza" + } + }, + { + "model": "message.messagetemplate", + "pk": 19, + "fields": { + "code": "fall_armyworm_7", + "name": "bestdate1", + "type": "Warning /Description", + "application": "PRISE", + "group": "PRISE Time To Action 1 - Beginning of the month", + "note": "", + "template": "If you planted in {{ last_month }} the best time to spray with pesticides will be {{ day_1 }} to {{ day_2 }} days after planting. Until then you can use other methods. Reply A for more", + "template_en": "If you planted in {{ last_month }} the best time to spray with pesticides will be {{ day_1 }} to {{ day_2 }} days after planting. Until then you can use other methods. Reply A for more", + "template_sw": "Ikiwa umepanda {{ last_moth }} wakati bora wa kunyinyiza dawa ni siku {{ day_1 }} hadi {{ day_1 }} baada ya kupanda. Hadi wakati huo tumia mbinu zingine. Jibu A kujua zaidi" + } + }, + { + "model": "message.messagetemplate", + "pk": 20, + "fields": { + "code": "fall_armyworm_8", + "name": "bestdate2", + "type": "Warning /Description", + "application": "PRISE", + "group": "PRISE Time To Action 1 - Beginning of the month", + "note": "", + "template": "If you planted in {{ month }} the best time to spray with pesticides will be {{ day_1 }} to {{ day_2 }} days after planting. Until then you can use other methods.", + "template_en": "If you planted in {{ month }} the best time to spray with pesticides will be {{ day_1 }} to {{ day_2 }} days after planting. Until then you can use other methods.", + "template_sw": "Ikiwa umepanda {{ month }} wakati bora wa kunyinyiza dawa ni siku {{ day_1 }} hadi {{ day_2 }} baada ya kupanda. Hadi wakati huo tumia mbinu zingine." + } + }, + { + "model": "message.messagetemplate", + "pk": 21, + "fields": { + "code": "fall_armyworm_9", + "name": "feedback", + "type": "Feedback", + "application": "PRISE", + "group": "PRISE Time To Action 2 - Second half of the month", + "note": "", + "template": "It is time to prepare yourself for Fall Armyworm! Have you seen new FAW damage on your maize in the past week?\r\na) Yes\r\nb) No\r\nc) I haven't checked", + "template_en": "It is time to prepare yourself for Fall Armyworm! Have you seen new FAW damage on your maize in the past week?\r\na) Yes\r\nb) No\r\nc) I haven't checked", + "template_sw": "Ni wakati wa kujiandaa kwa uvamizi wa Fall Armyworm! Je, umeona uharibu mpya wa FAW kwa mahindi yako wiki iliyopita?\r\na) Ndio \r\nb) La \r\nc) Sijaangalia" + } + }, + { + "model": "message.messagetemplate", + "pk": 22, + "fields": { + "code": "fall_armyworm_10", + "name": "spray1", + "type": "Introduction", + "application": "PRISE", + "group": "PRISE Time To Action 2 - Second half of the month", + "note": "", + "template": "If you spray pesticides, it is most effective when Fall Armyworm are young. Based on your weather conditions, we can predict how FAW will spread. A for more", + "template_en": "If you spray pesticides, it is most effective when Fall Armyworm are young. Based on your weather conditions, we can predict how FAW will spread. A for more", + "template_sw": "Ikiwa unanyunyuzia dawa, ni bora zaidi wadudu wa Fall Armyworm wakiwa wachanga. Kulingana na hali ya anga kwako, tunaweza tabiri jinsi FAW wataenea. A kwa zaidi" + } + }, + { + "model": "message.messagetemplate", + "pk": 23, + "fields": { + "code": "fall_armyworm_11", + "name": "spray2", + "type": "Context", + "application": "PRISE", + "group": "PRISE Time To Action 2 - Second half of the month", + "note": "", + "template": "If sprayed too early you risk missing the main infestation. If sprayed late, the worms may be too big and hard to kill. Reply A to learn the best time to spray.", + "template_en": "If sprayed too early you risk missing the main infestation. If sprayed late, the worms may be too big and hard to kill. Reply A to learn the best time to spray.", + "template_sw": "Ukinyunyiza mapema una hatari ya kukosa uvamizi mkuu. Ukinyunyiza kuchelewa, viwavi wanaweza kuwa wakubwa na wagumu kuua. Jibu A kujua wakati bora wa kunyunyiza" + } + }, + { + "model": "message.messagetemplate", + "pk": 24, + "fields": { + "code": "fall_armyworm_12", + "name": "advice1", + "type": "Warning /Description /Action /Advice1", + "application": "PRISE", + "group": "PRISE Time To Action 2 - Second half of the month", + "note": "", + "template": "Based on weather conditions in your area, we will predict the peak Fall Armyworm (FAW) infestation in your area and the best time to take action. A for more.", + "template_en": "Based on weather conditions in your area, we will predict the peak Fall Armyworm (FAW) infestation in your area and the best time to take action. A for more.", + "template_sw": "Kulingana na hali ya hewa katika eneo lako, tutatabiri kiwango cha juu cha uvamizi wa FAW katika eneo lako na wakati mwafaka wa kuchukua hatua. A kwa zaidi" + } + }, + { + "model": "message.messagetemplate", + "pk": 25, + "fields": { + "code": "fall_armyworm_13", + "name": "bestdate", + "type": "Warning /Description", + "application": "PRISE", + "group": "PRISE Time To Action 2 - Second half of the month", + "note": "", + "template": "If you planted in {{ month }} the best time to spray with pesticides will be {{ day_1 }} to {{ day_2 }} days after planting. Until then you can use other methods.", + "template_en": "If you planted in {{ month }} the best time to spray with pesticides will be {{ day_1 }} to {{ day_2 }} days after planting. Until then you can use other methods.", + "template_sw": "Ikiwa umepanda {{ month }} wakati bora wa kunyinyiza dawa ni siku {{ day_1 }} hadi {{ day_2 }} baada ya kupanda. Hadi wakati huo tumia mbinu zingine." + } + } +] \ No newline at end of file diff --git a/django_project/message/migrations/0001_initial.py b/django_project/message/migrations/0001_initial.py new file mode 100644 index 00000000..1d835f94 --- /dev/null +++ b/django_project/message/migrations/0001_initial.py @@ -0,0 +1,32 @@ +# Generated by Django 4.2.7 on 2024-10-24 06:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='MessageTemplate', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('code', models.CharField(max_length=512, unique=True)), + ('name', models.CharField(max_length=512)), + ('type', models.CharField(blank=True, max_length=512, null=True)), + ('application', models.CharField(choices=[('PRISE', 'PRISE')], default='PRISE', max_length=512)), + ('group', models.CharField(choices=[('Start of Season', 'Start of Season'), ('PRISE Time To Action 1 - Beginning of the month', 'PRISE Time To Action 1 - Beginning of the month'), ('PRISE Time To Action 2 - Second half of the month', 'PRISE Time To Action 2 - Second half of the month'), ('End of season', 'End of season')], default='Start of Season', max_length=512)), + ('note', models.TextField(blank=True, help_text='Just a note about the template.', null=True)), + ('template', models.TextField(help_text='Field for storing messages in translation. Include {{ context_key }} as a placeholder to be replaced with the appropriate context.')), + ('template_en', models.TextField(help_text='Field for storing messages in translation. Include {{ context_key }} as a placeholder to be replaced with the appropriate context.', null=True)), + ('template_sw', models.TextField(help_text='Field for storing messages in translation. Include {{ context_key }} as a placeholder to be replaced with the appropriate context.', null=True)), + ], + options={ + 'ordering': ('code',), + }, + ), + ] diff --git a/django_project/message/migrations/__init__.py b/django_project/message/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/django_project/message/models.py b/django_project/message/models.py new file mode 100644 index 00000000..03e3f3ae --- /dev/null +++ b/django_project/message/models.py @@ -0,0 +1,68 @@ +# coding=utf-8 +""" +Tomorrow Now GAP. + +.. note:: Message models. +""" + +from django.db import models +from django.utils.translation import gettext_lazy as _ + +from prise.variables import MessageType + + +class MessageApplication: + """The application that will use the message.""" + + PRISE = 'PRISE' # Message that will be used for CABI PRISE + + +class MessageTemplate(models.Model): + """Model that stores message template by group and application.""" + + code = models.CharField( + max_length=512, unique=True + ) + name = models.CharField( + max_length=512 + ) + type = models.CharField( + blank=True, null=True, max_length=512 + ) + application = models.CharField( + default=MessageApplication.PRISE, + choices=( + (MessageApplication.PRISE, _(MessageApplication.PRISE)), + ), + max_length=512 + ) + group = models.CharField( + default=MessageType.START_SEASON, + choices=( + (MessageType.START_SEASON, _(MessageType.START_SEASON)), + (MessageType.TIME_TO_ACTION_1, _(MessageType.TIME_TO_ACTION_1)), + (MessageType.TIME_TO_ACTION_2, _(MessageType.TIME_TO_ACTION_2)), + (MessageType.END_SEASON, _(MessageType.END_SEASON)), + ), + max_length=512 + ) + note = models.TextField( + blank=True, null=True, + help_text=_( + 'Just a note about the template.' + ) + ) + template = models.TextField( + help_text=_( + 'Field for storing messages in translation. ' + 'Include {{ context_key }} as a placeholder ' + 'to be replaced with the appropriate context.' + ) + ) + + class Meta: # noqa + ordering = ('code',) + + def __str__(self): + """Return string representation of MessageTemplate.""" + return self.code diff --git a/django_project/message/translation.py b/django_project/message/translation.py new file mode 100644 index 00000000..e57d8d08 --- /dev/null +++ b/django_project/message/translation.py @@ -0,0 +1,17 @@ +# coding=utf-8 +""" +Tomorrow Now GAP. + +.. note:: Message translation. +""" + +from modeltranslation.translator import register, TranslationOptions + +from message.models import MessageTemplate + + +@register(MessageTemplate) +class MessageTemplateTranslationOptions(TranslationOptions): + """Translation options for MessageTemplate.""" + + fields = ('template',) diff --git a/django_project/prise/__init__.py b/django_project/prise/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/django_project/prise/admin.py b/django_project/prise/admin.py new file mode 100644 index 00000000..56803773 --- /dev/null +++ b/django_project/prise/admin.py @@ -0,0 +1,22 @@ +# coding=utf-8 +""" +Tomorrow Now GAP. + +.. note:: Prise admins +""" +from django.contrib import admin + +from prise.models import PriseMessage + + +@admin.register(PriseMessage) +class PriseMessageAdmin(admin.ModelAdmin): + """Admin page for PriseMessage.""" + + list_display = ('pest', 'message_count') + + filter_horizontal = ('messages',) + + def message_count(self, obj: PriseMessage): + """Message count.""" + return obj.messages.count() diff --git a/django_project/prise/apps.py b/django_project/prise/apps.py new file mode 100644 index 00000000..77673feb --- /dev/null +++ b/django_project/prise/apps.py @@ -0,0 +1,27 @@ +# coding=utf-8 +""" +Tomorrow Now GAP. + +.. note:: PRISE Config + + PRISE: a Pest Risk Information SErvice + Pests can decimate crops and are estimated to cause around a 40% loss. + These insects, mites and plant pathogens can impact on food security and + impede supply chains and international trade. + A Pest Risk Information SErvice (PRISE) aims to solve this problem by + using data to help farmers manage pests in sub-Saharan Africa. +""" + +from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ + + +class PriseConfig(AppConfig): + """App Config for Prise.""" + + name = 'prise' + verbose_name = _('PRISE') + + def ready(self): + """App ready handler.""" + pass diff --git a/django_project/prise/fixtures/1.messages.json b/django_project/prise/fixtures/1.messages.json new file mode 100755 index 00000000..9e56af7d --- /dev/null +++ b/django_project/prise/fixtures/1.messages.json @@ -0,0 +1,45 @@ +[ + { + "model": "prise.prisemessage", + "pk": 1, + "fields": { + "pest": 1, + "messages": [ + 1, + 10, + 11, + 12, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ] + } + }, + { + "model": "prise.prisemessage", + "pk": 2, + "fields": { + "pest": 2, + "messages": [ + 13, + 22, + 23, + 24, + 25, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21 + ] + } + } +] \ No newline at end of file diff --git a/django_project/prise/migrations/0001_initial.py b/django_project/prise/migrations/0001_initial.py new file mode 100644 index 00000000..dffe1c9e --- /dev/null +++ b/django_project/prise/migrations/0001_initial.py @@ -0,0 +1,25 @@ +# Generated by Django 4.2.7 on 2024-10-24 06:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('message', '0001_initial'), + ('gap', '0032_preferences_api_log_batch_size'), + ] + + operations = [ + migrations.CreateModel( + name='PriseMessage', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('messages', models.ManyToManyField(blank=True, null=True, to='message.messagetemplate')), + ('pest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='gap.pest')), + ], + ), + ] diff --git a/django_project/prise/migrations/__init__.py b/django_project/prise/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/django_project/prise/models.py b/django_project/prise/models.py new file mode 100644 index 00000000..dca1eed7 --- /dev/null +++ b/django_project/prise/models.py @@ -0,0 +1,26 @@ +# coding=utf-8 +""" +Tomorrow Now GAP. + +.. note:: Message prise models. +""" + +from django.db import models + +from gap.models.crop_insight import Pest +from message.models import MessageTemplate + + +class PriseMessage(models.Model): + """Model that stores message template linked with pest.""" + + pest = models.ForeignKey( + Pest, on_delete=models.CASCADE + ) + messages = models.ManyToManyField( + MessageTemplate, null=True, blank=True + ) + + def __str__(self): + """Return string representation.""" + return self.pest.name diff --git a/django_project/prise/variables.py b/django_project/prise/variables.py new file mode 100644 index 00000000..c0be4742 --- /dev/null +++ b/django_project/prise/variables.py @@ -0,0 +1,15 @@ +# coding=utf-8 +""" +Tomorrow Now GAP. + +.. note:: Variable that being used for PRISE. +""" + + +class MessageType: + """Type of message that being used by Price.""" + + START_SEASON = 'Start of Season' + TIME_TO_ACTION_1 = 'PRISE Time To Action 1 - Beginning of the month' + TIME_TO_ACTION_2 = 'PRISE Time To Action 2 - Second half of the month' + END_SEASON = 'End of season'