From 02fc1896880a06f58b01d396723b603125dd3664 Mon Sep 17 00:00:00 2001
From: Tor-Einar Skog <tor-einar.skog@bioforsk.no>
Date: Mon, 8 Sep 2014 14:37:00 +0200
Subject: [PATCH] First version of crop type select New app: organisms

---
 VIPSWeb/local_settings_sample.py          |  10 ++-
 VIPSWeb/settings.py                       |   1 +
 VIPSWeb/urls.py                           |   1 +
 VIPSWeb/views.py                          |   3 +
 forecasts/models.py                       |  31 +++++---
 forecasts/templates/forecasts/index.html  |   2 +
 forecasts/urls.py                         |   6 +-
 forecasts/views.py                        |   2 +-
 organisms/__init__.py                     |   0
 organisms/admin.py                        |   3 +
 organisms/locale/nb/LC_MESSAGES/custom.mo | Bin 0 -> 457 bytes
 organisms/locale/nb/LC_MESSAGES/custom.po |  23 ++++++
 organisms/locale/nb/LC_MESSAGES/django.mo | Bin 0 -> 497 bytes
 organisms/locale/nb/LC_MESSAGES/django.po |  27 +++++++
 organisms/models.py                       |  82 ++++++++++++++++++++++
 organisms/templates/organisms/index.html  |   7 ++
 organisms/tests.py                        |   3 +
 organisms/urls.py                         |  27 +++++++
 organisms/views.py                        |  26 +++++++
 19 files changed, 242 insertions(+), 12 deletions(-)
 create mode 100644 organisms/__init__.py
 create mode 100644 organisms/admin.py
 create mode 100644 organisms/locale/nb/LC_MESSAGES/custom.mo
 create mode 100644 organisms/locale/nb/LC_MESSAGES/custom.po
 create mode 100644 organisms/locale/nb/LC_MESSAGES/django.mo
 create mode 100644 organisms/locale/nb/LC_MESSAGES/django.po
 create mode 100644 organisms/models.py
 create mode 100644 organisms/templates/organisms/index.html
 create mode 100644 organisms/tests.py
 create mode 100644 organisms/urls.py
 create mode 100644 organisms/views.py

diff --git a/VIPSWeb/local_settings_sample.py b/VIPSWeb/local_settings_sample.py
index 15ab14e9..27fbee0c 100644
--- a/VIPSWeb/local_settings_sample.py
+++ b/VIPSWeb/local_settings_sample.py
@@ -107,4 +107,12 @@ MAP_ZOOMLEVEL = 4
 MAP_ATTRIBUTION = "&copy; <a href='http://www.openstreetmap.org'>OpenStreetMap</a> contributors"
 
 # The message tags to use on the front page
-FRONTPAGE_MESSAGE_TAG_IDS = [1,2,3]
\ No newline at end of file
+FRONTPAGE_MESSAGE_TAG_IDS = [1,2,3]
+
+# For setting up groups of crops with forecasts. The crop_ids have to correspond to 
+# crops in VIPSLogic
+# Sample: 
+# CROP_GROUPS=[
+#     {"crop_group_id": 1, "name":{"en":"Fruit", "nb":"Frukt"},"crop_ids":[23,44,53]}
+# ]
+CROP_GROUPS=[]
\ No newline at end of file
diff --git a/VIPSWeb/settings.py b/VIPSWeb/settings.py
index d8fb8dcf..29ab44de 100644
--- a/VIPSWeb/settings.py
+++ b/VIPSWeb/settings.py
@@ -130,6 +130,7 @@ INSTALLED_APPS = (
     # 'django.contrib.admindocs',
     'forecasts',
     'messages',
+    'organisms'
 )
 
 SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
