Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[![GitHub commit activity](https://img.shields.io/github/commit-activity/y/softwaremagico/KendoTournamentManager)](https://github.com/softwaremagico/KendoTournamentManager)
[![GitHub last commit](https://img.shields.io/github/last-commit/softwaremagico/KendoTournamentManager)](https://github.com/softwaremagico/KendoTournamentManager)
[![CircleCI](https://circleci.com/gh/softwaremagico/KendoTournamentManager.svg?style=shield)](https://circleci.com/gh/softwaremagico/KendoTournamentManager)
[![Time](https://img.shields.io/badge/development-654h-blueviolet.svg)]()
[![Time](https://img.shields.io/badge/development-655h-blueviolet.svg)]()

[![Powered by](https://img.shields.io/badge/powered%20by%20java-orange.svg?logo=OpenJDK&logoColor=white)]()
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=kendo-tournament-backend&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=kendo-tournament-backend)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ public class QrController {
private static final String LOGO_RESOURCE = "/kote.svg";
private static final String QR_FORMAT = "png";
private static final Integer QR_SIZE = 500;
private static final Color QR_COLOR = Color.decode("#001239");
private static final Color QR_COLOR_LIGHT_MODE = Color.decode("#001239");
private static final Color QR_COLOR_NIGHT_MODE = Color.decode("#b0a3d5");
private static final Color BACKGROUND_LIGHT_MODE = Color.decode("#ffffff");
private static final Color BACKGROUND_NIGHT_MODE = Color.decode("#424242");

private final QrProvider qrProvider;

Expand All @@ -72,14 +75,17 @@ public QrController(QrProvider qrProvider, TournamentProvider tournamentProvider
}

@Cacheable(cacheNames = "qr-codes", key = "#tournamentId")
public QrCodeDTO generateGuestQrCodeForTournamentFights(Integer tournamentId, Integer port) {
public QrCodeDTO generateGuestQrCodeForTournamentFights(Integer tournamentId, Integer port, boolean nightMode) {
//Check that exists.
final Tournament tournament = tournamentProvider.get(tournamentId).orElseThrow(() ->
new TournamentNotFoundException(this.getClass(), "No tournament found with id '" + tournamentId + "'."));
try {
final String link = schema + "://" + machineDomain + (port != null ? ":" + port : "") + TOURNAMENT_FIGHTS_URL
+ "?tournamentId=" + tournament.getId() + "&user=guest";
final BufferedImage qrCode = qrProvider.getQr(link, QR_SIZE, QR_COLOR, LOGO_RESOURCE);
final BufferedImage qrCode = qrProvider.getQr(link, QR_SIZE,
!nightMode ? QR_COLOR_LIGHT_MODE : QR_COLOR_NIGHT_MODE,
LOGO_RESOURCE,
!nightMode ? BACKGROUND_LIGHT_MODE : BACKGROUND_NIGHT_MODE);
final QrCodeDTO qrCodeDTO = new QrCodeDTO();
qrCodeDTO.setData(toByteArray(qrCode, QR_FORMAT));
qrCodeDTO.setLink(link);
Expand All @@ -96,7 +102,7 @@ public QrCodeDTO generateGuestQrCodeForTournamentFights(Integer tournamentId, In
* @param port if the frontend is running on a different port.
* @return
*/
public QrCodeDTO generateParticipantQrCodeForStatistics(Integer participantId, Integer port) {
public QrCodeDTO generateParticipantQrCodeForStatistics(Integer participantId, Integer port, boolean nightMode) {
final Participant participant = participantProvider.get(participantId).orElseThrow(() ->
new ParticipantNotFoundException(this.getClass(), "No participant found with id '" + participantId + "'."));

Expand All @@ -106,7 +112,10 @@ public QrCodeDTO generateParticipantQrCodeForStatistics(Integer participantId, I
final String link = schema + "://" + machineDomain + (port != null ? ":" + port : "") + PARTICIPANT_STATISTICS_URL
+ "?participantId=" + participantId + "&temporalToken="
+ URLEncoder.encode(temporalToken.getContent(), StandardCharsets.UTF_8);
final BufferedImage qrCode = qrProvider.getQr(link, QR_SIZE, QR_COLOR, LOGO_RESOURCE);
final BufferedImage qrCode = qrProvider.getQr(link, QR_SIZE,
!nightMode ? QR_COLOR_LIGHT_MODE : QR_COLOR_NIGHT_MODE,
LOGO_RESOURCE,
!nightMode ? BACKGROUND_LIGHT_MODE : BACKGROUND_NIGHT_MODE);
final QrCodeDTO qrCodeDTO = new QrCodeDTO();
qrCodeDTO.setData(toByteArray(qrCode, QR_FORMAT));
qrCodeDTO.setLink(link);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.batik.util.XMLResourceDescriptor;
import org.springframework.stereotype.Service;
Expand All @@ -52,6 +53,8 @@
import java.io.InputStream;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

@Service
Expand All @@ -60,10 +63,10 @@ public class QrProvider {
private static final float DEFAULT_SVG_SIZE = 200F;
private static final double BORDER_RELATIVE_SIZE = 0.02d;
private static final double BORDER_RADIUS = 0.03d;
private static BufferedImage qrLogo;
private static Map<Color, BufferedImage> qrLogoByBackground = new HashMap<>();

public QrPositionalSquaresConfig crateSquareConfig(Boolean circleShaped, Double relativeSquareBorderRound,
Color center, Color innerSquare, Color outerSquare, Color outerBorder) {
Color center, Color outerSquare, Color background) {
final QrPositionalSquaresConfig.Builder builder = new QrPositionalSquaresConfig.Builder();

if (circleShaped != null) {
Expand All @@ -78,34 +81,34 @@ public QrPositionalSquaresConfig crateSquareConfig(Boolean circleShaped, Double
builder.centerColor(center);
}

if (innerSquare != null) {
builder.innerSquareColor(innerSquare);
if (background != null) {
builder.innerSquareColor(background);
}

if (outerSquare != null) {
builder.outerSquareColor(outerSquare);
}

if (outerBorder != null) {
builder.outerBorderColor(outerBorder);
if (background != null) {
builder.outerBorderColor(background);
}

return builder.build();
}

public BufferedImage getQr(String content, Integer size, Color color) {
public BufferedImage getQr(String content, Integer size, Color color, Color background) {
return getQr(content, size, color, color, null, null,
crateSquareConfig(false, null, color, null, color, null),
crateSquareConfig(false, null, color, color, background),
null);
}

public BufferedImage getQr(String content, Integer size, Color color, String resourceLogo) {
return getQr(content, size, color, resourceLogo, true);
public BufferedImage getQr(String content, Integer size, Color color, String resourceLogo, Color background) {
return getQr(content, size, color, resourceLogo, true, background);
}

public BufferedImage getQr(String content, Integer size, Color color, String resourceLogo, boolean circleShaped) {
return getQr(content, size, color, color, null, resourceLogo,
crateSquareConfig(circleShaped, null, color, null, color, null),
public BufferedImage getQr(String content, Integer size, Color color, String resourceLogo, boolean circleShaped, Color background) {
return getQr(content, size, color, color, background, resourceLogo,
crateSquareConfig(circleShaped, null, color, color, background),
null);
}

Expand Down Expand Up @@ -141,7 +144,7 @@ public BufferedImage getQr(String content, Integer size, Color borderColor, Colo
try {
final BufferedImage logoImage;
if (resourceLogo.endsWith(".svg")) {
logoImage = readSvgResource(resourceLogo, size != null ? (float) size : DEFAULT_SVG_SIZE, ink);
logoImage = readSvgResource(resourceLogo, size != null ? (float) size : DEFAULT_SVG_SIZE, ink, background);
} else {
logoImage = readImageResource(resourceLogo);
}
Expand Down Expand Up @@ -177,19 +180,23 @@ private BufferedImage readImageResource(String resourceLogo) {
return null;
}

private BufferedImage readSvgResource(String resourceLogo, float size, Color ink) throws IOException, TranscoderException {
if (qrLogo == null) {
private BufferedImage readSvgResource(String resourceLogo, float size, Color ink, Color background) throws IOException, TranscoderException {
if (qrLogoByBackground.get(background) == null) {
//Get SVG File.
final InputStream inputStream = QrProvider.class.getResourceAsStream(resourceLogo);
if (inputStream == null) {
return null;
}
final String svgText = new Scanner(inputStream, StandardCharsets.UTF_8).useDelimiter("\\A").next();
final SVGDocument svgDocument = updateLogoColor(svgText, ink);
final SVGDocument svgDocument = updateLogoColor(svgText, ink, background);

//Convert to PNG.
final Transcoder pngTranscoder = new PNGTranscoder();

//Background.
//pngTranscoder.addTranscodingHint(PNGTranscoder.KEY_FORCE_TRANSPARENT_WHITE, true);
pngTranscoder.addTranscodingHint(ImageTranscoder.KEY_BACKGROUND_COLOR, background);

// Set the transcoding hints.
pngTranscoder.addTranscodingHint(SVGAbstractTranscoder.KEY_WIDTH, size / 2);
pngTranscoder.addTranscodingHint(SVGAbstractTranscoder.KEY_HEIGHT, size / 2);
Expand All @@ -209,26 +216,38 @@ private BufferedImage readSvgResource(String resourceLogo, float size, Color ink

// Convert the byte stream into an image.
final byte[] imgData = outputStream.toByteArray();
qrLogo = ImageIO.read(new ByteArrayInputStream(imgData));
qrLogoByBackground.put(background, ImageIO.read(new ByteArrayInputStream(imgData)));
}
return qrLogo;
return qrLogoByBackground.get(background);
}

private SVGDocument updateLogoColor(String svgText, Color color) throws IOException {
private SVGDocument updateLogoColor(String svgText, Color ink, Color background) throws IOException {
final StringReader reader = new StringReader(svgText);
final String uri = "file:svgImage";
final String parser = XMLResourceDescriptor.getXMLParserClassName();
final SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
final SVGDocument svgDocument = f.createSVGDocument(uri, reader);
if (color != null) {
if (ink != null) {
final NodeList styleList = svgDocument.getElementsByTagName("path");
for (int i = 0; i < styleList.getLength(); i++) {
// To search only "style" desired children
final Node defsChild = styleList.item(i);
if (defsChild.getNodeType() == Node.ELEMENT_NODE) {
final Element element = (Element) defsChild;
element.setAttributeNS(null, "fill", "#"
+ Integer.toHexString(color.getRGB()).substring(2));
+ Integer.toHexString(ink.getRGB()).substring(2));
}
}
}
if (background != null) {
final NodeList styleList = svgDocument.getElementsByTagName("circle");
for (int i = 0; i < styleList.getLength(); i++) {
// To search only "style" desired children
final Node defsChild = styleList.item(i);
if (defsChild.getNodeType() == Node.ELEMENT_NODE) {
final Element element = (Element) defsChild;
element.setAttributeNS(null, "fill", "#"
+ Integer.toHexString(background.getRGB()).substring(2));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ private float getNamePosition(TournamentDTO tournamentDTO) {
}

public TournamentQr generateTournamentQr(Locale locale, TournamentDTO tournament, Integer port) {
final QrCodeDTO qrCodeDTO = qrController.generateGuestQrCodeForTournamentFights(tournament.getId(), port);
final QrCodeDTO qrCodeDTO = qrController.generateGuestQrCodeForTournamentFights(tournament.getId(), port, false);
return new TournamentQr(messageSource, locale, tournament, qrCodeDTO.getData(), null);
}
}
Loading
Loading