diff --git a/README.md b/README.md index 69008cb..1701357 100644 --- a/README.md +++ b/README.md @@ -23,3 +23,7 @@ include an ADIF test case to demonstrate your bug. ### Original repository https://github.com/Matir/adifparser + +### See goadiftools repository for the tools + +All tools by @jj1bdx are moved to https://github.com/jj1bdx/goadiftools diff --git a/goadifdump/goadifdump.go b/goadifdump/goadifdump.go deleted file mode 100644 index 12b6a35..0000000 --- a/goadifdump/goadifdump.go +++ /dev/null @@ -1,75 +0,0 @@ -// goadifdump: reformat preserve all ADIF file fields without deduping -// by Kenji Rikitake, JJ1BDX -// Usage: goadifdump [-f infile] [-o outfile] -// -// This is a skeleton code set for adding further processing -// -// Coding convention: -// Use reader for reading each record (with ADIFReader) -// Use writer for writing each record (with ADIFWriter) - -package main - -import ( - "flag" - "fmt" - "github.com/jj1bdx/adifparser" - "io" - "os" -) - -func main() { - var infile = flag.String("f", "", "input file (stdout in none)") - var outfile = flag.String("o", "", "output file (stdout if none)") - - var fp *os.File - var err error - - flag.Parse() - - if *infile == "" { - fp = os.Stdin - } else { - fp, err = os.Open(*infile) - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - } - - var writer adifparser.ADIFWriter - var writefp *os.File - if *outfile != "" { - writefp, err = os.Create(*outfile) - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - writer = adifparser.NewADIFWriter(writefp) - } else { - writefp = nil - writer = adifparser.NewADIFWriter(os.Stdout) - } - - // For deduping, use this filter API: - // reader := adifparser.NewDedupeADIFReader(fp) - - reader := adifparser.NewADIFReader(fp) - for record, err := reader.ReadRecord(); record != nil || err != nil; record, err = reader.ReadRecord() { - if err != nil { - if err != io.EOF { - fmt.Fprint(os.Stderr, err) - } - break // when io.EOF break the loop! - } - - // process things here with the record - writer.WriteRecord(record) - - } - - if writefp != os.Stdout { - writefp.Close() - } - fmt.Fprintf(os.Stderr, "Total records: %d\n", reader.RecordCount()) -} diff --git a/goadifstat/goadifstat.go b/goadifstat/goadifstat.go deleted file mode 100644 index 16eb33a..0000000 --- a/goadifstat/goadifstat.go +++ /dev/null @@ -1,264 +0,0 @@ -// goadifstat: check statistics of ADIF ADI files -// by Kenji Rikitake, JJ1BDX -// Usage: goadifstat [-f infile] [-o outfile] [-q query type] -// Valid query types: bands, country, dxcc, gridsquare, modes, nqso, submodes - -package main - -import ( - "bufio" - "flag" - "fmt" - "github.com/jj1bdx/adifparser" - "io" - "os" - "sort" - "strconv" - "strings" -) - -var ErrNoSuchField = adifparser.ErrNoSuchField - -var bandList = []string{ - "2190M", "630M", "560M", "160M", "80M", "60M", - "40M", "30M", "20M", "17M", "15M", "12M", - "10M", "6M", "5M", "4M", "2M", "1.25M", - "70CM", "33CM", "23CM", "13CM", "9CM", "6CM", - "3CM", "1.25CM", "6MM", "4MM", "2.5MM", "2MM", - "1MM"} - -var mapBand map[string]int -var mapCountry map[string]int -var mapDxcc map[int]bool -var mapGrid map[string]bool -var mapMode map[string]int -var mapSubmode map[string]int - -func initStatMaps() { - mapBand = make(map[string]int) - mapCountry = make(map[string]int) - mapDxcc = make(map[int]bool) - mapGrid = make(map[string]bool) - mapMode = make(map[string]int) - mapSubmode = make(map[string]int) -} - -func updateStatMaps(record adifparser.ADIFRecord) { - var err error - var exists bool - var key string - var keynum int - - // band - key, err = record.GetValue("band") - if err != nil && err != ErrNoSuchField { - fmt.Fprint(os.Stderr, err) - } else { - // Use uppercase for band names - key = strings.ToUpper(key) - _, exists = mapBand[key] - if exists { - mapBand[key]++ - } else { - mapBand[key] = 1 - } - } - - // country - key, err = record.GetValue("country") - if err != nil && err != ErrNoSuchField { - fmt.Fprint(os.Stderr, err) - } else { - if key == "" { - key = "(UNKNOWN)" - } else { - // Use uppercase for country names - key = strings.ToUpper(key) - } - _, exists = mapCountry[key] - if exists { - mapCountry[key]++ - } else { - mapCountry[key] = 1 - } - } - - // dxcc - key, err = record.GetValue("dxcc") - if err != nil && err != ErrNoSuchField { - fmt.Fprint(os.Stderr, err) - } else if key != "" { - // DXCC values are integers - keynum, err = strconv.Atoi(key) - if err != nil && err != ErrNoSuchField { - fmt.Fprint(os.Stderr, err) - } else { - _, exists = mapDxcc[keynum] - if !exists { - mapDxcc[keynum] = true - } - } - } - - // grid - key, err = record.GetValue("gridsquare") - if err != nil && err != ErrNoSuchField { - fmt.Fprint(os.Stderr, err) - } else if len(key) >= 4 { - // Pick first four letters only - key = key[0:4] - // Grid locator first two letters are uppercase - key = strings.ToUpper(key) - _, exists = mapGrid[key] - if !exists { - mapGrid[key] = true - } - } - - // mode - key, err = record.GetValue("mode") - if err != nil && err != ErrNoSuchField { - fmt.Fprint(os.Stderr, err) - } else { - key = strings.ToUpper(key) - _, exists = mapMode[key] - if exists { - mapMode[key]++ - } else { - mapMode[key] = 1 - } - } - - // submode - key, err = record.GetValue("submode") - if err != nil && err != ErrNoSuchField { - fmt.Fprint(os.Stderr, err) - } else if key != "" { - key = strings.ToUpper(key) - _, exists = mapSubmode[key] - if exists { - mapSubmode[key]++ - } else { - mapSubmode[key] = 1 - } - } -} - -func main() { - var infile = flag.String("f", "", "input file (stdin if none)") - var outfile = flag.String("o", "", "output file (stdout if none)") - var query = flag.String("q", "", "query type") - var fp *os.File - var err error - - flag.Parse() - - if *infile == "" { - fp = os.Stdin - } else { - fp, err = os.Open(*infile) - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - } - - var writefp *os.File - var writer *bufio.Writer - if *outfile != "" { - writefp, err = os.Create(*outfile) - writer = bufio.NewWriter(writefp) - } else { - writefp = nil - writer = bufio.NewWriter(os.Stdout) - } - - initStatMaps() - - reader := adifparser.NewADIFReader(fp) - for record, err := reader.ReadRecord(); record != nil || err != nil; record, err = reader.ReadRecord() { - if err != nil { - if err != io.EOF { - fmt.Fprint(os.Stderr, err) - } - break // when io.EOF break the loop! - } - updateStatMaps(record) - } - - // Calculate and output the stats - switch { - case *query == "bands": - for band := range bandList { - num, exists := mapBand[bandList[band]] - if exists { - fmt.Fprintf(writer, "%s %d ", bandList[band], num) - } - } - fmt.Fprintf(writer, "\n") - case *query == "country": - keys := make([]string, 0, len(mapCountry)) - for k := range mapCountry { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - fmt.Fprintf(writer, "%s: %d\n", k, mapCountry[k]) - } - fmt.Fprintln(writer, "(TOTAL):", reader.RecordCount()) - case *query == "dxcc": - keys := make([]int, 0, len(mapDxcc)) - for k := range mapDxcc { - keys = append(keys, k) - } - sort.Ints(keys) - for _, n := range keys { - fmt.Fprintf(writer, "%d ", n) - } - fmt.Fprintf(writer, "\n") - case *query == "gridsquare": - keys := make([]string, 0, len(mapGrid)) - for k := range mapGrid { - keys = append(keys, k) - } - sort.Strings(keys) - for _, g := range keys { - fmt.Fprintf(writer, "%s ", g) - } - fmt.Fprintf(writer, "\n") - case *query == "modes": - keys := make([]string, 0, len(mapMode)) - for k := range mapMode { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - fmt.Fprintf(writer, "%s %d ", k, mapMode[k]) - } - fmt.Fprintf(writer, "\n") - case *query == "submodes": - keys := make([]string, 0, len(mapSubmode)) - for k := range mapSubmode { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - fmt.Fprintf(writer, "%s %d ", k, mapSubmode[k]) - } - fmt.Fprintf(writer, "\n") - case *query == "nqso": - fmt.Fprintln(writer, reader.RecordCount()) - default: - fmt.Fprintln(os.Stderr, "Not a valid query type") - fmt.Fprintln(os.Stderr, "Valid types:") - fmt.Fprintln(os.Stderr, " bands, country, dxcc, gridsquare,") - fmt.Fprintln(os.Stderr, " modes, nqso, submodes") - } - - // Flush and close output here - writer.Flush() - if writefp != nil { - writefp.Close() - } - -} diff --git a/goadiftime/goadiftime.go b/goadiftime/goadiftime.go deleted file mode 100644 index 8893eae..0000000 --- a/goadiftime/goadiftime.go +++ /dev/null @@ -1,200 +0,0 @@ -// goadiftime: sort and filter ADIF file by time -// by Kenji Rikitake, JJ1BDX -// Usage: goadifstat [-f infile] [-o outfile] [-r] -// [-starttime RFC3339-time] [-endtime RFC3339-time] -// RFC3339-time example: 2022-10-11T12:33:45Z -// Time of ADIF record determined by: qso_date and time_on -// -// Time filtering conditions: -// if starttime and endtime both are specified: -// the condition is: starttime <= record time <= endtime -// if only starttime is specified: -// the condition is: starttime <= record time -// if only endtime is specified: -// the condition is: record time <= endtime -// -// Sorting conditions: -// when with -n option or -n=true: -// the output is not sorted -// when without -n option or -n=false (default): -// when without -r option or -r=false (default): -// the output is sorted by time increasing order -// when with -r option or -r=true: -// the output is sorted by time decreasing order - -package main - -import ( - "errors" - "flag" - "fmt" - "github.com/jj1bdx/adifparser" - "io" - "os" - "sort" - "strconv" - "time" -) - -type recordWithTime struct { - date time.Time - record adifparser.ADIFRecord -} - -func main() { - var infile = flag.String("f", "", "input file (stdout in none)") - var outfile = flag.String("o", "", "output file (stdout if none)") - var reverse bool - flag.BoolVar(&reverse, "r", false, "reverse sort (new to old)") - var nosorting bool - flag.BoolVar(&nosorting, "n", false, "no sorting with this flag") - var starttime = flag.String("starttime", "", "start time in RFC3339") - var endtime = flag.String("endtime", "", "end time in RFC3339") - - var fp *os.File - var err error - - records := []recordWithTime{} - - flag.Parse() - - if *infile == "" { - fp = os.Stdin - } else { - fp, err = os.Open(*infile) - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - } - - var writer adifparser.ADIFWriter - var writefp *os.File - if *outfile != "" { - writefp, err = os.Create(*outfile) - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - writer = adifparser.NewADIFWriter(writefp) - } else { - writefp = nil - writer = adifparser.NewADIFWriter(os.Stdout) - } - - var startTime time.Time - var endTime time.Time - starttimeexists := *starttime != "" - if starttimeexists { - parsedStartTime, err := time.Parse(time.RFC3339, *starttime) - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - startTime = parsedStartTime.UTC() - } - - endtimeexists := *endtime != "" - if endtimeexists { - parsedEndTime, err := time.Parse(time.RFC3339, *endtime) - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - endTime = parsedEndTime.UTC() - } - if starttimeexists && endtimeexists && - startTime.After(endTime) { - fmt.Fprint(os.Stderr, errors.New("starttime is after endtime")) - return - } - - reader := adifparser.NewADIFReader(fp) - for record, err := reader.ReadRecord(); record != nil || err != nil; record, err = reader.ReadRecord() { - if err != nil { - if err != io.EOF { - fmt.Fprint(os.Stderr, err) - } - break // when io.EOF break the loop! - } - - adifdate, err := record.GetValue("qso_date") - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - adiftime, err := record.GetValue("time_on") - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - - adifyear, err := strconv.Atoi(adifdate[0:4]) - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - adifmonth, err := strconv.Atoi(adifdate[4:6]) - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - adifday, err := strconv.Atoi(adifdate[6:8]) - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - adifhour, err := strconv.Atoi(adiftime[0:2]) - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - adifminute, err := strconv.Atoi(adiftime[2:4]) - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - adifsecond := 0 - if len(adiftime) > 4 { - adifsecond, err = strconv.Atoi(adiftime[4:6]) - } - recordtime := time.Date( - adifyear, time.Month(adifmonth), adifday, - adifhour, adifminute, adifsecond, - 0, time.UTC) - - passstart := !starttimeexists || - (recordtime.After(startTime) || recordtime.Equal(startTime)) - passend := !endtimeexists || - (recordtime.Before(endTime) || recordtime.Equal(endTime)) - if passstart && passend { - recordandtime := recordWithTime{recordtime, record} - records = append(records, recordandtime) - } - } - - if !nosorting { - if reverse { - sort.Slice(records, - func(i, j int) bool { - return records[i].date.After(records[j].date) - }) - } else { - sort.Slice(records, - func(i, j int) bool { - return records[i].date.Before(records[j].date) - }) - } - } - - for i := range records { - writer.WriteRecord(records[i].record) - } - - // Flush and close output here - writer.Flush() - if writefp != os.Stdout { - writefp.Close() - } - -}