views.py 31.3 KB
Newer Older
1
2
from app import app, mail
from flask_mail import Message
Vladislav Rykov's avatar
Vladislav Rykov committed
3

Vladislav Rykov's avatar
Vladislav Rykov committed
4
from flask import render_template, request, redirect, url_for, session, send_from_directory, flash
5
import psycopg2
Vladislav Rykov's avatar
Vladislav Rykov committed
6

Vladislav Rykov's avatar
Vladislav Rykov committed
7
8
9
10
11
import app.dao.user.user as ud
import app.dao.application.application as ad
import app.dao.device.device as dd
import app.dao.pend.pend as pend
import app.dao.data.data as data
Vladislav Rykov's avatar
Vladislav Rykov committed
12
13
import app.dao.notification.notification as nfs
import app.dao.trigger.trigger as tr
Vladislav Rykov's avatar
Vladislav Rykov committed
14
import app.dao.notification_queue.notification_queue as nq
Vladislav Rykov's avatar
Vladislav Rykov committed
15
import app.dao.misc.misc as md
Vladislav Rykov's avatar
Vladislav Rykov committed
16

Vladislav Rykov's avatar
Vladislav Rykov committed
17
import app.helpers.misc as misc
18
import app.helpers.mailer as mailer
Vladislav Rykov's avatar
Vladislav Rykov committed
19

20
import os
Vladislav Rykov's avatar
Vladislav Rykov committed
21
import binascii
Vladislav Rykov's avatar
Vladislav Rykov committed
22

23

24
25
MAX_PG = 5
MAX_PG_ENTRIES_USERS = 10
26
27
MAX_PG_ENTRIES_DATA = 10
MAX_PG_ENTRIES_GRAPH_HOURS = 24
28

Vladislav Rykov's avatar
Vladislav Rykov committed
29
@app.route('/')
30
def index():
Vladislav Rykov's avatar
Vladislav Rykov committed
31
    if 'name' in session and len(session['name']) > 0:
Vladislav Rykov's avatar
Vladislav Rykov committed
32
33
34
35
        created_apps = ad.get_count_by_user(session['name'])[1][0]
        active_devices = dd.get_count_by_user(session['name'])
        total_activity = md.get_user_data_count(session['name'])[1][0]
        last_activity = md.get_user_data_count_per_day(session['name'])[1][0]
36
        recent_activity = md.get_recent_activity(session['name'])[1]
Vladislav Rykov's avatar
Vladislav Rykov committed
37
        print (recent_activity)
Vladislav Rykov's avatar
Vladislav Rykov committed
38
39
        info = [created_apps, active_devices, total_activity, last_activity]

40
41
42
43
44
45
46
47
48
        day_chart_values = md.get_user_data_count_per_hour_period(session['name'], 11)[1]
        day_chart_values = [x[0] for x in day_chart_values]
        day_chart_labels = [misc.local_hour(x) for x in range(11,-1,-1)]
        day_chart = [day_chart_labels, day_chart_values]

        week_chart_values = md.get_user_data_count_per_day_period(session['name'], 6)[1]
        week_chart_values = [x[0] for x in week_chart_values]
        week_chart_labels = [misc.local_weekday(x) for x in range(6,-1,-1)]
        week_chart = [week_chart_labels, week_chart_values]
49

50
        return render_template('new/public/dashboard.html', info=info, recent_activity=recent_activity, day_chart=day_chart, week_chart=week_chart)
Vladislav Rykov's avatar
Vladislav Rykov committed
51
        
Vladislav Rykov's avatar
Vladislav Rykov committed
52
    else:
Vladislav Rykov's avatar
Vladislav Rykov committed
53
        return render_template('new/public/login.html', users_signup=app.config['USERS_SIGNUP'])
54

Vladislav Rykov's avatar
Vladislav Rykov committed
55
56
57
58
59
60
61
@app.route('/chart-update')
def chart_update():
    day_chart_values = md.get_user_data_count_per_hour_period(session['name'], 11)[1]
    day_chart_values = [x[0] for x in day_chart_values]
    day_chart_labels = [misc.local_hour(x) for x in range(11,-1,-1)]
    day_chart = [day_chart_labels, day_chart_values]
    return "{}".format(day_chart)
62
63


Vladislav Rykov's avatar
Vladislav Rykov committed
64
@app.route('/register', methods=['GET', 'POST'])
Vladislav Rykov's avatar
Vladislav Rykov committed
65
def register():
66
    if request.method == 'GET':
Vladislav Rykov's avatar
Vladislav Rykov committed
67
        if 'role' in session and session['role'] == 'admin':
Vladislav Rykov's avatar
Vladislav Rykov committed
68
            return render_template('old/admin/signup.html', users_signup=app.config['USERS_SIGNUP'])
Vladislav Rykov's avatar
Vladislav Rykov committed
69
        else:
70
            if app.config['USERS_SIGNUP']:
Vladislav Rykov's avatar
Vladislav Rykov committed
71
                return render_template('new/public/register.html', users_signup=app.config['USERS_SIGNUP'])
72
            else:
73
                return redirect(url_for('index', users_signup=app.config['USERS_SIGNUP']))
74
    else:
Vladislav Rykov's avatar
Vladislav Rykov committed
75
        if app.config['USERS_SIGNUP'] or ('role' in session and session['role'] == 'admin'):
76
77
78
79
            username = request.form['username']
            password = request.form['password'].encode('utf-8')
            
            if (username == '' or password == ''):
