lol
This commit is contained in:
240
app.py
240
app.py
@@ -5,14 +5,10 @@ from datetime import datetime
|
||||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
from werkzeug.utils import secure_filename
|
||||
import os
|
||||
from config import Config
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['SECRET_KEY'] = os.urandom(24)
|
||||
# Use DATABASE_URL from environment if available, else default to SQLite
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'sqlite:///site.db')
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
app.config['UPLOAD_FOLDER'] = 'static/uploads'
|
||||
app.config['MAX_CONTENT_LENGTH'] = 2 * 1024 * 1024 # 2MB max file size
|
||||
app.config.from_object(Config)
|
||||
|
||||
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
|
||||
|
||||
@@ -23,7 +19,7 @@ migrate = Migrate(app, db)
|
||||
class User(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
username = db.Column(db.String(80), unique=True, nullable=False)
|
||||
password_hash = db.Column(db.String(128), nullable=False)
|
||||
password_hash = db.Column(db.String(256), nullable=False)
|
||||
|
||||
def set_password(self, password):
|
||||
self.password_hash = generate_password_hash(password)
|
||||
@@ -270,6 +266,14 @@ def manage_environments():
|
||||
description = request.form['description']
|
||||
icon_file = request.files.get('icon')
|
||||
icon_filename = None
|
||||
if not name:
|
||||
flash('Name is required!', 'danger')
|
||||
print('No name provided')
|
||||
return redirect(url_for('manage_environments'))
|
||||
if Environment.query.filter_by(name=name).first():
|
||||
flash('Environment with this name already exists!', 'danger')
|
||||
print('Duplicate environment name')
|
||||
return redirect(url_for('manage_environments'))
|
||||
if icon_file and icon_file.filename:
|
||||
icon_filename = secure_filename(icon_file.filename)
|
||||
icon_path = os.path.join('static/icons', icon_filename)
|
||||
@@ -278,11 +282,18 @@ def manage_environments():
|
||||
icon_file.save(icon_path)
|
||||
except Exception as e:
|
||||
print('Error saving icon:', e)
|
||||
flash(f'Error saving icon: {e}', 'danger')
|
||||
try:
|
||||
environment = Environment(name=name, description=description, icon=icon_filename)
|
||||
db.session.add(environment)
|
||||
db.session.commit()
|
||||
flash('Environment added successfully!', 'success')
|
||||
return redirect(url_for('manage_environments'))
|
||||
print('Environment added:', name)
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print('Error adding environment:', e)
|
||||
flash(f'Error adding environment: {e}', 'danger')
|
||||
return redirect(url_for('manage_environments'))
|
||||
environments = Environment.query.all()
|
||||
return render_template('manage_environments.html',
|
||||
environments=environments,
|
||||
@@ -339,6 +350,14 @@ def manage_climates():
|
||||
description = request.form['description']
|
||||
icon_file = request.files.get('icon')
|
||||
icon_filename = None
|
||||
if not name:
|
||||
flash('Name is required!', 'danger')
|
||||
print('No name provided')
|
||||
return redirect(url_for('manage_climates'))
|
||||
if Climate.query.filter_by(name=name).first():
|
||||
flash('Climate with this name already exists!', 'danger')
|
||||
print('Duplicate climate name')
|
||||
return redirect(url_for('manage_climates'))
|
||||
if icon_file and icon_file.filename:
|
||||
icon_filename = secure_filename(icon_file.filename)
|
||||
icon_path = os.path.join('static/icons', icon_filename)
|
||||
@@ -347,11 +366,18 @@ def manage_climates():
|
||||
icon_file.save(icon_path)
|
||||
except Exception as e:
|
||||
print('Error saving icon:', e)
|
||||
flash(f'Error saving icon: {e}', 'danger')
|
||||
try:
|
||||
climate = Climate(name=name, description=description, icon=icon_filename)
|
||||
db.session.add(climate)
|
||||
db.session.commit()
|
||||
flash('Climate added successfully!', 'success')
|
||||
return redirect(url_for('manage_climates'))
|
||||
print('Climate added:', name)
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print('Error adding climate:', e)
|
||||
flash(f'Error adding climate: {e}', 'danger')
|
||||
return redirect(url_for('manage_climates'))
|
||||
climates = Climate.query.all()
|
||||
return render_template('manage_climates.html',
|
||||
climates=climates,
|
||||
@@ -470,30 +496,59 @@ def new_plant():
|
||||
picture_file = request.files.get('picture')
|
||||
picture_filename = None
|
||||
|
||||
# Required field checks
|
||||
if not name:
|
||||
flash('Name is required!', 'danger')
|
||||
print('No name provided')
|
||||
return redirect(url_for('new_plant'))
|
||||
if not climate_id:
|
||||
flash('Climate is required!', 'danger')
|
||||
print('No climate provided')
|
||||
return redirect(url_for('new_plant'))
|
||||
if not environment_id:
|
||||
flash('Environment is required!', 'danger')
|
||||
print('No environment provided')
|
||||
return redirect(url_for('new_plant'))
|
||||
if Plant.query.filter_by(name=name).first():
|
||||
flash('A plant with this name already exists!', 'danger')
|
||||
print('Duplicate plant name')
|
||||
return redirect(url_for('new_plant'))
|
||||
|
||||
if picture_file and picture_file.filename:
|
||||
filename = secure_filename(picture_file.filename)
|
||||
picture_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
||||
picture_file.save(picture_path)
|
||||
picture_filename = filename
|
||||
try:
|
||||
picture_file.save(picture_path)
|
||||
picture_filename = filename
|
||||
except Exception as e:
|
||||
print('Error saving plant picture:', e)
|
||||
flash(f'Error saving plant picture: {e}', 'danger')
|
||||
|
||||
plant = Plant(
|
||||
name=name,
|
||||
picture=picture_filename,
|
||||
climate_id=climate_id,
|
||||
environment_id=environment_id,
|
||||
light_id=light_id,
|
||||
toxicity_id=toxicity_id,
|
||||
size_id=size_id,
|
||||
care_difficulty_id=care_difficulty_id,
|
||||
growth_rate_id=growth_rate_id,
|
||||
products=','.join(product_ids),
|
||||
description=description,
|
||||
care_guide=care_guide
|
||||
)
|
||||
db.session.add(plant)
|
||||
db.session.commit()
|
||||
flash('Your plant has been added!', 'success')
|
||||
return redirect(url_for('home'))
|
||||
try:
|
||||
plant = Plant(
|
||||
name=name,
|
||||
picture=picture_filename,
|
||||
climate_id=climate_id,
|
||||
environment_id=environment_id,
|
||||
light_id=light_id,
|
||||
toxicity_id=toxicity_id,
|
||||
size_id=size_id,
|
||||
care_difficulty_id=care_difficulty_id,
|
||||
growth_rate_id=growth_rate_id,
|
||||
products=','.join(product_ids),
|
||||
description=description,
|
||||
care_guide=care_guide
|
||||
)
|
||||
db.session.add(plant)
|
||||
db.session.commit()
|
||||
flash('Your plant has been added!', 'success')
|
||||
print('Plant added:', name)
|
||||
return redirect(url_for('manage_plants', add=1))
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print('Error adding plant:', e)
|
||||
flash(f'Error adding plant: {e}', 'danger')
|
||||
return redirect(url_for('new_plant'))
|
||||
|
||||
climates = Climate.query.all()
|
||||
environments = Environment.query.all()
|
||||
@@ -591,20 +646,37 @@ def manage_plants():
|
||||
climates = Climate.query.all()
|
||||
environments = Environment.query.all()
|
||||
products = Product.query.all()
|
||||
lights = Light.query.order_by(Light.name).all()
|
||||
toxicities = Toxicity.query.order_by(Toxicity.name).all()
|
||||
sizes = Size.query.order_by(Size.name).all()
|
||||
difficulties = CareDifficulty.query.order_by(CareDifficulty.name).all()
|
||||
growth_rates = GrowthRate.query.order_by(GrowthRate.name).all()
|
||||
|
||||
# Create dictionaries for easy lookup
|
||||
climates_dict = {climate.id: climate.name for climate in climates}
|
||||
environments_dict = {env.id: env.name for env in environments}
|
||||
|
||||
return render_template('manage_plants.html',
|
||||
plants=plants,
|
||||
climates=climates,
|
||||
environments=environments,
|
||||
climates=climates, # list for form
|
||||
environments=environments, # list for form
|
||||
climates_dict=climates_dict, # dict for table
|
||||
environments_dict=environments_dict, # dict for table
|
||||
products=products,
|
||||
lights=lights,
|
||||
toxicities=toxicities,
|
||||
sizes=sizes,
|
||||
difficulties=difficulties,
|
||||
growth_rates=growth_rates,
|
||||
plant_count=len(plants),
|
||||
climate_count=len(climates),
|
||||
environment_count=len(environments),
|
||||
product_count=len(products),
|
||||
light_count=len(Light.query.all()),
|
||||
toxicity_count=len(Toxicity.query.all()),
|
||||
size_count=len(Size.query.all()),
|
||||
difficulty_count=len(CareDifficulty.query.all()),
|
||||
rate_count=len(GrowthRate.query.all()))
|
||||
light_count=len(lights),
|
||||
toxicity_count=len(toxicities),
|
||||
size_count=len(sizes),
|
||||
difficulty_count=len(difficulties),
|
||||
rate_count=len(growth_rates))
|
||||
|
||||
@app.route('/admin/attributes')
|
||||
def manage_attributes():
|
||||
@@ -634,6 +706,14 @@ def manage_lights():
|
||||
description = request.form['description']
|
||||
icon_file = request.files.get('icon')
|
||||
icon_filename = None
|
||||
if not name:
|
||||
flash('Name is required!', 'danger')
|
||||
print('No name provided')
|
||||
return redirect(url_for('manage_lights'))
|
||||
if Light.query.filter_by(name=name).first():
|
||||
flash('Light requirement with this name already exists!', 'danger')
|
||||
print('Duplicate light name')
|
||||
return redirect(url_for('manage_lights'))
|
||||
if icon_file and icon_file.filename:
|
||||
icon_filename = secure_filename(icon_file.filename)
|
||||
icon_path = os.path.join('static/icons', icon_filename)
|
||||
@@ -642,11 +722,18 @@ def manage_lights():
|
||||
icon_file.save(icon_path)
|
||||
except Exception as e:
|
||||
print('Error saving icon:', e)
|
||||
flash(f'Error saving icon: {e}', 'danger')
|
||||
try:
|
||||
light = Light(name=name, description=description, icon=icon_filename)
|
||||
db.session.add(light)
|
||||
db.session.commit()
|
||||
flash('Light requirement added successfully!', 'success')
|
||||
return redirect(url_for('manage_lights'))
|
||||
print('Light added:', name)
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print('Error adding light:', e)
|
||||
flash(f'Error adding light: {e}', 'danger')
|
||||
return redirect(url_for('manage_lights'))
|
||||
lights = Light.query.all()
|
||||
return render_template('manage_lights.html',
|
||||
lights=lights,
|
||||
@@ -703,6 +790,14 @@ def manage_toxicities():
|
||||
description = request.form['description']
|
||||
icon_file = request.files.get('icon')
|
||||
icon_filename = None
|
||||
if not name:
|
||||
flash('Name is required!', 'danger')
|
||||
print('No name provided')
|
||||
return redirect(url_for('manage_toxicities'))
|
||||
if Toxicity.query.filter_by(name=name).first():
|
||||
flash('Toxicity with this name already exists!', 'danger')
|
||||
print('Duplicate toxicity name')
|
||||
return redirect(url_for('manage_toxicities'))
|
||||
if icon_file and icon_file.filename:
|
||||
icon_filename = secure_filename(icon_file.filename)
|
||||
icon_path = os.path.join('static/icons', icon_filename)
|
||||
@@ -711,11 +806,18 @@ def manage_toxicities():
|
||||
icon_file.save(icon_path)
|
||||
except Exception as e:
|
||||
print('Error saving icon:', e)
|
||||
flash(f'Error saving icon: {e}', 'danger')
|
||||
try:
|
||||
toxicity = Toxicity(name=name, description=description, icon=icon_filename)
|
||||
db.session.add(toxicity)
|
||||
db.session.commit()
|
||||
flash('Toxicity level added successfully!', 'success')
|
||||
return redirect(url_for('manage_toxicities'))
|
||||
print('Toxicity added:', name)
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print('Error adding toxicity:', e)
|
||||
flash(f'Error adding toxicity: {e}', 'danger')
|
||||
return redirect(url_for('manage_toxicities'))
|
||||
toxicities = Toxicity.query.all()
|
||||
return render_template('manage_toxicities.html',
|
||||
toxicities=toxicities,
|
||||
@@ -772,6 +874,14 @@ def manage_sizes():
|
||||
description = request.form['description']
|
||||
icon_file = request.files.get('icon')
|
||||
icon_filename = None
|
||||
if not name:
|
||||
flash('Name is required!', 'danger')
|
||||
print('No name provided')
|
||||
return redirect(url_for('manage_sizes'))
|
||||
if Size.query.filter_by(name=name).first():
|
||||
flash('Size with this name already exists!', 'danger')
|
||||
print('Duplicate size name')
|
||||
return redirect(url_for('manage_sizes'))
|
||||
if icon_file and icon_file.filename:
|
||||
icon_filename = secure_filename(icon_file.filename)
|
||||
icon_path = os.path.join('static/icons', icon_filename)
|
||||
@@ -780,11 +890,18 @@ def manage_sizes():
|
||||
icon_file.save(icon_path)
|
||||
except Exception as e:
|
||||
print('Error saving icon:', e)
|
||||
flash(f'Error saving icon: {e}', 'danger')
|
||||
try:
|
||||
size = Size(name=name, description=description, icon=icon_filename)
|
||||
db.session.add(size)
|
||||
db.session.commit()
|
||||
flash('Size category added successfully!', 'success')
|
||||
return redirect(url_for('manage_sizes'))
|
||||
print('Size added:', name)
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print('Error adding size:', e)
|
||||
flash(f'Error adding size: {e}', 'danger')
|
||||
return redirect(url_for('manage_sizes'))
|
||||
sizes = Size.query.all()
|
||||
return render_template('manage_sizes.html',
|
||||
sizes=sizes,
|
||||
@@ -841,6 +958,14 @@ def manage_care_difficulties():
|
||||
description = request.form['description']
|
||||
icon_file = request.files.get('icon')
|
||||
icon_filename = None
|
||||
if not name:
|
||||
flash('Name is required!', 'danger')
|
||||
print('No name provided')
|
||||
return redirect(url_for('manage_care_difficulties'))
|
||||
if CareDifficulty.query.filter_by(name=name).first():
|
||||
flash('Care difficulty with this name already exists!', 'danger')
|
||||
print('Duplicate care difficulty name')
|
||||
return redirect(url_for('manage_care_difficulties'))
|
||||
if icon_file and icon_file.filename:
|
||||
icon_filename = secure_filename(icon_file.filename)
|
||||
icon_path = os.path.join('static/icons', icon_filename)
|
||||
@@ -849,11 +974,18 @@ def manage_care_difficulties():
|
||||
icon_file.save(icon_path)
|
||||
except Exception as e:
|
||||
print('Error saving icon:', e)
|
||||
flash(f'Error saving icon: {e}', 'danger')
|
||||
try:
|
||||
difficulty = CareDifficulty(name=name, description=description, icon=icon_filename)
|
||||
db.session.add(difficulty)
|
||||
db.session.commit()
|
||||
flash('Care difficulty level added successfully!', 'success')
|
||||
return redirect(url_for('manage_care_difficulties'))
|
||||
print('Care difficulty added:', name)
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print('Error adding care difficulty:', e)
|
||||
flash(f'Error adding care difficulty: {e}', 'danger')
|
||||
return redirect(url_for('manage_care_difficulties'))
|
||||
difficulties = CareDifficulty.query.all()
|
||||
return render_template('manage_care_difficulties.html',
|
||||
difficulties=difficulties,
|
||||
@@ -910,6 +1042,14 @@ def manage_growth_rates():
|
||||
description = request.form['description']
|
||||
icon_file = request.files.get('icon')
|
||||
icon_filename = None
|
||||
if not name:
|
||||
flash('Name is required!', 'danger')
|
||||
print('No name provided')
|
||||
return redirect(url_for('manage_growth_rates'))
|
||||
if GrowthRate.query.filter_by(name=name).first():
|
||||
flash('Growth rate with this name already exists!', 'danger')
|
||||
print('Duplicate growth rate name')
|
||||
return redirect(url_for('manage_growth_rates'))
|
||||
if icon_file and icon_file.filename:
|
||||
icon_filename = secure_filename(icon_file.filename)
|
||||
icon_path = os.path.join('static/icons', icon_filename)
|
||||
@@ -918,11 +1058,18 @@ def manage_growth_rates():
|
||||
icon_file.save(icon_path)
|
||||
except Exception as e:
|
||||
print('Error saving icon:', e)
|
||||
flash(f'Error saving icon: {e}', 'danger')
|
||||
try:
|
||||
rate = GrowthRate(name=name, description=description, icon=icon_filename)
|
||||
db.session.add(rate)
|
||||
db.session.commit()
|
||||
flash('Growth rate category added successfully!', 'success')
|
||||
return redirect(url_for('manage_growth_rates'))
|
||||
print('Growth rate added:', name)
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print('Error adding growth rate:', e)
|
||||
flash(f'Error adding growth rate: {e}', 'danger')
|
||||
return redirect(url_for('manage_growth_rates'))
|
||||
rates = GrowthRate.query.all()
|
||||
return render_template('manage_growth_rates.html',
|
||||
rates=rates,
|
||||
@@ -1147,4 +1294,15 @@ def seed_db():
|
||||
db.session.commit()
|
||||
|
||||
if __name__ == "__main__":
|
||||
with app.app_context():
|
||||
db.create_all() # Create all tables
|
||||
# Create admin user if it doesn't exist
|
||||
admin = User.query.filter_by(username='admin').first()
|
||||
if not admin:
|
||||
admin = User(username='admin')
|
||||
admin.set_password('admin123') # Set a default password
|
||||
db.session.add(admin)
|
||||
db.session.commit()
|
||||
print("Admin user created with username: admin and password: admin123")
|
||||
seed_db() # Seed initial data
|
||||
app.run(debug=True)
|
||||
Reference in New Issue
Block a user