<commit_before>/* YetAnotherForum.NET
 * Copyright (C) 2006-2012 <NAME>
 * http://www.yetanotherforum.net/
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
namespace YAF
{
    #region Using

    using System;
    using System.Data;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;
    using System.Drawing.Text;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Web;
    using System.Web.Security;
    using System.Web.SessionState;

    using YAF.Classes;
    using YAF.Classes.Data;
    using YAF.Controls;
    using YAF.Core;
    using YAF.Core.Services;
    using YAF.Types;
    using YAF.Types.Constants;
    using YAF.Types.Interfaces;
    using YAF.Utils;
    using YAF.Utils.Extensions;
    using YAF.Utils.Helpers;

    #endregion

    /// <summary>
    /// Yaf Resource Handler for all kind of Stuff (Avatars, Attachments, Albums, etc.)
    /// </summary>
    public class YafResourceHandler : IHttpHandler, IReadOnlySessionState, IHaveServiceLocator
    {
        #region Properties

        /// <summary>
        ///   Gets a value indicating whether IsReusable.
        /// </summary>
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// Gets ServiceLocator.
        /// </summary>
        public IServiceLocator ServiceLocator
        {
            get
            {
                return YafContext.Current.ServiceLocator;
            }
        }

        #endregion

        #region Implemented Interfaces

        #region IHttpHandler

        /// <summary>
        /// The process request.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        public void ProcessRequest([NotNull] HttpContext context)
        {
            // resource no longer works with dynamic compile...
            if (context.Request.QueryString.GetFirstOrDefault("r") != null)
            {
                // resource request
                GetResource(context);
            }
            else if (context.Session["lastvisit"] != null
                     ||
                     context.Request.UrlReferrer != null
                     && context.Request.UrlReferrer.AbsoluteUri.Contains(BaseUrlBuilder.BaseUrl))
            {
                // defaults
                var previewCropped = false;
                var localizationFile = "english.xml";

                if (context.Session["imagePreviewCropped"] != null && context.Session["imagePreviewCropped"] is bool)
                {
                    previewCropped = (bool)context.Session["imagePreviewCropped"];
                }

                if (context.Session["localizationFile"] != null && context.Session["localizationFile"] is string)
                {
                    localizationFile = context.Session["localizationFile"].ToString();
                }

                if (context.Session["localizationFile"] != null && context.Session["localizationFile"] is string)
                {
                    localizationFile = context.Session["localizationFile"].ToString();
                }
                /////////////

                if (context.Request.QueryString.GetFirstOrDefault("userinfo") != null)
                {
                    this.GetUserInfo(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("u") != null)
                {
                    this.GetResponseLocalAvatar(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("url") != null
                         && context.Request.QueryString.GetFirstOrDefault("width") != null
                         && context.Request.QueryString.GetFirstOrDefault("height") != null)
                {
                    this.GetResponseRemoteAvatar(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("a") != null)
                {
                    this.GetResponseAttachment(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("i") != null)
                {
                    // TommyB: Start MOD: Preview Images   ##########
                    this.GetResponseImage(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("p") != null)
                {
                    this.GetResponseImagePreview(
                        context, localizationFile, previewCropped);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("c") != null)
                {
                    // TommyB: End MOD: Preview Images   ##########
                    // captcha
                    this.GetResponseCaptcha(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("cover") != null
                         && context.Request.QueryString.GetFirstOrDefault("album") != null)
                {
                    // album cover
                    this.GetAlbumCover(context, localizationFile, previewCropped);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("imgprv") != null)
                {
                    // album image preview
                    this.GetAlbumImagePreview(context, localizationFile, previewCropped);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("image") != null)
                {
                    // album image
                    this.GetAlbumImage(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("s") != null
                         && context.Request.QueryString.GetFirstOrDefault("lang") != null)
                {
                    GetResponseGoogleSpell(context);
                }
            }
            else
            {
                // they don't have a session...
                context.Response.Write(
                    "Please do not link directly to this resource. You must have a session in the forum.");
            }
        }

        #endregion

        #endregion

        #region Methods

        /// <summary>
        /// Check if the ETag that sent from the client is match to the current ETag.
        ///   If so, set the status code to 'Not Modified' and stop the response.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <param name="eTagCode">
        /// The e Tag Code.
        /// </param>
        /// <returns>
        /// The check e tag.
        /// </returns>
        private static bool CheckETag([NotNull] HttpContext context, [NotNull] string eTagCode)
        {
            string ifNoneMatch = context.Request.Headers["If-None-Match"];
            if (eTagCode.Equals(ifNoneMatch, StringComparison.Ordinal))
            {
                context.Response.AppendHeader("Content-Length", "0");
                context.Response.StatusCode = (int)HttpStatusCode.NotModified;
                context.Response.StatusDescription = "Not modified";
                context.Response.SuppressContent = true;
                context.Response.Cache.SetCacheability(HttpCacheability.Public);
                context.Response.Cache.SetETag(eTagCode);
                context.Response.Flush();
                return true;
            }

            return false;
        }

        /// <summary>
        /// Get the Album Or Image Attachement Preview
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="previewWidth">The preview width.</param>
        /// <param name="previewHeight">The preview height.</param>
        /// <param name="previewCropped">The preview Cropped</param>
        /// <param name="downloads">The downloads.</param>
        /// <param name="localizationFile">The localization file.</param>
        /// <param name="localizationPage">The localization page.</param>
        /// <returns>
        /// Resized Image Stream
        /// </returns>
        [NotNull]
        private static MemoryStream GetAlbumOrAttachmentImageResized(
            [NotNull] Stream data,
            int previewWidth,
            int previewHeight,
            bool previewCropped,
            int downloads,
            [NotNull] string localizationFile,
            string localizationPage)
        {
            const int PixelPadding = 6;
            const int BottomSize = 26;

            var localization = new YafLocalization(localizationPage);
            localization.LoadTranslation(localizationFile);

            using (var src = new Bitmap(data))
            {
                var ms = new MemoryStream();

                // Cropped Image
                int size = previewWidth;

                var newImgSize = new Size(previewWidth, previewHeight);
                int x = 0;
                int y = 0;

                if (previewCropped)
                {
                    // Determine dimensions of resized version of the image 
                    if (newImgSize.Width > newImgSize.Height)
                    {
                        newImgSize.Width =
                            decimal.Round(
                                (size.ToType<decimal>()
                                 * (newImgSize.Width.ToType<decimal>() / newImgSize.Height.ToType<decimal>())).ToType<decimal>(),
                                0).ToType<int>();
                        newImgSize.Height = size;
                    }
                    else if (newImgSize.Height > newImgSize.Width)
                    {
                        newImgSize.Height =
                            decimal.Round(
                                (size.ToType<decimal>()
                                 * (newImgSize.Height.ToType<decimal>() / newImgSize.Width.ToType<decimal>())).ToType<decimal>(),
                                0).ToType<int>();
                        newImgSize.Width = size;
                    }
                    else
                    {
                        newImgSize.Width = size;
                        newImgSize.Height = size;
                    }

                    newImgSize.Width = newImgSize.Width - PixelPadding;
                    newImgSize.Height = newImgSize.Height - BottomSize - PixelPadding;

                    // moves cursor so that crop is more centered 
                    x = newImgSize.Width / 2;
                    y = newImgSize.Height / 2;
                }
                else
                {
                    var finalHeight = Math.Abs(src.Height * newImgSize.Width / src.Width);

                    // Height resize if necessary
                    if (finalHeight > newImgSize.Height)
                    {
                        newImgSize.Width = src.Width * newImgSize.Height / src.Height;
                        finalHeight = newImgSize.Height;
                    }

                    newImgSize.Height = finalHeight;
                    newImgSize.Width = newImgSize.Width - PixelPadding;
                    newImgSize.Height = newImgSize.Height - BottomSize - PixelPadding;

                    if (newImgSize.Height <= BottomSize + PixelPadding)
                    {
                        newImgSize.Height = finalHeight;
                    }
                }

                bool heightToSmallFix = newImgSize.Height <= BottomSize + PixelPadding;

                using (
                    var dst = new Bitmap(
                        newImgSize.Width + PixelPadding,
                        newImgSize.Height + BottomSize + PixelPadding,
                        PixelFormat.Format24bppRgb))
                {
                    var rSrcImg = new Rectangle(
                        0, 0, src.Width, src.Height + (heightToSmallFix ? BottomSize + PixelPadding : 0));

                    if (previewCropped)
                    {
                        rSrcImg = new Rectangle(x, y, newImgSize.Width, newImgSize.Height);
                    }

                    var rDstImg = new Rectangle(3, 3, dst.Width - PixelPadding, dst.Height - PixelPadding - BottomSize);
                    var rDstTxt1 = new Rectangle(3, rDstImg.Height + 3, newImgSize.Width, BottomSize - 13);
                    var rDstTxt2 = new Rectangle(3, rDstImg.Height + 16, newImgSize.Width, BottomSize - 13);

                    using (Graphics g = Graphics.FromImage(dst))
                    {
                        g.Clear(Color.FromArgb(64, 64, 64));
                        g.FillRectangle(Brushes.White, rDstImg);

                        g.CompositingMode = CompositingMode.SourceOver;
                        g.CompositingQuality = CompositingQuality.GammaCorrected;
                        g.SmoothingMode = SmoothingMode.HighQuality;
                        g.InterpolationMode = InterpolationMode.HighQualityBicubic;

                        g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;

                        g.DrawImage(src, rDstImg, rSrcImg, GraphicsUnit.Pixel);

                        using (var f = new Font("Arial", 10, FontStyle.Regular, GraphicsUnit.Pixel))
                        {
                            using (var brush = new SolidBrush(Color.FromArgb(191, 191, 191)))
                            {
                                var sf = new StringFormat
                                    { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Center };

                                g.DrawString(localization.GetText("IMAGE_RESIZE_ENLARGE"), f, brush, rDstTxt1, sf);

                                sf.Alignment = StringAlignment.Far;
                                g.DrawString(
                                    localization.GetText("IMAGE_RESIZE_VIEWS").FormatWith(downloads),
                                    f,
                                    brush,
                                    rDstTxt2,
                                    sf);
                            }
                        }
                    }

                    // save the bitmap to the stream...
                    dst.Save(ms, ImageFormat.Png);
                    ms.Position = 0;

                    return ms;
                }
            }
        }

        /// <summary>
        /// The get resource.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        private static void GetResource([NotNull] HttpContext context)
        {
            // redirect to the resource?
            context.Response.Redirect("resources/{0}".FormatWith(context.Request.QueryString.GetFirstOrDefault("r")));

            /*string resourceName = "YAF.App_GlobalResources." + context.Request.QueryString["r"];
            int lastIndex = resourceName.LastIndexOf('.');
            string extension = resourceName.Substring(lastIndex, resourceName.Length - lastIndex).ToLower();

            string resourceType = "text/plain";

            switch (extension)
            {
                case ".js":
                    resourceType = "application/x-javascript";
                    break;
                case ".css":
                    resourceType = "text/css";
                    break;
            }

            if (resourceType != string.Empty)
            {
                context.Response.Clear();
                context.Response.ContentType = resourceType;

                try
                {
                    // attempt to load the resource...
                    byte[] data = null;

                    Stream input = GetType().Assembly.GetManifestResourceStream(resourceName);

                    data = new byte[input.Length];
                    input.Read(data, 0, data.Length);
                    input.Close();

                    context.Response.OutputStream.Write(data, 0, data.Length);
                }
                catch
                {
                    YAF.Classes.Data.DB.eventlog_create(
                        null, GetType().ToString(), "Attempting to access invalid resource: " + resourceName, 1);
                    context.Response.Write("Error: Invalid forum resource. Please contact the forum admin.");
                }
            }*/
        }

        /// <summary>
        /// The get response google spell.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        private static void GetResponseGoogleSpell([NotNull] HttpContext context)
        {
            string url =
                "https://www.google.com/tbproxy/spell?lang={0}".FormatWith(
                    context.Request.QueryString.GetFirstOrDefault("lang"));

            var webRequest = (HttpWebRequest)WebRequest.Create(url);
            webRequest.KeepAlive = true;
            webRequest.Timeout = 100000;
            webRequest.Method = "POST";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.ContentLength = context.Request.InputStream.Length;

            Stream requestStream = webRequest.GetRequestStream();

            context.Request.InputStream.CopyTo(requestStream);

            requestStream.Close();

            var httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
            Stream responseStream = httpWebResponse.GetResponseStream();

            responseStream.CopyTo(context.Response.OutputStream);
        }

        /// <summary>
        /// Gets the user info as json string
        /// </summary>
        /// <param name="context">The context.</param>
        private void GetUserInfo([NotNull] HttpContext context)
        {
            try
            {
                var userId = context.Request.QueryString.GetFirstOrDefault("userinfo").ToType<int>();

                MembershipUser user = UserMembershipHelper.GetMembershipUserById(userId);

                if (user == null || user.ProviderUserKey.ToString() == "0")
                {
                    context.Response.Write(
                   "Error: Resource has been moved or is unavailable. Please contact the forum admin.");

                    return;
                }

                var userData = new CombinedUserDataHelper(user, userId);

                context.Response.Clear();

                context.Response.ContentType = "application/json";
                context.Response.ContentEncoding = Encoding.UTF8;
                context.Response.Cache.SetCacheability(HttpCacheability.Public);
                context.Response.Cache.SetExpires(
                    DateTime.UtcNow.AddMilliseconds(YafContext.Current.Get<YafBoardSettings>().OnlineStatusCacheTimeout));
                context.Response.Cache.SetLastModified(DateTime.UtcNow);

                var avatarUrl = this.Get<IAvatars>().GetAvatarUrlForUser(userId);

                avatarUrl = avatarUrl.IsNotSet()
                           ? "{0}images/noavatar.gif".FormatWith(YafForumInfo.ForumClientFileRoot)
                           : avatarUrl;

                var activeUsers = this.Get<IDataCache>().GetOrSet(
                    Constants.Cache.UsersOnlineStatus,
                    () =>
                    this.Get<IDBBroker>().GetActiveList(
                        false, YafContext.Current.Get<YafBoardSettings>().ShowCrawlersInActiveList),
                    TimeSpan.FromMilliseconds(YafContext.Current.Get<YafBoardSettings>().OnlineStatusCacheTimeout));

                var userIsOnline =
                    activeUsers.AsEnumerable().Any(
                        x => x.Field<int>("UserId").Equals(userId) && !x.Field<bool>("IsHidden"));

                var userName = this.Get<YafBoardSettings>().EnableDisplayName ? userData.DisplayName : userData.UserName;

                userName = HttpUtility.HtmlEncode(userName);

                var location = userData.Profile.Country.IsSet()
                                   ? YafContext.Current.Get<IHaveLocalization>().GetText(
                                       "COUNTRY", userData.Profile.Country.Trim())
                                   : userData.Profile.Location;

                if (userData.Profile.Region.IsSet() && userData.Profile.Country.IsSet())
                {
                    var tag = "RGN_{0}_{1}".FormatWith(userData.Profile.Country.Trim(), userData.Profile.Region);

                    location += ", {0}".FormatWith(YafContext.Current.Get<IHaveLocalization>().GetText("REGION", tag));
                }

                var pmButton = new ThemeButton
                                   {
                                       ID = "PM",
                                       CssClass = "yafcssimagebutton",
                                       TextLocalizedPage = "POSTS",
                                       TextLocalizedTag = "PM",
                                       ImageThemeTag = "PM",
                                       TitleLocalizedTag = "PM_TITLE",
                                       TitleLocalizedPage = "POSTS",
                                       NavigateUrl = YafBuildLink.GetLinkNotEscaped(ForumPages.pmessage, "u={0}", userId),
                                       ParamTitle0 = userName,
                                       Visible =
                                           !userData.IsGuest && this.Get<YafBoardSettings>().AllowPrivateMessages
                                           && !userId.Equals(YafContext.Current.PageUserID) && !YafContext.Current.IsGuest
                                   };

                var userInfo = new YafUserInfo
                                   {
                                       name = userName,
                                       realname = HttpUtility.HtmlEncode(userData.Profile.RealName),
                                       avatar = avatarUrl,
                                       profilelink =
                                           YafBuildLink.GetLink(ForumPages.profile, "u={0}", userId).Replace(
                                               "resource.ashx", "default.aspx"),
                                       interests = HttpUtility.HtmlEncode(userData.Profile.Interests),
                                       homepage = userData.Profile.Homepage,
                                       posts = "{0:N0}".FormatWith(userData.NumPosts),
                                       rank = userData.RankName,
                                       location = location,
                                       joined = this.Get<IDateTime>().FormatDateLong(userData.Joined),
                                       online = userIsOnline,
                                       actionButtons = pmButton.RenderToString()
                                   };
<commit_msg>Fixed incorrect PM Message Link in the HoverCards<commit_after>/* YetAnotherForum.NET
 * Copyright (C) 2006-2012 <NAME>
 * http://www.yetanotherforum.net/
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
namespace YAF
{
    #region Using

    using System;
    using System.Data;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;
    using System.Drawing.Text;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Web;
    using System.Web.Security;
    using System.Web.SessionState;

    using YAF.Classes;
    using YAF.Classes.Data;
    using YAF.Controls;
    using YAF.Core;
    using YAF.Core.Services;
    using YAF.Types;
    using YAF.Types.Constants;
    using YAF.Types.Interfaces;
    using YAF.Utils;
    using YAF.Utils.Extensions;
    using YAF.Utils.Helpers;

    #endregion

    /// <summary>
    /// Yaf Resource Handler for all kind of Stuff (Avatars, Attachments, Albums, etc.)
    /// </summary>
    public class YafResourceHandler : IHttpHandler, IReadOnlySessionState, IHaveServiceLocator
    {
        #region Properties

        /// <summary>
        ///   Gets a value indicating whether IsReusable.
        /// </summary>
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// Gets ServiceLocator.
        /// </summary>
        public IServiceLocator ServiceLocator
        {
            get
            {
                return YafContext.Current.ServiceLocator;
            }
        }

        #endregion

        #region Implemented Interfaces

        #region IHttpHandler

        /// <summary>
        /// The process request.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        public void ProcessRequest([NotNull] HttpContext context)
        {
            // resource no longer works with dynamic compile...
            if (context.Request.QueryString.GetFirstOrDefault("r") != null)
            {
                // resource request
                GetResource(context);
            }
            else if (context.Session["lastvisit"] != null
                     ||
                     context.Request.UrlReferrer != null
                     && context.Request.UrlReferrer.AbsoluteUri.Contains(BaseUrlBuilder.BaseUrl))
            {
                // defaults
                var previewCropped = false;
                var localizationFile = "english.xml";

                if (context.Session["imagePreviewCropped"] != null && context.Session["imagePreviewCropped"] is bool)
                {
                    previewCropped = (bool)context.Session["imagePreviewCropped"];
                }

                if (context.Session["localizationFile"] != null && context.Session["localizationFile"] is string)
                {
                    localizationFile = context.Session["localizationFile"].ToString();
                }

                if (context.Session["localizationFile"] != null && context.Session["localizationFile"] is string)
                {
                    localizationFile = context.Session["localizationFile"].ToString();
                }
                /////////////

                if (context.Request.QueryString.GetFirstOrDefault("userinfo") != null)
                {
                    this.GetUserInfo(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("u") != null)
                {
                    this.GetResponseLocalAvatar(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("url") != null
                         && context.Request.QueryString.GetFirstOrDefault("width") != null
                         && context.Request.QueryString.GetFirstOrDefault("height") != null)
                {
                    this.GetResponseRemoteAvatar(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("a") != null)
                {
                    this.GetResponseAttachment(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("i") != null)
                {
                    // TommyB: Start MOD: Preview Images   ##########
                    this.GetResponseImage(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("p") != null)
                {
                    this.GetResponseImagePreview(
                        context, localizationFile, previewCropped);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("c") != null)
                {
                    // TommyB: End MOD: Preview Images   ##########
                    // captcha
                    this.GetResponseCaptcha(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("cover") != null
                         && context.Request.QueryString.GetFirstOrDefault("album") != null)
                {
                    // album cover
                    this.GetAlbumCover(context, localizationFile, previewCropped);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("imgprv") != null)
                {
                    // album image preview
                    this.GetAlbumImagePreview(context, localizationFile, previewCropped);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("image") != null)
                {
                    // album image
                    this.GetAlbumImage(context);
                }
                else if (context.Request.QueryString.GetFirstOrDefault("s") != null
                         && context.Request.QueryString.GetFirstOrDefault("lang") != null)
                {
                    GetResponseGoogleSpell(context);
                }
            }
            else
            {
                // they don't have a session...
                context.Response.Write(
                    "Please do not link directly to this resource. You must have a session in the forum.");
            }
        }

        #endregion

        #endregion

        #region Methods

        /// <summary>
        /// Check if the ETag that sent from the client is match to the current ETag.
        ///   If so, set the status code to 'Not Modified' and stop the response.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <param name="eTagCode">
        /// The e Tag Code.
        /// </param>
        /// <returns>
        /// The check e tag.
        /// </returns>
        private static bool CheckETag([NotNull] HttpContext context, [NotNull] string eTagCode)
        {
            string ifNoneMatch = context.Request.Headers["If-None-Match"];
            if (eTagCode.Equals(ifNoneMatch, StringComparison.Ordinal))
            {
                context.Response.AppendHeader("Content-Length", "0");
                context.Response.StatusCode = (int)HttpStatusCode.NotModified;
                context.Response.StatusDescription = "Not modified";
                context.Response.SuppressContent = true;
                context.Response.Cache.SetCacheability(HttpCacheability.Public);
                context.Response.Cache.SetETag(eTagCode);
                context.Response.Flush();
                return true;
            }

            return false;
        }

        /// <summary>
        /// Get the Album Or Image Attachement Preview
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="previewWidth">The preview width.</param>
        /// <param name="previewHeight">The preview height.</param>
        /// <param name="previewCropped">The preview Cropped</param>
        /// <param name="downloads">The downloads.</param>
        /// <param name="localizationFile">The localization file.</param>
        /// <param name="localizationPage">The localization page.</param>
        /// <returns>
        /// Resized Image Stream
        /// </returns>
        [NotNull]
        private static MemoryStream GetAlbumOrAttachmentImageResized(
            [NotNull] Stream data,
            int previewWidth,
            int previewHeight,
            bool previewCropped,
            int downloads,
            [NotNull] string localizationFile,
            string localizationPage)
        {
            const int PixelPadding = 6;
            const int BottomSize = 26;

            var localization = new YafLocalization(localizationPage);
            localization.LoadTranslation(localizationFile);

            using (var src = new Bitmap(data))
            {
                var ms = new MemoryStream();

                // Cropped Image
                int size = previewWidth;

                var newImgSize = new Size(previewWidth, previewHeight);
                int x = 0;
                int y = 0;

                if (previewCropped)
                {
                    // Determine dimensions of resized version of the image 
                    if (newImgSize.Width > newImgSize.Height)
                    {
                        newImgSize.Width =
                            decimal.Round(
                                (size.ToType<decimal>()
                                 * (newImgSize.Width.ToType<decimal>() / newImgSize.Height.ToType<decimal>())).ToType<decimal>(),
                                0).ToType<int>();
                        newImgSize.Height = size;
                    }
                    else if (newImgSize.Height > newImgSize.Width)
                    {
                        newImgSize.Height =
                            decimal.Round(
                                (size.ToType<decimal>()
                                 * (newImgSize.Height.ToType<decimal>() / newImgSize.Width.ToType<decimal>())).ToType<decimal>(),
                                0).ToType<int>();
                        newImgSize.Width = size;
                    }
                    else
                    {
                        newImgSize.Width = size;
                        newImgSize.Height = size;
                    }

                    newImgSize.Width = newImgSize.Width - PixelPadding;
                    newImgSize.Height = newImgSize.Height - BottomSize - PixelPadding;

                    // moves cursor so that crop is more centered 
                    x = newImgSize.Width / 2;
                    y = newImgSize.Height / 2;
                }
                else
                {
                    var finalHeight = Math.Abs(src.Height * newImgSize.Width / src.Width);

                    // Height resize if necessary
                    if (finalHeight > newImgSize.Height)
                    {
                        newImgSize.Width = src.Width * newImgSize.Height / src.Height;
                        finalHeight = newImgSize.Height;
                    }

                    newImgSize.Height = finalHeight;
                    newImgSize.Width = newImgSize.Width - PixelPadding;
                    newImgSize.Height = newImgSize.Height - BottomSize - PixelPadding;

                    if (newImgSize.Height <= BottomSize + PixelPadding)
                    {
                        newImgSize.Height = finalHeight;
                    }
                }

                bool heightToSmallFix = newImgSize.Height <= BottomSize + PixelPadding;

                using (
                    var dst = new Bitmap(
                        newImgSize.Width + PixelPadding,
                        newImgSize.Height + BottomSize + PixelPadding,
                        PixelFormat.Format24bppRgb))
                {
                    var rSrcImg = new Rectangle(
                        0, 0, src.Width, src.Height + (heightToSmallFix ? BottomSize + PixelPadding : 0));

                    if (previewCropped)
                    {
                        rSrcImg = new Rectangle(x, y, newImgSize.Width, newImgSize.Height);
                    }

                    var rDstImg = new Rectangle(3, 3, dst.Width - PixelPadding, dst.Height - PixelPadding - BottomSize);
                    var rDstTxt1 = new Rectangle(3, rDstImg.Height + 3, newImgSize.Width, BottomSize - 13);
                    var rDstTxt2 = new Rectangle(3, rDstImg.Height + 16, newImgSize.Width, BottomSize - 13);

                    using (Graphics g = Graphics.FromImage(dst))
                    {
                        g.Clear(Color.FromArgb(64, 64, 64));
                        g.FillRectangle(Brushes.White, rDstImg);

                        g.CompositingMode = CompositingMode.SourceOver;
                        g.CompositingQuality = CompositingQuality.GammaCorrected;
                        g.SmoothingMode = SmoothingMode.HighQuality;
                        g.InterpolationMode = InterpolationMode.HighQualityBicubic;

                        g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;

                        g.DrawImage(src, rDstImg, rSrcImg, GraphicsUnit.Pixel);

                        using (var f = new Font("Arial", 10, FontStyle.Regular, GraphicsUnit.Pixel))
                        {
                            using (var brush = new SolidBrush(Color.FromArgb(191, 191, 191)))
                            {
                                var sf = new StringFormat
                                    { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Center };

                                g.DrawString(localization.GetText("IMAGE_RESIZE_ENLARGE"), f, brush, rDstTxt1, sf);

                                sf.Alignment = StringAlignment.Far;
                                g.DrawString(
                                    localization.GetText("IMAGE_RESIZE_VIEWS").FormatWith(downloads),
                                    f,
                                    brush,
                                    rDstTxt2,
                                    sf);
                            }
                        }
                    }

                    // save the bitmap to the stream...
                    dst.Save(ms, ImageFormat.Png);
                    ms.Position = 0;

                    return ms;
                }
            }
        }

        /// <summary>
        /// The get resource.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        private static void GetResource([NotNull] HttpContext context)
        {
            // redirect to the resource?
            context.Response.Redirect("resources/{0}".FormatWith(context.Request.QueryString.GetFirstOrDefault("r")));

            /*string resourceName = "YAF.App_GlobalResources." + context.Request.QueryString["r"];
            int lastIndex = resourceName.LastIndexOf('.');
            string extension = resourceName.Substring(lastIndex, resourceName.Length - lastIndex).ToLower();

            string resourceType = "text/plain";

            switch (extension)
            {
                case ".js":
                    resourceType = "application/x-javascript";
                    break;
                case ".css":
                    resourceType = "text/css";
                    break;
            }

            if (resourceType != string.Empty)
            {
                context.Response.Clear();
                context.Response.ContentType = resourceType;

                try
                {
                    // attempt to load the resource...
                    byte[] data = null;

                    Stream input = GetType().Assembly.GetManifestResourceStream(resourceName);

                    data = new byte[input.Length];
                    input.Read(data, 0, data.Length);
                    input.Close();

                    context.Response.OutputStream.Write(data, 0, data.Length);
                }
                catch
                {
                    YAF.Classes.Data.DB.eventlog_create(
                        null, GetType().ToString(), "Attempting to access invalid resource: " + resourceName, 1);
                    context.Response.Write("Error: Invalid forum resource. Please contact the forum admin.");
                }
            }*/
        }

        /// <summary>
        /// The get response google spell.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        private static void GetResponseGoogleSpell([NotNull] HttpContext context)
        {
            string url =
                "https://www.google.com/tbproxy/spell?lang={0}".FormatWith(
                    context.Request.QueryString.GetFirstOrDefault("lang"));

            var webRequest = (HttpWebRequest)WebRequest.Create(url);
            webRequest.KeepAlive = true;
            webRequest.Timeout = 100000;
            webRequest.Method = "POST";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.ContentLength = context.Request.InputStream.Length;

            Stream requestStream = webRequest.GetRequestStream();

            context.Request.InputStream.CopyTo(requestStream);

            requestStream.Close();

            var httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
            Stream responseStream = httpWebResponse.GetResponseStream();

            responseStream.CopyTo(context.Response.OutputStream);
        }

        /// <summary>
        /// Gets the user info as json string
        /// </summary>
        /// <param name="context">The context.</param>
        private void GetUserInfo([NotNull] HttpContext context)
        {
            try
            {
                var userId = context.Request.QueryString.GetFirstOrDefault("userinfo").ToType<int>();

                MembershipUser user = UserMembershipHelper.GetMembershipUserById(userId);

                if (user == null || user.ProviderUserKey.ToString() == "0")
                {
                    context.Response.Write(
                   "Error: Resource has been moved or is unavailable. Please contact the forum admin.");

                    return;
                }

                var userData = new CombinedUserDataHelper(user, userId);

                context.Response.Clear();

                context.Response.ContentType = "application/json";
                context.Response.ContentEncoding = Encoding.UTF8;
                context.Response.Cache.SetCacheability(HttpCacheability.Public);
                context.Response.Cache.SetExpires(
                    DateTime.UtcNow.AddMilliseconds(YafContext.Current.Get<YafBoardSettings>().OnlineStatusCacheTimeout));
                context.Response.Cache.SetLastModified(DateTime.UtcNow);

                var avatarUrl = this.Get<IAvatars>().GetAvatarUrlForUser(userId);

                avatarUrl = avatarUrl.IsNotSet()
                           ? "{0}images/noavatar.gif".FormatWith(YafForumInfo.ForumClientFileRoot)
                           : avatarUrl;

                var activeUsers = this.Get<IDataCache>().GetOrSet(
                    Constants.Cache.UsersOnlineStatus,
                    () =>
                    this.Get<IDBBroker>().GetActiveList(
                        false, YafContext.Current.Get<YafBoardSettings>().ShowCrawlersInActiveList),
                    TimeSpan.FromMilliseconds(YafContext.Current.Get<YafBoardSettings>().OnlineStatusCacheTimeout));

                var userIsOnline =
                    activeUsers.AsEnumerable().Any(
                        x => x.Field<int>("UserId").Equals(userId) && !x.Field<bool>("IsHidden"));

                var userName = this.Get<YafBoardSettings>().EnableDisplayName ? userData.DisplayName : userData.UserName;

                userName = HttpUtility.HtmlEncode(userName);

                var location = userData.Profile.Country.IsSet()
                                   ? YafContext.Current.Get<IHaveLocalization>().GetText(
                                       "COUNTRY", userData.Profile.Country.Trim())
                                   : userData.Profile.Location;

                if (userData.Profile.Region.IsSet() && userData.Profile.Country.IsSet())
                {
                    var tag = "RGN_{0}_{1}".FormatWith(userData.Profile.Country.Trim(), userData.Profile.Region);

                    location += ", {0}".FormatWith(YafContext.Current.Get<IHaveLocalization>().GetText("REGION", tag));
                }

                var pmButton = new ThemeButton
                                   {
                                       ID = "PM",
                                       CssClass = "yafcssimagebutton",
                                       TextLocalizedPage = "POSTS",
                                       TextLocalizedTag = "PM",
                                       ImageThemeTag = "PM",
                                       TitleLocalizedTag = "PM_TITLE",
                                       TitleLocalizedPage = "POSTS",
                                       NavigateUrl = YafBuildLink.GetLinkNotEscaped(ForumPages.pmessage, "u={0}", userId).Replace(
                                               "resource.ashx", "default.aspx"),
                                       ParamTitle0 = userName,
                                       Visible =
                                           !userData.IsGuest && this.Get<YafBoardSettings>().AllowPrivateMessages
                                           && !userId.Equals(YafContext.Current.PageUserID) && !YafContext.Current.IsGuest
                                   };

                var userInfo = new YafUserInfo
                                   {
                                       name = userName,
                                       realname = HttpUtility.HtmlEncode(userData.Profile.RealName),
                                       avatar = avatarUrl,
                                       profilelink =
                                           YafBuildLink.GetLink(ForumPages.profile, "u={0}", userId).Replace(
                                               "resource.ashx", "default.aspx"),
                                       interests = HttpUtility.HtmlEncode(userData.Profile.Interests),
                                       homepage = userData.Profile.Homepage,
                                       posts = "{0:N0}".FormatWith(userData.NumPosts),
                                       rank = userData.RankName,
                                       location = location,
                                       joined = this.Get<IDateTime>().FormatDateLong(userData.Joined),
                                       online = userIsOnline,
                                       actionButtons = pmButton.RenderToString()
                                   };

{'fraction_non_alphanumeric': 0.09445724066521564, 'fraction_numerical': 0.0039726982651142155, 'mean_word_length': 1.2866254348666408, 'pattern_counts': {'":': 4, '<': 153, '<?xml version=': 0, '>': 159, 'https://': 2, 'lorem ipsum': 0, 'www.': 6, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 110, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6342777', 'n_tokens_mistral': 11602, 'n_tokens_neox': 10638, 'n_words': 2245}