Dodano nowe pliki
This commit is contained in:
commit
7397020d64
11
README.md
Normal file
11
README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# OPIS INSTALACJI PROJEKTU - Lidia Wojciechowska
|
||||||
|
Cały folder należy otworzyć w visual studio code, w terminalu wpisać takie polecenia jak:
|
||||||
|
|
||||||
|
|
||||||
|
pip install flask
|
||||||
|
pip install pyodbc
|
||||||
|
pip install configparser
|
||||||
|
Należy rowniez ustawic swoje dane w pliku 'dane.ini', aby zobaczyc na serwerze w swojej bazie (mssql) listę todo.
|
||||||
|
następnie run and debug
|
||||||
|
w trakcie debuggowania nalezy wcisnąć ctrl+ kliknąć w link http://localhost:4449 .
|
||||||
|
powinna działać aplikacja
|
98
abcd.css
Normal file
98
abcd.css
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/* styles.css */
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: lightblue;
|
||||||
|
color: #333;
|
||||||
|
font-family: Monospace;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background-color: #f2c538;
|
||||||
|
color: #333;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task:hover {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task .timestamp {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
background-color: #f2c538;
|
||||||
|
color: #333;
|
||||||
|
border: none;
|
||||||
|
padding: 8px 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
background-color: #e0b52f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container input[type="text"] {
|
||||||
|
width: calc(100% - 100px);
|
||||||
|
padding: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container input[type="submit"] {
|
||||||
|
background-color: #f2c538;
|
||||||
|
color: #333;
|
||||||
|
border: none;
|
||||||
|
padding: 8px 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container input[type="submit"]:hover {
|
||||||
|
background-color: #e0b52f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container input[type="text"] {
|
||||||
|
width: 200px;
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container input[type="submit"] {
|
||||||
|
background-color: #f2c538;
|
||||||
|
color: #333;
|
||||||
|
border: none;
|
||||||
|
padding: 6px 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container input[type="submit"]:hover {
|
||||||
|
background-color: #e0b52f;
|
||||||
|
}
|
125
app.py
Normal file
125
app.py
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
from flask import Flask, render_template, request, redirect, url_for
|
||||||
|
import pyodbc
|
||||||
|
import configparser
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
app = Flask(__name__, template_folder='.',static_folder='')
|
||||||
|
|
||||||
|
class TodoList:
|
||||||
|
def __init__(self):
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read('dane.ini')
|
||||||
|
|
||||||
|
mssql_config = config['mssql']
|
||||||
|
|
||||||
|
self.conn = pyodbc.connect(
|
||||||
|
f"DRIVER={mssql_config['driver']};"
|
||||||
|
f"SERVER={mssql_config['server']};"
|
||||||
|
f"DATABASE={mssql_config['database']};"
|
||||||
|
f"UID={mssql_config['uid']};"
|
||||||
|
f"PWD={mssql_config['pwd']}"
|
||||||
|
)
|
||||||
|
self.create_table()
|
||||||
|
|
||||||
|
def create_table(self):
|
||||||
|
with self.conn.cursor() as cursor:
|
||||||
|
cursor.execute('''
|
||||||
|
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='tasks' and xtype='U')
|
||||||
|
CREATE TABLE tasks (
|
||||||
|
id INT PRIMARY KEY IDENTITY(1,1),
|
||||||
|
description NVARCHAR(255) NOT NULL
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
self.conn.commit()
|
||||||
|
|
||||||
|
def add_task(self, description):
|
||||||
|
description_with_timestamp = self.add_timestamp(description)
|
||||||
|
with self.conn.cursor() as cursor:
|
||||||
|
cursor.execute('INSERT INTO tasks (description) VALUES (?)', (description_with_timestamp,))
|
||||||
|
self.conn.commit()
|
||||||
|
|
||||||
|
def remove_task(self, task_id):
|
||||||
|
with self.conn.cursor() as cursor:
|
||||||
|
cursor.execute('DELETE FROM tasks WHERE id = ?', (task_id,))
|
||||||
|
self.conn.commit()
|
||||||
|
|
||||||
|
def edit_task(self, task_id, new_description):
|
||||||
|
new_description_with_timestamp = self.add_timestamp(new_description)
|
||||||
|
with self.conn.cursor() as cursor:
|
||||||
|
cursor.execute('UPDATE tasks SET description = ? WHERE id = ?', (new_description_with_timestamp, task_id))
|
||||||
|
self.conn.commit()
|
||||||
|
|
||||||
|
def get_tasks(self):
|
||||||
|
with self.conn.cursor() as cursor:
|
||||||
|
cursor.execute('SELECT id, description FROM tasks')
|
||||||
|
tasks = []
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
task_dict = {
|
||||||
|
'id': row.id,
|
||||||
|
'description': row.description
|
||||||
|
}
|
||||||
|
tasks.append(task_dict)
|
||||||
|
return tasks
|
||||||
|
|
||||||
|
def get_task(self, task_id):
|
||||||
|
with self.conn.cursor() as cursor:
|
||||||
|
cursor.execute('SELECT id, description FROM tasks WHERE id = ?', (task_id,))
|
||||||
|
return cursor.fetchone()
|
||||||
|
|
||||||
|
def add_timestamp(self, description):
|
||||||
|
return f"{description} (added/edited on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')})"
|
||||||
|
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.conn.close()
|
||||||
|
|
||||||
|
todo_list = TodoList()
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
tasks = todo_list.get_tasks()
|
||||||
|
return render_template('todo_list.html', tasks=tasks)
|
||||||
|
|
||||||
|
@app.route('/add', methods=['GET', 'POST'])
|
||||||
|
def add_task():
|
||||||
|
if request.method == 'POST':
|
||||||
|
description = request.form['description']
|
||||||
|
todo_list.add_task(description)
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
return render_template('task_add.html')
|
||||||
|
|
||||||
|
@app.route('/delete/<int:task_id>')
|
||||||
|
def delete_task(task_id):
|
||||||
|
todo_list.remove_task(task_id)
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/search', methods=['GET', 'POST'])
|
||||||
|
def search_tasks():
|
||||||
|
if request.method == 'POST':
|
||||||
|
keyword = request.form['keyword'].lower()
|
||||||
|
tasks = todo_list.get_tasks()
|
||||||
|
matching_tasks = [task for task in tasks if keyword in task['description'].lower()]
|
||||||
|
return render_template('task_search.html', tasks=matching_tasks, keyword=request.form['keyword'])
|
||||||
|
return render_template('task_search.html')
|
||||||
|
|
||||||
|
@app.route('/edit/<int:task_id>', methods=['GET', 'POST'])
|
||||||
|
def edit_task(task_id):
|
||||||
|
task = todo_list.get_task(task_id)
|
||||||
|
if request.method == 'POST':
|
||||||
|
new_description = request.form['description']
|
||||||
|
todo_list.edit_task(task_id, new_description)
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
return render_template('task_edit.html', task=task)
|
||||||
|
|
||||||
|
@app.route('/long')
|
||||||
|
def long_tasks():
|
||||||
|
tasks = todo_list.get_tasks()
|
||||||
|
long_tasks = list(filter(lambda task: len(task['description']) > 60, tasks))
|
||||||
|
return render_template('long.html', tasks=long_tasks)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run('localhost', 4449, debug=True)
|
8
dane.ini
Normal file
8
dane.ini
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[mssql]
|
||||||
|
driver=ODBC Driver 17 for SQL Server
|
||||||
|
server=mssql-2017.labs.wmi.amu.edu.pl
|
||||||
|
database=dbad_s490058
|
||||||
|
uid=dbad_s490058
|
||||||
|
pwd=MLJ8HKkKxJ
|
||||||
|
|
||||||
|
#https://www.geeksforgeeks.org/flask-rendering-templates/
|
18
long.html
Normal file
18
long.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Long Tasks</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/abcd.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Long Tasks</h1>
|
||||||
|
<ul>
|
||||||
|
{% for task in tasks %}
|
||||||
|
<li>{{ task.description }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
<a href="/">Back to TODO List</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
11
opis_instalacji.txt
Normal file
11
opis_instalacji.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
OPIS INSTALACJI PROJEKTU - Lidia Wojciechowska
|
||||||
|
Cały folder należy otworzyć w visual studio code, w terminalu wpisać takie polecenia jak:
|
||||||
|
|
||||||
|
|
||||||
|
pip install flask
|
||||||
|
pip install pyodbc
|
||||||
|
pip install configparser
|
||||||
|
Należy rowniez ustawic swoje dane w pliku 'dane.ini', aby zobaczyc na serwerze w swojej bazie listę todo.
|
||||||
|
następnie run and debug
|
||||||
|
w trakcie debuggowania nalezy wcisnąć ctrl+ kliknąć w link http://localhost:4449 .
|
||||||
|
powinna działać aplikacja
|
16
task_add.html
Normal file
16
task_add.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Add Task</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/abcd.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Add Task</h1>
|
||||||
|
<form action="/add" method="post" class="task-form">
|
||||||
|
<label for="description">Task Description:</label>
|
||||||
|
<input type="text" id="description" name="description" required>
|
||||||
|
<button type="submit" class="button">Add Task</button>
|
||||||
|
</form>
|
||||||
|
<a href="/" class="button">Back to List</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
16
task_edit.html
Normal file
16
task_edit.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Edit Task</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/abcd.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Edit Task</h1>
|
||||||
|
<form action="/edit/{{ task.id }}" method="post" class="task-form">
|
||||||
|
<label for="description">Task Description:</label>
|
||||||
|
<input type="text" id="description" name="description" value="{{ task.description }}" required>
|
||||||
|
<button type="submit" class="button">Update Task</button>
|
||||||
|
</form>
|
||||||
|
<a href="/" class="button">Back to List</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
24
task_search.html
Normal file
24
task_search.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Search Tasks</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/abcd.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Search Tasks</h1>
|
||||||
|
<form action="/search" method="post" class="task-form">
|
||||||
|
<label for="keyword">Keyword:</label>
|
||||||
|
<input type="text" id="keyword" name="keyword" required>
|
||||||
|
<button type="submit" class="button">Search</button>
|
||||||
|
</form>
|
||||||
|
<a href="/" class="button">Back to List</a>
|
||||||
|
{% if keyword %}
|
||||||
|
<h2>Search Results for "{{ keyword }}"</h2>
|
||||||
|
<ul class="task-list">
|
||||||
|
{% for task in tasks %}
|
||||||
|
<li>{{ task.description }} <a href="/edit/{{ task.id }}" class="button">Edit</a> <a href="/delete/{{ task.id }}" class="button delete">Delete</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
</body>
|
||||||
|
</html>
|
18
todo_list.html
Normal file
18
todo_list.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>TODO List</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/abcd.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>TODO List</h1>
|
||||||
|
<a href="/add" class="button">Add Task</a>
|
||||||
|
<a href="/search" class="button">Search Tasks</a>
|
||||||
|
<a href="/long" class="button">Show Long Tasks</a> <!-- Nowy przycisk -->
|
||||||
|
<ul class="task-list">
|
||||||
|
{% for task in tasks %}
|
||||||
|
<li>{{ task.description }} <a href="/edit/{{ task.id }}" class="button">Edit</a> <a href="/delete/{{ task.id }}" class="button delete">Delete</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user