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