mirror of
https://github.com/maputnik/editor.git
synced 2025-12-16 11:10:00 +00:00
Merge entire history from desktop repo to /desktop
Preserve history of the maputnik/desktop repository, but move related files to `/desktop` directory, and adjust the ci script to use it.
This commit is contained in:
52
.github/workflows/ci-desktop.yml
vendored
Normal file
52
.github/workflows/ci-desktop.yml
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
name: ci-desktop
|
||||||
|
|
||||||
|
on: [ push ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: ./desktop
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: 1.18
|
||||||
|
|
||||||
|
- name: Make
|
||||||
|
run: make
|
||||||
|
|
||||||
|
- name: Test --help
|
||||||
|
run: ./bin/linux/maputnik --help
|
||||||
|
|
||||||
|
- name: Test --version
|
||||||
|
run: ./bin/linux/maputnik --version
|
||||||
|
|
||||||
|
- name: Get style
|
||||||
|
run: wget https://maputnik.github.io/osm-liberty/style.json
|
||||||
|
|
||||||
|
- name: Test --watch
|
||||||
|
run: ./bin/linux/maputnik --watch --file style.json & sleep 5; kill $!
|
||||||
|
|
||||||
|
- name: Artifacts/linux
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: maputnik-linux
|
||||||
|
path: bin/linux/
|
||||||
|
|
||||||
|
- name: Artifacts/darwin
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: maputnik-darwin
|
||||||
|
path: bin/darwin/
|
||||||
|
|
||||||
|
- name: Artifacts/windows
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: maputnik-windows
|
||||||
|
path: bin/windows/
|
||||||
31
desktop/.gitignore
vendored
Normal file
31
desktop/.gitignore
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
editor
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*.prof
|
||||||
|
|
||||||
|
# Binary version of pubilic/editor
|
||||||
|
rice-box.go
|
||||||
|
|
||||||
|
# Built binary
|
||||||
|
maputnik
|
||||||
21
desktop/LICENSE
Normal file
21
desktop/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2016 Maputnik
|
||||||
|
|
||||||
|
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 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.
|
||||||
31
desktop/Makefile
Normal file
31
desktop/Makefile
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
SOURCEDIR=.
|
||||||
|
SOURCES := $(shell find $(SOURCEDIR) -name '*.go')
|
||||||
|
BINARY=maputnik
|
||||||
|
EDITOR_VERSION ?= v1.7.0
|
||||||
|
GOPATH := $(if $(GOPATH),$(GOPATH),$(HOME)/go)
|
||||||
|
GOBIN := $(if $(GOBIN),$(GOBIN),$(HOME)/go/bin)
|
||||||
|
|
||||||
|
all: $(BINARY)
|
||||||
|
|
||||||
|
$(BINARY): $(GOBIN)/gox $(SOURCES) rice-box.go
|
||||||
|
$(GOBIN)/gox -osarch "windows/amd64 linux/amd64 darwin/amd64" -output "bin/{{.OS}}/${BINARY}"
|
||||||
|
|
||||||
|
editor/create_folder:
|
||||||
|
mkdir -p editor
|
||||||
|
|
||||||
|
editor/pull_release: editor/create_folder
|
||||||
|
# if the directory /home/runner/work/editor/editor/build/build exists, we assume that we are are running the makefile within the editor ci workflow
|
||||||
|
test -d /home/runner/work/editor/editor/build/build && echo "exists" && cd editor && cp -R /home/runner/work/editor/editor/build/build public/ || (echo "does not exist" && cd editor && rm -rf public && curl -L https://github.com/maputnik/editor/releases/download/$(EDITOR_VERSION)/public.zip --output public.zip && unzip public.zip && rm public.zip)
|
||||||
|
|
||||||
|
$(GOBIN)/gox:
|
||||||
|
go install github.com/mitchellh/gox@v1.0.1
|
||||||
|
|
||||||
|
$(GOBIN)/rice:
|
||||||
|
go install github.com/GeertJohan/go.rice/rice@v1.0.3
|
||||||
|
|
||||||
|
rice-box.go: $(GOBIN)/rice editor/pull_release
|
||||||
|
$(GOBIN)/rice embed-go
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf editor/public && rm -f rice-box.go && rm -rf bin
|
||||||
78
desktop/README.md
Normal file
78
desktop/README.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# Maputnik Desktop [](https://github.com/maputnik/desktop/actions?query=workflow%3Aci)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
A Golang based cross platform executable for integrating Maputnik locally.
|
||||||
|
This binary packages up the JavaScript and CSS bundle produced by [maputnik/editor](https://github.com/maputnik/desktop)
|
||||||
|
and embeds it in the program for easy distribution. It also allows
|
||||||
|
exposing a local style file and work on it both in Maputnik and with your favorite
|
||||||
|
editor.
|
||||||
|
|
||||||
|
Report issues on [maputnik/editor](https://github.com/maputnik/editor).
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
You can download a single binary for Linux, OSX or Windows from [the latest releases of **maputnik/editor**](https://github.com/maputnik/editor/releases/latest).
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
Simply start up a web server and access the Maputnik editor GUI at `localhost:8000`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
maputnik
|
||||||
|
```
|
||||||
|
|
||||||
|
Expose a local style file to Maputnik allowing the web based editor
|
||||||
|
to save to the local filesystem.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
maputnik --file basic-v9.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Watch the local style for changes and inform the editor via web socket.
|
||||||
|
This makes it possible to edit the style with a local text editor and still
|
||||||
|
use Maputnik.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
maputnik --watch --file basic-v9.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Choose a local port to listen on, instead of using the default port 8000.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
maputnik --port 8001
|
||||||
|
```
|
||||||
|
|
||||||
|
Specify a path to a directory which, if it exists, will be served under http://localhost:8000/static/ .
|
||||||
|
Could be used to serve sprites and glyphs.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
maputnik --static ./localFolder
|
||||||
|
```
|
||||||
|
|
||||||
|
### API
|
||||||
|
|
||||||
|
`maputnik` exposes the configured styles via a HTTP API.
|
||||||
|
|
||||||
|
| Method | Description
|
||||||
|
|---------------------------------|---------------------------------------
|
||||||
|
| `GET /styles` | List the ID of all configured style files
|
||||||
|
| `GET /styles/{filename}` | Get contents of a single style file
|
||||||
|
| `PUT /styles/{filename}` | Update contents of a style file
|
||||||
|
| `WEBSOCKET /ws` | Listen to change events for the configured style files
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
Clone the repository. Make sure you clone it into the correct directory `$GOPATH/src/github.com/maputnik`.
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone git@github.com:maputnik/desktop.git
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `make` to install the 3rd party dependencies and build the `maputnik` binary embedding the editor.
|
||||||
|
|
||||||
|
```
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
You should now find the `maputnik` binary in your `bin` directory.
|
||||||
81
desktop/api.go
Normal file
81
desktop/api.go
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
func StyleFileAccessor(filename string) styleFileAccessor {
|
||||||
|
return styleFileAccessor{filename, styleId(filename)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func styleId(filename string) string {
|
||||||
|
raw, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var spec styleSpec
|
||||||
|
err = json.Unmarshal(raw, &spec)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if spec.Id == "" {
|
||||||
|
fmt.Println("No id in style")
|
||||||
|
}
|
||||||
|
return spec.Id
|
||||||
|
}
|
||||||
|
|
||||||
|
type styleSpec struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allows access to a single style file
|
||||||
|
type styleFileAccessor struct {
|
||||||
|
filename string
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fa styleFileAccessor) ListFiles(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
encoder := json.NewEncoder(w)
|
||||||
|
encoder.Encode([]string{fa.id})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fa styleFileAccessor) ReadFile(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
_ = vars["styleId"]
|
||||||
|
|
||||||
|
//TODO: Choose right file
|
||||||
|
// right now we just return the single file we know of
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
raw, err := ioutil.ReadFile(fa.filename)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicln(err)
|
||||||
|
}
|
||||||
|
w.Write(raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fa styleFileAccessor) SaveFile(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
_ = vars["styleId"]
|
||||||
|
|
||||||
|
//TODO: Save to right file
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
body, _ := ioutil.ReadAll(r.Body)
|
||||||
|
var out bytes.Buffer
|
||||||
|
json.Indent(&out, body, "", " ")
|
||||||
|
|
||||||
|
if err := ioutil.WriteFile(fa.filename, out.Bytes(), 0666); err != nil {
|
||||||
|
log.Fatalf("Can not copy from request to file: %s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
69
desktop/filewatch/filewatch.go
Normal file
69
desktop/filewatch/filewatch.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package filewatch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/fsnotify/fsnotify"
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
var upgrader = websocket.Upgrader{
|
||||||
|
ReadBufferSize: 1024,
|
||||||
|
WriteBufferSize: 1024,
|
||||||
|
CheckOrigin: func(r *http.Request) bool { return true },
|
||||||
|
}
|
||||||
|
|
||||||
|
func writer(ws *websocket.Conn, filename string) {
|
||||||
|
watcher, err := fsnotify.NewWatcher()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer watcher.Close()
|
||||||
|
|
||||||
|
done := make(chan bool)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case event := <-watcher.Events:
|
||||||
|
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||||
|
log.Println("Modified file:", event.Name)
|
||||||
|
var p []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
p, err = ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p != nil {
|
||||||
|
if err := ws.WriteMessage(websocket.TextMessage, p); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case err := <-watcher.Errors:
|
||||||
|
log.Println("Watch error:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err = watcher.Add(filename); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
<-done
|
||||||
|
}
|
||||||
|
|
||||||
|
func ServeWebsocketFileWatcher(filename string, w http.ResponseWriter, r *http.Request) {
|
||||||
|
ws, err := upgrader.Upgrade(w, r, nil)
|
||||||
|
if err != nil {
|
||||||
|
if _, ok := err.(websocket.HandshakeError); !ok {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
writer(ws, filename)
|
||||||
|
defer ws.Close()
|
||||||
|
}
|
||||||
27
desktop/go.mod
Normal file
27
desktop/go.mod
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
module maputnik/desktop
|
||||||
|
|
||||||
|
go 1.19
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/GeertJohan/go.rice v1.0.3
|
||||||
|
github.com/fsnotify/fsnotify v1.6.0
|
||||||
|
github.com/gorilla/handlers v1.5.1
|
||||||
|
github.com/gorilla/mux v1.8.0
|
||||||
|
github.com/gorilla/websocket v1.5.0
|
||||||
|
github.com/maputnik/desktop v1.0.7
|
||||||
|
github.com/urfave/cli v1.22.12
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/GeertJohan/go.incremental v1.0.0 // indirect
|
||||||
|
github.com/akavel/rsrc v0.8.0 // indirect
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||||
|
github.com/daaku/go.zipexe v1.0.2 // indirect
|
||||||
|
github.com/felixge/httpsnoop v1.0.1 // indirect
|
||||||
|
github.com/jessevdk/go-flags v1.4.0 // indirect
|
||||||
|
github.com/nkovacs/streamquote v1.0.0 // indirect
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
|
github.com/valyala/fasttemplate v1.0.1 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect
|
||||||
|
)
|
||||||
54
desktop/go.sum
Normal file
54
desktop/go.sum
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
|
github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg=
|
||||||
|
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
|
||||||
|
github.com/GeertJohan/go.rice v1.0.3 h1:k5viR+xGtIhF61125vCE1cmJ5957RQGXG6dmbaWZSmI=
|
||||||
|
github.com/GeertJohan/go.rice v1.0.3/go.mod h1:XVdrU4pW00M4ikZed5q56tPf1v2KwnIKeIdc9CBYNt4=
|
||||||
|
github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw=
|
||||||
|
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
|
github.com/daaku/go.zipexe v1.0.2 h1:Zg55YLYTr7M9wjKn8SY/WcpuuEi+kR2u4E8RhvpyXmk=
|
||||||
|
github.com/daaku/go.zipexe v1.0.2/go.mod h1:5xWogtqlYnfBXkSB1o9xysukNP9GTvaNkqzUZbt3Bw8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
|
||||||
|
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
|
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||||
|
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||||
|
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
|
||||||
|
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
|
||||||
|
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||||
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
||||||
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
|
github.com/maputnik/desktop v1.0.7 h1:rdFg7emIJOT3YsZpwqSChmWtMOvu+T4h6WwVQAZP9n4=
|
||||||
|
github.com/maputnik/desktop v1.0.7/go.mod h1:wmDjHUztx9jOBz0I22589yWguAGdV/sEM57YANpN8oQ=
|
||||||
|
github.com/nkovacs/streamquote v1.0.0 h1:PmVIV08Zlx2lZK5fFZlMZ04eHcDTIFJCv/5/0twVUow=
|
||||||
|
github.com/nkovacs/streamquote v1.0.0/go.mod h1:BN+NaZ2CmdKqUuTUXUEm9j95B2TRbpOWpxbJYzzgUsc=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8=
|
||||||
|
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
|
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
|
||||||
|
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||||
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY=
|
||||||
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
80
desktop/maputnik.go
Normal file
80
desktop/maputnik.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/GeertJohan/go.rice"
|
||||||
|
"github.com/gorilla/handlers"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/maputnik/desktop/filewatch"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := cli.NewApp()
|
||||||
|
app.Name = "maputnik"
|
||||||
|
app.Usage = "Server for integrating Maputnik locally"
|
||||||
|
app.Version = "Editor: 1.7.0; Desktop: 1.1.0"
|
||||||
|
|
||||||
|
app.Flags = []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "file, f",
|
||||||
|
Usage: "Allow access to JSON style from web client",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "watch",
|
||||||
|
Usage: "Notify web client about JSON style file changes",
|
||||||
|
},
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "port",
|
||||||
|
Value: 8000,
|
||||||
|
Usage: "TCP port to listen on",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "static",
|
||||||
|
Usage: "Serve directory under /static/",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
app.Action = func(c *cli.Context) error {
|
||||||
|
gui := http.FileServer(rice.MustFindBox("editor/public").HTTPBox())
|
||||||
|
|
||||||
|
router := mux.NewRouter().StrictSlash(true)
|
||||||
|
|
||||||
|
filename := c.String("file")
|
||||||
|
if filename != "" {
|
||||||
|
fmt.Printf("%s is accessible via Maputnik\n", filename)
|
||||||
|
// Allow access to reading and writing file on the local system
|
||||||
|
path, _ := filepath.Abs(filename)
|
||||||
|
accessor := StyleFileAccessor(path)
|
||||||
|
router.Path("/styles").Methods("GET").HandlerFunc(accessor.ListFiles)
|
||||||
|
router.Path("/styles/{styleId}").Methods("GET").HandlerFunc(accessor.ReadFile)
|
||||||
|
router.Path("/styles/{styleId}").Methods("PUT").HandlerFunc(accessor.SaveFile)
|
||||||
|
|
||||||
|
// Register websocket to notify we clients about file changes
|
||||||
|
if c.Bool("watch") {
|
||||||
|
router.Path("/ws").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
filewatch.ServeWebsocketFileWatcher(filename, w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
staticDir := c.String("static")
|
||||||
|
if staticDir != "" {
|
||||||
|
h := http.StripPrefix("/static/", http.FileServer(http.Dir(staticDir)))
|
||||||
|
router.PathPrefix("/static/").Handler(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
router.PathPrefix("/").Handler(http.StripPrefix("/", gui))
|
||||||
|
loggedRouter := handlers.LoggingHandler(os.Stdout, router)
|
||||||
|
corsRouter := handlers.CORS(handlers.AllowedHeaders([]string{"Content-Type"}), handlers.AllowedMethods([]string{"GET", "PUT"}), handlers.AllowedOrigins([]string{"*"}), handlers.AllowCredentials())(loggedRouter)
|
||||||
|
|
||||||
|
fmt.Printf("Exposing Maputnik on http://localhost:%d\n", c.Int("port"))
|
||||||
|
return http.ListenAndServe(fmt.Sprintf(":%d", c.Int("port")), corsRouter)
|
||||||
|
}
|
||||||
|
|
||||||
|
app.Run(os.Args)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user