diff --git a/pom.xml b/pom.xml
index cde3e13..dd7d1c2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -67,7 +67,7 @@
- de.ph87.kleinanzeigen.api.Main
+ de.ph87.kleinanzeigen.Main
diff --git a/src/main/java/de/ph87/kleinanzeigen/api/JSON.java b/src/main/java/de/ph87/kleinanzeigen/JSON.java
similarity index 83%
rename from src/main/java/de/ph87/kleinanzeigen/api/JSON.java
rename to src/main/java/de/ph87/kleinanzeigen/JSON.java
index b98caac..fa21ce5 100644
--- a/src/main/java/de/ph87/kleinanzeigen/api/JSON.java
+++ b/src/main/java/de/ph87/kleinanzeigen/JSON.java
@@ -1,4 +1,4 @@
-package de.ph87.kleinanzeigen.api;
+package de.ph87.kleinanzeigen;
import com.fasterxml.jackson.databind.ObjectMapper;
diff --git a/src/main/java/de/ph87/kleinanzeigen/Main.java b/src/main/java/de/ph87/kleinanzeigen/Main.java
new file mode 100644
index 0000000..282a983
--- /dev/null
+++ b/src/main/java/de/ph87/kleinanzeigen/Main.java
@@ -0,0 +1,48 @@
+package de.ph87.kleinanzeigen;
+
+import de.ph87.kleinanzeigen.kleinanzeigen.KleinanzeigenApi;
+import de.ph87.kleinanzeigen.kleinanzeigen.offer.OfferRepository;
+import de.ph87.kleinanzeigen.telegram.TelegramBot;
+import lombok.extern.slf4j.Slf4j;
+import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
+
+import java.io.IOException;
+import java.util.List;
+
+@Slf4j
+@SuppressWarnings({"InfiniteLoopStatement", "SameParameterValue", "SynchronizationOnLocalVariableOrMethodParameter"})
+public class Main {
+
+ private static TelegramBot telegramBot;
+
+ private static final OfferRepository offerRepository = new OfferRepository(offer -> telegramBot.remove(List.of(offer)));
+
+ private static final KleinanzeigenApi kleinanzeigenApi = new KleinanzeigenApi(offerRepository);
+
+ public static void main(String[] args) throws IOException, TelegramApiException {
+ telegramBot = new TelegramBot(offerRepository);
+ try {
+ while (true) {
+ handle(telegramBot);
+ waitSeconds(60);
+ }
+ } catch (InterruptedException e) {
+ log.warn(e.toString());
+ } finally {
+ telegramBot.stop();
+ }
+ }
+
+ private static void handle(final TelegramBot telegramBot) {
+ kleinanzeigenApi.fetchUntilDuplicate(5);
+ offerRepository.findAll().stream().filter(offer -> offer.getTelegramMessageId() == null).forEach(telegramBot::send);
+ }
+
+ private static void waitSeconds(final long seconds) throws InterruptedException {
+ final Object lock = new Object();
+ synchronized (lock) {
+ lock.wait(seconds * 1000);
+ }
+ }
+
+}
diff --git a/src/main/java/de/ph87/kleinanzeigen/api/Main.java b/src/main/java/de/ph87/kleinanzeigen/api/Main.java
deleted file mode 100644
index d7f14d9..0000000
--- a/src/main/java/de/ph87/kleinanzeigen/api/Main.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package de.ph87.kleinanzeigen.api;
-
-import lombok.extern.slf4j.Slf4j;
-import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
-
-import java.io.IOException;
-import java.util.List;
-
-@Slf4j
-@SuppressWarnings({"InfiniteLoopStatement", "SameParameterValue", "SynchronizationOnLocalVariableOrMethodParameter"})
-public class Main {
-
- private static Bot bot;
-
- private static final Kleinanzeigen kleinanzeigen = new Kleinanzeigen(offer -> bot.remove(List.of(offer)));
-
- public static void main(String[] args) throws IOException, TelegramApiException {
- bot = new Bot(kleinanzeigen::ignore, kleinanzeigen::findByTelegramMessageId, kleinanzeigen::remember);
- try {
- while (true) {
- handle(bot);
- waitSeconds(60);
- }
- } catch (InterruptedException e) {
- log.warn(e.toString());
- } finally {
- bot.stop();
- }
- }
-
- private static void handle(final Bot bot) {
- kleinanzeigen.fetchUntilDuplicate(5);
- kleinanzeigen.findAll().stream().filter(offer -> offer.getTelegramMessageId() == null).forEach(bot::send);
- }
-
- private static void waitSeconds(final long seconds) throws InterruptedException {
- final Object lock = new Object();
- synchronized (lock) {
- lock.wait(seconds * 1000);
- }
- }
-
-}
diff --git a/src/main/java/de/ph87/kleinanzeigen/api/FetchResult.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/FetchResult.java
similarity index 91%
rename from src/main/java/de/ph87/kleinanzeigen/api/FetchResult.java
rename to src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/FetchResult.java
index 35adff1..4d5bb43 100644
--- a/src/main/java/de/ph87/kleinanzeigen/api/FetchResult.java
+++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/FetchResult.java
@@ -1,4 +1,4 @@
-package de.ph87.kleinanzeigen.api;
+package de.ph87.kleinanzeigen.kleinanzeigen;
import lombok.Data;
diff --git a/src/main/java/de/ph87/kleinanzeigen/api/Kleinanzeigen.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/KleinanzeigenApi.java
similarity index 56%
rename from src/main/java/de/ph87/kleinanzeigen/api/Kleinanzeigen.java
rename to src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/KleinanzeigenApi.java
index 32eed6b..fed1edd 100644
--- a/src/main/java/de/ph87/kleinanzeigen/api/Kleinanzeigen.java
+++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/KleinanzeigenApi.java
@@ -1,86 +1,32 @@
-package de.ph87.kleinanzeigen.api;
+package de.ph87.kleinanzeigen.kleinanzeigen;
+import de.ph87.kleinanzeigen.kleinanzeigen.offer.Offer;
+import de.ph87.kleinanzeigen.kleinanzeigen.offer.OfferParseException;
+import de.ph87.kleinanzeigen.kleinanzeigen.offer.OfferRepository;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
-import org.telegram.telegrambots.meta.api.objects.MaybeInaccessibleMessage;
-import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZonedDateTime;
-import java.util.*;
-import java.util.function.Consumer;
+import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import static de.ph87.kleinanzeigen.api.JSON.objectMapper;
-
@Slf4j
-public class Kleinanzeigen {
-
- private static final int KEEP_LAST_OFFERS_COUNT = 200;
-
- private static final File FILE = new File("./offers.json");
+public class KleinanzeigenApi {
private static final String VERSCHENKEN_EPPELBORN_30KM = "https://www.kleinanzeigen.de/s-zu-verschenken/66571/seite:%d/c192l339r30";
- private final List offers;
+ private final OfferRepository offerRepository;
- private final Consumer remove;
-
- public Kleinanzeigen(final Consumer remove) {
- this.remove = remove;
- offers = load();
- }
-
- private List load() {
- try {
- final List offers = objectMapper.readerForListOf(Offer.class).readValue(FILE);
- log.info("Loaded {} offers from file: {}", offers.size(), FILE);
- return offers;
- } catch (IOException e) {
- log.warn("Failed to load Offers from file={}: {}", FILE, e.toString());
- return new ArrayList<>();
- }
- }
-
- private void save() {
- try {
- final List removed;
- synchronized (offers) {
- removed = _cleanUp();
- objectMapper.writerWithDefaultPrettyPrinter().writeValue(FILE, offers);
- log.debug("Wrote {} offers to file: {}", offers.size(), FILE);
- }
- removed.forEach(remove);
- } catch (IOException e) {
- log.warn("Failed to write Offers to file={}: {}", FILE, e.toString());
- }
- }
-
- private List _cleanUp() {
- if (offers.stream().anyMatch(Offer::_deleted_)) {
- throw new RuntimeException();
- }
-
- offers.sort(Comparator.comparing(Offer::getDate));
-
- final ZonedDateTime now = ZonedDateTime.now();
- final List deleted = new ArrayList<>();
- final List removable = new ArrayList<>(offers.stream().filter(offer -> !offer.isRemember() && (offer.getRememberUntil() == null || now.isAfter(offer.getRememberUntil()))).toList());
- while (!removable.isEmpty() && removable.size() > Kleinanzeigen.KEEP_LAST_OFFERS_COUNT) {
- final Offer offer = removable.removeFirst();
- offers.remove(offer);
- offer.markDeleted();
- deleted.add(offer);
- }
-
- return deleted;
+ public KleinanzeigenApi(final OfferRepository offerRepository) {
+ this.offerRepository = offerRepository;
}
public void fetchUntilDuplicate(final int maxPageCount) {
@@ -108,10 +54,10 @@ public class Kleinanzeigen {
fetchResult.add(MergeResult.ERROR);
continue;
}
- final MergeResult mergeResult = merge(offer);
+ final MergeResult mergeResult = offerRepository.save(offer);
fetchResult.add(mergeResult);
}
- save();
+ offerRepository.flush();
} catch (IOException e) {
log.error("Failed to fetch Kleinanzeigen: {}", e.toString());
}
@@ -165,20 +111,6 @@ public class Kleinanzeigen {
return "";
}
- private MergeResult merge(final Offer offer) {
- synchronized (offer) {
- final Optional existingOptional = offers.stream().filter(existing -> existing.getId().equals(offer.getId())).findFirst();
- if (existingOptional.isPresent()) {
- existingOptional.get().merge(offer);
- return MergeResult.UPDATED;
- } else {
- log.info("Created: {}", offer);
- offers.add(offer);
- return MergeResult.CREATED;
- }
- }
- }
-
private ZonedDateTime parseDate(final String text) {
final Matcher dayNameMatcher = Pattern.compile("(?Gestern|Heute), (?\\d+):(?\\d+)").matcher(text);
if (dayNameMatcher.find()) {
@@ -193,36 +125,4 @@ public class Kleinanzeigen {
throw new NumberFormatException("Failed to parse date: " + text);
}
- public List findAll() {
- synchronized (offers) {
- return new ArrayList<>(offers);
- }
- }
-
- public void ignore(final MaybeInaccessibleMessage message) {
- synchronized (offers) {
- findByTelegramMessageId(message).ifPresent(offer -> {
- offer.ignore();
- save();
- });
- }
- }
-
- public Optional remember(final MaybeInaccessibleMessage message, final boolean remember) {
- synchronized (offers) {
- final Optional optional = findByTelegramMessageId(message);
- optional.ifPresent(offer -> {
- offer.setRemember(remember);
- save();
- });
- return optional;
- }
- }
-
- public Optional findByTelegramMessageId(final MaybeInaccessibleMessage message) {
- synchronized (offers) {
- return offers.stream().filter(offer -> Objects.equals(offer.getTelegramMessageId(), message.getMessageId())).findFirst();
- }
- }
-
}
diff --git a/src/main/java/de/ph87/kleinanzeigen/api/MergeResult.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/MergeResult.java
similarity index 55%
rename from src/main/java/de/ph87/kleinanzeigen/api/MergeResult.java
rename to src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/MergeResult.java
index b1ce9fe..57aac4c 100644
--- a/src/main/java/de/ph87/kleinanzeigen/api/MergeResult.java
+++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/MergeResult.java
@@ -1,4 +1,4 @@
-package de.ph87.kleinanzeigen.api;
+package de.ph87.kleinanzeigen.kleinanzeigen;
public enum MergeResult {
CREATED, UPDATED, ERROR
diff --git a/src/main/java/de/ph87/kleinanzeigen/api/Offer.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/offer/Offer.java
similarity index 98%
rename from src/main/java/de/ph87/kleinanzeigen/api/Offer.java
rename to src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/offer/Offer.java
index 097a13c..dae6b71 100644
--- a/src/main/java/de/ph87/kleinanzeigen/api/Offer.java
+++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/offer/Offer.java
@@ -1,4 +1,4 @@
-package de.ph87.kleinanzeigen.api;
+package de.ph87.kleinanzeigen.kleinanzeigen.offer;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
diff --git a/src/main/java/de/ph87/kleinanzeigen/api/OfferParseException.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/offer/OfferParseException.java
similarity index 80%
rename from src/main/java/de/ph87/kleinanzeigen/api/OfferParseException.java
rename to src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/offer/OfferParseException.java
index c0db26b..8d7494a 100644
--- a/src/main/java/de/ph87/kleinanzeigen/api/OfferParseException.java
+++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/offer/OfferParseException.java
@@ -1,4 +1,4 @@
-package de.ph87.kleinanzeigen.api;
+package de.ph87.kleinanzeigen.kleinanzeigen.offer;
import org.jsoup.nodes.Element;
diff --git a/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/offer/OfferRepository.java b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/offer/OfferRepository.java
new file mode 100644
index 0000000..b19cbb0
--- /dev/null
+++ b/src/main/java/de/ph87/kleinanzeigen/kleinanzeigen/offer/OfferRepository.java
@@ -0,0 +1,122 @@
+package de.ph87.kleinanzeigen.kleinanzeigen.offer;
+
+import de.ph87.kleinanzeigen.kleinanzeigen.MergeResult;
+import lombok.extern.slf4j.Slf4j;
+import org.telegram.telegrambots.meta.api.objects.MaybeInaccessibleMessage;
+
+import java.io.File;
+import java.io.IOException;
+import java.time.ZonedDateTime;
+import java.util.*;
+import java.util.function.Consumer;
+
+import static de.ph87.kleinanzeigen.JSON.objectMapper;
+
+@Slf4j
+public class OfferRepository {
+
+ private static final int KEEP_LAST_OFFERS_COUNT = 200;
+
+ private static final File FILE = new File("./offers.json");
+
+ private final List offers;
+
+ private final Consumer remove;
+
+ public OfferRepository(final Consumer remove) {
+ this.remove = remove;
+ offers = load();
+ }
+
+ private List load() {
+ try {
+ final List offers = objectMapper.readerForListOf(Offer.class).readValue(FILE);
+ log.info("Loaded {} offers from file: {}", offers.size(), FILE);
+ return offers;
+ } catch (IOException e) {
+ log.warn("Failed to load Offers from file={}: {}", FILE, e.toString());
+ return new ArrayList<>();
+ }
+ }
+
+ public void flush() {
+ try {
+ final List removed;
+ synchronized (offers) {
+ removed = _cleanUp();
+ objectMapper.writerWithDefaultPrettyPrinter().writeValue(FILE, offers);
+ log.debug("Wrote {} offers to file: {}", offers.size(), FILE);
+ }
+ removed.forEach(remove);
+ } catch (IOException e) {
+ log.warn("Failed to write Offers to file={}: {}", FILE, e.toString());
+ }
+ }
+
+ private List _cleanUp() {
+ if (offers.stream().anyMatch(Offer::_deleted_)) {
+ throw new RuntimeException();
+ }
+
+ offers.sort(Comparator.comparing(Offer::getDate));
+
+ final ZonedDateTime now = ZonedDateTime.now();
+ final List deleted = new ArrayList<>();
+ final List removable = new ArrayList<>(offers.stream().filter(offer -> !offer.isRemember() && (offer.getRememberUntil() == null || now.isAfter(offer.getRememberUntil()))).toList());
+ while (!removable.isEmpty() && removable.size() > OfferRepository.KEEP_LAST_OFFERS_COUNT) {
+ final Offer offer = removable.removeFirst();
+ offers.remove(offer);
+ offer.markDeleted();
+ deleted.add(offer);
+ }
+
+ return deleted;
+ }
+
+ public MergeResult save(final Offer offer) {
+ synchronized (offer) {
+ final Optional existingOptional = offers.stream().filter(existing -> existing.getId().equals(offer.getId())).findFirst();
+ if (existingOptional.isPresent()) {
+ existingOptional.get().merge(offer);
+ return MergeResult.UPDATED;
+ } else {
+ log.info("Created: {}", offer);
+ offers.add(offer);
+ return MergeResult.CREATED;
+ }
+ }
+ }
+
+ public List findAll() {
+ synchronized (offers) {
+ return new ArrayList<>(offers);
+ }
+ }
+
+ public void ignore(final MaybeInaccessibleMessage message) {
+ synchronized (offers) {
+ findByTelegramMessageId(message).ifPresent(offer -> {
+ offer.ignore();
+ flush();
+ });
+ }
+ }
+
+ public Optional remember(final MaybeInaccessibleMessage message, final boolean remember) {
+ synchronized (offers) {
+ final Optional optional = findByTelegramMessageId(message);
+ optional.ifPresent(offer -> {
+ offer.setRemember(remember);
+ flush();
+ });
+ return optional;
+ }
+ }
+
+ public Optional findByTelegramMessageId(final MaybeInaccessibleMessage message) {
+ synchronized (offers) {
+ return offers.stream().filter(offer -> Objects.equals(offer.getTelegramMessageId(), message.getMessageId())).findFirst();
+ }
+ }
+
+}
diff --git a/src/main/java/de/ph87/kleinanzeigen/api/InlineCommand.java b/src/main/java/de/ph87/kleinanzeigen/telegram/InlineCommand.java
similarity index 60%
rename from src/main/java/de/ph87/kleinanzeigen/api/InlineCommand.java
rename to src/main/java/de/ph87/kleinanzeigen/telegram/InlineCommand.java
index 8aa0c31..12bba08 100644
--- a/src/main/java/de/ph87/kleinanzeigen/api/InlineCommand.java
+++ b/src/main/java/de/ph87/kleinanzeigen/telegram/InlineCommand.java
@@ -1,4 +1,4 @@
-package de.ph87.kleinanzeigen.api;
+package de.ph87.kleinanzeigen.telegram;
public enum InlineCommand {
IGNORE, REMEMBER, UNREMEMBER
diff --git a/src/main/java/de/ph87/kleinanzeigen/api/InlineDto.java b/src/main/java/de/ph87/kleinanzeigen/telegram/InlineDto.java
similarity index 89%
rename from src/main/java/de/ph87/kleinanzeigen/api/InlineDto.java
rename to src/main/java/de/ph87/kleinanzeigen/telegram/InlineDto.java
index 4c219f5..7cad161 100644
--- a/src/main/java/de/ph87/kleinanzeigen/api/InlineDto.java
+++ b/src/main/java/de/ph87/kleinanzeigen/telegram/InlineDto.java
@@ -1,4 +1,4 @@
-package de.ph87.kleinanzeigen.api;
+package de.ph87.kleinanzeigen.telegram;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
diff --git a/src/main/java/de/ph87/kleinanzeigen/api/Bot.java b/src/main/java/de/ph87/kleinanzeigen/telegram/TelegramBot.java
similarity index 87%
rename from src/main/java/de/ph87/kleinanzeigen/api/Bot.java
rename to src/main/java/de/ph87/kleinanzeigen/telegram/TelegramBot.java
index 4687530..8793d3e 100644
--- a/src/main/java/de/ph87/kleinanzeigen/api/Bot.java
+++ b/src/main/java/de/ph87/kleinanzeigen/telegram/TelegramBot.java
@@ -1,6 +1,8 @@
-package de.ph87.kleinanzeigen.api;
+package de.ph87.kleinanzeigen.telegram;
import com.fasterxml.jackson.core.JsonProcessingException;
+import de.ph87.kleinanzeigen.kleinanzeigen.offer.Offer;
+import de.ph87.kleinanzeigen.kleinanzeigen.offer.OfferRepository;
import lombok.extern.slf4j.Slf4j;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.TelegramBotsApi;
@@ -20,15 +22,15 @@ import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
-import java.util.*;
-import java.util.function.BiFunction;
-import java.util.function.Consumer;
-import java.util.function.Function;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
-import static de.ph87.kleinanzeigen.api.JSON.objectMapper;
+import static de.ph87.kleinanzeigen.JSON.objectMapper;
@Slf4j
-public class Bot extends TelegramLongPollingBot {
+public class TelegramBot extends TelegramLongPollingBot {
private static final long CHAT_ID = 101138682L;
@@ -40,29 +42,29 @@ public class Bot extends TelegramLongPollingBot {
private final DefaultBotSession session;
- private final Consumer ignore;
+ private final OfferRepository offerRepository;
- private final Function> find;
-
- private final BiFunction> remember;
-
- public Bot(final Consumer ignore, final Function> find, final BiFunction> remember) throws IOException, TelegramApiException {
+ public TelegramBot(final OfferRepository offerRepository) throws IOException, TelegramApiException {
super(readToken());
+ this.offerRepository = offerRepository;
final BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
ImageIO.write(img, "PNG", stream);
NO_IMAGE = stream.toByteArray();
- this.ignore = ignore;
- this.find = find;
- this.remember = remember;
log.info("Starting telegram bot...");
final TelegramBotsApi api = new TelegramBotsApi(DefaultBotSession.class);
session = (DefaultBotSession) api.registerBot(this);
log.info("Telegram bot registered.");
}
+ private static String readToken() throws IOException {
+ try (final FileInputStream stream = new FileInputStream("./telegram.token")) {
+ return new String(stream.readAllBytes(), StandardCharsets.UTF_8).trim();
+ }
+ }
+
@Override
public String getBotUsername() {
return "BotKleinanzeigenBot";
@@ -96,26 +98,26 @@ public class Bot extends TelegramLongPollingBot {
}
private void ignore(final MaybeInaccessibleMessage message) {
- ignore.accept(message);
+ offerRepository.ignore(message);
remove(message);
}
private void remember(final MaybeInaccessibleMessage message) {
- remember.apply(message, true).ifPresentOrElse(
+ offerRepository.remember(message, true).ifPresentOrElse(
offer -> updateMessage(message, offer),
() -> remove(message)
);
}
private void unremember(final MaybeInaccessibleMessage message) {
- remember.apply(message, false).ifPresentOrElse(
+ offerRepository.remember(message, false).ifPresentOrElse(
offer -> updateMessage(message, offer),
() -> remove(message)
);
}
private void updateMessage(final MaybeInaccessibleMessage message) {
- find.apply(message).ifPresentOrElse(
+ offerRepository.findByTelegramMessageId(message).ifPresentOrElse(
offer -> updateMessage(message, offer),
() -> remove(message)
);
@@ -131,12 +133,6 @@ public class Bot extends TelegramLongPollingBot {
}
}
- private static String readToken() throws IOException {
- try (final FileInputStream stream = new FileInputStream("./telegram.token")) {
- return new String(stream.readAllBytes(), StandardCharsets.UTF_8).trim();
- }
- }
-
public void send(final Offer offer) {
try {
final InputFile inputFile = offer.getImage().isEmpty() ? new InputFile(new ByteArrayInputStream(NO_IMAGE), "[Kein Bild]") : new InputFile(offer.getImage());