refactor: move more commands to internal/cmd (#207)
* refactor: move more commands to internal/cmd Part of https://github.com/ooni/probe/issues/1335. We would like all commands to be at the same level of engine rather than inside engine (now that we can do it). * fix: update .gitignore * refactor: also move jafar outside engine * We should be good now?
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
# apitool
|
||||
|
||||
This directory contains a tool to fetch measurements. This tool is
|
||||
intended to sporadically fetch measurements, not for batch downloading.
|
||||
|
||||
Please, see https://ooni.org/data for information pertaining how to
|
||||
access OONI data in bulk. Please see https://explorer.ooni.org if your
|
||||
intent is to navigate and explore OONI data.
|
||||
@@ -0,0 +1,115 @@
|
||||
// Command apitool is a simple tool to fetch individual OONI measurements.
|
||||
//
|
||||
// This tool IS NOT intended for batch downloading.
|
||||
//
|
||||
// Please, see https://ooni.org/data for information pertaining how to
|
||||
// access OONI data in bulk. Please see https://explorer.ooni.org if your
|
||||
// intent is to navigate and explore OONI data
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/atomicx"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/httpx"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/kvstore"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/probeservices"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/version"
|
||||
)
|
||||
|
||||
func newclient() probeservices.Client {
|
||||
txp := netx.NewHTTPTransport(netx.Config{Logger: log.Log})
|
||||
ua := fmt.Sprintf("apitool/%s ooniprobe-engine/%s", version.Version, version.Version)
|
||||
return probeservices.Client{
|
||||
Client: httpx.Client{
|
||||
BaseURL: "https://ams-pg.ooni.org/",
|
||||
HTTPClient: &http.Client{Transport: txp},
|
||||
Logger: log.Log,
|
||||
UserAgent: ua,
|
||||
},
|
||||
LoginCalls: atomicx.NewInt64(),
|
||||
RegisterCalls: atomicx.NewInt64(),
|
||||
StateFile: probeservices.NewStateFile(kvstore.NewMemoryKeyValueStore()),
|
||||
}
|
||||
}
|
||||
|
||||
var osExit = os.Exit
|
||||
|
||||
func fatalOnError(err error, message string) {
|
||||
if err != nil {
|
||||
log.WithError(err).Error(message)
|
||||
osExit(1) // overridable from tests
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
debug = flag.Bool("v", false, "Enable verbose mode")
|
||||
input = flag.String("input", "", "Input of the measurement")
|
||||
mode = flag.String("mode", "", "One of: check, meta, raw")
|
||||
reportid = flag.String("report-id", "", "Report ID of the measurement")
|
||||
)
|
||||
|
||||
var logmap = map[bool]log.Level{
|
||||
true: log.DebugLevel,
|
||||
false: log.InfoLevel,
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
log.SetLevel(logmap[*debug])
|
||||
client := newclient()
|
||||
switch *mode {
|
||||
case "check":
|
||||
check(client)
|
||||
case "meta":
|
||||
meta(client)
|
||||
case "raw":
|
||||
raw(client)
|
||||
default:
|
||||
fatalOnError(fmt.Errorf("invalid -mode flag value: %s", *mode), "usage error")
|
||||
}
|
||||
}
|
||||
|
||||
func check(c probeservices.Client) {
|
||||
found, err := c.CheckReportID(context.Background(), *reportid)
|
||||
fatalOnError(err, "c.CheckReportID failed")
|
||||
fmt.Printf("%+v\n", found)
|
||||
}
|
||||
|
||||
func meta(c probeservices.Client) {
|
||||
pprint(mmeta(c, false))
|
||||
}
|
||||
|
||||
func raw(c probeservices.Client) {
|
||||
m := mmeta(c, true)
|
||||
rm := []byte(m.RawMeasurement)
|
||||
var opaque interface{}
|
||||
err := json.Unmarshal(rm, &opaque)
|
||||
fatalOnError(err, "json.Unmarshal failed")
|
||||
pprint(opaque)
|
||||
}
|
||||
|
||||
func pprint(opaque interface{}) {
|
||||
data, err := json.MarshalIndent(opaque, "", " ")
|
||||
fatalOnError(err, "json.MarshalIndent failed")
|
||||
fmt.Printf("%s\n", data)
|
||||
}
|
||||
|
||||
func mmeta(c probeservices.Client, full bool) *probeservices.MeasurementMeta {
|
||||
config := probeservices.MeasurementMetaConfig{
|
||||
ReportID: *reportid,
|
||||
Full: full,
|
||||
Input: *input,
|
||||
}
|
||||
ctx := context.Background()
|
||||
m, err := c.GetMeasurementMeta(ctx, config)
|
||||
fatalOnError(err, "client.GetMeasurementMeta failed")
|
||||
return m
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func init() {
|
||||
*reportid = `20201209T052225Z_urlgetter_IT_30722_n1_E1VUhMz08SEkgYFU`
|
||||
*input = `https://www.example.org`
|
||||
}
|
||||
|
||||
func TestCheck(t *testing.T) {
|
||||
*mode = "check"
|
||||
main()
|
||||
}
|
||||
|
||||
func TestRaw(t *testing.T) {
|
||||
*mode = "raw"
|
||||
main()
|
||||
}
|
||||
|
||||
func TestMeta(t *testing.T) {
|
||||
*mode = "meta"
|
||||
main()
|
||||
}
|
||||
|
||||
func TestInvalidMode(t *testing.T) {
|
||||
defer func() {
|
||||
if recover() == nil {
|
||||
t.Fatal("the code did not panic")
|
||||
}
|
||||
}()
|
||||
osExit = func(code int) {
|
||||
panic(fmt.Errorf("%d", code))
|
||||
}
|
||||
*mode = "antani"
|
||||
main()
|
||||
}
|
||||
Reference in New Issue
Block a user