/// <summary> /// Evaluates quiz and survey; stores results; returns ID so client can navigate to results page. /// </summary> /// <param name="quiz">The user's quiz choices, JSON serialized in quiz.js.</param> /// <param name="survey">The user's survey input (whatever was provided), JSON serialized in quiz.js.</param> /// <returns></returns> public IActionResult EvalQuiz([FromForm] string quiz, [FromForm] string survey, [FromForm] string quizCount, [FromForm] string surveyCount) { // Parse data from query var oQuiz = JsonConvert.DeserializeObject <IList <string[]> >(quiz); var oSurvey = JsonConvert.DeserializeObject <SurveyData>(survey); // Have sampler evaluate result int score; char[] resCoded; sampler.Eval(oQuiz, out score, out resCoded); // Get country from remote IP. Trickier b/c of NGINX reverse proxy. string country; string xfwd = HttpContext.Request.Headers["X-Real-IP"]; if (xfwd != null) { country = countryResolver.GetContryCode(IPAddress.Parse(xfwd)); } else { country = countryResolver.GetContryCode(HttpContext.Connection.RemoteIpAddress); } // Store result int nQuizCount = int.Parse(quizCount); int nSurveyCount = int.Parse(surveyCount); StoredResult sr = new StoredResult(country, DateTime.Now, nQuizCount, nSurveyCount, score, new string(resCoded), oSurvey); string uid = resultRepo.StoreResult(sr); // Response is result code, pure and simple. return(new ObjectResult(uid)); }
/// <summary> /// Returns stroke order animation, it it exists for requested character. /// </summary> public IActionResult CharStrokes([FromQuery] string hanzi) { IActionResult res; if (hanzi != null) { hanzi = WebUtility.UrlDecode(hanzi); } if (hanzi == null || hanzi.Length != 1) { // TO-DO: log warning return(StatusCode(400, "A single Hanzi expected.")); } HanziStrokes strokes = langRepo.GetStrokes(hanzi[0]); if (strokes == null) { res = new ObjectResult(null); } else { CharStrokes cstrokes = new CharStrokes(); cstrokes.Strokes = new string[strokes.Strokes.Count]; cstrokes.Medians = new short[strokes.Strokes.Count][][]; for (int i = 0; i != strokes.Strokes.Count; ++i) { var stroke = strokes.Strokes[i]; cstrokes.Strokes[i] = stroke.SVG; cstrokes.Medians[i] = new short[stroke.Median.Count][]; for (int j = 0; j != stroke.Median.Count; ++j) { cstrokes.Medians[i][j] = new short[2]; cstrokes.Medians[i][j][0] = stroke.Median[j].Item1; cstrokes.Medians[i][j][1] = stroke.Median[j].Item2; } } res = new ObjectResult(cstrokes); } // Log this request (after resolving country code). string country; string xfwd = HttpContext.Request.Headers["X-Real-IP"]; if (xfwd != null) { country = cres.GetContryCode(IPAddress.Parse(xfwd)); } else { country = cres.GetContryCode(HttpContext.Connection.RemoteIpAddress); } qlog.LogHanzi(country, hanzi[0], strokes != null); // Return result return(res); }
public void GetRenderedConcordance(ref string query, int ofs, out string html, string lang, bool isMobile, HttpContext ctxt) { StringBuilder sb = new StringBuilder(); html = ""; int limit = pageSize; query = query.Trim(); string queryToLog = query; if (query.Length == 0) { return; } bool isZhoSearch = hasHanzi(query); if (!isZhoSearch) { query = pruneSurf(query, true, null); } // Lookup timer Stopwatch swatch = new Stopwatch(); swatch.Restart(); // Lookup SphinxResult sres = sphinx.Query(query, isZhoSearch, ofs, limit); // If first page, show result count on top if (ofs == 0 && sres.TotalCount > 0) { sb.Append("<p class='corpresultcount'><span>"); sb.Append(HtmlEncoder.Default.Encode(getResultCountStr(lang, sres.TotalCount))); sb.AppendLine("</span></p>"); } using (BinReader br = new BinReader(sphinx.CorpusBinFileName)) { List <float> trgHilites = new List <float>(); List <float> srcHilites = new List <float>(); HashSet <int> usedPoss = new HashSet <int>(); int resultCount = 0; // Render surface search results foreach (int pos in sres.SurfSegPositions) { ++resultCount; usedPoss.Add(pos); br.Position = pos; CorpusSegment cseg = new CorpusSegment(br); if (isZhoSearch) { buildHilitesZhoToHu(query, cseg, trgHilites, srcHilites); } else { buildHilitesHuToZho(query, null, cseg, trgHilites, srcHilites); } sb.Append("<div class='corprow'><div class='corpseg zho'>"); sb.Append(renderSegment(cseg.ZhSurf, srcHilites, isZhoSearch)); sb.Append("</div><div class='corpseg trg'>"); sb.Append(renderSegment(cseg.TrgSurf, trgHilites, isZhoSearch)); sb.AppendLine("</div></div>"); } // Render stem search results to fill up to limit for (int i = 0; i < sres.StemmedSegs.Count && resultCount < limit; ++i) { int pos = sres.StemmedSegs[i].Key; if (usedPoss.Contains(pos)) { continue; } ++resultCount; br.Position = pos; CorpusSegment cseg = new CorpusSegment(br); buildHilitesHuToZho(sres.StemmedQuery, sres.StemmedSegs[i].Value, cseg, trgHilites, srcHilites); sb.Append("<div class='corprow'><div class='corpseg zho'>"); sb.Append(renderSegment(cseg.ZhSurf, srcHilites, isZhoSearch)); sb.Append("</div><div class='corpseg trg'>"); sb.Append(renderSegment(cseg.TrgSurf, trgHilites, isZhoSearch)); sb.AppendLine("</div></div>"); } } // "Load more" button if (sres.TotalCount > ofs + limit) { string strMore = TextProvider.Instance.GetString(lang, "search.corpusLoadMore"); sb.Append("<div class='corpmore'>"); sb.Append("<div class='corpmorebtn' data-offset='" + (ofs + limit).ToString() + "' "); sb.Append("data-query='" + HtmlEncoder.Default.Encode(query) + "'>"); sb.Append(HtmlEncoder.Default.Encode(strMore)); sb.Append("<i class='fa fa-circle-o-notch fa-fw'></i>"); sb.AppendLine("</div></div>"); } // The response! html = sb.ToString(); // Query log int msecFull = (int)swatch.ElapsedMilliseconds; int msecPerlOuter = (int)(1000.0F * sres.PerlOuterElapsed); string country; string xfwd = ctxt.Request.Headers["X-Real-IP"]; if (xfwd != null) { country = cres.GetContryCode(IPAddress.Parse(xfwd)); } else { country = cres.GetContryCode(ctxt.Connection.RemoteIpAddress); } qlog.LogCorpus(country, isMobile, lang, sres.TotalCount, msecPerlOuter, msecFull, isZhoSearch, ofs > 0, query); }
private PageResult doSearchInner(string rel, string lang, string searchScript, string searchTones, bool isMobile, out string query) { query = ""; if (rel == "" || rel == "search" || rel == "search/") { return(doWelcome(lang)); } Stopwatch swatch = new Stopwatch(); swatch.Restart(); PageResult pr; // Search settings UiScript uiScript = UiScript.Both; if (searchScript == "simp") { uiScript = UiScript.Simp; } else if (searchScript == "trad") { uiScript = UiScript.Trad; } UiTones uiTones = UiTones.Pleco; if (searchTones == "dummitt") { uiTones = UiTones.Dummitt; } else if (searchTones == "none") { uiTones = UiTones.None; } // Perform query query = rel.Replace("search/", ""); query = query.Trim(); query = WebUtility.UrlDecode(query); query = query.Trim(); CedictLookupResult lr = dict.Lookup(query); int msecLookup = (int)swatch.ElapsedMilliseconds; int msecFull = msecLookup; // No results if (lr.Results.Count == 0 && lr.Annotations.Count == 0) { pr = pageProvider.GetPage(lang, "?/noresults", false); pr.Data = query; // Can add word now? if (canAddWord(query)) { pr.Html = pr.Html.Replace("{addnowclass}", "visible"); } else { pr.Html = pr.Html.Replace("{addnowclass}", ""); } } else { // Render results StringBuilder sb = new StringBuilder(); ResultsRenderer rr = new ResultsRenderer(lang, lr, uiScript, uiTones); rr.Render(sb, lang); // Title string title; if (lr.ActualSearchLang == SearchLang.Chinese) { title = TextProvider.Instance.Mut == Mutation.CHD ? TextProvider.Instance.GetString(lang, "misc.searchResultTitleCHD") : TextProvider.Instance.GetString(lang, "misc.searchResultTitleHDD"); } else { title = TextProvider.Instance.Mut == Mutation.CHD ? TextProvider.Instance.GetString(lang, "misc.searchResultTitleTrgCHD") : TextProvider.Instance.GetString(lang, "misc.searchResultTitleTrgHDD"); } title = string.Format(title, query); msecFull = (int)swatch.ElapsedMilliseconds; // Wrap up pr = new PageResult { RelNorm = rel, Title = title, Html = sb.ToString(), Data = query, }; } // Query log string country; string xfwd = HttpContext.Request.Headers["X-Real-IP"]; if (xfwd != null) { country = cres.GetContryCode(IPAddress.Parse(xfwd)); } else { country = cres.GetContryCode(HttpContext.Connection.RemoteIpAddress); } int resCount = lr.Results.Count > 0 ? lr.Results.Count : lr.Annotations.Count; QueryLogger.SearchMode smode = QueryLogger.SearchMode.Target; if (lr.ActualSearchLang == SearchLang.Target) { smode = QueryLogger.SearchMode.Target; } else if (lr.Results.Count > 0) { smode = QueryLogger.SearchMode.Source; } else if (lr.Annotations.Count > 0) { smode = QueryLogger.SearchMode.Annotate; } qlog.LogQuery(country, isMobile, lang, uiScript, uiTones, resCount, msecLookup, msecFull, smode, query); // Done return(pr); }