|
|
@ -6,18 +6,19 @@ import ( |
|
|
|
"net/url" |
|
|
|
"os" |
|
|
|
"strings" |
|
|
|
"time" |
|
|
|
|
|
|
|
again "git.rootprojects.org/root/go-again" |
|
|
|
) |
|
|
|
|
|
|
|
type JSONDB struct { |
|
|
|
dburl string |
|
|
|
file *os.File |
|
|
|
path string |
|
|
|
json *dbjson |
|
|
|
} |
|
|
|
|
|
|
|
type dbjson struct { |
|
|
|
Schedules []again.Schedule `json:"schedules"` |
|
|
|
Schedules []Schedule `json:"schedules"` |
|
|
|
} |
|
|
|
|
|
|
|
func Connect(dburl string) (*JSONDB, error) { |
|
|
@ -50,9 +51,11 @@ func Connect(dburl string) (*JSONDB, error) { |
|
|
|
stat, err := f.Stat() |
|
|
|
if 0 == stat.Size() { |
|
|
|
_, err := f.Write([]byte(`{"schedules":[]}`)) |
|
|
|
f.Close() |
|
|
|
if nil != err { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
|
|
|
|
f, err = os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0700) |
|
|
|
if nil != err { |
|
|
|
return nil, err |
|
|
@ -62,17 +65,102 @@ func Connect(dburl string) (*JSONDB, error) { |
|
|
|
decoder := json.NewDecoder(f) |
|
|
|
db := &dbjson{} |
|
|
|
err = decoder.Decode(db) |
|
|
|
f.Close() |
|
|
|
if nil != err { |
|
|
|
return nil, fmt.Errorf("Couldn't parse %q as JSON: %s", path, err) |
|
|
|
} |
|
|
|
|
|
|
|
return &JSONDB{ |
|
|
|
dburl: dburl, |
|
|
|
file: f, |
|
|
|
path: path, |
|
|
|
json: db, |
|
|
|
}, nil |
|
|
|
} |
|
|
|
|
|
|
|
func (db *JSONDB) List() ([]again.Schedule, error) { |
|
|
|
return db.json.Schedules, nil |
|
|
|
// A copy of again.Schedule, but with access_id json-able
|
|
|
|
type Schedule struct { |
|
|
|
ID string `json:"id" db:"id"` |
|
|
|
AccessID string `json:"access_id" db:"access_id"` |
|
|
|
Date string `json:"date" db:"date"` |
|
|
|
Time string `json:"time" db:"time"` |
|
|
|
TZ string `json:"tz" db:"tz"` |
|
|
|
NextRunAt time.Time `json:"next_run_at" db:"next_run_at"` |
|
|
|
Disabled bool `json:"disabled" db:"disabled"` |
|
|
|
Webhooks []again.Webhook `json:"webhooks" db"webhooks"` |
|
|
|
} |
|
|
|
|
|
|
|
func (db *JSONDB) List(accessID string) ([]*again.Schedule, error) { |
|
|
|
schedules := []*again.Schedule{} |
|
|
|
for i := range db.json.Schedules { |
|
|
|
s := db.json.Schedules[i] |
|
|
|
if !s.Disabled && accessID == s.AccessID { |
|
|
|
schedules = append(schedules, &again.Schedule{ |
|
|
|
ID: s.ID, |
|
|
|
AccessID: s.AccessID, |
|
|
|
Date: s.Date, |
|
|
|
Time: s.Time, |
|
|
|
TZ: s.TZ, |
|
|
|
NextRunAt: s.NextRunAt, |
|
|
|
Webhooks: s.Webhooks, |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
return schedules, nil |
|
|
|
} |
|
|
|
|
|
|
|
func (db *JSONDB) get(id string) *Schedule { |
|
|
|
for i := range db.json.Schedules { |
|
|
|
schedule := db.json.Schedules[i] |
|
|
|
if id == schedule.AccessID { |
|
|
|
return &schedule |
|
|
|
} |
|
|
|
} |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
func (db *JSONDB) Set(s again.Schedule) (*again.Schedule, error) { |
|
|
|
newSchedules := []Schedule{} |
|
|
|
|
|
|
|
for i := range db.json.Schedules { |
|
|
|
old := db.json.Schedules[i] |
|
|
|
if s.ID == old.AccessID { |
|
|
|
continue |
|
|
|
} |
|
|
|
newSchedules = append(newSchedules, old) |
|
|
|
} |
|
|
|
|
|
|
|
schedule := Schedule{ |
|
|
|
ID: s.ID, |
|
|
|
AccessID: s.AccessID, |
|
|
|
Date: s.Date, |
|
|
|
Time: s.Time, |
|
|
|
TZ: s.TZ, |
|
|
|
NextRunAt: s.NextRunAt, |
|
|
|
Webhooks: s.Webhooks, |
|
|
|
} |
|
|
|
newSchedules = append(newSchedules, schedule) |
|
|
|
|
|
|
|
err := db.save(s.AccessID) |
|
|
|
if nil != err { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
|
|
|
|
return &s, nil |
|
|
|
} |
|
|
|
|
|
|
|
func (db *JSONDB) save(accessID string) error { |
|
|
|
// TODO per-user files (w/ mutex lock or channel on open and write)
|
|
|
|
f, err := os.OpenFile(db.path, os.O_RDWR|os.O_CREATE, 0700) |
|
|
|
if nil != err { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
encoder := json.NewEncoder(f) |
|
|
|
err = encoder.Encode(db.json.Schedules) |
|
|
|
f.Close() |
|
|
|
if nil != err { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|