mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 08:02:36 +09:00 
			
		
		
		
	The frontpage uses a rather strange method to obtain the commit's avatar which I've overlooked earlier. I don't exactly understand how it works but this change fixes the wrong default avatars by using the function that was in previous use. Also introduced a few constants for size an size increase factor. Fixes: https://github.com/go-gitea/gitea/issues/13844
		
			
				
	
	
		
			139 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2020 The Gitea Authors. All rights reserved.
 | 
						|
// Use of this source code is governed by a MIT-style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
package models
 | 
						|
 | 
						|
import (
 | 
						|
	"crypto/md5"
 | 
						|
	"fmt"
 | 
						|
	"net/url"
 | 
						|
	"path"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"code.gitea.io/gitea/modules/base"
 | 
						|
	"code.gitea.io/gitea/modules/cache"
 | 
						|
	"code.gitea.io/gitea/modules/log"
 | 
						|
	"code.gitea.io/gitea/modules/setting"
 | 
						|
)
 | 
						|
 | 
						|
// EmailHash represents a pre-generated hash map
 | 
						|
type EmailHash struct {
 | 
						|
	Hash  string `xorm:"pk varchar(32)"`
 | 
						|
	Email string `xorm:"UNIQUE NOT NULL"`
 | 
						|
}
 | 
						|
 | 
						|
// DefaultAvatarLink the default avatar link
 | 
						|
func DefaultAvatarLink() string {
 | 
						|
	u, err := url.Parse(setting.AppSubURL)
 | 
						|
	if err != nil {
 | 
						|
		log.Error("GetUserByEmail: %v", err)
 | 
						|
		return ""
 | 
						|
	}
 | 
						|
 | 
						|
	u.Path = path.Join(u.Path, "/img/avatar_default.png")
 | 
						|
	return u.String()
 | 
						|
}
 | 
						|
 | 
						|
// DefaultAvatarSize is a sentinel value for the default avatar size, as
 | 
						|
// determined by the avatar-hosting service.
 | 
						|
const DefaultAvatarSize = -1
 | 
						|
 | 
						|
// DefaultAvatarPixelSize is the default size in pixels of a rendered avatar
 | 
						|
const DefaultAvatarPixelSize = 28
 | 
						|
 | 
						|
// AvatarRenderedSizeFactor is the factor by which the default size is increased for finer rendering
 | 
						|
const AvatarRenderedSizeFactor = 2
 | 
						|
 | 
						|
// HashEmail hashes email address to MD5 string.
 | 
						|
// https://en.gravatar.com/site/implement/hash/
 | 
						|
func HashEmail(email string) string {
 | 
						|
	return base.EncodeMD5(strings.ToLower(strings.TrimSpace(email)))
 | 
						|
}
 | 
						|
 | 
						|
// GetEmailForHash converts a provided md5sum to the email
 | 
						|
func GetEmailForHash(md5Sum string) (string, error) {
 | 
						|
	return cache.GetString("Avatar:"+md5Sum, func() (string, error) {
 | 
						|
		emailHash := EmailHash{
 | 
						|
			Hash: strings.ToLower(strings.TrimSpace(md5Sum)),
 | 
						|
		}
 | 
						|
 | 
						|
		_, err := x.Get(&emailHash)
 | 
						|
		return emailHash.Email, err
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
// LibravatarURL returns the URL for the given email. This function should only
 | 
						|
// be called if a federated avatar service is enabled.
 | 
						|
func LibravatarURL(email string) (*url.URL, error) {
 | 
						|
	urlStr, err := setting.LibravatarService.FromEmail(email)
 | 
						|
	if err != nil {
 | 
						|
		log.Error("LibravatarService.FromEmail(email=%s): error %v", email, err)
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	u, err := url.Parse(urlStr)
 | 
						|
	if err != nil {
 | 
						|
		log.Error("Failed to parse libravatar url(%s): error %v", urlStr, err)
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	return u, nil
 | 
						|
}
 | 
						|
 | 
						|
// HashedAvatarLink returns an avatar link for a provided email
 | 
						|
func HashedAvatarLink(email string) string {
 | 
						|
	lowerEmail := strings.ToLower(strings.TrimSpace(email))
 | 
						|
	sum := fmt.Sprintf("%x", md5.Sum([]byte(lowerEmail)))
 | 
						|
	_, _ = cache.GetString("Avatar:"+sum, func() (string, error) {
 | 
						|
		emailHash := &EmailHash{
 | 
						|
			Email: lowerEmail,
 | 
						|
			Hash:  sum,
 | 
						|
		}
 | 
						|
		// OK we're going to open a session just because I think that that might hide away any problems with postgres reporting errors
 | 
						|
		sess := x.NewSession()
 | 
						|
		defer sess.Close()
 | 
						|
		if err := sess.Begin(); err != nil {
 | 
						|
			// we don't care about any DB problem just return the lowerEmail
 | 
						|
			return lowerEmail, nil
 | 
						|
		}
 | 
						|
		_, _ = sess.Insert(emailHash)
 | 
						|
		if err := sess.Commit(); err != nil {
 | 
						|
			// Seriously we don't care about any DB problems just return the lowerEmail - we expect the transaction to fail most of the time
 | 
						|
			return lowerEmail, nil
 | 
						|
		}
 | 
						|
		return lowerEmail, nil
 | 
						|
	})
 | 
						|
	return setting.AppSubURL + "/avatar/" + url.PathEscape(sum)
 | 
						|
}
 | 
						|
 | 
						|
// MakeFinalAvatarURL constructs the final avatar URL string
 | 
						|
func MakeFinalAvatarURL(u *url.URL, size int) string {
 | 
						|
	vals := u.Query()
 | 
						|
	vals.Set("d", "identicon")
 | 
						|
	if size != DefaultAvatarSize {
 | 
						|
		vals.Set("s", strconv.Itoa(size))
 | 
						|
	}
 | 
						|
	u.RawQuery = vals.Encode()
 | 
						|
	return u.String()
 | 
						|
}
 | 
						|
 | 
						|
// SizedAvatarLink returns a sized link to the avatar for the given email address.
 | 
						|
func SizedAvatarLink(email string, size int) string {
 | 
						|
	var avatarURL *url.URL
 | 
						|
	if setting.EnableFederatedAvatar && setting.LibravatarService != nil {
 | 
						|
		// This is the slow path that would need to call LibravatarURL() which
 | 
						|
		// does DNS lookups. Avoid it by issuing a redirect so we don't block
 | 
						|
		// the template render with network requests.
 | 
						|
		return HashedAvatarLink(email)
 | 
						|
	} else if !setting.DisableGravatar {
 | 
						|
		// copy GravatarSourceURL, because we will modify its Path.
 | 
						|
		copyOfGravatarSourceURL := *setting.GravatarSourceURL
 | 
						|
		avatarURL = ©OfGravatarSourceURL
 | 
						|
		avatarURL.Path = path.Join(avatarURL.Path, HashEmail(email))
 | 
						|
	} else {
 | 
						|
		return DefaultAvatarLink()
 | 
						|
	}
 | 
						|
 | 
						|
	return MakeFinalAvatarURL(avatarURL, size)
 | 
						|
}
 |