website/pkg/models/shy_accounts.go

99 lines
2.4 KiB
Go

package models
// Supplementary functions to do with Shy Accounts.
import "code.nonshy.com/nonshy/website/pkg/log"
// IsShy returns whether the user might have an "empty" profile from the perspective of anybody.
//
// An empty profile means their profile is Private or else ALL of their photos are non-public; so that
// somebody viewing their page might see nothing at all from them and consider them a "blank" profile.
func (u *User) IsShy() bool {
// NOTE: if you change the logic for Shy Accounts, also align your changes
// in the functions: WhereClauseShyAccounts.
// Non-certified users are considered empty.
if !u.Certified {
return true
}
// Private profile automatically applies.
if u.Visibility == UserVisibilityPrivate {
return true
}
// If ALL of our photos are non-public, that counts too.
var photoTypes = u.DistinctPhotoTypes()
if _, ok := photoTypes[PhotoPublic]; !ok {
log.Info("IsEmptyProfile: true because visibilities %+v did not include public", photoTypes)
return true
}
return false
}
// WhereClauseShyAccounts returns SQL query fragments when running User table queries
// that will filter for shy accounts.
//
// This is used by SearchUsers and MapShyAccounts.
func WhereClauseShyAccounts() (where string, placeholders []interface{}) {
where = `(
certified IS NOT true
OR visibility = ?
OR NOT EXISTS (
SELECT 1 FROM photos
WHERE user_id = users.id
AND visibility = ?
)
)`
placeholders = []interface{}{
UserVisibilityPrivate,
PhotoPublic,
}
return
}
// ShyMap maps user IDs to Shy Account status in bulk queries.
type ShyMap map[uint64]bool
// MapShyAccounts looks up a set of user IDs in bulk and returns a ShyMap suitable for templates.
func MapShyAccounts(users []*User) ShyMap {
var (
usermap = ShyMap{}
set = map[uint64]interface{}{}
distinct = []uint64{}
)
// Uniqueify users.
for _, user := range users {
if _, ok := set[user.ID]; ok {
continue
}
set[user.ID] = nil
distinct = append(distinct, user.ID)
}
var (
matched = []*User{}
where, placeholders = WhereClauseShyAccounts()
result = (&User{}).
Preload().
Where("id IN ?", distinct).
Where(where, placeholders...).
Find(&matched)
)
if result.Error == nil {
for _, row := range matched {
usermap[row.ID] = true
}
}
return usermap
}
// Get a user from the ShyMap.
func (um ShyMap) Get(id uint64) bool {
return um[id]
}