@@ -16,6 +16,8 @@ import (
16
16
"math"
17
17
"math/big"
18
18
"net/http"
19
+ "net/url"
20
+ "path"
19
21
"strconv"
20
22
"strings"
21
23
"time"
@@ -197,24 +199,59 @@ func DefaultAvatarLink() string {
197
199
return setting .AppSubURL + "/img/avatar_default.png"
198
200
}
199
201
200
- // AvatarLink returns relative avatar link to the site domain by given email,
201
- // which includes app sub-url as prefix. However, it is possible
202
- // to return full URL if user enables Gravatar-like service.
203
- func AvatarLink (email string ) string {
202
+ // DefaultAvatarSize is a sentinel value for the default avatar size, as
203
+ // determined by the avatar-hosting service.
204
+ const DefaultAvatarSize = - 1
205
+
206
+ // libravatarURL returns the URL for the given email. This function should only
207
+ // be called if a federated avatar service is enabled.
208
+ func libravatarURL (email string ) (* url.URL , error ) {
209
+ urlStr , err := setting .LibravatarService .FromEmail (email )
210
+ if err != nil {
211
+ log .Error (4 , "LibravatarService.FromEmail(email=%s): error %v" , email , err )
212
+ return nil , err
213
+ }
214
+ u , err := url .Parse (urlStr )
215
+ if err != nil {
216
+ log .Error (4 , "Failed to parse libravatar url(%s): error %v" , urlStr , err )
217
+ return nil , err
218
+ }
219
+ return u , nil
220
+ }
221
+
222
+ // SizedAvatarLink returns a sized link to the avatar for the given email
223
+ // address.
224
+ func SizedAvatarLink (email string , size int ) string {
225
+ var avatarURL * url.URL
204
226
if setting .EnableFederatedAvatar && setting .LibravatarService != nil {
205
- url , err := setting .LibravatarService .FromEmail (email )
227
+ var err error
228
+ avatarURL , err = libravatarURL (email )
206
229
if err != nil {
207
- log .Error (4 , "LibravatarService.FromEmail(email=%s): error %v" , email , err )
208
230
return DefaultAvatarLink ()
209
231
}
210
- return url
232
+ } else if ! setting .DisableGravatar {
233
+ // copy GravatarSourceURL, because we will modify its Path.
234
+ copyOfGravatarSourceURL := * setting .GravatarSourceURL
235
+ avatarURL = & copyOfGravatarSourceURL
236
+ avatarURL .Path = path .Join (avatarURL .Path , HashEmail (email ))
237
+ } else {
238
+ return DefaultAvatarLink ()
211
239
}
212
240
213
- if ! setting .DisableGravatar {
214
- return setting .GravatarSource + HashEmail (email ) + "?d=identicon"
241
+ vals := avatarURL .Query ()
242
+ vals .Set ("d" , "identicon" )
243
+ if size != DefaultAvatarSize {
244
+ vals .Set ("s" , strconv .Itoa (size ))
215
245
}
246
+ avatarURL .RawQuery = vals .Encode ()
247
+ return avatarURL .String ()
248
+ }
216
249
217
- return DefaultAvatarLink ()
250
+ // AvatarLink returns relative avatar link to the site domain by given email,
251
+ // which includes app sub-url as prefix. However, it is possible
252
+ // to return full URL if user enables Gravatar-like service.
253
+ func AvatarLink (email string ) string {
254
+ return SizedAvatarLink (email , DefaultAvatarSize )
218
255
}
219
256
220
257
// Seconds-based time units
0 commit comments