Skip to content
This repository has been archived by the owner on Aug 3, 2024. It is now read-only.

Commit

Permalink
feat(triggers): inotify (#38)
Browse files Browse the repository at this point in the history
* feat(triggers): add inotify trigger

* refactor(triggers/bernard): prefix paths with / and resolve issue with files in root of drive

* docs: remove bernard mia status
  • Loading branch information
l3uddz authored Aug 30, 2020
1 parent 497ca67 commit 5c1a580
Show file tree
Hide file tree
Showing 9 changed files with 426 additions and 75 deletions.
28 changes: 20 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,8 @@ In addition, this rewrite introduces a more modular approach and should be easy

## Early Access

**We are looking for technical writers! If you have ideas on how to improve Autoscan's documentation, please write [@m-rots](mailto:[email protected]?subject=Autoscan%20technical%20writer) an email.**

We have not finished all work on Autoscan yet, and are still working on some things.

The major feature which is currently MIA:

- Google Drive monitoring (Shared Drives exclusively)

Some small things we are still working on:

- Automating the testing of the processor's business logic
Expand Down Expand Up @@ -159,6 +153,7 @@ Daemons run in the background and continuously fetch new changes based on a [cro
The following daemons are currently provided by Autoscan:

- Google Drive
- inotify

#### Webhooks

Expand Down Expand Up @@ -205,12 +200,29 @@ triggers:
to: /mnt/unionfs/Media/$1
# filter with regular expressions
include: # if set, then exclude is ignored
include:
- "^/mnt/unionfs/Media/*"
exclude:
- "\.srt$"
inotify:
- priority: 0
# filter with regular expressions
include:
- '/mnt/unionfs/Media/*'
exclude:
- '\.(srt|pdf)$'
# rewrite inotify path to unified filesystem
rewrite:
- from: ^/mnt/local/Media/*
to: /mnt/unionfs/Media/$1
# local filesystem paths to monitor
paths:
- path: /mnt/local/Media
sonarr:
- name: sonarr-docker # /triggers/sonarr-docker
priority: 2
Expand Down
59 changes: 59 additions & 0 deletions autoscan.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package autoscan

import (
"errors"
"fmt"
"net/http"
"regexp"
"time"
Expand Down Expand Up @@ -83,3 +84,61 @@ func NewRewriter(rewriteRules []Rewrite) (Rewriter, error) {

return rewriter, nil
}

type Filterer func(string) bool

func NewFilterer(includes []string, excludes []string) (Filterer, error) {
reIncludes := make([]regexp.Regexp, 0)
reExcludes := make([]regexp.Regexp, 0)

// compile patterns
for _, pattern := range includes {
re, err := regexp.Compile(pattern)
if err != nil {
return nil, fmt.Errorf("compiling include: %v: %w", pattern, err)
}
reIncludes = append(reIncludes, *re)
}

for _, pattern := range excludes {
re, err := regexp.Compile(pattern)
if err != nil {
return nil, fmt.Errorf("compiling exclude: %v: %w", pattern, err)
}
reExcludes = append(reExcludes, *re)
}

incSize := len(reIncludes)
excSize := len(reExcludes)

// create filterer
var fn Filterer = func(string) bool { return true }

if incSize > 0 || excSize > 0 {
fn = func(path string) bool {
// check excludes
for _, re := range reExcludes {
if re.MatchString(path) {
return false
}
}

// no includes (but excludes did not match)
if incSize == 0 {
return true
}

// check includes
for _, re := range reIncludes {
if re.MatchString(path) {
return true
}
}

// no includes passed
return false
}
}

return fn, nil
}
15 changes: 15 additions & 0 deletions cmd/autoscan/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/cloudbox/autoscan/targets/plex"
"github.com/cloudbox/autoscan/triggers"
"github.com/cloudbox/autoscan/triggers/bernard"
"github.com/cloudbox/autoscan/triggers/inotify"
"github.com/cloudbox/autoscan/triggers/lidarr"
"github.com/cloudbox/autoscan/triggers/radarr"
"github.com/cloudbox/autoscan/triggers/sonarr"
Expand All @@ -42,6 +43,7 @@ type config struct {
// autoscan.HTTPTrigger
Triggers struct {
Bernard []bernard.Config `yaml:"bernard"`
Inotify []inotify.Config `yaml:"inotify"`
Lidarr []lidarr.Config `yaml:"lidarr"`
Radarr []radarr.Config `yaml:"radarr"`
Sonarr []sonarr.Config `yaml:"sonarr"`
Expand Down Expand Up @@ -201,6 +203,18 @@ func main() {
go trigger(proc.Add)
}

for _, t := range c.Triggers.Inotify {
trigger, err := inotify.New(t)
if err != nil {
log.Fatal().
Err(err).
Str("trigger", "inotify").
Msg("Failed initialising trigger")
}

go trigger(proc.Add)
}

// HTTP Triggers
for _, t := range c.Triggers.Lidarr {
trigger, err := lidarr.New(t)
Expand Down Expand Up @@ -252,6 +266,7 @@ func main() {

log.Info().
Int("bernard", len(c.Triggers.Bernard)).
Int("inotify", len(c.Triggers.Inotify)).
Int("lidarr", len(c.Triggers.Lidarr)).
Int("sonarr", len(c.Triggers.Sonarr)).
Int("radarr", len(c.Triggers.Radarr)).
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.14
require (
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/alecthomas/kong v0.2.11
github.com/fsnotify/fsnotify v1.4.9
github.com/justinas/alice v1.2.0
github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f
github.com/m-rots/bernard v0.3.3-0.20200804121414-38394a889536
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ github.com/alecthomas/kong v0.2.11/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QL
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/justinas/alice v1.2.0 h1:+MHSA/vccVCF4Uq37S42jwlkvI2Xzl7zTPCN5BnZNVo=
github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA=
github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f h1:dKccXx7xA56UNqOcFIbuqFjAWPVtP688j5QMgmo6OHU=
Expand Down Expand Up @@ -40,6 +42,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c h1:UIcGWL6/wpCfyGuJnRFJRurA+yj8RrW7Q6x2YMCXt6c=
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
8 changes: 4 additions & 4 deletions triggers/bernard/bernard.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func New(c Config) (autoscan.Trigger, error) {
return nil, err
}

filterer, err := newFilterer(append(d.Include, c.Include...), append(d.Exclude, c.Exclude...))
filterer, err := autoscan.NewFilterer(append(d.Include, c.Include...), append(d.Exclude, c.Exclude...))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -106,7 +106,7 @@ func New(c Config) (autoscan.Trigger, error) {
}

// start job(s)
if err := d.StartAutoSync(); err != nil {
if err := d.startAutoSync(); err != nil {
l.Error().
Err(err).
Msg("Failed initialising cron jobs")
Expand All @@ -120,7 +120,7 @@ func New(c Config) (autoscan.Trigger, error) {
type drive struct {
ID string
Rewriter autoscan.Rewriter
Allowed filterer
Allowed autoscan.Filterer
ScanTime func() time.Time
}

Expand Down Expand Up @@ -207,7 +207,7 @@ func newSyncJob(c *cron.Cron, log zerolog.Logger, job func() error) *syncJob {
}
}

func (d daemon) StartAutoSync() error {
func (d daemon) startAutoSync() error {
c := cron.New()

for _, drive := range d.drives {
Expand Down
59 changes: 0 additions & 59 deletions triggers/bernard/filters.go

This file was deleted.

20 changes: 16 additions & 4 deletions triggers/bernard/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,18 @@ func getFolder(store *bds, driveId string, folderId string, folderMap map[string
return &folder, nil
}

if folderId == driveId {
folder := datastore.Folder{
ID: driveId,
Name: "",
Parent: "",
Trashed: false,
}

folderMap[driveId] = folder
return &folder, nil
}

// search datastore
folder, err := store.GetFolder(driveId, folderId)
if err != nil {
Expand All @@ -181,15 +193,15 @@ func getFolderPath(store *bds, driveId string, folderId string, folderMap map[st

// folderId == driveId
if folderId == driveId {
return path, nil
return "/", nil
}

// get top folder
topFolder, ok := folderMap[folderId]
if !ok {
f, err := store.GetFolder(driveId, folderId)
if err != nil {
return path, fmt.Errorf("could not get folder %v: %w", folderId, err)
return filepath.Join("/", path), fmt.Errorf("could not get folder %v: %w", folderId, err)
}

topFolder = *f
Expand All @@ -205,7 +217,7 @@ func getFolderPath(store *bds, driveId string, folderId string, folderMap map[st
if !ok {
df, err := store.GetFolder(driveId, nextFolderId)
if err != nil {
return path, fmt.Errorf("could not get folder %v: %w", nextFolderId, err)
return filepath.Join("/", path), fmt.Errorf("could not get folder %v: %w", nextFolderId, err)
}

f = *df
Expand All @@ -216,5 +228,5 @@ func getFolderPath(store *bds, driveId string, folderId string, folderMap map[st
nextFolderId = f.Parent
}

return path, nil
return filepath.Join("/", path), nil
}
Loading

0 comments on commit 5c1a580

Please sign in to comment.