Upload files to "/"
This commit is contained in:
commit
e51b975907
31
index.html
Normal file
31
index.html
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>To-Do List</title>
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>To-Do List</h1>
|
||||||
|
</header>
|
||||||
|
<div class="container">
|
||||||
|
<div class="input-section">
|
||||||
|
<input type="text" id="todo-input" placeholder="Add a new task">
|
||||||
|
<button id="add-button">Add</button>
|
||||||
|
<button id="random-task-button">Show Random Task</button> <!-- Nowy przycisk -->
|
||||||
|
</div>
|
||||||
|
<div class="list-section">
|
||||||
|
<ul id="todo-list"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="popup" class="popup">
|
||||||
|
<div class="popup-content">
|
||||||
|
<span class="close">×</span>
|
||||||
|
<p id="random-task-text"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="scripts.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
64
rand2.cpp
Normal file
64
rand2.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <random>
|
||||||
|
#include <mutex>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
std::mutex mtx;
|
||||||
|
int random_numbers[3] = {0, 0, 0};
|
||||||
|
int random_choice = 0;
|
||||||
|
|
||||||
|
void generateRandomNumber(int index, int min, int max) {
|
||||||
|
try {
|
||||||
|
std::random_device rd;
|
||||||
|
std::mt19937 gen(rd());
|
||||||
|
std::uniform_int_distribution<> dis(min, max);
|
||||||
|
|
||||||
|
int number = dis(gen);
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(mtx);
|
||||||
|
if (index >= 0 && index < 3) {
|
||||||
|
random_numbers[index] = number;
|
||||||
|
} else if (index == 3) {
|
||||||
|
random_choice = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
// Handle exception if necessary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveRandomNumberToFile() {
|
||||||
|
try {
|
||||||
|
std::lock_guard<std::mutex> lock(mtx);
|
||||||
|
std::ofstream outfile("random_number.txt");
|
||||||
|
if (outfile.is_open()) {
|
||||||
|
outfile << random_numbers[random_choice - 1];
|
||||||
|
outfile.close();
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
// Handle exception if necessary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
try {
|
||||||
|
std::thread threads[4];
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
threads[i] = std::thread(generateRandomNumber, i, 1, 100);
|
||||||
|
}
|
||||||
|
threads[3] = std::thread(generateRandomNumber, 3, 1, 3);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
threads[i].join();
|
||||||
|
}
|
||||||
|
|
||||||
|
saveRandomNumberToFile();
|
||||||
|
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
// Handle exception if necessary
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
185
scripts.js
Normal file
185
scripts.js
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const input = document.getElementById('todo-input');
|
||||||
|
const addButton = document.getElementById('add-button');
|
||||||
|
const randomTaskButton = document.getElementById('random-task-button'); // Nowy przycisk
|
||||||
|
const todoList = document.getElementById('todo-list');
|
||||||
|
const popup = document.getElementById('popup');
|
||||||
|
const popupContent = document.getElementById('random-task-text');
|
||||||
|
const closePopup = document.getElementsByClassName('close')[0];
|
||||||
|
|
||||||
|
addButton.addEventListener('click', addTodo);
|
||||||
|
randomTaskButton.addEventListener('click', showRandomTask); // Event listener dla nowego przycisku
|
||||||
|
|
||||||
|
input.addEventListener('keypress', (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
addTodo();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function fetchTasks() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('http://localhost:8000/get_tasks', {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const tasks = await response.json();
|
||||||
|
tasks.forEach(task => {
|
||||||
|
const listItem = document.createElement('li');
|
||||||
|
listItem.textContent = task.task_description;
|
||||||
|
listItem.dataset.id = task.id; // Store the id in data-id attribute
|
||||||
|
|
||||||
|
const deleteButton = document.createElement('button');
|
||||||
|
deleteButton.textContent = 'Delete';
|
||||||
|
deleteButton.classList.add('delete-button');
|
||||||
|
deleteButton.addEventListener('click', () => {
|
||||||
|
todoList.removeChild(listItem);
|
||||||
|
deleteTask(listItem.dataset.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
listItem.appendChild(deleteButton);
|
||||||
|
todoList.appendChild(listItem);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error('Failed to fetch tasks', await response.json());
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching tasks:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addTodo() {
|
||||||
|
const todoText = input.value.trim();
|
||||||
|
if (todoText === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('http://localhost:8000/add_task', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ task_description: todoText })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const responseData = await response.json(); // Assuming the server responds with the added task including its id
|
||||||
|
const listItem = document.createElement('li');
|
||||||
|
listItem.textContent = todoText;
|
||||||
|
listItem.dataset.id = responseData.id; // Store the id in data-id attribute
|
||||||
|
|
||||||
|
const deleteButton = document.createElement('button');
|
||||||
|
deleteButton.textContent = 'Delete';
|
||||||
|
deleteButton.classList.add('delete-button');
|
||||||
|
deleteButton.addEventListener('click', () => {
|
||||||
|
todoList.removeChild(listItem);
|
||||||
|
deleteTask(listItem.dataset.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
listItem.appendChild(deleteButton);
|
||||||
|
todoList.appendChild(listItem);
|
||||||
|
|
||||||
|
input.value = '';
|
||||||
|
input.focus();
|
||||||
|
} else {
|
||||||
|
console.error('Failed to add task', await response.json());
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error adding task:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteTask(taskId) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`http://localhost:8000/delete_task/${taskId}`, {
|
||||||
|
method: 'DELETE'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
console.error('Failed to delete task', await response.json());
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error deleting task:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function showRandomTask() {
|
||||||
|
try {
|
||||||
|
// Execute rand2.exe
|
||||||
|
const executeResponse = await fetch('http://localhost:8000/execute_rand2', {
|
||||||
|
method: 'POST'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!executeResponse.ok) {
|
||||||
|
console.error('Failed to execute rand2.exe', await executeResponse.json());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the random number from random_number.txt
|
||||||
|
const numberResponse = await fetch('http://localhost:8000/read_random_number', {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!numberResponse.ok) {
|
||||||
|
console.error('Failed to fetch random number', await numberResponse.text());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const randomNumberText = await numberResponse.text();
|
||||||
|
const randomNumber = parseInt(randomNumberText.trim(), 10);
|
||||||
|
|
||||||
|
// Fetch the list of tasks from the server
|
||||||
|
const tasksResponse = await fetch('http://localhost:8000/get_tasks', {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (tasksResponse.ok) {
|
||||||
|
const tasks = await tasksResponse.json();
|
||||||
|
if (tasks.length > 0) {
|
||||||
|
// Use the random number to select a task, considering the range
|
||||||
|
const taskIndex = randomNumber % tasks.length;
|
||||||
|
const randomTask = tasks[taskIndex];
|
||||||
|
popupContent.textContent = randomTask.task_description;
|
||||||
|
popup.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
alert('No tasks available');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('Failed to fetch tasks', await tasksResponse.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete random_number.txt after fetching the data
|
||||||
|
await fetch('http://localhost:8000/delete_random_number', {
|
||||||
|
method: 'DELETE'
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching data:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
closePopup.onclick = function() {
|
||||||
|
popup.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onclick = function(event) {
|
||||||
|
if (event.target === popup) {
|
||||||
|
popup.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch tasks when the page loads
|
||||||
|
fetchTasks();
|
||||||
|
});
|
133
server.py
Normal file
133
server.py
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
import subprocess
|
||||||
|
from wsgiref.simple_server import make_server
|
||||||
|
import json
|
||||||
|
import pymssql
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Database configuration
|
||||||
|
conn = pymssql.connect(
|
||||||
|
server='mssql-2017.labs.wmi.amu.edu.pl',
|
||||||
|
user='dbad_s490130',
|
||||||
|
password='lTk13e45Po',
|
||||||
|
database='dbad_s490130'
|
||||||
|
)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
def application(environ, start_response):
|
||||||
|
path = environ.get('PATH_INFO', '')
|
||||||
|
method = environ.get('REQUEST_METHOD', '')
|
||||||
|
|
||||||
|
# CORS Handling
|
||||||
|
if method == 'OPTIONS':
|
||||||
|
response_headers = [
|
||||||
|
('Content-Type', 'application/json'),
|
||||||
|
('Access-Control-Allow-Origin', '*'),
|
||||||
|
('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE'),
|
||||||
|
('Access-Control-Allow-Headers', 'Content-Type')
|
||||||
|
]
|
||||||
|
start_response('200 OK', response_headers)
|
||||||
|
return [b'']
|
||||||
|
|
||||||
|
response_headers = [
|
||||||
|
('Content-Type', 'application/json'),
|
||||||
|
('Access-Control-Allow-Origin', '*')
|
||||||
|
]
|
||||||
|
|
||||||
|
if path == '/add_task' and method == 'POST':
|
||||||
|
try:
|
||||||
|
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', '')
|
||||||
|
|
||||||
|
if task_description:
|
||||||
|
cursor.execute("INSERT INTO Tasks (task_description) OUTPUT INSERTED.id VALUES (%s)", (task_description,))
|
||||||
|
task_id = cursor.fetchone()[0] # Fetch the newly inserted task ID
|
||||||
|
conn.commit()
|
||||||
|
response = json.dumps({'message': 'Task added successfully', 'id': task_id})
|
||||||
|
status = '200 OK'
|
||||||
|
else:
|
||||||
|
response = json.dumps({'message': 'Task description is required'})
|
||||||
|
status = '400 Bad Request'
|
||||||
|
except Exception as e:
|
||||||
|
response = json.dumps({'message': str(e)})
|
||||||
|
status = '500 Internal Server Error'
|
||||||
|
|
||||||
|
elif path == '/get_tasks' and method == 'GET':
|
||||||
|
try:
|
||||||
|
cursor.execute("SELECT id, task_description FROM Tasks")
|
||||||
|
tasks = cursor.fetchall()
|
||||||
|
tasks_list = [{'id': task[0], 'task_description': task[1]} for task in tasks]
|
||||||
|
response = json.dumps(tasks_list)
|
||||||
|
status = '200 OK'
|
||||||
|
except Exception as e:
|
||||||
|
response = json.dumps({'message': str(e)})
|
||||||
|
status = '500 Internal Server Error'
|
||||||
|
|
||||||
|
elif path.startswith('/delete_task/') and method == 'DELETE':
|
||||||
|
try:
|
||||||
|
task_id = int(path.split('/')[-1])
|
||||||
|
cursor.execute("DELETE FROM Tasks WHERE id = %s", (task_id,))
|
||||||
|
conn.commit()
|
||||||
|
response = json.dumps({'message': 'Task deleted successfully'})
|
||||||
|
status = '200 OK'
|
||||||
|
except Exception as e:
|
||||||
|
response = json.dumps({'message': str(e)})
|
||||||
|
status = '500 Internal Server Error'
|
||||||
|
|
||||||
|
elif path == '/execute_rand2' and method == 'POST':
|
||||||
|
try:
|
||||||
|
# Ensure the path to rand2.exe is correct
|
||||||
|
exe_path = 'j:\\Desktop\\Paradygmaty\\wielki projekt\\primery\\rand2.exe'
|
||||||
|
print(f"Attempting to execute: {exe_path}")
|
||||||
|
|
||||||
|
if not os.path.exists(exe_path):
|
||||||
|
raise FileNotFoundError(f"File not found: {exe_path}")
|
||||||
|
|
||||||
|
result = subprocess.run([exe_path], check=True, capture_output=True, text=True)
|
||||||
|
response = json.dumps({'message': 'rand2.exe executed successfully', 'output': result.stdout})
|
||||||
|
status = '200 OK'
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
error_message = f'CalledProcessError: {e.stderr}'
|
||||||
|
print(error_message)
|
||||||
|
response = json.dumps({'message': error_message})
|
||||||
|
status = '500 Internal Server Error'
|
||||||
|
except Exception as e:
|
||||||
|
error_message = f'Exception: {str(e)}'
|
||||||
|
print(error_message)
|
||||||
|
response = json.dumps({'message': error_message})
|
||||||
|
status = '500 Internal Server Error'
|
||||||
|
|
||||||
|
elif path == '/read_random_number' and method == 'GET':
|
||||||
|
try:
|
||||||
|
with open('random_number.txt', 'r') as file:
|
||||||
|
random_number = file.read().strip()
|
||||||
|
response = random_number
|
||||||
|
status = '200 OK'
|
||||||
|
except Exception as e:
|
||||||
|
response = json.dumps({'message': str(e)})
|
||||||
|
status = '500 Internal Server Error'
|
||||||
|
|
||||||
|
elif path == '/delete_random_number' and method == 'DELETE':
|
||||||
|
try:
|
||||||
|
os.remove('random_number.txt')
|
||||||
|
response = json.dumps({'message': 'random_number.txt deleted successfully'})
|
||||||
|
status = '200 OK'
|
||||||
|
except Exception as e:
|
||||||
|
response = json.dumps({'message': str(e)})
|
||||||
|
status = '500 Internal Server Error'
|
||||||
|
|
||||||
|
else:
|
||||||
|
response = json.dumps({'message': 'Not Found'})
|
||||||
|
status = '404 Not Found'
|
||||||
|
|
||||||
|
response_headers.append(('Access-Control-Allow-Headers', 'Content-Type'))
|
||||||
|
response_headers.append(('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE'))
|
||||||
|
|
||||||
|
start_response(status, response_headers)
|
||||||
|
return [response.encode('utf-8')]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
httpd = make_server('', 8000, application)
|
||||||
|
print("Serving on port 8000...")
|
||||||
|
httpd.serve_forever()
|
136
styles.css
Normal file
136
styles.css
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/* styles.css */
|
||||||
|
body {
|
||||||
|
background-color: #333; /* Dark background color */
|
||||||
|
color: white; /* Text color */
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #444; /* Slightly lighter than the background */
|
||||||
|
border-bottom: 1px solid #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #444;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#todo-input {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #555; /* Input background */
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#add-button, #random-task-button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #28a745; /* Button background */
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#add-button {
|
||||||
|
background-color: #007bff; /* Blue background for Add button */
|
||||||
|
}
|
||||||
|
|
||||||
|
#random-task-button {
|
||||||
|
background-color: #28a745; /* Green background for Show Random Task button */
|
||||||
|
}
|
||||||
|
|
||||||
|
#add-button:hover {
|
||||||
|
background-color: #0056b3; /* Darker blue on hover for Add button */
|
||||||
|
}
|
||||||
|
|
||||||
|
#random-task-button:hover {
|
||||||
|
background-color: #218838; /* Darker green on hover for Show Random Task button */
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-button {
|
||||||
|
margin-left: 10px;
|
||||||
|
color: red;
|
||||||
|
cursor: pointer;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #dc3545;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-button:hover {
|
||||||
|
background-color: #c82333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup {
|
||||||
|
display: none; /* Initially hidden */
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-content {
|
||||||
|
background-color: #fefefe;
|
||||||
|
margin: 15% auto;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #888;
|
||||||
|
width: 80%;
|
||||||
|
color: black; /* Ensure text is visible */
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
color: #aaa;
|
||||||
|
float: right;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close:hover,
|
||||||
|
.close:focus {
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-section {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#todo-list {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#todo-list li {
|
||||||
|
background-color: #555;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user