diff --git a/src/main/java/cz/kamma/tvcom/HttpServerApp.java b/src/main/java/cz/kamma/tvcom/HttpServerApp.java index 3277c6d..be40765 100644 --- a/src/main/java/cz/kamma/tvcom/HttpServerApp.java +++ b/src/main/java/cz/kamma/tvcom/HttpServerApp.java @@ -18,19 +18,36 @@ public class HttpServerApp { public static void main(String[] args) throws Exception { TransmissionService service = new TransmissionService(); - service.loadNextDays(10); HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); ObjectMapper mapper = new ObjectMapper(); - // /transmissions -> all data + // /transmissions -> all data nebo jen pro konkrétní datum server.createContext("/transmissions", exchange -> { try { setCors(exchange); if (!checkApiKey(exchange)) return; - List all = service.getAll(); - respondJson(exchange, mapper.writeValueAsString(all)); + URI uri = exchange.getRequestURI(); + String query = uri.getQuery(); + String date = null; + + if (query != null) { + for (String part : query.split("&")) { + if (part.startsWith("date=")) { + date = java.net.URLDecoder.decode(part.substring(5), StandardCharsets.UTF_8); + } + } + } + + List result; + if (date != null && !date.isBlank()) { + result = service.getByDateLazy(date); + } else { + result = service.getAll(); + } + + respondJson(exchange, mapper.writeValueAsString(result)); } catch (Exception e) { e.printStackTrace(); sendError(exchange, 500, e.getMessage()); @@ -68,8 +85,28 @@ public class HttpServerApp { if (!checkApiKey(exchange)) return; if ("GET".equalsIgnoreCase(exchange.getRequestMethod())) { - service.reloadDataAsync(); - respondJson(exchange, "{\"status\":\"ok\",\"message\":\"Data se obnovují na pozadí.\"}"); + // přečti volitelné datum z query stringu + String dateParam = null; + String query = exchange.getRequestURI().getQuery(); + if (query != null) { + for (String part : query.split("&")) { + if (part.startsWith("date=")) { + dateParam = java.net.URLDecoder.decode(part.substring(5), StandardCharsets.UTF_8); + break; + } + } + } + + // pokud není zadané, použij dnešní den + String dateStr = (dateParam != null && !dateParam.isBlank()) + ? dateParam + : java.time.LocalDate.now().toString(); + + // načti data pro konkrétní den + System.out.println("🔄 Obnovuji data pro den: " + dateStr); + service.reloadDayAsync(dateStr); + + respondJson(exchange, "{\"status\":\"ok\",\"message\":\"Data pro den " + dateStr + " se obnovují.\"}"); } else { exchange.sendResponseHeaders(405, -1); } diff --git a/src/main/java/cz/kamma/tvcom/Searcher.java b/src/main/java/cz/kamma/tvcom/Searcher.java deleted file mode 100644 index 02d483d..0000000 --- a/src/main/java/cz/kamma/tvcom/Searcher.java +++ /dev/null @@ -1,29 +0,0 @@ -package cz.kamma.tvcom; - -import java.sql.*; - -public class Searcher { - private static final String URL = "jdbc:mysql://server01:3306/tvcom?useSSL=false&characterEncoding=UTF-8"; - private static final String USER = "tvcom"; - private static final String PASS = "Passw0rd"; - - public static void main(String[] args) throws Exception { - String search = args.length > 0 ? args[0] : "Nymburk"; - - try (Connection conn = DriverManager.getConnection(URL, USER, PASS)) { - String sql = "SELECT * FROM transmissions WHERE MATCH(title, sport, league) AGAINST (? IN NATURAL LANGUAGE MODE)"; - PreparedStatement ps = conn.prepareStatement(sql); - ps.setString(1, search); - ResultSet rs = ps.executeQuery(); - - while (rs.next()) { - System.out.printf("%s | %s | %s | %s | %s%n", - rs.getString("date"), - rs.getString("time"), - rs.getString("title"), - rs.getString("sport"), - rs.getString("league")); - } - } - } -} diff --git a/src/main/java/cz/kamma/tvcom/TransmissionService.java b/src/main/java/cz/kamma/tvcom/TransmissionService.java index e27cb37..ca9ec55 100644 --- a/src/main/java/cz/kamma/tvcom/TransmissionService.java +++ b/src/main/java/cz/kamma/tvcom/TransmissionService.java @@ -1,33 +1,45 @@ package cz.kamma.tvcom; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.*; -import java.util.concurrent.*; -import java.util.stream.Collectors; - public class TransmissionService { private final List transmissions = Collections.synchronizedList(new ArrayList<>()); - public void loadNextDays(int daysToLoad) throws InterruptedException { - LocalDate today = LocalDate.now(); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - ExecutorService executor = Executors.newFixedThreadPool(5); - - for (int i = 0; i < daysToLoad; i++) { - LocalDate targetDate = today.plusDays(i); - String dateStr = targetDate.format(formatter); - executor.submit(() -> loadDay(dateStr)); + public List getByDateLazy(String dateStr) { + if (dateStr == null || dateStr.isBlank()) return Collections.emptyList(); + synchronized (transmissions) { + boolean exists = transmissions.stream().anyMatch(t -> dateStr.equals(t.date)); + if (!exists) { + System.out.println("📅 Data pro " + dateStr + " nejsou v paměti – načítám..."); + loadDay(dateStr); + } + return transmissions.stream() + .filter(t -> dateStr.equals(t.date)) + .collect(Collectors.toList()); } - - executor.shutdown(); - executor.awaitTermination(5, TimeUnit.MINUTES); - System.out.println("✅ Načteno celkem přenosů: " + transmissions.size()); + } + + public void reloadDayAsync(String dateStr) { + new Thread(() -> { + synchronized (transmissions) { + transmissions.removeIf(t -> dateStr.equals(t.date)); // smaž jen konkrétní den + } + System.out.println("🔄 Načítám znovu data pro " + dateStr); + try { + loadDay(dateStr); + System.out.println("✅ Den " + dateStr + " znovu načten."); + } catch (Exception e) { + System.err.println("❌ Chyba při načítání dne " + dateStr + ": " + e.getMessage()); + } + }).start(); } private void loadDay(String dateStr) { @@ -74,19 +86,4 @@ public class TransmissionService { .collect(Collectors.toList()); } } - - public void reloadDataAsync() { - new Thread(() -> { - synchronized (transmissions) { - transmissions.clear(); - } - System.out.println("🔄 Obnovuji data z webu TVCOM..."); - try { - loadNextDays(10); - System.out.println("✅ Data znovu načtena, přenosů celkem: " + transmissions.size()); - } catch (Exception e) { - System.err.println("❌ Chyba při opětovném načítání: " + e.getMessage()); - } - }).start(); } -} diff --git a/src/main/resources/index.html b/src/main/resources/index.html index 6633a77..326dcf1 100644 --- a/src/main/resources/index.html +++ b/src/main/resources/index.html @@ -1,258 +1,238 @@ - + - - - TVCOM — Přenosy (lokální UI) + + +TVCOM Přenosy + +.filters { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 10px; + margin-bottom: 20px; +} + +input, select, button { + padding: 6px 10px; + font-size: 15px; +} + +.grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 15px; +} + +.card { + background: white; + border-radius: 10px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + overflow: hidden; + transition: transform 0.2s; +} + +.card:hover { + transform: scale(1.02); +} + +.card img { + width: 100%; + height: 160px; + object-fit: cover; +} + +.card-content { + padding: 10px; +} + +.title { + font-weight: bold; + margin-bottom: 5px; +} + +.meta { + font-size: 0.9em; + color: #666; +} + +#loading { + text-align: center; + font-size: 1.2em; + margin-top: 30px; +} + +@media (max-width: 500px) { + .card img { + height: 120px; + } +} + -
-

TVCOM — Přenosy (následujících 10 dní)

+

📺 TVCOM Přenosy

-
- - - - - +
+ + + + +
-
- -
-
- -
- - - - - - - - - - - - - -
ObrDatumČasNázev / TýmySportLigaOdkaz
-
- - -
+
Načítám data...
+