<commit_before>﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web;
using System.Web.Mvc;
using AzureStorageUtils;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage.Queue;
using Recaptcha.Web;
using Recaptcha.Web.Mvc;
using WebRole.Models;
using WebRole.Properties;

namespace WebRole.Controllers
{
    public class HomeController : BootstrapBaseController
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            return View();
        }

        //
        // GET: /Home/UploadImage/

        [HttpGet]
        [ActionName("UploadImage")]
        public ActionResult UploadImage_Get(UploadImageViewModel model)
        {
            NormalizeUploadImageViewModel(model);
            return View(model);
        }

        //
        // POST: /Home/UploadImage/

        [HttpPost]
        [ValidateAntiForgeryToken]
        [ActionName("UploadImage")]
        public ActionResult UploadImage_Post(UploadImageViewModel model)
        {
            NormalizeUploadImageViewModel(model);
            
            var image = ValidateAndExtractImage(model.ImageFile);
            ValidateCaptcha();

            if (!ModelState.IsValid)
            {
                return View(model);
            }

            try
            {
                var blob = UploadImageToStorage(image);
                image.Dispose();

                CreateNewOCRTask(blob.Name, model.EmailAddress);
                return View("UploadImageSuccessful");
            }
            catch (Exception e)
            {
                Error("An error occurred: " + e.Message);
                return View(model);
            }
        }

        private void NormalizeUploadImageViewModel(UploadImageViewModel model)
        {
            if (model != null && model.CaptchaPublicKey == null)
            {
                model.CaptchaPublicKey = Settings.Default.RecaptchaPublicKey;
            }
        }

        private Image ValidateAndExtractImage(HttpPostedFileBase imageFile)
        {
            Image result = null;
            try
            {
                result = Image.FromStream(imageFile.InputStream);
            }
            catch (Exception)
            {
                ModelState.AddModelError("invalid-image", "Invalid image or unsupported image format.");
            }
            return result;
        }

        private void ValidateCaptcha()
        {
            RecaptchaVerificationHelper recaptchaHelper = this.GetRecaptchaVerificationHelper(Settings.Default.RecaptchaPrivateKey);
            if (String.IsNullOrEmpty(recaptchaHelper.Response))
            {
                ModelState.AddModelError("captcha-answer-empty", "Verification code cannot be empty.");
                return;
            }

            RecaptchaVerificationResult recaptchaResult = recaptchaHelper.VerifyRecaptchaResponse();
            if (recaptchaResult != RecaptchaVerificationResult.Success)
            {
                ModelState.AddModelError("captcha-answer-incorrect", "Incorrect verification code.");
            }
        }

        private CloudBlockBlob UploadImageToStorage(Image image)
        {
            using (MemoryStream imageStream = new MemoryStream())
            {
                image.Save(imageStream, ImageFormat.Tiff);
                var blob = AzureBlobs.ImageBlobContainer.GetBlockBlobReference(Guid.NewGuid().ToString());
                blob.UploadFromStream(imageStream);<commit_msg>Fixed a bug with zero-length blob uploads.<commit_after>﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web;
using System.Web.Mvc;
using AzureStorageUtils;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage.Queue;
using Recaptcha.Web;
using Recaptcha.Web.Mvc;
using WebRole.Models;
using WebRole.Properties;

namespace WebRole.Controllers
{
    public class HomeController : BootstrapBaseController
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            return View();
        }

        //
        // GET: /Home/UploadImage/

        [HttpGet]
        [ActionName("UploadImage")]
        public ActionResult UploadImage_Get(UploadImageViewModel model)
        {
            NormalizeUploadImageViewModel(model);
            return View(model);
        }

        //
        // POST: /Home/UploadImage/

        [HttpPost]
        [ValidateAntiForgeryToken]
        [ActionName("UploadImage")]
        public ActionResult UploadImage_Post(UploadImageViewModel model)
        {
            NormalizeUploadImageViewModel(model);
            
            var image = ValidateAndExtractImage(model.ImageFile);
            ValidateCaptcha();

            if (!ModelState.IsValid)
            {
                return View(model);
            }

            try
            {
                var blob = UploadImageToStorage(image);
                image.Dispose();

                CreateNewOCRTask(blob.Name, model.EmailAddress);
                return View("UploadImageSuccessful");
            }
            catch (Exception e)
            {
                Error("An error occurred: " + e.Message);
                return View(model);
            }
        }

        private void NormalizeUploadImageViewModel(UploadImageViewModel model)
        {
            if (model != null && model.CaptchaPublicKey == null)
            {
                model.CaptchaPublicKey = Settings.Default.RecaptchaPublicKey;
            }
        }

        private Image ValidateAndExtractImage(HttpPostedFileBase imageFile)
        {
            Image result = null;
            try
            {
                result = Image.FromStream(imageFile.InputStream);
            }
            catch (Exception)
            {
                ModelState.AddModelError("invalid-image", "Invalid image or unsupported image format.");
            }
            return result;
        }

        private void ValidateCaptcha()
        {
            RecaptchaVerificationHelper recaptchaHelper = this.GetRecaptchaVerificationHelper(Settings.Default.RecaptchaPrivateKey);
            if (String.IsNullOrEmpty(recaptchaHelper.Response))
            {
                ModelState.AddModelError("captcha-answer-empty", "Verification code cannot be empty.");
                return;
            }

            RecaptchaVerificationResult recaptchaResult = recaptchaHelper.VerifyRecaptchaResponse();
            if (recaptchaResult != RecaptchaVerificationResult.Success)
            {
                ModelState.AddModelError("captcha-answer-incorrect", "Incorrect verification code.");
            }
        }

        private CloudBlockBlob UploadImageToStorage(Image image)
        {
            using (MemoryStream imageStream = new MemoryStream())
            {
                image.Save(imageStream, ImageFormat.Tiff);
                imageStream.Seek(0, SeekOrigin.Begin);

                string blobName = Guid.NewGuid() + ".tif";
                var blob = AzureBlobs.ImageBlobContainer.GetBlockBlobReference(blobName);
                blob.UploadFromStream(imageStream);
{'fraction_non_alphanumeric': 0.08309058121792204, 'fraction_numerical': 0.00013871549452073797, 'mean_word_length': 1.807632398753894, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2138463', 'n_tokens_mistral': 1808, 'n_tokens_neox': 1736, 'n_words': 329}