Passed
Push — master ( bdc329...fe0a02 )
by William
01:19
created

app.main.index()   B

Complexity

Conditions 6

Size

Total Lines 63
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 47
nop 0
dl 0
loc 63
rs 7.8012
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
from flask import request, redirect, url_for, send_from_directory, flash, send_file
2
from flask_login import login_required, current_user
3
from flask import Blueprint, render_template
4
from .models import Schedule, Balance, Total, Running, User, Settings, Transactions, Email, Hold, Skip
5
from app import db
6
from datetime import datetime
7
import os
8
from sqlalchemy import desc, extract, asc
9
from werkzeug.security import generate_password_hash
10
from .cashflow import calc_schedule, calc_transactions, plot_cash
11
from pathlib import Path
12
13
14
main = Blueprint('main', __name__)
15
16
17
@main.route('/', methods=('GET', 'POST'))
18
@login_required
19
def index():
20
    # get today's date
21
    todaydate = datetime.today().strftime('%A, %B %d, %Y')
22
23
    # query the latest balance information
24
    balance = Balance.query.order_by(desc(Balance.date), desc(Balance.id)).first()
25
26
    try:
27
        modifiedtime = os.path.getmtime(os.environ.get('DATABASE_URL').replace('sqlite:///', ''))
28
        modifiedtime = datetime.fromtimestamp(modifiedtime)
29
        modpath = os.environ.get('DATABASE_URL').replace('sqlite:///', '')
30
        modpath = modpath.replace('db.sqlite', 'modified')
31
        os.close(os.open(modpath, os.O_CREAT))
32
        dbmodified = os.path.getmtime(modpath)
33
        dbmodified = datetime.fromtimestamp(dbmodified)
34
    except:
35
        basedir = os.path.abspath(os.path.dirname(__file__))
36
        datafile = os.path.join(basedir, "data/db.sqlite")
37
        modifiedtime = os.path.getmtime(datafile)
38
        modifiedtime = datetime.fromtimestamp(modifiedtime)
39
        modpath = os.path.join(basedir, "data/modified")
40
        os.close(os.open(modpath, os.O_CREAT))
41
        dbmodified = os.path.getmtime(modpath)
42
        dbmodified = datetime.fromtimestamp(dbmodified)
43
44
    if modifiedtime > dbmodified:
45
        try:
46
            if balance.amount:
47
                db.session.query(Balance).delete()
48
                balance = Balance(amount=balance.amount, date=datetime.today())
49
                db.session.add(balance)
50
                db.session.commit()
51
        except:
52
            balance = Balance(amount='0',
53
                              date=datetime.today())
54
            db.session.add(balance)
55
            db.session.commit()
56
57
        # empty the tables to create fresh data from the schedule
58
        db.session.query(Total).delete()
59
        db.session.query(Running).delete()
60
        db.session.query(Transactions).delete()
61
        db.session.commit()
62
63
        # calculate total events for the year amount
64
        calc_schedule()
65
66
        # calculate sum of running transactions
67
        calc_transactions(balance)
68
69
        Path(modpath).touch()
70
71
    # plot cash flow results
72
    minbalance, graphJSON = plot_cash()
73
74
    if current_user.admin:
75
        return render_template('index.html', title='Index', todaydate=todaydate, balance=balance.amount,
76
                           minbalance=minbalance, graphJSON=graphJSON)
77
    else:
78
        return render_template('index_guest.html', title='Index', todaydate=todaydate, balance=balance.amount,
79
                           minbalance=minbalance, graphJSON=graphJSON)
80
81
82
@main.route('/profile')
83
@login_required
84
def profile():
85
86
    if current_user.admin:
87
        return render_template('profile.html')
88
    else:
89
        return render_template('profile_guest.html')
90
91
92
@main.route('/settings')
93
@login_required
94
def settings_page():
95
96
    if current_user.admin:
97
        return render_template('settings.html')
98
    else:
99
        return redirect(url_for('main.index'))
100
101
102
@main.route('/schedule')
103
@login_required
104
def schedule():
105
    schedule = Schedule.query.order_by(asc(extract('day', Schedule.startdate)))
106
107
    if current_user.admin:
108
        return render_template('schedule_table.html', title='Schedule Table', schedule=schedule)
109
    else:
