views.py 22.9 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

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

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

22

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

Vladislav Rykov's avatar
Vladislav Rykov committed
28
@app.route('/')
29
def index():
Vladislav Rykov's avatar
Vladislav Rykov committed
30
    if 'name' in session and len(session['name']) > 0:
Vladislav Rykov's avatar
Vladislav Rykov committed
31
32
        apps = ad.get_list(session['name'])
        
Vladislav Rykov's avatar
Vladislav Rykov committed
33
        session.pop('appkey', None)
34
        if apps[0]:
35
            return render_template('public/index.html', apps=apps[1], users_signup=app.config['USERS_SIGNUP'])
36
        else:
37
            return render_template('public/index.html', feedback=apps[1], users_signup=app.config['USERS_SIGNUP'])
Vladislav Rykov's avatar
Vladislav Rykov committed
38
    else:
39
        return render_template('public/index.html', users_signup=app.config['USERS_SIGNUP'])
40
41
42



Vladislav Rykov's avatar
Vladislav Rykov committed
43
@app.route('/signup', methods=['GET', 'POST'])
44
45
def signup():
    if request.method == 'GET':
Vladislav Rykov's avatar
Vladislav Rykov committed
46
        if session['role'] and session['role'] == 'admin':
47
            return render_template('admin/signup.html', users_signup=app.config['USERS_SIGNUP'])
Vladislav Rykov's avatar
Vladislav Rykov committed
48
        else:
49
            if app.config['USERS_SIGNUP']:
50
                return render_template('public/signup.html', users_signup=app.config['USERS_SIGNUP'])
51
            else:
52
                return redirect(url_for('index', users_signup=app.config['USERS_SIGNUP']))
53
54
55
56
57
58
59
    else:
        if app.config['USERS_SIGNUP'] or session['role'] == 'admin':
            username = request.form['username']
            password = request.form['password'].encode('utf-8')
            
            if (username == '' or password == ''):
                feedback = 'Username or password fields cannot be empty'
60
                return render_template('public/signup.html', feedback=feedback, users_signup=app.config['USERS_SIGNUP'])
61
62
            elif (len(password) < 8):
                flash('Password length must be at least 8 characters.', 'danger')
63
                return redirect(request.url, users_signup=app.config['USERS_SIGNUP'])
Vladislav Rykov's avatar
Vladislav Rykov committed
64
            else:
65
66
67
68
69
70
71
72
                role = 'user'
                if request.form['role'] and request.form['role'] == 'administrator':
                    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
73
                else:
74
75
76
                    session['name'] = username
                    
                    flash('User successfully created.', 'success')
77

78
79
80
81
82
83
                    if session['role'] and session['role'] == 'admin':
                        return redirect(url_for('dashboard'))
                    else:
                        return redirect(url_for('index'))
        else:
            return redirect(url_for('index'))
84
85


Vladislav Rykov's avatar
Vladislav Rykov committed
86
@app.route('/login', methods=['GET', 'POST'])
Vladislav Rykov's avatar
Vladislav Rykov committed
87
def login():
Vladislav Rykov's avatar
Vladislav Rykov committed
88
    if request.method == 'GET':
Vladislav Rykov's avatar
Vladislav Rykov committed
89
        return render_template('public/login.html')
Vladislav Rykov's avatar
Vladislav Rykov committed
90
91
    else: 
        username = request.form['username']
Vladislav Rykov's avatar
Vladislav Rykov committed
92
        password = request.form['password'].encode('utf-8')
Vladislav Rykov's avatar
Vladislav Rykov committed
93
94

        if (username == '' or password == ''):
Vladislav Rykov's avatar
Vladislav Rykov committed
95
96
            flash('Username or password fields cannot be empty', 'danger')
            return redirect(request.url)
Vladislav Rykov's avatar
Vladislav Rykov committed
97
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
98
            res = ud.check(username, password)
Vladislav Rykov's avatar
Vladislav Rykov committed
99
            if (not res[0]):
Vladislav Rykov's avatar
Vladislav Rykov committed
100
101
                flash('Error: {}'.format(res[1]), 'danger')
                return redirect(request.url)
Vladislav Rykov's avatar
Vladislav Rykov committed
102
103
            else:
                session['name'] = username
104
                session['role'] = res[1][2]
Vladislav Rykov's avatar
Vladislav Rykov committed
105
        
