func (s *ApiServer) FetchEntry(ctx context.Context, req *pb.EntryRequest) (*pb.Feed, error) { entry, err := store.GetEntry(s.rdb, req.Uuid) if err != nil { return nil, err } err = fmtEntryProfile(s.mdb, entry) if err != nil { return nil, err } profile, err := store.GetProfile(s.mdb, entry.From.Id) if err != nil { return nil, err } if profile == nil { return nil, fmt.Errorf("404") } feed := &pb.Feed{ Uuid: profile.Uuid, Id: profile.Id, Name: profile.Name, Type: profile.Type, Private: profile.Private, SupId: profile.SupId, Description: profile.Description, Entries: []*pb.Entry{entry}, } return feed, nil }
func (s *ApiServer) TestJob() error { profile, _ := store.GetProfile(s.mdb, "yinhm") feedinfo, _ := store.GetFeedinfo(s.rdb, profile.Uuid) // only sync twitter service graph := BuildGraph(feedinfo) if _, ok := graph.Services["twitter"]; !ok { return nil } service := graph.Services["twitter"] if service.Oauth == nil { return nil } job := &pb.FeedJob{ Uuid: feedinfo.Uuid, Id: feedinfo.Id, Profile: profile, Service: service, Start: 0, Created: time.Now().Unix(), Updated: time.Now().Unix(), } _, err := s.EnqueJob(context.Background(), job) return err }
func (s *ApiServer) ForwardFetchFeed(ctx context.Context, req *pb.FeedRequest) (*pb.Feed, error) { if req.PageSize <= 0 || req.PageSize >= 100 { req.PageSize = 50 } profile, err := store.GetProfile(s.mdb, req.Id) if err != nil { return nil, err } uuid1, _ := uuid.FromString(profile.Uuid) preKey := store.NewUUIDKey(store.TableReverseEntryIndex, uuid1) log.Println("forward seeking:", preKey.String()) start := req.Start var entries []*pb.Entry _, err = store.ForwardTableScan(s.rdb, preKey, func(i int, k, v []byte) error { if start > 0 { start-- return nil // continue } entry := new(pb.Entry) rawdata, err := s.rdb.Get(v) // index value point to entry key if err != nil || len(rawdata) == 0 { return fmt.Errorf("entry data missing") } if err := proto.Unmarshal(rawdata, entry); err != nil { return err } if err = FormatFeedEntry(s.mdb, req, entry); err != nil { return err } entries = append(entries, entry) if i > int(req.PageSize+req.Start) { return &store.Error{"ok", store.StopIteration} } return nil }) if err != nil { return nil, err } feed := &pb.Feed{ Uuid: profile.Uuid, Id: profile.Id, Name: profile.Name, Picture: profile.Picture, Type: profile.Type, Private: profile.Private, SupId: profile.SupId, Description: profile.Description, Entries: entries[:], } return feed, nil }
func fmtEntryProfile(mdb *store.Store, entry *pb.Entry) error { // refetch user profile profile, err := store.GetProfile(mdb, entry.From.Id) if err != nil { return err } entry.From.Picture = profile.Picture return nil }
func (s *ApiServer) MarkDelete(feedId string) (bool, error) { profile, err := store.GetProfile(s.mdb, feedId) if err != nil { return false, err } profile.Deleted = true store.UpdateProfile(s.mdb, profile) return true, nil }
func (s *ApiServer) DeleteComment(ctx context.Context, req *pb.CommentDeleteRequest) (*pb.Entry, error) { entry, err := store.GetEntry(s.rdb, req.Entry) if err != nil { return nil, err } profile, err := store.GetProfile(s.mdb, req.User) if err != nil || profile == nil { return nil, err } return store.DeleteComment(s.rdb, profile, entry, req.Comment) }
func (s *ApiServer) CommentEntry(ctx context.Context, req *pb.CommentRequest) (*pb.Entry, error) { entry, err := store.GetEntry(s.rdb, req.Entry) if err != nil { return nil, err } profile, err := store.GetProfile(s.mdb, req.Comment.From.Id) if err != nil || profile == nil { return nil, err } key, entry, err := store.Comment(s.rdb, profile, entry, req.Comment) if err != nil { return nil, err } s.spread(key) return entry, nil }
func (s *ApiServer) FixComment() error { req := &pb.FeedRequest{ Id: "public", Start: int32(0), PageSize: 50, } feed, _ := s.cachedFeed(req) for _, e := range feed.Entries { for _, cmt := range e.Comments { // date, _ := time.Parse(time.RFC3339, cmt.Date) profile, _ := store.GetProfile(s.mdb, cmt.From.Id) fixedName := e.Id + profile.Uuid + cmt.Date uuid1 := uuid.NewV5(uuid.NamespaceURL, fixedName) cmt.Id = uuid1.String() } store.PutEntry(s.rdb, e, true) } return nil }
func TestPostProfile(t *testing.T) { setup() defer teardown() Convey("Given ApiServer, post profile then get profile", t, func() { ctx := context.Background() p1 := &pb.Profile{ Uuid: "c6f8dca854f011ddb489003048343a40", Id: "yinhm", Name: "yinhm", Type: "user", Private: false, SupId: "4566789", Description: "desc", RemoteKey: "xxx", } feedinfo := &pb.Feedinfo{ Uuid: "c6f8dca854f011ddb489003048343a40", Id: "yinhm", Name: "Heming Friend", Type: "user", Private: false, SupId: "123456-1234", Description: "Friendfeed land", Subscriptions: []*pb.Profile{p1}, } got, err := srv.PostFeedinfo(ctx, feedinfo) So(err, ShouldBeNil) So(got.Uuid, ShouldEqual, feedinfo.Uuid) So(got.RemoteKey, ShouldEqual, feedinfo.RemoteKey) profile, err := store.GetProfile(srv.mdb, feedinfo.Id) So(err, ShouldBeNil) So(profile.Uuid, ShouldEqual, feedinfo.Uuid) So(profile.RemoteKey, ShouldEqual, feedinfo.RemoteKey) newinfo, err := store.GetFeedinfo(srv.rdb, feedinfo.Uuid) So(err, ShouldBeNil) So(newinfo.Uuid, ShouldEqual, feedinfo.Uuid) So(newinfo.RemoteKey, ShouldEqual, feedinfo.RemoteKey) So(len(newinfo.Subscriptions), ShouldEqual, 1) Convey("post entry", func() { from := &pb.Feed{ Id: "yinhm", Name: "yinhm", Type: "user", } entry := &pb.Entry{ Body: "张无忌对张三丰说:“太师父,武当山的生活太寂寞了,只有清风和明月两个朋友能陪我玩。”张三丰叹了口气:“已经很不错啦,至少还有清风明月呢。想当年我在少林寺的时候,也是只有两个朋友,其中一个也叫清风……”“那另一个呢?”“叫心相印。”…", Id: "e/2b43a9066074d120ed2e45494eea1797", Date: "2012-09-07T07:40:22Z", Url: "http://friendfeed.com/yinhm/2b43a906/rt-trojansj", From: from, ProfileUuid: "c6f8dca854f011ddb489003048343a40", } _, err := store.PutEntry(srv.rdb, entry, false) So(err, ShouldBeNil) req := &pb.FeedRequest{ Id: "yinhm", Start: 0, PageSize: 50, } feed, err := srv.FetchFeed(context.Background(), req) So(err, ShouldBeNil) So(feed.Id, ShouldEqual, "yinhm") So(len(feed.Entries), ShouldEqual, 1) // prefix stripped So(feed.Entries[0].Id, ShouldEqual, "2b43a9066074d120ed2e45494eea1797") Convey("comment on the entry", func() { cmt := &pb.Comment{ Id: "2b43a9066074d120ed2e45494eea1797", Date: "2012-09-07T07:40:22Z", From: from, Body: "this is a comment", RawBody: "this is a comment", } cReq := &pb.CommentRequest{ Entry: entry.Id, Comment: cmt, } entry, err := srv.CommentEntry(context.Background(), cReq) So(err, ShouldBeNil) So(entry.Id, ShouldEqual, "2b43a9066074d120ed2e45494eea1797") // BUG: duplicated entry when comment feed, err := srv.FetchFeed(context.Background(), req) So(err, ShouldBeNil) So(feed.Id, ShouldEqual, "yinhm") So(len(feed.Entries), ShouldEqual, 1) }) }) }) }