110
        return redirect(url_for('main.index'))
111
112
113
@main.route('/holds')
114
@login_required
115
def holds():
116
    hold = Hold.query
117
    skip = Skip.query
118
119
    if current_user.admin:
120
        return render_template('holds_table.html', title='Holds Table', hold=hold, skip=skip)
121
    else:
122
        return redirect(url_for('main.index'))
123
124
125
@main.route('/create', methods=('GET', 'POST'))
126
@login_required
127
def create():
128
    # create a new schedule item
129
    if current_user.admin:
130
        format = '%Y-%m-%d'
131
        if request.method == 'POST':
132
            name = request.form['name']
133
            amount = request.form['amount']
134
            frequency = request.form['frequency']
135
            startdate = request.form['startdate']
136
            type = request.form['type']
137
            schedule = Schedule(name=name,
138
                              type=type,
139
                              amount=amount,
140
                              frequency=frequency,
141
                              startdate=datetime.strptime(startdate, format).date())
142
            existing = Schedule.query.filter_by(name=name).first()
143
            if existing:
144
                flash("Schedule already exists")
145
                return redirect(url_for('main.schedule'))
146
            db.session.add(schedule)
147
            db.session.commit()
148
            flash("Added Successfully")
149
150
            return redirect(url_for('main.schedule'))
151
152
        return redirect(url_for('main.schedule'))
153
    else:
154
        return redirect(url_for('main.index'))
155
156
157
@main.route('/update', methods=['GET', 'POST'])
158
@login_required
159
def update():
160
    # update an existing schedule item
161
    if current_user.admin:
162
        format = '%Y-%m-%d'
163
164
        if request.method == 'POST':
165
            current = Schedule.query.filter_by(id=request.form['id']).first()
166
            existing = Schedule.query.filter_by(name=request.form['name']).first()
167
            if existing:
168
                if current.name != request.form['name']:
169
                    flash("Schedule name already exists")
170
                    return redirect(url_for('main.schedule'))
171
            my_data = Schedule.query.get(request.form.get('id'))
172
            my_data.name = request.form['name']
173
            my_data.amount = request.form['amount']
174
            my_data.type = request.form['type']
175
            my_data.frequency = request.form['frequency']
176
            my_data.startdate = request.form['startdate']
177
            startdate = request.form['startdate']
178
            my_data.startdate = datetime.strptime(startdate, format).date()
179
            db.session.commit()
180
            flash("Updated Successfully")
181
182
            return redirect(url_for('main.schedule'))
183
184
        return redirect(url_for('main.schedule'))
185
    else:
186
        return redirect(url_for('main.index'))
187
188
189
@main.route('/addhold/<id>')
190
@login_required
191
def addhold(id):
192
    # add a hold item from the schedule
193
    if current_user.admin:
194
        schedule = Schedule.query.filter_by(id=id).first()
195
        hold = Hold(name=schedule.name, type=schedule.type, amount=schedule.amount)
196
        db.session.add(hold)
197
        db.session.commit()
198
199
        return redirect(url_for('main.schedule'))
200
    else:
201
        return redirect(url_for('main.index'))
202
203
204
@main.route('/addskip/<id>')
205
@login_required
206
def addskip(id):
207
    # add a skip item from the schedule
208
    if current_user.admin:
209
        transaction = Transactions.query.filter_by(id=id).first()
210
        trans_type = ""
211
        if transaction.type == "Expense":
212
            trans_type = "Income"
213
        elif transaction.type == "Income":
214
            trans_type = "Expense"
215
        skip = Skip(name=transaction.name + " (SKIP)", type=trans_type, amount=transaction.amount, date=transaction.date)
216
        db.session.add(skip)
217
        db.session.commit()
218
219
        return redirect(url_for('main.transactions'))
220
    else:
221
        return redirect(url_for('main.index'))
222
223
224
@main.route('/deletehold/<id>')
225
@login_required
226
def holds_delete(id):
227
    # delete a hold item
228
    if current_user.admin:
229
        hold = Hold.query.filter_by(id=id).first()
230
231
        if hold:
232
            db.session.delete(hold)
233
            db.session.commit()
234
            flash("Deleted Successfully")
235
236
        return redirect(url_for('main.holds'))
237
    else:
238
        return redirect(url_for('main.index'))
