Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
f228861
Добавление в БД таблицы Отзывов(reviews)
LyutovSergey Feb 17, 2026
e714324
Добавление в БД таблицы Отзывов(reviews)
LyutovSergey Feb 17, 2026
ad22d46
Добавление в БД таблицы Отзывов(reviews)
LyutovSergey Feb 17, 2026
cd6b435
add-reviews ver 1.0
LyutovSergey Feb 17, 2026
80fe1bc
add-reviews ver 1.0
LyutovSergey Feb 17, 2026
5880c1b
add-reviews ver 1.0
LyutovSergey Feb 17, 2026
f65b591
add-reviews ver 1.1
LyutovSergey Feb 17, 2026
27159ea
Merge pull request #6 from AleksOBM/add-reviews
LyutovSergey Feb 18, 2026
dd320ad
Добавление сущности события + доработка UserService и FilmService на …
milayadasha Feb 18, 2026
916ec8f
feat: Implement film recommendation system
Darya346 Feb 18, 2026
0794ac6
Доработка ReviewService и решение конфликтов
milayadasha Feb 18, 2026
0dbf16c
trigger tests after changing base branch
Darya346 Feb 18, 2026
32a9779
fix: add empty line before getRecommendations for checkstyle
Darya346 Feb 18, 2026
ae14ec3
Решение ошибок тестов (убрала неиспользуемый импорт)
milayadasha Feb 18, 2026
0958a90
fix: force remove all trailing whitespaces
Darya346 Feb 18, 2026
1782a06
fix: remove trailing whitespace in UserService
Darya346 Feb 18, 2026
4109667
Merge pull request #7 from AleksOBM/add-recommendations
Darya346 Feb 18, 2026
c8ce8b8
Merge branch 'develop' into add-feed
milayadasha Feb 19, 2026
17781d9
Решение конфликтов при мёрже
milayadasha Feb 19, 2026
b6c4c14
Merge pull request #8 from AleksOBM/add-feed
milayadasha Feb 19, 2026
0d56fc7
Модернизация метода, который возвращает популярные фильмы. Добавлены …
milayadasha Feb 19, 2026
71675e1
Merge pull request #11 from AleksOBM/add-most-populars
milayadasha Feb 19, 2026
5d5816a
Создать основные классы, расставить todo
AleksOBM Feb 16, 2026
046673b
Отключить JPA
AleksOBM Feb 16, 2026
b7d0e40
Добавить таблицы в БД,
AleksOBM Feb 17, 2026
f163c26
Добавить логику обновления и удаления режиссеров, и сортировку фильмо…
AleksOBM Feb 18, 2026
2bb2201
Исправить readme
AleksOBM Feb 18, 2026
a44c77a
Добавить @Autowired
AleksOBM Feb 20, 2026
7ae6495
Merge pull request #9 from AleksOBM/add-director
AleksOBM Feb 20, 2026
18df2d1
ver 1.0 Добавлена возможность получать общих с другим пользователем ф…
LyutovSergey Feb 19, 2026
5baa904
ver 1.1 обновление после внесения изменений в film
LyutovSergey Feb 20, 2026
433de15
Merge pull request #12 from AleksOBM/add-common-films
LyutovSergey Feb 20, 2026
d824d6e
Добавить функциональность для удаления фильма и пользователя по идент…
AleksOBM Feb 20, 2026
90d5a75
Add search
Darya346 Feb 20, 2026
f9dc750
trigger search tests
Darya346 Feb 20, 2026
ad6eed3
Merge pull request #13 from AleksOBM/add-remove-endpoint
AleksOBM Feb 20, 2026
a53baf3
Merge branch 'develop' into add-search
Darya346 Feb 20, 2026
fac6ffb
fix: resolve all checkstyle issues
Darya346 Feb 20, 2026
ecaa10a
fix: fix checkstyle
Darya346 Feb 20, 2026
7602f02
fix: resolve checkstyle empty line issues
Darya346 Feb 20, 2026
a20a4de
fix: resolve checkstyle
Darya346 Feb 20, 2026
a9e27e5
checkstyle
Darya346 Feb 20, 2026
5513208
Merge pull request #14 from AleksOBM/add-search
Darya346 Feb 20, 2026
22faeb1
В сущности Event поле id заменила на eventId
milayadasha Feb 20, 2026
409ba1c
Merge pull request #16 from AleksOBM/add-feed
milayadasha Feb 20, 2026
0b9dda8
В метод getTopByFilters добавлен директор
milayadasha Feb 20, 2026
6c3ed03
Merge pull request #17 from AleksOBM/fix-most-popular
milayadasha Feb 20, 2026
a0361a1
Исправить валидацию имени пользователя
AleksOBM Feb 21, 2026
b61c976
Исправить текст ошибки при отсутствии режиссеров
AleksOBM Feb 21, 2026
fad5d92
Исправить ошибку отсктствия записи в базу при обновлении жанров и реж…
AleksOBM Feb 21, 2026
ff81dcc
Исправить ошибку при которой старый режиссер или жанр остается, если …
AleksOBM Feb 21, 2026
83d64a1
Убрать unused import
AleksOBM Feb 21, 2026
5f22178
Добавить проверку имени пользователя при получении события пользователя
AleksOBM Feb 21, 2026
b53306b
Рефакторинг и подготовка к первому ревью
AleksOBM Feb 21, 2026
47657a0
Отправка на первое ревью
AleksOBM Feb 21, 2026
c11817b
Исправить мелкие баги и доработать readme
AleksOBM Feb 22, 2026
c4491a5
fix: исправлены замечания в getRecommendations
Darya346 Feb 22, 2026
33681bb
fix: remove unused import in ReviewService
Darya346 Feb 22, 2026
d981d3e
Merge pull request #23 from AleksOBM/add-recommendations
Darya346 Feb 22, 2026
402c5ea
Отправить на второе ревью
AleksOBM Feb 23, 2026
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 ExamplesOfRequests.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added FILMO_RATE_DATABASE_MAP.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed QuickDBD-FILMO_RATE.png
Binary file not shown.
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
# java-filmorate (Java Filmorate)
### Описание (Description)
The Filmorate project — это приложение для работы с базой данных фильмов.
# java-filmorate
The Filmorate project — это приложение для работы с базой данных фильмов.
А также площадка для общения и взаимодействия пользователей.