Vladislav Rykov's avatar
Vladislav Rykov committed
106
107
108
                return redirect(url_for('index'))


109

Vladislav Rykov's avatar
Vladislav Rykov committed
110
@app.route('/logout')
Vladislav Rykov's avatar
Vladislav Rykov committed
111
112
113
def logout():
    session.clear()
    return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
114
115


116

Vladislav Rykov's avatar
Vladislav Rykov committed
117
@app.route('/new-app')
118
def new_application():
Vladislav Rykov's avatar
Vladislav Rykov committed
119
    if 'name' in session:
Vladislav Rykov's avatar
Vladislav Rykov committed
120
        return render_template('public/new-app.html')
Vladislav Rykov's avatar
Vladislav Rykov committed
121
122
    else:
        return redirect(url_for('index'))
123
124
125



Vladislav Rykov's avatar
Vladislav Rykov committed
126
127
@app.route('/app', methods=['GET', 'POST'])
def app_():
Vladislav Rykov's avatar
Vladislav Rykov committed
128
129
130
    if 'name' in session:
        if request.method == 'GET':
            session['appkey'] = request.args.get('appkey')
Vladislav Rykov's avatar
Vladislav Rykov committed
131

Vladislav Rykov's avatar
Vladislav Rykov committed
132
133
            ap = ad.get(session['appkey'])
            devs = dd.get_list(ap[1][1])
134
135

            session['appname'] = ap[1][0]
136
137
138
139
140
            
            if session['role'] == 'admin' or session['name'] == ap[1][2]:
                return render_template('public/app.html', app=ap[1], devs=devs[1])
            else:
                return redirect(url_for('index'))
141
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
142
143
            if request.form['appname'] == '':
                error = 'Application name cannot be empty.'
Vladislav Rykov's avatar
Vladislav Rykov committed
144
                return render_template('public/new-app.html', feedback=error)
Vladislav Rykov's avatar
Vladislav Rykov committed
145
            else:
Vladislav Rykov's avatar
Vladislav Rykov committed
146
                appkey = misc.rand_str(app.config['APPKEY_LENGTH']).decode('utf-8')
Vladislav Rykov's avatar
Vladislav Rykov committed
147
                res = ad.create(request.form['appname'], appkey, session['name'], request.form['appdesc'])
Vladislav Rykov's avatar
Vladislav Rykov committed
148
            
