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
Binary file modified img/schema-database.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 8 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
Expand All @@ -41,6 +40,14 @@
<artifactId>logbook-spring-boot-starter</artifactId>
<version>3.7.2</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,9 @@ public List<Film> getPopularFilms(@Positive @RequestParam(defaultValue = "10") i
return filmService.getPopularFilms(count);
}

@GetMapping("/{id}")
public Film getFilm(@PathVariable Long id) {
return filmService.getFilmById(id);
}

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

import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.yandex.practicum.filmorate.model.Genre;
import ru.yandex.practicum.filmorate.service.GenreService;

import java.util.Collection;

@RestController
@RequiredArgsConstructor
@RequestMapping("/genres")
public class GenreController {
private final GenreService genreService;

@GetMapping("{id}")
public Genre getGenre(@PathVariable Long id) {
return genreService.getGenreById(id);
}

@GetMapping
public Collection<Genre> getGenres() {
return genreService.getGenres();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ru.yandex.practicum.filmorate.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.yandex.practicum.filmorate.model.Rating;
import ru.yandex.practicum.filmorate.service.RatingService;

import java.util.Collection;

@RestController
@RequiredArgsConstructor
@RequestMapping("/mpa")
public class RatingController {
private final RatingService ratingService;

@GetMapping("{id}")
public Rating getRating(@PathVariable Long id) {
return ratingService.getRatingById(id);
}

@GetMapping
public Collection<Rating> getRating() {
return ratingService.getRatings();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public Collection<User> getUsers() {
}

@PostMapping
public User createFilm(@Valid @RequestBody User user) {
public User createUser(@Valid @RequestBody User user) {
return userService.createUser(user);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ public ErrorResponse(String error, String description) {
this.error = error;
this.description = description;
}

}
9 changes: 8 additions & 1 deletion src/main/java/ru/yandex/practicum/filmorate/model/Film.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package ru.yandex.practicum.filmorate.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import ru.yandex.practicum.filmorate.json.DeserializerDuration;
Expand All @@ -13,6 +15,7 @@
import java.time.Duration;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Data
Expand All @@ -30,5 +33,9 @@ public class Film {
@JsonDeserialize(using = DeserializerDuration.class)
private Duration duration;
private final Set<Long> likes = new HashSet<>();

@JsonProperty("mpa")
@Valid
private Rating rating;
@Valid
private List<Genre> genres;
}
17 changes: 17 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/model/Genre.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ru.yandex.practicum.filmorate.model;

import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Genre {
@NotNull
private Long id;
private String name;
}
19 changes: 19 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/model/Rating.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ru.yandex.practicum.filmorate.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Setter
@Getter
@JsonIgnoreProperties(ignoreUnknown = true)
@NoArgsConstructor
@AllArgsConstructor
public class Rating {
@NotNull
private Long id;
private String name;
}
3 changes: 1 addition & 2 deletions src/main/java/ru/yandex/practicum/filmorate/model/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,4 @@ public class User {
@PastOrPresent
private LocalDate birthday;
private final Set<Long> friends = new HashSet<>();

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,53 @@

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.yandex.practicum.filmorate.exception.ExceptionNotFound;
import ru.yandex.practicum.filmorate.model.Film;
import ru.yandex.practicum.filmorate.model.Genre;
import ru.yandex.practicum.filmorate.model.Rating;
import ru.yandex.practicum.filmorate.storage.dal.dao.FilmGenreDbStorage;
import ru.yandex.practicum.filmorate.storage.film.FilmStorage;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class FilmService {

private final FilmStorage filmStorage;
private final UserService userService;
private final GenreService genreService;
private final RatingService ratingService;
private final FilmGenreDbStorage filmGenreDbStorage;

public Collection<Film> getFilms() {
return filmStorage.getFilms();
}

@Transactional
public Film createFilm(Film film) {
return filmStorage.createFilm(film);
validateFilm(film);
Film createdFilm = filmStorage.createFilm(film);
if (film.getGenres() != null && !film.getGenres().isEmpty()) {
filmGenreDbStorage.saveFilmGenres(createdFilm.getId(), film.getGenres());
}
return createdFilm;
}

@Transactional
public Film updateFilm(Film film) {
return filmStorage.updateFilm(film)
validateFilm(film);
Film updatedFilm = filmStorage.updateFilm(film)
.orElseThrow(() -> new ExceptionNotFound("Фильм с идентификатором '%d' не найден".formatted(film.getId())));
filmGenreDbStorage.deleteFilmGenresForFilmId(updatedFilm.getId());
if (film.getGenres() != null && !film.getGenres().isEmpty()) {
filmGenreDbStorage.saveFilmGenres(updatedFilm.getId(), film.getGenres());
}
return updatedFilm;
}

public void addLike(Long filmId, Long userId) {
Expand All @@ -50,4 +72,28 @@ public Film getFilmById(Long id) {
.orElseThrow(() -> new ExceptionNotFound("Фильм с идентификатором '%d' не найден".formatted(id)));
}

private void validateFilm(Film film) {
if (film.getGenres() != null) {
Set<Long> allGenreId = genreService.getGenres()
.stream()
.map(Genre::getId)
.collect(Collectors.toSet());
Set<Long> allGenreIdFilm = film.getGenres()
.stream()
.map(Genre::getId)
.collect(Collectors.toSet());
if (!allGenreId.containsAll(allGenreIdFilm)) {
throw new ExceptionNotFound("Один или несколько жанров не существует.");
}
}
if (film.getRating() != null && film.getRating().getId() != null) {
Set<Long> ratingId = ratingService.getRatings()
.stream()
.map(Rating::getId)
.collect(Collectors.toSet());
if (!ratingId.contains(film.getRating().getId())) {
throw new ExceptionNotFound("Рейтинг с идентификатором %d не найден".formatted(film.getRating().getId()));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package ru.yandex.practicum.filmorate.service;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import ru.yandex.practicum.filmorate.exception.ExceptionNotFound;
import ru.yandex.practicum.filmorate.model.Genre;
import ru.yandex.practicum.filmorate.storage.dal.dao.GenreDbStorage;

import java.util.Collection;

@RequiredArgsConstructor
@Service
public class GenreService {
private final GenreDbStorage genreDbStorage;

public Genre getGenreById(Long id) {
return genreDbStorage.getGenreById(id)
.orElseThrow(() -> new ExceptionNotFound("Жанр с идентификатором '%d' не найден".formatted(id)));
}

public Collection<Genre> getGenres() {
return genreDbStorage.getGenres();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package ru.yandex.practicum.filmorate.service;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import ru.yandex.practicum.filmorate.exception.ExceptionNotFound;
import ru.yandex.practicum.filmorate.model.Rating;
import ru.yandex.practicum.filmorate.storage.dal.dao.RatingDbStorage;

import java.util.Collection;

@RequiredArgsConstructor
@Service
public class RatingService {
private final RatingDbStorage ratingDbStorage;

public Rating getRatingById(Long id) {
return ratingDbStorage.getRatingById(id)
.orElseThrow(() -> new ExceptionNotFound("Рейтинг с идентификатором '%d' не найден".formatted(id)));
}

public Collection<Rating> getRatings() {
return ratingDbStorage.getRatings();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
@RequiredArgsConstructor
@Service
public class UserService {

private final UserStorage userStorage;

public Collection<User> getUsers() {
Expand Down
Loading
Loading