1
0
forked from orson/bachemap
bachemap/app.py

230 lines
9.2 KiB
Python
Raw Normal View History

2024-08-21 19:38:01 +00:00
from flask import Flask, render_template, request, redirect, url_for, flash, send_from_directory
from flask_pymongo import PyMongo, ObjectId
from flask_login import LoginManager, UserMixin, login_user, login_required, current_user, logout_user
2024-08-17 19:05:28 +00:00
from werkzeug.utils import secure_filename
from werkzeug.security import generate_password_hash, check_password_hash
2024-08-21 19:38:01 +00:00
from datetime import datetime
from flask_pymongo import ObjectId
2024-08-17 19:05:28 +00:00
import os
from uuid import uuid4
from flask_wtf import FlaskForm
from wtforms import StringField, FileField, SubmitField, DateTimeField, SelectField, PasswordField
from wtforms.validators import DataRequired, Length
2024-08-17 19:05:28 +00:00
def create_app():
app = Flask(__name__)
app.config["MONGO_URI"] = "mongodb://localhost:27017/mapDB"
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['SECRET_KEY'] = 'supersecretkey'
app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'gif'}
2024-08-17 19:05:28 +00:00
mongo = PyMongo(app)
login_manager = LoginManager(app)
login_manager.session_protection = "strong"
2024-08-21 19:38:01 +00:00
#form = PinForm()
2024-08-17 19:05:28 +00:00
class User(UserMixin):
def __init__(self, user_data):
self.id = str(user_data['_id'])
self.username = user_data['username']
self.referral_code = user_data['referral_code']
self.invited_by = user_data.get('invited_by')
self.is_admin = user_data.get('is_admin', False)
self.pwd = user_data.get('pwd')
@staticmethod
def get(user_id):
user_data = mongo.db.users.find_one({"_id": ObjectId(user_id)})
if user_data:
return User(user_data)
else:
return None
class PinForm(FlaskForm):
description = StringField('Description', validators=[DataRequired()])
photo = FileField('Evidencia fotogénica', validators=[DataRequired()])
timedate = DateTimeField(default=datetime.now())
typeofpin = SelectField('Tipo de cosa', choices=['bache', 'coladera', 'obra sin terminar', 'escombro', 'robo-asalto', 'biciestacionamiento', 'mala iluminación'])
submit = SubmitField('Agregar')
class LoginForm(FlaskForm):
username = StringField('Usuario', validators=[DataRequired()])
pwd = PasswordField('Tu clave', validators=[DataRequired()])
submit = SubmitField('Entrar')
def Unique(model, field, message=None):
def _unique(form, field_data):
if mongo.db[model.__name__.lower()].find_one({field.name: field_data.data}):
raise ValidationError(message or f"{field.name} must be unique.")
return _unique
class RegistrationForm(FlaskForm):
username = StringField('Nombre de usuarix', validators=[DataRequired(), Unique('users', StringField('username', message="Username already exists"))])
pwd = PasswordField('Clave', validators=[DataRequired(), Length(min=10), Unique('users', StringField('pwd', message="Username already exists"))])
referral = StringField('ID de quien te invito', [DataRequired()])
submit = SubmitField('Registrar')
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'GET':
form = PinForm()
pins = mongo.db.pins.find()
return render_template('index.html', pins=pins, form=form)
else:
#@app.route('/add_pin')
#def add_pin():
form = request.form
# if form.validate_on_submit():
#description = form.description.data
try:
photo = request.files["photo"]
except Exception as e:
print(e)
if photo and allowed_file(photo.filename):
#try:
filename = secure_filename(photo.filename)
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
photo.save(filepath)
pin = {
#'description': description,
'time': datetime.now(),
'photo': filepath,
'lat': request.form['lat'],
'lng': request.form['lng'],
'typeofpin': request.form['typeofpin'],
'added_by': current_user.id,
}
mongo.db.pins.insert_one(pin)
flash('¡Gracias por tu aportación!')
return redirect(url_for('index'))
else:
return allowed_file(photo.filename), 404
#render_template('index.html', pins=pins, form=form)
#except Exception as e:
# flash(f'An error occurred: {e}')
#return redirect(url_for('add_pin'))
#else:
# flash('Invalid file type. Only images are allowed.')
#return render_template('index.html', form=form)
@app.route('/quienes')
def quienes():
return render_template('quienes.html')
@app.route('/uploads/<name>')
def download_file(name):
return send_from_directory(app.config["UPLOAD_FOLDER"], name)
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id)
@app.route('/registrame/<referral_code>', methods=['GET', 'POST'])
def registrame(referral_code):
inviter = mongo.db.users.find_one({"referral_code": referral_code})
if not inviter:
return "Ooops, parece que nadie te invitó aquí", 404
if request.method == 'POST':
username = request.form['username']
pwd = request.form['pwd']
new_user_data = {
"username": username,
"pwd": generate_password_hash(pwd),
"referral_code": str(uuid4()),
"invited_by": str(inviter['_id']),
"is_admin": False
2024-08-21 19:38:01 +00:00
}
new_user_id = mongo.db.users.insert_one(new_user_data).inserted_id
invite_link = url_for('registrame', referral_code=new_user_data['referral_code'], _external=True)
return render_template('dashboard.html', invite_link=invite_link)
if request.method == 'GET':
return render_template('register.html', form=RegistrationForm())
@app.route('/thelogin', methods=['GET', 'POST'])
def thelogin():
form2 = LoginForm()
if request.method == 'POST':
username = request.form['username']
pwd = request.form['pwd']
user_data = mongo.db.users.find_one({"username": username})
if user_data and check_password_hash(user_data['pwd'], pwd):
user = User(user_data)
login_user(user)
return redirect(url_for('dashboard'))
else:
return render_template('login.html', messages = 'Ooops, no hay tal usuario', form=form2)
return render_template('login.html',form=form2)
@app.route('/logout')
@login_required
def logout():
logout_user()
flash('Cerraste sesión exitosamente')
return redirect('/')
@app.route('/desheredame/<user_id>')
@login_required
def desheredame(user_id):
if not current_user.is_admin:
return redirect(url_for('index'))
else:
user_to_remove = mongo.db.users.find_one({"invited_by": user_id})
if not user_to_remove:
return "A este ya me lo desheredaron", 404
else:
mongo.db.users.delete_many({"invited_by": user_id})
mongo.db.users.delete_one({"_id": ObjectId(user_id)})
mongo.db.pins.delete_many({"user_id": user_id})
return redirect(url_for('dashboard'))
@app.route("/remove_pin/<pin_id>")
@login_required
def remove_pin(pin_id):
actual_pin = mongo.db.pins.find_one({"_id": pin_id})
added_by = actual_pin.added_by
if not current_user.is_admin or current_user.id != added_by:
2024-08-21 19:38:01 +00:00
return redirect(url_for('index'))
2024-08-17 19:05:28 +00:00
else:
mongo.db.pins.delete_one({"_id": ObjectId(pin_id)})
return redirect(url_for('dashboard'))
@app.route('/dashboard')
@login_required
def dashboard():
if not current_user.is_authenticated:
return redirect(url_for('thelogin'))
if not current_user.is_admin:
pins = list(mongo.db.pins.find({"added_by": current_user.id}))
return render_template('dashboard.html', pins=pins)
if current_user.is_admin:
users = list(mongo.db.users.find())
pins = list(mongo.db.pins.find())
return render_template('dashboard.html', users=users, pins=pins)
@app.cli.command('add_user')
def add_user():
username = input("Enter Username:\n")
pwd = input("Add pass:\n")
admin_user = {
"username": username,
"pwd": generate_password_hash(pwd),
"referral_code": str(uuid4()),
"invited_by": None,
"is_admin": True
}
mongo.db.users.insert_one(admin_user)
print(f"Admin {username} added! Referral code is {admin_user['referral_code']}")
return app
2024-08-17 19:05:28 +00:00
app=create_app()
2024-08-17 19:05:28 +00:00
if __name__ == '__main__':
app.run(debug=True)