Vladislav Rykov's avatar
Vladislav Rykov committed
149
                if not res[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
150
                    return render_template('public/new-app.html', feedback=res[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
151
            
Vladislav Rykov's avatar
Vladislav Rykov committed
152
                res = dd.create_table(appkey)
153
            
Vladislav Rykov's avatar
Vladislav Rykov committed
154
                if not res[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
155
                    ad.delete(appkey)
Vladislav Rykov's avatar
Vladislav Rykov committed
156
                    return render_template('public/new-app.html', feedback=res[1])
157
            
Vladislav Rykov's avatar
Vladislav Rykov committed
158
159
160
                return redirect(url_for('index'))
    else:
        return redirect(url_for('index'))
161

Vladislav Rykov's avatar
Vladislav Rykov committed
162
@app.route('/delete-app')
163
def delete_app():
Vladislav Rykov's avatar
Vladislav Rykov committed
164
    if 'name' in session:
Vladislav Rykov's avatar
Vladislav Rykov committed
165
        devs = dd.get_list(session['appkey'])
166
    
Vladislav Rykov's avatar
Vladislav Rykov committed
167
168
        for dev in devs[1]:
            data.delete_table(session['appkey'], dev[1])
169
    
Vladislav Rykov's avatar
Vladislav Rykov committed
170
        dd.delete_table(session['appkey'])
171
    
Vladislav Rykov's avatar
Vladislav Rykov committed
172
        res = ad.delete(session['appkey'])
173
    
Vladislav Rykov's avatar
Vladislav Rykov committed
174
        if not res[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
175
            return redirect(url_for('app_'))
Vladislav Rykov's avatar
Vladislav Rykov committed
176
177
        else:
            return redirect(url_for('index'))
178
179
    else:
        return redirect(url_for('index'))
180

Vladislav Rykov's avatar
Vladislav Rykov committed
181

Vladislav Rykov's avatar
Vladislav Rykov committed
182
@app.route('/add-dev')
Vladislav Rykov's avatar
Vladislav Rykov committed
183
def new_dev():
Vladislav Rykov's avatar
Vladislav Rykov committed
184
    if 'name' in session:
Vladislav Rykov's avatar
Vladislav Rykov committed
185
        dev_list = dd.get_list(session['appkey'])
Vladislav Rykov's avatar
Vladislav Rykov committed
186
    
Vladislav Rykov's avatar
Vladislav Rykov committed
187
        if not dev_list[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
188
            return render_template('public/add-dev.html', feedback=dev_list[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
189
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
190
            return render_template('public/add-dev.html', free_ids=misc.prep_id_range(dev_list[1]))
Vladislav Rykov's avatar
Vladislav Rykov committed
191
    else:
Vladislav Rykov's avatar
Vladislav Rykov committed
192
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
193
194
195
 


Vladislav Rykov's avatar
Vladislav Rykov committed
196
@app.route('/dev', methods=['GET', 'POST'])
Vladislav Rykov's avatar
Vladislav Rykov committed
197
def dev():
Vladislav Rykov's avatar
Vladislav Rykov committed
198
199
    if 'name' in session:
        if request.method == 'GET':
200
201
202
203
204
205
            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
206
        
207
                last = data.get_last_n(session['appkey'], session['devid'], 1)
Vladislav Rykov's avatar
Vladislav Rykov committed
208
        
209
                ltup = 'Device have not sent data yet'
Vladislav Rykov's avatar
Vladislav Rykov committed
210

211
212
                if last[0]:
                    ltup = last[1][0][1]
213

214
215
216
                return render_template('public/dev.html', dev=dev[1], appkey=session['appkey'], ltup=ltup)
            else:
                return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
217
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
218
            res = dd.create(request.form['devname'], request.form['devid'], session['appkey'], request.form['devdesc'])
Vladislav Rykov's avatar
Vladislav Rykov committed
219

220
            if not res[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
221
                return render_template('public/add-dev.html', feedback=res[1])
222
            else:
Vladislav Rykov's avatar
Vladislav Rykov committed
223
224
225
                res = data.create_table(session['appkey'], request.form['devid'])
            
                if not res[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
226
                    dd.delete(session['appkey'], request.form['devid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
227
                    return render_template('public/add-dev.html', feedback=res[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
228
                else:
229
                    return redirect(url_for('app_', appkey=session['appkey']))
Vladislav Rykov's avatar
Vladislav Rykov committed
230
231
    else:
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
232
233


Vladislav Rykov's avatar
Vladislav Rykov committed
234
@app.route('/dev-conf', methods=['GET', 'POST'])
Vladislav Rykov's avatar
Vladislav Rykov committed
235
def dev_conf():
Vladislav Rykov's avatar
Vladislav Rykov committed
236
237
    if 'name' in session and 'devid' in session:
        if request.method == 'GET':
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
            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]))

                return render_template('public/dev-conf.html', devname=session['devname'], config_list=config_list)
            else:
                return render_template('public/dev-conf.html', devname=session['devname'])
Vladislav Rykov's avatar
Vladislav Rykov committed
253
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
254
            base64_args = pend_base64_encode(request.form['arg'], request.form['confid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
255
            pend.create(session['appkey'], session['devid'], base64_args)
Vladislav Rykov's avatar
Vladislav Rykov committed
256

Vladislav Rykov's avatar
Vladislav Rykov committed
257
258
259
            return redirect(url_for('dev', id=session['devid']))
    else:
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
260

261
262
263
264
265
266
267
268
269
270
271
272
273
@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
274

Vladislav Rykov's avatar
Vladislav Rykov committed
275

Vladislav Rykov's avatar
Vladislav Rykov committed
276
@app.route('/delete-dev')
Vladislav Rykov's avatar
Vladislav Rykov committed
277
def delete_dev():
Vladislav Rykov's avatar
Vladislav Rykov committed
278
279
    if 'name' in session and 'devid' in session:
        data.delete_table(session['appkey'], session['devid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
280
        res = dd.delete(session['appkey'], session['devid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
281

Vladislav Rykov's avatar
Vladislav Rykov committed
282
        return redirect(url_for('app_', appkey=session['appkey']))
Vladislav Rykov's avatar
Vladislav Rykov committed
283
284
    else:
        return redirect(utl_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
285
286


Vladislav Rykov's avatar
Vladislav Rykov committed
287
@app.route('/dev-data')
288
289
290
291
292
293
294
295
296
297
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
298
299
300
301
        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)
302

Vladislav Rykov's avatar
Vladislav Rykov committed
303
            if ent_cnt[1][0] > 0:
Vladislav Rykov's avatar
Vladislav Rykov committed
304
                return render_template('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
305
            else:
Vladislav Rykov's avatar
Vladislav Rykov committed
306
                return render_template('public/dev-data-t.html', devname=session['devname'])
307
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
308
            flash('Error: {}'.format(ent_cnt[1]), 'danger')
Vladislav Rykov's avatar
Vladislav Rykov committed
309
            return render_template('public/dev-data-t.html', devname=session['devname'])
310
311
312
313
    else:
        return redirect(utl_for('index'))


Vladislav Rykov's avatar
Vladislav Rykov committed
314
315
316
317
318
@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
319
            select = '<select class="form-control notifelem" id="varname" name="varname" onchange="onvar(event)" required>'
Vladislav Rykov's avatar
Vladislav Rykov committed
320
321
322
323
324
325
326
327
            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'))

328

Vladislav Rykov's avatar
Vladislav Rykov committed
329
@app.route('/data-csv')
Vladislav Rykov's avatar
Vladislav Rykov committed
330
def data_csv():
Vladislav Rykov's avatar
Vladislav Rykov committed
331
332
    if 'name' in session and 'devid' in session:
        dumpd = data.get_all(session['appkey'], session['devid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
333

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

336
        with open(app.config['DATA_DOWNLOAD_DIR_OS']+'/'+fn, 'w+') as f: 
Vladislav Rykov's avatar
Vladislav Rykov committed
337
            f.write('utc,timestamp,')
Vladislav Rykov's avatar
Vladislav Rykov committed
338
339
            for d in dumpd[1][0][2]:
                f.write(d)
Vladislav Rykov's avatar
Vladislav Rykov committed
340
341
                f.write(',')
            f.write('\n')
Vladislav Rykov's avatar
Vladislav Rykov committed
342
343
        
            for row in dumpd[1]:
Vladislav Rykov's avatar
Vladislav Rykov committed
344
                f.write('{},{},'.format(row[0],row[1]))
Vladislav Rykov's avatar
Vladislav Rykov committed
345
346
347
348
                for v in row[2]:
                    f.write(str(row[2][v]))
                    f.write(',')
                f.write('\n')
Vladislav Rykov's avatar
Vladislav Rykov committed
349
    
Vladislav Rykov's avatar
Vladislav Rykov committed
350
        return send_from_directory(app.config['DATA_DOWNLOAD_DIR'], fn, as_attachment=True)
Vladislav Rykov's avatar
Vladislav Rykov committed
351
352
    else:
        return redirect(utl_for('index'))
353
354


Vladislav Rykov's avatar
Vladislav Rykov committed
355
356
357
358
359
360
361
362
363
364
365
366
367
@app.route('/dashboard', methods=['GET', 'POST'])
def dashboard():
    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
368
        users = None
Vladislav Rykov's avatar
Vladislav Rykov committed
369
        
Vladislav Rykov's avatar
Vladislav Rykov committed
370
371
        if request.method == 'POST':
            session['users_filter'] = request.form['username']
Vladislav Rykov's avatar
Vladislav Rykov committed
372
            
Vladislav Rykov's avatar
Vladislav Rykov committed
373
374
375
        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
376
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
377
378
379
380
            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)
        
        return render_template('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
381
382
383
    else:
        return redirect(url_for('index'))

Vladislav Rykov's avatar
Vladislav Rykov committed
384
385
386
387
388
389
390

@app.route('/dashboard-clean-search')
def dashboard_clean_search():
    if 'users_filter' in session:
        session.pop('users_filter', None)
    return redirect(url_for('dashboard'))

391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409

@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]:
            return render_template('admin/user.html', apps=apps[1], username=name)
        else:
            return render_template('admin/user.html', feedback=apps[1], username=name)
    else:
        return render_template('public/index.html')


@app.route('/user-delete')
def user_delete():
    user = ud.get(request.args.get('name'))
Vladislav Rykov's avatar
Vladislav Rykov committed
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
    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')
            return render_template('admin/user.html', username=user[1][0])
        else:
                return redirect(url_for('dashboard'))
    else:
        flash('Warning: the user is admin or does not exist.' ,'warning')
        return redirect(url_for('index'))
442

Vladislav Rykov's avatar
Vladislav Rykov committed
443

444
445
446
447
@app.route('/settings', methods=['GET', 'POST'])
def settings():
    if request.method == 'GET':
        if session['role'] == 'admin':
448
            return render_template('admin/settings.html', username=session['name'], users_signup=app.config['USERS_SIGNUP'])
449
450
451
452
453
454
455
456
457
458
459
460
461
462
        else:
            return render_template('public/settings.html', username=session['name'])
    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')
463
464
465
466
467
468
                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
469
470


471
        return redirect(request.url)
472
473


474
475
@app.route('/dev-data/<var>/<dest>/<page>')
def dev_data(var, dest, page):
476
    if dest == 'graph':
477
        last = data.get_last_hours(session['appkey'], session['devid'], MAX_PG_ENTRIES_GRAPH_HOURS, int(page))
478
479
480
481
482
483
484
485
        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
486
        last = data.get_last_range(session['appkey'], session['devid'], [MAX_PG_ENTRIES_DATA, (int(page)-1)*MAX_PG_ENTRIES_DATA])
487
488
489
490
491
492
493
        #t = """ <thead>
        #            <th>Time</th>
        #            <th>{}</th>
        #        </thead>
        #        <tbody>
        #""".format(var)
        t = ''
494
495
496
        if last[0]:
            for d in last[1]:
                t += '<tr><th>'+d[1]+'</th><th>'+str(d[2][var])+'</th></tr>'
497
        #t += '</tbody>'
498
        return t
499
500


Vladislav Rykov's avatar
Vladislav Rykov committed
501
502
503
@app.route('/alerts')
def alerts():
    if 'name' in session:
504
        alerts = nfs.get_alerts_list(session['appkey'])
Vladislav Rykov's avatar
Vladislav Rykov committed
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
        return render_template('public/alerts.html', alert_list=alerts[1])
    else:
        return redirect(url_for('index'))

@app.route('/new-alert')
def new_alert():
    if 'name' in session:
        devs = dd.get_list(session['appkey'])
        return render_template('public/new-alert.html', devs=devs[1])
    else:
        return redirect(url_for('index'))


@app.route('/alert', methods=['POST'])
def alert():
520
521
522
523
524
    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
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
            
            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'))
540
541
542
543
        else:
            return redirect(url_for('index'))
    else:
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
544
545
546
547

@app.route('/alert-rm')
def alarm_rm():
    if 'name' in session:
Vladislav Rykov's avatar
Vladislav Rykov committed
548
        nq.delete(session['appkey'], request.args.get('devid'), request.args.get('id'))
Vladislav Rykov's avatar
Vladislav Rykov committed
549
550
        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'))
551
        res = nfs.delete(session['appkey'], request.args.get('devid'), request.args.get('id'))
Vladislav Rykov's avatar
Vladislav Rykov committed
552
553

        if res[0]:
554
            flash('Alert removed', 'success')
Vladislav Rykov's avatar
Vladislav Rykov committed
555
556
            return redirect(url_for('alerts'))
        else:
557
            flash('Alert cannot be removed : {}'.format(res[1]), 'danger')
Vladislav Rykov's avatar
Vladislav Rykov committed
558
            return redirect(url_for('alerts'))
Vladislav Rykov's avatar
Vladislav Rykov committed
559
560
561
    else:
        return redirect(url_for('index'))

562
563
564
565
566
567
568

@app.route('/automation', methods=['GET','POST'])
def automation():
    if 'name' in session:
        if request.method == 'GET':
            auto = nfs.get_automation_list(session['appkey'])
            return render_template('public/automation.html', auto_list=auto[1])
569
570
        elif request.method == 'POST':
            # new automation
Vladislav Rykov's avatar
Vladislav Rykov committed
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
            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'))

593
594
595
596
597
598
599
600
601
602
603
604
605
    else:
        return redirect(url_for('index'))


@app.route('/new-automation')
def new_automation():
    if 'name' in session:
        devs = dd.get_list(session['appkey'])
        return render_template('public/new-automation.html', devs=devs[1])
    else:
        return redirect(url_for('index'))


606
607
def pend_delete_all_ack():
    pend.delete_all_ack()
Vladislav Rykov's avatar
Vladislav Rykov committed
608

609
610
611
612
613
614
615
616
617
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
618
619
620
621
622
623
                # 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])