Vladislav Rykov's avatar
Vladislav Rykov committed
80
81
                flash('Username or password fields cannot be empty', 'danger')
                return redirect(url_for('register', users_signup=app.config['USERS_SIGNUP']))
82
83
            elif (len(password) < 8):
                flash('Password length must be at least 8 characters.', 'danger')
Vladislav Rykov's avatar
Vladislav Rykov committed
84
                return redirect(url_for('register', users_signup=app.config['USERS_SIGNUP']))
Vladislav Rykov's avatar
Vladislav Rykov committed
85
            else:
86
                role = 'user'
Vladislav Rykov's avatar
Vladislav Rykov committed
87
                if 'role' in request.form and request.form['role'] == 'administrator':
88
89
90
91
92
93
                    role = 'admin'

                res = ud.create(username, password, role)
                if (not res[0]):
                    flash('Error: {}'.format(res[1]), 'danger')
                    return redirect(request.url)
Vladislav Rykov's avatar
Vladislav Rykov committed
94
                else:
95
96
97
                    session['name'] = username
                    
                    flash('User successfully created.', 'success')
98

Vladislav Rykov's avatar
Vladislav Rykov committed
99
                    if 'role' in session and session['role'] == 'admin':
Vladislav Rykov's avatar
Vladislav Rykov committed
100
                        return redirect(url_for('administration'))
101
102
103
104
                    else:
                        return redirect(url_for('index'))
        else:
            return redirect(url_for('index'))
105
106


Vladislav Rykov's avatar
Vladislav Rykov committed
107
@app.route('/login', methods=['GET', 'POST'])
Vladislav Rykov's avatar
Vladislav Rykov committed
108
def login():
Vladislav Rykov's avatar
Vladislav Rykov committed
109
    if request.method == 'GET':
Vladislav Rykov's avatar
Vladislav Rykov committed
110
        return render_template('new/public/login.html')
Vladislav Rykov's avatar
Vladislav Rykov committed
111
112
    else: 
        username = request.form['username']
Vladislav Rykov's avatar
Vladislav Rykov committed
113
        password = request.form['password'].encode('utf-8')
Vladislav Rykov's avatar
Vladislav Rykov committed
114
115

        if (username == '' or password == ''):
Vladislav Rykov's avatar
Vladislav Rykov committed
116
117
            flash('Username or password fields cannot be empty', 'danger')
            return redirect(request.url)
Vladislav Rykov's avatar
Vladislav Rykov committed
118
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
119
            res = ud.check(username, password)
Vladislav Rykov's avatar
Vladislav Rykov committed
120
            if (not res[0]):
Vladislav Rykov's avatar
Vladislav Rykov committed
121
122
                flash('Error: {}'.format(res[1]), 'danger')
                return redirect(request.url)
Vladislav Rykov's avatar
Vladislav Rykov committed
123
124
            else:
                session['name'] = username
125
                session['role'] = res[1][2]
Vladislav Rykov's avatar
Vladislav Rykov committed
126
        
Vladislav Rykov's avatar
Vladislav Rykov committed
127
128
129
                return redirect(url_for('index'))


Vladislav Rykov's avatar
Vladislav Rykov committed
130
@app.route('/logout')
Vladislav Rykov's avatar
Vladislav Rykov committed
131
132
133
def logout():
    session.clear()
    return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
134
135


Vladislav Rykov's avatar
Vladislav Rykov committed
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
@app.route('/applications')
def applications():
    if 'name' in session:
        apps = ad.get_list(session['name'])
       
        session.pop('appkey', None)
        
        return render_template('new/public/applications.html', apps=apps[1])
    else:
        return redirect(url_for('login', users_signup=app.config['USERS_SIGNUP']))


@app.route('/application/<appkey>')
def application(appkey):
    if 'name' in session:    
        ap = list(ad.get(appkey)[1])
        ap[5] = misc.skey_b64_to_hex(ap[5])
        devs = dd.get_list(ap[1])[1]

        return render_template('new/public/application.html', app=ap, devs=devs)
    else:
        return redirect(url_for('login', users_signup=app.config['USERS_SIGNUP']))


160
161
162
163
164
165
166
167
168
169
170
171
172
173
@app.route('/new-application', methods=['GET', 'POST'])
def new_application():
    if 'name' in session:
        if request.method == 'GET':
            return render_template('new/public/new-application.html')
        elif request.method == 'POST':
            if request.form['appname'] == '':
                flash('Application name cannot be empty.', 'danger')
                return render_template(request.url)
            else:
                appkey = misc.rand_str(app.config['APPKEY_LENGTH']).decode('utf-8')
                secure_key = misc.gen_skey_b64(16)
                secure = False

Vladislav Rykov's avatar
Vladislav Rykov committed
174
                if request.form.getlist('secure') and request.form.getlist('secure')[0] == 'on':
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
                    secure = True

                res = ad.create(request.form['appname'], appkey, session['name'], request.form['appdesc'], secure, secure_key)
            
                if not res[0]:
                    flash('Error: {}'.format(res[1]), 'danger')
                    return render_template(request.url)
            
                res = dd.create_table(appkey)
            
                if not res[0]:
                    ad.delete(appkey)
                    flash('Error: {}'.format(res[1]), 'danger')
                    return render_template(request.url)
            
                return redirect(url_for('applications'))
    else:
        return redirect(url_for('login', users_signup=app.config['USERS_SIGNUP']))


