예제 #1
0
        /// <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));
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }