Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.zalando</groupId>
<artifactId>logbook-spring-boot-starter</artifactId>
<version>3.7.2</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,78 +1,66 @@
package ru.yandex.practicum.filmorate.controller;

import org.springframework.http.HttpStatus;
import ru.yandex.practicum.filmorate.exceptions.UserNotFoundException;
import ru.yandex.practicum.filmorate.exceptions.ValidationException;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import ru.yandex.practicum.filmorate.model.Film;
import org.slf4j.Logger;

import jakarta.validation.Valid;
import ru.yandex.practicum.filmorate.service.FilmService;

import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.time.LocalDate;

@RestController
@RequestMapping("/films")
@RequiredArgsConstructor
public class FilmController {

private final Map<Long, Film> films = new HashMap<>();
private final LocalDate dayOfCreationCinema = LocalDate.of(1895, 12, 28);
private final FilmService filmService;
private static final Logger log = LoggerFactory.getLogger(FilmController.class);

private Long getNextId() {
long currentMaxId = films.keySet()
.stream()
.mapToLong(id -> id)
.max()
.orElse(0);
return ++currentMaxId;
}

@GetMapping
public List<Film> findAll() {
return new ArrayList<>(films.values());
return filmService.getAllFilms();
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Film createFilm(@Valid @RequestBody Film film) {
log.debug("Получен фильм для добавления: {}", film);
film.setId(getNextId());

films.put(film.getId(), film);
log.info("Фильм {} успешно добавлен", film);

return film;
return filmService.addFilm(film);
}

@PutMapping
@ResponseStatus(HttpStatus.OK)
public Film updateFilm(@Valid @RequestBody Film film) {
if (film.getId() == null) {
log.error("Не введен Id фильма");
throw new ValidationException("id фильма не может быть пустым");
}
if (films.containsKey(film.getId())) {
Film oldFilm = films.get(film.getId());
return filmService.updateFilm(film);
}

@PutMapping("/{id}/like/{userId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void addLike(@PathVariable Long id, @PathVariable Long userId) {
filmService.addLike(userId, id);
log.info("Добавлен лайк пользователем с id: {} к фильму с id: {}", userId, id);
}

oldFilm.setName(film.getName());
log.info("Название фильма {} изменено", oldFilm);
oldFilm.setDescription(film.getDescription());
log.info("Описание фильма {} изменено", oldFilm);
oldFilm.setReleaseDate(film.getReleaseDate());
log.info("Дата выхода фильма {} изменена", oldFilm);
oldFilm.setDuration(film.getDuration());
log.info("Длительность фильма {} изменена", oldFilm);
@DeleteMapping("/{id}/like/{userId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteLike(@PathVariable Long id, @PathVariable Long userId) {
filmService.deleteLike(userId, id);
log.info("Удален лайк пользователем с id: {} к фильму с id: {}", userId, id);
}

return oldFilm;
}
log.error("Фильм с id = {} не найден", film.getId());
throw new UserNotFoundException("Фильм с id = " + film.getId() + " не найден");
@GetMapping("/popular")
public List<Film> getPopularFilms(@RequestParam(required = false, defaultValue = "10") Integer count) {
log.info("Получен список популярных фильмов");
return filmService.getPopularFilms(count);
}
}
Original file line number Diff line number Diff line change
@@ -1,95 +1,66 @@
package ru.yandex.practicum.filmorate.controller;

import org.springframework.http.HttpStatus;
import ru.yandex.practicum.filmorate.exceptions.UserNotFoundException;
import ru.yandex.practicum.filmorate.exceptions.ValidationException;
import org.slf4j.LoggerFactory;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.springframework.web.bind.annotation.*;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import ru.yandex.practicum.filmorate.model.User;
import ru.yandex.practicum.filmorate.service.UserService;

import jakarta.validation.Valid;

import java.util.*;
import java.util.List;

@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {
private final Map<Long, User> users = new HashMap<>();
private final Set<String> emails = new HashSet<>();
private final Set<String> logins = new HashSet<>();
private final UserService userService;
private static final Logger log = LoggerFactory.getLogger(UserController.class);

private Long getNextId() {
long currentMaxId = users.keySet()
.stream()
.mapToLong(id -> id)
.max()
.orElse(0);
return ++currentMaxId;
}

@GetMapping
public List<User> findAll() {
return new ArrayList<>(users.values());
return userService.getAllUsers();
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User addUser(@Valid @RequestBody User user) {
user.setId(getNextId());

if (logins.contains(user.getLogin())) {
log.error("Попытка добавить пользователя с существующим логином: {}", user.getLogin());
throw new ValidationException("Ошибка. Попытка добавить логин, который уже существует");
}

if (emails.contains(user.getEmail())) {
log.error("Попытка добавить пользователя с существующим email: {}", user.getEmail());
throw new ValidationException("Ошибка. Email уже существует");
}

users.put(user.getId(), user);
emails.add(user.getEmail());
logins.add(user.getLogin());
log.info("Пользователь добавлен");
return user;
return userService.addUser(user);
}

@PutMapping
public User updateUser(@Valid @RequestBody User newUser) {
if (newUser.getId() == null) {
log.error("Не введен id пользователя при изменении");
throw new ValidationException("id пользователя должен быть указан");
}

if (users.containsKey(newUser.getId())) {
User oldUser = users.get(newUser.getId());

// Удаляем старый адрес электронной почты и логин из наборов
emails.remove(oldUser.getEmail());
logins.remove(oldUser.getLogin());
public User updateUser(@Valid @RequestBody User user) {
return userService.updateUser(user);
}

// Проверяем, не конфликтуют ли новые адрес электронной почты и логин
if (emails.contains(newUser.getEmail())) {
throw new ValidationException("Email уже существует");
}
if (logins.contains(newUser.getLogin())) {
throw new ValidationException("Логин уже существует");
}
@PutMapping("/{id}/friends/{friendId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void addFriend(@PathVariable Long id, @PathVariable Long friendId) {
userService.addFriend(id, friendId);
}

oldUser.setEmail(newUser.getEmail());
oldUser.setLogin(newUser.getLogin());
oldUser.setName(newUser.getName());
oldUser.setBirthday(newUser.getBirthday());
@DeleteMapping("/{id}/friends/{friendId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteFriend(@PathVariable Long id, @PathVariable Long friendId) {
userService.deleteFriend(id, friendId);
}

// Добавляем новый Email и Логин
emails.add(newUser.getEmail());
logins.add(newUser.getLogin());
@GetMapping("/{id}/friends")
public List<User> getFriends(@PathVariable Long id) {
return userService.allIdFriends(id);
}

return oldUser;
}
log.error("Пользователь с id {} не найден", newUser.getId());
throw new UserNotFoundException("Пользователь с id =" + newUser.getId() + " не найден");
@GetMapping("/{id}/friends/common/{otherId}")
public List<User> getCommonFriends(@PathVariable Long id, @PathVariable Long otherId) {
return userService.generalFriends(id, otherId);
}
}
19 changes: 12 additions & 7 deletions src/main/java/ru/yandex/practicum/filmorate/model/Film.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
package ru.yandex.practicum.filmorate.model;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.PositiveOrZero;
import jakarta.validation.constraints.Size;
import lombok.Data;
import jakarta.validation.constraints.*;
import ru.yandex.practicum.filmorate.validation.ReleaseDateValidation;

import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;

@Data
public class Film {
private Long id;

@NotBlank(message = "Название фильма не может быть пустым")
@NotBlank
private String name;

@NotBlank(message = "Описание фильма не может быть пустым")
@Size(max = 200, message = "Максимальная длина описания — 200 символов")
@NotBlank
@Size(max = 200)
private String description;

@NotNull(message = "Дата выхода не может быть пустой")
@ReleaseDateValidation // Кастомная аннотация валидации
@NotNull
@ReleaseDateValidation(message = "Release date cannot be earlier than December 28, 1895")
private LocalDate releaseDate;

@NotNull(message = "Длительность не может быть пустой")
@PositiveOrZero(message = "Длительность фильма должна быть больше или равна нулю")
private Integer duration;
private Set<Long> idUserLikes = new HashSet<>();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отличный выбор коллекции 👍

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Спасибо))

}
31 changes: 16 additions & 15 deletions src/main/java/ru/yandex/practicum/filmorate/model/User.java
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
package ru.yandex.practicum.filmorate.model;

import jakarta.validation.constraints.*;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.PastOrPresent;
import jakarta.validation.constraints.Pattern;
import lombok.Data;

import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;

@Data
public class User {
private Long id;

@NotBlank(message = "Email не может быть пустым")
@Email(message = "Email должен соответствовать формату")
@NotBlank
@Email
private String email;

@NotBlank(message = "Login не может быть пустым")
@Pattern(regexp = "^[^\\s]+$", message = "Login не должен содержать пробелы")
@NotBlank
@Pattern(regexp = "^\\S+$")
private String login;

private String name;

@NotNull(message = "Дата рождения не может быть пустой")
@PastOrPresent(message = "Дата рождения не может быть в будущем")
@NotNull
@PastOrPresent
private LocalDate birthday;

public User() {
}
private Set<Long> friends = new HashSet<>();

public void setLogin(String login) {
this.login = login;
// Устанавливаем name, если он не задан
if (this.name == null || this.name.isBlank()) {
this.name = login; // Или любое другое значение по умолчанию
}
public void setName(String name) {
this.name = (name == null || name.isBlank()) ? this.login : name;
}
}
Loading
Loading