Walter Mantovani commited on
Commit
f1d2cf1
·
1 Parent(s): be4de6a

First test

Browse files
.gitignore ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # macos
2
+ .DS_Store
3
+
4
+ # jupyter notebook server
5
+ .ipynb_checkpoints/
6
+
7
+ # various virtualenvs
8
+ .venv/
9
+ env/
10
+
11
+ # compiled python files
12
+ __pycache__/
13
+ *.py[co]
14
+
15
+ # backup files
16
+ # *~
17
+
18
+ # vs code
19
+ *.code-workspace
20
+ settings.json
21
+
22
+ # custom folders
23
+ _tmp/
24
+ _soluzioni/
25
+ .assets/
Dockerfile ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use the official Python 3.9 image
2
+ FROM python:3.11
3
+
4
+ # Set the working directory to /code
5
+ WORKDIR /code
6
+
7
+ # Copy the current directory contents into the container at /code
8
+ COPY ./requirements.txt /code/requirements.txt
9
+
10
+ # Install requirements.txt
11
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
12
+
13
+ # Set up a new user named "user" with user ID 1000
14
+ RUN useradd -m -u 1000 user
15
+ # Switch to the "user" user
16
+ USER user
17
+ # Set home to the user's home directory
18
+ ENV HOME=/home/user \
19
+ PATH=/home/user/.local/bin:$PATH
20
+
21
+ # Set the working directory to the user's home directory
22
+ WORKDIR $HOME/app
23
+
24
+ # Copy the current directory contents into the container at $HOME/app setting the owner to the user
25
+ COPY --chown=user . $HOME/app
26
+
27
+ # CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
28
+ CMD ["flask", "run", "--host=0.0.0.0"]
29
+ # CMD ["python", "-m", "flask", "run", "--host=0.0.0.0"]
app.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from flask import Flask, render_template, request, session, redirect, flash, url_for, jsonify
3
+ from flask_sqlalchemy import SQLAlchemy
4
+ from markupsafe import escape
5
+
6
+ BASE_DIR_PATH = os.path.abspath(os.path.dirname(__file__))
7
+ DATABASE_PATH = os.path.join(BASE_DIR_PATH, 'db.sqlite3')
8
+
9
+ app = Flask(__name__)
10
+ app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+DATABASE_PATH
11
+ app.config['SECRET_KEY'] = 'mysecretkey'
12
+ db = SQLAlchemy(app)
13
+
14
+ class Utente(db.Model):
15
+ id = db.Column(db.Integer, primary_key=True, autoincrement=True)
16
+ nickname = db.Column(db.String(80), unique=True, nullable=False)
17
+ username = db.Column(db.String(80), unique=True, nullable=False)
18
+ password = db.Column(db.String(30), nullable=False)
19
+ # messaggi = db.relationship('Messaggio', backref=db.backref('user', lazy='dynamic'))
20
+ # --- OR ---
21
+ messaggi = db.relationship('Messaggio', back_populates='user', lazy='dynamic')
22
+
23
+ class Messaggio(db.Model):
24
+ id = db.Column(db.Integer, primary_key=True)
25
+ user_id = db.Column(db.Integer, db.ForeignKey('utente.id'), nullable=False)
26
+ messaggio = db.Column(db.Text, nullable=False)
27
+ timestamp = db.Column(db.DateTime, default=db.func.now(), nullable=False)
28
+ # user = db.relationship('Utente', backref=db.backref('messaggi', lazy='dynamic'))
29
+ # --- OR ---
30
+ user = db.relationship('Utente', back_populates='messaggi')
31
+
32
+
33
+ @app.route('/')
34
+ def home():
35
+ if 'user_id' in session:
36
+ user = db.session.query(Utente).get(session['user_id'])
37
+ return render_template('home.html', user=user)
38
+ return render_template('home.html')
39
+
40
+
41
+ @app.route('/guestbook')
42
+ def guestbook():
43
+ if 'user_id' not in session:
44
+ return redirect(url_for('login'))
45
+ return render_template('guestbook.html')
46
+
47
+ @app.route('/api/guestbook', methods=['GET', 'POST'])
48
+ def api_guestbook():
49
+ if 'user_id' not in session:
50
+ return jsonify({'error': 'Accesso non autorizzato.'}), 401
51
+
52
+ if request.method == 'POST':
53
+ messaggio = request.json.get('messaggio')
54
+ if not messaggio:
55
+ return jsonify({'error': 'Il messaggio non può essere vuoto!'}), 400
56
+ new_message = Messaggio(user_id=session['user_id'], messaggio=escape(messaggio))
57
+ db.session.add(new_message)
58
+ db.session.commit()
59
+ return jsonify({'success': True}), 201
60
+
61
+ messages = Messaggio.query.order_by(Messaggio.timestamp.desc()).all()
62
+ response = [
63
+ {'nickname': message.user.nickname, 'messaggio': message.messaggio}
64
+ for message in messages
65
+ ]
66
+ return jsonify(response), 200
67
+
68
+
69
+
70
+ @app.route('/signup', methods=['GET', 'POST'])
71
+ def signup():
72
+ if request.method == 'POST':
73
+ nickname = request.form.get('nickname')
74
+ username = request.form.get('username')
75
+ password = request.form.get('password')
76
+ if not nickname or not username or not password:
77
+ flash('Tutti i campi sono obbligatori!')
78
+ return redirect(url_for('signup'))
79
+ if Utente.query.filter_by(username=username).first() or Utente.query.filter_by(nickname=nickname).first():
80
+ flash("Il nickname o l'username sono già in uso!")
81
+ return redirect(url_for('signup'))
82
+ new_user = Utente(nickname=nickname, username=username, password=password)
83
+ db.session.add(new_user)
84
+ db.session.commit()
85
+ flash('Registrazione effettuata con successo!')
86
+ return redirect(url_for('login'))
87
+ return render_template('signup.html')
88
+
89
+
90
+ @app.route('/login', methods=['GET', 'POST'])
91
+ def login():
92
+ if request.method == 'POST':
93
+ username = request.form['username']
94
+ password = request.form['password']
95
+ user = Utente.query.filter_by(username=username, password=password).first()
96
+ if user:
97
+ session['user_id'] = user.id
98
+ flash('Login riuscito!')
99
+ return redirect(url_for('guestbook'))
100
+ else:
101
+ flash('Credenziali non valide!')
102
+ return redirect(url_for('login'))
103
+ return render_template('login.html')
104
+
105
+ @app.route('/logout')
106
+ def logout():
107
+ session.pop('user_id', None)
108
+ flash('Logout effettuato con successo!')
109
+ return redirect(url_for('home'))
110
+
111
+
112
+ if __name__ == '__main__':
113
+ with app.app_context():
114
+ db.create_all()
115
+ app.run(debug=True)
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ Flask
2
+ Flask-SQLAlchemy
templates/guestbook.html ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Guestbook</title>
8
+ </head>
9
+
10
+ <body>
11
+ <h2>Guestbook</h2>
12
+
13
+ <!-- Mostra i messaggi flash -->
14
+ {% include 'includes/flash.html' %}
15
+
16
+ <form id="message-form">
17
+ <textarea id="message" name="message" required></textarea><br>
18
+ <button type="submit">Submit</button>
19
+ </form>
20
+
21
+ <h3>Messages:</h3>
22
+
23
+ <ul id="messages-list"></ul>
24
+
25
+ <script>
26
+ // Azioni da eseguire quando il DOM è pronto
27
+ document.addEventListener('DOMContentLoaded', () => {
28
+ // Legge e mostra i messaggi al caricamento della pagina
29
+ loadMessages();
30
+ // Aggiunge un event listener al pulsante di invio del messaggio
31
+ document.getElementById('message-form').addEventListener('submit', sendMessage);
32
+ });
33
+
34
+ // Funzione per inviare un messaggio al guestbook
35
+ async function sendMessage(event) {
36
+ event.preventDefault();
37
+ let messageTextarea = document.getElementById('message')
38
+ const message = messageTextarea.value;
39
+ const response = await fetch('/api/guestbook', {
40
+ method: 'POST',
41
+ headers: { 'Content-Type': 'application/json' },
42
+ body: JSON.stringify({messaggio: message})
43
+ });
44
+ const result = await response.json();
45
+ if (result.success) {
46
+ loadMessages();
47
+ messageTextarea.value = '';
48
+ // document.getElementById('message-form').reset();
49
+ } else if (result.error){
50
+ alert(result.error);
51
+ } else {
52
+ alert("Errore sconosciuto durante l'invio del messaggio.");
53
+ }
54
+ }
55
+
56
+ // Funzione per leggere i messaggi dal guestbook
57
+ async function loadMessages() {
58
+ const response = await fetch('/api/guestbook');
59
+ const messages = await response.json();
60
+ const messagesList = document.getElementById('messages-list');
61
+ messagesList.innerHTML = '';
62
+ messages.forEach(message => {
63
+ const li = document.createElement('li');
64
+ li.textContent = `${message.nickname}: ${message.messaggio}`;
65
+ messagesList.appendChild(li);
66
+ });
67
+ }
68
+ </script>
69
+ </body>
70
+
71
+ </html>
templates/home.html ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Home</title>
8
+ </head>
9
+
10
+ <body>
11
+ <h2>Home</h2>
12
+
13
+ <!-- Mostra i messaggi flash -->
14
+ {% include 'includes/flash.html' %}
15
+
16
+ {% if 'user_id' in session %}
17
+ <p>Benvenuto, {{ user.username }} detto {{ user.nickname }}!</p>
18
+ <p><a href="{{ url_for('guestbook') }}">Vai al Guestbook</a>.</p>
19
+ <p>Oppure <a href="{{ url_for('logout') }}">fai il Logout</a>.</p>
20
+ {% else %}
21
+ <p>
22
+ Per accedere fai il <a href="{{ url_for('login') }}">Login</a>
23
+ oppure, se non hai un account, fai il <a href="{{ url_for('signup') }}">Sign Up</a>
24
+ </p>
25
+ {% endif %}
26
+
27
+ </body>
28
+
29
+ </html>
templates/includes/flash.html ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <!-- Mostra i messaggi flash -->
2
+ {% with messages = get_flashed_messages() %}
3
+ {% if messages %}
4
+ {% for message in messages %}
5
+ <p>{{ message }}</p>
6
+ {% endfor %}
7
+ {% endif %}
8
+ {% endwith %}
templates/login.html ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Login</title>
8
+ </head>
9
+
10
+ <body>
11
+ <h2>Login</h2>
12
+
13
+ <form method="POST" action="/login">
14
+ <label for="username">Username:</label>
15
+ <input type="text" id="username" name="username" required><br>
16
+ <label for="password">Password:</label>
17
+ <input type="password" id="password" name="password" required><br>
18
+ <button type="submit">Login</button>
19
+ </form>
20
+
21
+ <!-- Mostra i messaggi flash -->
22
+ {% include 'includes/flash.html' %}
23
+
24
+ </body>
25
+
26
+ </html>
templates/signup.html ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Sign Up</title>
8
+ </head>
9
+
10
+ <body>
11
+ <h2>Sign Up</h2>
12
+
13
+ <form method="POST" action="/signup">
14
+ <label for="nickname">Nickname:</label>
15
+ <input type="text" id="nickname" name="nickname" required><br>
16
+ <label for="username">Username:</label>
17
+ <input type="text" id="username" name="username" required><br>
18
+ <label for="password">Password:</label>
19
+ <input type="password" id="password" name="password" required><br>
20
+ <button type="submit">Sign Up</button>
21
+ </form>
22
+
23
+ <!-- Mostra i messaggi flash -->
24
+ {% include 'includes/flash.html' %}
25
+
26
+ </body>
27
+
28
+ </html>