示例#1
0
        public NanoHttpResponse Handle(NanoHttpRequest request)
        {
            Hash hash = new Hash(request.Address.Split('/').Last());

            if (hash.Invalid)
            {
                return new ErrorHandler(StatusCode.BadRequest, "Invalid hash").Handle(request);
            }

            try
            {
                var tag = _db.Get(hash).ContainerTag;

                for (int i = 0; i < _db.GetPostCount(); i++)
                {
                    var p = _db.GetPost(i);

                    if (p.ContainerTag != null && p.ContainerTag.Equals(tag))
                    {
                        _db.HideOnce(p.GetHash());
                    }
                }

                return new NanoHttpResponse(StatusCode.Ok, "\n");
            }

            catch (Exception e)
            {
                return new ErrorHandler(StatusCode.InternalServerError, e.ToString().Replace("\n", "<br>")).Handle(request);
            }
        }
示例#2
0
        public NanoHttpResponse Handle(NanoHttpRequest request)
        {
            Hash hash = new Hash(request.Address.Split('/').Last());

            if (hash.Invalid)
            {
                return new ErrorHandler(StatusCode.BadRequest, "Invalid hash").Handle(request);
            }

            try
            {
                if (_db.IsHidden(hash))
                {
                    _db.Unhide(hash);
                }

                else
                {
                    _db.Hide(hash);
                }

                return new NanoHttpResponse(StatusCode.Ok, "\n");
            }

            catch (Exception e)
            {
                return new ErrorHandler(StatusCode.InternalServerError, e.ToString().Replace("\n", "<br>")).Handle(request);
            }
        }
示例#3
0
        public NanoHttpResponse Handle(NanoHttpRequest request)
        {
            if (string.IsNullOrEmpty(request.Content))
            {
                return new ErrorHandler(StatusCode.BadRequest, "Empty message").Handle(request);
            }

            Hash thread = new Hash(request.Address.Split('/').Last());

            if (thread.Invalid)
            {
                return new ErrorHandler(StatusCode.BadRequest, "Invalid hash").Handle(request);
            }

            var str = Encoding.UTF8.GetString(request.Connection.Raw);
            str = str.Substring(str.IndexOf("\r\n\r\n") + 4);
            NanoPost post = null;

            if (thread.Value != NanoDB.CategoriesHashValue)
            {
                post = new NanoPost(thread, "[g]" + GetPostHeader() + "[/g]\n" + str);
            }

            else
            {
                post = new NanoPost(thread, str);
            }

            if (post.Invalid)
            {
                NotificationHandler.Instance.AddNotification("Превышен максимальный размер поста.");
                return new NanoHttpResponse(StatusCode.BadRequest, "");
            }

            if (SpamDetector.IsSpam(post.Message))
            {
                NotificationHandler.Instance.AddNotification("Ваш пост из-за своего содержания будет считаться спамом.");
                return new NanoHttpResponse(StatusCode.BadRequest, "");
            }
            else
            {
                NotificationHandler.Instance.AddNotification(
                    "Сообщение добавлено, " + post.SerializedBytes().Length + " байт ("+post.SerializedString().Length+" симв.)");

                if (_db.AddPost(post))
                {
                    _db.WriteNewPosts(false);
                }

                return new NanoHttpResponse(StatusCode.Ok, post.GetHash().Value);
            }
        }
示例#4
0
        //public event Action<NanoPost> BookmarkAdded = delegate(NanoPost obj) {};

        public void Init()
        {
            var root = new NanoPost(Hash.CreateZero(), NanoPost.RootStub);
            AddPost(root, false);
            RootHash = root.GetHash();

            var cat = new NanoPost(RootHash, "[b]КАТЕГОРИИ[/b]\nЧтобы создать новую категорию, ответьте на это сообщение.\nОтветьте на одну из категорий, чтобы создать там тред.");
            AddPost(cat, false);
            var cathash = cat.GetHash();
            AddPost(new NanoPost(cathash, "[b]Автомобили/Мотоциклы[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Бред/Разное[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Видеоигры[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Выживание[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Железо/Софт[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Иностранные языки[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Кино и ТВ[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Книги[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Криптоанархия[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Музыка[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Мода и стиль[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Наука[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Обсуждение Наноборды[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Паранормальное[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Политика[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Психология[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Программирование[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Реквесты[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Смартфоны/Планшеты[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Секс[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Спорт[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Творчество[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]Японская культура[/b]"), false);
            AddPost(new NanoPost(cathash, "[b]18+[/b]"), false);

            foreach (var p in _posts)
            {
                p.Value.NumberTag = int.MaxValue;
            }

            try
            {
                if (File.Exists(HideList))
                {
                    _hideList = new HashSet<string>(File.ReadAllLines(HideList));
                }
            }
            catch (Exception e)
            {
                Logger.LogError("Error wile reading hide.list\n" + e.ToString());
            }
        }
