Upload files to "/"

This commit is contained in:
s490127 2024-06-13 13:55:46 +02:00
commit 9699b5b650
4 changed files with 302 additions and 0 deletions

84
app.js Normal file
View File

@ -0,0 +1,84 @@
// Funkcja do dodawania nowego zadania
async function addTask() {
const taskDescription = document.getElementById('new-task').value;
if (!taskDescription) {
alert('Opis zadania nie może być pusty!');
return;
}
try {
const response = await fetch('http://localhost:8000/add_task', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ task_description: taskDescription })
});
if (!response.ok) {
throw new Error('Odpowiedź sieci nie była OK');
}
const result = await response.json();
console.log('Zadanie dodane:', result);
document.getElementById('new-task').value = '';
loadTasks(); // Ponowne załadowanie zadań po dodaniu nowego
} catch (error) {
console.error('Błąd podczas dodawania zadania:', error);
}
}
// Funkcja do ładowania zadań
async function loadTasks() {
try {
const response = await fetch('http://localhost:8000/get_tasks');
if (!response.ok) {
throw new Error('Odpowiedź sieci nie była OK');
}
const tasks = await response.json();
const taskList = document.getElementById('task-list');
taskList.innerHTML = '';
tasks.forEach(task => {
const listItem = document.createElement('li');
listItem.textContent = task.task_description;
// Przycisk do usuwania zadania
const deleteButton = document.createElement('button');
deleteButton.textContent = 'Usuń';
deleteButton.onclick = () => deleteTask(task.id);
listItem.appendChild(deleteButton);
taskList.appendChild(listItem);
});
} catch (error) {
console.error('Błąd podczas ładowania zadań:', error);
}
}
// Funkcja do usuwania zadania
async function deleteTask(taskId) {
try {
const response = await fetch(`http://localhost:8000/delete_task/${taskId}`, {
method: 'DELETE'
});
if (!response.ok) {
throw new Error('Odpowiedź sieci nie była OK');
}
const result = await response.json();
console.log('Zadanie usunięte:', result);
loadTasks(); // Ponowne załadowanie zadań po usunięciu
} catch (error) {
console.error('Błąd podczas usuwania zadania:', error);
}
}
// Nasłuchiwanie na załadowanie DOM
document.addEventListener('DOMContentLoaded', () => {
loadTasks();
});

20
index.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>To-Do App</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<h1>To-Do List</h1>
<div class="input-container">
<input type="text" id="new-task" placeholder="Enter new task">
<button onclick="addTask()">Add Task</button>
</div>
<ul id="task-list"></ul>
</div>
<script src="app.js"></script>
</body>
</html>

97
serwer.py Normal file
View File

@ -0,0 +1,97 @@
from wsgiref.simple_server import make_server
import json
import pyodbc
# Nagłówki odpowiedzi HTTP
response_headers = [
('Content-Type', 'application/json'),
('Access-Control-Allow-Origin', '*'),
('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE'),
('Access-Control-Allow-Headers', 'Content-Type')
]
# Konfiguracja połączenia z bazą danych
conn = pyodbc.connect(
'DRIVER={ODBC Driver 17 for SQL Server};'
'SERVER=mssql-2017.labs.wmi.amu.edu.pl;'
'DATABASE=dbad_s490127;'
'UID=dbad_s490127;'
'PWD=Bjf5w2Hhco'
)
cursor = conn.cursor()
def application(environ, start_response):
path = environ.get('PATH_INFO', '') # Pobranie ścieżki żądania
method = environ.get('REQUEST_METHOD', '') # Pobranie metody HTTP
response_headers = [
('Content-Type', 'application/json'),
('Access-Control-Allow-Origin', '*'),
('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE'),
('Access-Control-Allow-Headers', 'Content-Type')
]
# Obsługa preflight requests dla CORS
if method == 'OPTIONS':
start_response('200 OK', response_headers)
return [b'']
# Obsługa dodawania nowego zadania
if path == '/add_task' and method == 'POST':
try:
# Odczytanie i sparsowanie treści żądania
request_body_size = int(environ.get('CONTENT_LENGTH', 0))
request_body = environ['wsgi.input'].read(request_body_size)
data = json.loads(request_body)
task_description = data.get('task_description', '')
# Dodanie zadania do bazy danych, jeśli opis jest podany
if task_description:
cursor.execute("INSERT INTO Tasks (task_description) OUTPUT INSERTED.id VALUES (?)", (task_description,))
task_id = cursor.fetchone()[0] # Pobranie ID nowo dodanego zadania
conn.commit() # Zatwierdzenie zmian w bazie danych
response = json.dumps({'message': 'Task added successfully', 'id': task_id})
status = '200 OK'
else:
response = json.dumps({'message': 'Task description is required'}) # Brak opisu zadania
status = '400 Bad Request'
except Exception as e:
response = json.dumps({'message': str(e)}) # Obsługa błędu
status = '500 Internal Server Error'
# Obsługa pobierania wszystkich zadań
elif path == '/get_tasks' and method == 'GET':
try:
cursor.execute("SELECT id, task_description FROM Tasks") # Pobranie zadań z bazy danych
tasks = cursor.fetchall()
tasks_list = [{'id': task[0], 'task_description': task[1]} for task in tasks] # Przygotowanie listy zadań
response = json.dumps(tasks_list) # Konwersja listy zadań do formatu JSON
status = '200 OK'
except Exception as e:
response = json.dumps({'message': str(e)}) # Obsługa błędu
status = '500 Internal Server Error'
# Obsługa usuwania konkretnego zadania
elif path.startswith('/delete_task/') and method == 'DELETE':
try:
task_id = int(path.split('/')[-1]) # Wyodrębnienie ID zadania z URL
cursor.execute("DELETE FROM Tasks WHERE id = ?", (task_id,)) # Usunięcie zadania z bazy danych
conn.commit() # Zatwierdzenie zmian w bazie danych
response = json.dumps({'message': 'Task deleted successfully'})
status = '200 OK'
except Exception as e:
response = json.dumps({'message': str(e)}) # Obsługa błędu
status = '500 Internal Server Error'
# Obsługa nieznanych ścieżek
else:
response = json.dumps({'message': 'Not Found'}) # Nieznana ścieżka
status = '404 Not Found'
start_response(status, response_headers) # Wysłanie odpowiedzi HTTP
return [response.encode('utf-8')]
if __name__ == "__main__":
httpd = make_server('', 8000, application) # Utworzenie serwera na porcie 8000
print("Serving on port 8000...")
httpd.serve_forever() # Rozpoczęcie obsługi żądań

101
styles.css Normal file
View File

@ -0,0 +1,101 @@
/* Reset some default browser styles */
body, h1, ul, li, button, input {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, sans-serif;
}
body {
background-color: #f4f4f9;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
background: #fff;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 300px;
}
h1 {
font-size: 24px;
margin-bottom: 20px;
text-align: center;
color: #333;
}
.input-container {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
input[type="text"] {
flex: 1;
padding: 10px;
font-size: 16px;
border: 1px solid #ddd;
border-radius: 5px;
margin-right: 10px;
}
button {
padding: 10px;
font-size: 16px;
border: none;
border-radius: 5px;
background-color: #007bff;
color: #fff;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #0056b3;
}
ul {
list-style: none;
}
li {
background: #f9f9f9;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
li.completed {
text-decoration: line-through;
color: #999;
}
li button {
margin-left: 10px;
}
li button:first-of-type {
background-color: #28a745;
}
li button:first-of-type:hover {
background-color: #218838;
}
li button:last-of-type {
background-color: #dc3545;
}
li button:last-of-type:hover {
background-color: #c82333;
}