1. the description of the command and the helper function are clear hints that the command is intended to show a single JSON measurement at a time (also the use case seems clear) [*] 2. the function used to read lines was failing for all my measurements that take input. Since that was not the optimal pattern anyway, use a better pattern to fix it. 3. some changes are automatically applied by my editor (VSCode with the Go plugin) and I am fine with them. 4. while reading code, I also applied my preferred pattern wrt whitespaces, i.e.: no whitespace inside functions, if a function feels too long in this way, just break it. Closes #57 [*] Even if we want to show many measurements at a time, which does not seem needed, given the UI patterns, this functionality won't be P0. What is P0 is to bless a new beta and give to @sarathms binaries for all archs that support a basic `show`.
		
			
				
	
	
		
			129 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package list
 | 
						|
 | 
						|
import (
 | 
						|
	"github.com/alecthomas/kingpin"
 | 
						|
	"github.com/apex/log"
 | 
						|
	"github.com/ooni/probe-cli/internal/cli/root"
 | 
						|
	"github.com/ooni/probe-cli/internal/database"
 | 
						|
	"github.com/ooni/probe-cli/internal/output"
 | 
						|
)
 | 
						|
 | 
						|
func init() {
 | 
						|
	cmd := root.Command("list", "List results")
 | 
						|
	resultID := cmd.Arg("id", "the id of the result to list measurements for").Int64()
 | 
						|
	cmd.Action(func(_ *kingpin.ParseContext) error {
 | 
						|
		ctx, err := root.Init()
 | 
						|
		if err != nil {
 | 
						|
			log.WithError(err).Error("failed to initialize root context")
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		if *resultID > 0 {
 | 
						|
			measurements, err := database.ListMeasurements(ctx.DB, *resultID)
 | 
						|
			if err != nil {
 | 
						|
				log.WithError(err).Error("failed to list measurements")
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			msmtSummary := output.MeasurementSummaryData{
 | 
						|
				TotalCount:         0,
 | 
						|
				AnomalyCount:       0,
 | 
						|
				DataUsageUp:        0.0,
 | 
						|
				DataUsageDown:      0.0,
 | 
						|
				TotalRuntime:       0,
 | 
						|
				ASN:                0,
 | 
						|
				NetworkName:        "",
 | 
						|
				NetworkCountryCode: "ZZ",
 | 
						|
			}
 | 
						|
			isFirst := true
 | 
						|
			isLast := false
 | 
						|
			for idx, msmt := range measurements {
 | 
						|
				if idx > 0 {
 | 
						|
					isFirst = false
 | 
						|
				}
 | 
						|
				if idx == len(measurements)-1 {
 | 
						|
					isLast = true
 | 
						|
				}
 | 
						|
				// We assume that since these are summary level information the first
 | 
						|
				// item will contain the information necessary.
 | 
						|
				if isFirst {
 | 
						|
					msmtSummary.TotalRuntime = msmt.Result.Runtime
 | 
						|
					msmtSummary.DataUsageUp = msmt.DataUsageUp
 | 
						|
					msmtSummary.DataUsageDown = msmt.DataUsageDown
 | 
						|
					msmtSummary.NetworkName = msmt.NetworkName
 | 
						|
					msmtSummary.NetworkCountryCode = msmt.Network.CountryCode
 | 
						|
					msmtSummary.ASN = msmt.ASN
 | 
						|
					msmtSummary.StartTime = msmt.Measurement.StartTime
 | 
						|
				}
 | 
						|
				if msmt.IsAnomaly.Bool == true {
 | 
						|
					msmtSummary.AnomalyCount++
 | 
						|
				}
 | 
						|
				msmtSummary.TotalCount++
 | 
						|
				output.MeasurementItem(msmt, isFirst, isLast)
 | 
						|
			}
 | 
						|
			output.MeasurementSummary(msmtSummary)
 | 
						|
		} else {
 | 
						|
			doneResults, incompleteResults, err := database.ListResults(ctx.DB)
 | 
						|
			if err != nil {
 | 
						|
				log.WithError(err).Error("failed to list results")
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			if len(incompleteResults) > 0 {
 | 
						|
				output.SectionTitle("Incomplete results")
 | 
						|
			}
 | 
						|
			for idx, result := range incompleteResults {
 | 
						|
				output.ResultItem(output.ResultItemData{
 | 
						|
					ID:                      result.Result.ID,
 | 
						|
					Index:                   idx,
 | 
						|
					TotalCount:              len(incompleteResults),
 | 
						|
					Name:                    result.TestGroupName,
 | 
						|
					StartTime:               result.StartTime,
 | 
						|
					NetworkName:             result.Network.NetworkName,
 | 
						|
					Country:                 result.Network.CountryCode,
 | 
						|
					ASN:                     result.Network.ASN,
 | 
						|
					MeasurementCount:        0,
 | 
						|
					MeasurementAnomalyCount: 0,
 | 
						|
					TestKeys:                "{}", // FIXME this used to be Summary we probably need to use a list now
 | 
						|
					Done:                    result.IsDone,
 | 
						|
					DataUsageUp:             result.DataUsageUp,
 | 
						|
					DataUsageDown:           result.DataUsageDown,
 | 
						|
				})
 | 
						|
			}
 | 
						|
			resultSummary := output.ResultSummaryData{}
 | 
						|
			netCount := make(map[uint]int)
 | 
						|
			output.SectionTitle("Results")
 | 
						|
			for idx, result := range doneResults {
 | 
						|
				totalCount, anmlyCount, err := database.GetMeasurementCounts(ctx.DB, result.Result.ID)
 | 
						|
				if err != nil {
 | 
						|
					log.WithError(err).Error("failed to list measurement counts")
 | 
						|
				}
 | 
						|
				testKeys, err := database.GetResultTestKeys(ctx.DB, result.Result.ID)
 | 
						|
				if err != nil {
 | 
						|
					log.WithError(err).Error("failed to get testKeys")
 | 
						|
				}
 | 
						|
				output.ResultItem(output.ResultItemData{
 | 
						|
					ID:                      result.Result.ID,
 | 
						|
					Index:                   idx,
 | 
						|
					TotalCount:              len(doneResults),
 | 
						|
					Name:                    result.TestGroupName,
 | 
						|
					StartTime:               result.StartTime,
 | 
						|
					NetworkName:             result.Network.NetworkName,
 | 
						|
					Country:                 result.Network.CountryCode,
 | 
						|
					ASN:                     result.Network.ASN,
 | 
						|
					TestKeys:                testKeys,
 | 
						|
					MeasurementCount:        totalCount,
 | 
						|
					MeasurementAnomalyCount: anmlyCount,
 | 
						|
					Done:                    result.IsDone,
 | 
						|
					DataUsageUp:             result.DataUsageUp,
 | 
						|
					DataUsageDown:           result.DataUsageDown,
 | 
						|
				})
 | 
						|
				resultSummary.TotalTests++
 | 
						|
				netCount[result.Network.ASN]++
 | 
						|
				resultSummary.TotalDataUsageUp += result.DataUsageUp
 | 
						|
				resultSummary.TotalDataUsageDown += result.DataUsageDown
 | 
						|
			}
 | 
						|
			resultSummary.TotalNetworks = int64(len(netCount))
 | 
						|
			output.ResultSummary(resultSummary)
 | 
						|
		}
 | 
						|
		return nil
 | 
						|
	})
 | 
						|
}
 |