Skip to content

Commit

Permalink
add new check
Browse files Browse the repository at this point in the history
  • Loading branch information
NastasiyaT committed Oct 20, 2023
1 parent 276278a commit 4a3adfa
Show file tree
Hide file tree
Showing 18 changed files with 398 additions and 78 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ dependencies {
implementation("io.javalin:javalin-bundle:5.6.1")
implementation("io.javalin:javalin-rendering:5.6.0")
implementation("gg.jte:jte:3.0.1")
implementation("com.konghq:unirest-java:4.0.0-RC2")

implementation("org.apache.commons:commons-lang3:3.12.0")
implementation("com.fasterxml.jackson.core:jackson-databind:2.15.1")

implementation("org.mockito:mockito-core:5.4.0")
testImplementation("org.assertj:assertj-core:3.24.2")
testImplementation(platform("org.junit:junit-bom:5.9.2"))
testImplementation("org.junit.jupiter:junit-jupiter:5.9.2")
testImplementation("com.squareup.okhttp3:mockwebserver:4.11.0")
}

tasks.test {
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/hexlet/code/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import gg.jte.ContentType;
import gg.jte.TemplateEngine;
import gg.jte.resolve.ResourceCodeResolver;
import hexlet.code.controller.UrlChecksController;
import hexlet.code.controller.UrlsController;
import hexlet.code.repository.BaseRepository;
import hexlet.code.util.NamedRoutes;
Expand Down Expand Up @@ -82,6 +83,7 @@ public static Javalin getApp() throws IOException, SQLException {
app.post(NamedRoutes.rootPath(), UrlsController::create);
app.get(NamedRoutes.urlsPath(), UrlsController::index);
app.get(NamedRoutes.urlPath("{id}"), UrlsController::show);
app.post(NamedRoutes.urlCheckPath("{id}"), UrlChecksController::check);

return app;
}
Expand Down
56 changes: 56 additions & 0 deletions app/src/main/java/hexlet/code/controller/UrlChecksController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package hexlet.code.controller;

import hexlet.code.model.UrlCheck;
import hexlet.code.repository.UrlCheckRepository;
import hexlet.code.repository.UrlRepository;
import hexlet.code.util.NamedRoutes;
import io.javalin.http.Context;
import io.javalin.http.NotFoundResponse;
import kong.unirest.HttpResponse;
import kong.unirest.Unirest;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UrlChecksController {
public static void check(Context ctx) throws SQLException {
var urlId = ctx.pathParamAsClass("id", Long.class).get();

var url = UrlRepository.find(urlId)
.orElseThrow(() -> new NotFoundResponse("Запись с таким ID не найдена"));
var name = url.getName();

try {
HttpResponse<String> response = Unirest.get(name).asString();
String responseBody = response.getBody();

int statusCode = response.getStatus();

Pattern patternH1 = Pattern.compile("<h1>([^<]*)</h1>", Pattern.CASE_INSENSITIVE);
Matcher matcherH1 = patternH1.matcher(responseBody);
String h1 = matcherH1.find() ? matcherH1.group(1) : "";

Pattern patternTitle = Pattern.compile("<title>([^<]*)</title>", Pattern.CASE_INSENSITIVE);
Matcher matcherTitle = patternTitle.matcher(responseBody);
String title = matcherTitle.find() ? matcherTitle.group(1) : "";

Pattern patternDescription = Pattern.compile("<meta name=\"description\" content=\"([^<]*)\">",
Pattern.CASE_INSENSITIVE);
Matcher matcherDescription = patternDescription.matcher(responseBody);
String description = matcherDescription.find() ? matcherDescription.group(1) : "";

var createdAt = new Timestamp(System.currentTimeMillis());

var urlCheck = new UrlCheck(statusCode, h1, title, description, createdAt);
urlCheck.setUrlId(urlId);
UrlCheckRepository.save(urlCheck);

} catch (Exception e) {
throw new RuntimeException(e);
}

ctx.redirect(NamedRoutes.urlPath(urlId));
}
}
46 changes: 26 additions & 20 deletions app/src/main/java/hexlet/code/controller/UrlsController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import hexlet.code.dto.urls.UrlPage;
import hexlet.code.dto.urls.UrlsPage;
import hexlet.code.model.Url;
import hexlet.code.model.UrlCheck;
import hexlet.code.repository.UrlCheckRepository;
import hexlet.code.repository.UrlRepository;
import hexlet.code.util.NamedRoutes;
import hexlet.code.util.Utils;
Expand All @@ -14,7 +16,10 @@
import java.net.URL;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class UrlsController {

Expand Down Expand Up @@ -46,36 +51,37 @@ public static void create(Context ctx) throws SQLException {

public static void index(Context ctx) throws SQLException {
var urls = UrlRepository.getEntities();
final int itemsPerPage = 10;
int pageCount = (urls.size() % itemsPerPage == 0)
? (urls.size() / itemsPerPage) : (urls.size() / itemsPerPage + 1);
int pageNumber = ctx.queryParamAsClass("page", Integer.class).getOrDefault(pageCount);
List<Url> urlsPerPage = new ArrayList<>();

if (!urls.isEmpty()) {
final int itemsPerPage = 10;
int pageCount = (urls.size() % itemsPerPage == 0)
? (urls.size() / itemsPerPage) : (urls.size() / itemsPerPage + 1);
int pageNumber = ctx.queryParamAsClass("page", Integer.class).getOrDefault(pageCount);

if (pageNumber <= pageCount) {
var urlsPerPage = Utils.getItemsPerPage(urls, pageNumber, itemsPerPage);
var page1 = new UrlsPage(urlsPerPage, pageNumber);
String message = ctx.consumeSessionAttribute("message");
page1.setMessage(message);
ctx.render("urls/index.jte", Collections.singletonMap("page", page1));
} else {
throw new NotFoundResponse("Страница не найдена");
}
if (urls.isEmpty()) {
var pageEmpty = new UrlsPage(urlsPerPage);
String message = ctx.consumeSessionAttribute("message");
pageEmpty.setMessage(message);
ctx.render("urls/index.jte", Collections.singletonMap("page", pageEmpty));
} else if (pageNumber <= pageCount) {
urlsPerPage = Utils.getItemsPerPage(urls, pageNumber, itemsPerPage);
Map<Url, List<UrlCheck>> checks = Utils.getItemsPerPageWithChecks(urlsPerPage);

} else {
var page2 = new UrlsPage(urls);
var page = new UrlsPage(urlsPerPage, checks, pageNumber);
String message = ctx.consumeSessionAttribute("message");
page2.setMessage(message);
ctx.render("urls/index.jte", Collections.singletonMap("page", page2));
page.setMessage(message);
ctx.render("urls/index.jte", Collections.singletonMap("page", page));
} else {
throw new NotFoundResponse("Страница не найдена");
}
}

public static void show(Context ctx) throws SQLException {
var id = ctx.pathParamAsClass("id", Long.class).get();
var url = UrlRepository.find(id)
.orElseThrow(() -> new NotFoundResponse("Запись с таким ID не найдена"));
var page = new UrlPage(url);
var checks = UrlCheckRepository.find(id)
.orElse(null);
var page = new UrlPage(url, checks);
ctx.render("urls/show.jte", Collections.singletonMap("page", page));
}
}
4 changes: 4 additions & 0 deletions app/src/main/java/hexlet/code/dto/urls/UrlPage.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package hexlet.code.dto.urls;

import hexlet.code.model.Url;
import hexlet.code.model.UrlCheck;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.List;

@AllArgsConstructor
@Getter
public class UrlPage {
private Url url;
private List<UrlCheck> checks;
}
3 changes: 3 additions & 0 deletions app/src/main/java/hexlet/code/dto/urls/UrlsPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

import hexlet.code.dto.BasePage;
import hexlet.code.model.Url;
import hexlet.code.model.UrlCheck;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.List;
import java.util.Map;

@AllArgsConstructor
@Getter
public class UrlsPage extends BasePage {
private List<Url> urls;
private Map<Url, List<UrlCheck>> checks;
private int pageNumber;

public UrlsPage(List<Url> urls) {
Expand Down
8 changes: 2 additions & 6 deletions app/src/main/java/hexlet/code/model/Url.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package hexlet.code.model;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.sql.Timestamp;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
Expand All @@ -18,10 +20,4 @@ public Url(String name, Timestamp createdAt) {
this.name = name;
this.createdAt = createdAt;
}

public Url(Long id, String name, Timestamp createdAt) {
this.name = name;
this.createdAt = createdAt;
this.id = id;
}
}
30 changes: 30 additions & 0 deletions app/src/main/java/hexlet/code/model/UrlCheck.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package hexlet.code.model;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.sql.Timestamp;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class UrlCheck {
private Long id;
private Long urlId;
private int statusCode;
private String h1;
private String title;
private String description;
private Timestamp createdAt;

public UrlCheck(int statusCode, String h1, String title, String description, Timestamp createdAt) {
this.statusCode = statusCode;
this.h1 = h1;
this.title = title;
this.description = description;
this.createdAt = createdAt;
}
}
97 changes: 97 additions & 0 deletions app/src/main/java/hexlet/code/repository/UrlCheckRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package hexlet.code.repository;

import hexlet.code.model.UrlCheck;

import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

public class UrlCheckRepository extends BaseRepository {

public static void save(UrlCheck urlCheck) throws SQLException {
var sql = "INSERT INTO url_checks (url_id, status_code, h1, title, description, created_at) "
+ "VALUES (?, ?, ?, ?, ?, ?)";
try (var conn = dataSource.getConnection();
var preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {

preparedStatement.setLong(1, urlCheck.getUrlId());
preparedStatement.setInt(2, urlCheck.getStatusCode());
preparedStatement.setString(3, urlCheck.getH1());
preparedStatement.setString(4, urlCheck.getTitle());
preparedStatement.setString(5, urlCheck.getDescription());
preparedStatement.setTimestamp(6, urlCheck.getCreatedAt());
preparedStatement.executeUpdate();

var generatedKeys = preparedStatement.getGeneratedKeys();
if (generatedKeys.next()) {
urlCheck.setId(generatedKeys.getLong(1));
} else {
throw new SQLException("Не сформирован ID");
}
}
}

public static Optional<List<UrlCheck>> find(Long urlId) throws SQLException {
var sql = "SELECT * FROM url_checks WHERE url_id = ?";
try (var conn = dataSource.getConnection();
var stmt = conn.prepareStatement(sql)) {

stmt.setLong(1, urlId);
var resultSet = stmt.executeQuery();

var results = new ArrayList<UrlCheck>();
var currentListId = 1L;

while (resultSet.next()) {
var statusCode = resultSet.getInt("status_code");
var h1 = resultSet.getString("h1");
var title = resultSet.getString("title");
var description = resultSet.getString("description");
var createdAt = resultSet.getTimestamp("created_at");
var urlCheck = new UrlCheck(statusCode, h1, title, description, createdAt);
urlCheck.setUrlId(urlId);
urlCheck.setId(currentListId);

currentListId++;

results.add(urlCheck);
}

if (!results.isEmpty()) {
return Optional.of(results);
} else {
return Optional.empty();
}
}
}

public static List<UrlCheck> getEntities() throws SQLException {
var sql = "SELECT * FROM url_checks";
try (var conn = dataSource.getConnection();
var stmt = conn.prepareStatement(sql)) {

var resultSet = stmt.executeQuery();
var result = new ArrayList<UrlCheck>();

while (resultSet.next()) {
var id = resultSet.getLong("id");
var urlId = resultSet.getLong("url_id");
var statusCode = resultSet.getInt("status_code");
var h1 = resultSet.getString("h1");
var title = resultSet.getString("title");
var description = resultSet.getString("description");
var createdAt = resultSet.getTimestamp("created_at");
var urlCheck = new UrlCheck(statusCode, h1, title, description, createdAt);
urlCheck.setId(id);
urlCheck.setUrlId(urlId);
result.add(urlCheck);
}
result.sort(Comparator.comparing(UrlCheck::getId));

return result;
}
}
}
3 changes: 3 additions & 0 deletions app/src/main/java/hexlet/code/repository/UrlRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

Expand Down Expand Up @@ -73,6 +74,8 @@ public static List<Url> getEntities() throws SQLException {
url.setId(id);
result.add(url);
}
result.sort(Comparator.comparing(Url::getId));

return result;
}
}
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/java/hexlet/code/util/NamedRoutes.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,12 @@ public static String urlsPath() {
public static String urlsPath(int page) {
return "/urls?page=" + page;
}

public static String urlCheckPath(Long id) {
return urlCheckPath(String.valueOf(id));
}

public static String urlCheckPath(String id) {
return "/urls/" + id + "/checks";
}
}
Loading

0 comments on commit 4a3adfa

Please sign in to comment.