Uses svg images instead of pngs
@ -1,11 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
<option name="gradleHome" value="C:/Program Files/Gradle" />
|
<option name="gradleHome" value="$PROJECT_DIR$/../../../../Program Files/Gradle" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
|
@ -8,6 +8,10 @@ version '0.1.0'
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
maven {
|
||||||
|
name 'OpenMind'
|
||||||
|
url 'https://repository.openmindonline.it/'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -15,6 +19,8 @@ dependencies {
|
|||||||
implementation 'com.sparkjava:spark-core:2.9.4'
|
implementation 'com.sparkjava:spark-core:2.9.4'
|
||||||
implementation 'org.slf4j:slf4j-simple:2.0.3'
|
implementation 'org.slf4j:slf4j-simple:2.0.3'
|
||||||
implementation 'com.google.code.gson:gson:2.10'
|
implementation 'com.google.code.gson:gson:2.10'
|
||||||
|
implementation 'org.apache.xmlgraphics:batik-svggen:1.16'
|
||||||
|
implementation 'org.apache.batik:org.apache.batik.dom:1.6.0-20081006'
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
|
@ -2,13 +2,17 @@ package tech.nevets.codebadgerestapi;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import org.apache.batik.dom.GenericDOMImplementation;
|
||||||
|
import org.apache.batik.svggen.SVGGraphics2D;
|
||||||
|
import org.apache.batik.svggen.SVGGraphics2DIOException;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.w3c.dom.DOMImplementation;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
import java.net.http.HttpRequest;
|
import java.net.http.HttpRequest;
|
||||||
@ -16,18 +20,76 @@ import java.net.http.HttpResponse;
|
|||||||
|
|
||||||
public class BadgeFactory {
|
public class BadgeFactory {
|
||||||
|
|
||||||
|
public static byte[] genSVGBadge(String leftStr, String rightStr, Color secondaryColor) {
|
||||||
|
DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
|
||||||
|
Document doc = domImpl.createDocument("http://www.w3.org/2000/svg", "svg", null);
|
||||||
|
SVGGraphics2D graphics2D = new SVGGraphics2D(doc);
|
||||||
|
Font font = new Font("Calibri", Font.PLAIN, 16);
|
||||||
|
|
||||||
|
graphics2D.setFont(font);
|
||||||
|
FontMetrics fm = graphics2D.getFontMetrics();
|
||||||
|
int lWidth = fm.stringWidth(leftStr);
|
||||||
|
int rWidth = fm.stringWidth(rightStr);
|
||||||
|
int totalWidth = lWidth = lWidth + rWidth + 40;
|
||||||
|
int totalHeight = 20;
|
||||||
|
graphics2D.setPaint(Color.GRAY);
|
||||||
|
graphics2D.fillRect(0, 0, totalWidth, totalHeight);
|
||||||
|
graphics2D.setPaint(secondaryColor);
|
||||||
|
graphics2D.fillRect(totalWidth - rWidth - 20, 0, rWidth + 20, totalHeight);
|
||||||
|
graphics2D.setPaint(Color.GRAY);
|
||||||
|
graphics2D.drawString(leftStr, 10, (totalHeight / 2) + 6);
|
||||||
|
graphics2D.drawString(rightStr, totalWidth - rWidth - 10, (totalHeight / 2) + 6);
|
||||||
|
graphics2D.setPaint(Color.WHITE);
|
||||||
|
graphics2D.drawString(leftStr, 10, (totalHeight / 2) + 5);
|
||||||
|
graphics2D.drawString(rightStr, totalWidth - rWidth - 10, (totalHeight / 2) + 5);
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
OutputStreamWriter osw = new OutputStreamWriter(baos);
|
||||||
|
try {
|
||||||
|
graphics2D.stream(osw, true);
|
||||||
|
} catch (SVGGraphics2DIOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return new byte[]{};
|
||||||
|
}
|
||||||
|
return baos.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] generateBadge(String leftStr, String rightStr, BadgeColor secondaryColor) {
|
public static byte[] generateBadge(String leftStr, String rightStr, BadgeColor secondaryColor) {
|
||||||
// TODO: 11/16/2022 Make this automatically adjust the width of the badge depending on how long both strings are
|
|
||||||
// TODO: 11/16/2022 Make the secondary color always adjust to half the total width of the badge
|
|
||||||
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
|
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
|
||||||
Graphics2D graphics2D = img.createGraphics();
|
Graphics2D graphics2D = img.createGraphics();
|
||||||
Font font = new Font("Calibri", Font.PLAIN, 6);
|
Font font = new Font("Calibri", Font.PLAIN, 23);
|
||||||
graphics2D.setFont(font);
|
graphics2D.setFont(font);
|
||||||
FontMetrics fontMetrics = graphics2D.getFontMetrics();
|
FontMetrics fontMetrics = graphics2D.getFontMetrics();
|
||||||
int width = fontMetrics.stringWidth(leftStr + rightStr);
|
int lWidth = fontMetrics.stringWidth(leftStr);
|
||||||
|
int rWidth = fontMetrics.stringWidth(rightStr);
|
||||||
int height = fontMetrics.getHeight();
|
int height = fontMetrics.getHeight();
|
||||||
graphics2D.dispose();
|
graphics2D.dispose();
|
||||||
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
|
||||||
|
int totalWidth = lWidth + rWidth + 20;
|
||||||
|
int totalHeight = 25;
|
||||||
|
int textY = 19;
|
||||||
|
|
||||||
|
BufferedImage baseBadgeImg;
|
||||||
|
BufferedImage secondaryImg;
|
||||||
|
try {
|
||||||
|
baseBadgeImg = ImageIO.read(BadgeFactory.class.getResourceAsStream("/badge-base-gray.png"));
|
||||||
|
switch (secondaryColor) {
|
||||||
|
case RED -> secondaryImg = ImageIO.read(BadgeFactory.class.getResourceAsStream("/badge-color-red.png"));
|
||||||
|
case ORANGE -> secondaryImg = ImageIO.read(BadgeFactory.class.getResourceAsStream("/badge-color-orange.png"));
|
||||||
|
case YELLOW -> secondaryImg = ImageIO.read(BadgeFactory.class.getResourceAsStream("/badge-color-yellow.png"));
|
||||||
|
case GREEN -> secondaryImg = ImageIO.read(BadgeFactory.class.getResourceAsStream("/badge-color-green.png"));
|
||||||
|
case BLUE -> secondaryImg = ImageIO.read(BadgeFactory.class.getResourceAsStream("/badge-color-blue.png"));
|
||||||
|
case PURPLE -> secondaryImg = ImageIO.read(BadgeFactory.class.getResourceAsStream("/badge-color-purple.png"));
|
||||||
|
case LIGHTGRAY -> secondaryImg = ImageIO.read(BadgeFactory.class.getResourceAsStream("/badge-color-light-gray.png"));
|
||||||
|
default -> secondaryImg = ImageIO.read(BadgeFactory.class.getResourceAsStream("/badge-base-gray.png"));
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
baseBadgeImg = null;
|
||||||
|
secondaryImg = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
img = new BufferedImage(totalWidth, totalHeight, BufferedImage.TYPE_INT_ARGB);
|
||||||
graphics2D = img.createGraphics();
|
graphics2D = img.createGraphics();
|
||||||
graphics2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
|
graphics2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
|
||||||
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
@ -38,9 +100,14 @@ public class BadgeFactory {
|
|||||||
graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||||
graphics2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
graphics2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
||||||
graphics2D.setFont(font);
|
graphics2D.setFont(font);
|
||||||
fontMetrics = graphics2D.getFontMetrics();
|
graphics2D.drawImage(resizeImage(baseBadgeImg, totalWidth), 0, 0, totalWidth, totalHeight, null);
|
||||||
graphics2D.setColor(Color.BLACK);
|
graphics2D.drawImage(secondaryImg, totalWidth - rWidth - 10, 0, rWidth + 10, totalHeight, null);
|
||||||
graphics2D.drawString(leftStr + " " + rightStr, 0, fontMetrics.getAscent());
|
graphics2D.setColor(Color.GRAY);
|
||||||
|
graphics2D.drawString(leftStr, 5, textY - 1);
|
||||||
|
graphics2D.drawString(rightStr, totalWidth - rWidth - 5, textY - 1);
|
||||||
|
graphics2D.setColor(Color.WHITE);
|
||||||
|
graphics2D.drawString(leftStr, 5, textY);
|
||||||
|
graphics2D.drawString(rightStr, totalWidth - rWidth - 5, textY);
|
||||||
graphics2D.dispose();
|
graphics2D.dispose();
|
||||||
|
|
||||||
ByteArrayOutputStream baos;
|
ByteArrayOutputStream baos;
|
||||||
|
@ -1,11 +1,33 @@
|
|||||||
package tech.nevets.codebadgerestapi;
|
package tech.nevets.codebadgerestapi;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
import static spark.Spark.*;
|
import static spark.Spark.*;
|
||||||
|
|
||||||
public class Server {
|
public class Server {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
path("/badge", () -> {
|
path("/badge", () -> {
|
||||||
before("/*");
|
before("/*");
|
||||||
|
get("/test/:left/:right/:color", (req, res) -> {
|
||||||
|
res.type("image/svg+xml");
|
||||||
|
Color color = Color.GRAY;
|
||||||
|
switch (req.params(":color").toLowerCase()) {
|
||||||
|
case "red" -> color = Color.RED;
|
||||||
|
case "orange" -> color = Color.ORANGE;
|
||||||
|
case "yellow" -> color = Color.YELLOW;
|
||||||
|
case "green" -> color = Color.GREEN;
|
||||||
|
case "cyan" -> color = Color.CYAN;
|
||||||
|
case "blue" -> color = Color.BLUE;
|
||||||
|
case "purple", "magenta" -> color = Color.MAGENTA;
|
||||||
|
case "pink" -> color = Color.PINK;
|
||||||
|
case "white" -> color = Color.WHITE;
|
||||||
|
case "lightgray" -> color = Color.LIGHT_GRAY;
|
||||||
|
case "darkgray" -> color = Color.DARK_GRAY;
|
||||||
|
case "black" -> color = Color.BLACK;
|
||||||
|
default -> color = Color.GRAY;
|
||||||
|
}
|
||||||
|
return BadgeFactory.genSVGBadge(req.params(":left"), req.params(":right"), color);
|
||||||
|
});
|
||||||
get("/version/*/:gitUrl/:org/:repo/:branch", (req, res) -> {
|
get("/version/*/:gitUrl/:org/:repo/:branch", (req, res) -> {
|
||||||
switch (req.splat()[0]) {
|
switch (req.splat()[0]) {
|
||||||
case "gitea" -> {
|
case "gitea" -> {
|
||||||
@ -32,7 +54,20 @@ public class Server {
|
|||||||
get("/buildStatus/*/:ciUrl/:projectName", (req, res) -> {
|
get("/buildStatus/*/:ciUrl/:projectName", (req, res) -> {
|
||||||
switch (req.splat()[0]) {
|
switch (req.splat()[0]) {
|
||||||
case "jenkins" -> {
|
case "jenkins" -> {
|
||||||
return BadgeFactory.getLatestBuildStatusFromJenkins(req.params(":ciUrl"), req.params(":projectName"));
|
res.type("image/png");
|
||||||
|
String buildStatus = BadgeFactory.getLatestBuildStatusFromJenkins(req.params(":ciUrl"), req.params(":projectName"));
|
||||||
|
BadgeColor badgeColor = BadgeColor.GRAY;
|
||||||
|
switch (buildStatus) {
|
||||||
|
case "SUCCESS" -> {
|
||||||
|
buildStatus = "passing";
|
||||||
|
badgeColor = BadgeColor.GREEN;
|
||||||
|
}
|
||||||
|
case "FAILURE" -> {
|
||||||
|
buildStatus = "failing";
|
||||||
|
badgeColor = BadgeColor.RED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BadgeFactory.generateBadge("Build", buildStatus, badgeColor);
|
||||||
}
|
}
|
||||||
case "circleci" -> {
|
case "circleci" -> {
|
||||||
res.status(405);
|
res.status(405);
|
||||||
@ -42,6 +77,10 @@ public class Server {
|
|||||||
res.status(405);
|
res.status(405);
|
||||||
return "Not yet Implemented!";
|
return "Not yet Implemented!";
|
||||||
}
|
}
|
||||||
|
case "test" -> {
|
||||||
|
res.type("image/svg+xml");
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
res.status(404);
|
res.status(404);
|
||||||
return "Not Found!";
|
return "Not Found!";
|
||||||
|
@ -4,6 +4,7 @@ import java.awt.*;
|
|||||||
|
|
||||||
public class askjdf {
|
public class askjdf {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
for (Font font : GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts()) {
|
for (Font font : GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts()) {
|
||||||
System.out.println(font.getName());
|
System.out.println(font.getName());
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
@ -1,18 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="112.0" height="20">
|
|
||||||
<linearGradient id="a" x2="0" y2="100%">
|
|
||||||
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
||||||
<stop offset="1" stop-opacity=".1"/>
|
|
||||||
</linearGradient>
|
|
||||||
<rect rx="3" width="112.0" height="20" fill="#555"/>
|
|
||||||
<rect rx="0" x="47.0" width="4" height="20" fill="#44cc11"/>
|
|
||||||
<rect rx="3" x="47.0" width="65.0" height="20" fill="#44cc11"/>
|
|
||||||
|
|
||||||
<rect rx="3" width="112.0" height="20" fill="url(#a)"/>
|
|
||||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
|
||||||
<text x="24.5" y="15" fill="#010101" fill-opacity=".3">build</text>
|
|
||||||
<text x="24.5" y="14">build</text>
|
|
||||||
<text x="78.5" y="15" fill="#010101" fill-opacity=".3">passing</text>
|
|
||||||
<text x="78.5" y="14">passing</text>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 902 B |