Export
This commit is contained in:
parent
638b4df0e7
commit
53ccf1715b
5 changed files with 90 additions and 6 deletions
|
@ -24,7 +24,7 @@ func makeExportRequest(ej *xport.ExportJob, url string) *http.Request {
|
|||
|
||||
perr(body.WriteField("systemID", strconv.Itoa(int(ej.SystemID))))
|
||||
|
||||
perr(body.WriteField("talkgroups", "3,4"))
|
||||
perr(body.WriteField("talkgroups", "[197:3,4]"))
|
||||
|
||||
w, err := body.CreateFormFile("template", ej.TemplateFileName)
|
||||
perr(err)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package forms
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -104,6 +105,7 @@ func (o *options) parseDuration(s string) (v time.Duration, set bool, err error)
|
|||
var typeOfByteSlice = reflect.TypeOf([]byte(nil))
|
||||
|
||||
func (o *options) unmIterFields(r *http.Request, destStruct reflect.Value) error {
|
||||
textUnmarshaler := reflect.TypeFor[encoding.TextUnmarshaler]()
|
||||
structType := destStruct.Type()
|
||||
for i := 0; i < destStruct.NumField(); i++ {
|
||||
destFieldVal := destStruct.Field(i)
|
||||
|
@ -175,6 +177,8 @@ func (o *options) unmIterFields(r *http.Request, destStruct reflect.Value) error
|
|||
|
||||
ff := r.Form.Get(formField)
|
||||
|
||||
destFieldType := destFieldVal.Type()
|
||||
|
||||
switch v := destFieldIntf.(type) {
|
||||
case string, *string:
|
||||
setVal(destFieldVal, ff != "" || o.acceptBlank, ff)
|
||||
|
@ -223,11 +227,34 @@ func (o *options) unmIterFields(r *http.Request, destStruct reflect.Value) error
|
|||
}
|
||||
destFieldVal.Set(reflect.ValueOf(ar))
|
||||
default:
|
||||
dvt := destFieldVal.Type()
|
||||
if dvt.Kind() == reflect.Ptr {
|
||||
dvt = dvt.Elem()
|
||||
if destFieldType.Kind() == reflect.Slice && reflect.PointerTo(destFieldType.Elem()).Implements(textUnmarshaler) {
|
||||
val := strings.Trim(ff, "[]")
|
||||
if val == "" && o.acceptBlank {
|
||||
continue
|
||||
}
|
||||
if reflect.ValueOf(ff).CanConvert(dvt) {
|
||||
|
||||
vals := strings.Split(val, ",")
|
||||
elemType := destFieldType.Elem()
|
||||
sliceVal := reflect.MakeSlice(destFieldType, len(vals), len(vals))
|
||||
|
||||
for i, tElem := range vals {
|
||||
newElem := reflect.New(elemType)
|
||||
tum := newElem.Interface().(encoding.TextUnmarshaler)
|
||||
err := tum.UnmarshalText([]byte(tElem))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sliceVal.Index(i).Set(newElem.Elem())
|
||||
}
|
||||
|
||||
destFieldVal.Set(sliceVal)
|
||||
|
||||
continue
|
||||
}
|
||||
if destFieldType.Kind() == reflect.Ptr {
|
||||
destFieldType = destFieldType.Elem()
|
||||
}
|
||||
if reflect.ValueOf(ff).CanConvert(destFieldType) {
|
||||
setVal(destFieldVal, ff != "" || o.acceptBlank, ff)
|
||||
} else {
|
||||
panic(fmt.Errorf("unsupported type %T", v))
|
||||
|
|
|
@ -137,7 +137,7 @@ var (
|
|||
TalkgroupFilter: filter.TalkgroupFilter{
|
||||
Talkgroups: []talkgroups.ID{
|
||||
talkgroups.TG(197, 3),
|
||||
talkgroups.TG(197, 4),
|
||||
talkgroups.TG(0, 4),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package talkgroups
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"dynatron.me/x/stillbox/pkg/database"
|
||||
)
|
||||
|
@ -32,6 +36,54 @@ type ID struct {
|
|||
Talkgroup uint32 `json:"tg"`
|
||||
}
|
||||
|
||||
var _ encoding.TextUnmarshaler = (*ID)(nil)
|
||||
|
||||
var ErrBadTG = errors.New("bad talkgroup format")
|
||||
|
||||
func (tid *ID) UnmarshalJSON(j []byte) error {
|
||||
// this is a dirty hack since we cannot implement both TextUnmarshaler
|
||||
// and json.Unmarshaler at the same time. sigh.
|
||||
v := &struct{
|
||||
System uint32 `json:"sys"`
|
||||
Talkgroup uint32 `json:"tg"`
|
||||
}{}
|
||||
|
||||
if tid != nil {
|
||||
v.System, v.Talkgroup = tid.System, tid.Talkgroup
|
||||
}
|
||||
|
||||
err := json.Unmarshal(j, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tid.System, tid.Talkgroup = v.System, v.Talkgroup
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tid *ID) UnmarshalText(txt []byte) error {
|
||||
ar := strings.Split(string(txt), ":")
|
||||
switch len(ar) {
|
||||
case 2:
|
||||
sys, err := strconv.Atoi(ar[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tid.System = uint32(sys)
|
||||
fallthrough
|
||||
case 1:
|
||||
tg, err := strconv.Atoi(ar[len(ar)-1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tid.Talkgroup = uint32(tg)
|
||||
default:
|
||||
return ErrBadTG
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type IDs []ID
|
||||
|
||||
func (t IDs) Tuples() database.TGTuples {
|
||||
|
|
|
@ -34,6 +34,11 @@ func (ej *ExportJob) Export(ctx context.Context, w io.Writer) error {
|
|||
return err
|
||||
}
|
||||
} else {
|
||||
for i, v := range ej.TalkgroupFilter.Talkgroups {
|
||||
if v.System == 0 {
|
||||
ej.TalkgroupFilter.Talkgroups[i].System = uint32(ej.SystemID)
|
||||
}
|
||||
}
|
||||
ids, err := ej.TalkgroupFilter.TGs(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in a new issue