### Основные возможности
- Хранение данных о фильмах
- Хранение данных о фильмах
- Хранение данных о пользователях
- Возможность пользователям ставить лайки фильмам
- Возможность пользователям добавлять друг друга в друзья
- Возможность получать рейтинг TOP_N фильмов по количеству лайков
- Возможность получать общих с другим пользователем фильмов с сортировкой по их популярности
- Возможность заводить друзей
- Возможность оставлять отзывы о фильмах
- Фильмы содержат возрастные ограничения по стандарту MPPA
- Реализован поиск по названию и режиссерам
- Реализована система жанров для фильмов
- Есть лента событий

### Требования (Environmental Requirements)
Для запуска проекта требуется: - Java версии 21
Приложение работает на порту 8080
Expand Down Expand Up @@ -48,7 +55,7 @@ The Filmorate project — это приложение для работы с б
- logback-classic
- logbook-spring-boot-starter
### Схема базы данных (Database map)
![DatabaseMap](QuickDBD-FILMO_RATE.png "Database map:")
![DatabaseMap](FILMO_RATE_DATABASE_MAP.png "Database map:")
### Примеры запросов к базе данных:
1. Get TOP-10 films:
```sql
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;

@SpringBootApplication
@SpringBootApplication(exclude = {HibernateJpaAutoConfiguration.class})
public class FilmorateApplication {
public static void main(String[] args) {
SpringApplication.run(FilmorateApplication.class, args);
}
public static void main(String[] args) {
SpringApplication.run(FilmorateApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package ru.yandex.practicum.filmorate.controller;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.dto.DirectorDto;
import ru.yandex.practicum.filmorate.dto.request.create.DirectorCreateRequest;
import ru.yandex.practicum.filmorate.dto.request.update.DirectorUpdateRequest;
import ru.yandex.practicum.filmorate.service.DirectorService;

import java.util.Collection;

@RequestMapping("/directors")
@RestController
@RequiredArgsConstructor
public class DirectorController {
private final DirectorService directorService;

@GetMapping
public Collection<DirectorDto> getAllDirectors() {
return directorService.getAllDirectorDtos();
}

@GetMapping("/{directorId}")
public DirectorDto getDirectorById(@PathVariable Integer directorId) {
return directorService.getDirectorDtoById(directorId);
}

@PostMapping
public DirectorDto createDirector(@RequestBody @Valid DirectorCreateRequest directorRequest) {
return directorService.create(directorRequest);
}

@PutMapping
public DirectorDto updateDirector(@RequestBody @Valid DirectorUpdateRequest directorRequest) {
return directorService.update(directorRequest);
}

@DeleteMapping("/{directorId}")
public void deleteDirector(@PathVariable Integer directorId) {
directorService.delete(directorId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.FieldError;
import org.springframework.validation.method.MethodValidationException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import ru.yandex.practicum.filmorate.model.ErrorResponse;
import ru.yandex.practicum.filmorate.exception.*;
import ru.yandex.practicum.filmorate.model.ErrorResponse;

import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -83,6 +84,12 @@ public ErrorResponse handlerMethodValidationException(final MethodValidationExce
return new ErrorResponse(e.getAllErrors().getFirst().getDefaultMessage());
}

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler
public ErrorResponse handleEmptyBody(HttpMessageNotReadableException ex) {
return new ErrorResponse("Тело запроса отсутствует или некорректно");
}

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleMethodArgumentException(final MethodArgumentNotValidException e) {
Map<String, String> errors = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,80 @@
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.dto.request.create.FilmCreateRequest;
import ru.yandex.practicum.filmorate.dto.FilmDto;
import ru.yandex.practicum.filmorate.dto.request.create.FilmCreateRequest;
import ru.yandex.practicum.filmorate.dto.request.update.FilmUpdateRequest;
import ru.yandex.practicum.filmorate.servise.FilmService;
import ru.yandex.practicum.filmorate.servise.util.LikeAction;
import ru.yandex.practicum.filmorate.service.FilmService;
import ru.yandex.practicum.filmorate.service.util.LikeAction;

import java.util.Collection;

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

private final FilmService filmService;

@GetMapping
public Collection<FilmDto> findAll() {
return filmService.findAll();
}

@GetMapping("/{id}")
public FilmDto findById(@PathVariable long id) {
return filmService.findById(id);
}

@GetMapping("/popular")
public Collection<FilmDto> getTop(@RequestParam (defaultValue = "10", required = false) Integer count) {
return filmService.getTopFilms(count);
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public FilmDto create(@RequestBody @Valid FilmCreateRequest request) {
return filmService.create(request);
}

@PutMapping
public FilmDto update(@RequestBody FilmUpdateRequest request) {
return filmService.update(request);
}

@PutMapping("/{filmId}/like/{userId}")
public void setLike(@PathVariable long filmId, @PathVariable long userId) {
filmService.changeLike(LikeAction.SET, filmId, userId);
}

@DeleteMapping("/{filmId}/like/{userId}")
public void deleteLike(@PathVariable long filmId, @PathVariable long userId) {
filmService.changeLike(LikeAction.REMOVE, filmId, userId);
}
}
private final FilmService filmService;

@GetMapping
public Collection<FilmDto> findAll() {
return filmService.findAll();
}

@GetMapping("/{id}")
public FilmDto findById(@PathVariable long id) {
return filmService.findById(id);
}

@GetMapping("/popular")
public Collection<FilmDto> getTop(@RequestParam(defaultValue = "10", required = false) Integer count,
@RequestParam(required = false) Integer genreId,
@RequestParam(required = false) String year) {
return filmService.getTopFilms(count, genreId, year);
}

@GetMapping("/common")
public Collection<FilmDto> getCommonLikedFilms(@RequestParam(required = true) Long userId,
@RequestParam(required = true) Long friendId) {
return filmService.getCommonLikedFilms(userId, friendId);
}

@GetMapping("/director/{directorId}")
public Collection<FilmDto> findSortedFilmsOfDirector(
@PathVariable Integer directorId,
@RequestParam(required = false) String sortBy
) {
return filmService.getSortedFilmsOfDirector(directorId, sortBy);
}

@GetMapping("/search")
public Collection<FilmDto> search(@RequestParam String query, @RequestParam String by) {
return filmService.search(query, by);
}

@ResponseStatus(HttpStatus.CREATED)
@PostMapping
public FilmDto create(@RequestBody @Valid FilmCreateRequest request) {
return filmService.create(request);
}

@PutMapping
public FilmDto update(@RequestBody FilmUpdateRequest request) {
return filmService.update(request);
}

@PutMapping("/{filmId}/like/{userId}")
public void setLike(@PathVariable long filmId, @PathVariable long userId) {
filmService.changeLike(LikeAction.SET, filmId, userId);
}

@DeleteMapping("/{filmId}/like/{userId}")
public void deleteLike(@PathVariable long filmId, @PathVariable long userId) {
filmService.changeLike(LikeAction.REMOVE, filmId, userId);
}

@DeleteMapping("/{filmId}")
public void deleteFilm(@PathVariable long filmId) {
filmService.remove(filmId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.yandex.practicum.filmorate.dto.GenreDto;
import ru.yandex.practicum.filmorate.servise.GenreService;
import ru.yandex.practicum.filmorate.service.GenreService;

import java.util.Collection;

@RestController
@RequestMapping("/genres")
@RestController
@RequiredArgsConstructor
public class GenreController {
private final GenreService genreService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,43 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("")
@RestController
public class HomeController {

@GetMapping
public String homePage() {
return """
<p><br></p>
<pre>
███████╗██╗██╗ ███╗ ███╗ ██████╗ ██████╗ █████╗ ████████╗███████╗
██╔════╝██║██║ ████╗ ████║██╔═══██╗ ██╔══██╗██╔══██╗╚══██╔══╝██╔════╝
█████╗ ██║██║ ██╔████╔██║██║ ██║ ██████╔╝███████║ ██║ █████╗
██╔══╝ ██║██║ ██║╚██╔╝██║██║ ██║ ██╔══██╗██╔══██║ ██║ ██╔══╝
██║ ██║███████╗██║ ╚═╝ ██║╚██████╔╝ ██║ ██║██║ ██║ ██║ ███████╗
╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚══════╝
</pre>
""";
}
@GetMapping
public String homePage() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

вау))

return """
<p><br></p>
<pre>
███████╗██╗██╗ ███╗ ███╗ ██████╗ ██████╗ █████╗ ████████╗███████╗
██╔════╝██║██║ ████╗ ████║██╔═══██╗ ██╔══██╗██╔══██╗╚══██╔══╝██╔════╝
█████╗ ██║██║ ██╔████╔██║██║ ██║ ██████╔╝███████║ ██║ █████╗
██╔══╝ ██║██║ ██║╚██╔╝██║██║ ██║ ██╔══██╗██╔══██║ ██║ ██╔══╝
██║ ██║███████╗██║ ╚═╝ ██║╚██████╔╝ ██║ ██║██║ ██║ ██║ ███████╗
╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚══════╝
</pre>
""";
}

@GetMapping("favicon.ico")
public String faviconIco() {
return """
<p><br></p>
""";
}
@GetMapping("favicon.ico")
public String faviconIco() {
return """
<p><br></p>
""";
}

@GetMapping(".well-known/appspecific/com.chrome.devtools.json")
public String devtools() {
return """
<p><br></p>
""";
}
@GetMapping(".well-known/appspecific/com.chrome.devtools.json")
public String devtools() {
return """
<p><br></p>
""";
}

@GetMapping("sw.js")
public String swjs() {
return """
<p><br></p>
""";
}
@GetMapping("sw.js")
public String swjs() {
return """
<p><br></p>
""";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.yandex.practicum.filmorate.dto.MpaDto;
import ru.yandex.practicum.filmorate.servise.MpaServise;
import ru.yandex.practicum.filmorate.service.MpaService;

import java.util.Collection;

@RestController
@RequestMapping("/mpa")
@RestController
@RequiredArgsConstructor
public class MpaController {
private final MpaServise mpaService;
private final MpaService mpaService;

@GetMapping("/{mpaId}")
public MpaDto getMpaById(@PathVariable long mpaId) {
Expand Down
Loading