diff --git a/models/group/avatar.go b/models/group/avatar.go new file mode 100644 index 0000000000..3b6bf66bf7 --- /dev/null +++ b/models/group/avatar.go @@ -0,0 +1,80 @@ +package group + +import ( + "code.gitea.io/gitea/models/avatars" + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/avatar" + "code.gitea.io/gitea/modules/httplib" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/storage" + "context" + "fmt" + "image/png" + "io" + "net/url" +) + +func (g *Group) CustomAvatarRelativePath() string { + return g.Avatar +} +func generateRandomAvatar(ctx context.Context, group *Group) error { + idToString := fmt.Sprintf("%d", group.ID) + + seed := idToString + img, err := avatar.RandomImage([]byte(seed)) + if err != nil { + return fmt.Errorf("RandomImage: %w", err) + } + + group.Avatar = idToString + + if err = storage.SaveFrom(storage.RepoAvatars, group.CustomAvatarRelativePath(), func(w io.Writer) error { + if err = png.Encode(w, img); err != nil { + log.Error("Encode: %v", err) + } + return err + }); err != nil { + return fmt.Errorf("Failed to create dir %s: %w", group.CustomAvatarRelativePath(), err) + } + + log.Info("New random avatar created for repository: %d", group.ID) + + if _, err = db.GetEngine(ctx).ID(group.ID).Cols("avatar").NoAutoTime().Update(group); err != nil { + return err + } + + return nil +} +func (g *Group) relAvatarLink(ctx context.Context) string { + // If no avatar - path is empty + avatarPath := g.CustomAvatarRelativePath() + if len(avatarPath) == 0 { + switch mode := setting.RepoAvatar.Fallback; mode { + case "image": + return setting.RepoAvatar.FallbackImage + case "random": + if err := generateRandomAvatar(ctx, g); err != nil { + log.Error("generateRandomAvatar: %v", err) + } + default: + // default behaviour: do not display avatar + return "" + } + } + return setting.AppSubURL + "/group-avatars/" + url.PathEscape(g.Avatar) +} + +func (g *Group) AvatarLink(ctx context.Context) string { + relLink := g.relAvatarLink(ctx) + if relLink != "" { + return httplib.MakeAbsoluteURL(ctx, relLink) + } + return "" +} +func (g *Group) AvatarLinkWithSize(size int) string { + if g.Avatar == "" { + return avatars.DefaultAvatarLink() + } + return avatars.GenerateUserAvatarImageLink(g.Avatar, size) +} diff --git a/models/group/group.go b/models/group/group.go index 0f0209b4d9..aee073999a 100644 --- a/models/group/group.go +++ b/models/group/group.go @@ -19,6 +19,7 @@ type Group struct { Name string `xorm:"INDEX NOT NULL"` DisplayName string `xorm:"TEXT"` Description string `xorm:"TEXT"` + Avatar string `xorm:"VARCHAR(64)"` ParentGroupID int64 `xorm:"INDEX DEFAULT NULL"` Subgroups GroupList `xorm:"-"`