示例#5
0
        private NanoHttpResponse HandleSafe(NanoHttpRequest request)
        {
            Hash thread = new Hash(request.Address.Split('/').Last());

            if (thread.Invalid)
            {
                return new ErrorHandler(StatusCode.BadRequest, "Wrong hash format.").Handle(request);
            }

            var sb = new StringBuilder();

            sb.Append("{ \n    \"posts\" : [\n");

            var posts = _expanded ? _db.GetExpandedThreadPosts(thread) : _db.GetThreadPosts(thread);

            for (int i = 0; i < posts.Length; i++)
            {
                var p = posts[i];
                bool last = i == posts.Length - 1;
                sb.Append("    {\n        \"hash\" :    \"");
                sb.Append(p.GetHash().Value);
                sb.Append("\", \n        \"isHidden\" : \"");
                sb.Append(_db.IsHidden(p.GetHash()) ? "1" : "0");
                sb.Append("\", \n        \"replyTo\" : \"");
                sb.Append(p.ReplyTo.Value);
                sb.Append("\", \n        \"message\" : \"");

                string s = p.SerializedString().Substring(32);
                s = s.Replace("\\", "\\\\");
                s = s.Replace("\n", "\\n");
                s = s.Replace("\"", "\\\"");
                s = s.Replace("\t", "\\t");
                s = s.Replace("\r", "\\r");
                sb.Append(s);
                sb.Append("\"\n    }");
                if (!last) sb.Append(",\n");
            }

            sb.Append("\n    ]\n}");

            return new NanoHttpResponse(StatusCode.Ok, sb.ToString(), "application/json; charset=utf-8");
        }
