summaryrefslogtreecommitdiffstats
path: root/resources
diff options
context:
space:
mode:
Diffstat (limited to 'resources')
-rw-r--r--resources/images/config.go15
-rw-r--r--resources/images/filters.go3
-rw-r--r--resources/postpub/fields_test.go1
-rw-r--r--resources/resource.go3
-rw-r--r--resources/resource_factories/create/remote.go30
-rw-r--r--resources/resource_spec.go37
6 files changed, 58 insertions, 31 deletions
diff --git a/resources/images/config.go b/resources/images/config.go
index c8990d5ca..a8b5412d6 100644
--- a/resources/images/config.go
+++ b/resources/images/config.go
@@ -20,6 +20,7 @@ import (
"strings"
"github.com/gohugoio/hugo/helpers"
+ "github.com/gohugoio/hugo/media"
"github.com/pkg/errors"
@@ -45,6 +46,15 @@ var (
".webp": WEBP,
}
+ imageFormatsBySubType = map[string]Format{
+ media.JPEGType.SubType: JPEG,
+ media.PNGType.SubType: PNG,
+ media.TIFFType.SubType: TIFF,
+ media.BMPType.SubType: BMP,
+ media.GIFType.SubType: GIF,
+ media.WEBPType.SubType: WEBP,
+ }
+
// Add or increment if changes to an image format's processing requires
// re-generation.
imageFormatsVersions = map[Format]int{
@@ -102,6 +112,11 @@ func ImageFormatFromExt(ext string) (Format, bool) {
return f, found
}
+func ImageFormatFromMediaSubType(sub string) (Format, bool) {
+ f, found := imageFormatsBySubType[sub]
+ return f, found
+}
+
const (
defaultJPEGQuality = 75
defaultResampleFilter = "box"
diff --git a/resources/images/filters.go b/resources/images/filters.go
index e166a0f9d..fd7e31457 100644
--- a/resources/images/filters.go
+++ b/resources/images/filters.go
@@ -66,6 +66,9 @@ func (*Filters) Text(text string, options ...interface{}) gift.Filter {
case "linespacing":
tf.linespacing = cast.ToInt(v)
case "font":
+ if err, ok := v.(error); ok {
+ panic(fmt.Sprintf("invalid font source: %s", err))
+ }
fontSource, ok1 := v.(hugio.ReadSeekCloserProvider)
identifier, ok2 := v.(resource.Identifier)
diff --git a/resources/postpub/fields_test.go b/resources/postpub/fields_test.go
index 19c3720f7..c408e7791 100644
--- a/resources/postpub/fields_test.go
+++ b/resources/postpub/fields_test.go
@@ -36,6 +36,7 @@ func TestCreatePlaceholders(t *testing.T) {
"Suffixes": "pre_foo.Suffixes_post",
"Delimiter": "pre_foo.Delimiter_post",
"FirstSuffix": "pre_foo.FirstSuffix_post",
+ "IsText": "pre_foo.IsText_post",
"String": "pre_foo.String_post",
"Type": "pre_foo.Type_post",
"MainType": "pre_foo.MainType_post",
diff --git a/resources/resource.go b/resources/resource.go
index 1f6246859..4bf35f9ac 100644
--- a/resources/resource.go
+++ b/resources/resource.go
@@ -69,6 +69,9 @@ type ResourceSourceDescriptor struct {
Fs afero.Fs
+ // Set when its known up front, else it's resolved from the target filename.
+ MediaType media.Type
+
// The relative target filename without any language code.
RelTargetFilename string
diff --git a/resources/resource_factories/create/remote.go b/resources/resource_factories/create/remote.go
index 53e77bc5e..f6d3f13dd 100644
--- a/resources/resource_factories/create/remote.go
+++ b/resources/resource_factories/create/remote.go
@@ -29,6 +29,7 @@ import (
"github.com/gohugoio/hugo/common/hugio"
"github.com/gohugoio/hugo/common/types"
"github.com/gohugoio/hugo/helpers"
+ "github.com/gohugoio/hugo/media"
"github.com/gohugoio/hugo/resources"
"github.com/gohugoio/hugo/resources/resource"
"github.com/mitchellh/mapstructure"
@@ -99,7 +100,7 @@ func (c *Client) FromRemote(uri string, optionsm map[string]interface{}) (resour
body, err := ioutil.ReadAll(res.Body)
if err != nil {
- return nil, errors.Wrapf(err, "failed to read remote resource %s", uri)
+ return nil, errors.Wrapf(err, "failed to read remote resource %q", uri)
}
filename := path.Base(rURL.Path)
@@ -109,33 +110,30 @@ func (c *Client) FromRemote(uri string, optionsm map[string]interface{}) (resour
}
}
- var extension string
+ var extensionHint string
+
if arr, _ := mime.ExtensionsByType(res.Header.Get("Content-Type")); len(arr) == 1 {
- extension = arr[0]
+ extensionHint = arr[0]
}
- // If extension was not determined by header, look for a file extention
- if extension == "" {
+ // Look for a file extention
+ if extensionHint == "" {
if ext := path.Ext(filename); ext != "" {
- extension = ext
+ extensionHint = ext
}
}
- // If extension was not determined by header or file extention, try using content itself
- if extension == "" {
- if ct := http.DetectContentType(body); ct != "application/octet-stream" {
- if ct == "image/jpeg" {
- extension = ".jpg"
- } else if arr, _ := mime.ExtensionsByType(ct); arr != nil {
- extension = arr[0]
- }
- }
+ // Now resolve the media type primarily using the content.
+ mediaType := media.FromContent(c.rs.MediaTypes, extensionHint, body)
+ if mediaType.IsZero() {
+ return nil, errors.Errorf("failed to resolve media type for remote resource %q", uri)
}
- resourceID = filename[:len(filename)-len(path.Ext(filename))] + "_" + resourceID + extension
+ resourceID = filename[:len(filename)-len(path.Ext(filename))] + "_" + resourceID + mediaType.FirstSuffix.FullSuffix
return c.rs.New(
resources.ResourceSourceDescriptor{
+ MediaType: mediaType,
LazyPublish: true,
OpenReadSeekCloser: func() (hugio.ReadSeekCloser, error) {
return hugio.NewReadSeekerNoOpCloser(bytes.NewReader(body)), nil
diff --git a/resources/resource_spec.go b/resources/resource_spec.go
index 897c1bbaa..cd1e5010d 100644
--- a/resources/resource_spec.go
+++ b/resources/resource_spec.go
@@ -272,21 +272,28 @@ func (r *Spec) newResource(sourceFs afero.Fs, fd ResourceSourceDescriptor) (reso
fd.RelTargetFilename = sourceFilename
}
- ext := strings.ToLower(filepath.Ext(fd.RelTargetFilename))
- mimeType, suffixInfo, found := r.MediaTypes.GetFirstBySuffix(strings.TrimPrefix(ext, "."))
- // TODO(bep) we need to handle these ambiguous types better, but in this context
- // we most likely want the application/xml type.
- if suffixInfo.Suffix == "xml" && mimeType.SubType == "rss" {
- mimeType, found = r.MediaTypes.GetByType("application/xml")
- }
+ mimeType := fd.MediaType
+ if mimeType.IsZero() {
+ ext := strings.ToLower(filepath.Ext(fd.RelTargetFilename))
+ var (
+ found bool
+ suffixInfo media.SuffixInfo
+ )
+ mimeType, suffixInfo, found = r.MediaTypes.GetFirstBySuffix(strings.TrimPrefix(ext, "."))
+ // TODO(bep) we need to handle these ambiguous types better, but in this context
+ // we most likely want the application/xml type.
+ if suffixInfo.Suffix == "xml" && mimeType.SubType == "rss" {
+ mimeType, found = r.MediaTypes.GetByType("application/xml")
+ }
- if !found {
- // A fallback. Note that mime.TypeByExtension is slow by Hugo standards,
- // so we should configure media types to avoid this lookup for most
- // situations.
- mimeStr := mime.TypeByExtension(ext)
- if mimeStr != "" {
- mimeType, _ = media.FromStringAndExt(mimeStr, ext)
+ if !found {
+ // A fallback. Note that mime.TypeByExtension is slow by Hugo standards,
+ // so we should configure media types to avoid this lookup for most
+ // situations.
+ mimeStr := mime.TypeByExtension(ext)
+ if mimeStr != "" {
+ mimeType, _ = media.FromStringAndExt(mimeStr, ext)
+ }
}
}
@@ -301,7 +308,7 @@ func (r *Spec) newResource(sourceFs afero.Fs, fd ResourceSourceDescriptor) (reso
mimeType)
if mimeType.MainType == "image" {
- imgFormat, ok := images.ImageFormatFromExt(ext)
+ imgFormat, ok := images.ImageFormatFromMediaSubType(mimeType.SubType)
if ok {
ir := &imageResource{
Image: images.NewImage(imgFormat, r.imaging, nil, gr),