PageRenderTime 66ms CodeModel.GetById 50ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 1ms

/BlogEngine/BlogEngine.NET/widgets/Most comments/widget.ascx.cs

#
C# | 345 lines | 199 code | 55 blank | 91 comment | 19 complexity | 7e5a6ec525fbed2762435db9a14f0597 MD5 | raw file
  1// --------------------------------------------------------------------------------------------------------------------
  2// <summary>
  3//   The most comments widget.
  4// </summary>
  5// --------------------------------------------------------------------------------------------------------------------
  6
  7namespace Widgets.MostComments
  8{
  9    using System;
 10    using System.Collections.Generic;
 11    using System.Globalization;
 12    using System.Linq;
 13    using System.Web;
 14    using System.Web.UI.WebControls;
 15
 16    using App_Code.Controls;
 17
 18    using BlogEngine.Core;
 19
 20    using Resources;
 21
 22    /// <summary>
 23    /// The visitor.
 24    /// </summary>
 25    public struct Visitor
 26    {
 27        #region Constants and Fields
 28
 29        /// <summary>
 30        ///     The comments.
 31        /// </summary>
 32        public int Comments;
 33
 34        /// <summary>
 35        ///     The country.
 36        /// </summary>
 37        public string Country;
 38
 39        /// <summary>
 40        ///     The email.
 41        /// </summary>
 42        public string Email;
 43
 44        /// <summary>
 45        ///     The visitor name.
 46        /// </summary>
 47        public string Name;
 48
 49        /// <summary>
 50        ///     The website.
 51        /// </summary>
 52        public Uri Website;
 53
 54        #endregion
 55    }
 56
 57    /// <summary>
 58    /// The most comments widget.
 59    /// </summary>
 60    public partial class Widget : WidgetBase
 61    {
 62        #region Constants and Fields
 63
 64        /// <summary>
 65        ///     The avatar size.
 66        /// </summary>
 67        private int avatarSize = 50;
 68
 69        /// <summary>
 70        ///     The 60 days.
 71        /// </summary>
 72        private int days = 60;
 73
 74        /// <summary>
 75        ///     The number of visitors.
 76        /// </summary>
 77        private int numberOfVisitors = 3;
 78
 79        /// <summary>
 80        ///     The show comments.
 81        /// </summary>
 82        private bool showComments = true;
 83
 84        #endregion
 85
 86        #region Constructors and Destructors
 87
 88        /// <summary>
 89        ///     Initializes static members of the <see cref = "Widget" /> class.
 90        /// </summary>
 91        static Widget()
 92        {
 93            Post.CommentAdded += (sender, args) => Blog.CurrentInstance.Cache.Remove("most_comments");
 94        }
 95
 96        #endregion
 97
 98        #region Properties
 99
100        /// <summary>
101        ///     Gets whether the widget can be edited.
102        ///     <remarks>
103        ///         The only way a widget can be editable is by adding a edit.ascx file to the widget folder.
104        ///     </remarks>
105        /// </summary>
106        public override bool IsEditable
107        {
108            get
109            {
110                return true;
111            }
112        }
113
114        /// <summary>
115        ///     Gets the name. It must be exactly the same as the folder that contains the widget.
116        /// </summary>
117        public override string Name
118        {
119            get
120            {
121                return "Most comments";
122            }
123        }
124
125        #endregion
126
127        #region Public Methods
128
129        /// <summary>
130        /// This method works as a substitute for Page_Load. You should use this method for
131        ///     data binding etc. instead of Page_Load.
132        /// </summary>
133        public override void LoadWidget()
134        {
135            this.LoadSettings();
136
137            if (Blog.CurrentInstance.Cache["most_comments"] == null)
138            {
139                this.BuildList();
140            }
141
142            var visitors = (List<Visitor>)Blog.CurrentInstance.Cache["most_comments"];
143
144            this.rep.ItemDataBound += this.RepItemDataBound;
145            this.rep.DataSource = visitors;
146            this.rep.DataBind();
147        }
148
149        #endregion
150
151        #region Methods
152
153        /// <summary>
154        /// Finds the visitor.
155        /// </summary>
156        /// <param name="email">
157        /// The email.
158        /// </param>
159        /// <param name="comments">
160        /// The comments.
161        /// </param>
162        /// <returns>
163        /// The Visitor.
164        /// </returns>
165        private static Visitor FindVisitor(string email, int comments)
166        {
167            foreach (var visitor in from post in Post.Posts
168                                    from comment in post.ApprovedComments
169                                    where comment.Email == email
170                                    select
171                                        new Visitor
172                                            {
173                                                Name = comment.Author, 
174                                                Country = comment.Country, 
175                                                Website = comment.Website, 
176                                                Comments = comments, 
177                                                Email = email
178                                            })
179            {
180                return visitor;
181            }
182
183            return new Visitor();
184        }
185
186        /// <summary>
187        /// Sorts the dictionary.
188        /// </summary>
189        /// <param name="dic">
190        /// The dictionary.
191        /// </param>
192        /// <returns>
193        /// The sorted dictionary.
194        /// </returns>
195        private static Dictionary<string, int> SortDictionary(Dictionary<string, int> dic)
196        {
197            var list = dic.Keys.Select(key => new KeyValuePair<string, int>(key, dic[key])).ToList();
198
199            list.Sort((obj1, obj2) => obj2.Value.CompareTo(obj1.Value));
200
201            return list.ToDictionary(pair => pair.Key, pair => pair.Value);
202        }
203
204        /// <summary>
205        /// Builds the list.
206        /// </summary>
207        private void BuildList()
208        {
209            var visitors = new Dictionary<string, int>();
210            foreach (var comment in from post in Post.Posts
211                                    from comment in post.ApprovedComments
212                                    where
213                                        (comment.DateCreated.AddDays(this.days) >= DateTime.Now &&
214                                         !string.IsNullOrEmpty(comment.Email)) && comment.Email.Contains("@")
215                                    where !post.Author.Equals(comment.Author, StringComparison.OrdinalIgnoreCase)
216                                    select comment)
217            {
218                if (visitors.ContainsKey(comment.Email))
219                {
220                    visitors[comment.Email] += 1;
221                }
222                else
223                {
224                    visitors.Add(comment.Email, 1);
225                }
226            }
227
228            visitors = SortDictionary(visitors);
229            
230            // var max = Math.Min(visitors.Count, this.numberOfVisitors);
231            var count = 0;
232            var list = new List<Visitor>();
233
234            foreach (var v in visitors.Keys.Select(key => FindVisitor(key, visitors[key])))
235            {
236                list.Add(v);
237
238                count++;
239
240                if (count == this.numberOfVisitors)
241                {
242                    break;
243                }
244            }
245
246            Blog.CurrentInstance.Cache.Insert("most_comments", list);
247        }
248
249        /// <summary>
250        /// The load settings.
251        /// </summary>
252        private void LoadSettings()
253        {
254            var settings = this.GetSettings();
255            try
256            {
257                if (settings.ContainsKey("avatarsize"))
258                {
259                    this.avatarSize = int.Parse(settings["avatarsize"]);
260                }
261
262                if (settings.ContainsKey("numberofvisitors"))
263                {
264                    this.numberOfVisitors = int.Parse(settings["numberofvisitors"]);
265                }
266
267                if (settings.ContainsKey("days"))
268                {
269                    this.days = int.Parse(settings["days"]);
270                }
271
272                if (settings.ContainsKey("showcomments"))
273                {
274                    this.showComments = settings["showcomments"].Equals("true", StringComparison.OrdinalIgnoreCase);
275                }
276            }
277            catch
278            {
279            }
280        }
281
282        /// <summary>
283        /// Handles the ItemDataBound event of the rep control.
284        /// </summary>
285        /// <param name="sender">
286        /// The source of the event.
287        /// </param>
288        /// <param name="e">
289        /// The <see cref="System.Web.UI.WebControls.RepeaterItemEventArgs"/> instance containing the event data.
290        /// </param>
291        private void RepItemDataBound(object sender, RepeaterItemEventArgs e)
292        {
293            if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
294            {
295                return;
296            }
297
298            var visitor = (Visitor)e.Item.DataItem;
299            var imgAvatar = (Image)e.Item.FindControl("imgAvatar");
300            var imgCountry = (Image)e.Item.FindControl("imgCountry");
301            var name = (Literal)e.Item.FindControl("litName");
302            var number = (Literal)e.Item.FindControl("litNumber");
303            var litCountry = (Literal)e.Item.FindControl("litCountry");
304
305            imgAvatar.ImageUrl = Avatar.GetAvatar(this.avatarSize, visitor.Email, null, null, null).Url.ToString();
306            imgAvatar.AlternateText = visitor.Name;
307            imgAvatar.Width = Unit.Pixel(this.avatarSize);
308
309            if (this.showComments)
310            {
311                number.Text = string.Format("{0} {1}<br />", visitor.Comments, labels.comments.ToLowerInvariant());
312            }
313
314            if (visitor.Website != null)
315            {
316                const string LinkFormat = "<a rel=\"nofollow contact\" class=\"url fn\" href=\"{0}\">{1}</a>";
317                name.Text = string.Format(LinkFormat, visitor.Website, visitor.Name);
318            }
319            else
320            {
321                name.Text = string.Format("<span class=\"fn\">{0}</span>", visitor.Name);
322            }
323
324            if (!string.IsNullOrEmpty(visitor.Country))
325            {
326                imgCountry.ImageUrl = string.Format("{0}pics/flags/{1}.png", Utils.RelativeWebRoot, visitor.Country);
327                imgCountry.AlternateText = visitor.Country;
328
329                foreach (var ri in
330                    CultureInfo.GetCultures(CultureTypes.SpecificCultures).Select(ci => new RegionInfo(ci.Name)).Where(
331                        ri => ri.TwoLetterISORegionName.Equals(visitor.Country, StringComparison.OrdinalIgnoreCase)))
332                {
333                    litCountry.Text = ri.DisplayName;
334                    break;
335                }
336            }
337            else
338            {
339                imgCountry.Visible = false;
340            }
341        }
342
343        #endregion
344    }
345}