From 3041ea9aa72db4ccc74ec8f518ab5ab203f6f922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Thu, 25 Jul 2024 12:02:15 +0200 Subject: [PATCH] Blacklist --- .../kleinanzeigen/KleinanzeigenApi.java | 15 +++++- .../kleinanzeigen/blacklist/Blacklist.java | 52 +++++++++++++++++++ .../blacklist/BlacklistController.java | 26 ++++++++++ .../blacklist/BlacklistCreate.java | 19 +++++++ .../kleinanzeigen/blacklist/BlacklistDto.java | 22 ++++++++ .../blacklist/BlacklistRepository.java | 11 ++++ .../blacklist/BlacklistService.java | 43 +++++++++++++++ .../kleinanzeigen/search/SearchService.java | 18 ------- 8 files changed, 186 insertions(+), 20 deletions(-) create mode 100644 src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/Blacklist.java create mode 100644 src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistController.java create mode 100644 src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistCreate.java create mode 100644 src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistDto.java create mode 100644 src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistRepository.java create mode 100644 src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistService.java diff --git a/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/KleinanzeigenApi.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/KleinanzeigenApi.java index db0ccac..8c3d462 100644 --- a/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/KleinanzeigenApi.java +++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/KleinanzeigenApi.java @@ -1,5 +1,7 @@ package de.ph87.kleinanzeigen.kleinanzeigen; +import de.ph87.kleinanzeigen.kleinanzeigen.blacklist.BlacklistDto; +import de.ph87.kleinanzeigen.kleinanzeigen.blacklist.BlacklistService; import de.ph87.kleinanzeigen.kleinanzeigen.offer.LocationNotFound; import de.ph87.kleinanzeigen.kleinanzeigen.offer.OfferCreate; import de.ph87.kleinanzeigen.kleinanzeigen.offer.OfferService; @@ -17,6 +19,7 @@ import org.springframework.stereotype.Service; import java.io.IOException; import java.net.URI; import java.time.DateTimeException; +import java.util.List; import java.util.concurrent.TimeUnit; @Slf4j @@ -35,6 +38,8 @@ public class KleinanzeigenApi { private final KleinanzeigenConfig config; + private final BlacklistService blacklistService; + @Scheduled(initialDelay = 0, fixedRate = 1, timeUnit = TimeUnit.MINUTES) public void fetch() { fetch(VERSCHENKEN_EPPELBORN_RADIUS.formatted(config.getRadiusKm()), config.getRadiusKm()); @@ -65,9 +70,15 @@ public class KleinanzeigenApi { private void tryParse(final Element article, final URI uri, final int radius) { try { final OfferCreate create = new OfferCreate(article, uri); - if (create.getDistance() <= radius) { - offerService.updateOrCreate(create); + if (create.getDistance() > radius) { + return; } + final List blacklist = blacklistService.findAllBlacklisted(create.getTitle()); + if (!blacklist.isEmpty()) { + log.info("Offer is blacklisted due to: blacklists={}, offer={}", blacklist.stream().map(BlacklistDto::getQuery).toList(), create); + return; + } + offerService.updateOrCreate(create); } catch (NumberFormatException | DateTimeException | LocationNotFound e) { log.error("Failed to parse Offer:\n{}\n", article.outerHtml(), e); } diff --git a/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/Blacklist.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/Blacklist.java new file mode 100644 index 0000000..a1d84f9 --- /dev/null +++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/Blacklist.java @@ -0,0 +1,52 @@ +package de.ph87.kleinanzeigen.kleinanzeigen.blacklist; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.ToString; + +import java.util.Arrays; +import java.util.Locale; + +@Entity +@Getter +@ToString +@NoArgsConstructor +public class Blacklist { + + @Id + @GeneratedValue + private long id; + + @Column(nullable = false) + private boolean enabled; + + @NonNull + @Column(nullable = false) + private String query; + + public Blacklist(final BlacklistCreate create) { + enabled = create.isEnabled(); + query = create.getQuery(); + } + + public void edit(final BlacklistDto edit) { + enabled = edit.isEnabled(); + query = edit.getQuery(); + } + + public boolean matches(@NonNull final String title) { + final String[] words = query.replaceAll("([0-9])([a-zA-Z])", "$1 $2") + .replaceAll("([a-zA-Z])([0-9])", "$1 $2") + .replaceAll("([a-z])([A-Z])", "$1 $2") + .replaceAll("^\\W+|\\W+$", "") + .toLowerCase(Locale.ROOT) + .split("\\W+"); + return Arrays.stream(words).map(".*%s.*"::formatted).allMatch(title::matches); + } + +} diff --git a/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistController.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistController.java new file mode 100644 index 0000000..5102bd7 --- /dev/null +++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistController.java @@ -0,0 +1,26 @@ +package de.ph87.kleinanzeigen.kleinanzeigen.blacklist; + +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("Kleinanzeigen/Blacklist") +public class BlacklistController { + + private final BlacklistService blacklistService; + + @PostMapping("create") + public BlacklistDto create(@RequestBody BlacklistCreate create) { + return blacklistService.create(create); + } + + @PostMapping("edit") + public BlacklistDto edit(@RequestBody BlacklistDto edit) { + return blacklistService.edit(edit); + } + +} diff --git a/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistCreate.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistCreate.java new file mode 100644 index 0000000..b130e2c --- /dev/null +++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistCreate.java @@ -0,0 +1,19 @@ +package de.ph87.kleinanzeigen.kleinanzeigen.blacklist; + +import lombok.Data; +import lombok.NonNull; + +@Data +public class BlacklistCreate { + + private final boolean enabled; + + @NonNull + private final String query; + + public BlacklistCreate(final boolean enabled, @NonNull final String query) { + this.enabled = enabled; + this.query = query; + } + +} diff --git a/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistDto.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistDto.java new file mode 100644 index 0000000..11def9e --- /dev/null +++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistDto.java @@ -0,0 +1,22 @@ +package de.ph87.kleinanzeigen.kleinanzeigen.blacklist; + +import lombok.Data; +import lombok.NonNull; + +@Data +public class BlacklistDto { + + private final long id; + + private final boolean enabled; + + @NonNull + private final String query; + + public BlacklistDto(final Blacklist blacklist) { + this.id = blacklist.getId(); + this.enabled = blacklist.isEnabled(); + this.query = blacklist.getQuery(); + } + +} diff --git a/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistRepository.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistRepository.java new file mode 100644 index 0000000..523721d --- /dev/null +++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistRepository.java @@ -0,0 +1,11 @@ +package de.ph87.kleinanzeigen.kleinanzeigen.blacklist; + +import org.springframework.data.repository.ListCrudRepository; + +import java.util.List; + +public interface BlacklistRepository extends ListCrudRepository { + + List findAllByEnabledTrue(); + +} diff --git a/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistService.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistService.java new file mode 100644 index 0000000..c50d304 --- /dev/null +++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/blacklist/BlacklistService.java @@ -0,0 +1,43 @@ +package de.ph87.kleinanzeigen.kleinanzeigen.blacklist; + +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.server.ResponseStatusException; + +import java.util.List; + +@Slf4j +@Service +@Transactional +@RequiredArgsConstructor +public class BlacklistService { + + private final BlacklistRepository blacklistRepository; + + private BlacklistDto toDto(Blacklist blacklist) { + return new BlacklistDto(blacklist); + } + + public BlacklistDto create(final BlacklistCreate create) { + final BlacklistDto dto = toDto(blacklistRepository.save(new Blacklist(create))); + log.info("Blacklist CREATED: {}", dto); + return dto; + } + + public BlacklistDto edit(final BlacklistDto edit) { + final Blacklist blacklist = blacklistRepository.findById(edit.getId()).orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST)); + blacklist.edit(edit); + final BlacklistDto dto = toDto(blacklist); + log.info("Blacklist EDITED: {}", dto); + return dto; + } + + public List findAllBlacklisted(@NonNull final String title) { + return blacklistRepository.findAllByEnabledTrue().stream().filter(blacklist -> blacklist.matches(title)).map(BlacklistDto::new).toList(); + } + +} diff --git a/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/search/SearchService.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/search/SearchService.java index 8da1496..cd50dcc 100644 --- a/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/search/SearchService.java +++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/search/SearchService.java @@ -1,7 +1,5 @@ package de.ph87.kleinanzeigen.kleinanzeigen.search; -import de.ph87.kleinanzeigen.kleinanzeigen.KleinanzeigenConfig; -import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -19,22 +17,6 @@ public class SearchService { private final SearchRepository searchRepository; - private final KleinanzeigenConfig kleinanzeigenConfig; - - @PostConstruct - public void init() { - if (kleinanzeigenConfig.isDemo()) { - if (searchRepository.count() == 0) { - demoCreate("Garten Bank"); - demoCreate("Teich Pumpe"); - } - } - } - - private void demoCreate(final String Garten_Bank) { - searchRepository.save(new Search(new SearchCreate(true, Garten_Bank, 15, 0, 30))); - } - public List findAllEnabledDto() { return searchRepository.findAllByEnabledTrue().stream().map(this::toDto).toList(); }