Skip to content

Commit

Permalink
implemented handling repost and quote repost event data.
Browse files Browse the repository at this point in the history
  • Loading branch information
ryogrid committed Apr 17, 2024
1 parent 9477643 commit cb1f84d
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 26 deletions.
55 changes: 48 additions & 7 deletions api_server/api_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,10 @@ func (s *ApiServer) publishHandler(w rest.ResponseWriter, req *rest.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Private-Network", "true")
switch input.Kind {
case core.KIND_EVT_POST:
case core.KIND_EVT_POST: // including quote repost
s.sendPost(w, &input)
case core.KIND_EVT_REPOST:
s.sendRePost(w, &input)
case core.KIND_EVT_PROFILE:
s.updateProfile(w, &input)
case core.KIND_EVT_FOLLOW_LIST:
Expand All @@ -208,25 +210,39 @@ func (s *ApiServer) publishHandler(w rest.ResponseWriter, req *rest.Request) {
}
}

func (s *ApiServer) sendRePost(w rest.ResponseWriter, input *Np2pEventForREST) {
evt := NewNp2pEventFromREST(input)
s.buzzPeer.MessageMan.BcastOwnPost(evt)

// store for myself
s.buzzPeer.MessageMan.DataMan.StoreEvent(evt)

w.WriteJson(&EventsResp{})
}

func (s *ApiServer) sendPost(w rest.ResponseWriter, input *Np2pEventForREST) {
if input.Content == "" {
rest.Error(w, "Content is required", 400)
return
}

// if mention or reply, extract related user's pubkey
// if mention, reply or quote repost, extract related user's pubkey
sendDests := make([]string, 0)
isQuoteRpost := false
if input.Tags != nil {
for _, tag := range input.Tags {
if tag[0] == "p" && tag[1] != glo_val.SelfPubkeyStr {
// extract short pubkey from p tags hex string value
sendDests = append(sendDests, tag[1])
}
if tag[0] == "q" {
isQuoteRpost = true
}
}
}

evt := NewNp2pEventFromREST(input)
if len(sendDests) > 0 {
if len(sendDests) > 0 && !isQuoteRpost {
// send to specified users because post is mention or reply
resendDests := make([]uint64, 0)
for _, dest := range sendDests {
Expand All @@ -240,11 +256,12 @@ func (s *ApiServer) sendPost(w rest.ResponseWriter, input *Np2pEventForREST) {
// so add event to retry queue
s.buzzPeer.MessageMan.DataMan.AddReSendNeededEvent(resendDests, evt, true)
} else {
// normal post or quote repost
s.buzzPeer.MessageMan.BcastOwnPost(evt)
}

// store for myself
// if destination server is offline, this event will be sent again
// if destination server is offline, this event will be sent again (when unicast)
s.buzzPeer.MessageMan.DataMan.StoreEvent(evt)

w.WriteJson(&EventsResp{})
Expand Down Expand Up @@ -333,8 +350,10 @@ func (s *ApiServer) reqHandler(w rest.ResponseWriter, req *rest.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Private-Network", "true")
// TODO: need to implement each kind and other fliter condition request handling (ApiServer::reqHandler)
if slices.Contains(input.Kinds, core.KIND_REQ_SHARE_EVT_DATA) || slices.Contains(input.Kinds, core.KIND_REQ_POST) {
if slices.Contains(input.Kinds, core.KIND_REQ_SHARE_EVT_DATA) {
s.getEvents(w, &input)
} else if slices.Contains(input.Kinds, core.KIND_REQ_POST) {
s.getPost(w, &input)
} else if slices.Contains(input.Kinds, core.KIND_REQ_PROFILE) {
s.getProfile(w, &input)
} else if slices.Contains(input.Kinds, core.KIND_REQ_FOLLOW_LIST) {
Expand All @@ -348,6 +367,28 @@ func (s *ApiServer) reqHandler(w rest.ResponseWriter, req *rest.Request) {
}
}

// RESTRICTION: only one ID and author is supported
func (s *ApiServer) getPost(w rest.ResponseWriter, input *Np2pReqForREST) {
if input.Ids == nil || len(input.Ids) == 0 || input.Authors == nil || len(input.Authors) == 0 {
rest.Error(w, "Ids and Authors are needed", http.StatusBadRequest)
return
}

tgtEvtId := np2p_util.StrTo32BytesArr(input.Ids[0])
shortPkey := np2p_util.GetUint64FromHexPubKeyStr(input.Authors[0])
gotEvt, ok := s.buzzPeer.MessageMan.DataMan.GetEventById(tgtEvtId)

if ok {
// found at local
w.WriteJson(&EventsResp{Events: []Np2pEventForREST{*NewNp2pEventForREST(gotEvt)}})
} else {
// post data will be included on response of "getEvents"
w.WriteJson(&EventsResp{Events: []Np2pEventForREST{}})
// request post data for future
s.buzzPeer.MessageMan.UnicastPostReq(shortPkey, tgtEvtId)
}
}

func (s *ApiServer) getProfile(w rest.ResponseWriter, input *Np2pReqForREST) {
shortPkey := np2p_util.GetUint64FromHexPubKeyStr(input.Authors[0])
profEvt := s.buzzPeer.MessageMan.DataMan.GetProfileLocal(shortPkey)
Expand All @@ -358,7 +399,7 @@ func (s *ApiServer) getProfile(w rest.ResponseWriter, input *Np2pReqForREST) {
// profile data will be included on response of "getEvents"
w.WriteJson(&EventsResp{Events: []Np2pEventForREST{}})
// request profile data for future
s.buzzPeer.MessageMan.UnicastProfileReq(shortPkey & 0x0000ffffffffffff)
s.buzzPeer.MessageMan.UnicastProfileReq(shortPkey)
}
}

Expand All @@ -372,7 +413,7 @@ func (s *ApiServer) getFollowList(w rest.ResponseWriter, input *Np2pReqForREST)
// follow list data will be included on response of "getEvents"
w.WriteJson(&EventsResp{Events: []Np2pEventForREST{}})
// request profile data for future
s.buzzPeer.MessageMan.UnicastFollowListReq(shortPkey & 0x0000ffffffffffff)
s.buzzPeer.MessageMan.UnicastFollowListReq(shortPkey)
}
}

Expand Down
59 changes: 41 additions & 18 deletions core/message_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type Np2pTransport interface {
const (
KIND_EVT_PROFILE = 0
KIND_EVT_POST = 1
KIND_EVT_REPOST = 6
KIND_EVT_FOLLOW_LIST = 3
KIND_EVT_REACTION = 7
KIND_REQ_PROFILE = KIND_EVT_PROFILE
Expand Down Expand Up @@ -144,7 +145,15 @@ func (mm *MessageManager) handleRecvMsgUnicast(src uint64, pkt *schema.Np2pPacke
switch pkt.Reqs[0].Kind {
case KIND_REQ_PROFILE: // profile request
// send profile data asynchronous
go mm.UnicastOwnProfile(uint64(src))
go mm.UnicastOwnProfile(src)
case KIND_REQ_POST:
// send post data asynchronous
if tgtEvtId, ok := pkt.Reqs[0].Args["evtId"][0].([32]byte); ok {
if tgtEvt, ok2 := mm.DataMan.GetEventById(tgtEvtId); ok2 {
events := []*schema.Np2pEvent{tgtEvt}
go mm.SendMsgUnicast(src, schema.NewNp2pPacket(&events, nil))
}
}
default:
fmt.Println("received unknown kind request: " + strconv.Itoa(int(pkt.Reqs[0].Kind)))
}
Expand Down Expand Up @@ -187,37 +196,45 @@ func (mm *MessageManager) BcastProfile(evt *schema.Np2pEvent) {
func (mm *MessageManager) UnicastProfileReq(pubkey64bit uint64) {
reqs := []*schema.Np2pReq{schema.NewNp2pReq(KIND_REQ_PROFILE, nil)}
pkt := schema.NewNp2pPacket(nil, &reqs)
mm.SendMsgUnicast(pubkey64bit&0x0000ffffffffffff, pkt)
mm.SendMsgUnicast(pubkey64bit, pkt)
}

func (mm *MessageManager) UnicastPostReq(pubkey64bit uint64, evtId [32]byte) {
arg := make(map[string][]interface{})
arg["evtId"] = []interface{}{evtId}
reqs := []*schema.Np2pReq{schema.NewNp2pReq(KIND_REQ_POST, arg)}
pkt := schema.NewNp2pPacket(nil, &reqs)
mm.SendMsgUnicast(pubkey64bit, pkt)
}

func (mm *MessageManager) UnicastFollowListReq(pubkey64bit uint64) {
reqs := []*schema.Np2pReq{schema.NewNp2pReq(KIND_REQ_FOLLOW_LIST, nil)}
pkt := schema.NewNp2pPacket(nil, &reqs)
mm.SendMsgUnicast(pubkey64bit&0x0000ffffffffffff, pkt)
mm.SendMsgUnicast(pubkey64bit, pkt)
}

// used for response of profile request
func (mm *MessageManager) UnicastOwnProfile(dest uint64) {
if glo_val.CurrentProfileEvt != nil {
// send latest profile data
events := []*schema.Np2pEvent{glo_val.CurrentProfileEvt}
mm.SendMsgUnicast(dest&0x0000ffffffffffff, schema.NewNp2pPacket(&events, nil))
mm.SendMsgUnicast(dest, schema.NewNp2pPacket(&events, nil))
}
}

// TODO: need to implent MessageManager::GenProfileFromEvent
func GenProfileFromEvent(evt *schema.Np2pEvent) *schema.Np2pProfile {
return &schema.Np2pProfile{
Pubkey64bit: np2p_util.GetLower64bitUint(evt.Pubkey),
//Name: evt.Tags["name"][0].(string),
//About: evt.Tags["about"][0].(string),
//Picture: evt.Tags["picture"][0].(string),
Name: "",
About: "",
Picture: "",
UpdatedAt: evt.Created_at,
}
}
//// todo: need to implent messagemanager::genprofilefromevent
//func genprofilefromevent(evt *schema.np2pevent) *schema.np2pprofile {
// return &schema.np2pprofile{
// pubkey64bit: np2p_util.getlower64bituint(evt.pubkey),
// //name: evt.tags["name"][0].(string),
// //about: evt.tags["about"][0].(string),
// //picture: evt.tags["picture"][0].(string),
// name: "",
// about: "",
// picture: "",
// updatedat: evt.created_at,
// }
//}

// TODO: TEMPORAL IMPL
func (mm *MessageManager) BcastShareEvtDataReq() {
Expand All @@ -237,7 +254,13 @@ func (mm *MessageManager) UnicastHavingEvtData(dest uint64) {
}

func (mm *MessageManager) UnicastEventData(destPubHexStr string, evt *schema.Np2pEvent) error {
events := []*schema.Np2pEvent{evt}
var events []*schema.Np2pEvent
if evt != nil {
events = []*schema.Np2pEvent{evt}
} else {
events = []*schema.Np2pEvent{}
}

pkt := schema.NewNp2pPacket(&events, nil)
return mm.SendMsgUnicast(np2p_util.Get6ByteUint64FromHexPubKeyStr(destPubHexStr), pkt)
}
Expand Down
11 changes: 11 additions & 0 deletions np2p_util/np2p_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,14 @@ func GetUint64FromHexPubKeyStr(pubKeyStr string) uint64 {

return binary.BigEndian.Uint64(pubKeyBytes[len(pubKeyBytes)-8:])
}

func StrTo32BytesArr(pubKeyStr string) [32]byte {
bytes, err := hex.DecodeString(pubKeyStr)
if err != nil {
panic(err)
}
byteArr32 := [32]byte{}
copy(byteArr32[:], bytes)

return byteArr32
}
2 changes: 1 addition & 1 deletion transport/mesh_transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (mt *MeshTransport) Register(send mesh.Gossip) {
}

func (mt *MeshTransport) SendMsgUnicast(dst uint64, buf []byte) error {
return mt.send.GossipUnicast(mesh.PeerName(dst), buf)
return mt.send.GossipUnicast(mesh.PeerName(dst&0x0000ffffffffffff), buf)
}

func (mt *MeshTransport) SendMsgBroadcast(pkt schema.EncodableAndMergeable) {
Expand Down

0 comments on commit cb1f84d

Please sign in to comment.