Tweak content type determination for resource decoders

This commit is contained in:
Tomaž Jerman
2020-11-27 18:59:25 +01:00
parent 2586fb9c23
commit 851a9a7e11
5 changed files with 64 additions and 37 deletions
+13 -4
View File
@@ -5,12 +5,11 @@ import (
"context"
"encoding/csv"
"io"
"os"
"path/filepath"
"strings"
"github.com/cortezaproject/corteza-server/pkg/envoy"
"github.com/cortezaproject/corteza-server/pkg/envoy/resource"
"github.com/gabriel-vasile/mimetype"
)
type (
@@ -31,8 +30,18 @@ func Decoder() *decoder {
}
// CanDecodeFile determines if the file can be determined by this decoder
func (y *decoder) CanDecodeFile(i os.FileInfo) bool {
return strings.Trim(filepath.Ext(i.Name()), ".") == "csv"
func (y *decoder) CanDecodeFile(f io.Reader) bool {
_, ext, err := mimetype.DetectReader(f)
if err != nil {
return false
}
return y.CanDecodeExt(ext)
}
func (y *decoder) CanDecodeExt(ext string) bool {
pt := strings.Split(ext, ".")
return strings.TrimSpace(pt[len(pt)-1]) == "csv"
}
// Decode decodes the given io.Reader into a generic resource dataset
+14 -5
View File
@@ -14,7 +14,8 @@ import (
type (
decoder interface {
CanDecodeFile(os.FileInfo) bool
CanDecodeExt(string) bool
CanDecodeFile(io.Reader) bool
Decode(context.Context, io.Reader, *envoy.DecoderOpts) ([]resource.Interface, error)
}
)
@@ -46,22 +47,30 @@ func Decode(ctx context.Context, p string, decoders ...decoder) ([]resource.Inte
return nil
}
if f, err = os.Open(p); err != nil {
return err
}
defer f.Close()
for _, d = range decoders {
// find compatible decoder
if d.CanDecodeFile(info) {
if d.CanDecodeFile(f) {
break
}
// Do a fallback for extensions
if d.CanDecodeExt(info.Name()) {
break
}
}
if d == nil {
// no decoder found
return nil
}
if f, err = os.Open(p); err != nil {
_, err = f.Seek(0, 0)
if err != nil {
return err
}
defer f.Close()
dir, fn := path.Split(p)
do := &envoy.DecoderOpts{
+26 -4
View File
@@ -5,12 +5,12 @@ import (
"context"
"encoding/json"
"io"
"os"
"path/filepath"
"strings"
"github.com/cortezaproject/corteza-server/pkg/envoy"
"github.com/cortezaproject/corteza-server/pkg/envoy/resource"
"github.com/cortezaproject/corteza-server/pkg/mime"
"github.com/gabriel-vasile/mimetype"
)
type (
@@ -35,8 +35,30 @@ func Decoder() *decoder {
}
// CanDecodeFile determines if the file can be decoded by this decoder
func (d *decoder) CanDecodeFile(i os.FileInfo) bool {
return strings.Trim(filepath.Ext(i.Name()), ".") == "jsonl"
func (d *decoder) CanDecodeFile(f io.Reader) bool {
var buff bytes.Buffer
tr := io.TeeReader(f, &buff)
_, ext, err := mimetype.DetectReader(tr)
if err != nil {
return false
}
if ext == "txt" {
if is, err := mime.JsonL(&buff); err != nil {
return false
} else if is {
ext = "jsonl"
}
}
return d.CanDecodeExt(ext)
}
func (d *decoder) CanDecodeExt(ext string) bool {
pt := strings.Split(ext, ".")
ext = strings.TrimSpace(pt[len(pt)-1])
return ext == "jsonl" || ext == "json"
}
// Decode decodes the given io.Reader into a generic resource dataset
+9 -9
View File
@@ -3,8 +3,6 @@ package yaml
import (
"context"
"io"
"os"
"path/filepath"
"strings"
"github.com/cortezaproject/corteza-server/pkg/envoy"
@@ -29,16 +27,18 @@ func Decoder() *decoder {
return &decoder{}
}
// CanDecodeFile
func (y *decoder) CanDecodeFile(i os.FileInfo) bool {
switch strings.Trim(filepath.Ext(i.Name()), ".") {
case "yaml", "yml":
return true
}
// CanDecodeFile checks if the file can be handled by this decoder
//
// @todo Add support for this; current library is unable to detect this.
func (y *decoder) CanDecodeFile(f io.Reader) bool {
return false
}
func (y *decoder) CanDecodeExt(ext string) bool {
pt := strings.Split(ext, ".")
return strings.TrimSpace(pt[len(pt)-1]) == "yaml"
}
func (y *decoder) Decode(ctx context.Context, r io.Reader, dctx *envoy.DecoderOpts) ([]resource.Interface, error) {
var (
doc = &Document{}
+2 -15
View File
@@ -3,26 +3,13 @@ package mime
import (
"bufio"
"io"
"github.com/gabriel-vasile/mimetype"
)
func Type(file io.ReadSeeker) (mt string, ext string, err error) {
if _, err = file.Seek(0, 0); err != nil {
return
}
// Make sure we rewind when we're done
defer file.Seek(0, 0)
return mimetype.DetectReader(file)
}
func JsonL(file io.ReadSeeker) (bool, error) {
func JsonL(f io.Reader) (bool, error) {
// ExtractMimetype fails to detect json if jsonl is used
// For now check if first rune is {
r := bufio.NewReader(file)
r := bufio.NewReader(f)
rn, _, err := r.ReadRune()
defer file.Seek(0, 0)
if err != nil {
return false, err
}