-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathconfig.go
132 lines (105 loc) · 2.62 KB
/
config.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
package main
import (
"crypto/md5"
"errors"
"fmt"
"io"
"log"
"os"
"os/exec"
"os/user"
"path/filepath"
"strings"
"time"
"github.com/scalingdata/gcfg"
"github.com/lmika/oaipmh/client"
)
// The provider struct
type Provider struct {
// The provider URL
Url string
// The default set
Set string
}
// Baseline configuration
type Config struct {
// Provider aliases
Provider map[string]*Provider
// External processes
ExtProcess map[string]*ExtProcess
}
// Looks up a provider. If one is not defined, creates a dummy provider.
func (cfg *Config) LookupProvider(endpoint string) *Provider {
if endpoint == "" {
return nil
}
if prov, hasProv := cfg.Provider[endpoint]; hasProv {
return prov
} else {
return &Provider{Url: endpoint}
}
}
func ReadConfig() *Config {
c := &Config{
Provider: make(map[string]*Provider),
}
u, err := user.Current()
if err != nil {
log.Println("Error trying to get local user. Using default config. Error = %s\n", err.Error())
return c
}
// Read the home config file
homeConfig := filepath.Join(u.HomeDir, ".oaipmh.cfg")
if _, err := os.Stat(homeConfig); err == nil {
err := gcfg.ReadFileInto(c, homeConfig)
if err != nil {
panic(err)
}
}
return c
}
// The external process configuration
type ExtProcess struct {
// The shell command to execute
Cmd string
// When true, the metadata will be written to a temp file and the filename will be
// provided as a shell parameter "file"
TempFile bool
}
// Invoke this external process configuration with the given Oaipmh record
func (ep *ExtProcess) invokeWithRecord(rec *oaipmh.OaipmhRecord) error {
shell, hasShell := os.LookupEnv("SHELL")
if !hasShell {
return errors.New("No SHELL defined")
}
// Setup the command
cmd := exec.Command(shell, "-c", ep.Cmd)
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, "urn="+rec.Header.Identifier)
// Setup the metadata content
if ep.TempFile {
tmpFileName, err := ep.writeToTempFile(rec)
if err != nil {
return err
}
defer os.Remove(tmpFileName)
cmd.Env = append(cmd.Env, "file="+tmpFileName)
cmd.Stdin = nil
} else {
cmd.Stdin = strings.NewReader(rec.Content.Xml)
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
func (ep *ExtProcess) writeToTempFile(rec *oaipmh.OaipmhRecord) (string, error) {
tmpFilename := fmt.Sprintf("oaipmh-%d-%x.xml", time.Now().UnixNano(), md5.Sum([]byte(rec.Header.Identifier)))
fullPath := filepath.Join(os.TempDir(), tmpFilename)
file, err := os.Create(fullPath)
if err != nil {
return "", err
}
defer file.Close()
_, err = io.Copy(file, strings.NewReader(rec.Content.Xml))
return fullPath, err
}