server.py 9.17 KB
Newer Older
Vladislav Rykov's avatar
Vladislav Rykov committed
1
from flask import Flask, render_template, request, redirect, url_for, session, send_from_directory
2
import psycopg2
Vladislav Rykov's avatar
Vladislav Rykov committed
3
import bcrypt
4
import misc
Vladislav Rykov's avatar
Vladislav Rykov committed
5
import dao.user.user as ud
Vladislav Rykov's avatar
Vladislav Rykov committed
6
import dao.application.application as ad
7
import dao.device.device as dd
Vladislav Rykov's avatar
Vladislav Rykov committed
8
import dao.pend.pend as pend
Vladislav Rykov's avatar
Vladislav Rykov committed
9
import dao.data.data as data
Vladislav Rykov's avatar
Vladislav Rykov committed
10
import binascii
11
import os
Vladislav Rykov's avatar
Vladislav Rykov committed
12

13

14
APP_KEY_LEN = 8
Vladislav Rykov's avatar
Vladislav Rykov committed
15
DATA_DOWNLOAD_DIR = 'data'
16
17

server = Flask(__name__, template_folder='templates/')
Vladislav Rykov's avatar
Vladislav Rykov committed
18

19
@server.route('/')
20
def index():
Vladislav Rykov's avatar
Vladislav Rykov committed
21
    if 'name' in session and len(session['name']) > 0:
Vladislav Rykov's avatar
Vladislav Rykov committed
22
        apps = ad.get_list(session['name'].encode('utf-8'))
Vladislav Rykov's avatar
Vladislav Rykov committed
23
24

        session.pop('appkey', None)
Vladislav Rykov's avatar
Vladislav Rykov committed
25
        # print('apps: ', apps)