diff --git a/VIPSWeb/urls.py b/VIPSWeb/urls.py
index d91654b9..71658345 100644
--- a/VIPSWeb/urls.py
+++ b/VIPSWeb/urls.py
@@ -41,6 +41,7 @@ urlpatterns = patterns('',
 
     url(r'^forecasts/', include('forecasts.urls', namespace = "forecasts")),
     url(r'^messages/', include('messages.urls', namespace = "messages")),
+    url(r'^organisms/', include('organisms.urls', namespace = "organisms")),
     
     # Uncomment the next line to enable the admin:
     url(r'^admin/', include(admin.site.urls)),
diff --git a/VIPSWeb/views.py b/VIPSWeb/views.py
index be81801a..d5e54b29 100644
--- a/VIPSWeb/views.py
+++ b/VIPSWeb/views.py
@@ -17,7 +17,9 @@
 
 from django.shortcuts import render
 from django.conf import settings
+from django.utils import translation
 from messages.models import Message, MessageTag
+from organisms.models import CropGroup
 
 def index(request):
     # Get front page categories. This is defined in local_settings.py
@@ -35,6 +37,7 @@ def index(request):
     context = {
               'message_tags': message_tags,
               'messages_by_tag': messages_by_tag,
+              'crop_groups': CropGroup.get_crop_groups(translation.get_language())
               }
     return render(request, 'index.html', context)
 
diff --git a/forecasts/models.py b/forecasts/models.py
index 9c0cedc6..54504a37 100644
--- a/forecasts/models.py
+++ b/forecasts/models.py
@@ -26,10 +26,12 @@ from django.db import models
 from django.utils import translation
 from django.core.exceptions import ValidationError
 
+from organisms.models import Organism
+
 # Create your models here.
 
 """
-Represent a single result from the running of a forecasting model
+Represents a single result from the running of a forecasting model
 """
 class ForecastResult:
     def __init__(self,forecast_result_id,result_valid_time,warning_status,all_values):
@@ -67,7 +69,8 @@ class ForecastConfiguration:
                  date_end,
                  location_point_of_interest, 
                  weather_station_point_of_interest,
-                 user_id = None):
+                 user_id = None,
+                 crop_organism = None):
         self.forecast_configuration_id = forecast_configuration_id
         self.model_id = model_id
         self.date_start = date_start
@@ -75,6 +78,7 @@ class ForecastConfiguration:
         self.location_point_of_interest = location_point_of_interest#PointOfInterest(location_point_of_interest)
         self.weather_station_point_of_interest = weather_station_point_of_interest
         self.user_id = user_id
+        self.crop_organism = crop_organism
     
     def set_model_local_name(self, model_local_name):
         self.model_local_name = model_local_name
@@ -85,11 +89,11 @@ class ForecastConfiguration:
     Currently this is a REST service
     """
     @staticmethod
-    def get_forecast_configurations():
+    def get_forecast_configurations(crop_organism_ids):
         forecasts = []
         model_local_names = {}
     
-        for item in ForecastConfiguration.get_forecast_configurations_as_json():
+        for item in ForecastConfiguration.get_forecast_configurations_as_json(None):
             forecast = ForecastConfiguration.get_instance_from_dict(item)
             # Get the name of the model in the current locale
             if model_local_names.get(forecast.model_id, None) == None:
@@ -100,9 +104,19 @@ class ForecastConfiguration:
         return forecasts
 
     @staticmethod
-    def get_forecast_configurations_as_json():
-        requestResult = requests.get("http://%s/rest/organizationforecastconfigurations/%s" % (settings.VIPSLOGIC_SERVER_NAME, settings.VIPS_ORGANIZATION_ID))
-        return requestResult.json()
+    def get_forecast_configurations_as_json(crop_organism_ids):
+        crop_organism_id_paramstring = ""
+        if crop_organism_ids != None:
+            for crop_organism_id in crop_organism_ids:
+                crop_organism_id_paramstring += "&cropOrganismId=%s" % crop_organism_id
+            
+        request_result = requests.get("http://%s/rest/organizationforecastconfigurations/%s?%s" % (
+                                                                              settings.VIPSLOGIC_SERVER_NAME, 
+                                                                              settings.VIPS_ORGANIZATION_ID,
+                                                                              crop_organism_id_paramstring
+                                                                              )
+                                     )
+        return request_result.json()
     
     @staticmethod
     def get_forecast_configuration(forecast_configuration_id):
@@ -124,7 +138,8 @@ class ForecastConfiguration:
                                          theDict["dateEnd"],
                                          PointOfInterest(theDict["locationPointOfInterestId"]),
                                          PointOfInterest(theDict["weatherStationPointOfInterestId"]),
-                                         theDict.get("vipsLogicUserId",None)
+                                         theDict.get("vipsLogicUserId",None),
+                                         Organism.get_instance_from_dict(theDict.get("cropOrganismId", None))
                                          )
         return instance
 """
