from flask import Flask, render_template, request, flash, redirect import datetime import sendNotifications from sqlalchemy import create_engine, Column, Integer, String, Date from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from flask_apscheduler import APScheduler # Set to True to simplify testing TESTING = False notificationHour = 10 textSent = False emailSent = False class Config: SCHEDULER_API_ENABLED = True SCHEDULER_TIMEZONE = 'US/Eastern' app = Flask(__name__) app.config['SECRET_KEY'] = 'fa6166b0218186fb852429060105aca18e0f979240be8ebf' app.config.from_object(Config()) scheduler = APScheduler() scheduler.init_app(app) # Needed below to access native APSchedule objects sched = scheduler.scheduler Base = declarative_base() class Dates(Base): __tablename__ = 'Dates' id = Column(Integer, primary_key=True, autoincrement=True) dateTypeID = Column(Integer) dateValue = Column(Date) class DatesMetadata(Base): __tablename__ = 'DatesMetadata' id = Column(Integer, primary_key=True, autoincrement=True) dateTypeID = Column(Integer) DateTypeName = Column(String(50)) class Settings(Base): __tablename__ = 'Settings' id = Column(Integer, primary_key=True, autoincrement=True) settingType = Column(Integer) settingValue = Column(String(50)) class SettingsMetadata(Base): __tablename__ = 'SettingsMetadata' id = Column(Integer, primary_key=True, autoincrement=True) settingTypeID = Column(Integer) settingTypeName = Column(String(50)) engine = create_engine('mysql+pymysql://hydro:pRnCWH/M)dujdifi@db.dandembinski.com:3306/Hydro') Dates.__table__.create(bind=engine, checkfirst=True) Settings.__table__.create(bind=engine, checkfirst=True) DatesMetadata.__table__.create(bind=engine, checkfirst=True) SettingsMetadata.__table__.create(bind=engine, checkfirst=True) Session = sessionmaker(bind=engine) @scheduler.task('cron', id='send_notifications', hour=notificationHour) def Checknotifications(): session = Session() global textSent global emailSent nextFeed = session.query(Dates).filter_by(dateTypeID=3).first().dateValue nextClean = session.query(Dates).filter_by(dateTypeID=5).first().dateValue clean = False today = datetime.date.today() if nextClean <= today or TESTING is True: clean = True else: clean = False # Check if notifications need to be sent out if nextFeed <= today or TESTING is True: # Check what notifications should be sent out grab the grab relevant contact info and pass it to the appropriate # notification method notifications = {'text': session.query(Settings).filter_by(settingType=1).first().settingValue, 'email': session.query(Settings).filter_by(settingType=2).first().settingValue} if notifications['text'] and textSent is False: contact = session.query(Settings).filter_by(settingType=4).first().settingValue sendNotifications.sendText(contact, clean) textSent = True if notifications['email'] and emailSent is False: contact = session.query(Settings).filter_by(settingType=5).first().settingValue sendNotifications.sendEmail(contact, clean) print('sent any selected notifications') # print(today) # print(nextFeed) if TESTING is True: resetNotifcations() else: print('Not time to Send') session.close() @scheduler.task('cron', id='reset_notifications', hour=notificationHour+1) def resetNotifcations(): global textSent global emailSent if textSent is True: textSent = False if emailSent is True: emailSent = False return scheduler.start() # If in testing mode reschedule the notification check to run every minute if TESTING is True: sched.reschedule_job('send_notifications', trigger='cron', minute='*') print('Sending notifications every minute') @app.route('/', methods=('GET', 'POST')) @app.route('/index.html', methods=('GET', 'POST')) def index(): session = Session() installCheck = session.query(Dates).first() is None if installCheck is True: # session.close() return redirect('install.html') # Init the dates dict dates = {'plant': '', 'last': '', 'next': '', 'freq': '', 'lastClean': '', 'nextClean': '', 'cleanFreq': ''} alerts = {'text': False, 'email': False} # Get the feeding frequency and cleaning frequency set them to ints dates['freq'] = int(session.query(Settings).filter_by(settingType=3).first().settingValue) dates['cleanFreq'] = int(session.query(Settings).filter_by(settingType=6).first().settingValue) # If clicked the update button for dates, grab the new values and save them to the db. Then render the template if request.method == 'POST': dates['plant'] = request.form['plantDate'] dates['last'] = request.form['lastDate'] dates['next'] = datetime.datetime.strptime(dates['last'], '%Y-%m-%d') + datetime.timedelta(days=dates['freq']) dates['lastClean'] = request.form['lastClean'] dates['cleanFreq'] = datetime.datetime.strptime(dates['lastClean'], '%Y-%m-%d') + datetime.timedelta(days=dates['cleanFreq']) session.query(Dates).filter_by(dateTypeID=1).update({Dates.dateValue: dates['plant']}) session.query(Dates).filter_by(dateTypeID=2).update({Dates.dateValue: dates['last']}) session.query(Dates).filter_by(dateTypeID=3).update({Dates.dateValue: dates['next']}) session.query(Dates).filter_by(dateTypeID=4).update({Dates.dateValue: dates['lastClean']}) session.query(Dates).filter_by(dateTypeID=5).update({Dates.dateValue: dates['cleanFreq']}) # grab text message alert box. Set 'True' if checked or null if unchecked if request.form.get('AlertText'): alerts['text'] = 'True' else: alerts['text'] = None # grab email message alert box. Set 'True' if checked or null if unchecked if request.form.get('AlertEmail'): alerts['email'] = 'True' else: alerts['email'] = None # Update the alert settings to the database session.query(Settings).filter_by(settingType=1).update({Settings.settingValue: alerts['text']}) session.query(Settings).filter_by(settingType=2).update({Settings.settingValue: alerts['email']}) session.commit() # return render_template("index.html", plant=dates, alerts=alerts) return redirect('index.html') # If regular page load, grab all the dates from the db and render the template else: dates['plant'] = session.query(Dates).filter_by(dateTypeID=1).first().dateValue dates['last'] = session.query(Dates).filter_by(dateTypeID=2).first().dateValue dates['next'] = session.query(Dates).filter_by(dateTypeID=3).first().dateValue dates['lastClean'] = session.query(Dates).filter_by(dateTypeID=4).first().dateValue dates['nextClean'] = session.query(Dates).filter_by(dateTypeID=5).first().dateValue alerts['text'] = session.query(Settings).filter_by(settingType=1).first().settingValue alerts['email'] = session.query(Settings).filter_by(settingType=2).first().settingValue return render_template("index.html", plant=dates, alerts=alerts) @app.route('/updateFeed') def updateFeed(): session = Session() dates = {'plant': '', 'last': '', 'next': '', 'freq': ''} dates['freq'] = int(session.query(Settings).filter_by(settingType=3).first().settingValue) dates['last'] = datetime.date.today() dates['next'] = dates['last'] + datetime.timedelta(days=dates['freq']) session.query(Dates).filter_by(dateTypeID=2).update({Dates.dateValue: dates['last']}) session.query(Dates).filter_by(dateTypeID=3).update({Dates.dateValue: dates['next']}) session.commit() session.close() return redirect('/index.html') @app.route('/install.html') def install(): session = Session() populateDate = datetime.date.today() # Populate Dates Table session.add(Dates(dateTypeID=1, dateValue=populateDate)) session.add(Dates(dateTypeID=2, dateValue=populateDate)) session.add(Dates(dateTypeID=3, dateValue=populateDate)) # Populate DatesMetadata session.add(DatesMetadata(dateTypeID=1, DateTypeName='Plant Date')) session.add(DatesMetadata(dateTypeID=2, DateTypeName='Last Feeding Date')) session.add(DatesMetadata(dateTypeID=3, DateTypeName='Next Feeding Date')) # Populate Settings session.add(Settings(settingType=1, settingValue='False')) session.add(Settings(settingType=2, settingValue='False')) session.add(Settings(settingType=3, settingValue='14')) session.add(Settings(settingType=4, settingValue=None)) session.add(Settings(settingType=5, settingValue=None)) session.add(Settings(settingType=6, settingValue='28')) # Populate SettingsMetadata session.add(SettingsMetadata(settingTypeID=1, settingTypeName='Text')) session.add(SettingsMetadata(settingTypeID=2, settingTypeName='Email')) session.add(SettingsMetadata(settingTypeID=3, settingTypeName='Feeding Frequency')) session.add(SettingsMetadata(settingTypeID=4, settingTypeName='Alert Phone Number')) session.add(SettingsMetadata(settingTypeID=5, settingTypeName='Alert Email')) session.add(SettingsMetadata(settingTypeID=6, settingTypeName='Cleaning Frequency')) session.commit() return redirect('index.html') if __name__ == '__main__': serve(app, host='0.0.0.0', port=8000)