26
27
28
29
        if apps[0]:
            return render_template('index.html', apps=apps[1])
        else:
            return render_template('index.html', feedback=apps[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
30
31
    else:
        return render_template('index.html')
32
33
34
35



@server.route('/signup', methods=['GET', 'POST'])
36
37
38
39
40
def signup():
    if request.method == 'GET':
        return render_template('signup.html')
    else: 
        username = request.form['username']
Vladislav Rykov's avatar
Vladislav Rykov committed
41
        password = request.form['password'].encode('utf-8')
42
43
44
45
46

        if (username == '' or password == ''):
            feedback = 'Username or password fields cannot be empty'
            return render_template('signup.html', feedback=feedback)
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
47
48
49
50
            uh = ud.UserDao()
            res = uh.create(username, password)
            if (not res[0]):
                return render_template('signup.html', feedback=res[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
51
52
            else:
                session['name'] = username
53
        
Vladislav Rykov's avatar
Vladislav Rykov committed
54
                return redirect(url_for('index'))
55

56
57
58


@server.route('/login', methods=['GET', 'POST'])
Vladislav Rykov's avatar
Vladislav Rykov committed
59
def login():
Vladislav Rykov's avatar
Vladislav Rykov committed
60
61
62
63
    if request.method == 'GET':
        return render_template('login.html')
    else: 
        username = request.form['username']
Vladislav Rykov's avatar
Vladislav Rykov committed
64
        password = request.form['password'].encode('utf-8')
Vladislav Rykov's avatar
Vladislav Rykov committed
65
66
67
68
69

        if (username == '' or password == ''):
            feedback = 'Username or password fields cannot be empty'
            return render_template('login.html', feedback=feedback)
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
70
71
72
73
            uh = ud.UserDao()
            res = uh.get(username, password)
            if (not res[0]):
                return render_template('login.html', feedback=msg[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
74
75
            else:
                session['name'] = username
Vladislav Rykov's avatar
Vladislav Rykov committed
76
        
Vladislav Rykov's avatar
Vladislav Rykov committed
77
78
79
                return redirect(url_for('index'))


80
81

@server.route('/logout')
Vladislav Rykov's avatar
Vladislav Rykov committed
82
83
84
def logout():
    session.clear()
    return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
85
86


87
88
89

@server.route('/new-app')
def new_application():
Vladislav Rykov's avatar
Vladislav Rykov committed
90
91
92
93
    if 'name' in session:
        return render_template('new-app.html')
    else:
        return redirect(url_for('index'))
94
95
96
97
98



@server.route('/app', methods=['GET', 'POST'])
def app():
Vladislav Rykov's avatar
Vladislav Rykov committed
99
100
101
    if 'name' in session:
        if request.method == 'GET':
            dh = dd.DeviceDao()
Vladislav Rykov's avatar
Vladislav Rykov committed
102
            
Vladislav Rykov's avatar
Vladislav Rykov committed
103
            session['appkey'] = request.args.get('appkey')
Vladislav Rykov's avatar
Vladislav Rykov committed
104

Vladislav Rykov's avatar
Vladislav Rykov committed
105
            app = ad.get(session['appkey'])
Vladislav Rykov's avatar
Vladislav Rykov committed
106
            devs = dh.get_list(app[1][1])
Vladislav Rykov's avatar
Vladislav Rykov committed
107
        
Vladislav Rykov's avatar
Vladislav Rykov committed
108
109
110
111
112
113
114
115
116
            try:
                filelist = [f for f in os.listdir(DATA_DOWNLOAD_DIR) if f.startswith(session['appkey'])]
                for f in filelist:
                    os.remove(DATA_DOWNLOAD_DIR+'/'+f)
            except OSError:
                pass

           # print('devs : ', devs)
            return render_template('app.html', app=app[1], devs=devs[1])
117
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
118
119
120
121
122
            if request.form['appname'] == '':
                error = 'Application name cannot be empty.'
                return render_template('new-app.html', feedback=error)
            else:
                appkey = misc.rand_str(APP_KEY_LEN)
Vladislav Rykov's avatar
Vladislav Rykov committed
123
                res = ad.create(request.form['appname'], appkey, session['name'], request.form['appdesc'])
Vladislav Rykov's avatar
Vladislav Rykov committed
124
            
Vladislav Rykov's avatar
Vladislav Rykov committed
125
126
                if not res[0]:
                    return render_template('new-app.html', feedback=res[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
127
            
Vladislav Rykov's avatar
Vladislav Rykov committed
128
129
                dh = dd.DeviceDao()
                res = dh.create_table(appkey)
130
            
Vladislav Rykov's avatar
Vladislav Rykov committed
131
                if not res[0]:
Vladislav Rykov's avatar
Vladislav Rykov committed
132
                    ad.delete(appkey)
Vladislav Rykov's avatar
Vladislav Rykov committed
133
                    return render_template('new-app.html', feedback=res[1])
134
            
Vladislav Rykov's avatar
Vladislav Rykov committed
135
136
137
                return redirect(url_for('index'))
    else:
        return redirect(url_for('index'))
138

139
140
@server.route('/delete-app')
def delete_app():
Vladislav Rykov's avatar
Vladislav Rykov committed
141
142
143
    if 'name' in session:
        dh = dd.DeviceDao()
        devs = dh.get_list(session['appkey'])
144
    
Vladislav Rykov's avatar
Vladislav Rykov committed
145
146
        for dev in devs[1]:
            data.delete_table(session['appkey'], dev[1])
147
    
Vladislav Rykov's avatar
Vladislav Rykov committed
148
        dh.delete_table(session['appkey'])
149
    
Vladislav Rykov's avatar
Vladislav Rykov committed
150
        res = ad.delete(session['appkey'])
151
    
Vladislav Rykov's avatar
Vladislav Rykov committed
152
153
154
155
        if not res[0]:
            return redirect(url_for('app'))
        else:
            return redirect(url_for('index'))
156
157
    else:
        return redirect(url_for('index'))
158

Vladislav Rykov's avatar
Vladislav Rykov committed
159

Vladislav Rykov's avatar
Vladislav Rykov committed
160
161
@server.route('/add-dev')
def new_dev():
Vladislav Rykov's avatar
Vladislav Rykov committed
162
163
164
    if 'name' in session:
        dh = dd.DeviceDao()
        dev_list = dh.get_list(session['appkey'])
Vladislav Rykov's avatar
Vladislav Rykov committed
165
    
Vladislav Rykov's avatar
Vladislav Rykov committed
166
    #print('dev list : ', dev_list)
Vladislav Rykov's avatar
Vladislav Rykov committed
167

Vladislav Rykov's avatar
Vladislav Rykov committed
168
169
170
171
        if not dev_list[0]:
            return render_template('add-dev.html', feedback=dev_list[1])
        else:
            return render_template('add-dev.html', free_ids=misc.prep_id_range(dev_list[1]))
Vladislav Rykov's avatar
Vladislav Rykov committed
172
    else:
Vladislav Rykov's avatar
Vladislav Rykov committed
173
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
174
175
176
177
178
 


@server.route('/dev', methods=['GET', 'POST'])
def dev():
Vladislav Rykov's avatar
Vladislav Rykov committed
179
180
181
182
    if 'name' in session:
        dh = dd.DeviceDao()
        if request.method == 'GET':
            dev = dh.get(session['appkey'], request.args.get('id'))
Vladislav Rykov's avatar
Vladislav Rykov committed
183

Vladislav Rykov's avatar
Vladislav Rykov committed
184
185
            session['devid'] = dev[1][1]
            session['devname'] = dev[1][0]
Vladislav Rykov's avatar
Vladislav Rykov committed
186
        
Vladislav Rykov's avatar
Vladislav Rykov committed
187
            last = data.get_last_n(session['appkey'], session['devid'], 1)
Vladislav Rykov's avatar
Vladislav Rykov committed
188
        
Vladislav Rykov's avatar
Vladislav Rykov committed
189
            ltup = 'Device have not sent data yet'
Vladislav Rykov's avatar
Vladislav Rykov committed
190

Vladislav Rykov's avatar
Vladislav Rykov committed
191
192
            if last[0]:
                ltup = last[1][0][1]
193

Vladislav Rykov's avatar
Vladislav Rykov committed
194
            return render_template('dev.html', dev=dev[1], appkey=session['appkey'], ltup=ltup)
Vladislav Rykov's avatar
Vladislav Rykov committed
195
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
196
197
            res = dh.create(request.form['devname'], request.form['devid'], session['appkey'], request.form['devdesc'])

198
199
200
            if not res[0]:
                return render_template('add-dev.html', feedback=res[1])
            else:
Vladislav Rykov's avatar
Vladislav Rykov committed
201
202
203
204
205
206
207
208
209
                res = data.create_table(session['appkey'], request.form['devid'])
            
                if not res[0]:
                    dh.delete(session['appkey'], request.form['devid'])
                    return render_template('add-dev.html', feedback=res[1])
                else:
                    return redirect(url_for('app', appkey=session['appkey']))
    else:
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
210
211


Vladislav Rykov's avatar
Vladislav Rykov committed
212
213
@server.route('/dev-conf', methods=['GET', 'POST'])
def dev_conf():
Vladislav Rykov's avatar
Vladislav Rykov committed
214
215
216
217
    if 'name' in session and 'devid' in session:
        if request.method == 'GET':
            return render_template('dev-conf.html', devname=session['devname'])
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
218
        
Vladislav Rykov's avatar
Vladislav Rykov committed
219
220
221
222
            argslen = len(request.form['arg']) + 1
            args = bytearray(argslen + 2)
            args[0] = int(request.form['confid'])
            args[1] = argslen
Vladislav Rykov's avatar
Vladislav Rykov committed
223
        
Vladislav Rykov's avatar
Vladislav Rykov committed
224
225
226
227
228
            bstr = bytes(request.form['arg'])
            i = 0
            while i < argslen - 1:
                args[2+i] = bstr[i]
                i += 1
Vladislav Rykov's avatar
Vladislav Rykov committed
229

Vladislav Rykov's avatar
Vladislav Rykov committed
230
            base64_args = binascii.b2a_base64(args).decode('utf-8')
Vladislav Rykov's avatar
Vladislav Rykov committed
231

Vladislav Rykov's avatar
Vladislav Rykov committed
232
            pend.create(session['appkey'], session['devid'], base64_args)
Vladislav Rykov's avatar
Vladislav Rykov committed
233
234
235
236
237

        #print('msg = ', args)
        #print('base64 = ', base64_args)
        #print(type(request.form['arg'].encode('utf-8')))
        #print(request.form['arg'].encode('utf-8'))
Vladislav Rykov's avatar
Vladislav Rykov committed
238
        
Vladislav Rykov's avatar
Vladislav Rykov committed
239
240
241
            return redirect(url_for('dev', id=session['devid']))
    else:
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
242

Vladislav Rykov's avatar
Vladislav Rykov committed
243

Vladislav Rykov's avatar
Vladislav Rykov committed
244
245
@server.route('/delete-dev')
def delete_dev():
Vladislav Rykov's avatar
Vladislav Rykov committed
246
247
248
249
    if 'name' in session and 'devid' in session:
        dh = dd.DeviceDao()
        data.delete_table(session['appkey'], session['devid'])
        res = dh.delete(session['appkey'], session['devid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
250

Vladislav Rykov's avatar
Vladislav Rykov committed
251
252
253
        return redirect(url_for('app', appkey=session['appkey']))
    else:
        return redirect(utl_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
254
255


Vladislav Rykov's avatar
Vladislav Rykov committed
256
257
@server.route('/dev-data')
def dev_data():
Vladislav Rykov's avatar
Vladislav Rykov committed
258
259
260
261
262
263
264
265
266
267
268
269
270
271
    if 'name' in session and 'devid' in session:
        last = data.get_last_n(session['appkey'], session['devid'], 10)  
        count = data.get_count(session['appkey'], session['devid'])

        last_ctr = 10
        if count[1][0] < 10:
            last_ctr = count[1][0]

        #print(last)
        #print(count)
        if count[1][0] > 0:
            return render_template('dev-data.html', data=last[1], total=count[1][0], lastctr=last_ctr, devname=session['devname'])
        else:
            return render_template('dev-data.html', devname=session['devname'])
Vladislav Rykov's avatar
Vladislav Rykov committed
272
    else:
Vladislav Rykov's avatar
Vladislav Rykov committed
273
        return redirect(utl_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
274

Vladislav Rykov's avatar
Vladislav Rykov committed
275
276
@server.route('/data-csv')
def data_csv():
Vladislav Rykov's avatar
Vladislav Rykov committed
277
278
    if 'name' in session and 'devid' in session:
        dumpd = data.get_all(session['appkey'], session['devid'])
Vladislav Rykov's avatar
Vladislav Rykov committed
279

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

Vladislav Rykov's avatar
Vladislav Rykov committed
282
283
284
        with open(DATA_DOWNLOAD_DIR+'/'+fn, 'w') as f: 
            for d in dumpd[1][0][2]:
                f.write(d)
Vladislav Rykov's avatar
Vladislav Rykov committed
285
286
                f.write(',')
            f.write('\n')
Vladislav Rykov's avatar
Vladislav Rykov committed
287
288
289
290
291
292
        
            for row in dumpd[1]:
                for v in row[2]:
                    f.write(str(row[2][v]))
                    f.write(',')
                f.write('\n')
Vladislav Rykov's avatar
Vladislav Rykov committed
293
    
Vladislav Rykov's avatar
Vladislav Rykov committed
294
295
296
        return send_from_directory(DATA_DOWNLOAD_DIR, fn, as_attachment=True)
    else:
        return redirect(utl_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
297
298
        

299
if __name__ == '__main__':
300
301
302
303
    server.secret_key = 'sdjfklsjf^$654sd^#sPH'
    server.run(debug = True, host='0.0.0.0')