239
240
241
@main.route('/deleteskip/<id>')
242
@login_required
243
def skips_delete(id):
244
    # delete a skip item
245
    if current_user.admin:
246
        skip = Skip.query.filter_by(id=id).first()
247
248
        if skip:
249
            db.session.delete(skip)
250
            db.session.commit()
251
            flash("Deleted Successfully")
252
253
        return redirect(url_for('main.holds'))
254
    else:
255
        return redirect(url_for('main.index'))
256
257
258
@main.route('/clearholds')
259
@login_required
260
def clear_holds():
261
    # clear holds
262
    if current_user.admin:
263
        db.session.query(Hold).delete()
264
        db.session.commit()
265
266
        return redirect(url_for('main.holds'))
267
    else:
268
        return redirect(url_for('main.index'))
269
270
271
@main.route('/clearskips')
272
@login_required
273
def clear_skips():
274
    # clear skips
275
    if current_user.admin:
276
        db.session.query(Skip).delete()
277
        db.session.commit()
278
279
        return redirect(url_for('main.index'))
280
    else:
281
        return redirect(url_for('main.index'))
282
283
284
@main.route('/delete/<id>')
285
@login_required
286
def schedule_delete(id):
287
    # delete a schedule item
288
    if current_user.admin:
289
        schedule = Schedule.query.filter_by(id=id).first()
290
291
        if schedule:
292
            db.session.delete(schedule)
293
            db.session.commit()
294
            flash("Deleted Successfully")
295
296
        return redirect(url_for('main.schedule'))
297
    else:
298
        return redirect(url_for('main.index'))
299
300
301
@main.route('/favicon')
302
def favicon():
303
    return send_from_directory(os.path.join(main.root_path, 'static'),
304
                               'favicon.ico', mimetype='image/vnd.microsoft.icon')
305
306
307
@main.route('/appleicon')
308
def appleicon():
309
    return send_from_directory(os.path.join(main.root_path, 'static'),
310
                               'apple-touch-icon.png', mimetype='image/png')
311
312
313
@main.route('/balance', methods=('GET', 'POST'))
314
@login_required
315
def balance():
316
    # manually update the balance from the balance button
317
    if current_user.admin:
318
        format = '%Y-%m-%d'
319
        if request.method == 'POST':
320
            amount = request.form['amount']
321
            dateentry = request.form['date']
322
            balance = Balance(amount=amount,
323
                              date=datetime.strptime(dateentry, format).date())
324
            db.session.add(balance)
325
            db.session.commit()
326
327
            return redirect(url_for('main.index'))
328
    else:
329
        return redirect(url_for('main.index'))
330
331
332
@main.route('/changepw', methods=('GET', 'POST'))
333
@login_required
334
def changepw():
335
    # change the users password from the profile page
336
    if request.method == 'POST':
337
        curr_user = current_user.id
338
        my_user = User.query.filter_by(id=curr_user).first()
339
        password = request.form['password']
340
        my_user.password = generate_password_hash(password, method='scrypt')
341
        db.session.commit()
342
343
        return redirect(url_for('main.profile'))
344
345
    return redirect(url_for('main.profile'))
346
347
348
@main.route('/settings', methods=('GET', 'POST'))
349
@login_required
350
def settings():
351
    # set the settings options, in this case disable signups, from the profile page
352
    if current_user.admin:
353
        if request.method == 'POST':
354
            signupsettingname = Settings.query.filter_by(name='signup').first()
355
356
            if signupsettingname:
357
                signupvalue = request.form['signupvalue']
358
                signupsettingname.value = eval(signupvalue)
359
                db.session.commit()
360
361
                return redirect(url_for('main.profile'))
362
363
            # store the signup option value in the database to check when the user clicks signup
364
            signupvalue = request.form['signupvalue']
365
            signupvalue = eval(signupvalue)
366
            settings = Settings(name="signup",
367
                              value=signupvalue)
368
            db.session.add(settings)
369
            db.session.commit()
370
371
            return redirect(url_for('main.profile'))
372
373
        return redirect(url_for('main.profile'))
374
    else:
375
        return redirect(url_for('main.index'))
376
377
378
@main.route('/transactions')
379
@login_required
380
def transactions():
381
    total = Transactions.query
382
383
    if current_user.admin:
