Browse Source

Fix mentions lookup and expansion based on the new (by default) nick@domain format with fallback to local user and custom aliases

master
James Mills 2 weeks ago
parent
commit
20dcbaec1f
Signed by untrusted user: prologic GPG Key ID: AC4C014F1440EBD6
  1. 2
      cmd/yarnc/root.go
  2. 2
      internal/handlers.go
  3. 18
      internal/models.go
  4. 23
      internal/utils.go
  5. 16
      types/lextwt/ast.go
  6. 20
      types/retwt/retwt.go

2
cmd/yarnc/root.go

@ -120,8 +120,6 @@ func initConfig() {
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err != nil {
log.WithError(err).Warnf("error loading config file: %s", viper.ConfigFileUsed())
} else {
log.Debugf("Using config file: %s", viper.ConfigFileUsed())
}
// from the environment

2
internal/handlers.go

@ -694,8 +694,6 @@ func (s *Server) PostHandler() httprouter.Handle {
return nil
})); err != nil {
log.WithError(err).Warn("error submitting task for webmentions")
} else {
log.Debugf("submitted webmentions task %s", URLForTask(s.config.BaseURL, uuid))
}
http.Redirect(w, r, RedirectRefererURL(r, s.config, "/"), http.StatusFound)

18
internal/models.go

@ -467,6 +467,13 @@ func (u *User) Follows(url string) bool {
return ok
}
func (u *User) FollowsAs(url string) string {
if url, ok := u.sources[NormalizeURL(url)]; ok {
return url
}
return ""
}
func (u *User) HasMuted(url string) bool {
_, ok := u.muted[NormalizeURL(url)]
return ok
@ -564,8 +571,9 @@ func (u *User) Reply(twt types.Twt) string {
for _, m := range twt.Mentions() {
twter := m.Twter()
if u.Follows(twter.URL) && !u.Is(twter.URL) {
if _, ok := mentionsSet[twter.Nick]; !ok {
mentionsSet[twter.Nick] = true
as := fmt.Sprintf("@%s", u.FollowsAs(twter.URL))
if _, ok := mentionsSet[as]; !ok {
mentionsSet[as] = true
}
}
}
@ -576,12 +584,12 @@ func (u *User) Reply(twt types.Twt) string {
// If we follow the original twt's Twter, add them as the first mention
// only if the original twter isn't ourselves!
if u.Follows(twt.Twter().URL) && !u.Is(twt.Twter().URL) {
tokens = append(tokens, fmt.Sprintf("@%s", twt.Twter().Nick))
tokens = append(tokens, fmt.Sprintf("@%s", u.FollowsAs(twt.Twter().URL)))
}
// Add all other mentions
for nick := range mentionsSet {
tokens = append(tokens, fmt.Sprintf("@%s", nick))
for mention := range mentionsSet {
tokens = append(tokens, mention)
}
tokens = UniqStrings(tokens)

23
internal/utils.go

@ -1818,19 +1818,30 @@ func GetMediaNamesFromText(text string) []string {
}
func NewFeedLookup(conf *Config, db Store, user *User) types.FeedLookup {
return types.FeedLookupFn(func(nick string) *types.Twter {
for followedNick, followedURL := range user.Following {
if strings.ToLower(nick) == strings.ToLower(followedNick) {
return &types.Twter{Nick: followedNick, URL: followedURL}
return types.FeedLookupFn(func(alias string) *types.Twter {
for followedAs, followedURL := range user.Following {
if strings.ToLower(alias) == strings.ToLower(followedAs) {
u, err := url.Parse(followedURL)
if err != nil {
log.WithError(err).Warnf("error looking up follow alias %s for user %s", alias, user)
return &types.Twter{}
}
parts := strings.SplitN(followedAs, "@", 2)
if len(parts) == 2 && u.Hostname() == parts[1] {
return &types.Twter{Nick: parts[0], URL: followedURL}
}
return &types.Twter{Nick: followedAs, URL: followedURL}
}
}
username := NormalizeUsername(nick)
username := NormalizeUsername(alias)
if db.HasUser(username) || db.HasFeed(username) {
return &types.Twter{Nick: username, URL: URLForUser(conf.BaseURL, username)}
}
return &types.Twter{Nick: nick}
return &types.Twter{}
})
}

16
types/lextwt/ast.go

@ -890,13 +890,17 @@ func (twt *Twt) ExpandTags(opts types.FmtOpts, lookup types.FeedLookup) {
func (twt *Twt) ExpandMentions(opts types.FmtOpts, lookup types.FeedLookup) {
for i, m := range twt.mentions {
if lookup != nil && m.target == "" {
twter := lookup.FeedLookup(m.name)
m.name = twter.Nick
if sp := strings.SplitN(twter.Nick, "@", 2); len(sp) == 2 {
m.name = sp[0]
m.domain = sp[1]
twter := lookup.FeedLookup(fmt.Sprintf("%s@%s", m.name, m.domain))
if twter.IsZero() {
twter = lookup.FeedLookup(m.name)
}
if !twter.IsZero() {
if sp := strings.SplitN(twter.Nick, "@", 2); len(sp) == 2 {
m.name = sp[0]
m.domain = sp[1]
}
m.target = twter.URL
}
m.target = twter.URL
}
twt.mentions[i] = m

20
types/retwt/retwt.go

@ -474,24 +474,20 @@ func (r reSubject) String() string {
// or if they exist on the local pod. Also turns @user@domain into
// @<user URL> as a convenient way to mention users across pods.
func ExpandMentions(opts types.FmtOpts, lookup types.FeedLookup, text string) string {
re := regexp.MustCompile(`@([a-zA-Z0-9][a-zA-Z0-9_-]+)(?:@)?((?:[_a-z0-9](?:[_a-z0-9-]{0,61}[a-z0-9]\.)|(?:[0-9]+/[0-9]{2})\.)+(?:[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?)?)?`)
re := regexp.MustCompile(`@([a-zA-Z0-9][a-zA-Z0-9_-]+)(?:@)?((?:[_a-z0-9](?:[_a-z0-9-]{0,61}[a-z0-9])?\.)+(?:[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?)?)?`)
return re.ReplaceAllStringFunc(text, func(match string) string {
parts := re.FindStringSubmatch(match)
mentionedNick := parts[1]
mentionedDomain := parts[2]
if mentionedNick != "" && mentionedDomain != "" {
// TODO: Validate the remote end for a valid Twtxt pod?
// XXX: Should we always assume https:// ?
return fmt.Sprintf(
"@<%s https://%s/user/%s/twtxt.txt>",
mentionedNick, mentionedDomain, mentionedNick,
)
}
if lookup != nil {
twter := lookup.FeedLookup(mentionedNick)
return fmt.Sprintf("@<%s %s>", twter.Nick, twter.URL)
twter := lookup.FeedLookup(fmt.Sprintf("%s@%s", mentionedNick, mentionedDomain))
if twter.IsZero() {
twter = lookup.FeedLookup(mentionedNick)
}
if !twter.IsZero() {
return fmt.Sprintf("@<%s %s>", twter.Nick, twter.URL)
}
}
// Not expanding if we're not following, not a local user/feed

Loading…
Cancel
Save