· 6 years ago · Aug 29, 2019, 09:44 AM
1from firebase_admin import db
2import firebase_admin
3import flask
4from flask_cors import CORS
5import json,re
6from multiprocessing.dummy import Pool as ThreadPool
7from flask import Response
8import datetime
9
10OK_CODE=200
11BAD_REQUEST=400
12FORBIDDEN=403
13INTERNAL_SERVER_ERROR=500
14NOT_FOUND=404
15
16#-----------------messaggi----------
17MESSAGE_1 = "Richiesta non formulata correttamente: campo 'apikey' non presente."
18MESSAGE_2 = 'Data non formattata correttamente. Utilizzare il formato "dd/mm/yyyy". Esempio: "01/01/2019.'
19MESSAGE_3 = "Autorizzazione negata." # Api key non presente
20MESSAGE_4 = "Formato APIKEY errato."
21MESSAGE_5="Utilizzare un unico parametro di filtraggio."
22MESSAGE_6='Nessun dato per i parametri richiesti.'
23
24
25
26app=firebase_admin.initialize_app(options={
27 'databaseURL': 'https://sensesquaredb.firebaseio.com',
28})
29
30
31# from firebase_admin import auth
32# auth.create_user()
33app = flask.Flask(__name__)
34CORS(app,methods='POST')
35
36def dati_centralina(request):
37 apikey = request.args.get('apikey')
38
39 #-----------------VERIFICA DELL'APIKEY E DELL'EVENTUALE ACCESSO ADMIN-------------
40 check_apikey=check_access(apikey)
41 check_admin=False
42 if check_apikey[0]==False:
43 return give_Response(data={},message=check_apikey[1],response_code=check_apikey[2])
44 else:
45 if check_apikey[1]=='ADMIN':
46 check_admin=True
47
48
49 #------------------VERIFICA DEI CAMPI OBBLIGATORI----------------
50 id_centralina=request.args.get('id_centralina')
51 data=request.args.get('data')
52
53 if None in [id_centralina,data]:
54 message='Campi obbligatori non presenti: '
55 campi=[]
56 if id_centralina ==None:
57 campi.append('id_centralina')
58 if data ==None:
59 campi.append('data')
60 message+=str(campi)
61 return give_Response(data={},message=message,response_code=BAD_REQUEST)
62
63 try:
64 datetime.datetime.strptime(data,"%d/%m/%Y")
65 except:
66 return give_Response({},response_code=BAD_REQUEST,message=MESSAGE_2)
67
68
69 if not check_admin:
70 check_centralina=centralina_is_enabled(apikey,id_centralina)
71
72 if check_centralina == False:
73 return give_Response(data={},message=MESSAGE_3,response_code=FORBIDDEN)
74
75 month_key =str(data.split('/')[2])+'M'+str(data.split('/')[1]).zfill(2)
76 day_key='D'+str(data.split('/')[0]).zfill(2)
77
78
79 #------------------VERIFICA DEI CAMPI OPZIONALI----------------
80 ora=request.args.get('ora')
81 range_ore=request.args.get('range_ore')
82
83 if ora!= None and range_ore!=None:
84 return give_Response(data={}, message=MESSAGE_5,response_code=BAD_REQUEST)
85
86 fields_updated_query=db.reference('fields_updated').get()
87 fields_updated=[]
88 for field_key in fields_updated_query:
89 fields_updated.append(field_key)
90 fields_updated.append('latitude')
91 fields_updated.append('longitude')
92 nodo_centralina = db.reference('Sensori').child(id_centralina)
93 feeds_ref = nodo_centralina.child('feeds').child(month_key + "/" + day_key)
94
95 if ora != None:
96
97 try:
98 ora=int(ora)
99 if not 0<ora<23:
100 return give_Response(response_code=BAD_REQUEST,message='Inserire un ora compresa tra 0 e 23.')
101 except:
102 return give_Response(response_code=BAD_REQUEST, message='Il campo ora deve essere un campo numerico.')
103
104 hour_key='H'+str(ora).zfill(2)
105
106
107 if check_admin or check_centralina:
108 data_to_send=[]
109 feeds_data=feeds_ref.child(hour_key).get()
110 if feeds_data != None and feeds_data!={}:
111 for feed_id in feeds_data:
112 single_data={}
113 key_time=month_key+day_key+hour_key+feed_id
114 single_data['sample_time']=get_feed_timestamp(key_time)
115 for k in feeds_data[feed_id]:
116 if k in fields_updated:
117 single_data[k] = feeds_data[feed_id][k]
118 data_to_send.append(single_data)
119
120 if len(data_to_send)>0:
121 return give_Response(data=data_to_send)
122 else:
123 return give_Response(data=data_to_send,response_code=NOT_FOUND,message=MESSAGE_6)
124
125 elif range_ore !=None:
126
127 if type(range_ore)!=list:
128 try:
129 range_ore=json.loads(range_ore)
130 except:
131 message = 'Campo "range_ore" deve essere un array nel formato [int,int] con numeri compresi tra 0 e 23'
132 return give_Response(response_code=BAD_REQUEST,message=message)
133
134 check_range=check_range_ore(range_ore)
135
136 if check_range[0]==False:
137 return give_Response(response_code=BAD_REQUEST,message=check_range[1])
138
139
140 range_hour_key = ['H' + str(x).zfill(2) for x in range(range_ore[0],range_ore[1]+1)]
141
142 if check_admin or check_centralina:
143 data_to_send = []
144 for hour_key in range_hour_key:
145 feeds_data = feeds_ref.child(hour_key).get()
146 if feeds_data=={} or feeds_data==None:
147 continue
148 for feed_id in feeds_data:
149 single_data = {}
150 key_time = month_key + day_key + hour_key + feed_id
151 single_data['sample_time'] = get_feed_timestamp(key_time)
152 for k in feeds_data[feed_id]:
153 if k in fields_updated:
154 single_data[k] = feeds_data[feed_id][k]
155 data_to_send.append(single_data)
156
157 if len(data_to_send) > 0:
158 return give_Response(data=data_to_send)
159 else:
160 return give_Response(data=data_to_send, response_code=NOT_FOUND, message=MESSAGE_6)
161
162 else:
163 range_hour_key=['H'+str(x).zfill(2) for x in range(24)]
164
165 if check_admin or check_centralina:
166 data_to_send = []
167 for hour_key in range_hour_key:
168 feeds_data = feeds_ref.child(hour_key).get()
169 if feeds_data=={} or feeds_data==None:
170 continue
171 for feed_id in feeds_data:
172 single_data = {}
173 key_time = month_key + day_key + hour_key + feed_id
174 single_data['sample_time'] = get_feed_timestamp(key_time)
175 for k in feeds_data[feed_id]:
176 if k in fields_updated:
177 single_data[k] = feeds_data[feed_id][k]
178 data_to_send.append(single_data)
179
180 if len(data_to_send) > 0:
181 return give_Response(data=data_to_send)
182 else:
183 return give_Response(data=data_to_send, response_code=NOT_FOUND, message=MESSAGE_6)
184
185
186
187
188def get_timestamp(data_param,hour=0):
189 #data_param nel formato 'dd/mm/yyyy' esempio '25/07/2019'
190 #parametro ora è opzionale...di default restituisce il timestamp a mezzanotte
191 data = datetime.datetime.strptime(data_param,"%d/%m/%Y") + datetime.timedelta(hours=2+hour)
192 timestamp = int(data.timestamp())
193 return timestamp
194
195def get_tipo_centralina(code):
196
197 #code deve essere un intero
198 tipologia=db.reference('codici_centraline').order_by_child('code').equal_to(code).get()
199
200 if tipologia != None:
201 return tipologia['tipo']
202 else:
203 return None
204
205def get_code_centralina(tipo):
206 tipologia = db.reference('codici_centraline').order_by_child('tipo').equal_to(code).get()
207
208 if tipologia != None and tipologia != {}:
209 return tipologia['code']
210 else:
211 return None
212
213
214
215
216
217def check_access(api_key):
218 if type(api_key)!= str:
219 return (False, MESSAGE_4, 400)
220 else:
221 if len(api_key)<1:
222 return (False, MESSAGE_3,403)
223
224 if (api_key == None):
225 return (False, MESSAGE_1,400) #richiesta non formulata correttamente
226 regex = re.compile('[@_!#$%^&*()<>?/\|}{~:.-]')
227 if (regex.search(api_key) == None):
228 search = db.reference("apikeys/" + str(api_key)).get()
229
230 if search != None and search != {}:
231 search=search['admin']
232 #search = db.reference("apikeys/" + str(api_key)).child("admin").get()
233 if search == True or search =='True' or search =='true':
234 return (True, "ADMIN",200)
235 else:
236 return (True, "NO_ADMIN",200)
237
238 else:
239 return (False, MESSAGE_3,403) #Non autorizzato
240 else:
241 return (False, MESSAGE_4,400) #Errore nella richiesta
242
243
244def give_Response(data={},response_code=200,message=''):
245
246 response_data={'response_code':response_code,
247 'message': message,
248 'result':data}
249
250 json_string = json.dumps(response_data, ensure_ascii=False)
251
252 response = Response(json_string, content_type="application/json; charset=utf-8")
253 response.headers.set('Access-Control-Allow-Origin', '*')
254 response.headers.set('Access-Control-Allow-Methods', 'GET')
255
256 return response
257
258
259def check_range_ore(range_ore):
260 # range_ore=[0,23]
261 message='Campo "range_ore" deve essere un array nel formato [int,int] con numeri compresi tra 0 e 23'
262 if type(range_ore)!=list:
263 print("Diverso da list")
264 return (False,message,BAD_REQUEST)
265 if len(range_ore)!=2:
266 print("len diversa da 2")
267 return (False,message,BAD_REQUEST)
268 try:
269 if range_ore[1] > range_ore[0]:
270 print(1)
271 if range_ore[0] >= 0 and range_ore[0] < 23:
272 print(2)
273 if range_ore[1] >= 1 and range_ore[1] < 24:
274 print(3)
275 return (True,'',200)
276 except:
277 print(4)
278 pass
279 return (False,message,BAD_REQUEST)
280
281
282
283def centralina_is_enabled(apikey,id_centralina):
284 id=db.reference('apikeys').child(apikey).child('centraline').order_by_child('id_centralina').equal_to(id_centralina).get()
285 print("risultato della query {}".format(id))
286 if id!={}:
287 print("Ritorno True")
288 return True
289 else:
290 print("Ritorno False")
291 return False
292
293def get_feed_timestamp(key):
294 #key='2019M03D25H14M04S11' monthkey + daykey + hour day + feed_id
295 date=datetime.datetime.strptime(key, "%YM%mD%dH%HM%MS%S")
296 date=date+datetime.timedelta(hours=-2)
297
298 return int(date.timestamp())