Add files via upload
This commit is contained in:
18
MojaAplikacja/Dockerfile
Normal file
18
MojaAplikacja/Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
FROM node:18-slim as builder
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
|
||||
FROM node:18-slim
|
||||
LABEL org.opencontainers.image.authors="Julia"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:3000/ || exit 1
|
||||
|
||||
CMD ["npm", "start"]
|
||||
100
MojaAplikacja/app.js
Normal file
100
MojaAplikacja/app.js
Normal file
@@ -0,0 +1,100 @@
|
||||
// Importujemy wymagane moduły
|
||||
const express = require('express'); // framework do tworzenia serwera HTTP
|
||||
const axios = require('axios'); // biblioteka do wykonywania zapytań HTTP
|
||||
const path = require('path'); // moduł do obsługi ścieżek plików
|
||||
|
||||
// Tworzymy instancję aplikacji Express
|
||||
const app = express();
|
||||
const PORT = 3000; // Port, na którym nasłuchuje serwer
|
||||
|
||||
// Wyświetlamy informację o starcie aplikacji
|
||||
const now = new Date();
|
||||
console.log(`Aplikacja uruchomiona: ${now.toLocaleString()}, autor: Julia, port: ${PORT}`);
|
||||
|
||||
// Ustawiamy folder 'public' jako katalog ze statycznymi plikami (CSS, obrazy itd.)
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
|
||||
// Middleware do parsowania danych przesyłanych przez formularz (x-www-form-urlencoded)
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
|
||||
// Obsługa żądania GET na ścieżkę główną – wyświetlenie strony startowej (formularza)
|
||||
app.get('/', (req, res) => {
|
||||
res.sendFile(path.join(__dirname, 'views', 'index.html'));
|
||||
});
|
||||
|
||||
// Obsługa żądania POST na ścieżkę /pogoda – po wysłaniu formularza
|
||||
app.post('/pogoda', async (req, res) => {
|
||||
const country = req.body.country; // Pobieramy kraj z formularza
|
||||
const city = req.body.city; // Pobieramy miasto z formularza
|
||||
|
||||
// Przykładowe dane – współrzędne geograficzne dla wybranych miast
|
||||
const cities = {
|
||||
"Polska": {
|
||||
"Warszawa": { lat: 52.23, lon: 21.01 },
|
||||
"Lublin": { lat: 51.25, lon: 22.57 },
|
||||
"Gdańsk": { lat: 54.35, lon: 18.65 }
|
||||
},
|
||||
"Niemcy": {
|
||||
"Berlin": { lat: 52.52, lon: 13.41 },
|
||||
"Monachium": { lat: 48.14, lon: 11.58 },
|
||||
"Hamburg": { lat: 53.55, lon: 9.99 }
|
||||
},
|
||||
"Francja": {
|
||||
"Paryż": { lat: 48.85, lon: 2.35 },
|
||||
"Marsylia": { lat: 43.30, lon: 5.37 },
|
||||
"Lyon": { lat: 45.75, lon: 4.85 }
|
||||
}
|
||||
};
|
||||
|
||||
// Sprawdzenie, czy dane miasto i kraj są dostępne w naszej bazie
|
||||
if (!cities[country] || !cities[country][city]) {
|
||||
return res.send("Błąd: Nie znaleziono danych dla wybranego miasta i kraju.");
|
||||
}
|
||||
|
||||
// Pobieramy współrzędne geograficzne miasta
|
||||
const { lat, lon } = cities[country][city];
|
||||
|
||||
try {
|
||||
// Wysyłamy zapytanie do API open-meteo z aktualnymi danymi pogodowymi
|
||||
const response = await axios.get(`https://api.open-meteo.com/v1/forecast`, {
|
||||
params: {
|
||||
latitude: lat,
|
||||
longitude: lon,
|
||||
current_weather: true // Pobieramy tylko aktualną pogodę
|
||||
}
|
||||
});
|
||||
|
||||
// Odczytujemy dane pogodowe z odpowiedzi
|
||||
const weather = response.data.current_weather;
|
||||
|
||||
// Pobieramy bieżącą datę i czas serwera (w strefie czasu Warszawy)
|
||||
const serverDate = new Date();
|
||||
const localServerDate = new Date(serverDate.toLocaleString("en-US", { timeZone: "Europe/Warsaw" }));
|
||||
|
||||
// Formatowanie daty i czasu
|
||||
const serverDateFormatted = localServerDate.toLocaleDateString('pl-PL');
|
||||
const serverTimeFormatted = localServerDate.toLocaleTimeString('pl-PL', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
});
|
||||
|
||||
// Wyświetlamy wyniki w przeglądarce
|
||||
res.send(`
|
||||
<h2>Pogoda w ${city}, ${country}</h2>
|
||||
<p>Temperatura: ${weather.temperature}°C</p>
|
||||
<p>Wiatr: ${weather.windspeed} km/h</p>
|
||||
<p>Data i Godzina: ${serverDateFormatted} ${serverTimeFormatted}</p>
|
||||
`);
|
||||
|
||||
} catch (err) {
|
||||
// Obsługa błędów np. problemów z API
|
||||
console.error(err);
|
||||
res.send("Wystąpił błąd podczas pobierania pogody.");
|
||||
}
|
||||
});
|
||||
|
||||
// Uruchamiamy serwer i nasłuchujemy na wskazanym porcie
|
||||
app.listen(PORT, '0.0.0.0', () => {
|
||||
console.log(`Aplikacja działa na porcie ${PORT}`);
|
||||
});
|
||||
15
MojaAplikacja/package.json
Normal file
15
MojaAplikacja/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "pogoda-app",
|
||||
"version": "1.0.0",
|
||||
"description": "Aplikacja pogodowa w Express",
|
||||
"main": "app.js",
|
||||
"author": "Julia",
|
||||
"scripts": {
|
||||
"start": "node app.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.6.2",
|
||||
"express": "^4.18.2"
|
||||
}
|
||||
}
|
||||
|
||||
70
MojaAplikacja/public/style.css
Normal file
70
MojaAplikacja/public/style.css
Normal file
@@ -0,0 +1,70 @@
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f7f7f7;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 30px;
|
||||
background-color: white;
|
||||
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #333;
|
||||
font-size: 28px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
font-size: 18px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
select {
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
font-size: 18px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 18px;
|
||||
font-size: 20px;
|
||||
border-radius: 10px;
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #218838;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #007bff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #0056b3;
|
||||
}
|
||||
98
MojaAplikacja/views/index.html
Normal file
98
MojaAplikacja/views/index.html
Normal file
@@ -0,0 +1,98 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8"> <!-- Ustawienie kodowania znaków na UTF-8 -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Responsywność na urządzeniach mobilnych -->
|
||||
<title>Aplikacja Pogodowa</title> <!-- Tytuł strony w przeglądarce -->
|
||||
<link rel="stylesheet" href="/style.css"> <!-- Dołączenie zewnętrznego pliku CSS -->
|
||||
</head>
|
||||
<body>
|
||||
<div class="container"> <!-- Główne opakowanie dla treści -->
|
||||
<h1>Aplikacja Pogodowa</h1> <!-- Nagłówek strony -->
|
||||
|
||||
<!-- Formularz pogodowy wysyłany metodą POST na adres /pogoda -->
|
||||
<form id="weather-form" method="POST" action="/pogoda">
|
||||
<div class="form-group">
|
||||
<label for="country">Wybierz kraj:</label>
|
||||
<!-- Lista rozwijana z krajami -->
|
||||
<select name="country" id="country" required>
|
||||
<option value="">Wybierz kraj...</option>
|
||||
<option value="Polska">Polska</option>
|
||||
<option value="Niemcy">Niemcy</option>
|
||||
<option value="Francja">Francja</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="city">Miasto:</label>
|
||||
<!-- Lista rozwijana z miastami (uzupełniana dynamicznie przez JavaScript) -->
|
||||
<select name="city" id="city" required>
|
||||
<option value="">Wybierz miasto...</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button type="submit">Sprawdź pogodę</button> <!-- Przycisk wysyłający formularz -->
|
||||
</form>
|
||||
|
||||
<!-- Sekcja, w której pojawi się wynik (odpowiedź z serwera) -->
|
||||
<div id="weather-result" style="margin-top: 20px;"></div>
|
||||
</div>
|
||||
|
||||
<!-- Skrypt JS do dynamicznej obsługi formularza -->
|
||||
<script>
|
||||
// Po zmianie wybranego kraju, uzupełniamy listę miast
|
||||
document.getElementById("country").addEventListener("change", function() {
|
||||
const country = this.value; // Wartość wybranego kraju
|
||||
const citySelect = document.getElementById("city"); // Element select z miastami
|
||||
|
||||
let cities = []; // Lista miast do uzupełnienia
|
||||
|
||||
// W zależności od kraju, ustawiamy odpowiednie miasta
|
||||
if (country === "Polska") {
|
||||
cities = ["Warszawa", "Lublin", "Gdańsk"];
|
||||
} else if (country === "Niemcy") {
|
||||
cities = ["Berlin", "Monachium", "Hamburg"];
|
||||
} else if (country === "Francja") {
|
||||
cities = ["Paryż", "Marsylia", "Lyon"];
|
||||
}
|
||||
|
||||
// Czyścimy poprzednie opcje i dodajemy nowe
|
||||
citySelect.innerHTML = '<option value="">Wybierz miasto...</option>';
|
||||
|
||||
cities.forEach(function(city) {
|
||||
const option = document.createElement("option");
|
||||
option.value = city;
|
||||
option.textContent = city;
|
||||
citySelect.appendChild(option);
|
||||
});
|
||||
});
|
||||
|
||||
// Obsługa formularza – wysyłanie danych AJAXem (bez przeładowania strony)
|
||||
document.getElementById("weather-form").addEventListener("submit", function(event) {
|
||||
event.preventDefault(); // Zatrzymujemy domyślne wysyłanie formularza
|
||||
|
||||
const country = document.getElementById("country").value; // Wybrany kraj
|
||||
const city = document.getElementById("city").value; // Wybrane miasto
|
||||
|
||||
// Wysyłamy dane do serwera metodą POST
|
||||
fetch("/pogoda", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({ country, city }) // Przesyłane dane formularza
|
||||
})
|
||||
.then(response => response.text()) // Odbieramy odpowiedź jako tekst HTML
|
||||
.then(data => {
|
||||
// Wyświetlamy wynik w <div id="weather-result">
|
||||
document.getElementById("weather-result").innerHTML = data;
|
||||
})
|
||||
.catch(error => {
|
||||
// Obsługa błędu – np. brak odpowiedzi z serwera
|
||||
document.getElementById("weather-result").innerHTML = "Błąd podczas pobierania pogody.";
|
||||
console.error("Błąd:", error);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
45
MojaAplikacja/zadanie1.md
Normal file
45
MojaAplikacja/zadanie1.md
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
# Aplikacja Pogodowa w Node.js z użyciem Dockera
|
||||
|
||||
## 1. Opis aplikacji
|
||||
|
||||
Aplikacja pogodowa została stworzona w technologii **Node.js** z użyciem frameworka **Express**. Umożliwia użytkownikowi wybór kraju i miasta w celu wyświetlenia aktualnej pogody na podstawie danych pobieranych z API.
|
||||
Aplikacja wykorzystuje metodę POST do przesyłania danych z formularza i dynamicznie wyświetla wynik w przeglądarce użytkownika.
|
||||
Użytkownik może wybrać jeden z trzech krajów: Polska, Niemcy lub Francja, a następnie miasto dostępne w wybranym kraju.
|
||||
|
||||
## 2. Struktura projektu
|
||||
|
||||
├── public/
|
||||
│ └── style.css # Style CSS dla aplikacji
|
||||
├── views/
|
||||
│ └── index.html # Szablon HTML z formularzem
|
||||
├── app.js # Główny plik serwera Express
|
||||
├── Dockerfile # Plik Dockerfile do budowania kontenera
|
||||
├── package.json # Zależności npm i konfiguracja aplikacji
|
||||
|
||||
## 3. Uruchamianie aplikacji
|
||||
|
||||
1. Zbuduj obraz:
|
||||
|
||||
docker build -t moja-aplikacja .
|
||||
|
||||
2. Uruchom kontener:
|
||||
|
||||
docker run -d -p 3000:3000 --name moja-aplikacja moja-aplikacja
|
||||
|
||||
3. Sprawdzanie lagów:
|
||||
|
||||
docker logs moja-aplikacja
|
||||
|
||||
4. Rozmiar obrazu:
|
||||
|
||||
docker images
|
||||
|
||||
Aplikacja będzie dostępna pod adresem `http://localhost:3000`.
|
||||
|
||||
## 4. Linki
|
||||
|
||||
**GitHub (repozytorium z kodem źródłowym)**: https://github.com/Julka616/moja-aplikacja
|
||||
|
||||
**DockerHub (obraz aplikacji)**: [https://hub.docker.com/r/twoja-nazwa-uzytkownika/pogoda-app](https://hub.docker.com/r/twoja-nazwa-uzytkownika/pogoda-app)
|
||||
|
||||
Reference in New Issue
Block a user