using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using System.Web.UI; using AutoMapper; using DR.FV2016.Service.Interfaces; using DR.FV2016.Service.Models; using DR.FV2016.Web.Helpers; using DR.FV2016.Web.Models; using DR.FV2016.Web.Models.Match; using DR.WCMS.Web.UIBindings.Extensions; using Question = DR.FV2016.Web.Models.Match.Question; namespace DR.FV2016.Web.Controllers { public class MatchController : Controller { private const string ApiKey = "135526786459028"; private const string ShareUrl = "https://www.facebook.com/dialog/feed?app_id={0}&link={1}&picture={2}&name={3}&description={4}&redirect_uri={5}"; private readonly IMatchService _matchService; private readonly ICompositeCandidateService _candidateService; private readonly IArticleService _articleService; private readonly IAgreementService _agreementService; public MatchController(IMatchService matchService, ICompositeCandidateService candidateService, IArticleService articleService, IAgreementService agreementService) { if(matchService == null) throw new ArgumentNullException("matchService", "matchService cannot be NULL!"); if(candidateService == null) throw new ArgumentNullException("candidateService", "candidateService cannot be NULL!"); if (articleService == null) throw new ArgumentNullException("articleService", "An instance of IArticleSerice is required!"); if (agreementService == null) throw new ArgumentNullException("agreementService", "agreementService may not be null"); _matchService = matchService; _candidateService = candidateService; _articleService = articleService; _agreementService = agreementService; } [OutputCache(Location = OutputCacheLocation.Downstream, Duration = 600)] public ActionResult Index() { //var baseViewModelProvider = new BaseViewModelProvider(); var viewModel = Mapper.Map(_articleService.GetWebCmsArticle("/kandidat-testen")); var questions = _matchService.GetQuestions(); viewModel.Questions = Mapper.Map>(questions); viewModel.IsResponsive = true; SearchableHelper.EnsureUrn(viewModel, "urn:dr:valg2015:kandidat-testen"); viewModel.CanonicalLink = string.Format("http://www.dr.dk{0}/{1}", HttpRuntime.AppDomainAppVirtualPath, ((Route)(RouteTable.Routes["Match"])).Url); return View(viewModel); } public ActionResult getQuestionsJson() { var questions = _matchService.GetQuestions(); if (questions != null) { return new JsonNetResult(questions, JsonRequestBehavior.AllowGet); } return null; } [OutputCache(Location = OutputCacheLocation.Downstream, Duration = 600)] public ActionResult Result() { //TODO : viewModel should be removed or returned to View var viewModel = Mapper.Map(_articleService.GetWebCmsArticle("/kandidat-testen")); //TODO: Do we get canonical from mimer? viewModel.CanonicalLink = string.Format("http://www.dr.dk{0}/{1}", HttpRuntime.AppDomainAppVirtualPath, ((Route)(RouteTable.Routes["Match"])).Url); viewModel.IsResponsive = true; return View(viewModel); } public ActionResult ResultJson(string constituencySlug, string answerString, int? candidateId = null, bool isCandidateList = false) { int numberOfQuestions = Int32.Parse(ConfigurationManager.AppSettings["CandidateTestQuestionCount"]); if (string.IsNullOrEmpty(constituencySlug)) throw new HttpException(400, "ConsitutencySlug may not be null or empty or whitespace"); if (string.IsNullOrWhiteSpace(answerString)) { throw new HttpException(400, "User answer string invalid, it may not be null, empty or whitespace."); } if (string.IsNullOrWhiteSpace(answerString) || !answerString.Length.Equals(numberOfQuestions)) { throw new HttpException(400, string.Format("User answer string invalid. Actual value (length): {0} ({1}), expected length: {2}", answerString, answerString.Length, numberOfQuestions)); } try { var candidates = _candidateService.GetCandidatesByConstituency(constituencySlug).Where(c => !string.IsNullOrWhiteSpace(c.AnswerString)).ToList(); candidates.ForEach(c => c.MatchResult = _agreementService.Agreement(answerString, c.AnswerString)); BasicCandidate candidate = null; if (candidateId.HasValue) { var candidateListItem = _candidateService.GetCandidate(candidateId.Value); if (candidateListItem != null) { candidate = candidateListItem; candidate.MatchResult = _agreementService.Agreement(answerString, candidate.AnswerString); } } if (isCandidateList) { var obj = candidates.Select(CreateTiny); return new JsonNetResult(obj, JsonRequestBehavior.AllowGet); } var model = new { Top = candidates.OrderByDescending(a => a.MatchResult).ThenBy(a => a.Name).Take(5), Bottom = candidates.OrderBy(a => a.MatchResult).ThenBy(a => a.Name).Take(5), Candidate = candidate }; return new JsonNetResult(model, JsonRequestBehavior.AllowGet); } catch (KeyNotFoundException) { return new HttpNotFoundResult(); } } public ActionResult Agreement(string answerA, string answerB) { if (answerA == null || answerB == null) return new HttpStatusCodeResult(400); var result = _agreementService.Agreement(answerA, answerB); return new JsonNetResult(new { agreement = result }, JsonRequestBehavior.AllowGet); } private object CreateTiny(BasicCandidate scoredCandidate) { if (scoredCandidate == null) return null; return new { Id = scoredCandidate.Id, //CandidatePageUrl = scoredCandidate.CandidatePageUrl, Pct = scoredCandidate.MatchResult }; } public ActionResult ShareMatchResult(int candidateId, int result) { var candidate = _candidateService.GetCandidate(candidateId); if (candidate == null) { throw new ArgumentException(string.Format("Kandidat med ID {0} ej fundet.", candidateId), "candidateId"); } var shareUrl = string.Format("http://www.dr.dk{0}", Url.ActionRemapped("Index", "Match", null)); var imageUrl = string.Format("http://asset.dr.dk/imagescaler/?file={0}&w=500&h=500&scaleAfter=crop&server=www.altinget.dk", candidate.ImageUrl); var title = string.Format("Jeg er {0}% enig med {1} fra {2}. Hvem er du enig med?", result, candidate.Name, candidate.Party.Name); const string description = "Der er folketingsvalg d. 18. juni og du kan få hjælp til at finde den rette kandidat på dr.dk/valg2015. Prøv selv testen her og find din kandidat."; var returnUrl = string.Format("http://www.dr.dk{0}", Url.ActionRemapped("Result", "Match")); var fbShareUrl = string.Format(ShareUrl, ApiKey, HttpUtility.UrlEncode(shareUrl), HttpUtility.UrlEncode(imageUrl), HttpUtility.UrlEncode(title), HttpUtility.UrlEncode(description), HttpUtility.UrlEncode(returnUrl)); return Redirect(fbShareUrl); } } }