-
Notifications
You must be signed in to change notification settings - Fork 136
/
minimum_needs.py
248 lines (213 loc) · 8.15 KB
/
minimum_needs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# coding=utf-8
"""This module contains the abstract class of the MinimumNeeds. The storage
logic is omitted here."""
__author__ = 'Christian Christelis <christian@kartoza.com>'
__date__ = '05/10/2014'
__copyright__ = ('Copyright 2014, Australia Indonesia Facility for '
'Disaster Reduction')
from collections import OrderedDict
import json
from os.path import exists, dirname
from os import remove
from safe.utilities.i18n import tr
class MinimumNeeds(object):
"""A abstract class for handling the minimum needs.
The persistence logic is excluded from this class.
.. versionadded:: 2.2.
"""
def get_need(self, resource):
"""Get a resource from the minimum_needs.
:param resource: The resource name
:type resource: basestring
:returns: resource needed.
:rtype: dict, None
"""
for need in self.minimum_needs:
if need['name'] == resource:
return need
return None
def get_minimum_needs(self):
"""Get the minimum needed information about the minimum needs.
That is the resource and the amount.
:returns: minimum needs
:rtype: OrderedDict
"""
minimum_needs = OrderedDict()
for resource in self.minimum_needs['resources']:
if resource['Unit abbreviation']:
name = '%s [%s]' % (
tr(resource['Resource name']),
resource['Unit abbreviation']
)
else:
name = tr(resource['Resource name'])
amount = resource['Default']
minimum_needs[name] = amount
return OrderedDict(minimum_needs)
def get_full_needs(self):
"""The full list of minimum needs with all fields.
:returns: minimum needs
:rtype: dict
"""
return self.minimum_needs
def set_need(self, resource, amount, units, frequency='weekly'):
"""Append a single new minimum need entry to the list.
:param resource: Minimum need resource name.
:type resource: basestring
:param amount: Amount per person per time interval
:type amount: int, float
:param units: The unit that the resource is measured in.
:type: basestring
:param frequency: How regularly the unit needs to be dispatched
:type: basestring # maybe at some point fix this to a selection.
"""
self.minimum_needs['resources'].append({
'Resource name': resource,
'Default': amount,
'Unit abbreviation': units,
'Frequency': frequency
})
def update_minimum_needs(self, minimum_needs):
"""Overwrite the internal minimum needs with new needs.
Validate the new minimum needs. If ok, set these as the internal
minimum needs.
:param minimum_needs: The new minimum
:type minimum_needs: dict
:returns: Returns success code, -1 for failure, 0 for success.
:rtype: int
"""
if type(minimum_needs) != dict:
return -1
# noinspection PyAttributeOutsideInit
self.minimum_needs = minimum_needs
return 0
@staticmethod
def _defaults():
"""Helper to get the default minimum needs.
.. note:: Key names will be translated.
"""
rice = tr('Rice')
drinking_water = tr('Drinking Water')
water = tr('Clean Water')
family_kits = tr('Family Kits')
toilets = tr('Toilets')
minimum_needs = {
"resources": [
{
"Default": "2.8",
"Minimum allowed": "0",
"Maximum allowed": "100",
"Frequency": "weekly",
"Resource name": rice,
"Resource description": "Basic food",
"Unit": "kilogram",
"Units": "kilograms",
"Unit abbreviation": "kg",
"Readable sentence": (
"Each person should be provided with {{ Default }} "
"{{ Units }} of {{ Resource name }} {{ Frequency }}.")
},
{
"Default": "17.5",
"Minimum allowed": "0",
"Maximum allowed": "100",
"Frequency": "weekly",
"Resource name": drinking_water,
"Resource description": "For drinking",
"Unit": "litre",
"Units": "litres",
"Unit abbreviation": "l",
"Readable sentence": (
"Each person should be provided with {{ Default }} "
"{{ Units }} of {{ Resource name }} {{ Frequency }} "
"for drinking.")
},
{
"Default": "67",
"Minimum allowed": "10",
"Maximum allowed": "100",
"Frequency": "weekly",
"Resource name": water,
"Resource description": "For washing",
"Unit": "litre",
"Units": "litres",
"Unit abbreviation": "l",
"Readable sentence": (
"Each person should be provided with {{ Default }} "
"{{ Units }} of {{ Resource name }} {{ Frequency }} "
"for washing.")
},
{
"Default": "0.2",
"Minimum allowed": "0.1",
"Maximum allowed": "1",
"Frequency": "weekly",
"Resource name": family_kits,
"Resource description": "Hygiene kits",
"Unit": "",
"Units": "",
"Unit abbreviation": "",
"Readable sentence": (
"Each family of 5 persons should be provided with 1 "
"Family Kit per week.")
},
{
"Default": "0.05",
"Minimum allowed": "0.02",
"Maximum allowed": "1",
"Frequency": "single",
"Resource name": toilets,
"Resource description": "",
"Unit": "",
"Units": "",
"Unit abbreviation": "",
"Readable sentence": (
"A Toilet should be provided for every 20 persons.")
}
],
"provenance": "The minimum needs are based on Perka 7/2008.",
"profile": "BNPB_en"
}
return minimum_needs
def read_from_file(self, filename):
"""Read from an existing json file.
:param filename: The file to be written to.
:type filename: basestring, str
:returns: Success status. -1 for unsuccessful 0 for success
:rtype: int
"""
if not exists(filename):
return -1
with open(filename) as fd:
needs_json = fd.read()
try:
minimum_needs = json.loads(needs_json)
except (TypeError, ValueError):
minimum_needs = None
if not minimum_needs:
return -1
return self.update_minimum_needs(minimum_needs)
def write_to_file(self, filename):
"""Write minimum needs as json to a file.
:param filename: The file to be written to.
:type filename: basestring, str
"""
if not exists(dirname(filename)):
return -1
with open(filename, 'w') as fd:
needs_json = json.dumps(self.minimum_needs)
fd.write(needs_json)
return 0
@staticmethod
def remove_file(filename):
"""Remove a minimum needs file.
:param filename: The file to be removed.
:type filename: basestring, str
"""
if not exists(dirname(filename)):
return -1
try:
remove(filename)
except OSError:
return -1
return 0