package toot import "fmt" import "encoding/json" import "errors" import "strings" import "github.com/sneak/feta/jsonapis" import "github.com/davecgh/go-spew/spew" import "github.com/rs/zerolog/log" //import "encoding/hex" import mh "github.com/multiformats/go-multihash" import mhopts "github.com/multiformats/go-multihash/opts" type TootHash string type Toot struct { Original []byte Parsed *jsonapis.APISerializedToot Hash TootHash FromHost string } func NewTootCollectionFromMastodonAPIResponse(in []byte, hostname string) (*[]Toot, error) { var rt []json.RawMessage err := json.Unmarshal(in, &rt) if err != nil { return nil, errors.New("unable to parse api response") } var tc []Toot // iterate over rawtoots from api for _, item := range rt { parsed := new(jsonapis.APISerializedToot) err := json.Unmarshal(item, parsed) if err != nil { log.Error().Msg("unable to parse toot, skipping") continue } t := new(Toot) t.Parsed = parsed o, err := item.MarshalJSON() if err != nil { panic(err) } t.Original = o t.FromHost = hostname t.calcHash() tc = append(tc, *t) } spew.Dump(tc) panic("") return &tc, nil } func (t *Toot) String() string { return fmt.Sprintf("%#v", t) } func (t *Toot) multiHash(in []byte) string { opts := new(mhopts.Options) opts.Algorithm = "sha2-256" opts.Encoding = "base58" var found bool opts.AlgorithmCode, found = mh.Names[opts.Algorithm] if !found { panic("oops") } opts.Length = mh.DefaultLengths[opts.AlgorithmCode] r := strings.NewReader(string(in)) h, err := opts.Multihash(r) if err != nil { panic(err) } return h.B58String() } func (t *Toot) DiskStoragePath() string { // FIXME make this error if fields are missing // '/YYYYMMDD/example.com/username/YYYY-MM-DD.HHMMSS.username@fromHost.multihash.json' return fmt.Sprintf("%s/%s/%s/%s.%s@%s.%s.json", t.Parsed.CreatedAt.Format("20060102"), strings.ToLower(t.FromHost), t.Parsed.Account.Acct, t.Parsed.CreatedAt.Format("2006-01-02.150405"), t.Parsed.Account.Acct, strings.ToLower(t.FromHost), t.Hash, ) } func (t *Toot) identityHashInput() string { return fmt.Sprintf( "%s.%s.%s.%s.%s", t.Parsed.Account.URL, t.Parsed.CreatedAt, t.Parsed.ID, t.Parsed.Content, strings.ToLower(t.FromHost), ) } func (t *Toot) calcHash() { hi := t.identityHashInput() t.Hash = TootHash(t.multiHash([]byte(hi))) }