private NanoHttpResponse HandleSafe(NanoHttpRequest request) { _places = HtmlStringExtensions.UpdatePlaces().ToArray(); _allowed = HtmlStringExtensions.UpdateAllowed(); var sw = new System.Diagnostics.Stopwatch(); sw.Start(); Hash thread = null; if (request.Address != "/") { thread = new Hash(request.Address.Split('/').Last()); if (thread.Invalid) { return(new ErrorHandler(StatusCode.BadRequest, "Wrong hash format.").Handle(request)); } } else { thread = new Hash(NanoDB.CategoriesHashValue); } var sb = new StringBuilder(); AddHeader(sb); string s1 = ""; if (thread.Value != NanoDB.CategoriesHashValue) { s1 = "<a href='#' onclick='history.go(-1)'>[Назад]</a>"; s1 += "<a href='#' onclick='location.reload()'>[Обновить]</a>"; if (!_expand) { s1 += "<a href='#' onclick='window.location.href=window.location.toString().replace(\"thread\",\"expand\")'>[Развернуть]</a>"; } else { s1 += "<a href='#' onclick='window.location.href=window.location.toString().replace(\"expand\",\"thread\")'>[Свернуть]</a>"; } } else { s1 = "<a href='#' onclick='location.reload()'>[Обновить]</a>"; } sb.Append(s1.ToDiv("", "")); NanoPost[] posts = null; /* * if (!_expand) * posts = _db.GetThreadPosts(thread).ExceptHidden(_db); * else * posts = _db.GetExpandedThreadPosts(thread).ExceptHidden(_db); */ if (!_expand) { posts = _db.GetThreadPosts(thread); } else { posts = _db.GetExpandedThreadPosts(thread); } bool first = true; if (!_expand) { posts = posts.OrderByDescending(p => p.NumberTag).ToArray(); } string postScript = ""; foreach (var sp in posts) { var p = sp; //string pMessage = p.Message; string pMessage = p.Message.Strip(true); var fmPattern = "\\[fm=.*\\]"; var music = Regex.Matches(pMessage, fmPattern); int musicNum = 0; foreach (var m in music) { musicNum += 1; var value = (m as Match).Value; var formula = value.Substring(4).TrimEnd(']').Replace(">", ">").Replace("<", "<").Replace("<grn>", "").Replace("</grn>", "").Replace(" ", " "). Replace("’", "'").Replace("“", "\"").Replace(";", ""); var strictFmPattern = "()t *0123456789abcdefxABCDEF|><!%:^&.-+/?=~"; bool invalid = formula.Length > 8192; if (!invalid) { foreach (var ch in formula) { if (!strictFmPattern.Contains(ch)) { invalid = true; break; } } } if (invalid) { continue; } var replacement = string.Format(@"<b>Фрактальная музыка:</b> <small><pre>{1}</pre></small><button id='mb{0}'>Сгенерировать</button> <audio style='visibility:hidden;' controls='false' id='au{0}'></audio>", sp.GetHash().Value + musicNum, formula); postScript += "document.getElementById('mb" + sp.GetHash().Value + musicNum + "').onclick = function() { addFractalMusic(function(t){return " + formula + ";}, 210*8000, 'au" + sp.GetHash().Value + musicNum + "');" + "this.parentNode.removeChild(this);" + "}\n"; pMessage = pMessage.Replace(value, replacement); } string numTag = (p.NumberTag == int.MaxValue ? "" : "<grn><sup>#" + p.GetHash().Value.ShortenHash() + "</sup></grn> "); bool hidden = false; if (_db.IsHidden(p.GetHash())) { hidden = true; } string handler = "/expand/"; bool corePost = false; if (p.GetHash().Value == NanoDB.RootHashValue || // root p.ReplyTo.Value == NanoDB.RootHashValue || // root p.GetHash().Value == NanoDB.CategoriesHashValue || // categories p.ReplyTo.Value == NanoDB.CategoriesHashValue) // categories { handler = "/thread/"; corePost = true; } if (_db.Get(p.ReplyTo) != null && (_db.Get(p.ReplyTo).ReplyTo.Value == NanoDB.CategoriesHashValue || _db.Get(p.ReplyTo).ReplyTo.Value == NanoDB.RootHashValue)) { corePost = true; } Func <NanoPost, string> addRefs = pst => { var children = _db.GetThreadPosts(pst.GetHash(), eraseDepth: false); var refs1 = "<br/><div><small>"; int line = 0; foreach (var ch in children) { if (ch.GetHash().Value != pst.GetHash().Value) { line += 1; refs1 += "<a href='#" + ch.GetHash().Value + "'><i>>>" + ch.GetHash().Value.ShortenHash() + "</i></a>"; if (line > 5) { line = 0; refs1 += "</br>"; } } } refs1 += "</small></div>"; return(refs1); }; if (_expand && first && !p.GetHash().Zero&& !p.ReplyTo.Zero) { string refs = ""; if (p.ReplyTo.Value != NanoDB.CategoriesHashValue && p.ReplyTo.Value != NanoDB.RootHashValue && _expand) { refs = addRefs(p); } sb.Append( ( (numTag + pMessage + refs).Replace("\n", "<br/>").ToDiv("postinner", p.GetHash().Value) + ("[Вверх]".ToRef((corePost ? "/thread/" : "/expand/") + p.ReplyTo.Value) + //("[В закладки]").ToRef("/bookmark/" + p.GetHash().Value) + ("<a onclick='show_reply(\"" + p.GetHash().Value + "\")'>[Быстрый ответ]</a>") + ("[Ответить]").ToRef("/reply/" + p.GetHash().Value)).ToDiv("", "") ).ToDiv("post", "")); first = false; continue; } first = false; int answers = _db.CountAnswers(p.GetHash()); string ans = "ответ"; int a = answers % 100; if (a == 0 || a % 10 == 0 || (a > 10 && a < 20)) { ans += "ов"; } else if (a % 10 >= 2 && a % 10 <= 4) { ans += "а"; } else if (a % 10 >= 5 && a % 10 <= 9) { ans += "ов"; } if (p.GetHash().Value == _db.RootHash.Value) { sb.Append( ( (@" Добро пожаловать на Наноборду! Это корневой нанопост. В целях тестирования на него можно было отвечать в предыдущих версиях. Это немного засорило Главную. Рекомендуется почистить её у себя вручную. Негласное правило: отвечать нужно на конкретное сообщение, а не просто ""в тред"", полагаясь на то, что сообщение выше вашего будет таким же и у других - порядок попадания нанопостов к другим участникам сложно предсказать. Создавать тред желательно в соответствующей категории." ).Strip().Replace("\n", "<br/>").ToDiv("postinner", p.GetHash().Value) + //(("[Ответить]").ToRef("/reply/" + p.GetHash().Value)).ToDiv("", "") + ("[Развернуть всё (осторожно!)]").ToRef("/expand/f682830a470200d738d32c69e6c2b8a4").ToDiv("", "") + ("[Категории]").ToRef("/thread/bdd4b5fc1b3a933367bc6830fef72a35").ToDiv("", "") ).ToDiv("post main", "")); } else { string refs = ""; if (p.ReplyTo.Value != NanoDB.CategoriesHashValue && p.ReplyTo.Value != NanoDB.RootHashValue && _expand) { refs = addRefs(p); } sb.Append( ( ((_expand?("<a href='#" + p.ReplyTo.Value + "'><i>>>" + p.ReplyTo.Value.ShortenHash() + "</i></a><br/>"):"") + numTag + pMessage + refs).Replace("\n", "<br/>").ToStyledDiv("postinner", p.GetHash().Value, hidden?"visibility:hidden;height:0px;":"") + ((answers > MinAnswers ? ("[" + answers + " " + ans + "]").ToRef(handler + p.GetHash().Value) : "") + (p.GetHash().Value != "bdd4b5fc1b3a933367bc6830fef72a35" ? ( (hidden?"[Вернуть]":"[Удалить]").ToButton("", "", @"var x = new XMLHttpRequest(); x.open('POST', '../hide/" + p.GetHash().Value + @"', true); x.send(''); var elem = document.getElementById('" + p.GetHash().Value + @"'); if (elem.style.visibility != 'hidden') { elem.style.visibility='hidden'; elem.style.height = '0px'; innerHTML = '[Вернуть]'; } else { elem.style.visibility='visible'; elem.style.height = '100%'; innerHTML = '[Удалить]'; } ")) : "") + //("[В закладки]").ToRef("/bookmark/" + p.GetHash().Value) + ("[Дамп]".ToPostRef("/dump/" + p.GetHash().Value)) + ("<a onclick='show_reply(\"" + p.GetHash().Value + "\")'>[Быстрый ответ]</a>") + ("[Ответить]").ToRef("/reply/" + p.GetHash().Value)).ToDiv("", "") ).ToStyledDiv("post", "", "position:relative;left:" + p.DepthTag * 20 + "px;")); } } sb.Append(s1.ToDiv("", "")); sw.Stop(); sb.Append("<div><br>места:"); var places = _places.Where(l => !l.StartsWith("#")).ToList(); places.ForEach(p => sb.Append(string.Format("<br><a target='_blank' href='{0}'>{0}</a>" + "<a target='_blank' href='/del/{0}'>[-]</a>", p))); sb.Append("</div>"); AddFooter(sb, sw.ElapsedMilliseconds, _db); var result = sb.ToString(); /* * if (!_expand) * sb.Append("Развернуть".ToButton("", "", "window.location.href=window.location.toString().replace('thread','expand')").ToDiv("","")); * else * sb.Append("Обновить".ToButton("", "", "location.reload()").ToDiv("","")); */ return(new NanoHttpResponse(StatusCode.Ok, result.AddVideo().AddReply().ToHtmlBody(JQueryMinJs + JQueryUiMinJs + Base64Js + FractalMusicScript + BitSendJs + PostScript(postScript)))); }
private NanoHttpResponse HandleSafe(NanoHttpRequest request) { var sw = new System.Diagnostics.Stopwatch(); sw.Start(); var sb = new StringBuilder(); ThreadViewHandler.AddHeader(sb); sb.Append(string.Format("<div>Количество правил игнорирования постов: {0}. Настройте spamfilter.txt под себя.</div>", SpamDetector.RuleCount)); sb.Append("[Очистить список]".ToButton("", "", @" var x = new XMLHttpRequest(); x.open('POST', '../save/', true); x.send(''); location.reload(); ").ToDiv("", "")); var posts = _db.GetNewPosts();//.ExceptHidden(_db); posts = posts.Reverse().ToArray(); foreach (var p in posts) { int answers = _db.CountAnswers(p.GetHash()); string ans = "ответ"; if (answers != 11 && answers % 10 == 1) { // } else if (answers != 11 && answers % 10 == 5) { ans += "ов"; } else { ans += "а"; } bool corePost = false; if (_db.Get(p.ReplyTo) != null && (_db.Get(p.ReplyTo).ReplyTo.Value == NanoDB.CategoriesHashValue || _db.Get(p.ReplyTo).ReplyTo.Value == NanoDB.RootHashValue)) { corePost = true; } bool hidden = _db.IsHidden(p.GetHash()); sb.Append( ( p.Message.Strip(true).Replace("\n", "<br/>").ToStyledDiv("postinner", p.GetHash().Value, hidden?"visibility:hidden;height:0px;":"") + ((answers > ThreadViewHandler.MinAnswers ? ("[" + answers + " " + ans + "]").ToRef("/expand/" + p.GetHash().Value):"") + (hidden?"[Вернуть]":"[Удалить]").ToButton("", "", @"var x = new XMLHttpRequest(); x.open('POST', '../hide/" + p.GetHash().Value + @"', true); x.send(''); var elem = document.getElementById('" + p.GetHash().Value + @"'); if (elem.style.visibility != 'hidden') { elem.style.visibility='hidden'; elem.style.height = '0px'; innerHTML = '[Вернуть]'; } else { elem.style.visibility='visible'; elem.style.height = '100%'; innerHTML = '[Удалить]'; } ") + (p.ContainerTag != null ? "[Отклонить контейнер]".ToButton("", "", @"var x = new XMLHttpRequest(); x.open('POST', '../hideall/" + p.GetHash().Value + @"', true); x.send('');location.reload();") : "") + //("[В закладки]").ToRef("/bookmark/" + p.GetHash().Value) + ("[В тред]").ToRef((corePost?"/thread/":"/expand/") + p.ReplyTo.Value) + ("[Ответить]").ToRef("/reply/" + p.GetHash().Value)).ToDiv("", "") ).ToDiv("post", "")); } string s1 = "<a href='#' onclick='location.reload()'>[Обновить]</a>"; sb.Append(s1.ToDiv("", "")); sw.Stop(); ThreadViewHandler.AddFooter(sb, sw.ElapsedMilliseconds, _db); return(new NanoHttpResponse(StatusCode.Ok, sb.ToString().ToHtmlBody(ThreadViewHandler.NotifierScript))); }