Vladislav Rykov's avatar
Vladislav Rykov committed
195
@app.route('/application/<appkey>/device/<devid>')
Vladislav Rykov's avatar
Vladislav Rykov committed
196
def application_device(appkey, devid):
Vladislav Rykov's avatar
Vladislav Rykov committed
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
    if 'name' in session:
        ap = ad.get(appkey)
        if session['role'] == 'admin' or session['name'] == ap[1][2]:
            dev = dd.get(appkey, devid)

            session['devid'] = int(dev[1][1])
            session['devname'] = dev[1][0]
    
            ld = data.get_last_range(appkey, devid, [MAX_PG_ENTRIES_DATA, 0])
            cnt = data.get_count(appkey, devid)
    
            print(ld)

            ltup = 'Device have not any sent data yet'

            if ld[0] and ld[1][0] != []:
                ltup = ld[1][0][1]

Vladislav Rykov's avatar
Vladislav Rykov committed
215
216
217
218
            if ld[0]: 
                return render_template('new/public/device.html', dev=dev[1], app=ap[1], ltup=ltup, data=ld[1], total=cnt[1][0])
            else:
                return render_template('new/public/device.html', dev=dev[1], app=ap[1], ltup=ltup, data=[], total=cnt[1][0])
Vladislav Rykov's avatar
Vladislav Rykov committed
219
220
221
    else:
        return redirect(url_for('login'))

Vladislav Rykov's avatar
Vladislav Rykov committed
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
@app.route('/application/<appkey>/add-device', methods=['GET', 'POST'])
def application_add_device(appkey):
    if 'name' in session:
        if request.method == 'GET':
            ap = ad.get(appkey)
            dev_list = dd.get_list(appkey)
            return render_template('new/public/add-device.html', app=ap[1], free_ids=misc.prep_id_range(dev_list[1]))
        elif request.method == 'POST':
            res = dd.create(request.form['devname'], request.form['devid'], appkey, request.form['devdesc'])

            if not res[0]:
                flash('Error: {}'.format(res[1]), 'danger')
                return render_template(request.url)
            else:
                res = data.create_table(appkey, request.form['devid'])
            
                if not res[0]:
                    dd.delete(session['appkey'], request.form['devid'])
                    flash('Error: {}'.format(res[1]), 'danger')
                    return render_template(request.url)
                else:
                    return redirect(url_for('applications'))
    else:
        return redirect(url_for('login'))
246

247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275

@app.route('/application/<appkey>/device/<devid>/configure', methods=['GET', 'POST'])
def application_device_configuration(appkey, devid):
    if 'name' in session:
        if request.method == 'GET':
            pend_msgs = pend.get_list(appkey, devid)
            ap = ad.get(appkey)[1]
            dev = dd.get(appkey, devid)[1]
            if pend_msgs[0]:
                config_list = []

                for pm in pend_msgs[1]:
                    cntt = binascii.a2b_base64(pm[2])
                    config_id = int(cntt[0])
                    config_args = cntt[2:(len(cntt)-1)].decode('utf-8')
                    ack = pm[3]
                    config_list.append((config_id, config_args, ack, pm[2]))

            return render_template('new/public/device-configuration.html', dev=dev, app=ap, config_list=config_list)
        else:
            base64_args = misc.pend_base64_encode(request.form['arg'], request.form['confid'])
            pend.create(appkey, devid, base64_args)

            return redirect(url_for('applications'))
    else:
        return redirect(url_for('login'))



Vladislav Rykov's avatar
Vladislav Rykov committed
276
@app.route('/new-app')
277
def new_app():
Vladislav Rykov's avatar
Vladislav Rykov committed
278
    if 'name' in session:
Vladislav Rykov's avatar
Vladislav Rykov committed
279
        return render_template('old/public/new-app.html')
Vladislav Rykov's avatar
Vladislav Rykov committed
280
281
    else:
        return redirect(url_for('index'))
282
283


Vladislav Rykov's avatar
Vladislav Rykov committed
284
285
@app.route('/app', methods=['GET', 'POST'])
def app_():
Vladislav Rykov's avatar
Vladislav Rykov committed
286
287
288
    if 'name' in session:
        if request.method == 'GET':
            session['appkey'] = request.args.get('appkey')
Vladislav Rykov's avatar
Vladislav Rykov committed
289

Vladislav Rykov's avatar
Vladislav Rykov committed
290
            ap = ad.get(session['appkey'])
Vladislav Rykov's avatar
Vladislav Rykov committed
291
            print(ap)
Vladislav Rykov's avatar
Vladislav Rykov committed
292
            devs = dd.get_list(ap[1][1])
Vladislav Rykov's avatar
Vladislav Rykov committed
293
            print(devs)
294
            session['appname'] = ap[1][0]
295
296
            
            if session['role'] == 'admin' or session['name'] == ap[1][2]:
Vladislav Rykov's avatar
Vladislav Rykov committed
297
                return render_template('old/public/app.html', app=ap[1], devs=devs[1])
298
299
            else:
                return redirect(url_for('index'))
300
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
301
302
            if request.form['appname'] == '':
                error = 'Application name cannot be empty.'
Vladislav Rykov's avatar
Vladislav Rykov committed
303
                return render_template('old/public/new-app.html', feedback=error)
Vladislav Rykov's avatar
Vladislav Rykov committed
304
            else:
Vladislav Rykov's avatar
Vladislav Rykov committed
305
                appkey = misc.rand_str(app.config['APPKEY_LENGTH']).decode('utf-8')
306
307
308
309
310
311
312
                secure_key = misc.gen_skey_b64(16)
                secure = False

                if request.form.getlist('secure') and request.form.getlist('secure')[0] == 'true':
                    secure = True

                res = ad.create(request.form['appname'], appkey, session['name'], request.form['appdesc'], secure, secure_key)
