WIP: stuff for saving
This commit is contained in:
parent
f135020914
commit
7db71b94b1
11
again.go
11
again.go
|
@ -7,9 +7,16 @@ import (
|
|||
webhooks "git.rootprojects.org/root/go-again/webhooks"
|
||||
)
|
||||
|
||||
type Webhook webhooks.Webhook
|
||||
|
||||
type Schedule struct {
|
||||
NextRunAt time.Time
|
||||
Webhooks []webhooks.Webhook
|
||||
ID string `json:"id" db:"id"`
|
||||
AccessID string `json:"-" 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"`
|
||||
Webhooks []Webhook `json:"webhooks" db"webhooks"`
|
||||
}
|
||||
|
||||
// https://yourbasic.org/golang/time-change-convert-location-timezone/
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
|
@ -85,7 +86,8 @@ func main() {
|
|||
}
|
||||
|
||||
type ScheduleDB interface {
|
||||
List() ([]again.Schedule, error)
|
||||
List(string) ([]*again.Schedule, error)
|
||||
Set(again.Schedule) (*again.Schedule, error)
|
||||
}
|
||||
|
||||
type scheduler struct {
|
||||
|
@ -93,12 +95,17 @@ type scheduler struct {
|
|||
}
|
||||
|
||||
func (s *scheduler) Handle(w http.ResponseWriter, r *http.Request) {
|
||||
// note: no go-routines reading body in handlers to follow
|
||||
defer r.Body.Close()
|
||||
|
||||
token := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
|
||||
if "" == token {
|
||||
if 32 != len(token) {
|
||||
http.Error(w, "Authorization Header did not contain a valid token", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
ctx := r.Context()
|
||||
ctx = context.WithValue(ctx, "token", token)
|
||||
r = r.WithContext(ctx)
|
||||
|
||||
fmt.Println("whatever", r.Method, r.URL)
|
||||
switch r.Method {
|
||||
|
@ -106,7 +113,7 @@ func (s *scheduler) Handle(w http.ResponseWriter, r *http.Request) {
|
|||
s.List(w, r)
|
||||
return
|
||||
case http.MethodPost:
|
||||
http.Error(w, "Not Implemented", http.StatusNotImplemented)
|
||||
s.Create(w, r)
|
||||
return
|
||||
default:
|
||||
http.Error(w, "Not Implemented", http.StatusNotImplemented)
|
||||
|
@ -115,7 +122,8 @@ func (s *scheduler) Handle(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func (s *scheduler) List(w http.ResponseWriter, r *http.Request) {
|
||||
schedules, err := s.DB.List()
|
||||
accessID := r.Context().Value("token").(string)
|
||||
schedules, err := s.DB.List(accessID)
|
||||
if nil != err {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
@ -127,3 +135,27 @@ func (s *scheduler) List(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
w.Write(buf)
|
||||
}
|
||||
|
||||
func (s *scheduler) Create(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO validate user
|
||||
accessID := r.Context().Value("token").(string)
|
||||
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
sched := &again.Schedule{}
|
||||
err := decoder.Decode(s)
|
||||
if nil != err {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO validate and modify
|
||||
sched.AccessID = accessID
|
||||
s.DB.Set(*sched)
|
||||
|
||||
buf, err := json.Marshal(sched)
|
||||
if nil != err {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Write(buf)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -87,16 +87,22 @@
|
|||
function newSchedule() {
|
||||
var $hook = $('.js-schedule');
|
||||
//var deviceId = $hook.closest('.js-schedule').querySelector('.js-id').value;
|
||||
var hook = {
|
||||
var schedule = {
|
||||
schedule: {
|
||||
date: $('.js-date', $hook).value,
|
||||
time: $('.js-time', $hook).value,
|
||||
tz: $('.js-tz', $hook).value,
|
||||
tz: $('.js-tz', $hook).value
|
||||
},
|
||||
webhooks: []
|
||||
};
|
||||
var hook = {
|
||||
comment: $('.js-comment', $hook).value,
|
||||
method: $('.js-method', $hook).value,
|
||||
url: $('.js-url', $hook).value,
|
||||
headers: {}
|
||||
};
|
||||
console.log('schedule:', hook);
|
||||
schedule.webhooks.push(hook);
|
||||
console.log('schedule:', schedule);
|
||||
$$('.js-header', $hook).forEach(function($head) {
|
||||
var key = $('.js-key', $head).value;
|
||||
var val = $('.js-value', $head).value;
|
||||
|
@ -114,7 +120,7 @@
|
|||
Authorization: getToken(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(hook),
|
||||
body: JSON.stringify(schedule),
|
||||
cors: true
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue