WIP: stuff for saving

This commit is contained in:
AJ ONeal 2019-06-22 21:50:17 -06:00
parent f135020914
commit 7db71b94b1
4 changed files with 149 additions and 16 deletions

View File

@ -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/

View File

@ -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)
}

View File

@ -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
}

View File

@ -87,16 +87,22 @@
function newSchedule() {
var $hook = $('.js-schedule');
//var deviceId = $hook.closest('.js-schedule').querySelector('.js-id').value;
var schedule = {
schedule: {
date: $('.js-date', $hook).value,
time: $('.js-time', $hook).value,
tz: $('.js-tz', $hook).value
},
webhooks: []
};
var hook = {
date: $('.js-date', $hook).value,
time: $('.js-time', $hook).value,
tz: $('.js-tz', $hook).value,
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
};