mirror of https://github.com/abpframework/abp.git
6 changed files with 221 additions and 18 deletions
@ -0,0 +1,210 @@ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Linq; |
|||
using System.Security.Cryptography; |
|||
using System.Text; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Razor.TagHelpers; |
|||
|
|||
namespace Volo.Blogging.Areas.Blog.Helpers.TagHelpers |
|||
{ |
|||
/// <inheritdoc />
|
|||
/// <summary>
|
|||
/// Returns a Globally Recognised Avatar https://en.gravatar.com
|
|||
/// </summary>
|
|||
[HtmlTargetElement("img", Attributes = "gravatar-email")] |
|||
public class GravatarTagHelper : TagHelper |
|||
{ |
|||
private readonly IHttpContextAccessor _contextAccessor; |
|||
|
|||
public GravatarTagHelper(IHttpContextAccessor contextAccessor) |
|||
{ |
|||
_contextAccessor = contextAccessor; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Email Address for the Gravatar
|
|||
/// </summary>
|
|||
[HtmlAttributeName("gravatar-email")] |
|||
public string Email { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gravatar content rating (note that Gravatars are self-rated)
|
|||
/// </summary>
|
|||
[HtmlAttributeName("gravatar-rating")] |
|||
public GravatarRating Rating { get; set; } = GravatarRating.GeneralAudiences; |
|||
|
|||
/// <summary>
|
|||
/// Size in pixels (default: 80)
|
|||
/// </summary>
|
|||
[HtmlAttributeName("gravatar-size")] |
|||
public int Size { get; set; } = 80; |
|||
|
|||
/// <summary>
|
|||
/// URL to a custom default image (e.g: 'Url.Content("~/images/no-grvatar.png")' )
|
|||
/// </summary>
|
|||
[HtmlAttributeName("default-image-url")] |
|||
public string DefaultImageUrl { get; set; } = ""; |
|||
|
|||
/// <summary>
|
|||
/// Prefer the default image over the users own Gravatar
|
|||
/// </summary>
|
|||
[HtmlAttributeName("force-default-image")] |
|||
public bool ForceDefaultImage { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Default image if user hasn't created a Gravatar
|
|||
/// </summary>
|
|||
[HtmlAttributeName("default-image")] |
|||
public GravatarDefaultImage DefaultImage { get; set; } = GravatarDefaultImage.Default; |
|||
|
|||
/// <summary>
|
|||
/// Always do secure (https) requests
|
|||
/// </summary>
|
|||
[HtmlAttributeName("force-secure-request")] |
|||
public bool ForceSecureRequest { get; set; } = true; |
|||
|
|||
|
|||
public override void Process(TagHelperContext context, TagHelperOutput output) |
|||
{ |
|||
var emailAddress = Email == null ? string.Empty : Email.Trim().ToLower(); |
|||
|
|||
var url = string.Format("{0}://{1}.gravatar.com/avatar/{2}?s={3}{4}{5}{6}", |
|||
GetUrlScheme(), |
|||
GetUrlPrefix(), |
|||
GetMd5Hash(emailAddress), |
|||
Size, |
|||
GetDefaultImageParameter(), |
|||
GetForceDefaultImageParameter(), |
|||
GetRatingParameter() |
|||
); |
|||
|
|||
output.Attributes.SetAttribute("src", url); |
|||
} |
|||
|
|||
private string GetUrlScheme() |
|||
{ |
|||
return ForceSecureRequest || _contextAccessor.HttpContext.Request.IsHttps |
|||
? "https" : "http"; |
|||
} |
|||
|
|||
private string GetUrlPrefix() |
|||
{ |
|||
return ForceSecureRequest || _contextAccessor.HttpContext.Request.IsHttps ? "secure" : "www"; |
|||
} |
|||
|
|||
private string GetDefaultImageParameter() |
|||
{ |
|||
return "&d=" + (!string.IsNullOrEmpty(DefaultImageUrl) |
|||
? System.Net.WebUtility.UrlEncode(DefaultImageUrl) |
|||
: GetEnumDescription(DefaultImage)); |
|||
} |
|||
|
|||
private string GetForceDefaultImageParameter() |
|||
{ |
|||
return ForceDefaultImage ? "&f=y" : ""; |
|||
} |
|||
|
|||
private string GetRatingParameter() |
|||
{ |
|||
return "&r=" + GetEnumDescription(Rating); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Generates an MD5 hash of the given string
|
|||
/// </summary>
|
|||
/// <remarks>Source: http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5.aspx </remarks>
|
|||
private static string GetMd5Hash(string input) |
|||
{ |
|||
// Convert the input string to a byte array and compute the hash.
|
|||
var data = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(input)); |
|||
|
|||
// Create a new Stringbuilder to collect the bytes
|
|||
// and create a string.
|
|||
var sBuilder = new StringBuilder(); |
|||
|
|||
// Loop through each byte of the hashed data
|
|||
// and format each one as a hexadecimal string.
|
|||
foreach (var t in data) |
|||
{ |
|||
sBuilder.Append(t.ToString("x2")); |
|||
} |
|||
|
|||
// Return the hexadecimal string.
|
|||
return sBuilder.ToString(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the value of a Description for a given Enum value
|
|||
/// </summary>
|
|||
/// <remarks>Source: http://blogs.msdn.com/b/abhinaba/archive/2005/10/21/483337.aspx </remarks>
|
|||
/// <param name="en"></param>
|
|||
/// <returns></returns>
|
|||
private static string GetEnumDescription(Enum en) |
|||
{ |
|||
var type = en.GetType(); |
|||
var memInfo = type.GetMember(en.ToString()); |
|||
|
|||
if (memInfo == null || memInfo.Length <= 0) |
|||
{ |
|||
return en.ToString(); |
|||
} |
|||
|
|||
var attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false); |
|||
|
|||
if (attrs != null && attrs.Any()) |
|||
{ |
|||
return ((DescriptionAttribute)attrs.First()).Description; |
|||
} |
|||
|
|||
return en.ToString(); |
|||
} |
|||
|
|||
public enum GravatarDefaultImage |
|||
{ |
|||
/// <summary>Default Gravatar logo</summary>
|
|||
[Description("")] |
|||
Default, |
|||
/// <summary>404 - do not load any image if none is associated with the email hash, instead return an HTTP 404 (File Not Found) response</summary>
|
|||
[Description("404")] |
|||
Http404, |
|||
/// <summary>Mystery-Man - a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)</summary>
|
|||
[Description("mm")] |
|||
MysteryMan, |
|||
/// <summary>Identicon - a geometric pattern based on an email hash</summary>
|
|||
[Description("identicon")] |
|||
Identicon, |
|||
/// <summary>MonsterId - a generated 'monster' with different colors, faces, etc</summary>
|
|||
[Description("monsterid")] |
|||
MonsterId, |
|||
/// <summary>Wavatar - generated faces with differing features and backgrounds</summary>
|
|||
[Description("wavatar")] |
|||
Wavatar, |
|||
/// <summary>Retro - awesome generated, 8-bit arcade-style pixelated faces</summary>
|
|||
[Description("retro")] |
|||
Retro |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gravatar allows users to self-rate their images so that they can indicate if an image is appropriate for a certain audience. By default, only 'G' rated images are displayed unless you indicate that you would like to see higher ratings
|
|||
/// </summary>
|
|||
public enum GravatarRating |
|||
{ |
|||
/// <summary>Suitable for display on all websites with any audience type</summary>
|
|||
[Description("g")] |
|||
GeneralAudiences, |
|||
|
|||
/// <summary>May contain rude gestures, provocatively dressed individuals, the lesser swear words, or mild violence</summary>
|
|||
[Description("pg")] |
|||
ParentalGuidance, |
|||
|
|||
/// <summary>May contain such things as harsh profanity, intense violence, nudity, or hard drug use</summary>
|
|||
[Description("r")] |
|||
Restricted, |
|||
|
|||
/// <summary>May contain hardcore sexual imagery or extremely disturbing violence</summary>
|
|||
[Description("x")] |
|||
OnlyMature |
|||
} |
|||
} |
|||
} |
|||
@ -1,3 +1,4 @@ |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
@addTagHelper *, Volo.Blogging.Web |
|||
|
|||
Loading…
Reference in new issue