Commit 58b34712 authored by Delorus's avatar Delorus
Browse files

Merge branch '33-dont-create-files' into 'develop'

Resolve "Не делать промеждуточного сохранения графиков на диск"

Closes #33

See merge request !40
parents f76879fd 4816d703
Pipeline #453 failed with stages
in 4 minutes and 23 seconds
plugins {
id 'java-library'
}
rootProject.name = 'hacks'
package page.devnet.hacks;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
/**
* @author sherb
* @since 15.05.2021
*/
public class BufferPipedInputStream {
public static boolean isBufferInputStream(InputStream stream) {
return stream instanceof BufferByteArrayInputStream;
}
public static ByteBuffer unwrapBuffer(InputStream stream) {
if (isBufferInputStream(stream)) {
return ((BufferByteArrayInputStream) stream).buffer();
}
return ByteBuffer.allocate(0);
}
private final BufferByteArrayOutputStream outputStream = new BufferByteArrayOutputStream();
public OutputStream asOutputStream() {
return outputStream;
}
public InputStream asInputStream() {
if (outputStream.size() == 0) {
return new ByteArrayInputStream(new byte[0]);
}
return new BufferByteArrayInputStream(outputStream.buffer(), 0, outputStream.size());
}
private static class BufferByteArrayOutputStream extends ByteArrayOutputStream {
public BufferByteArrayOutputStream() {
super();
}
public BufferByteArrayOutputStream(int size) {
super(size);
}
public byte[] buffer() {
return this.buf;
}
}
private static class BufferByteArrayInputStream extends ByteArrayInputStream {
private final ByteBuffer buffer;
public BufferByteArrayInputStream(byte[] buf) {
super(buf);
buffer = ByteBuffer.wrap(buf);
}
public BufferByteArrayInputStream(byte[] buf, int offset, int length) {
super(buf, offset, length);
buffer = ByteBuffer.wrap(buf, offset, length);
}
public ByteBuffer buffer() {
return buffer;
}
}
}
package page.devnet.hacks;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author sherb
* @since 16.05.2021
*/
class BufferPipedInputStreamTest {
@Test
public void dataTransferCorrectly() throws IOException {
// Setup
var stream = new BufferPipedInputStream();
// When
try (var out = stream.asOutputStream()) {
out.write("hello world".getBytes(StandardCharsets.UTF_8));
}
// Then
assertEquals("hello world", buf2str(BufferPipedInputStream.unwrapBuffer(stream.asInputStream())));
}
private static String buf2str(ByteBuffer buffer) {
return StandardCharsets.UTF_8.decode(buffer).toString();
}
}
......@@ -7,4 +7,5 @@ include 'telegrambot'
include 'cli'
include 'database'
include 'vertxtgbot'
include 'hacks'
......@@ -16,10 +16,6 @@ import page.devnet.wordstat.api.Statistics;
import page.devnet.wordstat.chart.Chart;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.ArrayList;
......@@ -92,7 +88,7 @@ public class WordStatisticPlugin implements Plugin<Update, List<PartialBotApiMet
var fromLastDay = ZonedDateTime.now().minusDays(1);
try {
Chart top10UsedWordsFromLastDay = statistics.getTop10UsedWordsFrom(fromLastDay.toInstant());
SendPhoto sendPhoto = wrapToSendPhoto(top10UsedWordsFromLastDay, chatId);
SendPhoto sendPhoto = wrapToSendPhoto(top10UsedWordsFromLastDay, "top 10 used words from last day", chatId);
return List.of(sendPhoto);
} catch (IllegalArgumentException e) {
return List.of(new SendMessage(chatId, e.getMessage()));
......@@ -103,7 +99,7 @@ public class WordStatisticPlugin implements Plugin<Update, List<PartialBotApiMet
List<Chart> top10WordsFromEachUserFromLastDay = statistics.getTop10UsedWordsFromEachUser(fromLastDay.toInstant());
List<PartialBotApiMethod<?>> result = new ArrayList<>();
for (Chart chart : top10WordsFromEachUserFromLastDay) {
SendPhoto sendPhoto = wrapToSendPhoto(chart, chatId);
SendPhoto sendPhoto = wrapToSendPhoto(chart, "top 10 words by each user from last day", chatId);
result.add(sendPhoto);
}
return result;
......@@ -114,7 +110,7 @@ public class WordStatisticPlugin implements Plugin<Update, List<PartialBotApiMet
fromLastDay = ZonedDateTime.now().minusDays(1);
try {
Chart top10WordsFromLastDayByUser = statistics.getWordsCountByUserFrom(fromLastDay.toInstant());
SendPhoto sendPhoto = wrapToSendPhoto(top10WordsFromLastDayByUser, chatId);
SendPhoto sendPhoto = wrapToSendPhoto(top10WordsFromLastDayByUser, "top 10 words from last day by user", chatId);
return List.of(sendPhoto);
} catch (IllegalArgumentException e) {
return List.of(new SendMessage(chatId, e.getMessage()));
......@@ -125,16 +121,12 @@ public class WordStatisticPlugin implements Plugin<Update, List<PartialBotApiMet
}
}
private SendPhoto wrapToSendPhoto(Chart chart, String chatId) throws IOException {
private SendPhoto wrapToSendPhoto(Chart chart, String title, String chatId) throws IOException {
SendPhoto sendPhoto = new SendPhoto();
sendPhoto.setChatId(chatId);
Path file = Files.createTempFile("chart", ".png");
try (InputStream in = chart.toInputStream()) {
Files.copy(in, file, StandardCopyOption.REPLACE_EXISTING);
}
sendPhoto.setPhoto(new InputFile(file.toFile()));
log.info("Send new chart {} with size: {}bytes", file.toFile().getName(), file.toFile().length());
sendPhoto.setPhoto(new InputFile(chart.toInputStream(), title));
log.info("Send new chart {} to group: {}", title, chatId);
return sendPhoto;
}
......
plugins {
id 'java'
id 'java-library'
}
group 'page.devnet'
version '0.1.0'
ext {
vertxVersion = '4.0.3'
telegrambotsVersion = '5.2.0'
}
repositories {
mavenCentral()
}
dependencies {
api "io.vertx:vertx-core:$vertxVersion"
api "org.telegram:telegrambots-meta:$telegrambotsVersion"
......@@ -22,6 +14,7 @@ dependencies {
implementation "io.vertx:vertx-web:$vertxVersion"
implementation "io.vertx:vertx-web-client:$vertxVersion"
implementation "io.vertx:vertx-junit5:$vertxVersion"
implementation project(":hacks")
testImplementation "org.telegram:telegrambots:$telegrambotsVersion"
}
package page.devnet.vertxtgbot.tgapi;
import io.netty.buffer.Unpooled;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.Json;
import io.vertx.ext.web.multipart.MultipartForm;
import org.telegram.telegrambots.meta.api.objects.InputFile;
......@@ -7,6 +9,7 @@ import org.telegram.telegrambots.meta.api.objects.media.InputMedia;
import org.telegram.telegrambots.meta.api.objects.media.InputMediaAudio;
import org.telegram.telegrambots.meta.api.objects.media.InputMediaDocument;
import org.telegram.telegrambots.meta.api.objects.media.InputMediaVideo;
import page.devnet.hacks.BufferPipedInputStream;
import java.io.File;
import java.util.List;
......@@ -18,6 +21,7 @@ import java.util.List;
final class InputFileHelper {
public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
public static final String TEXT_PLAIN = "text/plain";
private InputFileHelper() throws IllegalAccessException {
throw new IllegalAccessException();
......@@ -39,11 +43,21 @@ final class InputFileHelper {
file.getNewMediaFile().getAbsolutePath(), APPLICATION_OCTET_STREAM);
} else {
form.textFileUpload(file.getMediaName(), file.getMediaName(),
file.getNewMediaFile().getAbsolutePath(), APPLICATION_OCTET_STREAM);
file.getNewMediaFile().getAbsolutePath(), TEXT_PLAIN);
}
} else if (file.getNewMediaStream() != null) {
throw new UnsupportedOperationException("Upload file via InputStream is not supported to ensure non-blocking operations");
var stream = file.getNewMediaStream();
if (BufferPipedInputStream.isBufferInputStream(stream)) {
var buffer = Buffer.buffer(Unpooled.wrappedBuffer(BufferPipedInputStream.unwrapBuffer(stream)));
if (isBinary) {
form.binaryFileUpload(file.getMediaName(), file.getMediaName(), buffer, APPLICATION_OCTET_STREAM);
} else {
form.textFileUpload(file.getMediaName(), file.getMediaName(), buffer, TEXT_PLAIN);
}
} else {
throw new UnsupportedOperationException("Upload file via InputStream is not supported to ensure non-blocking operations");
}
}
}
......
......@@ -5,6 +5,7 @@ plugins {
dependencies {
// https://github.com/knowm/XChart
implementation "org.knowm.xchart:xchart:3.6.0"
implementation project(":database")
}
\ No newline at end of file
implementation project(":database")
implementation project(":hacks")
}
package page.devnet.wordstat.chart;
import page.devnet.hacks.BufferPipedInputStream;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
......@@ -16,17 +16,15 @@ public final class Chart {
private final BufferedImage bufferedImage;
Chart(BufferedImage bufferedImage) {
this.bufferedImage = bufferedImage;
}
public InputStream toInputStream() throws IOException {
byte[] imageInBytes;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ImageIO.write(bufferedImage, "png", baos);
baos.flush();
imageInBytes = baos.toByteArray();
var pipe = new BufferPipedInputStream();
try (var out = pipe.asOutputStream()) {
ImageIO.write(bufferedImage, "png", out);
}
return new ByteArrayInputStream(imageInBytes);
return pipe.asInputStream();
}
}
package page.devnet.wordstat.chart;
import lombok.Value;
import org.knowm.xchart.*;
import org.knowm.xchart.BitmapEncoder;
import org.knowm.xchart.CategoryChart;
import org.knowm.xchart.CategoryChartBuilder;
import org.knowm.xchart.PieChart;
import org.knowm.xchart.PieChartBuilder;
import org.knowm.xchart.style.CategoryStyler;
import org.knowm.xchart.style.Styler;
import java.awt.*;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
......@@ -49,7 +53,7 @@ public final class XChartRenderer {
Chart createBarChart(String title, BarChartData... data) {
CategoryChart chart = new CategoryChartBuilder()
.title(title)
.xAxisTitle("user") //todo
.xAxisTitle("user")
.yAxisTitle("count")
.theme(Styler.ChartTheme.GGPlot2)
.build();
......
......@@ -20,7 +20,7 @@ import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ExampleListChart {
public class ListChartTest {
//WordStorage wordStorage;
WordStorageRepository wordStorageRepository;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment