minor updates

This commit is contained in:
Dmitry Isaenko 2025-05-04 23:54:01 +03:00
parent 79a5a04488
commit 04db2d02f6
21 changed files with 104 additions and 159 deletions

View file

@ -5,7 +5,6 @@ import org.springframework.stereotype.Repository;
import ru.redrise.marinesco.library.Genre; import ru.redrise.marinesco.library.Genre;
@Repository @Repository
public interface GenreRepository extends JpaRepository<Genre, String>{ public interface GenreRepository extends JpaRepository<Genre, String>{
} }

View file

@ -6,6 +6,5 @@ import org.springframework.stereotype.Repository;
import ru.redrise.marinesco.library.LibraryMetadata; import ru.redrise.marinesco.library.LibraryMetadata;
@Repository @Repository
public interface LibraryMetadataRepository extends CrudRepository<LibraryMetadata, Long>{ public interface LibraryMetadataRepository extends CrudRepository<LibraryMetadata, Long>{
} }

View file

@ -11,5 +11,5 @@ import ru.redrise.marinesco.security.UserRole.Type;
@Repository @Repository
public interface RolesRepository extends CrudRepository<UserRole, Long>{ public interface RolesRepository extends CrudRepository<UserRole, Long>{
public List<UserRole> findByType(Type type); List<UserRole> findByType(Type type);
} }

View file

@ -7,5 +7,5 @@ import ru.redrise.marinesco.User;
@Repository @Repository
public interface UserRepository extends CrudRepository<User, Long>{ public interface UserRepository extends CrudRepository<User, Long>{
public User findByUsername(String username); User findByUsername(String username);
} }

View file