384
        return render_template('transactions_table.html', total=total)
385
    else:
386
        return redirect(url_for('main.index'))
387
388
389
@main.route('/email', methods=('GET', 'POST'))
390
@login_required
391
def email():
392
    # set the users email address, password, and server for the auto email balance update
393
    if current_user.admin:
394
        if request.method == 'POST':
395
            emailsettings = Email.query.filter_by(id=1).first()
396
397
            if emailsettings:
398
                email = request.form['email']
399
                password = request.form['password']
400
                server = request.form['server']
401
                subjectstr = request.form['subject_str']
402
                startstr = request.form['start_str']
403
                endstr = request.form['end_str']
404
                emailsettings.email = email
405
                emailsettings.password = password
406
                emailsettings.server = server
407
                emailsettings.subjectstr = subjectstr
408
                emailsettings.startstr = startstr
409
                emailsettings.endstr = endstr
410
                db.session.commit()
411
412
                return redirect(url_for('main.profile'))
413
414
            email = request.form['email']
415
            password = request.form['password']
416
            server = request.form['server']
417
            subjectstr = request.form['subject_str']
418
            startstr = request.form['start_str']
419
            endstr = request.form['end_str']
420
            emailentry = Email(email=email, password=password, server=server, subjectstr=subjectstr, startstr=startstr,
421
                               endstr=endstr)
422
            db.session.add(emailentry)
423
            db.session.commit()
424
425
            return redirect(url_for('main.profile'))
426
427
        return redirect(url_for('main.profile'))
428
    else:
429
        return redirect(url_for('main.index'))
430
431
432
@main.route('/users_table')
433
@login_required
434
def users():
435
    users = User.query
436
437
    if current_user.admin:
438
        return render_template('users_table.html', title='Users Table', users=users)
439
    else:
440
        return redirect(url_for('main.index'))
441
442
443
@main.route('/update_user', methods=['GET', 'POST'])
444
@login_required
445
def update_user():
446
    # update an existing user
447
    if current_user.admin:
448
        if request.method == 'POST':
449
            current = User.query.filter_by(id=request.form['id']).first()
450
            existing = User.query.filter_by(email=request.form['email']).first()
451
            if existing:
452
                if current.email != request.form['email']:
453
                    flash("Email already exists")
454
                    return redirect(url_for('main.users'))
455
            my_data = User.query.get(request.form.get('id'))
456
            my_data.name = request.form['name']
457
            my_data.email = request.form['email']
458
            my_data.admin = eval(request.form['admin'])
459
            db.session.commit()
460
            flash("Updated Successfully")
461
462
            return redirect(url_for('main.users'))
463
464
        return redirect(url_for('main.users'))
465
    else:
466
        return redirect(url_for('main.index'))
467
468
469
@main.route('/delete_user/<id>')
470
@login_required
471
def delete_user(id):
472
    # delete a user
473
    if current_user.admin:
474
        user = User.query.filter_by(id=id).first()
475
476
        if user:
477
            db.session.delete(user)
478
            db.session.commit()
479
            flash("Deleted Successfully")
480
481
        return redirect(url_for('main.users'))
482
    else:
483
        return redirect(url_for('main.index'))
484
485
486
@main.route('/create_user', methods=('GET', 'POST'))
487
@login_required
488
def create_user():
489
    # create a new user
490
    if current_user.admin:
491
        if request.method == 'POST':
492
            name = request.form['name']
493
            email = request.form['email']
494
            admin = eval(request.form['admin'])
495
            password = generate_password_hash(request.form['password'], method='scrypt')
496
            user = User(name=name, email=email, admin=admin, password=password)
497
            existing = User.query.filter_by(email=email).first()
498
            if existing:
499
                flash("User already exists")
500
                return redirect(url_for('main.users'))
501
            db.session.add(user)
502
            db.session.commit()
503
            flash("Added Successfully")
504
505
            return redirect(url_for('main.users'))
506
507
        return redirect(url_for('main.users'))
508
    else:
509
        return redirect(url_for('main.index'))
510
511
512
@main.route('/manifest.json')
513
def serve_manifest():
514
    return send_file('manifest.json', mimetype='application/manifest+json')
515
516
517
@main.route('/sw.js')
518
def serve_sw():
519
    return send_file('sw.js', mimetype='application/javascript')
520