示例#6
0
        private NanoHttpResponse HandleSafe(NanoHttpRequest request)
        {
            Hash thread = new Hash(request.Address.Split('/').Last());

            if (thread.Invalid)
            {
                return new ErrorHandler(StatusCode.BadRequest, "Wrong hash format.").Handle(request);
            }

            var sb = new StringBuilder();
            ThreadViewHandler.AddHeader(sb);
            var p = _db.Get(thread);

            bool corePost = false;

            if ( p.GetHash().Value == NanoDB.CategoriesHashValue || // создал категорию - не разворачивать все категории
                 p.ReplyTo.Value == NanoDB.CategoriesHashValue) // создал тред в одной из категорий - не разворачивать все треды
            {
                corePost = true;
            }

                sb.Append(
                    (
                        p.Message.Strip(true).Replace("\n", "<br/>").ToDiv("postinner", p.GetHash().Value)
                    ).ToDiv("post", ""));
                sb.Append(((/*">" + p.Message.StripInput().Replace("\n", "\n>") + "\n"*/"").ToTextArea("", "reply").AddBreak() +
                ("Отправить".ToButton("", "sendbtn", @"
                    var x = new XMLHttpRequest();
                    x.open('POST', '../write/"+p.GetHash().Value+@"', true);
                    x.send(document.getElementById('reply').value);
                    x.onreadystatechange = function(){
                    location.replace('/"+(corePost?"thread":"expand")+"/" + p.GetHash().Value + @"');}
                "))).ToDiv("post", ""));

            return new NanoHttpResponse(StatusCode.Ok, sb.ToString().ToHtmlBody());
        }
示例#7
0
 public bool Equals(Hash h)
 {
     return h != null && h.Value == Value;
 }
示例#8
0
        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 = _db.RootHash;
            }

            var sb = new StringBuilder();
            AddHeader(sb);
            string s1 = "";

            if (thread.Value != _db.RootHash.Value)
            {
                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("&gt;", ">").Replace("&lt;", "<").Replace("<grn>", "").Replace("</grn>", "").Replace("&nbsp;", " ").
                        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>&gt;&gt;" + 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>&gt;&gt;"+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) +
                     ("<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(FractalMusicScript + PostScript(postScript)));
        }
示例#9
0
        public NanoPost[] GetThreadPosts(Hash thread, bool eraseDepth = true)
        {
            if (!_threadPosts.ContainsKey(thread))
            {
                if (_posts.ContainsKey(thread))
                {
                    return new NanoPost[] { _posts[thread] };
                }

                else
                {
                    return new NanoPost[0];
                }
            }

            var list = new List<NanoPost>();

            if (_posts.ContainsKey(thread))
            {
                list.Add(_posts[thread]);
            }

            list.AddRange(_threadPosts[thread].ToArray().Sorted());
            if (eraseDepth)
                list.ForEach(p => p.DepthTag = 0);
            return list.ToArray();
        }
示例#10
0
        public int CountAnswersRecursive(Hash thread)
        {
            if (!_threadPosts.ContainsKey(thread))
                return 0;

            int res = 0;
            var stack = new Stack<Hash>();
            stack.Push(thread);

            while (stack.Count > 0)
            {
                var v = stack.Pop();

                if (_threadPosts.ContainsKey(v))
                {
                    foreach (var p in _threadPosts[v])
                    {
                        res += 1;
                        stack.Push(p.GetHash());
                    }
                }
            }

            return res;
        }
示例#11
0
        public NanoPost[] GetExpandedThreadPosts(Hash thread, int depth = 0, List<NanoPost> list = null)
        {
            if (list == null)
            {
                list = new List<NanoPost>();
            }

            if (depth == 0)
            {
                // clear depth
                foreach (var p in _posts)
                {
                    p.Value.DepthTag = 0;
                }
            }


            if (!_threadPosts.ContainsKey(thread))
            {
                if (_posts.ContainsKey(thread))
                {
                    _posts[thread].DepthTag = depth;
                    list.Add(_posts[thread]);
                    return new NanoPost[] { _posts[thread] };
                }
                else
                {
                    return new NanoPost[0];
                }
            }


            if (depth == 0 && _posts.ContainsKey(thread))
            {
                _posts[thread].DepthTag = depth;
                list.Add(_posts[thread]);
            }

            var tps = _threadPosts[thread].OrderBy(p => p.NumberTag).ToArray();

            foreach (var tp in tps)
            {
                tp.DepthTag = depth + 1;
                list.Add(tp);
                GetExpandedThreadPosts(tp.GetHash(), depth + 1, list);
            }

            return list.Distinct().ToArray();
        }
示例#12
0
 public int CountAnswers(Hash thread)
 {
     return CountAnswersRecursive(thread);
     //return _threadPosts.ContainsKey(thread) ? _threadPosts[thread].ToArray().ExceptHidden(this).Length : 0;
 }
示例#13
0
        public NanoPost Get(Hash hash)
        {
            if (!_posts.ContainsKey(hash))
            {
                return null;
            }

            return _posts[hash];
        }
示例#14
0
        public void Unhide(Hash hash)
        {
            if (!_hideList.Contains(hash.Value))
                return;
            if (hash.Zero)
                return;
            if (hash.Value == RootHash.Value)
                return;
            _hideList.Remove(hash.Value);

            if (_onceList.Contains(hash.Value))
            {
                _onceList.Remove(hash.Value);
            }
        }
示例#15
0
 public void Hide(Hash hash)
 {
     if (_hideList.Contains(hash.Value)) return;
     if (hash.Zero) return;
     if (hash.Value == RootHash.Value) return;
     _hideList.Add(hash.Value);
 }
示例#16
0
  public bool IsHidden(Hash hash)
  {
      return _hideList.Contains(hash.Value) || 
             _onceList.Contains(hash.Value);
 }