Uses svg images instead of pngs
@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<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">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
|
@ -8,6 +8,10 @@ version '0.1.0'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name 'OpenMind'
|
||||
url 'https://repository.openmindonline.it/'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -15,6 +19,8 @@ dependencies {
|
||||
implementation 'com.sparkjava:spark-core:2.9.4'
|
||||
implementation 'org.slf4j:slf4j-simple:2.0.3'
|
||||
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 {
|
||||
|
@ -2,13 +2,17 @@ package tech.nevets.codebadgerestapi;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
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.w3c.dom.DOMImplementation;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
@ -16,18 +20,76 @@ import java.net.http.HttpResponse;
|
||||
|
||||
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) {
|
||||
// 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);
|
||||
Graphics2D graphics2D = img.createGraphics();
|
||||
Font font = new Font("Calibri", Font.PLAIN, 6);
|
||||
Font font = new Font("Calibri", Font.PLAIN, 23);
|
||||
graphics2D.setFont(font);
|
||||
FontMetrics fontMetrics = graphics2D.getFontMetrics();
|
||||
int width = fontMetrics.stringWidth(leftStr + rightStr);
|
||||
int lWidth = fontMetrics.stringWidth(leftStr);
|
||||
int rWidth = fontMetrics.stringWidth(rightStr);
|
||||
int height = fontMetrics.getHeight();
|
||||
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.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
|
||||
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_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
||||
graphics2D.setFont(font);
|
||||
fontMetrics = graphics2D.getFontMetrics();
|
||||
graphics2D.setColor(Color.BLACK);
|
||||
graphics2D.drawString(leftStr + " " + rightStr, 0, fontMetrics.getAscent());
|
||||
graphics2D.drawImage(resizeImage(baseBadgeImg, totalWidth), 0, 0, totalWidth, totalHeight, null);
|
||||
graphics2D.drawImage(secondaryImg, totalWidth - rWidth - 10, 0, rWidth + 10, totalHeight, null);
|
||||
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();
|
||||
|
||||
ByteArrayOutputStream baos;
|
||||
|
@ -1,11 +1,33 @@
|
||||
package tech.nevets.codebadgerestapi;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import static spark.Spark.*;
|
||||
|
||||
public class Server {
|
||||
public static void main(String[] args) {
|
||||
path("/badge", () -> {
|
||||
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) -> {
|
||||
switch (req.splat()[0]) {
|
||||
case "gitea" -> {
|
||||
@ -32,7 +54,20 @@ public class Server {
|
||||
get("/buildStatus/*/:ciUrl/:projectName", (req, res) -> {
|
||||
switch (req.splat()[0]) {
|
||||
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" -> {
|
||||
res.status(405);
|
||||
@ -42,6 +77,10 @@ public class Server {
|
||||
res.status(405);
|
||||
return "Not yet Implemented!";
|
||||
}
|
||||
case "test" -> {
|
||||
res.type("image/svg+xml");
|
||||
|
||||
}
|
||||
}
|
||||
res.status(404);
|
||||
return "Not Found!";
|
||||
|
@ -4,6 +4,7 @@ import java.awt.*;
|
||||
|
||||
public class askjdf {
|
||||
public static void main(String[] args) {
|
||||
|
||||
for (Font font : GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts()) {
|
||||
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 |