Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
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
}
Ejemplo n.º 5
0
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
}
Ejemplo n.º 6
0
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)
}
Ejemplo n.º 7
0
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
}
Ejemplo n.º 8
0
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
}
Ejemplo n.º 9
0
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)
			})
		})
	})
}