Ejemplo n.º 1
0
// NewWithNamespace returns a new UUIDv5 (or v4 if name is empty), encoded with base57.
func NewWithNamespace(name string) string {
	var u uuid.UUID

	switch {
	case name == "":
		u = uuid.NewV4()
	case strings.HasPrefix(name, "http"):
		u = uuid.NewV5(uuid.NamespaceURL, name)
	default:
		u = uuid.NewV5(uuid.NamespaceDNS, name)
	}

	return DefaultEncoder.Encode(u)
}
Ejemplo n.º 2
0
// UUID returns a new (short) UUID. If name is non-empty, the namespace
// matching the name will be used to generate a UUID.
func (su *ShortUUID) UUID(name string) string {
	var u uuid.UUID

	switch {
	case name == "":
		u = uuid.NewV4()
	case strings.HasPrefix(name, "http"):
		u = uuid.NewV5(uuid.NamespaceDNS, name)
	default:
		u = uuid.NewV5(uuid.NamespaceURL, name)
	}

	return su.Encode(u)
}
Ejemplo n.º 3
0
// /a/comment
func (s *Server) CommentHandler(c *gin.Context) {
	c.Request.ParseForm()
	id := c.Request.Form.Get("id")
	entryId := c.Request.Form.Get("entry")
	rawBody := c.Request.Form.Get("body")
	if entryId == "" || rawBody == "" {
		c.JSON(http.StatusBadRequest, gin.H{"status": "bad request"})
		return
	}

	body := util.DefaultSanitize(rawBody)
	body = util.EntityToLink(body)

	profile, _ := s.CurrentUser(c)
	from := &pb.Feed{
		Id:   profile.Id,
		Name: profile.Name,
		Type: profile.Type,
	}
	comment := &pb.Comment{
		Body:    body,
		RawBody: rawBody,
		From:    from,
	}

	var err error
	var uuid1 uuid.UUID
	if id != "" {
		uuid1, err = uuid.FromString(id)
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"status": "bad request"})
			return
		}
	} else {
		comment.Date = time.Now().UTC().Format(time.RFC3339)
		name := entryId + profile.Uuid + comment.Date
		uuid1 = uuid.NewV5(uuid.NamespaceURL, name)
	}
	comment.Id = uuid1.String()

	req := &pb.CommentRequest{
		Entry:   entryId,
		Comment: comment,
	}

	ctx, cancel := DefaultTimeoutContext()
	defer cancel()

	_, err = s.client.CommentEntry(ctx, req)
	if RequestError(c, err) {
		return
	}

	comment.Commands = []string{"edit", "delete"}
	c.JSON(200, comment)
}
Ejemplo n.º 4
0
// TODO: allow cross post to multiply feeds
func (s *Server) EntryPostHandler(c *gin.Context) {
	var form struct {
		FeedId string `form:"feedid" binding:"required"`
		Body   string `form:"body" binding:"required"`
	}
	c.BindWith(&form, binding.MultipartForm)

	if !s.feedWritable(c, form.FeedId) {
		c.AbortWithStatus(401)
		return
	}

	body := util.DefaultSanitize(form.Body)
	body = util.EntityToLink(body)

	ctx, cancel := DefaultTimeoutContext()
	defer cancel()

	profile, _ := s.CurrentUser(c)
	dt := time.Now().UTC()
	name := profile.Uuid + "/" + dt.Format(time.RFC3339)
	uuid1 := uuid.NewV5(uuid.NamespaceURL, name)

	from := &pb.Feed{
		Id:   profile.Id,
		Name: profile.Name,
		Type: profile.Type,
	}

	entry := &pb.Entry{
		Id:      uuid1.String(),
		Date:    dt.Format(time.RFC3339),
		Body:    body,
		RawBody: form.Body,
		From:    from,
		// To:      []*pb.Feed{from},
		// Thumbnails: thumbnails,
		ProfileUuid: profile.Uuid,
	}

	entry, err := s.client.PostEntry(ctx, entry)
	if RequestError(c, err) {
		return
	}
	// c.JSON(200, gin.H{"entry": entry})
	c.Redirect(http.StatusFound, "/")
}
Ejemplo n.º 5
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.º 6
0
func (fa *FeedAgent) fetchService(job *pb.FeedJob) (int, error) {
	stream, err := fa.client.ArchiveFeed(context.Background())
	defer stream.CloseAndRecv()
	if err != nil {
		return 0, err
	}

	updated := time.Unix(job.Service.Updated, 0)
	authinfo := job.Service.Oauth
	if authinfo == nil {
		return 0, fmt.Errorf("skip job: no authinfo")
	}
	api := anaconda.NewTwitterApi(authinfo.AccessToken, authinfo.AccessTokenSecret)
	defer api.Close()

	v := url.Values{}
	v.Set("screen_name", authinfo.NickName) // goth user.NickName == screen_name
	tweets, _ := api.GetUserTimeline(v)

	n := 0
	for i := len(tweets) - 1; i >= 0; i-- {
		tweet := tweets[i]

		// skip reply status
		if tweet.InReplyToStatusID != 0 {
			continue
		}

		url := "https://twitter.com/" + tweet.User.ScreenName + "/status/" + tweet.IdStr
		// deterministic uuid or feed will be polluted
		uuid1 := uuid.NewV5(uuid.NamespaceURL, url)
		tt, err := tweet.CreatedAtTime()
		if err != nil || tt.Before(updated) {
			continue
		}

		from := &pb.Feed{
			Id:   job.Profile.Id,
			Name: job.Profile.Name,
			Type: job.Profile.Type,
		}

		var thumbnails []*pb.Thumbnail
		for _, media := range tweet.Entities.Media {
			if media.Type != "photo" {
				continue
			}

			url := ""
			if media.Media_url_https != "" {
				url = media.Media_url_https
			} else {
				url = media.Media_url
			}
			thumb := &pb.Thumbnail{
				Url:    url,
				Link:   media.Expanded_url,
				Width:  int32(media.Sizes.Small.W),
				Height: int32(media.Sizes.Small.H),
			}
			thumbnails = append(thumbnails, thumb)
		}

		body := tweet.Text
		tags := ttext.ExtractHashtags(body)
		for _, tag := range tags {
			new := fmt.Sprintf("<a href=\"https://twitter.com/hashtag/%s\">%s</a>", tag, tag)
			body = strings.Replace(body, tag, new, -1)
		}
		urls := ttext.ExtractURLs(tweet.Text)
		for _, url := range urls {
			new := fmt.Sprintf("<a href=\"%s\">%s</a>", url, url)
			body = strings.Replace(body, url, new, -1)
		}

		entry := &pb.Entry{
			Id:      uuid1.String(),
			Url:     url,
			Date:    tt.Format(time.RFC3339),
			Body:    body,
			RawBody: tweet.Text,
			RawLink: url,
			From:    from,
			// To:         []*pb.Feed{from},
			Thumbnails: thumbnails,
			Via: &pb.Via{
				Name: "Twitter",
				Url:  url,
			},
			ProfileUuid: job.Profile.Uuid,
		}

		if err := stream.Send(entry); err != nil {
			log.Printf("%v.Send(%v) = %v", stream, entry, err)
			return n, err
		}

		n++
	}
	return n, nil
}
Ejemplo n.º 7
0
// Return a new unique id :)
func getUUID() string {
	// @todo is this good enough?
	var secret = uuid.NewV4()
	u := uuid.NewV5(secret, domain)
	return u.String()
}