initial add call
This commit is contained in:
parent
b3e7d107a8
commit
6928e2432c
6 changed files with 117 additions and 78 deletions
|
@ -33,19 +33,19 @@ RETURNING id, submitter, system, talkgroup, call_date, audio_name, audio_blob, a
|
||||||
`
|
`
|
||||||
|
|
||||||
type AddCallParams struct {
|
type AddCallParams struct {
|
||||||
Submitter pgtype.Int4
|
Submitter *int32 `json:"submitter"`
|
||||||
System int32
|
System int `json:"system"`
|
||||||
Talkgroup int32
|
Talkgroup int `json:"talkgroup"`
|
||||||
CallDate pgtype.Timestamp
|
CallDate pgtype.Timestamp `json:"call_date"`
|
||||||
AudioName pgtype.Text
|
AudioName *string `json:"audio_name"`
|
||||||
AudioBlob []byte
|
AudioBlob []byte `json:"audio_blob"`
|
||||||
AudioType pgtype.Text
|
AudioType *string `json:"audio_type"`
|
||||||
AudioUrl pgtype.Text
|
AudioUrl *string `json:"audio_url"`
|
||||||
Frequency pgtype.Int4
|
Frequency *int32 `json:"frequency"`
|
||||||
Frequencies []byte
|
Frequencies []byte `json:"frequencies"`
|
||||||
Patches []byte
|
Patches []byte `json:"patches"`
|
||||||
TgLabel pgtype.Text
|
TgLabel *string `json:"tg_label"`
|
||||||
Source pgtype.Text
|
Source *string `json:"source"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) AddCall(ctx context.Context, arg AddCallParams) (Call, error) {
|
func (q *Queries) AddCall(ctx context.Context, arg AddCallParams) (Call, error) {
|
||||||
|
@ -89,7 +89,7 @@ const setCallTranscript = `-- name: SetCallTranscript :exec
|
||||||
UPDATE calls SET transcript = $2 WHERE id = $1
|
UPDATE calls SET transcript = $2 WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) SetCallTranscript(ctx context.Context, iD uuid.UUID, transcript pgtype.Text) error {
|
func (q *Queries) SetCallTranscript(ctx context.Context, iD uuid.UUID, transcript *string) error {
|
||||||
_, err := q.db.Exec(ctx, setCallTranscript, iD, transcript)
|
_, err := q.db.Exec(ctx, setCallTranscript, iD, transcript)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,79 +10,79 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type ApiKey struct {
|
type ApiKey struct {
|
||||||
ID int32
|
ID int32 `json:"id"`
|
||||||
Owner pgtype.Int4
|
Owner *int32 `json:"owner"`
|
||||||
CreatedAt pgtype.Timestamp
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
Expires pgtype.Timestamp
|
Expires pgtype.Timestamp `json:"expires"`
|
||||||
Disabled pgtype.Bool
|
Disabled *bool `json:"disabled"`
|
||||||
ApiKey uuid.UUID
|
ApiKey uuid.UUID `json:"api_key"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Call struct {
|
type Call struct {
|
||||||
ID uuid.UUID
|
ID uuid.UUID `json:"id"`
|
||||||
Submitter pgtype.Int4
|
Submitter *int32 `json:"submitter"`
|
||||||
System int32
|
System int `json:"system"`
|
||||||
Talkgroup int32
|
Talkgroup int `json:"talkgroup"`
|
||||||
CallDate pgtype.Timestamp
|
CallDate pgtype.Timestamp `json:"call_date"`
|
||||||
AudioName pgtype.Text
|
AudioName *string `json:"audio_name"`
|
||||||
AudioBlob []byte
|
AudioBlob []byte `json:"audio_blob"`
|
||||||
AudioType pgtype.Text
|
AudioType *string `json:"audio_type"`
|
||||||
AudioUrl pgtype.Text
|
AudioUrl *string `json:"audio_url"`
|
||||||
Frequency pgtype.Int4
|
Frequency *int32 `json:"frequency"`
|
||||||
Frequencies []byte
|
Frequencies []byte `json:"frequencies"`
|
||||||
Patches []byte
|
Patches []byte `json:"patches"`
|
||||||
TgLabel pgtype.Text
|
TgLabel *string `json:"tg_label"`
|
||||||
Source pgtype.Text
|
Source *string `json:"source"`
|
||||||
Transcript pgtype.Text
|
Transcript *string `json:"transcript"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Incident struct {
|
type Incident struct {
|
||||||
ID uuid.UUID
|
ID uuid.UUID `json:"id"`
|
||||||
Name string
|
Name string `json:"name"`
|
||||||
Description pgtype.Text
|
Description *string `json:"description"`
|
||||||
StartTime pgtype.Timestamp
|
StartTime pgtype.Timestamp `json:"start_time"`
|
||||||
EndTime pgtype.Timestamp
|
EndTime pgtype.Timestamp `json:"end_time"`
|
||||||
Location []byte
|
Location []byte `json:"location"`
|
||||||
Metadata []byte
|
Metadata []byte `json:"metadata"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type IncidentsCall struct {
|
type IncidentsCall struct {
|
||||||
IncidentID uuid.UUID
|
IncidentID uuid.UUID `json:"incident_id"`
|
||||||
CallID uuid.UUID
|
CallID uuid.UUID `json:"call_id"`
|
||||||
Notes []byte
|
Notes []byte `json:"notes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Setting struct {
|
type Setting struct {
|
||||||
Name string
|
Name string `json:"name"`
|
||||||
UpdatedBy pgtype.Int4
|
UpdatedBy *int32 `json:"updated_by"`
|
||||||
Value []byte
|
Value []byte `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type System struct {
|
type System struct {
|
||||||
ID int32
|
ID int `json:"id"`
|
||||||
Name string
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Talkgroup struct {
|
type Talkgroup struct {
|
||||||
SystemID int32
|
SystemID int `json:"system_id"`
|
||||||
Tgid int32
|
Tgid int `json:"tgid"`
|
||||||
Name pgtype.Text
|
Name *string `json:"name"`
|
||||||
Frequency pgtype.Int4
|
Frequency *int32 `json:"frequency"`
|
||||||
AutoCreated pgtype.Bool
|
AutoCreated *bool `json:"auto_created"`
|
||||||
Metadata []byte
|
Metadata []byte `json:"metadata"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TalkgroupsTag struct {
|
type TalkgroupsTag struct {
|
||||||
SystemID int32
|
SystemID int `json:"system_id"`
|
||||||
TalkgroupID int32
|
TalkgroupID int `json:"talkgroup_id"`
|
||||||
Tags []string
|
Tags []string `json:"tags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID int32
|
ID int32 `json:"id"`
|
||||||
Username string
|
Username string `json:"username"`
|
||||||
Password string
|
Password string `json:"password"`
|
||||||
Email string
|
Email string `json:"email"`
|
||||||
IsAdmin pgtype.Bool
|
IsAdmin *bool `json:"is_admin"`
|
||||||
Prefs []byte
|
Prefs []byte `json:"prefs"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ SELECT tags FROM talkgroups_tags
|
||||||
WHERE talkgroup_id = $1
|
WHERE talkgroup_id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetTalkgroupTags(ctx context.Context, talkgroupID int32) ([]string, error) {
|
func (q *Queries) GetTalkgroupTags(ctx context.Context, talkgroupID int) ([]string, error) {
|
||||||
row := q.db.QueryRow(ctx, getTalkgroupTags, talkgroupID)
|
row := q.db.QueryRow(ctx, getTalkgroupTags, talkgroupID)
|
||||||
var tags []string
|
var tags []string
|
||||||
err := row.Scan(&tags)
|
err := row.Scan(&tags)
|
||||||
|
@ -27,8 +27,8 @@ WHERE tags && ARRAY[$1]
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetTalkgroupsWithAllTagsRow struct {
|
type GetTalkgroupsWithAllTagsRow struct {
|
||||||
SystemID int32
|
SystemID int `json:"system_id"`
|
||||||
TalkgroupID int32
|
TalkgroupID int `json:"talkgroup_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetTalkgroupsWithAllTags(ctx context.Context, tags []string) ([]GetTalkgroupsWithAllTagsRow, error) {
|
func (q *Queries) GetTalkgroupsWithAllTags(ctx context.Context, tags []string) ([]GetTalkgroupsWithAllTagsRow, error) {
|
||||||
|
@ -57,8 +57,8 @@ WHERE tags @> ARRAY[$1]
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetTalkgroupsWithAnyTagsRow struct {
|
type GetTalkgroupsWithAnyTagsRow struct {
|
||||||
SystemID int32
|
SystemID int `json:"system_id"`
|
||||||
TalkgroupID int32
|
TalkgroupID int `json:"talkgroup_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetTalkgroupsWithAnyTags(ctx context.Context, tags []string) ([]GetTalkgroupsWithAnyTagsRow, error) {
|
func (q *Queries) GetTalkgroupsWithAnyTags(ctx context.Context, tags []string) ([]GetTalkgroupsWithAnyTagsRow, error) {
|
||||||
|
@ -86,7 +86,7 @@ INSERT INTO talkgroups_tags(system_id, talkgroup_id, tags) VALUES($1, $2, $3)
|
||||||
ON CONFLICT (system_id, talkgroup_id) DO UPDATE SET tags = $3
|
ON CONFLICT (system_id, talkgroup_id) DO UPDATE SET tags = $3
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) SetTalkgroupTags(ctx context.Context, systemID int32, talkgroupID int32, tags []string) error {
|
func (q *Queries) SetTalkgroupTags(ctx context.Context, systemID int, talkgroupID int, tags []string) error {
|
||||||
_, err := q.db.Exec(ctx, setTalkgroupTags, systemID, talkgroupID, tags)
|
_, err := q.db.Exec(ctx, setTalkgroupTags, systemID, talkgroupID, tags)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ INSERT INTO api_keys(
|
||||||
RETURNING id, owner, created_at, expires, disabled, api_key
|
RETURNING id, owner, created_at, expires, disabled, api_key
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) CreateAPIKey(ctx context.Context, owner pgtype.Int4, expires pgtype.Timestamp, disabled pgtype.Bool) (ApiKey, error) {
|
func (q *Queries) CreateAPIKey(ctx context.Context, owner *int32, expires pgtype.Timestamp, disabled *bool) (ApiKey, error) {
|
||||||
row := q.db.QueryRow(ctx, createAPIKey, owner, expires, disabled)
|
row := q.db.QueryRow(ctx, createAPIKey, owner, expires, disabled)
|
||||||
var i ApiKey
|
var i ApiKey
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
|
@ -48,10 +48,10 @@ RETURNING id, username, password, email, is_admin, prefs
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateUserParams struct {
|
type CreateUserParams struct {
|
||||||
Username string
|
Username string `json:"username"`
|
||||||
Password string
|
Password string `json:"password"`
|
||||||
Email string
|
Email string `json:"email"`
|
||||||
IsAdmin pgtype.Bool
|
IsAdmin *bool `json:"is_admin"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, error) {
|
func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, error) {
|
||||||
|
|
|
@ -11,6 +11,8 @@ import (
|
||||||
|
|
||||||
"dynatron.me/x/stillbox/pkg/gordio/database"
|
"dynatron.me/x/stillbox/pkg/gordio/database"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/jackc/pgtype"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type callUploadRequest struct {
|
type callUploadRequest struct {
|
||||||
|
@ -32,6 +34,29 @@ type callUploadRequest struct {
|
||||||
TalkgroupTag string `form:"talkgroupTag"`
|
TalkgroupTag string `form:"talkgroupTag"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AddCallParams struct {
|
||||||
|
Submitter pgtype.Int4 `json:"submitter"`
|
||||||
|
System int32 `json:"system"`
|
||||||
|
Talkgroup int32 `json:"talkgroup"`
|
||||||
|
CallDate pgtype.Timestamp `json:"call_date"`
|
||||||
|
AudioName pgtype.Text `json:"audio_name"`
|
||||||
|
AudioBlob []byte `json:"audio_blob"`
|
||||||
|
AudioType pgtype.Text `json:"audio_type"`
|
||||||
|
AudioUrl pgtype.Text `json:"audio_url"`
|
||||||
|
Frequency pgtype.Int4 `json:"frequency"`
|
||||||
|
Frequencies []byte `json:"frequencies"`
|
||||||
|
Patches []byte `json:"patches"`
|
||||||
|
TgLabel pgtype.Text `json:"tg_label"`
|
||||||
|
Source pgtype.Text `json:"source"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (car *callUploadRequest) ToAddCallParams(submitter int) database.AddCallParams {
|
||||||
|
return database.AddCallParams{
|
||||||
|
Submitter: submitter,
|
||||||
|
System: car.System,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) routeCallUpload(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) routeCallUpload(w http.ResponseWriter, r *http.Request) {
|
||||||
err := r.ParseMultipartForm(1024 * 1024 * 2) // 2MB
|
err := r.ParseMultipartForm(1024 * 1024 * 2) // 2MB
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -44,7 +69,8 @@ func (s *Server) routeCallUpload(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Error(w, "cannot parse key "+err.Error(), http.StatusBadRequest)
|
http.Error(w, "cannot parse key "+err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
apik, err := s.db.GetAPIKey(r.Context(), keyUuid)
|
db := database.FromCtx(r.Context())
|
||||||
|
apik, err := db.GetAPIKey(r.Context(), keyUuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if database.IsNoRows(err) {
|
if database.IsNoRows(err) {
|
||||||
http.Error(w, "bad key", http.StatusUnauthorized)
|
http.Error(w, "bad key", http.StatusUnauthorized)
|
||||||
|
@ -57,6 +83,7 @@ func (s *Server) routeCallUpload(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
if apik.Disabled.Bool || (apik.Expires.Valid && time.Now().After(apik.Expires.Time)) {
|
if apik.Disabled.Bool || (apik.Expires.Valid && time.Now().After(apik.Expires.Time)) {
|
||||||
http.Error(w, "disabled", http.StatusUnauthorized)
|
http.Error(w, "disabled", http.StatusUnauthorized)
|
||||||
|
log.Error().Str("key", apik.ApiKey.String()).Msg("key disabled")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +94,12 @@ func (s *Server) routeCallUpload(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write([]byte(fmt.Sprintf("%#v", call)))
|
dbCall, err := db.AddCall(r.Context(), call.ToAddCallParams())
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "internal error", http.StatusInternalServerError)
|
||||||
|
log.Error().Err(err).Msg("add call")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (car *callUploadRequest) fill(r *http.Request) error {
|
func (car *callUploadRequest) fill(r *http.Request) error {
|
||||||
|
|
|
@ -9,9 +9,16 @@ sql:
|
||||||
out: "../pkg/gordio/database"
|
out: "../pkg/gordio/database"
|
||||||
sql_package: "pgx/v5"
|
sql_package: "pgx/v5"
|
||||||
query_parameter_limit: 3
|
query_parameter_limit: 3
|
||||||
|
emit_json_tags: true
|
||||||
|
emit_pointers_for_null_types: true
|
||||||
overrides:
|
overrides:
|
||||||
- db_type: "uuid"
|
- db_type: "uuid"
|
||||||
go_type:
|
go_type:
|
||||||
import: "github.com/google/uuid"
|
import: "github.com/google/uuid"
|
||||||
type: "UUID"
|
type: "UUID"
|
||||||
|
- db_type: "pg_catalog.int4"
|
||||||
|
go_type: "int"
|
||||||
|
- db_type: "pg_catalog.serial4"
|
||||||
|
go_type: "int"
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue