Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

проект 11 спринтаAdd friends likes #106

Closed
Closed
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
22 changes: 22 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,28 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.13.0</version>
</dependency>
<dependency>
<groupId>org.zalando</groupId>
<artifactId>logbook-spring-boot-starter</artifactId>
<version>3.9.0</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ public class FilmorateApplication {
public static void main(String[] args) {
SpringApplication.run(FilmorateApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,65 @@
package ru.yandex.practicum.filmorate.controller;

import org.springframework.web.bind.annotation.RestController;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.model.Film;
import ru.yandex.practicum.filmorate.service.FilmService;

import java.util.Collection;
import java.util.List;

@RestController
@Slf4j
@RequestMapping("/films")
@RequiredArgsConstructor
public class FilmController {
private final FilmService filmService;

@GetMapping
public Collection<Film> findAll() {
log.debug("Получен запрос на получение всех фильмов");
return filmService.findAll();
}

@PostMapping
public Film create(@Valid @RequestBody Film film) {
log.debug("Получен запрос на создание фильма: {}", film.getName());
return filmService.createFilm(film);
}

@PutMapping
public ResponseEntity<Film> update(@Valid @RequestBody Film film) {
log.debug("Получен запрос на обновление фильма с ID: {}", film.getId());
return ResponseEntity.ok(filmService.updateFilm(film));
}

@GetMapping("/popular")
public ResponseEntity<List<Film>> getTenPopularFilms() {
log.debug("Получен запрос на топ 10 фильмов");
return ResponseEntity.ok(filmService.getPopularFilms(10));
}


@GetMapping("/popular?count={count}")
public ResponseEntity<List<Film>> getPopularFilms(@RequestParam(defaultValue = "10") int count) {
log.debug("Получен запрос на получение списка популярный фильмов в количестве %d".formatted(count));
return ResponseEntity.ok(filmService.getPopularFilms(count));
}

@PutMapping("/{id}/like/{userId}")
public ResponseEntity<?> putLike(@PathVariable Long id, @PathVariable Long userId) {
log.debug("Получен запрос на создание лайка фильму с id=%d пользователем с Id=%d".formatted(id, userId));
filmService.putLike(id, userId);
return ResponseEntity.noContent().build();
}

@DeleteMapping("/{id}/like/{userId}")
public ResponseEntity<?> deleteLike(@PathVariable Long id, @PathVariable Long userId) {
log.debug("Получен запрос на удаление лайка фильму с id=%d пользователем с Id=%d".formatted(id, userId));
filmService.deleteLike(id, userId);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package ru.yandex.practicum.filmorate.controller;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.model.User;
import ru.yandex.practicum.filmorate.service.UserService;

import java.util.List;

@RestController
@Slf4j
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;

@GetMapping
public ResponseEntity<List<User>> findAll() {
log.debug("Получен запрос на получение всех пользователей");
return ResponseEntity.ok(userService.findAll());
}

@PostMapping
public ResponseEntity<User> create(@Valid @RequestBody User user) {
log.debug("Получен запрос на создание пользователя: {}", user);
return ResponseEntity.ok(userService.createUser(user));
}

@PutMapping
public ResponseEntity<User> update(@Valid @RequestBody User user) {
log.debug("Получен запрос на обновление пользователя с ID: {}", user.getId());
User persistedUser = userService.updateUser(user);
return ResponseEntity.ok(persistedUser);
}

@PutMapping("/{id}/friends/{friendId}")
public ResponseEntity<?> createFriendship(@PathVariable Long id, @PathVariable Long friendId) {
log.debug(
"Получен запрос на создание дружбы пользователя с id %d с пользователем с id %d".formatted(id, friendId)
);
userService.createFriendship(id, friendId);
return ResponseEntity.noContent().build();
}

@DeleteMapping("/{id}/friends/{friendId}")
public ResponseEntity<?> removeFriendship(@PathVariable Long id, @PathVariable Long friendId) {
log.debug(
"Получен запрос на удаление дружбы пользователя с id %d с пользователем с id %d".formatted(id, friendId)
);
userService.removeFriendship(id, friendId);
return ResponseEntity.noContent().build();
}

@GetMapping("/{id}/friends")
public ResponseEntity<List<User>> showFriends(@PathVariable Long id) {
log.debug("Получен запрос на отображение всех друзей пользователя с id " + id);
return userService.getAllFriendsFromUser(id);
}

@GetMapping("/{id}/friends/common/{friendId}")
public ResponseEntity<List<User>> showCommonFriends(@PathVariable Long id, @PathVariable Long friendId) {
log.debug(("Получен запрос на отображение списка общих друзей " +
"пользователя с id %d, и пользователя с id %d").formatted(id, friendId));
return userService.getCommonFriends(id, friendId);
}
}
15 changes: 15 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/dao/FilmStorage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ru.yandex.practicum.filmorate.dao;

import ru.yandex.practicum.filmorate.model.Film;

import java.util.List;

public interface FilmStorage {
Film save(Film film);

List<Film> findAll();

Film findById(Long id);

Long findMaxId();
}
15 changes: 15 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/dao/UserStorage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ru.yandex.practicum.filmorate.dao;

import ru.yandex.practicum.filmorate.model.User;

import java.util.List;

public interface UserStorage {
User save(User user);

List<User> findAll();

User findById(Long id);

Long findMaxId();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package ru.yandex.practicum.filmorate.dao.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import ru.yandex.practicum.filmorate.dao.FilmStorage;
import ru.yandex.practicum.filmorate.exception.FilmNotFoundException;
import ru.yandex.practicum.filmorate.model.Film;

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

@Repository
@Slf4j
public class InMemoryFilmStorage implements FilmStorage {
private final Map<Long, Film> films = new HashMap<>();


@Override
public Film save(Film film) {
log.info("Сохранение фильма с названием: {}", film.getName());
films.put(film.getId(), film);
return film;
}

@Override
public List<Film> findAll() {
log.info("Получение списка всех фильмов");
System.out.println(films.values());
return new ArrayList<>(films.values());
}


@Override
public Film findById(Long id) {
log.info("Поиск фильма по id: {}", id);
if (!films.containsKey(id)) throw new FilmNotFoundException(id);
return films.get(id);
}

@Override
public Long findMaxId() {
log.info("Поиск максимального значения Id среди существующих фильмов");
return films.keySet()
.stream()
.mapToLong(id -> id)
.max()
.orElse(0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package ru.yandex.practicum.filmorate.dao.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import ru.yandex.practicum.filmorate.dao.UserStorage;
import ru.yandex.practicum.filmorate.exception.UserNotFoundException;
import ru.yandex.practicum.filmorate.model.User;

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

@Repository
@Slf4j
public class InMemoryUserStorage implements UserStorage {
private final Map<Long, User> users = new HashMap<>();

@Override
public User save(User user) {
log.info("Сохранение пользователя: {}", user.getName());
users.put(user.getId(), user);
return user;
}

@Override
public List<User> findAll() {
log.info("Получение списка всех пользователей");
return new ArrayList<>(users.values());
}

@Override
public User findById(Long id) {
log.info("Поиск пользователя по id: {}", id);
if (!users.containsKey(id)) {
log.info("Пользователя с ID: {} не существует", id);
throw new UserNotFoundException(id);
} else {
log.info("Пользователь с ID {} найден", id);
return users.get(id);
}
}

@Override
public Long findMaxId() {
log.info("Поиск максимального значения Id среди существующих пользователей");
return users.keySet()
.stream()
.mapToLong(id -> id)
.max()
.orElse(0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ru.yandex.practicum.filmorate.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@Slf4j
@RestControllerAdvice
public class ErrorHandler {
@ExceptionHandler(NotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse handleNotFoundException(final NotFoundException e) {
log.warn("Ошибка Not Found Exception");
return new ErrorResponse("Ошибка NotFoundException", e.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package ru.yandex.practicum.filmorate.exception;

public record ErrorResponse(String error, String description) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ru.yandex.practicum.filmorate.exception;

public class FilmNotFoundException extends NotFoundException {
public FilmNotFoundException(Long id) {
super(id);
message = "Фильм с id=%d не найден".formatted(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ru.yandex.practicum.filmorate.exception;

public class NotFoundException extends RuntimeException{
long id;
String message;
public NotFoundException(long id) {
this.id = id;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ru.yandex.practicum.filmorate.exception;

public class UserNotFoundException extends NotFoundException {
public UserNotFoundException(Long id) {
super(id);
message = "Пользователь с id=%d не найден".formatted(id);
}
}
30 changes: 22 additions & 8 deletions src/main/java/ru/yandex/practicum/filmorate/model/Film.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
package ru.yandex.practicum.filmorate.model;

import lombok.Getter;
import lombok.Setter;

/**
* Film.
*/
@Getter
@Setter
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.Size;
import lombok.Data;
import ru.yandex.practicum.filmorate.utils.AfterFirstFilmDate;

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

@Data
public class Film {
private Long id;
@NotBlank(message = "Название не должно быть пустым")
private String name;
@Size(max = 200, message = "Превышена максимальная длина описания")
private String description;
@AfterFirstFilmDate
private LocalDate releaseDate;
@Positive(message = "Продолжительность должна быть положительным числом")
private int duration;

private Set<Long> likes = new HashSet<>();
}
Loading
Loading