code.gitea.io/gitea@v1.22.3/services/user/avatar.go (about)

     1  // Copyright 2023 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package user
     5  
     6  import (
     7  	"context"
     8  	"errors"
     9  	"fmt"
    10  	"io"
    11  	"os"
    12  
    13  	"code.gitea.io/gitea/models/db"
    14  	user_model "code.gitea.io/gitea/models/user"
    15  	"code.gitea.io/gitea/modules/avatar"
    16  	"code.gitea.io/gitea/modules/log"
    17  	"code.gitea.io/gitea/modules/storage"
    18  )
    19  
    20  // UploadAvatar saves custom avatar for user.
    21  func UploadAvatar(ctx context.Context, u *user_model.User, data []byte) error {
    22  	avatarData, err := avatar.ProcessAvatarImage(data)
    23  	if err != nil {
    24  		return err
    25  	}
    26  
    27  	ctx, committer, err := db.TxContext(ctx)
    28  	if err != nil {
    29  		return err
    30  	}
    31  	defer committer.Close()
    32  
    33  	u.UseCustomAvatar = true
    34  	u.Avatar = avatar.HashAvatar(u.ID, data)
    35  	if err = user_model.UpdateUserCols(ctx, u, "use_custom_avatar", "avatar"); err != nil {
    36  		return fmt.Errorf("updateUser: %w", err)
    37  	}
    38  
    39  	if err := storage.SaveFrom(storage.Avatars, u.CustomAvatarRelativePath(), func(w io.Writer) error {
    40  		_, err := w.Write(avatarData)
    41  		return err
    42  	}); err != nil {
    43  		return fmt.Errorf("Failed to create dir %s: %w", u.CustomAvatarRelativePath(), err)
    44  	}
    45  
    46  	return committer.Commit()
    47  }
    48  
    49  // DeleteAvatar deletes the user's custom avatar.
    50  func DeleteAvatar(ctx context.Context, u *user_model.User) error {
    51  	aPath := u.CustomAvatarRelativePath()
    52  	log.Trace("DeleteAvatar[%d]: %s", u.ID, aPath)
    53  
    54  	return db.WithTx(ctx, func(ctx context.Context) error {
    55  		hasAvatar := len(u.Avatar) > 0
    56  		u.UseCustomAvatar = false
    57  		u.Avatar = ""
    58  		if _, err := db.GetEngine(ctx).ID(u.ID).Cols("avatar, use_custom_avatar").Update(u); err != nil {
    59  			return fmt.Errorf("DeleteAvatar: %w", err)
    60  		}
    61  
    62  		if hasAvatar {
    63  			if err := storage.Avatars.Delete(aPath); err != nil {
    64  				if !errors.Is(err, os.ErrNotExist) {
    65  					return fmt.Errorf("failed to remove %s: %w", aPath, err)
    66  				}
    67  				log.Warn("Deleting avatar %s but it doesn't exist", aPath)
    68  			}
    69  		}
    70  
    71  		return nil
    72  	})
    73  }