Vladislav Rykov's avatar
Vladislav Rykov committed
313
            
Vladislav Rykov's avatar
Vladislav Rykov committed
314
                if not res[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
315
                    return render_template('old/public/new-app.html', feedback=res[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
316
            
Vladislav Rykov's avatar
Vladislav Rykov committed
317
                res = dd.create_table(appkey)
318
            
Vladislav Rykov's avatar
Vladislav Rykov committed
319
                if not res[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
320
                    ad.delete(appkey)
Vladislav Rykov's avatar
Vladislav Rykov committed
321
                    return render_template('old/public/new-app.html', feedback=res[1])
322
            
Vladislav Rykov's avatar
Vladislav Rykov committed
323
324
325
                return redirect(url_for('index'))
    else:
        return redirect(url_for('index'))
326

Vladislav Rykov's avatar
Vladislav Rykov committed
327
@app.route('/delete-app')
328
def delete_app():
Vladislav Rykov's avatar
Vladislav Rykov committed
329
    if 'name' in session:
Vladislav Rykov's avatar
Vladislav Rykov committed
330
        devs = dd.get_list(session['appkey'])
331
    
Vladislav Rykov's avatar
Vladislav Rykov committed
332
333
        for dev in devs[1]:
            data.delete_table(session['appkey'], dev[1])
334
    
Vladislav Rykov's avatar
Vladislav Rykov committed
335
        dd.delete_table(session['appkey'])
336
    
Vladislav Rykov's avatar
Vladislav Rykov committed
337
        res = ad.delete(session['appkey'])
338
    
Vladislav Rykov's avatar
Vladislav Rykov committed
339
        if not res[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
340
            return redirect(url_for('app_'))
Vladislav Rykov's avatar
Vladislav Rykov committed
341
342
        else:
            return redirect(url_for('index'))
343
344
    else:
        return redirect(url_for('index'))
345

Vladislav Rykov's avatar
Vladislav Rykov committed
346

Vladislav Rykov's avatar
Vladislav Rykov committed
347
@app.route('/add-dev')
Vladislav Rykov's avatar
Vladislav Rykov committed
348
def new_dev():
Vladislav Rykov's avatar
Vladislav Rykov committed
349
    if 'name' in session:
Vladislav Rykov's avatar
Vladislav Rykov committed
350
        dev_list = dd.get_list(session['appkey'])
Vladislav Rykov's avatar
Vladislav Rykov committed
351
    
Vladislav Rykov's avatar
Vladislav Rykov committed
352
        if not dev_list[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
353
            return render_template('old/public/add-dev.html', feedback=dev_list[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
354
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
355
            return render_template('old/public/add-dev.html', free_ids=misc.prep_id_range(dev_list[1]))
Vladislav Rykov's avatar
Vladislav Rykov committed
356
    else:
Vladislav Rykov's avatar
Vladislav Rykov committed
357
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
358
359
360
 


Vladislav Rykov's avatar
Vladislav Rykov committed
361
@app.route('/dev', methods=['GET', 'POST'])
Vladislav Rykov's avatar
Vladislav Rykov committed
362
def dev():
Vladislav Rykov's avatar
Vladislav Rykov committed
363
364
    if 'name' in session:
        if request.method == 'GET':
365
366
367
368
369
370
            ap = ad.get(session['appkey'])
            if session['role'] == 'admin' or session['name'] == ap[1][2]:
                dev = dd.get(session['appkey'], request.args.get('id'))

                session['devid'] = int(dev[1][1])
                session['devname'] = dev[1][0]
Vladislav Rykov's avatar
Vladislav Rykov committed
371
        
372
                last = data.get_last_n(session['appkey'], session['devid'], 1)
Vladislav Rykov's avatar
Vladislav Rykov committed
373
        
374
                ltup = 'Device have not sent data yet'
Vladislav Rykov's avatar
Vladislav Rykov committed
375

376
377
                if last[0]:
                    ltup = last[1][0][1]
378

Vladislav Rykov's avatar
Vladislav Rykov committed
379
                return render_template('old/public/dev.html', dev=dev[1], appkey=session['appkey'], ltup=ltup)
380
381
            else:
                return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
382
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
383
            res = dd.create(request.form['devname'], request.form['devid'], session['appkey'], request.form['devdesc'])
Vladislav Rykov's avatar
Vladislav Rykov committed
384

385
            if not res[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
386
                return render_template('old/public/add-dev.html', feedback=res[1])
387
            else:
Vladislav Rykov's avatar
Vladislav Rykov committed
388
389
390
                res = data.create_table(session['appkey'], request.form['devid'])
            
                if not res[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
391
                    dd.delete(session['appkey'], request.form['devid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
392
                    return render_template('old/public/add-dev.html', feedback=res[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
393
                else:
394
                    return redirect(url_for('app_', appkey=session['appkey']))
Vladislav Rykov's avatar
Vladislav Rykov committed
395
396
    else:
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
397
398


Vladislav Rykov's avatar
Vladislav Rykov committed
399
@app.route('/dev-conf', methods=['GET', 'POST'])
Vladislav Rykov's avatar
Vladislav Rykov committed
400
def dev_conf():
Vladislav Rykov's avatar
Vladislav Rykov committed
401
402
    if 'name' in session and 'devid' in session:
        if request.method == 'GET':
403
404
405
406
407
408
409
410
411
412
413
414
            pend_msgs = pend.get_list(session['appkey'], session['devid'])
            
            if pend_msgs[0]:
                config_list = []

                for pm in pend_msgs[1]:
                    cntt = binascii.a2b_base64(pm[2])
                    config_id = int(cntt[0])
                    config_args = cntt[2:(len(cntt)-1)].decode('utf-8')
                    ack = pm[3]
                    config_list.append((config_id, config_args, ack, pm[2]))

Vladislav Rykov's avatar
Vladislav Rykov committed
415
                return render_template('old/public/dev-conf.html', devname=session['devname'], config_list=config_list)
416
            else:
Vladislav Rykov's avatar
Vladislav Rykov committed
417
                return render_template('old/public/dev-conf.html', devname=session['devname'])
Vladislav Rykov's avatar
Vladislav Rykov committed
418
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
419
            base64_args = pend_base64_encode(request.form['arg'], request.form['confid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
420
            pend.create(session['appkey'], session['devid'], base64_args)
Vladislav Rykov's avatar
Vladislav Rykov committed
421

Vladislav Rykov's avatar
Vladislav Rykov committed
422
423
424
            return redirect(url_for('dev', id=session['devid']))
    else:
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
425

426
427
428
429
430
431
432
433
434
435
436
437
438
@app.route('/dev-conf-rm')
def dev_conf_rm():
    if 'name' in session and 'appkey' in session and 'devid' in session:
        res = pend.delete(session['appkey'], session['devid'], request.args.get('conf')+'_')

        if res[0]:
            flash('Configuration message successfully removed.','success')
            return redirect(url_for('dev_conf'))
        else:
            flash('Error removing configuration message: {}'.format(res[1]), 'danger')
            return redirect(url_for('dev_conf'))
    else:
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
439

Vladislav Rykov's avatar
Vladislav Rykov committed
440

Vladislav Rykov's avatar
Vladislav Rykov committed
441
@app.route('/delete-dev')
Vladislav Rykov's avatar
Vladislav Rykov committed
442
def delete_dev():
Vladislav Rykov's avatar
Vladislav Rykov committed
443
444
    if 'name' in session and 'devid' in session:
        data.delete_table(session['appkey'], session['devid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
445
        res = dd.delete(session['appkey'], session['devid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
446

Vladislav Rykov's avatar
Vladislav Rykov committed
447
        return redirect(url_for('app_', appkey=session['appkey']))
Vladislav Rykov's avatar
Vladislav Rykov committed
448
449
    else:
        return redirect(utl_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
450
451


Vladislav Rykov's avatar
Vladislav Rykov committed
452
@app.route('/dev-data')
453
454
455
456
457
458
459
460
461
462
def dev_data_pg():
    if 'name' in session and 'devid' in session:
        cur_pg = 1
        if request.args.get('p'):
            cur_pg = int(request.args.get('p'))
            if cur_pg < 1:
                cur_pg = 1
        
        last = data.get_last_range(session['appkey'], session['devid'], [MAX_PG_ENTRIES_DATA, (cur_pg-1)*MAX_PG_ENTRIES_DATA])
        
Vladislav Rykov's avatar
Vladislav Rykov committed
463
464
465
466
        ent_cnt = data.get_count(session['appkey'], session['devid'])
        if ent_cnt[0]:
            # range data
            rd = misc.paging(cur_pg, ent_cnt[1][0], MAX_PG_ENTRIES_DATA, MAX_PG)
467

Vladislav Rykov's avatar
Vladislav Rykov committed
468
            if ent_cnt[1][0] > 0:
Vladislav Rykov's avatar
Vladislav Rykov committed
469
                return render_template('old/public/dev-data-t.html', data=last[1], total=ent_cnt[1][0], cp=cur_pg, np=rd[2], pp=rd[0], pr=rd[1], devname=session['devname'])
Vladislav Rykov's avatar
Vladislav Rykov committed
470
            else:
Vladislav Rykov's avatar
Vladislav Rykov committed
471
                return render_template('old/public/dev-data-t.html', devname=session['devname'])
472
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
473
            flash('Error: {}'.format(ent_cnt[1]), 'danger')
Vladislav Rykov's avatar
Vladislav Rykov committed
474
            return render_template('old/public/dev-data-t.html', devname=session['devname'])
475
476
477
478
    else:
        return redirect(utl_for('index'))


Vladislav Rykov's avatar
Vladislav Rykov committed
479
480
481
482
483
@app.route('/dev-vars')
def dev_vars():
    if 'name' in session:
        last = data.get_last_n(session['appkey'], request.args.get('id'), 1)
        if last[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
484
            select = '<select class="form-control notifelem" id="varname" name="varname" onchange="onvar(event)" required>'
Vladislav Rykov's avatar
Vladislav Rykov committed
485
486
487
488
489
490
491
492
            select += '<option value="-">Select Variable</option>'
            for k in last[1][0][2]:
                select += '<option>'+k+'</option>'
            select += '</select>'
            return select
    else:
        return redirect(url_for('index'))

493

Vladislav Rykov's avatar
Vladislav Rykov committed
494
@app.route('/data-csv')
Vladislav Rykov's avatar
Vladislav Rykov committed
495
def data_csv():
Vladislav Rykov's avatar
Vladislav Rykov committed
496
497
    if 'name' in session and 'devid' in session:
        dumpd = data.get_all(session['appkey'], session['devid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
498

Vladislav Rykov's avatar
Vladislav Rykov committed
499
        fn = session['appkey']+ '_' +str(session['devid'])+ '.csv'
Vladislav Rykov's avatar
Vladislav Rykov committed
500

501
        with open(app.config['DATA_DOWNLOAD_DIR_OS']+'/'+fn, 'w+') as f: 
Vladislav Rykov's avatar
Vladislav Rykov committed
502
            f.write('utc,timestamp,')
Vladislav Rykov's avatar
Vladislav Rykov committed
503
504
            for d in dumpd[1][0][2]:
                f.write(d)
Vladislav Rykov's avatar
Vladislav Rykov committed
505
506
                f.write(',')
            f.write('\n')
Vladislav Rykov's avatar
Vladislav Rykov committed
507
508
        
            for row in dumpd[1]:
Vladislav Rykov's avatar
Vladislav Rykov committed
509
                f.write('{},{},'.format(row[0],row[1]))
Vladislav Rykov's avatar
Vladislav Rykov committed
510
511
512
513
                for v in row[2]:
                    f.write(str(row[2][v]))
                    f.write(',')
                f.write('\n')
Vladislav Rykov's avatar
Vladislav Rykov committed
514
    
Vladislav Rykov's avatar
Vladislav Rykov committed
515
        return send_from_directory(app.config['DATA_DOWNLOAD_DIR'], fn, as_attachment=True)
Vladislav Rykov's avatar
Vladislav Rykov committed
516
517
    else:
        return redirect(utl_for('index'))
518
519


Vladislav Rykov's avatar
Vladislav Rykov committed
520
521
@app.route('/administration', methods=['GET', 'POST'])
def administration():
Vladislav Rykov's avatar
Vladislav Rykov committed
522
523
524
525
526
527
528
529
530
531
532
    if 'role' in session and session['role'] == 'admin':
        user_cnt = ud.get_count()
        apps_cnt = ad.get_count()
        devs_cnt = dd.get_count_all()

        cur_pg = 1
        if request.args.get('p'):
            cur_pg = int(request.args.get('p'))
            if cur_pg < 1:
                cur_pg = 1

Vladislav Rykov's avatar
Vladislav Rykov committed
533
        users = None
Vladislav Rykov's avatar
Vladislav Rykov committed
534
        
Vladislav Rykov's avatar
Vladislav Rykov committed
535
536
        if request.method == 'POST':
            session['users_filter'] = request.form['username']
Vladislav Rykov's avatar
Vladislav Rykov committed
537
            
Vladislav Rykov's avatar
Vladislav Rykov committed
538
539
540
        if 'users_filter' in session:
            users = ud.get_range_name(session['users_filter'], [MAX_PG_ENTRIES_USERS, (cur_pg-1)*MAX_PG_ENTRIES_USERS])
            rd = misc.paging(cur_pg, len(users[1]), MAX_PG_ENTRIES_USERS, MAX_PG)
Vladislav Rykov's avatar
Vladislav Rykov committed
541
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
542
543
544
            users = ud.get_range([MAX_PG_ENTRIES_USERS, (cur_pg-1)*MAX_PG_ENTRIES_USERS])
            rd = misc.paging(cur_pg, user_cnt[1][0], MAX_PG_ENTRIES_USERS, MAX_PG)
        
Vladislav Rykov's avatar
Vladislav Rykov committed
545
        return render_template('old/admin/dashboard.html', users_cnt=user_cnt[1][0], apps_cnt=apps_cnt[1][0], dev_cnt=devs_cnt, users=users[1], pp=rd[0], pr=rd[1], np=rd[2], cp=cur_pg, usn=(cur_pg-1)*MAX_PG_ENTRIES_USERS+1)
Vladislav Rykov's avatar
Vladislav Rykov committed
546
547
548
    else:
        return redirect(url_for('index'))

Vladislav Rykov's avatar
Vladislav Rykov committed
549
550
551
552
553

@app.route('/dashboard-clean-search')
def dashboard_clean_search():
    if 'users_filter' in session:
        session.pop('users_filter', None)
Vladislav Rykov's avatar
Vladislav Rykov committed
554
    return redirect(url_for('administration'))
Vladislav Rykov's avatar
Vladislav Rykov committed
555

556
557
558
559
560
561
562
563
564

@app.route('/user')
def user():
    if 'role' in session and session['role'] == 'admin':
        name = request.args.get('name')
        apps = ad.get_list(name)
        
        session.pop('appkey', None)
        if apps[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
565
            return render_template('old/admin/user.html', apps=apps[1], username=name)
566
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
567
            return render_template('old/admin/user.html', feedback=apps[1], username=name)
568
    else:
Vladislav Rykov's avatar
Vladislav Rykov committed
569
        return render_template('old/public/index.html')
570
571
572
573
574


@app.route('/user-delete')
def user_delete():
    user = ud.get(request.args.get('name'))
Vladislav Rykov's avatar
Vladislav Rykov committed
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
    if user[0] and user[1][2] != 'admin' and session['role'] == 'admin':
        app_list = ad.get_list(user[1][0])

        res = (True,)
        if app_list[0]:
            for app in app_list[1]:
                devs = dd.get_list(app[1])
                for dev in devs[1]:
                    res = data.delete_table(app[1], dev[1])
                    if not res[0]:
                        break
    
                if res[0]:
                    res = dd.delete_table(app[1])
                    
                if res[0]:
                    res = ad.delete(app[1])

                if not res[0]:
                    break

        if res[0]:
            res = ud.delete(user[1][0])

        if not res[0]:
            flash('Error: {}'.format(res[1]), 'danger')
Vladislav Rykov's avatar
Vladislav Rykov committed
601
            return render_template('old/admin/user.html', username=user[1][0])
Vladislav Rykov's avatar
Vladislav Rykov committed
602
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
603
                return redirect(url_for('administraion'))
Vladislav Rykov's avatar
Vladislav Rykov committed
604
605
606
    else:
        flash('Warning: the user is admin or does not exist.' ,'warning')
        return redirect(url_for('index'))
607

Vladislav Rykov's avatar
Vladislav Rykov committed
608

609
610
611
612
@app.route('/settings', methods=['GET', 'POST'])
def settings():
    if request.method == 'GET':
        if session['role'] == 'admin':
Vladislav Rykov's avatar
Vladislav Rykov committed
613
            return render_template('old/admin/settings.html', username=session['name'], users_signup=app.config['USERS_SIGNUP'])
614
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
615
            return render_template('old/public/settings.html', username=session['name'])
616
617
618
619
620
621
622
623
624
625
626
627
    else:
        if request.form['name'] != session['name']:
            res = ud.update_name(session['name'], request.form['name'])
            if not res[0]:
                flash('Error: {}'.format(res[1]), 'danger')
                return redirect(request.url);
            else:
                session['name'] = request.form['name']
        if request.form['password'] != '':
            res = ud.update_password(session['name'], request.form['password'].encode('utf-8'))
            if not res[0]:
                flash('Error: {}'.format(res[1]), 'danger')
628
629
630
631
632
633
                return redirect(request.url)
        if session['role'] == 'admin':
            if request.form.getlist('users_signup') and request.form.getlist('users_signup')[0] == 'us':
                app.config['USERS_SIGNUP'] = True
            else:
                app.config['USERS_SIGNUP'] = False
634
635


636
        return redirect(request.url)
637
638


639
640
@app.route('/dev-data/<var>/<dest>/<page>')
def dev_data(var, dest, page):
641
    if dest == 'graph':
642
        last = data.get_last_hours(session['appkey'], session['devid'], MAX_PG_ENTRIES_GRAPH_HOURS, int(page))
643
644
645
646
647
648
649
650
        arr = '[["Time", "{}"],'.format(var)
        if last[0]:
            for d in last[1]:
                arr += '[new Date('+str(d[0])+'*1000),'+str(d[2][var])+'],'
            arr += ']'
        return arr
    elif dest == 'table':
        # for table <cnt> is in items
651
        last = data.get_last_range(session['appkey'], session['devid'], [MAX_PG_ENTRIES_DATA, (int(page)-1)*MAX_PG_ENTRIES_DATA])
652
653
654
655
656
657
658
        #t = """ <thead>
        #            <th>Time</th>
        #            <th>{}</th>
        #        </thead>
        #        <tbody>
        #""".format(var)
        t = ''
659
660
661
        if last[0]:
            for d in last[1]:
                t += '<tr><th>'+d[1]+'</th><th>'+str(d[2][var])+'</th></tr>'
662
        #t += '</tbody>'
663
        return t
664
665


Vladislav Rykov's avatar
Vladislav Rykov committed
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
@app.route('/application/<appkey>/device/<devid>/data/<var>/<dest>/<page>')
def new_dev_data(appkey, devid, var, dest, page):
    if dest == 'graph':
        last = data.get_last_hours(appkey, devid, MAX_PG_ENTRIES_GRAPH_HOURS, int(page))
        arr = '[["Time", "{}"],'.format(var)
        if last[0]:
            for d in last[1]:
                arr += '[new Date('+str(d[0])+'*1000),'+str(d[2][var])+'],'
            arr += ']'
        return arr
    elif dest == 'table':
        # for table <cnt> is in items
        last = data.get_last_range(appkey, devid, [MAX_PG_ENTRIES_DATA, (int(page)-1)*MAX_PG_ENTRIES_DATA])
        t = ''
        if last[0]:
            for d in last[1]:
                t += '<tr><th>'+d[1]+'</th><th>'+str(d[2][var])+'</th></tr>'
        return t


Vladislav Rykov's avatar
Vladislav Rykov committed
686
687
688
@app.route('/alerts')
def alerts():
    if 'name' in session:
689
        alerts = nfs.get_alerts_list(session['appkey'])
Vladislav Rykov's avatar
Vladislav Rykov committed
690
        return render_template('old/public/alerts.html', alert_list=alerts[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
691
692
693
694
695
696
697
    else:
        return redirect(url_for('index'))

@app.route('/new-alert')
def new_alert():
    if 'name' in session:
        devs = dd.get_list(session['appkey'])
Vladislav Rykov's avatar
Vladislav Rykov committed
698
        return render_template('old/public/new-alert.html', devs=devs[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
699
700
701
702
703
704
    else:
        return redirect(url_for('index'))


@app.route('/alert', methods=['POST'])
def alert():
705
706
707
708
709
    if 'name' in session:
        if request.method == 'POST':
            # create new notification
            nid = misc.rand_str(app.config['NID_LENGTH']).decode('utf-8')
            dev = dd.get(session['appkey'], request.form['devid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
            
            try:
                desc = dev[1][0]+'.'+request.form['varname']+' '+request.form['operation']+' '+request.form['avalue']
                res = nfs.create(nid, session['appkey'], request.form['devid'], request.form['alertname'], desc, 'alert', request.form['alertemail'])
                if res[0]:
                    # create new function and trigger
                    tr.create_function(session['appkey'], request.form['devid'], nid, [request.form['varname'],request.form['operation'],request.form['avalue']])
                    tr.create(session['appkey'], request.form['devid'], nid)
                    return redirect(url_for('alerts'))
                else:
                    flash('Error creating new alert: {}'.format(res[1]), 'danger')
                    return redirect(url_for('alerts'))
            except Exception as e:
                flash('Error creating new alert: {}. Make sure you have filled all form fields.'.format(e), 'danger')
                return redirect(url_for('new_alert'))
725
726
727
728
        else:
            return redirect(url_for('index'))
    else:
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
729
730
731
732

@app.route('/alert-rm')
def alarm_rm():
    if 'name' in session:
Vladislav Rykov's avatar
Vladislav Rykov committed
733
        nq.delete(session['appkey'], request.args.get('devid'), request.args.get('id'))
Vladislav Rykov's avatar
Vladislav Rykov committed
734
735
        tr.delete(session['appkey'], request.args.get('devid'), request.args.get('id'))
        tr.delete_function(session['appkey'], request.args.get('devid'), request.args.get('id'))
736
        res = nfs.delete(session['appkey'], request.args.get('devid'), request.args.get('id'))
Vladislav Rykov's avatar
Vladislav Rykov committed
737
738

        if res[0]:
739
            flash('Alert removed', 'success')
Vladislav Rykov's avatar
Vladislav Rykov committed
740
741
            return redirect(url_for('alerts'))
        else:
742
            flash('Alert cannot be removed : {}'.format(res[1]), 'danger')
Vladislav Rykov's avatar
Vladislav Rykov committed
743
            return redirect(url_for('alerts'))
Vladislav Rykov's avatar
Vladislav Rykov committed
744
745
746
    else:
        return redirect(url_for('index'))

747
748
749
750
751
752

@app.route('/automation', methods=['GET','POST'])
def automation():
    if 'name' in session:
        if request.method == 'GET':
            auto = nfs.get_automation_list(session['appkey'])
Vladislav Rykov's avatar
Vladislav Rykov committed
753
            return render_template('old/public/automation.html', auto_list=auto[1])
754
755
        elif request.method == 'POST':
            # new automation
Vladislav Rykov's avatar
Vladislav Rykov committed
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
            nid = misc.rand_str(app.config['NID_LENGTH']).decode('utf-8')
            dev = dd.get(session['appkey'], request.form['devid'])
            adev = dd.get(session['appkey'], request.form['adevid'])
            try:
                desc = 'IF '+dev[1][0]+'.'+request.form['varname']+' '+request.form['operation']+' '+request.form['avalue']+' THEN '+adev[1][0]+'.confID_'+request.form['confid']+' = '+request.form['arg']
                # action format: '<devid>#<confid>#<arg>'
                action = request.form['adevid']+'#'+request.form['confid']+'#'+request.form['arg']
                res = nfs.create(nid, session['appkey'], request.form['devid'], request.form['automationname'], desc, 'automation', action)
                if res[0]:
                    # create new function and trigger
                    tr.create_function(session['appkey'], request.form['devid'], nid, [request.form['varname'],request.form['operation'],request.form['avalue']])
                    tr.create(session['appkey'], request.form['devid'], nid)
                    return redirect(url_for('automation'))
                else:
                    flash('Error creating new alert: {}'.format(res[1]), 'danger')
                    return redirect(url_for('automation'))
            
                return redirect(url_for('autmation'))
            except Exception as e:
                flash('Error creating new automation: {}. Make sure you have filled all form fields correctly.'.format(e), 'danger')
                return redirect(url_for('automation'))

778
779
780
781
782
783
784
785
    else:
        return redirect(url_for('index'))


@app.route('/new-automation')
def new_automation():
    if 'name' in session:
        devs = dd.get_list(session['appkey'])
Vladislav Rykov's avatar
Vladislav Rykov committed
786
        return render_template('old/public/new-automation.html', devs=devs[1])
787
788
789
790
    else:
        return redirect(url_for('index'))


Vladislav Rykov's avatar
Vladislav Rykov committed
791
@app.route('/automation-rm')
Vladislav Rykov's avatar
Vladislav Rykov committed
792
def automation_rm():
Vladislav Rykov's avatar
Vladislav Rykov committed
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
    if 'name' in session:
        nq.delete(session['appkey'], request.args.get('devid'), request.args.get('id'))
        tr.delete(session['appkey'], request.args.get('devid'), request.args.get('id'))
        tr.delete_function(session['appkey'], request.args.get('devid'), request.args.get('id'))
        res = nfs.delete(session['appkey'], request.args.get('devid'), request.args.get('id'))

        if res[0]:
            flash('Automation removed', 'success')
            return redirect(url_for('alerts'))
        else:
            flash('Automation cannot be removed : {}'.format(res[1]), 'danger')
            return redirect(url_for('alerts'))
    else:
        return redirect(url_for('index'))




811
812
def pend_delete_all_ack():
    pend.delete_all_ack()
Vladislav Rykov's avatar
Vladislav Rykov committed
813

814
815
816
817
818
819
820
821
822
def fire_notifications(app):
    fnfs = nq.get_all()
    if fnfs[0]:
        for fnf in fnfs[1]:
            nf = nfs.get(fnf[1], fnf[2], fnf[0])
            if nf[1][5] == 'alert':
                # send mail
                mailer.send_mail(app, nf[1], fnf)
            elif nf[1][5] == 'automation':
Vladislav Rykov's avatar
Vladislav Rykov committed
823
824
825
826
827
828
                # enqueue confid
                # action format: '<devid>#<confid>#<arg>'
                action = nf[1][6].split('#')
                base64_args = misc.pend_base64_encode(action[2], action[1])
                pend.create(nf[1][1], action[0], base64_args)
            nq.delete(fnf[1], fnf[2], fnf[0])