File: mps.go

package info (click to toggle)
pat 0.19.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,296 kB
  • sloc: javascript: 3,891; sh: 124; makefile: 11
file content (108 lines) | stat: -rw-r--r-- 2,834 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package cmsapi

import (
	"context"
	"encoding/json"
	"net/url"
	"regexp"
	"strconv"
	"time"
)

const (
	PathMPSAdd    = "/mps/add"
	PathMPSDelete = "/mps/delete"
	PathMPSGet    = "/mps/get"
	PathMPSList   = "/mps/list"
)

// MessagePickupStationRecord represents an MPS record
type MessagePickupStationRecord struct {
	Callsign    string     `json:"callsign"`
	MpsCallsign string     `json:"mpsCallsign"`
	Timestamp   DotNetTime `json:"timestamp"`
}

// DotNetTime handles .NET-style JSON date serialization
type DotNetTime struct{ time.Time }

// UnmarshalJSON implements custom JSON unmarshaling for .NET date format
func (t *DotNetTime) UnmarshalJSON(b []byte) error {
	var str string
	if err := json.Unmarshal(b, &str); err != nil {
		return err
	}

	// Handle .NET date format: \/Date(milliseconds)\/
	re := regexp.MustCompile(`\/Date\((-?\d+)\)\/`)
	matches := re.FindStringSubmatch(str)
	if len(matches) == 2 {
		millis, err := strconv.ParseInt(matches[1], 10, 64)
		if err != nil {
			return err
		}
		t.Time = time.Unix(millis/1000, (millis%1000)*1000000)
		return nil
	}

	// Fall back to RFC3339 format
	parsedTime, err := time.Parse(time.RFC3339, str)
	if err == nil {
		t.Time = parsedTime
		return nil
	}

	// Fall back to RFC1123 format
	parsedTime, err = time.Parse(time.RFC1123, str)
	if err == nil {
		t.Time = parsedTime
		return nil
	}

	return err
}

// MPSAdd adds an entry to the MPS table
func MPSAdd(ctx context.Context, requester, callsign, password, mpsCallsign string) error {
	params := url.Values{
		"requester":   []string{requester},
		"callsign":    []string{callsign},
		"password":    []string{password},
		"mpsCallsign": []string{mpsCallsign},
	}
	var resp struct{ ResponseStatus responseStatus }
	if err := getJSON(ctx, PathMPSAdd, params, &resp); err != nil {
		return err
	}
	return resp.ResponseStatus.errorOrNil()
}

// MPSDelete deletes all MPS records for the specified callsign
func MPSDelete(ctx context.Context, requester, callsign, password string) error {
	params := url.Values{
		"requester": []string{requester},
		"callsign":  []string{callsign},
		"password":  []string{password},
	}
	var resp struct{ ResponseStatus responseStatus }
	if err := getJSON(ctx, PathMPSDelete, params, &resp); err != nil {
		return err
	}
	return resp.ResponseStatus.errorOrNil()
}

// MPSGet returns all MPS records for the specified callsign
func MPSGet(ctx context.Context, requester, callsign string) ([]MessagePickupStationRecord, error) {
	params := url.Values{
		"requester": []string{requester},
		"callsign":  []string{callsign},
	}
	var resp struct {
		MpsList        []MessagePickupStationRecord `json:"mpsList"`
		ResponseStatus responseStatus
	}
	if err := getJSON(ctx, PathMPSGet, params, &resp); err != nil {
		return nil, err
	}
	return resp.MpsList, resp.ResponseStatus.errorOrNil()
}