Skip to content

Commit

Permalink
add downloader script, improve readme
Browse files Browse the repository at this point in the history
  • Loading branch information
pafo committed Apr 20, 2024
1 parent 0d55a15 commit aeee85c
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 836 deletions.
54 changes: 52 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,35 +113,85 @@ For strings... This is a little bit more complicated, In AWS package they are us

For numbers... It's similar to strings, Right now you cannot create plots with integer/float numbers with 0 value. I've only encounter problems when trying to remove the margin and can be workaround with an small value like `0.001`. I would like to avoid using interface{} or defining types again to keep the package interface as simple as possible.

### Go Plotly Update to plotly version v2.29.0
### Go Plotly Update to any json schema version

#### Method 1) Get schema files with script

> [!TIP]
> Use this script for easier download of plotly json schemas.
> ```shell
> go run generator/cmd/downloader/main.go -version=v2.29.0 -p
> ```
> And then clean up the generated files in **graph_objects** folder and regenerate the new graph objects. DO NOT REMOVE **graph_objects/plotly.go**:
> ```shell
> rm -f graph_objects/*_gen.go
> go run generator/cmd/generator/main.go -schema=plotly-schema-v2.29.0_ready_for_gen.json -output-directory=graph_objects
> ```
This script will save a file, which then can be used by the generator. It downloads the schema file directly from the plotly.js repository and adjusts its content.
When using the `-p` flag, the script also removes whitespace and new line characters.
#### Method 2) Get schema files manually from the repository
The Schema has to be of the format as defined in:
https://api.plot.ly/v2/plot-schema?format=json&sha1=%27%27
However, the version in this file is often not updated.
Download the latest plotly schema from the plotly repository:
Download the json file of the version you need from the original plotly.js repo under:
https://github.com/plotly/plotly.js
Example:
The plot-schema.json file for the latest version can be found under:
https://github.com/plotly/plotly.js/blob/master/dist/plot-schema.json
```json
{"sha1": "11b662302a42aa0698df091a9974ac8f6e1a2292","modified": true,"schema": "<INSERT NEW SCHEMA HERE>"}
```
> [!CAUTION]
> Do not add extra lines in your schema json. This can break the golang code generation.
Save this file as your new schema file and use it as input to regenerate your library.
The library should be in graph_objects to overwrite the old types, and to be in the same folder as plotly.go.

When you paste the schema, please take care not to add any extra lines in long text fields such as "description".
This can have a negative impact on the code generation, and the code generator may not
recognize the following lines have to be commented out, thereby producing invalid golang code.

This is also the reason why the placeholder above is kept in a single line, as this issue will not happen
if you guarantee that you json is a compact single line json.

#### Command

```shell
go run generator/cmd/generator/main.go -schema=generator/schema.json -output-directory=graph_objects
```

#### Missing Files?

if in doubt whether all types and traces have been generated, you can use the jsonviewer tool to introspect the json:
https://jsonviewer.stack.hu/

Or use `jq` tool for quick introspection into the json files.
Example:
Display all traces in the schema.json file.
```shell
jq '.schema.traces | keys' schema.json --sort-keys | less
```

More on the `jq` tool on: https://jqlang.github.io/jq/manual/

### plotly online editor sandbox
http://plotly-json-editor.getforge.io/

## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=Metalblueberry/go-plotly&type=Date)](https://star-history.com/#Metalblueberry/go-plotly&Date)

## Update Notes:

### Update to Version 2.29.0
#### Removed and new generated objects
- REMOVED: area
- ADDED: icicle, scattersmith
#### Release Notes
For detailed changes please follow the release notes of the original JS repo: https://github.com/plotly/plotly.js/releases
196 changes: 196 additions & 0 deletions generator/cmd/downloader/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package main

import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io"
"net/http"
"os"
"strings"
)

// Tag represents a git tag content
type Tag struct {
Name string `json:"name"`
ZipballURL string `json:"zipball_url"`
TarballURL string `json:"tarball_url"`
Commit struct {
SHA string `json:"sha"`
URL string `json:"url"`
} `json:"commit"`
NodeID string `json:"node_id"`
}

// getSchemaUrl returns the url to 'plot-schema.json' for the given version saved in the plotly.js repo
func getSchemaUrl(version string) string {
return fmt.Sprintf("https://raw.githubusercontent.com/plotly/plotly.js/%s/test/plot-schema.json", version)
}

// downloadSchema gets the schema file for a given version, and either saves the raw content,
// or prepares the file for the generator if prep is set to true
func downloadSchema(version string, prep bool) error {
schemaURL := getSchemaUrl(version)

// Make GET request to download schema
response, err := http.Get(schemaURL)
if err != nil {
return err
}
if response.StatusCode != http.StatusOK {
return fmt.Errorf("could not schema file for version: %s\n[Status Code: %d (%s)]\nused url: %s\nlist the available tags first and recheck", version, response.StatusCode, response.Status, schemaURL)
}
defer response.Body.Close()

// Read and decode JSON content
var jsonData interface{}
err = json.NewDecoder(response.Body).Decode(&jsonData)
if err != nil {
return err
}

// Re-encode JSON content with minimized whitespace and no new lines
var buf bytes.Buffer
encoder := json.NewEncoder(&buf)
encoder.SetIndent("", "")
err = encoder.Encode(jsonData)
if err != nil {
return err
}

// Remove newline character from the end of the encoded JSON
buf.Truncate(buf.Len() - 1)

// Create file to save the schema
var filename string
if prep {
filename = fmt.Sprintf("plotly-schema-%s_ready_for_gen.json", version)
} else {
filename = fmt.Sprintf("plotly-schema-%s_raw.json", version)
}

_, err = os.Stat(filename)
if err == nil {
fmt.Printf("WARN: overwriting: %s\n", filename)
}
file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()

// Copy response body to file
fmt.Printf("Downloading %s -> %s [adjusted for generator: %t]\n", schemaURL, filename, prep)
if prep {
_, err = file.Write([]byte(`{"sha1":"11b662302a42aa0698df091a9974ac8f6e1a2292","modified":true,"schema":`))
if err != nil {
return err
}
}
// Write JSON content to file
_, err = io.Copy(file, &buf)
if err != nil {
return err
}
if prep {
_, err = file.Write([]byte(`}`))
if err != nil {
return err
}
}

fmt.Println("Schema downloaded and saved as", filename)
return nil
}

// getTags lists the git tags of the plotly repo, for which a schema file can be downloaded and go files can be generated
func getTags() ([]Tag, error) {
const url = "https://api.github.com/repos/plotly/plotly.js/tags"
// Make GET request
response, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("error making GET request. %w", err)
}
defer response.Body.Close()

// Decode JSON response
var tags []Tag
err = json.NewDecoder(response.Body).Decode(&tags)
if err != nil {
return nil, fmt.Errorf("error decoding JSON. %w", err)
}
return tags, nil
}

// printTags prints the name of given tags to std out.
func printTags(tags []Tag) {
// Print names of each entry
fmt.Println("Tags:")
var tagNames []string
for _, tag := range tags {
tagNames = append(tagNames, tag.Name)
}
fmt.Println(strings.Join(tagNames, `,`))
}

func printExamples() {
fmt.Println(`
Run with current working directory set to the project root.
Download 'v2.31.1' and Prepare it for use by the generator script:
go run generator/cmd/downloader/main.go -version=v2.31.1 -p
Check the url used to download 'v2.31.1':
go run generator/cmd/downloader/main.go -version=v2.31.1 -s
List available versions from the git tags:
go run generator/cmd/downloader/main.go -l`,
)
}

func main() {
// Define a flag for the version
flag.Usage()
versionPtr := flag.String("version", "v2.29.0", "version of Plotly.js")
listPtr := flag.Bool("l", false, "list available versions")
showPtr := flag.Bool("s", false, "only show schema url based on version - no download")
prepPtr := flag.Bool("p", false, "prepare 'schema.json' used by generator to great *_gen.go files.")
examplePtr := flag.Bool("u", false, "display usage examples.")
// Parse the command-line flags
flag.Parse()

if *examplePtr {
printExamples()
return
}

// if list flag is passed, only parse tags
if *listPtr {
tags, err := getTags()
if err != nil {
fmt.Println("error fetching versions:", err)
return
}
printTags(tags)
return
}

// Check if version flag is provided
if *versionPtr == "" {
fmt.Println("Please provide the version using -version flag.")
return
}

// If show is true, only the url to the schema has to be displayed, otherwise the content is downloaded
if *showPtr {
fmt.Println(getSchemaUrl(*versionPtr))
} else {
err := downloadSchema(*versionPtr, *prepPtr)
if err != nil {
fmt.Printf("error downloading the schema. %s", err)
return
}
}

}
2 changes: 1 addition & 1 deletion generator/schema.json

Large diffs are not rendered by default.

Loading

0 comments on commit aeee85c

Please sign in to comment.