package notify import "sort" type fileTransferSummaryGroup struct { Send []fileTransferSummary Receive []fileTransferSummary } type fileTransferSummaryQuery struct { Scope string RuntimeScope string TransportGeneration uint64 MatchTransportGeneration bool } type fileTransferQuery struct { monitor *fileTransferMonitor } func newFileTransferQuery(m *fileTransferMonitor) fileTransferQuery { return fileTransferQuery{monitor: m} } func (q fileTransferQuery) active() fileTransferSummaryGroup { if q.monitor == nil { return fileTransferSummaryGroup{} } return groupFileTransferSummaries(q.monitor.activeSummaries()) } func (q fileTransferQuery) completed() fileTransferSummaryGroup { if q.monitor == nil { return fileTransferSummaryGroup{} } return groupFileTransferSummaries(filterFileTransferSummaries(q.monitor.completedSummaries(), func(summary fileTransferSummary) bool { return summary.Done && !summary.Failed })) } func (q fileTransferQuery) failed() fileTransferSummaryGroup { return groupFileTransferSummaries(filterFileTransferSummaries(latestFileTransferSummaries(q.monitor), func(summary fileTransferSummary) bool { return summary.Failed })) } func (q fileTransferQuery) latestByFileID(fileID string) fileTransferSummaryGroup { if q.monitor == nil || fileID == "" { return fileTransferSummaryGroup{} } return groupFileTransferSummaries(q.monitor.summariesByFileID(fileID)) } func (q fileTransferQuery) latestSendByFileID(fileID string) []fileTransferSummary { if q.monitor == nil || fileID == "" { return nil } return q.monitor.summariesByDirectionAndFileID(fileTransferDirectionSend, fileID) } func (q fileTransferQuery) latestReceiveByFileID(fileID string) []fileTransferSummary { if q.monitor == nil || fileID == "" { return nil } return q.monitor.summariesByDirectionAndFileID(fileTransferDirectionReceive, fileID) } func (q fileTransferQuery) latestByFileIDQuery(fileID string, query fileTransferSummaryQuery) fileTransferSummaryGroup { if q.monitor == nil || fileID == "" { return fileTransferSummaryGroup{} } return groupFileTransferSummaries(filterFileTransferSummaries(q.monitor.runtimeSummariesByFileID(fileID), func(summary fileTransferSummary) bool { return fileTransferSummaryQueryMatch(summary, query) })) } func (q fileTransferQuery) latestSendByFileIDQuery(fileID string, query fileTransferSummaryQuery) []fileTransferSummary { if q.monitor == nil || fileID == "" { return nil } return filterFileTransferSummaries(q.monitor.runtimeSummariesByDirectionAndFileID(fileTransferDirectionSend, fileID), func(summary fileTransferSummary) bool { return fileTransferSummaryQueryMatch(summary, query) }) } func (q fileTransferQuery) latestReceiveByFileIDQuery(fileID string, query fileTransferSummaryQuery) []fileTransferSummary { if q.monitor == nil || fileID == "" { return nil } return filterFileTransferSummaries(q.monitor.runtimeSummariesByDirectionAndFileID(fileTransferDirectionReceive, fileID), func(summary fileTransferSummary) bool { return fileTransferSummaryQueryMatch(summary, query) }) } func latestFileTransferSummaries(m *fileTransferMonitor) []fileTransferSummary { if m == nil { return nil } summaries := append([]fileTransferSummary{}, m.activeSummaries()...) summaries = append(summaries, m.completedSummaries()...) sort.Slice(summaries, func(i int, j int) bool { return fileTransferSummarySortKey(summaries[i]) < fileTransferSummarySortKey(summaries[j]) }) return summaries } func fileTransferSummarySortKey(summary fileTransferSummary) string { return fileTransferMonitorKey(summary.Direction, summary.Scope, summary.FileID) } func groupFileTransferSummaries(src []fileTransferSummary) fileTransferSummaryGroup { var group fileTransferSummaryGroup for _, summary := range src { switch summary.Direction { case fileTransferDirectionReceive: group.Receive = append(group.Receive, summary) case fileTransferDirectionSend: group.Send = append(group.Send, summary) } } return group } func filterFileTransferSummaries(src []fileTransferSummary, keep func(fileTransferSummary) bool) []fileTransferSummary { out := make([]fileTransferSummary, 0, len(src)) for _, summary := range src { if !keep(summary) { continue } out = append(out, summary) } return out } func fileTransferSummaryQueryMatch(summary fileTransferSummary, query fileTransferSummaryQuery) bool { if query.Scope != "" && normalizeFileScope(summary.Scope) != normalizeFileScope(query.Scope) { return false } if query.RuntimeScope != "" && normalizeFileScope(summary.RuntimeScope) != normalizeFileScope(query.RuntimeScope) { return false } if query.MatchTransportGeneration && summary.TransportGeneration != query.TransportGeneration { return false } return true }