package idec // Base IDEC protocol implementation import ( "errors" "io/ioutil" "net/http" "strconv" "strings" log "github.com/sirupsen/logrus" ) // IDEC Extensions. see: https://ii-net.tk/idec-doc/?p=extensions const ( listTXT = "list.txt" blacklistTXT = "blacklist.txt" features = "x/features" xcount = "x/c/" echoSchema = "u/e/" messageSchema = "u/m/" ) // Extensions IDEC extensions type Extensions struct { ListTXT string `json:"list_txt"` BlacklistTXT string `json:"backlist_txt"` Features string `json:"features"` XCount string `json:"xcount"` } // NewExtensions ... func NewExtensions() Extensions { e := Extensions{ listTXT, blacklistTXT, features, xcount, } return e } // FetchConfig node, echo, and other connection settings type FetchConfig struct { Node string `json:"node"` Echoes []string `json:"echo"` Num int `json:"count"` Offset int `json:"offset"` Limit int `json:"limit"` } // ID ... type ID struct { Echo string `json:"echo"` MsgID string `json:"msgids"` } // GetMessagesIDS get message ids from node func (f FetchConfig) GetMessagesIDS() ([]ID, error) { var ids []ID var getURI string getEchoes := strings.Join(f.Echoes, "/") // Make strings offset := strconv.Itoa(f.Offset) limit := strconv.Itoa(f.Limit) getURI = strings.Join([]string{f.Node, echoSchema, getEchoes, "/", offset, ":", limit}, "") log.Info(getURI) // Get messages ids response, err := http.Get(getURI) if err != nil { return ids, err } defer response.Body.Close() c, err := ioutil.ReadAll(response.Body) if err != nil { return ids, err } var i ID var curEcho string rawIDS := strings.Split(string(c), "\n") for _, line := range rawIDS { // Match echoarea if strings.Contains(line, ".") { curEcho = line continue } // Match message ID if !strings.Contains(line, ".") && !strings.Contains(line, ":") && line != "" { i.Echo = curEcho i.MsgID = line ids = append(ids, i) } } return ids, nil } // GetAllMessagesIDS get all message ids from node func (f FetchConfig) GetAllMessagesIDS() ([]ID, error) { var ids []ID var getURI string getEchoes := strings.Join(f.Echoes, "/") getURI = strings.Join([]string{f.Node, echoSchema, getEchoes}, "") // Get messages ids response, err := http.Get(getURI) if err != nil { return ids, err } defer response.Body.Close() c, err := ioutil.ReadAll(response.Body) if err != nil { return ids, err } var i ID var curEcho string rawIDS := strings.Split(string(c), "\n") for _, line := range rawIDS { // Match echoarea if strings.Contains(line, ".") { curEcho = line continue } // Match message ID if !strings.Contains(line, ".") && !strings.Contains(line, ":") && line != "" { i.Echo = curEcho i.MsgID = line ids = append(ids, i) } } return ids, nil } // MSG ... type MSG struct { Message string `json:"message"` ID string `json:"id"` } // GetRawMessages get messages from node func (f FetchConfig) GetRawMessages(ids []ID) ([]MSG, error) { var messages []MSG var messagesIDS []string for _, id := range ids { messagesIDS = append(messagesIDS, id.MsgID) } getMessages := strings.Join(messagesIDS, "/") getURI := strings.Join([]string{f.Node, messageSchema, getMessages}, "") // Get messages ids response, err := http.Get(getURI) if err != nil { e := errors.New("Failed to get " + getURI + ". ") return messages, e } defer response.Body.Close() c, err := ioutil.ReadAll(response.Body) if err != nil { return messages, err } for _, m := range strings.Split(string(c), "\n") { if len(m) == 0 { break } message := strings.Split(m, ":") if len(message) > 1 { messages = append(messages, MSG{message[1], message[0]}) } } return messages, err } // Echo echo description type Echo struct { Name string `json:"name"` Size int `json:"size"` Description string `json:"description"` } // GetEchoList ... func (f FetchConfig) GetEchoList() ([]Echo, error) { var echoes []Echo // Check node features support fres, err := http.Get(strings.Join([]string{f.Node, features}, "")) if err != nil { return echoes, err } defer fres.Body.Close() c, err := ioutil.ReadAll(fres.Body) if err != nil { return echoes, err } if !strings.Contains(string(c), listTXT) { err = errors.New(strings.Join([]string{f.Node, features}, "") + " Node does not support echoes list " + string(c)) return echoes, err } lres, err := http.Get(strings.Join([]string{f.Node, listTXT}, "")) if err != nil { return echoes, err } defer lres.Body.Close() l, err := ioutil.ReadAll(lres.Body) if err != nil { return echoes, err } echoes, err = ParseEchoList(string(l)) return echoes, err }