mirror of
https://github.com/simon987/beemer.git
synced 2025-04-10 13:56:42 +00:00
Command line + readme
This commit is contained in:
parent
00d92a6084
commit
230a2cba59
42
README.md
42
README.md
@ -3,4 +3,44 @@
|
||||
[](https://ci.simon987.net/job/beemer_builds/)
|
||||
[](https://www.codefactor.io/repository/github/simon987/beemer)
|
||||
|
||||
wip
|
||||
**beemer** executes a custom command on files written in the watched directory and deletes it.
|
||||
|
||||
### Usage
|
||||
|
||||
```
|
||||
NAME:
|
||||
beemer - Execute a command on a file after a delay of inactivity
|
||||
|
||||
GLOBAL OPTIONS:
|
||||
--command value, -c value Will be executed on file write. You can use %file and %dir. Example: "rclone move %file remote:/beem/%dir"
|
||||
--wait DELAY, -w DELAY Files will be beemed after DELAY of inactivity (default: 10s)
|
||||
--directory DIRECTORY, -d DIRECTORY DIRECTORY to watch. If non-empty, its current files & subdirectories will be ignored
|
||||
--help, -h show help
|
||||
--version, -v print the version
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
Upload file to an rclone remote when it has been inactive for at least 30s,
|
||||
keeps the directory structure
|
||||
```bash
|
||||
./beemer -w 30s -d ./test -c "rclone move %file remote:/beem/%dir"
|
||||
```
|
||||
|
||||
Send file via SSH, ignoring the local directory structure
|
||||
```bash
|
||||
./beemer -d ./test -c "scp %file worker@StagingServer:flatdir/"
|
||||
```
|
||||
|
||||
Upload file to transfer.sh, store URLs in `urls.txt`
|
||||
```bash
|
||||
./beemer -w 1s -d ./test -c "bash -c \"curl -s -w '\\n' --upload-file %file https://transfer.sh/%name &>> urls.txt\""
|
||||
```
|
||||
|
||||
### Beem command template
|
||||
|
||||
| Special sequence | Description | Example |
|
||||
| :--- | :--- | :--- |
|
||||
| `%file` | Full path of the modified file | `/tmp/beemer/test/a/myFile.txt` |
|
||||
| `%name` | Name of the modified file | `myFile.txt` |
|
||||
| `%dir` | Directory of the modified file, relative to the watched dir. | `test/a` |
|
||||
|
76
main.go
76
main.go
@ -2,7 +2,9 @@ package main
|
||||
|
||||
import (
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@ -21,8 +23,7 @@ type File struct {
|
||||
BeemLock bool
|
||||
}
|
||||
|
||||
var CmdString = "rclone move %file remote:/beem/%dir"
|
||||
var InactiveDelay = time.Second * 5
|
||||
var InactiveDelay time.Duration
|
||||
|
||||
var ctx = Ctx{
|
||||
FileMap: make(map[string]*File, 0),
|
||||
@ -31,26 +32,71 @@ var ctx = Ctx{
|
||||
func main() {
|
||||
logrus.SetLevel(logrus.TraceLevel)
|
||||
|
||||
initTempDir()
|
||||
ctx.BeemCommand = parseCommand(CmdString)
|
||||
app := cli.NewApp()
|
||||
app.Name = "beemer"
|
||||
app.Usage = "Execute a command on a file after a delay of inactivity"
|
||||
app.Email = "me@simon987.net"
|
||||
app.Author = "simon987"
|
||||
app.Version = "1.0"
|
||||
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
var cmdString string
|
||||
var watchDir string
|
||||
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "command, c",
|
||||
Usage: "Will be executed on file write. You can use %file, %name and %dir. " +
|
||||
"Example: \"rclone move %file remote:/beem/%dir\"",
|
||||
Destination: &cmdString,
|
||||
},
|
||||
cli.DurationFlag{
|
||||
Name: "wait, w",
|
||||
Usage: "Files will be beemed after `DELAY` of inactivity",
|
||||
Destination: &InactiveDelay,
|
||||
Value: time.Second * 10,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "directory, d",
|
||||
Usage: "`DIRECTORY` to watch. If non-empty, its current files & subdirectories will be ignored",
|
||||
Destination: &watchDir,
|
||||
},
|
||||
}
|
||||
|
||||
defer watcher.Close()
|
||||
app.Action = func(c *cli.Context) error {
|
||||
|
||||
go handleFileChange(watcher)
|
||||
if !c.IsSet("directory") {
|
||||
return errors.New("Directory must be specified")
|
||||
}
|
||||
|
||||
err = watcher.Add("./test")
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
initTempDir()
|
||||
ctx.BeemCommand = parseCommand(cmdString)
|
||||
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
defer watcher.Close()
|
||||
|
||||
go handleFileChange(watcher)
|
||||
|
||||
logrus.WithField("dir", watchDir).Info("Watching directory for changes")
|
||||
err = watcher.Add(watchDir)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
//TODO gracefully handle SIGINT
|
||||
done := make(chan bool)
|
||||
<-done
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//TODO gracefully handle SIGINT
|
||||
done := make(chan bool)
|
||||
<-done
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
logrus.Fatal(app.OnUsageError)
|
||||
}
|
||||
}
|
||||
|
||||
func getAndResetTimer(name string) *time.Timer {
|
||||
|
7
util.go
7
util.go
@ -84,13 +84,16 @@ func copyFile(src string, dst string) error {
|
||||
func parseCommand(command string) func(string, string) (string, []string) {
|
||||
args, _ := argv.Argv([]rune(command), argv.ParseEnv(os.Environ()), argv.Run)
|
||||
|
||||
logrus.WithField("cmd", args[0]).Info("Parsed beem command")
|
||||
|
||||
return func(name string, dir string) (string, []string) {
|
||||
newTokens := make([]string, len(args[0]))
|
||||
copy(newTokens, args[0])
|
||||
|
||||
for i := range newTokens {
|
||||
newTokens[i] = strings.Replace(newTokens[i], "%file", name,-1)
|
||||
newTokens[i] = strings.Replace(newTokens[i], "%dir", dir,-1)
|
||||
newTokens[i] = strings.Replace(newTokens[i], "%file", name, -1)
|
||||
newTokens[i] = strings.Replace(newTokens[i], "%dir", dir, -1)
|
||||
newTokens[i] = strings.Replace(newTokens[i], "%name", filepath.Base(name), -1)
|
||||
}
|
||||
return args[0][0], newTokens[1:]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user