@ -8,7 +8,7 @@ import ru.redrise.marinesco.data.AuthorRepository;
@Component @Component
public class AthorByIdConverter implements Converter<Long, Author>{ public class AthorByIdConverter implements Converter<Long, Author>{
private AuthorRepository authorRepository; private final AuthorRepository authorRepository;
public AthorByIdConverter(AuthorRepository authorRepository){ public AthorByIdConverter(AuthorRepository authorRepository){
this.authorRepository = authorRepository; this.authorRepository = authorRepository;

View file

@ -8,7 +8,7 @@ import ru.redrise.marinesco.data.GenreRepository;
@Component @Component
public class GenreByIdConverter implements Converter<String, Genre>{ public class GenreByIdConverter implements Converter<String, Genre>{
private GenreRepository genreRepository; private final GenreRepository genreRepository;
public GenreByIdConverter(GenreRepository genreRepository){ public GenreByIdConverter(GenreRepository genreRepository){
this.genreRepository = genreRepository; this.genreRepository = genreRepository;

View file

@ -12,9 +12,9 @@ public class InpxLibraryMetadataScanner {
private InpxLibraryMetadataScanner() { } private InpxLibraryMetadataScanner() { }
public static LibraryMetadata saveFromFile(File inpxFile, LibraryMetadataRepository repository) throws Exception { public static LibraryMetadata saveFromFile(File inpxFile, LibraryMetadataRepository repository) throws Exception {
LibraryMetadata libraryMetadata = new LibraryMetadata(); var libraryMetadata = new LibraryMetadata();
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(inpxFile))) { try (var zipInputStream = new ZipInputStream(new FileInputStream(inpxFile))) {
ZipEntry zipEntry; ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) { while ((zipEntry = zipInputStream.getNextEntry()) != null) {
@ -37,8 +37,8 @@ public class InpxLibraryMetadataScanner {
} }
private static String readPlainText(ZipInputStream zipInputStream) throws Exception { private static String readPlainText(ZipInputStream zipInputStream) throws Exception {
byte[] content = new byte[1024]; var content = new byte[1024];
StringBuilder stringBuilder = new StringBuilder(); var stringBuilder = new StringBuilder();
while (zipInputStream.read(content) > 0) while (zipInputStream.read(content) > 0)
stringBuilder.append(new String(content, StandardCharsets.UTF_8)); stringBuilder.append(new String(content, StandardCharsets.UTF_8));

View file

@ -25,19 +25,18 @@ public class InpxScanner {
private static volatile String lastRunErrors = ""; private static volatile String lastRunErrors = "";
private final ThreadPoolTaskExecutor executor; private final ThreadPoolTaskExecutor executor;
private final String filesLocation;
private final AuthorRepository authorRepository; private final AuthorRepository authorRepository;
private final GenreRepository genreRepository; private final GenreRepository genreRepository;
private final BookRepository bookRepository; private final BookRepository bookRepository;
private final LibraryMetadataRepository libraryMetadataRepository; private final LibraryMetadataRepository libraryMetadataRepository;
private final String filesLocation;
public InpxScanner(ThreadPoolTaskExecutor executor, public InpxScanner(ThreadPoolTaskExecutor executor,
ApplicationSettings applicationSettings, ApplicationSettings applicationSettings,
AuthorRepository authorRepository, AuthorRepository authorRepository,
GenreRepository genreRepository, GenreRepository genreRepository,
BookRepository bookRepository, BookRepository bookRepository,
LibraryMetadataRepository libraryMetadataRepository) { LibraryMetadataRepository libraryMetadataRepository) {
this.executor = executor; this.executor = executor;
this.filesLocation = applicationSettings.getFilesLocation(); this.filesLocation = applicationSettings.getFilesLocation();
this.authorRepository = authorRepository; this.authorRepository = authorRepository;
@ -81,7 +80,7 @@ public class InpxScanner {
} }
private File getInpxFile() throws Exception { private File getInpxFile() throws Exception {
final FileSystemResource libraryLocation = new FileSystemResource(filesLocation); var libraryLocation = new FileSystemResource(filesLocation);
return Arrays.stream(libraryLocation.getFile().listFiles()) return Arrays.stream(libraryLocation.getFile().listFiles())
.filter(file -> file.getName().endsWith(".inpx")) .filter(file -> file.getName().endsWith(".inpx"))
.findFirst() .findFirst()
@ -89,8 +88,8 @@ public class InpxScanner {
} }
private HashMap<String, byte[]> collectInp(File inpxFile) throws Exception { private HashMap<String, byte[]> collectInp(File inpxFile) throws Exception {
final HashMap<String, byte[]> inpEntries = new HashMap<>(); var inpEntries = new HashMap<String, byte[]>();
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(inpxFile))) { try (var zipInputStream = new ZipInputStream(new FileInputStream(inpxFile))) {
ZipEntry zipEntry; ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) { while ((zipEntry = zipInputStream.getNextEntry()) != null) {
if (isInp(zipEntry)) { if (isInp(zipEntry)) {
@ -108,7 +107,7 @@ public class InpxScanner {
} }
private byte[] inpToByteArray(ZipInputStream stream, long fileSize) throws Exception { private byte[] inpToByteArray(ZipInputStream stream, long fileSize) throws Exception {
ByteBuffer inpByteBuffer = ByteBuffer.allocate((int) fileSize); var inpByteBuffer = ByteBuffer.allocate((int) fileSize);
int blockSize = 0x200; int blockSize = 0x200;
if (fileSize < 0x200) if (fileSize < 0x200)
blockSize = (int) fileSize; blockSize = (int) fileSize;
@ -147,8 +146,8 @@ public class InpxScanner {
private byte[] content; private byte[] content;
private InpxWorker(Map.Entry<String, byte[]> entry, private InpxWorker(Map.Entry<String, byte[]> entry,
Long libraryId, Long libraryId,
String libraryVersion) { String libraryVersion) {
this.libraryId = libraryId; this.libraryId = libraryId;
this.libraryVersion = libraryVersion; this.libraryVersion = libraryVersion;
this.name = entry.getKey(); this.name = entry.getKey();
@ -185,7 +184,7 @@ public class InpxScanner {
} }
saveAll(books, authors, genres); saveAll(books, authors, genres);
} catch (Exception e) { } catch (Exception e) {
log.error("{}", e); log.error(e.toString());
lastRunErrors = lastRunErrors + " " + e.getMessage(); lastRunErrors = lastRunErrors + " " + e.getMessage();
} }
} }

View file

@ -37,7 +37,7 @@ public class LibraryMetadata {
} }
public void setCollectionInfo(String content) throws Exception { public void setCollectionInfo(String content) throws Exception {
String[] lines = content.split("\n"); var lines = content.split("\n");
if (lines.length < 4) if (lines.length < 4)
throw new Exception("Invalid 'collection.info' file. It contains only "+lines.length+" lines!"); throw new Exception("Invalid 'collection.info' file. It contains only "+lines.length+" lines!");
libraryName = lines[0].trim(); libraryName = lines[0].trim();

View file

@ -15,35 +15,28 @@ import ru.redrise.marinesco.library.Author;
@RequestMapping(path = "/api/author", @RequestMapping(path = "/api/author",
produces = "application/json") produces = "application/json")
public class AuthorsApiController { public class AuthorsApiController {
private AuthorRepository authorRepository; private final AuthorRepository authorRepository;
public AuthorsApiController(AuthorRepository authorRepository){ public AuthorsApiController(AuthorRepository authorRepository){
this.authorRepository = authorRepository; this.authorRepository = authorRepository;
} }
@GetMapping @GetMapping
public Iterable<Author> getAuthors( public Iterable<Author> getAuthors(@RequestParam(value = "page", required = false, defaultValue = "0") Integer page,
@RequestParam(value = "page", required = false, defaultValue = "0") Integer page, @RequestParam(value = "sort", required = false, defaultValue = "authorName") String sortBy) {
@RequestParam(value = "sort", required = false, defaultValue = "authorName") String sortBy){ var pageRequest = PageRequest.of(page, 10, Sort.by(sortBy).descending());
PageRequest pageRequest = PageRequest.of(
page, 10, Sort.by(sortBy).descending());
return authorRepository.findAll(pageRequest).getContent(); return authorRepository.findAll(pageRequest).getContent();
} }
@GetMapping("/by/name/{name}") @GetMapping("/by/name/{name}")
public Iterable<Author> getAuthorId( public Iterable<Author> getAuthorId(@PathVariable("name") String authorName,
@PathVariable("name") String authorName, @RequestParam(value = "page", required = false, defaultValue = "0") Integer page) {
@RequestParam(value = "page", required = false, defaultValue = "0") Integer page){ var pageRequest = PageRequest.of(page, 10);
PageRequest pageRequest = PageRequest.of(page, 10);
return authorRepository.findByAuthorNameContainingIgnoreCase(authorName, pageRequest); return authorRepository.findByAuthorNameContainingIgnoreCase(authorName, pageRequest);
} }
@GetMapping("/by/id/{id}") @GetMapping("/by/id/{id}")
public Author getAuthorId(@PathVariable("id") Long authorId){ public Author getAuthorId(@PathVariable("id") Long authorId){
return authorRepository.findById(authorId).get(); return authorRepository.findById(authorId).get();
} }
} }

View file

@ -17,7 +17,7 @@ import ru.redrise.marinesco.library.Book;
@RequestMapping(path = "/api/book", @RequestMapping(path = "/api/book",
produces = "application/json") produces = "application/json")
public class BooksApiController { public class BooksApiController {
private BookRepository bookRepository ; private final BookRepository bookRepository ;
public BooksApiController(BookRepository bookRepository){ public BooksApiController(BookRepository bookRepository){
this.bookRepository = bookRepository; this.bookRepository = bookRepository;
@ -30,33 +30,23 @@ public class BooksApiController {
} }
@GetMapping(params = "page") @GetMapping(params = "page")
public Iterable<Book> getBooks( public Iterable<Book> getBooks(@RequestParam(value = "page", required = true) Integer page,
@RequestParam(value = "page", required = true) Integer page, @RequestParam(value = "sort", required = false, defaultValue = "title") String sortBy){
@RequestParam(value = "sort", required = false, defaultValue = "title") String sortBy){ var pageRequest = PageRequest.of(page, 10, Sort.by(sortBy).descending());
PageRequest pageRequest = PageRequest.of(
page, 10, Sort.by(sortBy).descending());
return bookRepository.findAll(pageRequest).getContent(); return bookRepository.findAll(pageRequest).getContent();
} }
@GetMapping("/by/title/{title}") @GetMapping("/by/title/{title}")
public Iterable<Book> getBooksByName( public Iterable<Book> getBooksByName(@PathVariable("title") String title,
@PathVariable("title") String title, @RequestParam(value = "page", required = false, defaultValue = "0") Integer page){
@RequestParam(value = "page", required = false, defaultValue = "0") Integer page){ var pageRequest = PageRequest.of(page, 10);
PageRequest pageRequest = PageRequest.of(page, 10);
return bookRepository.findByTitleContainingIgnoreCase(title, pageRequest); return bookRepository.findByTitleContainingIgnoreCase(title, pageRequest);
} }
@GetMapping("/by/series/{series}") @GetMapping("/by/series/{series}")
public Iterable<Book> getBooksBySeries( public Iterable<Book> getBooksBySeries(@PathVariable("series") String series,
@PathVariable("series") String series, @RequestParam(value = "page", required = false, defaultValue = "0") Integer page){
@RequestParam(value = "page", required = false, defaultValue = "0") Integer page){ var pageRequest = PageRequest.of(page, 10);
PageRequest pageRequest = PageRequest.of(page, 10);
return bookRepository.findBySeriesContainingIgnoreCase(series, pageRequest); return bookRepository.findBySeriesContainingIgnoreCase(series, pageRequest);
} }

View file

@ -24,18 +24,16 @@ import ru.redrise.marinesco.library.Genre;
@RestController @RestController
@RequestMapping(path = "/api/genres", produces = "application/json") @RequestMapping(path = "/api/genres", produces = "application/json")
public class GenresApiController { public class GenresApiController {
private GenreRepository genreRepository; private final GenreRepository genreRepository;
public GenresApiController(GenreRepository genreRepository) { public GenresApiController(GenreRepository genreRepository) {
this.genreRepository = genreRepository; this.genreRepository = genreRepository;
} }
@GetMapping @GetMapping
public Iterable<Genre> getGenres( public Iterable<Genre> getGenres(@RequestParam(value = "page", required = false, defaultValue = "0") Integer page,
@RequestParam(value = "page", required = false, defaultValue = "0") Integer page, @RequestParam(value = "sort", required = false, defaultValue = "genreId") String sortBy) {
@RequestParam(value = "sort", required = false, defaultValue = "genreId") String sortBy) { var pageRequest = PageRequest.of(page, 10, Sort.by(sortBy).descending());
PageRequest pageRequest = PageRequest.of(page, 10, Sort.by(sortBy).descending());
return genreRepository.findAll(pageRequest).getContent(); return genreRepository.findAll(pageRequest).getContent();
} }
@ -53,8 +51,8 @@ public class GenresApiController {
@PutMapping(path = "/{genreId}", consumes = "application/json") @PutMapping(path = "/{genreId}", consumes = "application/json")
public Genre putGenre(@PathVariable("genreId") String genreId, public Genre putGenre(@PathVariable("genreId") String genreId,
@RequestBody Genre genre){ @RequestBody Genre genre){
genre.setGenreId(genreId); genre.setGenreId(genreId);
return genreRepository.save(genre); return genreRepository.save(genre);
} }

View file

@ -1,13 +1,10 @@
package ru.redrise.marinesco.library.settings; package ru.redrise.marinesco.library.settings;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -21,7 +18,6 @@ import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import ru.redrise.marinesco.data.GenreRepository; import ru.redrise.marinesco.data.GenreRepository;
import ru.redrise.marinesco.library.Genre; import ru.redrise.marinesco.library.Genre;
import org.springframework.web.bind.annotation.RequestBody;
@Slf4j @Slf4j
@ -30,7 +26,7 @@ import org.springframework.web.bind.annotation.RequestBody;
@PreAuthorize("hasRole('ADMIN')") @PreAuthorize("hasRole('ADMIN')")
public class GenreSettingsController { public class GenreSettingsController {
private GenreRepository genreRepository; private final GenreRepository genreRepository;
public GenreSettingsController(GenreRepository genreRepository) { public GenreSettingsController(GenreRepository genreRepository) {
this.genreRepository = genreRepository; this.genreRepository = genreRepository;
@ -45,9 +41,8 @@ public class GenreSettingsController {
public GenresHolder setRegistrationSetting() { public GenresHolder setRegistrationSetting() {
List<Genre> genres = new ArrayList<>(); List<Genre> genres = new ArrayList<>();
genreRepository.findAll() genreRepository.findAll().iterator()
.iterator() .forEachRemaining(genres::add);
.forEachRemaining(genres::add);
return new GenresHolder(genres); return new GenresHolder(genres);
} }
@ -65,14 +60,10 @@ public class GenreSettingsController {
} }
@PostMapping("/upload") @PostMapping("/upload")
public String postMethodName(@RequestParam("file") MultipartFile file, public String postUpload(@RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) { RedirectAttributes redirectAttributes) {
var message = GenresUpload.upload(file, genreRepository);
final String message = GenresUpload.upload(file.getResource(), file.getSize(), genreRepository);
redirectAttributes.addFlashAttribute("message", message); redirectAttributes.addFlashAttribute("message", message);
return "redirect:/settings/genres"; return "redirect:/settings/genres";
} }
} }

View file

@ -3,24 +3,20 @@ package ru.redrise.marinesco.library.settings;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import org.springframework.core.io.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import ru.redrise.marinesco.data.GenreRepository; import ru.redrise.marinesco.data.GenreRepository;
import ru.redrise.marinesco.library.Genre; import ru.redrise.marinesco.library.Genre;
@Slf4j @Slf4j
public class GenresUpload { public class GenresUpload {
public static String upload(Resource resource, long fileSize, GenreRepository repository) { public static String upload(MultipartFile file, GenreRepository repository) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()))){ try (var reader = new BufferedReader(new InputStreamReader(file.getInputStream()))){
if (fileSize == 0)
throw new Exception("empty file");
String line; String line;
List<Genre> genres = new ArrayList<>(); var genres = new ArrayList<Genre>();
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
String[] arr = line.split(":::"); String[] arr = line.split(":::");
@ -36,6 +32,6 @@ public class GenresUpload {
return "Upload failed: " + e.getMessage(); return "Upload failed: " + e.getMessage();
} }
return "Successfully uploaded: " + resource.getFilename(); return "Successfully uploaded: " + file.getResource().getFilename();
} }
} }

View file

@ -1,8 +1,6 @@
package ru.redrise.marinesco.library.web; package ru.redrise.marinesco.library.web;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@ -11,7 +9,6 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import ru.redrise.marinesco.data.AuthorRepository; import ru.redrise.marinesco.data.AuthorRepository;
import ru.redrise.marinesco.library.Author;
import ru.redrise.marinesco.library.Book; import ru.redrise.marinesco.library.Book;
@Controller @Controller
@ -25,15 +22,14 @@ public class AuthorController {
@GetMapping("/{authorId}") @GetMapping("/{authorId}")
public String getPage(@PathVariable("authorId") Long authorId, Model model) { public String getPage(@PathVariable("authorId") Long authorId, Model model) {
final Author author = authorRepository.findById(authorId).orElse(null); var author = authorRepository.findById(authorId).orElse(null);
if (author == null){ if (author == null){
model.addAttribute("Error", "Not found"); model.addAttribute("Error", "Not found");
return "author"; return "author";
} }
List<Book> books = author.getBooks(); var books = author.getBooks();
books.sort(Comparator.comparing(Book::getSeries)); books.sort(Comparator.comparing(Book::getSeries));
model.addAttribute("author", author) model.addAttribute("author", author)

View file

@ -20,7 +20,8 @@ public class BookController {
@GetMapping("/{bookId}") @GetMapping("/{bookId}")
public String getPage(@PathVariable("bookId") Integer bookId, Model model) { public String getPage(@PathVariable("bookId") Integer bookId, Model model) {
Book book = bookRepository.findById(bookId).orElse(null); var book = bookRepository.findById(bookId).orElse(null);
if (book == null){ if (book == null){
model.addAttribute("Error", "Not found"); model.addAttribute("Error", "Not found");
return "book"; return "book";

View file

@ -31,23 +31,24 @@ public class DownloadController {
@GetMapping(value = "/") @GetMapping(value = "/")
public void getMethodName(@RequestParam String container, public void getMethodName(@RequestParam String container,
@RequestParam String file, @RequestParam String file,
HttpServletResponse response) throws Exception { HttpServletResponse response) throws Exception {
try {
File bookFile = new File(filesLocation + File.separator + container + File.separator + file);
if (! bookFile.exists())
throw new Exception("No file found :[");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
ContentDisposition.attachment()
.filename(file, StandardCharsets.UTF_8) // TODO: fix
.build()
.toString());
try (ServletOutputStream outStream = response.getOutputStream(); var bookFile = new File(filesLocation + File.separator + container + File.separator + file);
FileInputStream inputStream = new FileInputStream(bookFile)) {
IOUtils.copy(inputStream, outStream); if (! bookFile.exists())
} throw new Exception("No file found :[");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
ContentDisposition.attachment()
.filename(file, StandardCharsets.UTF_8) // TODO: fix
.build()
.toString());
try (var outStream = response.getOutputStream();
var inputStream = new FileInputStream(bookFile)) {
IOUtils.copy(inputStream, outStream);
} catch (Exception e) { } catch (Exception e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Book not found [" + e.getMessage() + "]"); throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Book not found [" + e.getMessage() + "]");
} }

View file

@ -1,7 +1,5 @@
package ru.redrise.marinesco.library.web; package ru.redrise.marinesco.library.web;
import java.util.List;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@ -11,61 +9,45 @@ import org.springframework.web.bind.annotation.RequestParam;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import ru.redrise.marinesco.data.AuthorRepository; import ru.redrise.marinesco.data.AuthorRepository;
import ru.redrise.marinesco.data.BookRepository; import ru.redrise.marinesco.data.BookRepository;
import ru.redrise.marinesco.library.Author;
import ru.redrise.marinesco.library.Book;
@Slf4j @Slf4j
@Controller @Controller
@RequestMapping("/search") @RequestMapping("/search")
public class SearchController { public class SearchController {
private final BookRepository inpEntryRepository; private final BookRepository booksRepository;
private final AuthorRepository authorRepository; private final AuthorRepository authorRepository;
public SearchController(BookRepository bookRepository, AuthorRepository authorRepository){ public SearchController(BookRepository bookRepository, AuthorRepository authorRepository){
this.inpEntryRepository = bookRepository; this.booksRepository = bookRepository;
this.authorRepository = authorRepository; this.authorRepository = authorRepository;
} }
@GetMapping @GetMapping
public String requestMethodName(@RequestParam String search, public String requestMethodName(@RequestParam String search,
@RequestParam(value = "title", required = false) Boolean title, @RequestParam(value = "title", required = false) Boolean title,
@RequestParam(value = "series", required = false) Boolean series, @RequestParam(value = "series", required = false) Boolean series,
@RequestParam(value = "author", required = false) Boolean author, @RequestParam(value = "author", required = false) Boolean author,
Model model) { Model model) {
model.addAttribute("searchPattern", search)
.addAttribute("isTitle", title)
.addAttribute("isSeries", series)
.addAttribute("isAuthor", author);
if (search.trim().isEmpty()) if (search.isBlank() || search.length() < 4){
return "search";
model.addAttribute("searchPattern", search);
if (search.length() < 4){
model.addAttribute("error", "Should be at least 4 chars"); model.addAttribute("error", "Should be at least 4 chars");
return "search"; return "search";
} }
if (title != null){ if (title != null && title)
List<Book> books = inpEntryRepository.findByTitleContainingIgnoreCase(search); model.addAttribute("books", booksRepository.findByTitleContainingIgnoreCase(search));
if (!books.isEmpty())
model.addAttribute("books", books); if (series != null && series)
model.addAttribute("isTitle", true); model.addAttribute("series", booksRepository.findBySeriesContainingIgnoreCase(search));
}
if (author != null && author)
if (series != null){ model.addAttribute("authors", authorRepository.findByAuthorNameContainingIgnoreCase(search));
List<Book> bookSeries = inpEntryRepository.findBySeriesContainingIgnoreCase(search);
if (!bookSeries.isEmpty())
model.addAttribute("series", bookSeries);
model.addAttribute("isSeries", true);
}
if (author != null){
List<Author> authors = authorRepository.findByAuthorNameContainingIgnoreCase(search);
if (!authors.isEmpty())
model.addAttribute("authors", authors);
model.addAttribute("isAuthor", true);
}
return "search"; return "search";
} }
} }

View file

@ -12,7 +12,7 @@ import ru.redrise.marinesco.User;
//TODO: refactor along with RegistrationForm.java //TODO: refactor along with RegistrationForm.java
@Data @Data
public class AdministatorAddUserForm { public class AdministratorAddUserForm {
@NotNull @NotNull
@Size(min=3, max=32, message="Username must be at least 3 characters long. Should not exceed 32 characters.") @Size(min=3, max=32, message="Username must be at least 3 characters long. Should not exceed 32 characters.")

View file

@ -47,7 +47,7 @@ public class ManageUsersController {
@ModelAttribute @ModelAttribute
public void addTitle(Model model) { public void addTitle(Model model) {
model.addAttribute("header_text", "Manage users"); model.addAttribute("header_text", "Manage users");
model.addAttribute("administatorAddUserForm", new AdministatorAddUserForm()); model.addAttribute("administratorAddUserForm", new AdministratorAddUserForm());
} }
@ModelAttribute @ModelAttribute
@ -103,7 +103,7 @@ public class ManageUsersController {
} }
@PostMapping @PostMapping
public String processNewUser(@Valid AdministatorAddUserForm form, Errors errors, Model model) { public String processNewUser(@Valid AdministratorAddUserForm form, Errors errors, Model model) {
if (userRepository.findByUsername(form.getUsername()) != null) { if (userRepository.findByUsername(form.getUsername()) != null) {
model.addAttribute("loginOccupied", "Login already in use. Please choose another one"); model.addAttribute("loginOccupied", "Login already in use. Please choose another one");
return "manage_users"; return "manage_users";

View file

@ -44,7 +44,7 @@
</div> </div>
<hr> <hr>
<b>Add user</b> <b>Add user</b>
<form method="POST" th:action="@{/settings/manage_users}" th:object="${administatorAddUserForm}"> <form method="POST" th:action="@{/settings/manage_users}" th:object="${administratorAddUserForm}">
<span class="validationError" th:if="${loginOccupied} != null" th:text="${loginOccupied}">pew</span> <span class="validationError" th:if="${loginOccupied} != null" th:text="${loginOccupied}">pew</span>
<span class="validationError" th:if="${#fields.hasErrors('username')}" <span class="validationError" th:if="${#fields.hasErrors('username')}"
th:errors="*{username}">Error</span> th:errors="*{username}">Error</span>