2018-10-13 14:04:17 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"archive/zip"
|
|
|
|
"encoding/xml"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"path"
|
|
|
|
"regexp"
|
|
|
|
)
|
|
|
|
|
|
|
|
func acquireFile(specFilename string, xmlSpecURL string) error {
|
|
|
|
if f, err := os.Open(specFilename); err != nil {
|
|
|
|
if !os.IsNotExist(err) {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
f.Close()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := http.Get(xmlSpecURL)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
2020-05-10 08:48:28 +00:00
|
|
|
return fmt.Errorf("could not download spec %q from %q: %s",
|
2018-10-13 14:04:17 +00:00
|
|
|
specFilename, xmlSpecURL, resp.Status)
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpFilename := specFilename + ".download"
|
|
|
|
w, err := os.Create(tmpFilename)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer w.Close()
|
|
|
|
|
|
|
|
_, err = io.Copy(w, resp.Body)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return os.Rename(tmpFilename, specFilename)
|
|
|
|
}
|
|
|
|
|
|
|
|
func globFiles(pattern string, archive *zip.ReadCloser) []*zip.File {
|
|
|
|
var files []*zip.File
|
|
|
|
for _, f := range archive.File {
|
|
|
|
if matched, err := path.Match(pattern, f.Name); err != nil {
|
|
|
|
// This shouldn't happen - all patterns are hard-coded, errors in them
|
|
|
|
// are a programming error.
|
|
|
|
panic(err)
|
|
|
|
} else if matched {
|
|
|
|
files = append(files, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return files
|
|
|
|
}
|
|
|
|
|
|
|
|
func unmarshalXmlFile(file *zip.File, data interface{}) error {
|
|
|
|
r, err := file.Open()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
decoder := xml.NewDecoder(r)
|
|
|
|
defer r.Close()
|
|
|
|
return decoder.Decode(data)
|
|
|
|
}
|
|
|
|
|
|
|
|
var scpdFilenameRe = regexp.MustCompile(
|
|
|
|
`.*/([a-zA-Z0-9]+)([0-9]+)\.xml`)
|
|
|
|
|
|
|
|
func urnPartsFromSCPDFilename(filename string) (*URNParts, error) {
|
|
|
|
parts := scpdFilenameRe.FindStringSubmatch(filename)
|
|
|
|
if len(parts) != 3 {
|
|
|
|
return nil, fmt.Errorf("SCPD filename %q does not have expected number of parts", filename)
|
|
|
|
}
|
|
|
|
name, version := parts[1], parts[2]
|
|
|
|
return &URNParts{
|
|
|
|
URN: serviceURNPrefix + name + ":" + version,
|
|
|
|
Name: name,
|
|
|
|
Version: version,
|
|
|
|
}, nil
|
|
|
|
}
|