mirror of
https://github.com/dutchcoders/transfer.sh.git
synced 2024-12-12 13:50:19 +01:00
75 lines
1.7 KiB
Go
75 lines
1.7 KiB
Go
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||
|
//
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file or at
|
||
|
// https://developers.google.com/open-source/licenses/bsd.
|
||
|
|
||
|
package gosrc
|
||
|
|
||
|
import (
|
||
|
"path/filepath"
|
||
|
"regexp"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type Presentation struct {
|
||
|
Filename string
|
||
|
Files map[string][]byte
|
||
|
Updated time.Time
|
||
|
}
|
||
|
|
||
|
type presBuilder struct {
|
||
|
filename string
|
||
|
data []byte
|
||
|
resolveURL func(fname string) string
|
||
|
fetch func(fnames []string) ([]*File, error)
|
||
|
}
|
||
|
|
||
|
var assetPat = regexp.MustCompile(`(?m)^\.(play|code|image|iframe|html)\s+(?:-\S+\s+)*(\S+)`)
|
||
|
|
||
|
func (b *presBuilder) build() (*Presentation, error) {
|
||
|
var data []byte
|
||
|
var fnames []string
|
||
|
i := 0
|
||
|
for _, m := range assetPat.FindAllSubmatchIndex(b.data, -1) {
|
||
|
name := filepath.Clean(string(b.data[m[4]:m[5]]))
|
||
|
switch string(b.data[m[2]:m[3]]) {
|
||
|
case "iframe", "image":
|
||
|
data = append(data, b.data[i:m[4]]...)
|
||
|
data = append(data, b.resolveURL(name)...)
|
||
|
case "html":
|
||
|
// TODO: sanitize and fix relative URLs in HTML.
|
||
|
data = append(data, "\nERROR: .html not supported\n"...)
|
||
|
case "play", "code":
|
||
|
data = append(data, b.data[i:m[5]]...)
|
||
|
found := false
|
||
|
for _, n := range fnames {
|
||
|
if n == name {
|
||
|
found = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
if !found {
|
||
|
fnames = append(fnames, name)
|
||
|
}
|
||
|
default:
|
||
|
data = append(data, "\nERROR: unknown command\n"...)
|
||
|
}
|
||
|
i = m[5]
|
||
|
}
|
||
|
data = append(data, b.data[i:]...)
|
||
|
files, err := b.fetch(fnames)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
pres := &Presentation{
|
||
|
Updated: time.Now().UTC(),
|
||
|
Filename: b.filename,
|
||
|
Files: map[string][]byte{b.filename: data},
|
||
|
}
|
||
|
for _, f := range files {
|
||
|
pres.Files[f.Name] = f.Data
|
||
|
}
|
||
|
return pres, nil
|
||
|
}
|