diff --git a/forecasts/templates/forecasts/index.html b/forecasts/templates/forecasts/index.html
index 5ae6a1a1..16253f39 100644
--- a/forecasts/templates/forecasts/index.html
+++ b/forecasts/templates/forecasts/index.html
@@ -27,6 +27,7 @@
 		<thead>
 			<tr>
 				<th>{% trans "Model name" %}</th>
+				<th>{% trans "Crop" %}
 				<th>{% trans "Location" %}</th>
 				<th>{% trans "Date start" %}</th>
 				<th>{% trans "Date end" %}</th>
@@ -37,6 +38,7 @@
 			{% for forecast_configuration in forecast_configurations %}
 			<tr>
 				<td>{{ forecast_configuration.model_local_name }}</td>
+				<td>{{ forecast_configuration.crop_organism.local_name }}</td>
 				<td>{{ forecast_configuration.location_point_of_interest.name }}</td>
 				<td>{{ forecast_configuration.date_start }}</td>
 				<td>{{ forecast_configuration.date_end }}</td>
diff --git a/forecasts/urls.py b/forecasts/urls.py
index 844731fe..b9b3fad5 100644
--- a/forecasts/urls.py
+++ b/forecasts/urls.py
@@ -24,8 +24,10 @@ urlpatterns = patterns('',
     # ex: /forecasts/                   
     url(r'^$', views.index, name='index'),
     # ex: /forecasts/5/
-    url(r'^(?P<forecast_id>\d+)/detail_highcharts_json/$', cache_page(60 * 15)(views.detail_highcharts_json), name='detail_highcharts_json'),
-    url(r'^(?P<forecast_id>\d+)/$', cache_page(60 * 15)(views.detail), name='detail'),
+    #url(r'^(?P<forecast_id>\d+)/detail_highcharts_json/$', cache_page(60 * 15)(views.detail_highcharts_json), name='detail_highcharts_json'),
+    url(r'^(?P<forecast_id>\d+)/detail_highcharts_json/$', views.detail_highcharts_json, name='detail_highcharts_json'),
+    #url(r'^(?P<forecast_id>\d+)/$', cache_page(60 * 15)(views.detail), name='detail'),
+    url(r'^(?P<forecast_id>\d+)/$', (views.detail), name='detail'),
     url(r'^models/(?P<model_id>\w+)/$', views.models_detail, name='models_detail'),
     url(r'^models/js/modelLocalNames.js', cache_page(60 * 30)(views.model_local_names_js), name='model_local_names_js'),
     url(r'^models/$', views.models_index, name='models_index'),
diff --git a/forecasts/views.py b/forecasts/views.py
index 700abc85..cfb2b540 100644
--- a/forecasts/views.py
+++ b/forecasts/views.py
@@ -25,7 +25,7 @@ from django.shortcuts import render
 from forecasts.models import ForecastConfiguration, ForecastResult, ResultParameter, Model, MeasurementUnit, ModelGraphParameter
 
 def index(request):
-    forecast_configurations = ForecastConfiguration.get_forecast_configurations()
+    forecast_configurations = ForecastConfiguration.get_forecast_configurations(None)
     forecast_configurations.sort(key=lambda x: x.date_start, reverse=False)
     context = {'forecast_configurations': forecast_configurations}
     return render(request, 'forecasts/index.html', context)
diff --git a/organisms/__init__.py b/organisms/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/organisms/admin.py b/organisms/admin.py
new file mode 100644
index 00000000..8c38f3f3
--- /dev/null
+++ b/organisms/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/organisms/locale/nb/LC_MESSAGES/custom.mo b/organisms/locale/nb/LC_MESSAGES/custom.mo
new file mode 100644
index 0000000000000000000000000000000000000000..69cdba616a8d58cec09539f6844bf65727221bee
GIT binary patch
literal 457
zcmca7#4?qEfq{XEfq_AWfq_AXfq{XQfq}sWB*?(P5CG)|GB7Y?GcquQL-~gp85kI$
zYCw9SOa=zGqSDL~hJd2{tkmQZUC$KVu+*aB%=|nng#brqZ%21mg)rBkU{8NPuAtO{
z{Gt+F-{SPl6kVs%^kUtRd@BX60RIqO=c3falFa-(U6;g?R4WA|149#C14~^469ofH
zD<d;)10w?it^j}CpwzNVkl|2uk*<zGy1xFpE{+Nw{#L%8+EM;~u3SEe#U;8SMTvRE
zIf*6tMOF%Kp*}teevZDb3O263j-EaajxH`iuED`}Tt10;>7|M3sk$MliMdt^K8}9w
zp&%#Q`1m;FWa{M?r6bf>DRB9E`nn?gXQ*eu<(!{alA2ed8&X-2YNb$;T2Z23kdv61
zXRVN&kyuomT4Ea-;-+hXPzQ2WT56H5YhH4GN@iZVm4Zc5W(ik7PH9nMj;>pNQEsu7
gLS6xwTWo7&tpH)#YUC*>+A0`oT62LyJiCMe0EohQ)&Kwi

literal 0
HcmV?d00001

diff --git a/organisms/locale/nb/LC_MESSAGES/custom.po b/organisms/locale/nb/LC_MESSAGES/custom.po
new file mode 100644
index 00000000..cee4c5d7
--- /dev/null
+++ b/organisms/locale/nb/LC_MESSAGES/custom.po
@@ -0,0 +1,23 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-09-04 09:26+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+# CUSTOM STUFF
+msgid "Fruit"
+msgstr "Frukt"
diff --git a/organisms/locale/nb/LC_MESSAGES/django.mo b/organisms/locale/nb/LC_MESSAGES/django.mo
new file mode 100644
index 0000000000000000000000000000000000000000..dbccee87d852359c8c4387b3d0fa4d60d2529952
GIT binary patch
literal 497
zcmca7#4?qEfq{XUfq_AWfq}t<fq{XQfq}sXB*?(PkO1W;GB7Z3GB7ZtGcYh@Gcqs~
zGB7Z3FfcIOWn^IBVqjo+#>l|H2-O2J3&dms5za;V1;q^hMd^uonZ>!q3;{*?S*gh-
zx}GVzVW~yMnfZBE3IUGJ-j43B3Sq86!JhtpTtTS?`9&qVzQyU8DY{Oj>BYJs`Bn;C
z0sbMn&PAz-C7Jnox-N+&sa6U`28JfO29~-8CJF|YRz_yp21W)3Tmk;NL8)b#Aj6^R
zB3&JWbbbAGT^toW{H=UFwWIv~T)BJ_i%WDviW2jRa}rDPi>wsfLVbJ`{2YB<6>MC6
z9X)*<99>+3T!Vw{xO@`x(n}N5Q*}d96LYN;d>sAULqSfq@$qrU$<)g)N=K-%QsDCS
z^mRq}&rr{R%Q-)<BsH%@H>9#4)k>ixwW377ASW?1&srflBeAGBwZt|w#7)-%p$_D%
zwA3P9*SzHXl+3(zD+P<B%o47EoYJDi99_5kqTFIDg}eeVx7gOmS^>he)yPv&v{f+F
VwB};)F3l+^ElMqd2Y+f20|1m+gu?&;

literal 0
HcmV?d00001

diff --git a/organisms/locale/nb/LC_MESSAGES/django.po b/organisms/locale/nb/LC_MESSAGES/django.po
new file mode 100644
index 00000000..f8a34021
--- /dev/null
+++ b/organisms/locale/nb/LC_MESSAGES/django.po
@@ -0,0 +1,27 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-09-04 09:26+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: templates/organisms/index.html:3 templates/organisms/index.html.py:5
+msgid "Organisms"
+msgstr "Organismer"
+
+#: templates/organisms/index.html:5
+msgid "Crops"
+msgstr "Kulturer"
diff --git a/organisms/models.py b/organisms/models.py
new file mode 100644
index 00000000..dd4a9a0a
--- /dev/null
+++ b/organisms/models.py
@@ -0,0 +1,82 @@
+#    Copyright (C) 2014 Bioforsk
+#    
+#    This file is part of VIPSWeb
+#
+#    VIPSWeb is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    VIPSWeb is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with VIPSWeb.  If not, see <http://www.gnu.org/licenses/>.
+
+import requests
+from django.conf import settings
+from django.utils import translation
+
+class CropGroup:
+    def __init__(self,
+                 crop_group_id,
+                 name,
+                 crop_ids
+                 ): 
+        self.crop_group_id = crop_group_id
+        self.name = name
+        self.crop_ids = crop_ids
+    
+    @staticmethod
+    def get_crop_groups(language):
+        crop_groups = []
+        for item in settings.CROP_GROUPS:
+            crop_groups.append(CropGroup.get_instance_from_dict(item,language))
+        return crop_groups
+    
+    @staticmethod
+    def get_instance_from_dict(dict,language):
+        return CropGroup(dict["crop_group_id"],
+                         dict["name"].get(language,dict["name"]["en"]),
+                         dict["crop_ids"]
+                         )
+            
+
+class Organism:
+    def __init__(self,
+                 organism_id,
+                 latin_name,
+                 trade_name,
+                 parent_organism_id,
+                 hierarchy_category_id,
+                 local_name
+                 ):
+        self.organism_id = organism_id
+        self.latin_name = latin_name
+        self.trade_name = trade_name
+        self.parent_organism_id = parent_organism_id
+        self.hierarchy_category_id = hierarchy_category_id
+        self.local_name = local_name
+    
+    @staticmethod
+    def get_instance_from_dict(theDict):
+        if theDict == None:
+            return None
+        # Get the local name (if it exists, fallback is English, then Latin name)
+        local_name = ""
+        for item in theDict["organismLocaleSet"]:
+            if item["organismLocalePK"]["locale"] == translation.get_language() \
+                or (local_name == "" and item["organismLocalePK"]["locale"] == "en"):
+                local_name = item["localName"]
+        if local_name == "":
+            local_name = theDict["latinName"]
+                
+        return Organism(theDict["organismId"],
+                        theDict["latinName"],
+                        theDict["tradeName"],
+                        theDict["parentOrganismId"],
+                        theDict["hierarchyCategoryId"],
+                        local_name
+                        )
diff --git a/organisms/templates/organisms/index.html b/organisms/templates/organisms/index.html
new file mode 100644
index 00000000..537af5d1
--- /dev/null
+++ b/organisms/templates/organisms/index.html
@@ -0,0 +1,7 @@
+{% extends "base.html" %}
+{% load i18n %}
+{% block title%}{% trans "Organisms" %}{%endblock%}
+{% block content %}
+<h1>{% trans "Organisms" %}/{% trans "Crops" %}</h1>
+<p>{% trans "Crop" %}</p>
+{% endblock %}
\ No newline at end of file
diff --git a/organisms/tests.py b/organisms/tests.py
new file mode 100644
index 00000000..7ce503c2
--- /dev/null
+++ b/organisms/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/organisms/urls.py b/organisms/urls.py
new file mode 100644
index 00000000..a6a352f8
--- /dev/null
+++ b/organisms/urls.py
@@ -0,0 +1,27 @@
+#    Copyright (C) 2014 Bioforsk
+#    
+#    This file is part of VIPSWeb
+#
+#    VIPSWeb is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    VIPSWeb is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with VIPSWeb.  If not, see <http://www.gnu.org/licenses/>.
+
+from django.conf.urls import patterns, url
+
+from organisms import views
+
+urlpatterns = patterns('',
+    # ex: /organisms/                   
+    url(r'^$', views.index, name='index'),
+    # ex: /organisms/5/
+    #url(r'^(?P<organism_id>\d+)/$', views.detail, name='detail'),
+)
\ No newline at end of file
diff --git a/organisms/views.py b/organisms/views.py
new file mode 100644
index 00000000..961f111e
--- /dev/null
+++ b/organisms/views.py
@@ -0,0 +1,26 @@
+#    Copyright (C) 2014 Bioforsk
+#    
+#    This file is part of VIPSWeb
+#
+#    VIPSWeb is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    VIPSWeb is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with VIPSWeb.  If not, see <http://www.gnu.org/licenses/>.
+
+from django.shortcuts import render, get_object_or_404
+
+
+def index(request):
+    context = {
+               
+               }
+    return render(request, 'organisms/index.html', context)
+# Create your views here.
-- 
GitLab