Initial commit
This commit is contained in:
commit
e061b14eec
10
Dockerfile
Normal file
10
Dockerfile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
FROM jess/inkscape
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y python-lxml python-numpy
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
RUN apt-get update && apt-get install -y golang
|
||||||
|
ADD main.go .
|
||||||
|
RUN go build -o main main.go
|
||||||
|
|
||||||
|
ENTRYPOINT ["/app/main"]
|
19
LICENSE
Normal file
19
LICENSE
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
MIT License Copyright (c) 2020 - present Marcus Noble
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice (including the next
|
||||||
|
paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||||
|
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||||
|
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
61
Makefile
Normal file
61
Makefile
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
.DEFAULT_GOAL := default
|
||||||
|
|
||||||
|
IMAGE ?= docker.cluster.fun/averagemarcus/svg-to-dxf:latest
|
||||||
|
|
||||||
|
.PHONY: test # Run all tests, linting and format checks
|
||||||
|
test: lint check-format run-tests
|
||||||
|
|
||||||
|
.PHONY: lint # Perform lint checks against code
|
||||||
|
lint:
|
||||||
|
@echo "⚠️ 'lint' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: check-format # Checks code formatting and returns a non-zero exit code if formatting errors found
|
||||||
|
check-format:
|
||||||
|
@echo "⚠️ 'check-format' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: format # Performs automatic format fixes on all code
|
||||||
|
format:
|
||||||
|
@echo "⚠️ 'format' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: run-tests # Runs all tests
|
||||||
|
run-tests:
|
||||||
|
@echo "⚠️ 'run-tests' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: fetch-deps # Fetch all project dependencies
|
||||||
|
fetch-deps:
|
||||||
|
@echo "⚠️ 'fetch-deps' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: build # Build the project
|
||||||
|
build: lint check-format fetch-deps
|
||||||
|
@echo "⚠️ 'build' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: docker-build # Build the docker image
|
||||||
|
docker-build:
|
||||||
|
@docker build build --tag $(IMAGE) .
|
||||||
|
|
||||||
|
.PHONY: docker-publish # Push the docker image to the remote registry
|
||||||
|
docker-publish:
|
||||||
|
@docker push $(IMAGE)
|
||||||
|
|
||||||
|
.PHONY: run # Run the application
|
||||||
|
run:
|
||||||
|
@echo "⚠️ 'run' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: ci # Perform CI specific tasks to perform on a pull request
|
||||||
|
ci:
|
||||||
|
@echo "⚠️ 'ci' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: release # Release the latest version of the application
|
||||||
|
release:
|
||||||
|
@echo "⚠️ 'release' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: help # Show this list of commands
|
||||||
|
help:
|
||||||
|
@echo "svg-to-dxf"
|
||||||
|
@echo "Usage: make [target]"
|
||||||
|
@echo ""
|
||||||
|
@echo "target description" | expand -t20
|
||||||
|
@echo "-----------------------------------"
|
||||||
|
@grep '^.PHONY: .* #' Makefile | sed 's/\.PHONY: \(.*\) # \(.*\)/\1 \2/' | expand -t20
|
||||||
|
|
||||||
|
default: test build
|
37
README.md
Normal file
37
README.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# svg-to-dxf
|
||||||
|
|
||||||
|
Convert .svg files to .dxf
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
Runs a webserver that takes in an `?url=` query string, fetches the SVG from that URL and then returns it as a .dxf
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker run -it --rm -p 8080:8080 docker.cluster.fun/averagemarcus/svg-to-dxf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building from source
|
||||||
|
|
||||||
|
With Docker:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make docker-build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
* [inkscape](https://inkscape.org/)
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
If you find a bug or have an idea for a new feature please raise an issue to discuss it.
|
||||||
|
|
||||||
|
Pull requests are welcomed but please try and follow similar code style as the rest of the project and ensure all tests and code checkers are passing.
|
||||||
|
|
||||||
|
Thank you 💛
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
See [LICENSE](LICENSE)
|
92
main.go
Normal file
92
main.go
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
var port = os.Getenv("PORT")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if port == "" {
|
||||||
|
port = "8080"
|
||||||
|
}
|
||||||
|
|
||||||
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
svgURL := r.URL.Query().Get("url")
|
||||||
|
if svgURL == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Fetching " + svgURL)
|
||||||
|
|
||||||
|
filename := "/app/" + randomString(7) + ".svg"
|
||||||
|
|
||||||
|
fmt.Println("Filename: " + filename)
|
||||||
|
if err := downloadFile(svgURL, filename); err != nil {
|
||||||
|
fmt.Fprintf(w, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Downloaded SVG")
|
||||||
|
|
||||||
|
dxf, err := convertToDXF(filename)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(w, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Converted to DXF")
|
||||||
|
|
||||||
|
w.Header().Add("Content-Type", "application/octet-stream")
|
||||||
|
w.Header().Add("Content-Length", fmt.Sprint(len(dxf)))
|
||||||
|
w.Header().Add("Content-Disposition", "inline; filename=out.dxf")
|
||||||
|
fmt.Fprintf(w, string(dxf))
|
||||||
|
|
||||||
|
os.Remove(filename)
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(http.ListenAndServe(":"+port, nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func downloadFile(URL, fileName string) error {
|
||||||
|
response, err := http.Get(URL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
if response.StatusCode != 200 {
|
||||||
|
return errors.New("Received non 200 response code")
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(file, response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertToDXF(filename string) ([]byte, error) {
|
||||||
|
cmd := exec.Command("python", "/usr/share/inkscape/extensions/dxf_outlines.py", filename)
|
||||||
|
return cmd.Output()
|
||||||
|
}
|
||||||
|
|
||||||
|
func randomString(n int) string {
|
||||||
|
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||||
|
|
||||||
|
s := make([]rune, n)
|
||||||
|
for i := range s {
|
||||||
|
s[i] = letters[rand.Intn(len(letters))]
|
||||||
|
}
|
||||||
|
return string(s)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user