package hmndata import ( "context" "regexp" "strings" "git.handmade.network/hmn/hmn/src/db" "git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/oops" ) const InvalidUserTwitchID = "INVALID_USER" type TwitchStreamer struct { TwitchID string TwitchLogin string UserID *int ProjectID *int } var twitchRegex = regexp.MustCompile(`twitch\.tv/(?P[^/]+)$`) func FetchTwitchStreamers(ctx context.Context, dbConn db.ConnOrTx) ([]TwitchStreamer, error) { dbStreamers, err := db.Query[models.Link](ctx, dbConn, ` SELECT $columns{link} FROM link LEFT JOIN hmn_user AS link_owner ON link_owner.id = link.user_id WHERE url ~* 'twitch\.tv/([^/]+)$' AND ((link.user_id IS NOT NULL AND link_owner.status = $1) OR (link.project_id IS NOT NULL AND (SELECT COUNT(*) FROM user_project AS hup JOIN hmn_user AS project_owner ON project_owner.id = hup.user_id WHERE hup.project_id = link.project_id AND project_owner.status != $1 ) = 0)) `, models.UserStatusApproved, ) if err != nil { return nil, oops.New(err, "failed to fetch twitch links") } result := make([]TwitchStreamer, 0, len(dbStreamers)) for _, dbStreamer := range dbStreamers { streamer := TwitchStreamer{ UserID: dbStreamer.UserID, ProjectID: dbStreamer.ProjectID, } match := twitchRegex.FindStringSubmatch(dbStreamer.URL) if match != nil { login := strings.ToLower(match[twitchRegex.SubexpIndex("login")]) streamer.TwitchLogin = login } if len(streamer.TwitchLogin) > 0 { duplicate := false for _, r := range result { if r.TwitchLogin == streamer.TwitchLogin { duplicate = true break } } if !duplicate { result = append(result, streamer) } } } return result, nil } func FetchTwitchLoginsForUserOrProject(ctx context.Context, dbConn db.ConnOrTx, userId *int, projectId *int) ([]string, error) { links, err := db.Query[models.Link](ctx, dbConn, ` SELECT $columns FROM link WHERE url ~* 'twitch\.tv/([^/]+)$' AND ((user_id = $1 AND project_id IS NULL) OR (user_id IS NULL AND project_id = $2)) ORDER BY url ASC `, userId, projectId, ) if err != nil { return nil, oops.New(err, "failed to fetch twitch links") } result := make([]string, 0, len(links)) for _, l := range links { match := twitchRegex.FindStringSubmatch(l.URL) if match != nil { login := strings.ToLower(match[twitchRegex.SubexpIndex("login")]) result = append(result, login) } } return result, nil }