|
|
|
@ -61,17 +61,15 @@ func (bot *botInstance) processShowcaseMsg(ctx context.Context, msg *Message) er
|
|
|
|
|
// ...and maybe make a snippet too, if the user wants us to
|
|
|
|
|
duser, err := FetchDiscordUser(ctx, tx, newMsg.UserID)
|
|
|
|
|
if err == nil && duser.HMNUser.DiscordSaveShowcase {
|
|
|
|
|
err = CreateMessageSnippets(ctx, tx, newMsg.UserID, msg.ID)
|
|
|
|
|
err = CreateMessageSnippets(ctx, tx, msg.ID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return oops.New(err, "failed to create snippet in gateway")
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if err == db.NotFound {
|
|
|
|
|
} else if err == db.NotFound {
|
|
|
|
|
// this is fine, just don't create a snippet
|
|
|
|
|
} else {
|
|
|
|
|
} else if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = tx.Commit(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
@ -148,11 +146,9 @@ func SaveMessage(
|
|
|
|
|
|
|
|
|
|
guildID := msg.GuildID
|
|
|
|
|
if guildID == nil {
|
|
|
|
|
/*
|
|
|
|
|
This is weird, but it can happen when we fetch messages from
|
|
|
|
|
history instead of receiving it from the gateway. In this case
|
|
|
|
|
we just assume it's from the HMN server.
|
|
|
|
|
*/
|
|
|
|
|
// This is weird, but it can happen when we fetch messages from
|
|
|
|
|
// history instead of receiving it from the gateway. In this case
|
|
|
|
|
// we just assume it's from the HMN server.
|
|
|
|
|
guildID = &config.Config.Discord.GuildID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -593,7 +589,13 @@ func CreateMessageSnippets(ctx context.Context, dbConn db.ConnOrTx, msgIDs ...st
|
|
|
|
|
`,
|
|
|
|
|
msgID,
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
if err == db.NotFound {
|
|
|
|
|
logging.ExtractLogger(ctx).Warn().
|
|
|
|
|
Str("messageID", msgID).
|
|
|
|
|
Stack().
|
|
|
|
|
Msg("No record was found for this Discord message at all. Is it actually a message ID?")
|
|
|
|
|
continue
|
|
|
|
|
} else if err != nil {
|
|
|
|
|
return oops.New(err, "failed to check for existing snippet for message %s", msgID)
|
|
|
|
|
}
|
|
|
|
|
existing := iexisting.(*existingSnippetResult)
|
|
|
|
@ -689,6 +691,8 @@ If no Discord user is linked, or no snippet exists, or whatever, this will do
|
|
|
|
|
nothing and return no error.
|
|
|
|
|
*/
|
|
|
|
|
func UpdateSnippetTagsIfAny(ctx context.Context, dbConn db.ConnOrTx, msg *Message) error {
|
|
|
|
|
logging.ExtractLogger(ctx).Debug().Str("msgID", msg.ID).Msg("updating snippets for message (if any)")
|
|
|
|
|
|
|
|
|
|
tx, err := dbConn.Begin(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return oops.New(err, "failed to start transaction")
|
|
|
|
@ -720,10 +724,50 @@ func UpdateSnippetTagsIfAny(ctx context.Context, dbConn db.ConnOrTx, msg *Messag
|
|
|
|
|
if err != nil {
|
|
|
|
|
return oops.New(err, "failed to look up user projects")
|
|
|
|
|
}
|
|
|
|
|
projectIDs := make([]int, len(projects))
|
|
|
|
|
for i, p := range projects {
|
|
|
|
|
projectIDs[i] = p.Project.ID
|
|
|
|
|
userTagIDs := make([]int, 0, len(projects))
|
|
|
|
|
for _, p := range projects {
|
|
|
|
|
if p.Project.TagID != nil {
|
|
|
|
|
userTagIDs = append(userTagIDs, *p.Project.TagID)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Try to associate tags in the message with project tags in HMN.
|
|
|
|
|
// Match only tags for projects in which the current user is a collaborator.
|
|
|
|
|
messageTags := getDiscordTags(s.Snippet.Description)
|
|
|
|
|
type tagsRow struct {
|
|
|
|
|
Tag models.Tag `db:"tags"`
|
|
|
|
|
}
|
|
|
|
|
itUserTags, err := db.Query(ctx, tx, tagsRow{},
|
|
|
|
|
`
|
|
|
|
|
SELECT $columns
|
|
|
|
|
FROM
|
|
|
|
|
tags
|
|
|
|
|
WHERE
|
|
|
|
|
id = ANY ($1)
|
|
|
|
|
`,
|
|
|
|
|
userTagIDs,
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return oops.New(err, "failed to fetch tags for user projects")
|
|
|
|
|
}
|
|
|
|
|
iUserTags := itUserTags.ToSlice()
|
|
|
|
|
|
|
|
|
|
var tagIDs []int
|
|
|
|
|
for _, itag := range iUserTags {
|
|
|
|
|
tag := itag.(*tagsRow).Tag
|
|
|
|
|
for _, messageTag := range messageTags {
|
|
|
|
|
if tag.Text == messageTag {
|
|
|
|
|
userTagIDs = append(userTagIDs, tag.ID)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logging.ExtractLogger(ctx).Info().
|
|
|
|
|
Interface("messageTags", messageTags).
|
|
|
|
|
Interface("tagIDs", tagIDs).
|
|
|
|
|
Int("snippetID", s.Snippet.ID).
|
|
|
|
|
Str("discordMsgID", msg.ID).
|
|
|
|
|
Msg("adding tags to snippet based on Discord message")
|
|
|
|
|
|
|
|
|
|
// Delete any existing project tags for this snippet. We don't want to
|
|
|
|
|
// delete other tags in case in the future we have manual tagging on the
|
|
|
|
@ -743,39 +787,6 @@ func UpdateSnippetTagsIfAny(ctx context.Context, dbConn db.ConnOrTx, msg *Messag
|
|
|
|
|
return oops.New(err, "failed to delete existing snippet tags")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Try to associate tags in the message with project tags in HMN.
|
|
|
|
|
// Match only tags for projects in which the current user is a collaborator.
|
|
|
|
|
messageTags := getDiscordTags(s.Snippet.Description)
|
|
|
|
|
type tagsRow struct {
|
|
|
|
|
Tag models.Tag `db:"tags"`
|
|
|
|
|
}
|
|
|
|
|
itUserTags, err := db.Query(ctx, tx, tagsRow{},
|
|
|
|
|
`
|
|
|
|
|
SELECT $columns
|
|
|
|
|
FROM
|
|
|
|
|
tags
|
|
|
|
|
JOIN handmade_project AS project ON project.tag = tags.id
|
|
|
|
|
JOIN handmade_user_projects AS user_project ON user_project.project_id = project.id
|
|
|
|
|
WHERE
|
|
|
|
|
project.id = ANY ($1)
|
|
|
|
|
`,
|
|
|
|
|
projectIDs,
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return oops.New(err, "failed to fetch tags for user projects")
|
|
|
|
|
}
|
|
|
|
|
iUserTags := itUserTags.ToSlice()
|
|
|
|
|
|
|
|
|
|
var tagIDs []int
|
|
|
|
|
for _, itag := range iUserTags {
|
|
|
|
|
tag := itag.(*tagsRow).Tag
|
|
|
|
|
for _, messageTag := range messageTags {
|
|
|
|
|
if tag.Text == messageTag {
|
|
|
|
|
tagIDs = append(tagIDs, tag.ID)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tagID := range tagIDs {
|
|
|
|
|
_, err = tx.Exec(ctx,
|
|
|
|
|
`
|
|
|
|
|