aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2018-08-11 13:53:05 +0200
committerMartin Polden <mpolden@mpolden.no>2018-08-11 13:53:05 +0200
commit9d753132b9e04d6c2f25f1ae1408f3f22f414338 (patch)
treeda9f1db374aa08782000ad2559b1ee92473d27fb
parent073754374f4a802585c249db92dcbbde41e6a488 (diff)
Make LocalDir configuration reusable
-rw-r--r--cmd/lftpq/main.go6
-rw-r--r--cmd/lftpq/main_test.go83
-rw-r--r--queue/config.go101
-rw-r--r--queue/config_test.go95
4 files changed, 221 insertions, 64 deletions
diff --git a/cmd/lftpq/main.go b/cmd/lftpq/main.go
index 3d97191..a6d1cad 100644
--- a/cmd/lftpq/main.go
+++ b/cmd/lftpq/main.go
@@ -22,6 +22,7 @@ type CLI struct {
Test bool `short:"t" long:"test" description:"Test and print config"`
Quiet bool `short:"q" long:"quiet" description:"Do not print output from lftp"`
Import bool `short:"i" long:"import" description:"Build queues from stdin"`
+ LocalDir string `short:"l" long:"local-dir" description:"Override local dir for this run" value-name:"NAME"`
LftpPath string `short:"p" long:"lftp" description:"Path to lftp program" value-name:"NAME" default:"lftp"`
consumer queue.Consumer
lister lister
@@ -35,6 +36,11 @@ func (c *CLI) Run() error {
if err != nil {
return err
}
+ if c.LocalDir != "" {
+ if err := cfg.SetLocalDir(c.LocalDir); err != nil {
+ return err
+ }
+ }
if c.Test {
json, err := cfg.JSON()
if err != nil {
diff --git a/cmd/lftpq/main_test.go b/cmd/lftpq/main_test.go
index 7eea98b..ab4e2c3 100644
--- a/cmd/lftpq/main_test.go
+++ b/cmd/lftpq/main_test.go
@@ -82,7 +82,18 @@ func TestInvalidConfig(t *testing.T) {
}
func TestConfigTest(t *testing.T) {
- cli, buf := newTestCLI(`{"Default": {"Parser": "show"}, "Sites": []}`)
+ cli, buf := newTestCLI(`
+{
+ "LocalDirs": [
+ {
+ "Name": "d1",
+ "Parser": "movie",
+ "Template": "/tmp/"
+ }
+ ],
+ "Sites": []
+}
+`)
defer os.Remove(cli.Config)
cli.Test = true
if err := cli.Run(); err != nil {
@@ -99,14 +110,20 @@ func TestConfigTest(t *testing.T) {
"SkipSymlinks": false,
"SkipExisting": false,
"SkipFiles": false,
- "Parser": "show",
"LocalDir": "",
"Priorities": null,
"PostCommand": "",
- "Replacements": null,
"Merge": false,
"Skip": false
},
+ "LocalDirs": [
+ {
+ "Name": "d1",
+ "Parser": "movie",
+ "Template": "/tmp/",
+ "Replacements": null
+ }
+ ],
"Sites": []
}
`
@@ -118,23 +135,29 @@ func TestConfigTest(t *testing.T) {
func TestRunImport(t *testing.T) {
cli, buf := newTestCLI(`
{
+ "LocalDirs": [
+ {
+ "Name": "d1",
+ "Parser": "movie",
+ "Template": "/tmp/"
+ }
+ ],
"Default": {
- "Parser": "movie",
+ "LocalDir": "d1",
"GetCmd": "mirror"
- },
- "Sites": [
+ },
+ "Sites": [
{
"MaxAge": "0",
- "Name": "t1",
- "LocalDir": "/tmp/"
+ "Name": "t1"
},
{
"MaxAge": "0",
- "Name": "t2",
- "LocalDir": "/tmp/"
+ "Name": "t2"
}
- ]
-}`)
+ ]
+}
+`)
defer os.Remove(cli.Config)
toImport := `
t1 /foo/bar.2017
@@ -224,19 +247,25 @@ wait
func TestRun(t *testing.T) {
cli, buf := newTestCLI(`
{
+ "LocalDirs": [
+ {
+ "Name": "d1",
+ "Parser": "movie",
+ "Template": "/tmp/"
+ }
+ ],
"Default": {
- "Parser": "movie",
+ "LocalDir": "d1",
"GetCmd": "mirror",
"Patterns": [".*"]
},
- "Sites": [
+ "Sites": [
{
"MaxAge": "0",
"Name": "t1",
"Dirs": [
"/baz"
- ],
- "LocalDir": "/tmp/"
+ ]
}
]
}`)
@@ -308,10 +337,18 @@ wait
func TestRunSkipSite(t *testing.T) {
cli, buf := newTestCLI(`
{
- "Sites": [
+ "LocalDirs": [
+ {
+ "Name": "d1",
+ "Parser": "movie",
+ "Template": "/tmp/"
+ }
+ ],
+ "Sites": [
{
"MaxAge": "0",
"Name": "t1",
+ "LocalDir": "d1",
"Skip": true
}
]
@@ -329,13 +366,21 @@ func TestRunSkipSite(t *testing.T) {
func TestRunListError(t *testing.T) {
cli, buf := newTestCLI(`
{
- "Sites": [
+ "LocalDirs": [
+ {
+ "Name": "d1",
+ "Parser": "movie",
+ "Template": "/tmp/"
+ }
+ ],
+ "Sites": [
{
"MaxAge": "0",
"Name": "t1",
"Dirs": [
"/foo"
- ]
+ ],
+ "LocalDir": "d1"
}
]
}`)
diff --git a/queue/config.go b/queue/config.go
index 0d30ecd..b1f8b1b 100644
--- a/queue/config.go
+++ b/queue/config.go
@@ -18,8 +18,9 @@ import (
)
type Config struct {
- Default Site
- Sites []Site
+ Default Site
+ LocalDirs []LocalDir
+ Sites []Site
}
type Replacement struct {
@@ -28,6 +29,13 @@ type Replacement struct {
Replacement string
}
+type LocalDir struct {
+ Name string
+ Parser string
+ Template string
+ Replacements []Replacement
+}
+
type Site struct {
GetCmd string
Name string
@@ -41,13 +49,11 @@ type Site struct {
SkipSymlinks bool
SkipExisting bool
SkipFiles bool
- Parser string
LocalDir string
Priorities []string
priorities []*regexp.Regexp
PostCommand string
postCommand *exec.Cmd
- Replacements []Replacement
Merge bool
Skip bool
itemParser
@@ -104,7 +110,49 @@ func command(cmd string) (*exec.Cmd, error) {
return exec.Command(argv[0], argv[1:]...), nil
}
+func (c *Config) itemParsers() (map[string]itemParser, error) {
+ itemParsers := make(map[string]itemParser)
+ for _, d := range c.LocalDirs {
+ if d.Name == "" {
+ return nil, fmt.Errorf("invalid local dir name: %q", d.Name)
+ }
+ if d.Template == "" {
+ return nil, fmt.Errorf("invalid local dir template: %q", d.Template)
+ }
+ var parserFunc parser.Parser
+ switch d.Parser {
+ case "show":
+ parserFunc = parser.Show
+ case "movie":
+ parserFunc = parser.Movie
+ case "":
+ parserFunc = parser.Default
+ default:
+ return nil, fmt.Errorf("invalid local dir %q: invalid parser: %q (must be %q, %q or %q)",
+ d.Name, d.Parser, "show", "movie", "")
+ }
+ tmpl, err := parseTemplate(d.Template)
+ if err != nil {
+ return nil, err
+ }
+ replacements, err := compileReplacements(d.Replacements)
+ if err != nil {
+ return nil, err
+ }
+ itemParsers[d.Name] = itemParser{
+ parser: parserFunc,
+ replacements: replacements,
+ template: tmpl,
+ }
+ }
+ return itemParsers, nil
+}
+
func (c *Config) load() error {
+ itemParsers, err := c.itemParsers()
+ if err != nil {
+ return err
+ }
for i := range c.Sites {
site := &c.Sites[i]
maxAge, err := time.ParseDuration(site.MaxAge)
@@ -127,16 +175,6 @@ func (c *Config) load() error {
return err
}
site.priorities = priorities
- replacements, err := compileReplacements(site.Replacements)
- if err != nil {
- return err
- }
- site.Replacements = replacements
-
- tmpl, err := parseTemplate(site.LocalDir)
- if err != nil {
- return err
- }
cmd, err := command(site.PostCommand)
if err != nil {
@@ -144,27 +182,30 @@ func (c *Config) load() error {
}
site.postCommand = cmd
- var parserFunc parser.Parser
- switch site.Parser {
- case "show":
- parserFunc = parser.Show
- case "movie":
- parserFunc = parser.Movie
- case "":
- parserFunc = parser.Default
- default:
- return fmt.Errorf("invalid parser: %q (must be %q, %q or %q)",
- site.Parser, "show", "movie", "")
- }
- site.itemParser = itemParser{
- parser: parserFunc,
- replacements: site.Replacements,
- template: tmpl,
+ itemParser, ok := itemParsers[site.LocalDir]
+ if !ok {
+ return fmt.Errorf("site: %q: invalid local dir: %q", site.Name, site.LocalDir)
}
+ site.itemParser = itemParser
}
return nil
}
+func (c *Config) SetLocalDir(name string) error {
+ itemParsers, err := c.itemParsers()
+ if err != nil {
+ return err
+ }
+ _, ok := itemParsers[name]
+ if !ok {
+ return fmt.Errorf("invalid local dir: %q", name)
+ }
+ for i := range c.Sites {
+ c.Sites[i].LocalDir = name
+ }
+ return c.load()
+}
+
func (c *Config) JSON() ([]byte, error) {
return json.MarshalIndent(c, "", " ")
}
diff --git a/queue/config_test.go b/queue/config_test.go
index af4b4d5..e1b899c 100644
--- a/queue/config_test.go
+++ b/queue/config_test.go
@@ -9,21 +9,28 @@ import (
func TestLoad(t *testing.T) {
cfg := Config{
- Sites: []Site{Site{
+ LocalDirs: []LocalDir{
+ {
+ Name: "d1",
+ Parser: "show",
+ Template: "/tmp/{{ .Name }}",
+ Replacements: []Replacement{
+ {
+ Pattern: "\\.the\\.",
+ Replacement: ".The.",
+ }},
+ },
+ },
+ Sites: []Site{{
Name: "foo",
Dirs: []string{"/site"},
MaxAge: "24h",
Patterns: []string{"^match"},
Filters: []string{"^skip"},
SkipSymlinks: true,
- Parser: "show",
- LocalDir: "/tmp/{{ .Name }}",
+ LocalDir: "d1",
Priorities: []string{"important"},
- Replacements: []Replacement{
- Replacement{
- Pattern: "\\.the\\.",
- Replacement: ".The.",
- }},
+
PostCommand: "xargs echo",
}},
}
@@ -61,8 +68,20 @@ func TestLoad(t *testing.T) {
func TestReadConfig(t *testing.T) {
jsonConfig := `
{
+ "LocalDirs": [
+ {
+ "Name": "d1",
+ "Parser": "show",
+ "Template": "/tmp/d1/"
+ },
+ {
+ "Name": "d2",
+ "Parser": "movie",
+ "Template": "/tmp/d2/"
+ }
+ ],
"Default": {
- "Parser": "show"
+ "LocalDir": "d1"
},
"Sites": [
{
@@ -70,11 +89,11 @@ func TestReadConfig(t *testing.T) {
},
{
"Name": "bar",
- "Parser": "movie"
+ "LocalDir": "d2"
},
{
"Name": "baz",
- "Parser": ""
+ "LocalDir": ""
}
]
}
@@ -88,14 +107,60 @@ func TestReadConfig(t *testing.T) {
i int
out string
}{
- {0, "show"},
- {1, "movie"},
+ {0, "d1"},
+ {1, "d2"},
{2, ""},
}
for _, tt := range tests {
site := cfg.Sites[tt.i]
- if got := site.Parser; got != tt.out {
- t.Errorf("Expected Parser=%q, got Parser=%q for Name=%q", tt.out, got, site.Name)
+ if got := site.LocalDir; got != tt.out {
+ t.Errorf("got LocalDir=%q, want %q for Name=%q", got, tt.out, site.Name)
+ }
+ }
+}
+
+func TestOverrideLocalDir(t *testing.T) {
+ jsonConfig := `
+{
+ "LocalDirs": [
+ {
+ "Name": "d1",
+ "Parser": "show",
+ "Template": "/tmp/d1/"
+ },
+ {
+ "Name": "d2",
+ "Parser": "movie",
+ "Template": "/tmp/d2/"
+ }
+ ],
+ "Default": {
+ "LocalDir": "d1",
+ "MaxAge": "24h"
+ },
+ "Sites": [
+ {
+ "Name": "foo"
+ },
+ {
+ "Name": "bar"
+ }
+ ]
+}
+`
+ cfg, err := readConfig(strings.NewReader(jsonConfig))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := cfg.load(); err != nil {
+ t.Fatal(err)
+ }
+ if err := cfg.SetLocalDir("d2"); err != nil {
+ t.Fatal(err)
+ }
+ for _, s := range cfg.Sites {
+ if s.LocalDir != "d2" {
+ t.Errorf("got %q, want %q for Name=%q", s.LocalDir, "d2", s.Name)
}
}
}