Skip to content

Commit

Permalink
Sprite library and spritesets (#265)
Browse files Browse the repository at this point in the history
SpriteLibrary and Json SpriteSets
  • Loading branch information
chriskn authored Dec 2, 2024
1 parent 8fd611b commit 5bfa30b
Show file tree
Hide file tree
Showing 95 changed files with 38,063 additions and 639 deletions.
42 changes: 42 additions & 0 deletions scripts/gilbarbaraImageSpriteParser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import re
import json
import urllib.request

GILBARBARA_ICON_URL = "https://raw.githubusercontent.com/plantuml-stdlib/gilbarbara-plantuml-sprites/v1.1"
SPRITE_FILE_URL = "https://raw.githubusercontent.com/rabelenda/gilbarbara-plantuml-sprites/refs/heads/master/sprites-list.md"
OUTPUT_FILE_JSON = "../src/main/resources/sprites/gilbarbara_image_sprites.json"
URL_VAR_NAME = "GILBARBARA_PNG_URL"
ADDITIOANL_DEFINITIONS = [URL_VAR_NAME + " " + GILBARBARA_ICON_URL+"/pngs"]


def icon_names_to_path():
sprite_defs = urllib.request.urlopen(SPRITE_FILE_URL).readlines()
icon_name_to_path = {}
for sprite_def in sprite_defs[5:]:
sprite_values = sprite_def.decode("utf-8").split("|")
name = sprite_values[1] + "-img"
icon = sprite_values[2]
icon_path = re.search(r"\((.+)\)", icon).group(1).replace("pngs","")
icon_path = "img:" + GILBARBARA_ICON_URL + icon_path
icon_name_to_path[name] = icon_path
return icon_name_to_path


if __name__ == "__main__":
json_sprites = []
for name, url in icon_names_to_path().items():
json_sprites.append(
{
"@type": "ImageSprite",
"name": "logos-" + name,
"url": url.replace(GILBARBARA_ICON_URL, URL_VAR_NAME),
}
)

sprite_set = {}
sprite_set["name"] = "gilbarbara PNG sprites"
sprite_set["source"] = GILBARBARA_ICON_URL
sprite_set["additionalDefinitions"] = ADDITIOANL_DEFINITIONS
sprite_set["sprites"] = json_sprites
with open(OUTPUT_FILE_JSON, "w") as f:
f.write(json.dumps(sprite_set))
271 changes: 271 additions & 0 deletions scripts/standardLibSpriteParser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
import json
from collections import OrderedDict
import os
import glob

STANDARD_LIB_FOLDER = "../../plantuml-stdlib/stdlib"
STANDARD_LIB_FOLDER_URL = "https://github.com/plantuml/plantuml-stdlib/tree/master/stdlib"

AWS_STANDARD_LIB_FOLDER = "/awslib14/"
AWS_OUTPUT_FILE_PATH = "../src/main/resources/sprites/aws_stdlib_sprites.json"

AZURE_STANDARD_LIB_FOLDER = "/azure/"
AZURE_OUTPUT_FILE_PATH = "../src/main/resources/sprites/azure_stdlib_sprites.json"

ELASTIC_STANDARD_LIB_FOLDER = "/elastic/"
ELASTIC_OUTPUT_FILE_PATH = "../src/main/resources/sprites/elastic_stdlib_sprites.json"

GCP_STANDARD_LIB_FOLDER = "/gcp/"
GCP_OUTPUT_FILE_PATH = "../src/main/resources/sprites/gcp_stdlib_sprites.json"

K8S_STANDARD_LIB_FOLDER = "/k8s/"
K8S_OUTPUT_FILE_PATH = "../src/main/resources/sprites/k8s_stdlib_sprites.json"

CLOUDINSIGHT_STANDARD_LIB_FOLDER = "/cloudinsight/"
CLOUDINSIGHT_OUTPUT_FILE_PATH = (
"../src/main/resources/sprites/cloudinsight_stdlib_sprites.json"
)


MATERIAL_STANDARD_LIB_FOLDER = "/material/"
MATERIAL_OUTPUT_FILE_PATH = "../src/main/resources/sprites/material_stdlib_sprites.json"

LOGOS_STANDARD_LIB_FOLDER = "/logos/"
LOGOS_OUTPUT_FILE_PATH = "../src/main/resources/sprites/logos_stdlib_sprites.json"

OFFICE_STANDARD_LIB_FOLDER = "/office/"
OFFICE_OUTPUT_FILE_PATH = "../src/main/resources/sprites/office_stdlib_sprites.json"

OSA_STANDARD_LIB_FOLDER = "/osa/"
OSA_OUTPUT_FILE_PATH = "../src/main/resources/sprites/osa_stdlib_sprites.json"

TUPADR3_STANDARD_LIB_FOLDER = "/tupadr3/"
TUPADR3_OUTPUT_FILE_PATH = "../src/main/resources/sprites/tupadr3_stdlib_sprites.json"

# violet
AWS_COLOR_NEBULA = "#C925D1"
# green
AWS_COLOR_ENDOR = "#7AA116"
# orange
AWS_COLOR_SMILE = "#ED7100"
# pink
AWS_COLOR_COSMOS = "#E7157B"
# purple
AWS_COLOR_GALAXY = "#8C4FFF"
# red
AWS_COLOR_MARS = "#DD344C"
# turquoise
AWS_COLOR_ORBIT = "#01A88D"
# Default (blue)
AWS_COLOR_SQUID = "#232F3E"


def elastic_name_function(path):
name = path.replace("/", "-")
deduplicated_name = "-".join(OrderedDict.fromkeys(name.split("-")))
return deduplicated_name.replace("_", "-")


def default_name_function(path):
return path.replace("/", "-").replace("_", "-")


def k8s_name_function(path):
return default_name_function(path).replace("OSS-", "")


def aws_name_function(path):
return default_name_function(path).replace("lib14", "")


def aws_color_by_group(group):
color = AWS_COLOR_SQUID
if group in ["Customer", "Enablement", "Database", "DeveloperTools", "Satellite"]:
color = AWS_COLOR_NEBULA
elif group in ["CloudFinancialManagement", "InternetOfThings", "Storage"]:
color = AWS_COLOR_ENDOR
elif group in [
"Blockchain",
"Compute",
"Containers",
"Media Services",
"QuantumTechnologies",
]:
color = AWS_COLOR_SMILE
elif group in ["ApplicationIntegration", "ManagementGovernance"]:
color = AWS_COLOR_COSMOS
elif group in ["Analytics", "Games", "NetworkingContentDelivery", "Serverless"]:
color = AWS_COLOR_GALAXY
elif group in [
"BusinessApplications",
"ContactCenter",
"FrontEndWebMobile",
"Robotics",
"Security",
"Identity",
"Compliance",
]:
color = AWS_COLOR_MARS
elif group in ["EndUserComputing", "MachineLearning", "MigrationTransfer"]:
color = AWS_COLOR_ORBIT
return color


def write_sprite_set(
output_file,
sprite_set_name,
sprite_set_source,
json_sprites,
additional_includes,
):
with open(output_file, "w") as f:
sprite_set = {}
sprite_set["name"] = sprite_set_name
sprite_set["source"] = sprite_set_source
if additional_includes:
sprite_set["additionalIncludes"] = additional_includes
sprite_set["sprites"] = json_sprites
f.write(json.dumps(sprite_set))


def create_sprites(
paths,
color_function,
name_function,
reference_function
):
json_sprites = []
for path in paths:
category = path.split("/")[1]
sprite = {}
sprite["@type"] = "PlantUmlSprite"
sprite["name"] = name_function(path)
sprite["path"] = "<" + path + ">"
if reference_function:
sprite["reference"] = reference_function(path)
if color_function:
sprite["color"] = color_function(category)
json_sprites.append(sprite)
return json_sprites


def parse_paths(path_to_icon_folder, fileending):
paths = []
for full_path in glob.iglob(
path_to_icon_folder + "**/**/*[!LARGE|all]*" + fileending, recursive=True
):
relativ_path = full_path.replace(STANDARD_LIB_FOLDER, "")
norm_path = os.path.normpath(relativ_path)
icon_path = norm_path.replace(os.sep, "/").replace(fileending, "")
paths.append(icon_path[1:])
return paths


def process_sprite_folder(
sprite_source_folder,
output_file,
sprite_set_name,
sprite_fileending=".puml",
additional_includes=None,
color_function=None,
name_function=default_name_function,
reference_function=None
):
paths = parse_paths(STANDARD_LIB_FOLDER+sprite_source_folder, sprite_fileending)
json_sprites = create_sprites(
paths=paths,
color_function=color_function,
name_function=name_function,
reference_function=reference_function
)
write_sprite_set(
output_file=output_file,
sprite_set_name=sprite_set_name,
sprite_set_source=STANDARD_LIB_FOLDER_URL+sprite_source_folder,
json_sprites=json_sprites,
additional_includes=additional_includes,
)


if __name__ == "__main__":
process_sprite_folder(
sprite_source_folder=AWS_STANDARD_LIB_FOLDER,
output_file=AWS_OUTPUT_FILE_PATH,
sprite_set_name="AWS plantuml-stdlib Sprites",
additional_includes=["<awslib14/AWSCommon>"],
color_function=aws_color_by_group,
name_function=aws_name_function,
)

process_sprite_folder(
sprite_source_folder=AZURE_STANDARD_LIB_FOLDER,
output_file=AZURE_OUTPUT_FILE_PATH,
sprite_set_name="Azure plantuml-stdlib Sprites",
additional_includes=["<azure/AzureCommon>"],
color_function=lambda _: "#0072C6",
)

process_sprite_folder(
sprite_source_folder=ELASTIC_STANDARD_LIB_FOLDER,
output_file=ELASTIC_OUTPUT_FILE_PATH,
sprite_set_name="Elastic plantuml-stdlib Sprites",
color_function=lambda _: "#51D0C8",
sprite_fileending="-sprite.puml",
name_function=elastic_name_function,
)

process_sprite_folder(
sprite_source_folder=GCP_STANDARD_LIB_FOLDER,
output_file=GCP_OUTPUT_FILE_PATH,
sprite_set_name="Google Cloud Platform plantuml-stdlib Sprites",
additional_includes=["<gcp/GCPCommon>"],
color_function=lambda _: "#79B3FE",
)

process_sprite_folder(
sprite_source_folder=K8S_STANDARD_LIB_FOLDER,
output_file=K8S_OUTPUT_FILE_PATH,
sprite_set_name="Kubernetes plantuml-stdlib Sprites",
additional_includes=["<k8s/Common>"],
color_function=lambda _: "#66ABDD",
name_function=k8s_name_function,
)

process_sprite_folder(
sprite_source_folder=CLOUDINSIGHT_STANDARD_LIB_FOLDER,
output_file=CLOUDINSIGHT_OUTPUT_FILE_PATH,
sprite_set_name="Cloudinsight plantuml-stdlib Sprites",
color_function=lambda _: "#23a3dd",
)

process_sprite_folder(
sprite_source_folder=MATERIAL_STANDARD_LIB_FOLDER,
output_file=MATERIAL_OUTPUT_FILE_PATH,
sprite_set_name="Google Material plantuml-stdlib Sprites",
reference_function=lambda path: "ma_"+path.split("/")[-1]
)

process_sprite_folder(
sprite_source_folder=LOGOS_STANDARD_LIB_FOLDER,
output_file=LOGOS_OUTPUT_FILE_PATH,
sprite_set_name="Logos plantuml-stdlib Sprites",
)

process_sprite_folder(
sprite_source_folder=OFFICE_STANDARD_LIB_FOLDER,
output_file=OFFICE_OUTPUT_FILE_PATH,
sprite_set_name="Office plantuml-stdlib Sprites",
)

process_sprite_folder(
sprite_source_folder=OSA_STANDARD_LIB_FOLDER,
output_file=OSA_OUTPUT_FILE_PATH,
sprite_set_name="Open Security Architecture plantuml-stdlib Sprites",
sprite_fileending="-sprite.puml",
)

process_sprite_folder(
sprite_source_folder=TUPADR3_STANDARD_LIB_FOLDER,
output_file=TUPADR3_OUTPUT_FILE_PATH,
sprite_set_name="TUPADR3 plantuml-stdlib Sprites",
)
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package com.github.chriskn.structurizrextension.api.icons

import com.github.chriskn.structurizrextension.api.view.style.sprite.PUmlSprite
import java.net.MalformedURLException
import java.net.URI
import java.net.URL

internal const val AWS_ICON_URL = "https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v11.1/dist/"
internal const val AWS_ICON_URL = "https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v18.0/dist/"
internal const val AWS_ICON_COMMONS = "${AWS_ICON_URL}AWSCommon.puml"

// TODO deprecate
/**
* Registry containing the available icons.
*
Expand Down Expand Up @@ -36,7 +34,7 @@ object IconRegistry {
}

internal fun validate(name: String, url: String) {
require(name.isNotBlank()) { "Icon name cannot be blank" }
require(name.isNotBlank()) { "Icon name must not be blank" }
require(url.endsWith(PUML_FILE_EXTENSION)) {
"Icon URL needs to point to .puml file but was $url"
}
Expand All @@ -56,7 +54,7 @@ object IconRegistry {
/**
* @return The file name of an icon with the given name (case-insensitive) or null if no icon with the given name exists.
*/
@Deprecated("use spriteForName instead")
@Deprecated("use sprite API instead")
internal fun iconFileNameFor(name: String?): String? {
return if (name == null || !exists(name)) {
null
Expand All @@ -69,22 +67,6 @@ object IconRegistry {
}
}

/**
* @param name the name of the sprite
* @return the PumlSprite for a given name or null if no sprites exists
*/
internal fun spriteForName(name: String?): PUmlSprite? {
if (name == null || !exists(name)) {
return null
}
val url = iconNameToIconUrl[name.lowercase()]
val iconFileName = iconFileNameFor(name)
if (url == null || iconFileName == null) {
return null
}
return PUmlSprite(name = iconFileName, url = url.toString())
}

internal fun reset() {
iconNameToIconUrl.clear()
iconNameToIconUrl.putAll(commonIcons.mapValues { URI(it.value).toURL() })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.chriskn.structurizrextension.api.model

import com.github.chriskn.structurizrextension.api.icons.IconRegistry
import com.github.chriskn.structurizrextension.api.view.style.sprite.Sprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.Sprite
import com.structurizr.model.Component
import com.structurizr.model.Container
import com.structurizr.model.StaticStructureElement
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.chriskn.structurizrextension.api.model

import com.github.chriskn.structurizrextension.api.icons.IconRegistry
import com.github.chriskn.structurizrextension.api.view.style.sprite.Sprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.Sprite
import com.structurizr.model.Element
import com.structurizr.model.InteractionStyle

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.chriskn.structurizrextension.api.model

import com.github.chriskn.structurizrextension.api.icons.IconRegistry
import com.github.chriskn.structurizrextension.api.view.style.sprite.Sprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.Sprite
import com.structurizr.model.Container
import com.structurizr.model.DeploymentElement
import com.structurizr.model.DeploymentNode
Expand Down
Loading

0 comments on commit 5bfa30b

Please sign in to comment.