server.py 9.27 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
23
        ah = ad.ApplicationDao()
        apps = ah.get_list(session['name'].encode('utf-8'))
Vladislav Rykov's avatar
Vladislav Rykov committed
24
25

        session.pop('appkey', None)
Vladislav Rykov's avatar
Vladislav Rykov committed
26
        # print('apps: ', apps)
27
28
29
30
        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
31
32
    else:
        return render_template('index.html')
33
34
35
36



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

        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
48
49
50
51
            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
52
53
            else:
                session['name'] = username
54
        
Vladislav Rykov's avatar
Vladislav Rykov committed
55
                return redirect(url_for('index'))
56

57
58
59


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

        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
71
72
73
74
            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
75
76
            else:
                session['name'] = username
Vladislav Rykov's avatar
Vladislav Rykov committed
77
        
Vladislav Rykov's avatar
Vladislav Rykov committed
78
79
80
                return redirect(url_for('index'))


81
82

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


88
89
90

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



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

Vladislav Rykov's avatar
Vladislav Rykov committed
107
108
            app = ah.get(session['appkey'])
            devs = dh.get_list(app[1][1])
Vladislav Rykov's avatar
Vladislav Rykov committed
109
        
Vladislav Rykov's avatar
Vladislav Rykov committed
110
111
112
113
114
115
116
117
118
            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])
119
        else:
Vladislav Rykov's avatar
Vladislav Rykov committed
120
121
122
123
124
125
            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)
                res = ah.create(request.form['appname'], appkey, session['name'], request.form['appdesc'])
Vladislav Rykov's avatar
Vladislav Rykov committed
126
            
Vladislav Rykov's avatar
Vladislav Rykov committed
127
128
                if not res[0]:
                    return render_template('new-app.html', feedback=res[1])
Vladislav Rykov's avatar
Vladislav Rykov committed
129
            
Vladislav Rykov's avatar
Vladislav Rykov committed
130
131
                dh = dd.DeviceDao()
                res = dh.create_table(appkey)
132
            
Vladislav Rykov's avatar
Vladislav Rykov committed
133
134
135
                if not res[0]:
                    ah.delete(appkey)
                    return render_template('new-app.html', feedback=res[1])
136
            
Vladislav Rykov's avatar
Vladislav Rykov committed
137
138
139
                return redirect(url_for('index'))
    else:
        return redirect(url_for('index'))
140

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

Vladislav Rykov's avatar
Vladislav Rykov committed
162

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

Vladislav Rykov's avatar
Vladislav Rykov committed
171
172
173
174
        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
175
    else:
Vladislav Rykov's avatar
Vladislav Rykov committed
176
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
177
178
179
180
181
 


@server.route('/dev', methods=['GET', 'POST'])
def dev():
Vladislav Rykov's avatar
Vladislav Rykov committed
182
183
184
185
    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
186

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

Vladislav Rykov's avatar
Vladislav Rykov committed
194
195
            if last[0]:
                ltup = last[1][0][1]
196

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

201
202
203
            if not res[0]:
                return render_template('add-dev.html', feedback=res[1])
            else:
Vladislav Rykov's avatar
Vladislav Rykov committed
204
205
206
207
208
209
210
211
212
                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
213
214


Vladislav Rykov's avatar
Vladislav Rykov committed
215
216
@server.route('/dev-conf', methods=['GET', 'POST'])
def dev_conf():
Vladislav Rykov's avatar
Vladislav Rykov committed
217
218
219
220
    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
221
        
Vladislav Rykov's avatar
Vladislav Rykov committed
222
223
224
225
            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
226
        
Vladislav Rykov's avatar
Vladislav Rykov committed
227
228
229
230
231
            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
232

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

Vladislav Rykov's avatar
Vladislav Rykov committed
235
            pend.create(session['appkey'], session['devid'], base64_args)
Vladislav Rykov's avatar
Vladislav Rykov committed
236
237
238
239
240

        #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
241
        
Vladislav Rykov's avatar
Vladislav Rykov committed
242
243
244
            return redirect(url_for('dev', id=session['devid']))
    else:
        return redirect(url_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
245

Vladislav Rykov's avatar
Vladislav Rykov committed
246

Vladislav Rykov's avatar
Vladislav Rykov committed
247
248
@server.route('/delete-dev')
def delete_dev():
Vladislav Rykov's avatar
Vladislav Rykov committed
249
250
251
252
    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
253

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


Vladislav Rykov's avatar
Vladislav Rykov committed
259
260
@server.route('/dev-data')
def dev_data():
Vladislav Rykov's avatar
Vladislav Rykov committed
261
262
263
264
265
266
267
268
269
270
271
272
273
274
    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
275
    else:
Vladislav Rykov's avatar
Vladislav Rykov committed
276
        return redirect(utl_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
277

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

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

Vladislav Rykov's avatar
Vladislav Rykov committed
285
286
287
        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
288
289
                f.write(',')
            f.write('\n')
Vladislav Rykov's avatar
Vladislav Rykov committed
290
291
292
293
294
295
        
            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
296
    
Vladislav Rykov's avatar
Vladislav Rykov committed
297
298
299
        return send_from_directory(DATA_DOWNLOAD_DIR, fn, as_attachment=True)
    else:
        return redirect(utl_for('index'))
Vladislav Rykov's avatar
Vladislav Rykov committed
300
301
        

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