-
Notifications
You must be signed in to change notification settings - Fork 0
/
sourcedescriptor.go
153 lines (124 loc) · 3.99 KB
/
sourcedescriptor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package valueobject
import (
"errors"
"github.com/gohugonet/hugoverse/internal/domain/resources"
"github.com/gohugonet/hugoverse/pkg/identity"
"github.com/gohugonet/hugoverse/pkg/io"
"github.com/gohugonet/hugoverse/pkg/media"
"github.com/gohugonet/hugoverse/pkg/paths"
"mime"
)
type ResourceSourceDescriptor struct {
// The source Content.
OpenReadSeekCloser io.OpenReadSeekCloser
// The canonical source path.
Path *paths.Path
// The normalized name of the resource.
NameNormalized string
// The name of the resource as it was read from the source.
NameOriginal string
// Any base paths prepended to the target path. This will also typically be the
// language code, but setting it here means that it should not have any effect on
// the permalink.
// This may be several values. In multihost mode we may publish the same resources to
// multiple targets.
TargetBasePaths []string
TargetPath string
BasePathRelPermalink string
BasePathTargetPath string
// The Data to associate with this resource.
Data map[string]any
// Delay publishing until either Permalink or RelPermalink is called. Maybe never.
LazyPublish bool
// Set when its known up front, else it's resolved from the target filename.
MediaType media.Type
// Used to track dependencies (e.g. imports). May be nil if that's of no concern.
DependencyManager identity.Manager
// A shared identity for this resource and all its clones.
// If this is not set, an Identity is created.
GroupIdentity identity.Identity
}
func NewResourceSourceDescriptor(
pathname string,
path *paths.Path,
mediaService resources.MediaTypesConfig,
openReadSeekCloser io.OpenReadSeekCloser) (*ResourceSourceDescriptor, error) {
sd := &ResourceSourceDescriptor{
LazyPublish: true,
OpenReadSeekCloser: openReadSeekCloser,
Path: path,
GroupIdentity: path,
TargetPath: pathname,
Data: make(map[string]any),
}
if err := sd.setup(mediaService); err != nil {
return nil, err
}
return sd, nil
}
func (fd *ResourceSourceDescriptor) setup(mediaService resources.MediaTypesConfig) error {
if fd.OpenReadSeekCloser == nil {
panic(errors.New("OpenReadSeekCloser is nil"))
}
if fd.TargetPath == "" {
panic(errors.New("RelPath is empty"))
}
if fd.Path == nil {
fd.Path = paths.Parse("", fd.TargetPath)
}
if fd.TargetPath == "" {
fd.TargetPath = fd.Path.Path()
} else {
fd.TargetPath = paths.ToSlashPreserveLeading(fd.TargetPath)
}
fd.BasePathRelPermalink = paths.ToSlashPreserveLeading(fd.BasePathRelPermalink)
if fd.BasePathRelPermalink == "/" {
fd.BasePathRelPermalink = ""
}
fd.BasePathTargetPath = paths.ToSlashPreserveLeading(fd.BasePathTargetPath)
if fd.BasePathTargetPath == "/" {
fd.BasePathTargetPath = ""
}
fd.TargetPath = paths.ToSlashPreserveLeading(fd.TargetPath)
for i, base := range fd.TargetBasePaths {
dir := paths.ToSlashPreserveLeading(base)
if dir == "/" {
dir = ""
}
fd.TargetBasePaths[i] = dir
}
if fd.NameNormalized == "" {
fd.NameNormalized = fd.TargetPath
}
if fd.NameOriginal == "" {
fd.NameOriginal = fd.NameNormalized
}
mediaType := fd.MediaType
if mediaType.IsZero() {
ext := fd.Path.Ext()
var (
found bool
suffixInfo media.SuffixInfo
)
mediaType, suffixInfo, found = mediaService.LookFirstBySuffix(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" && mediaType.SubType == "rss" {
mediaType, found = mediaService.LookByType("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 != "" {
mediaType, _ = media.FromStringAndExt(mimeStr, ext)
}
}
}
fd.MediaType = mediaType
if fd.DependencyManager == nil {
fd.DependencyManager = identity.NewManager("resource")
}
return nil
}