diff --git a/.gitignore b/.gitignore index d2eac58..c498442 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .gocache/ java/ gliffy2drawio +server sample*.drawio sample*.gliffy .DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..947f7a4 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +## About +AI generated code, both command line and simple REST API. Converts a supplied gliffy diagram to draw.io format. \ No newline at end of file diff --git a/cmd/server/main.go b/cmd/server/main.go index 1713032..44e14f1 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -7,7 +7,9 @@ import ( "io" "log" "net/http" + "net/url" "strings" + "time" gliffy2drawio "gliffy2drawio" ) @@ -16,32 +18,106 @@ const ( maxUploadSize = 10 << 20 // 10MB ) +var diagramStore = struct { + data map[string]string +}{ + data: make(map[string]string), +} + var uploadTpl = template.Must(template.New("upload").Parse(` - + - + + Gliffy β†’ draw.io Converter -
-

Gliffy β†’ draw.io Converter

-
- - -
- -
-

API docs: Swagger UI

+
+

Gliffy β†’ draw.io Converter

+

Upload a .gliffy (zip) or .gon JSON file. Convert to .drawio, or open directly in diagrams.net.

+ +
+
+
+ Drag & drop your Gliffy file here
+ …or choose a file. +
+ + + +
+
+
+ + +
+ +

API docs: Swagger UI

+
+ + `)) @@ -59,9 +135,11 @@ func main() { mux := http.NewServeMux() mux.HandleFunc("/", uploadHandler) mux.HandleFunc("/convert", uploadConvertHandler) + mux.HandleFunc("/open", uploadOpenHandler) mux.HandleFunc("/api/convert", apiConvertHandler) mux.HandleFunc("/openapi.json", openAPISpecHandler) mux.HandleFunc("/swagger", swaggerUIHandler) + mux.HandleFunc("/diagram", diagramHandler) addr := ":8080" log.Printf("Server listening on %s", addr) @@ -118,6 +196,46 @@ func uploadConvertHandler(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte(xml)) } +func uploadOpenHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + return + } + log.Printf("[open] %s %s from %s", r.Method, r.URL.Path, r.RemoteAddr) + + r.Body = http.MaxBytesReader(w, r.Body, maxUploadSize) + if err := r.ParseMultipartForm(maxUploadSize); err != nil { + http.Error(w, "failed to parse form: "+err.Error(), http.StatusBadRequest) + return + } + file, _, err := r.FormFile("file") + if err != nil { + http.Error(w, "missing file: "+err.Error(), http.StatusBadRequest) + return + } + defer file.Close() + data, err := io.ReadAll(file) + if err != nil { + http.Error(w, "failed to read file: "+err.Error(), http.StatusInternalServerError) + return + } + + xml, warn, err := convert(string(data)) + if err != nil { + log.Printf("[open] conversion failed: %v", err) + http.Error(w, "conversion failed: "+err.Error(), http.StatusBadRequest) + return + } + if warn != "" { + log.Printf("[open] conversion warning: %s", warn) + } + + id := storeDiagram(xml) + targetURL := buildDiagramsNetURL(r, id) + log.Printf("[open] redirecting to %s", targetURL) + http.Redirect(w, r, targetURL, http.StatusFound) +} + func apiConvertHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) @@ -176,6 +294,37 @@ func openAPISpecHandler(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte(openAPISpec)) } +func diagramHandler(w http.ResponseWriter, r *http.Request) { + id := r.URL.Query().Get("id") + if id == "" { + http.Error(w, "missing id", http.StatusBadRequest) + return + } + xml, ok := diagramStore.data[id] + if !ok { + http.Error(w, "not found", http.StatusNotFound) + return + } + w.Header().Set("Content-Type", "application/xml") + _, _ = w.Write([]byte(xml)) +} + +func storeDiagram(xml string) string { + now := time.Now().UnixNano() + id := fmt.Sprintf("diag-%d", now) + diagramStore.data[id] = xml + return id +} + +func buildDiagramsNetURL(r *http.Request, id string) string { + scheme := "http" + if r.Header.Get("X-Forwarded-Proto") == "https" || r.TLS != nil { + scheme = "https" + } + base := fmt.Sprintf("%s://%s/diagram?id=%s", scheme, r.Host, url.QueryEscape(id)) + return "https://app.diagrams.net/?splash=0&ui=min&url=" + url.QueryEscape(base) +} + func swaggerUIHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) diff --git a/server b/server deleted file mode 100755 index 46c2553..0000000 Binary files a/server and /dev/null differ