gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

defaulticons.go (4403B)


      1 // GoToSocial
      2 // Copyright (C) GoToSocial Authors admin@gotosocial.org
      3 // SPDX-License-Identifier: AGPL-3.0-or-later
      4 //
      5 // This program is free software: you can redistribute it and/or modify
      6 // it under the terms of the GNU Affero General Public License as published by
      7 // the Free Software Foundation, either version 3 of the License, or
      8 // (at your option) any later version.
      9 //
     10 // This program is distributed in the hope that it will be useful,
     11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 // GNU Affero General Public License for more details.
     14 //
     15 // You should have received a copy of the GNU Affero General Public License
     16 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18 package typeutils
     19 
     20 import (
     21 	"math/rand"
     22 	"os"
     23 	"path/filepath"
     24 	"strings"
     25 
     26 	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
     27 	"github.com/superseriousbusiness/gotosocial/internal/config"
     28 	"github.com/superseriousbusiness/gotosocial/internal/log"
     29 )
     30 
     31 const defaultHeaderPath = "/assets/default_header.png"
     32 
     33 // populateDefaultAvatars returns a slice of standard avatars found
     34 // in the path [web-assets-base-dir]/default_avatars. The slice
     35 // entries correspond to the relative url via which they can be
     36 // retrieved from the server.
     37 //
     38 // So for example, an avatar called default.jpeg would be returned
     39 // in the slice as "/assets/default_avatars/default.jpeg".
     40 func populateDefaultAvatars() (defaultAvatars []string) {
     41 	webAssetsAbsFilePath, err := filepath.Abs(config.GetWebAssetBaseDir())
     42 	if err != nil {
     43 		log.Panicf(nil, "error getting abs path for web assets: %s", err)
     44 	}
     45 
     46 	defaultAvatarsAbsFilePath := filepath.Join(webAssetsAbsFilePath, "default_avatars")
     47 	defaultAvatarFiles, err := os.ReadDir(defaultAvatarsAbsFilePath)
     48 	if err != nil {
     49 		log.Warnf(nil, "error reading default avatars at %s: %s", defaultAvatarsAbsFilePath, err)
     50 		return
     51 	}
     52 
     53 	for _, f := range defaultAvatarFiles {
     54 		// ignore directories
     55 		if f.IsDir() {
     56 			continue
     57 		}
     58 
     59 		// ignore files bigger than 50kb
     60 		if i, err := f.Info(); err != nil || i.Size() > 50000 {
     61 			continue
     62 		}
     63 
     64 		// get the name of the file, eg avatar.jpeg
     65 		fileName := f.Name()
     66 
     67 		// get just the .jpeg, for example, from avatar.jpeg
     68 		extensionWithDot := filepath.Ext(fileName)
     69 
     70 		// remove the leading . to just get, eg, jpeg
     71 		extension := strings.TrimPrefix(extensionWithDot, ".")
     72 
     73 		// take only files with simple extensions
     74 		// that we know will work OK as avatars
     75 		switch strings.ToLower(extension) {
     76 		case "jpeg", "jpg", "gif", "png":
     77 			avatarURL := config.GetProtocol() + "://" + config.GetHost() + "/assets/default_avatars/" + fileName
     78 			defaultAvatars = append(defaultAvatars, avatarURL)
     79 		default:
     80 			continue
     81 		}
     82 	}
     83 
     84 	return
     85 }
     86 
     87 // ensureAvatar ensures that the given account has a value set
     88 // for the avatar URL.
     89 //
     90 // If no value is set, an avatar will be selected at random from
     91 // the available default avatars. This selection is 'sticky', so
     92 // the same account will get the same result on subsequent calls.
     93 //
     94 // If a value for the avatar URL is already set, this function is
     95 // a no-op.
     96 //
     97 // If there are no default avatars available, this function is a
     98 // no-op.
     99 func (c *converter) ensureAvatar(account *apimodel.Account) {
    100 	if (account.Avatar != "" && account.AvatarStatic != "") || len(c.defaultAvatars) == 0 {
    101 		return
    102 	}
    103 
    104 	var avatar string
    105 	if avatarI, ok := c.randAvatars.Load(account.ID); ok {
    106 		// we already have a default avatar stored for this account
    107 		avatar, ok = avatarI.(string)
    108 		if !ok {
    109 			panic("avatarI was not a string")
    110 		}
    111 	} else {
    112 		// select + store a default avatar for this account at random
    113 		randomIndex := rand.Intn(len(c.defaultAvatars)) //nolint:gosec
    114 		avatar = c.defaultAvatars[randomIndex]
    115 		c.randAvatars.Store(account.ID, avatar)
    116 	}
    117 
    118 	account.Avatar = avatar
    119 	account.AvatarStatic = avatar
    120 }
    121 
    122 // EnsureAvatar ensures that the given account has a value set
    123 // for the header URL.
    124 //
    125 // If no value is set, the default header will be set.
    126 //
    127 // If a value for the header URL is already set, this function is
    128 // a no-op.
    129 func (c *converter) ensureHeader(account *apimodel.Account) {
    130 	if account.Header != "" && account.HeaderStatic != "" {
    131 		return
    132 	}
    133 
    134 	h := config.GetProtocol() + "://" + config.GetHost() + defaultHeaderPath
    135 	account.Header = h
    136 	account.HeaderStatic = h
    137 }