diff --git a/app/__init__.py b/app/__init__.py index e63cd40..3f12961 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,8 +1,13 @@ +import os from flask import Flask from config import Config +import logging +from loggin.handlers import RotatingFileHandler +from logging.handlers import SMTPHandler from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate from flask_login import LoginManager +from app import routes, models, errors app = Flask(__name__) app.config.from_object(Config) @@ -16,4 +21,36 @@ login = LoginManager(app) # sets de default login view login.login_view = "login" -from app import routes, models +if not app.debug: + if app.config["MAIL_SERVER"]: + auth = None + if app.config["MAIL_USERNAME"] or app.config["MAIL_PASSWORD"]: + auth = (app.config["MAIL_USERNAME"], app.config["MAIL_PASSWORD"]) + secure = None + if app.config["MAIL_USE_TLS"]: + secure = () + mail_handler = SMTPHandler( + mailhost=(app.config["MAIL_SERVER"], app.config["MAIL_PORT"]), + fromaddr="no-reply@" + app.config["MAIL_SERVER"], + toaddrs=app.config["ADMINS"], + subject="Microblog Failure", + credentials=auth, + secure=secure, + ) + mail_handler.setLevel(logging.ERROR) + app.logger.addHandler(mail_handler) + if not os.path.exists("logs"): + os.mkdir("logs") + file_handler = RotatingFileHandler( + "logs/microblog.log", maxBytes=10240, backupCount=10 + ) + file_handler.setFormatter( + logging.Formatter( + "%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]" + ) + ) + file_handler.setLevel(logging.INFO) + app.logger.addHandler(file_handler) + + app.logger.setLevel(logging.INFO) + app.logger.info("Microblog startup") diff --git a/app/errors.py b/app/errors.py new file mode 100644 index 0000000..447c6cd --- /dev/null +++ b/app/errors.py @@ -0,0 +1,13 @@ +from flask import render_template +from app import app, db + + +@app.errorhandler(404) +def not_found_error(error): + return render_template("404.html"), 404 + + +@app.errorhandler(500) +def internal_error(error): + db.session.rollback() + return render_template("500.html"), 500 diff --git a/app/forms.py b/app/forms.py index 87b0da3..f62d31a 100644 --- a/app/forms.py +++ b/app/forms.py @@ -47,3 +47,13 @@ class EditProfileForm(FlaskForm): username = StringField("Username", validators=[DataRequired()]) about_me = TextAreaField("About me", validators=[Length(min=0, max=140)]) submit = SubmitField("Submit") + + def __init__(self, original_username, *args, **kwargs): + super(EditProfileForm, self).__init__(*args, **kwargs) + self.original_username = original_username + + def validate_username(self, username): + if username.data != self.original_username: + user = User.query.filter_by(username=self.username.data).first() + if user is not None: + raise ValidationError("Please use a different username.") diff --git a/app/routes.py b/app/routes.py index 1ef9c86..1272572 100644 --- a/app/routes.py +++ b/app/routes.py @@ -81,7 +81,7 @@ def user(username): @app.route("/edit_profile", methods=["GET", "POST"]) @login_required def edit_profile(): - form = EditProfileForm() + form = EditProfileForm(current_user.username) if form.validate_on_submit(): current_user.username = form.username.data current_user.about_me = form.about_me.data diff --git a/app/templates/404.html b/app/templates/404.html new file mode 100644 index 0000000..9655dd8 --- /dev/null +++ b/app/templates/404.html @@ -0,0 +1,8 @@ +{% extends 'base.html' %} + +{% block content %} +
+ Back +
+{% endblock %} diff --git a/app/templates/500.html b/app/templates/500.html new file mode 100644 index 0000000..0f1eba7 --- /dev/null +++ b/app/templates/500.html @@ -0,0 +1,9 @@ +{% extends 'base.html' %} + +{% block content %} +The administrator has been notified. Sorry for the inconvenience!
++ Back +
+{% endblock %} diff --git a/config.py b/config.py index 694181f..6bed8d8 100644 --- a/config.py +++ b/config.py @@ -9,3 +9,9 @@ class Config(object): "DATABASE_URL" ) or "sqlite:///" + os.path.join(basedir, "app.db") SQLALCHEMY_TRACK_MODIFICATIONS = False + MAIL_SERVER = os.environ.get("MAIL_SERVER") + MAIL_PORT = int(os.environ.get("MAIL_PORT") or 25) + MAIL_USE_TLS = os.environ.get("MAIL_USE_TLS") is not None + MAIL_USERNAME = os.environ.get("MAIL_USERNAME") + MAIL_PASSWORD = os.environ.get("MAIL_PASSWORD") + ADMINS = ["your-email@example.com"]