def check_feed(): format_now = format_time( ) # Gets the current time and converts it to a string we can do comparison against resultQuery = attributes.query.filter_by(scheduleFeed=1).all() try: bbLog.info("Time now: " + format_now) # Query the DB and get days the feeder should run. This will be returned as a string of numbers, w/ 1 being Mon # Ex: Feeder is supposed to run M W F. String from DB would be 135 # i is the position in the string, v is the value in that position for query in resultQuery: user = users.query.filter_by(id=query.userID).first() bbLog.info(str(users.query.filter_by(id=query.userID).first())) for i, v in enumerate(str(query.feedDays)): # Create string to match above in format Day Hour Minute. Hour and Minute pulled from DB entry directly result = v + " " + str(query.feedHour) + " " + str( query.feedMinute) # If the current time == the time in the DB run the motor if format_now == result: db_write_log(user.username, write_time(), 'scheduled') instant_feed(motor_pi.motor(), run=True) else: bbLog.info(" Time Feed: " + result) except: bbLog.info("An error occurred while checking the scheduled feed.") else: bbLog.info("Successfully checked the scheduled feed.")
def admin_settings(): theme = route_logic.get_user_theme() attr = attributes.query.filter_by(userID=current_user.get_id()).first_or_404() can_feed = attr.check_feed() is_admin = attr.check_admin() accounts = users.query.all() form = forms.admin_register() if form.validate_on_submit(): usr = users(username=form.username.data) usr.set_password(form.password.data) usr.email = form.email.data db.session.add(usr) db.session.commit() committedUser = users.query.filter_by(username=form.username.data).first() uid = committedUser.id if form.isAdmin.data: isAdmin = 1 else: isAdmin = 0 attr = attributes(userID=uid, canFeed=1, style='light', isAdmin=isAdmin) db.session.add(attr) db.session.commit() flash("User Registered") bbLog.info("Registration: " + str(current_user) + " has successfully registered.") return redirect(url_for('admin_settings')) return render_template('adminSettings.html', accounts=accounts, can_feed=can_feed, is_admin=is_admin, form=form, theme=theme)
def gen(camera): try: while True: frame = camera.get_frame() time.sleep(.12) yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n') except: bbLog.info("The camera feed is loading or an error has occurred.")
def oobe(): if current_user.is_authenticated: bbLog.info("Registration: " + str(current_user) + " has already successfully registered.") return redirect(url_for('startPage')) # Disallow access to the OOBE page if an admin already exists for security reasons if attributes.query.filter_by(isAdmin=1).first(): bbLog.info("Out of Box Experience cannot be accessed if there is an existing administrator account") return redirect(url_for('login')) # Register a new user as administrator registrationForm = forms.register() if registrationForm.validate_on_submit(): uname = registrationForm.username.data usr = users(username=uname) usr.set_password(registrationForm.password.data) usr.email = registrationForm.email.data db.session.add(usr) db.session.commit() committedUser = users.query.filter_by(username=uname).first() uid = committedUser.id attr = attributes(userID=uid, canFeed=1, style='light', isAdmin=1) db.session.add(attr) db.session.commit() flash("User Registered") bbLog.info("Registration: " + str(current_user) + " has successfully registered.") return redirect(url_for('login')) bbLog.info("Registration: Error occurred during first admin registration.") return render_template('oobe.html', form=registrationForm)
def _thread(cls): """Camera background thread.""" bbLog.info("Starting camera thread.") frames_iterator = cls.frames( ) # This references the frames function in camera_pi.py for frame in frames_iterator: BaseCamera.frame = frame BaseCamera.event.set() # send signal to clients time.sleep(0) # if there hasn't been any clients asking for frames in # the last 10 seconds OR if the post request has set global check to True # then stop the thread if time.time( ) - BaseCamera.last_access > 10 or routes.check == True: frames_iterator.close() bbLog.info("Stopping camera thread due to inactivity.") routes.check = False break BaseCamera.thread = None
def login(): # If the user somehow makes it to the login page without going through OOBE to make admin acct. Redirect them if attributes.query.filter_by(isAdmin=1).first(): # if a logged in user tries to view the login page, send them home if current_user.is_authenticated: bbLog.info(("Login: "******" is already logged in.")) return redirect(url_for('startPage')) login = forms.signIn() # Only run this when the form is submitted, not on page load if login.validate_on_submit(): # Query DB to get user usr = users.query.filter_by(username=login.username.data).first() if usr is None or not usr.check_password(login.password.data): flash("Incorrect Username or Password") bbLog.info("Login: User entered invalid credentials.") # Refresh page to show the flashed message return redirect(url_for('login')) login_user(usr, remember=login.remember.data) next_page = request.args.get('next') # 'next' will take the user to the last page they tried to visit before logging in # if that page required login and kicked them back to this page # .netloc ensures that the URL actually exists in the app and hasn't been injected if not next_page or url_parse(next_page).netloc != '': bbLog.info("Login: "******" has logged in.") next_page = url_for('startPage') return redirect(next_page) return render_template('login.html', form=login) else: return redirect(url_for('oobe'))
def register(): if attributes.query.filter_by(isAdmin=1).first(): if current_user.is_authenticated: bbLog.info("Registration: " + str(current_user) + " has already successfully registered.") return redirect(url_for('startPage')) registrationForm = forms.register() if registrationForm.validate_on_submit(): usr = users(username=registrationForm.username.data) usr.set_password(registrationForm.password.data) usr.email = registrationForm.email.data db.session.add(usr) db.session.commit() committedUser = users.query.filter_by(username=registrationForm.username.data).first() uid = committedUser.id attr = attributes(userID=uid, canFeed=1, style='light', isAdmin=0) db.session.add(attr) db.session.commit() flash("User Registered") bbLog.info("Registration: " + str(current_user) + " has successfully registered.") return redirect(url_for('login')) bbLog.info("Registration: Error occurred during registration.") return render_template('register.html', form=registrationForm) else: return redirect(url_for('oobe'))
def instant_feed(motor, run): try: motor.spin(run) except Exception as e: bbLog.info("An error occurred with the motor.") bbLog.info(e) else: bbLog.info("Motor function was successful.")
def schedule_settings(): form = forms.feed_schedule() attr = attributes.query.filter_by(userID=current_user.get_id()).first_or_404() can_feed = attr.check_feed() is_admin = attr.check_admin() theme = route_logic.get_user_theme() # Ensure the user has permission to view this form if can_feed: # If the form passes validation and is submitted if form.scheduledFeed.data and form.validate_on_submit(): # Get the current user's ID and load the attributes table for that usr (userID is FK with ID in users table) uid = current_user.get_id() attr = attributes.query.filter_by(userID=uid).first() # Set the attributes in the attributes table to the values in the form # Since SQLite does not have bools, some of this is passed to separate functions to convert bool to int attr.scheduleFeed = route_logic.convert_can_feed_from_form(form.scheduledFeed.data) attr.feedDays = route_logic.get_feed_days( form.feedDay_Monday.data, form.feedDay_Tuesday.data, form.feedDay_Wednesday.data, form.feedDay_Thursday.data, form.feedDay_Friday.data, form.feedDay_Saturday.data, form.feedDay_Sunday.data ) attr.feedHour = form.feedHour.data attr.feedMinute = str(form.feedMinute.data) # write changes to DB and flash a message to users db.session.commit() flash("Schedule Updated") bbLog.info(str(current_user) + " successfully updated their scheduled feed.") return render_template('scheduledFeedSettings.html', form=form, can_feed=can_feed, is_admin=is_admin, theme=theme) # if the form validates but the "schedule feed" checkbox is unchecked, disable scheduled feeding elif form.validate_on_submit(): attr.scheduleFeed = None attr.feedDays = None attr.feedHour = None attr.feedMinute = None flash('Scheduled feeding disabled') bbLog.info(str(current_user.username) + " disabled their scheduled feed") db.session.commit() if attr.scheduleFeed: # Auto populate form based on current settings bbLog.info("Populating " + current_user.username + " settings on feed schedule page") feeds = route_logic.get_Feed_Schedule(current_user.get_id()) form.scheduledFeed.data = True if 'Mon' in feeds[0].feed_days: form.feedDay_Monday.data = True if 'Tues' in feeds[0].feed_days: form.feedDay_Tuesday.data = True if 'Wed' in feeds[0].feed_days: form.feedDay_Wednesday.data = True if 'Thur' in feeds[0].feed_days: form.feedDay_Thursday.data = True if 'Fri' in feeds[0].feed_days: form.feedDay_Friday.data = True if 'Sat' in feeds[0].feed_days: form.feedDay_Saturday.data = True if 'Sun' in feeds[0].feed_days: form.feedDay_Sunday.data = True form.feedHour.data = feeds[0].feed_hour form.feedMinute.data = feeds[0].feed_minute else: # users that are logged in but do not have rights to view this page (and have navigated directly via URL) # Are bounced back to the starting page. return redirect(url_for('startPage')) # If form fails to validate, reload the page (this could be a first time visit, no form submission attempted) return render_template('scheduledFeedSettings.html', form=form, can_feed=can_feed, is_admin=is_admin, theme=theme)
def logout(): bbLog.info("Logout: " + str(current_user) + " has logged out.") logout_user() return redirect(url_for('login'))
from flask import Flask from config import configObject from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate from flask_login import LoginManager app = Flask(__name__) # Load our configuration from the config.py file for CSRF form security app.config.from_object(configObject) # Connect SQLAlchehmy to Database db = SQLAlchemy(app) # Connect DB migration tool to DB and SQLAlchemy migrate = Migrate(app, db) # Create instance of Flask_Login login manager loginManager = LoginManager(app) # Allow for "Login Required Decorator loginManager.login_view = 'login' from app import routes, models, schedule_pi from app.bb_log import bbLog schedule_pi.schedule_feed() # Scheduled feed thread initalization bbLog.info("Scheduled feed thread established.")