diff --git a/README.md b/README.md index 7cc6f5d..b8e2776 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,9 @@ This project provides a collection of useful template renderers. | Renderer | Description | |:--------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------| | [rife.render.formatCreditcard](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.FormatCreditCard) | Formats a template credit card number value to the last 4 digits | -| [rife.render.Normalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Normalize) | Normalizes a template value for inclusion in a URL path | -| [rife.render.ShortenUrl](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.ShortenUrl) | Shortens a template value using [is./gd](https://is.gd/) | +| [rife.render.Normalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Normalize) | Normalizes a template value for inclusion in a URL path | +| [rife.render.QrCode](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.QrCode) | Generate a SVG QR Code from a template value | +| [rife.render.ShortenUrl](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.ShortenUrl) | Shortens a template value | | [rife.render.Uptime](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uptime) | Renders the server uptime in various customizable formats | diff --git a/lib/src/main/java/rife/render/QrCode.java b/lib/src/main/java/rife/render/QrCode.java new file mode 100644 index 0000000..96569db --- /dev/null +++ b/lib/src/main/java/rife/render/QrCode.java @@ -0,0 +1,59 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package rife.render; + +import rife.template.Template; +import rife.template.ValueRenderer; + +import java.io.IOException; +import java.io.StringReader; +import java.util.Properties; + +/** + *

Generates an SVG QR Code for a template value using goQR.me.

+ * + *

Usage:

+ * + *
+ *   <!--v render:rife.render.QrCode:valueId/-->
+ *   {{v render:rife.render.QrCode:valueId/}}
+ * 
+ * + * @author Erik C. Thauvin + * @see rife.render.QrCode + * @since 1.0 + */ +public class QrCode implements ValueRenderer { + /** + * {@inheritDoc} + */ + @Override + public String render(Template template, String valueId, String differentiator) { + var size = "150x150"; + if (template.hasDefaultValue(valueId)) { + var properties = new Properties(); + try { + properties.load(new StringReader(template.getDefaultValue(valueId))); + size = properties.getProperty("size", size); + } catch (IOException ignore) { + // do nothing + } + } + return RenderUtils.qrCode(template.getValueOrAttribute(differentiator), size); + } +} diff --git a/lib/src/main/java/rife/render/RenderUtils.java b/lib/src/main/java/rife/render/RenderUtils.java index 3883f05..f7c9061 100644 --- a/lib/src/main/java/rife/render/RenderUtils.java +++ b/lib/src/main/java/rife/render/RenderUtils.java @@ -129,8 +129,8 @@ public final class RenderUtils { * @return The normalized String */ public static String normalize(String src) { - var sb = new StringBuilder(src.length()); var normalized = Normalizer.normalize(src.trim(), Normalizer.Form.NFD); + var sb = new StringBuilder(normalized.length()); boolean space = false; for (var c : normalized.toCharArray()) { if (c <= '\u007F') { // ascii only @@ -166,6 +166,39 @@ public final class RenderUtils { } } + /** + * Generates an SVG QR Code from the given String using goQR.me. + * + * @param src the data String + * @param size the QR Code size. (e.g. {@code 150x150}) + * @return the QR code + */ + public static String qrCode(String src, String size) { + if (src == null || src.isBlank()) { + return src; + } + + var svg = src; + try { + var connection = (HttpURLConnection) new URL( + String.format("https://api.qrserver.com/v1/create-qr-code/?format=svg&size=%s&data=%s", size, + StringUtils.encodeUrl(src.trim()))) + .openConnection(); + connection.setRequestProperty( + "User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0" + ); + var responseCode = connection.getResponseCode(); + if (responseCode >= 200 && responseCode <= 399) { + try (var inputStream = connection.getInputStream()) { + svg = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + } + } + } catch (IOException ignore) { + // do nothing + } + return svg; + } + /** * Translates a String to/from ROT13. * @@ -221,7 +254,7 @@ public final class RenderUtils { var shorten = url; try { var connection = (HttpURLConnection) new URL( - String.format("https://is.gd/create.php?format=simple&url=%s", StringUtils.decodeUrl(url.trim()))) + String.format("https://is.gd/create.php?format=simple&url=%s", StringUtils.encodeUrl(url.trim()))) .openConnection(); connection.setRequestProperty( "User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0" @@ -385,5 +418,4 @@ public final class RenderUtils { return sb.toString(); } - } diff --git a/lib/src/test/java/rife/render/TestFormat.java b/lib/src/test/java/rife/render/TestFormat.java index f2e98b0..8ebdd8f 100644 --- a/lib/src/test/java/rife/render/TestFormat.java +++ b/lib/src/test/java/rife/render/TestFormat.java @@ -45,6 +45,14 @@ class TestFormat { + foo + ""); } + @Test + void testQrCode() { + var t = TemplateFactory.SVG.get("qrCode"); + var foo = "https://example.com/"; + t.setAttribute(TestCase.FOO, foo); + assertThat(t.getContent()).startsWith("" + foo + "