public void Replace_Custom_Code_Tags_With_Pre_Tags(string input, string expected)
        {
            var pf     = new PostFormatter();
            var output = pf.Prettify(input);

            Assert.AreEqual(output, expected);
        }
        public void Not_Change_String_Without_Code_Tags(string input, string expected)
        {
            var pf     = new PostFormatter();
            var output = pf.Prettify(input);

            Assert.AreEqual(output, expected);
        }
        public void Replace_Env_NewLine_With_Br_Tag()
        {
            var input    = $"Here is a post {Environment.NewLine} with a newline.";
            var expected = $"Here is a post <br /> with a newline.";
            var pf       = new PostFormatter();
            var output   = pf.Prettify(input);

            Assert.AreEqual(output, expected);
        }
예제 #4
0
        public async Task <IActionResult> Search(int threadId, string query = "")
        {
            try
            {
                if (User.Identity.IsAuthenticated)
                {
                    ViewBag.CurrentAdmin = _db.Admin.First(a => a.Email == User.Identity.Name);
                }

                var postsFiles = new Dictionary <Post, List <File> >();

                if (!string.IsNullOrWhiteSpace(query) || !string.IsNullOrEmpty(query))
                {
                    if (ModelState.IsValid)
                    {
                        try
                        {
                            var posts = _db.Post.Where(p =>
                                                       p.ThreadId == threadId && (p.Comment.Contains(query) || p.Subject.Contains(query)))
                                        .Include(p => p.File).Take(50).ToList();

                            foreach (var post in posts)
                            {
                                post.Comment = PostFormatter.GetFormattedPostText(post);
                                postsFiles.Add(post, post.File.ToList());
                            }
                        }
                        catch (InvalidOperationException)
                        {
                            return(NotFound());
                        }
                    }
                }

                ViewBag.Thread     = _db.Thread.Include(t => t.Board).First(t => t.ThreadId == threadId);
                ViewBag.Board      = ViewBag.Thread.Board;
                ViewBag.PostsFiles = postsFiles;
            }
            catch (InvalidOperationException)
            {
                return(NotFound());
            }
            catch (Exception e)
            {
                await LogIntoFile(_logDirectory, string.Concat(e.Message, "\n", e.StackTrace),
                                  LoggingInformationKind.Error);

                return(StatusCode(500));
            }

            return(View());
        }
예제 #5
0
        public async Task <IActionResult> Report(int postId)
        {
            var ipHash = _md5.ComputeHash(HttpContext.Connection.RemoteIpAddress.GetAddressBytes())
                         .GetString();

            var anon = new Anon(ipHash, IpCheck.UserIsBanned(_db, ipHash));

            ViewBag.UserIpHash = anon.IpHash;

            ViewBag.UserIsBanned = false;

            if (anon.IsBanned)
            {
                ViewBag.UserIsBanned = anon.IsBanned;
                var ban = _db.Ban.First(b => b.AnonIpHash == anon.IpHash);
                ViewBag.BanReason = ban.Reason;
                ViewBag.BanEnd    = DateTimeOffset.FromUnixTimeSeconds(ban.Term).ToLocalTime();
            }

            try
            {
                var post = _db.Post.Include(p => p.File)
                           .Include(p => p.Admin)
                           .First(p => p.PostId == postId) ?? throw new Exception();

                ViewBag.Board = _collection.Boards.First(brd => brd.BoardId == post.BoardId);

                ViewBag.Thread = _db.Thread.First(t => t.ThreadId == post.ThreadId);

                post.Comment = PostFormatter.GetFormattedPostText(post);

                ViewBag.PostFiles = new KeyValuePair <Post, List <File> >(post, post.File.ToList());

                return(View());
            }
            catch (Exception e)
            {
                await LogIntoFile(_logDirectory, string.Concat(e.Message, "\n", e.StackTrace),
                                  LoggingInformationKind.Error);

                return(NotFound());
            }
        }
예제 #6
0
        public PostFormatterTests()
        {
            _formatter = new PostFormatter(_htmlMock.Object);

            _htmlMock.SetupGet(x => x.DivForTextStart).Returns("");
            _htmlMock.SetupGet(x => x.DivEnd).Returns("");
            _htmlMock.Setup(x => x.Blockquote(It.IsAny <string>()))
            .Returns((string text) => $"@{text}@");
            _htmlMock.Setup(x => x.Centered(It.IsAny <string>())).Returns((string text) => $"c[{text}]");
            _htmlMock.Setup(x => x.FloatRight(It.IsAny <string>()))
            .Returns((string text) => $"fr[{text}]");
            _htmlMock.Setup(x => x.Image(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <int>(), It.IsAny <int>()))
            .Returns((string url, string src, int height, int width) => $"<{url}/{src}/{height}/{width}>");
            _htmlMock.Setup(x => x.Link(It.IsAny <string>(), It.IsAny <string>()))
            .Returns((string url, string title) => $"<{url}-{title}>");
            _htmlMock.Setup(x => x.LjCut(It.IsAny <string>()))
            .Returns((string text) => text);
            _htmlMock.Setup(x => x.Strikeout(It.IsAny <string>()))
            .Returns((string text) => $"={text}=");
        }
예제 #7
0
        private string build_page_html(string board, string threadId, PostFormatter[] thread_data, string notes)
        {
            StringBuilder pageHtml = new StringBuilder(Properties.Resources.zip_page_template);

            StringBuilder body = new StringBuilder();
            {
                body.Append(thread_data[0].ToString(true));

                body.Replace("{post:link}", string.Format("#p{0}", thread_data[0].PostID));

                for (int i = 1; i < thread_data.Length; i++)
                {
                    body.Append(thread_data[i].ToString(true));
                }
            }

            pageHtml.Replace("{title}", string.Format("/{0}/ Thread No. {1}", board, threadId));

            pageHtml.Replace("{board-letter}", board);

            pageHtml.Replace("{notes}", System.Web.HttpUtility.HtmlEncode(notes));

            pageHtml.Replace("{thread-id}", threadId);

            pageHtml.Replace("{thread-posts}", body.ToString());

            return pageHtml.ToString();
        }
예제 #8
0
        private PostFormatter load_post_data_str(string data, bool isop)
        {
            JsonObject post_data = JsonConvert.Import<JsonObject>(data);

            string[] keys = post_data.Names.Cast<string>().ToArray();

            PostFormatter pf = new PostFormatter();

            foreach (JsonMember member in post_data)
            {
                switch (member.Name)
                {
                    case "RawComment":
                        pf.Comment = Convert.ToString(member.Value);
                        continue;
                    case "Email":
                        pf.Email = Convert.ToString(member.Value);
                        continue;
                    case "Name":
                        pf.Name = Convert.ToString(member.Value);
                        continue;
                    case "PosterID":
                        pf.PosterID = Convert.ToString(member.Value);
                        continue;
                    case "Subject":
                        pf.Subject = Convert.ToString(member.Value);
                        continue;
                    case "Trip":
                        pf.Trip = Convert.ToString(member.Value);
                        continue;
                    case "ID":
                        pf.PostID = Convert.ToInt32(member.Value);
                        continue;
                    case "Time":
                        try
                        {
                            pf.Time = DateTime.Parse(member.Value.ToString());
                        }
                        catch
                        {

                        }
                        continue;
                    case "FileHash":
                        {
                            FileFormatter f = new FileFormatter();
                            f.PostID = pf.PostID;
                            f.FileName = Convert.ToString(post_data["FileName"]);
                            f.Hash = Convert.ToString(post_data["FileHash"]);
                            f.ThumbName = Convert.ToString(post_data["ThumbTime"]);
                            f.Height = Convert.ToInt32(post_data["FileHeight"]);
                            f.Width = Convert.ToInt32(post_data["FileWidth"]);
                            f.Size = Convert.ToInt32(post_data["FileSize"]);
                            pf.MyFile = f;
                            continue;
                        }
                    case "Sticky":
                        pf.IsSticky = Convert.ToBoolean(member.Value);
                        continue;
                    case "Closed":
                        pf.IsLocked = Convert.ToBoolean(member.Value);
                        continue;
                }
            }
            pf.Type = isop ? PostFormatter.PostType.OP : PostFormatter.PostType.Reply;
            return pf;
        }
예제 #9
0
        private PostFormatter load_post_data_str(string data, bool isop)
        {
            JsonObject post_data = JsonConvert.Import <JsonObject>(data);

            string[] keys = post_data.Names.Cast <string>().ToArray();

            PostFormatter pf = new PostFormatter();

            foreach (JsonMember member in post_data)
            {
                switch (member.Name)
                {
                case "RawComment":
                    pf.Comment = Convert.ToString(member.Value);
                    continue;

                case "Email":
                    pf.Email = Convert.ToString(member.Value);
                    continue;

                case "Name":
                    pf.Name = Convert.ToString(member.Value);
                    continue;

                case "PosterID":
                    pf.PosterID = Convert.ToString(member.Value);
                    continue;

                case "Subject":
                    pf.Subject = Convert.ToString(member.Value);
                    continue;

                case "Trip":
                    pf.Trip = Convert.ToString(member.Value);
                    continue;

                case "ID":
                    pf.PostID = Convert.ToInt32(member.Value);
                    continue;

                case "Time":
                    try
                    {
                        pf.Time = DateTime.Parse(member.Value.ToString());
                    }
                    catch
                    {
                    }
                    continue;

                case "FileHash":
                {
                    FileFormatter f = new FileFormatter();
                    f.PostID    = pf.PostID;
                    f.FileName  = Convert.ToString(post_data["FileName"]);
                    f.Hash      = Convert.ToString(post_data["FileHash"]);
                    f.ThumbName = Convert.ToString(post_data["ThumbTime"]);
                    f.Height    = Convert.ToInt32(post_data["FileHeight"]);
                    f.Width     = Convert.ToInt32(post_data["FileWidth"]);
                    f.Size      = Convert.ToInt32(post_data["FileSize"]);
                    pf.MyFile   = f;
                    continue;
                }

                case "Sticky":
                    pf.IsSticky = Convert.ToBoolean(member.Value);
                    continue;

                case "Closed":
                    pf.IsLocked = Convert.ToBoolean(member.Value);
                    continue;
                }
            }
            pf.Type = isop ? PostFormatter.PostType.OP : PostFormatter.PostType.Reply;
            return(pf);
        }
예제 #10
0
        public PostFormatter[] GetThread(string board, string id)
        {
            string thread_dir_path = Path.Combine(Program.post_files_dir, board, id.ToString());

            DirectoryInfo info = new DirectoryInfo(thread_dir_path);

            if (!info.Exists)
            {
                return(new PostFormatter[] { });
            }

            // optimized thread path
            string opt_path = Path.Combine(thread_dir_path, id + "-opt.json");

            List <PostFormatter> thread_pf = new List <PostFormatter>();

            if (File.Exists(opt_path))
            {
                JsonObject thread_data = JsonConvert.Import <JsonObject>(File.ReadAllText(opt_path));

                string data;

                if (thread_data.Names.Cast <string>().Contains("op"))
                {
                    data = thread_data["op"].ToString();

                    if (!string.IsNullOrEmpty(data))
                    {
                        thread_pf.Add(load_post_data_str(data, true));
                        // remove the op post
                        thread_data.Remove("op");
                    }
                }

                // sort the replies by their id
                foreach (string key in thread_data.Names.Cast <object>().OrderBy(x => Convert.ToInt32(x)))
                {
                    data = thread_data[key].ToString();

                    if (!string.IsNullOrEmpty(data))
                    {
                        thread_pf.Add(load_post_data_str(data, false));
                    }
                }
            }
            else
            {
                string data;
                string op = Path.Combine(thread_dir_path, "op.json");
                if (File.Exists(op))
                {
                    data = File.ReadAllText(op);
                    if (!string.IsNullOrEmpty(data))
                    {
                        thread_pf.Add(load_post_data_str(data, true));
                    }
                }

                foreach (string file in
                         Directory.EnumerateFiles(thread_dir_path, "*.json", SearchOption.TopDirectoryOnly).OrderBy(x => Path.GetFileNameWithoutExtension(x)))
                {
                    if (!file.EndsWith("op.json"))
                    {
                        data = File.ReadAllText(file);

                        if (!string.IsNullOrWhiteSpace(data))
                        {
                            try
                            {
                                PostFormatter post = load_post_data_str(data, false);
                                thread_pf.Add(post);
                            }
                            catch (JsonException)
                            {
                                File.Delete(file);
                            }
                            catch (Exception)
                            { }
                        }
                    }
                }
            }
            return(thread_pf.ToArray());
        }
예제 #11
0
        public async Task <IActionResult> Thread(int id)
        {
            var ipHash = _md5.ComputeHash(HttpContext.Connection.RemoteIpAddress.GetAddressBytes())
                         .GetString();

            var anon = new Anon(ipHash, IpCheck.UserIsBanned(_db, ipHash));

            ViewBag.UserIpHash = anon.IpHash;

            ViewBag.UserIsBanned = false;

            ViewBag.Id = 0;

            if (anon.IsBanned)
            {
                ViewBag.UserIsBanned = anon.IsBanned;
                var ban = _db.Ban.First(b => b.AnonIpHash == anon.IpHash);
                ViewBag.BanReason = ban.Reason;
                ViewBag.BanEnd    = DateTimeOffset.FromUnixTimeSeconds(ban.Term).ToLocalTime();
            }

            if (User.Identity.IsAuthenticated)
            {
                ViewBag.CurrentAdmin = _db.Admin.First(a => a.Email == User.Identity.Name);
            }

            try
            {
                using (_db)
                {
                    try
                    {
                        var thread = _db.Thread.Where(t => t.ThreadId == id)
                                     .Include(t => t.Board)
                                     .ToList()[0];

                        var posts = _db.Post.Where(p => p.ThreadId == id)
                                    .Include(p => p.File)
                                    .Include(p => p.Admin)
                                    .ToList();

                        var postsFiles = new Dictionary <Post, List <File> >();

                        ViewBag.PinnedPost = new KeyValuePair <Post, List <File> >(null, null);

                        foreach (var post in posts)
                        {
                            post.Comment = PostFormatter.GetFormattedPostText(post);
                            if (post.IsPinned)
                            {
                                ViewBag.PinnedPost = new KeyValuePair <Post, List <File> >(post, post.File.ToList());
                                continue;
                            }

                            postsFiles.Add(post, post.File.ToList());
                        }

                        ViewBag.Board      = thread.Board;
                        ViewBag.Thread     = thread;
                        ViewBag.UserIsOp   = IpCheck.UserIsOp(thread, anon.IpHash);
                        ViewBag.PostsFiles = postsFiles;
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        return(NotFound());
                    }
                    catch (Exception e)
                    {
                        await LogIntoFile(_logDirectory, string.Concat(e.Message, "\n", e.StackTrace),
                                          LoggingInformationKind.Error);
                    }
                }
            }
            catch (InvalidOperationException)
            {
                return(NotFound());
            }
            catch (Exception e)
            {
                await LogIntoFile(_logDirectory, string.Concat(e.Message, "\n", e.StackTrace),
                                  LoggingInformationKind.Error);
            }

            return(View());
        }
예제 #12
0
        public async Task <IActionResult> AddPost(Post post, List <IFormFile> files, bool sage, bool isWrittenByOp = false)
        {
            try
            {
                var ipHash = _md5.ComputeHash(HttpContext.Connection.RemoteIpAddress.GetAddressBytes())
                             .GetString();

                var anon = new Anon(ipHash, IpCheck.UserIsBanned(_db, ipHash));

                if (anon.IsBanned)
                {
                    return(RedirectToAction("YouAreBanned", "Ban"));
                }

                post.Comment           = PostFormatter.GetHtmlTrimmedString(post.Comment);
                post.AnonIpHash        = ipHash;
                post.TimeInUnixSeconds = DateTimeOffset.Now.ToUnixTimeSeconds();

                if (User.Identity.IsAuthenticated)
                {
                    var admin = _db.Admin.First(a => a.Email == User.Identity.Name);
                    post.AnonName = admin.Login;
                    post.Admin    = admin;
                }

                if (ModelState.IsValid)
                {
                    DbAccess.AddPostToThread(_db, post, sage, isWrittenByOp);

                    if (files.Count > 0)
                    {
                        var fileDirectory = Path.Combine(_env.WebRootPath, "postImages");

                        var thumbNailDirectory = Path.Combine(_env.WebRootPath, "thumbnails");

                        foreach (var file in files)
                        {
                            if (file.Length > 0)
                            {
                                switch (Path.GetExtension(file.FileName))
                                {
                                case ".jpeg":
                                case ".jpg":
                                case ".png":
                                {
                                    var imageThumbnailCreator =
                                        new ImageThumbnailCreator(file, fileDirectory, thumbNailDirectory);

                                    imageThumbnailCreator.CreateThumbnail();

                                    DbAccess.AddFilesToPost(_db, post, imageThumbnailCreator.FileInfo);

                                    break;
                                }

                                case ".gif":
                                {
                                    var gifThumbnailCreator =
                                        new GifThumbnailCreator(file, fileDirectory, thumbNailDirectory);

                                    gifThumbnailCreator.CreateThumbnail();

                                    DbAccess.AddFilesToPost(_db, post, gifThumbnailCreator.FileInfo);

                                    break;
                                }
                                }
                            }
                            else
                            {
                                ModelState.AddModelError("FileLengthNotValid", "Файл пустой.");
                            }
                        }
                    }

                    await LogIntoFile(_logDirectory,
                                      string.Concat("Added new post: ", post.PostId, "at thread: ", post.ThreadId),
                                      LoggingInformationKind.Info);
                }
                else
                {
                    return(StatusCode(500));
                }
            }
            catch (InvalidOperationException)
            {
                return(NotFound());
            }
            catch (Exception e)
            {
                await LogIntoFile(_logDirectory, string.Concat(e.Message, "\n", e.StackTrace),
                                  LoggingInformationKind.Error);
            }

            return(RedirectToAction("Thread", new { id = post.ThreadId }));
        }
예제 #13
0
        public async Task <IActionResult> AddThread(Post post, List <IFormFile> files)
        {
            try
            {
                var ipHash = _md5.ComputeHash(HttpContext.Connection.RemoteIpAddress.GetAddressBytes())
                             .GetString();

                var anon = new Anon(ipHash, IpCheck.UserIsBanned(_db, ipHash));

                if (anon.IsBanned)
                {
                    return(RedirectToAction("YouAreBanned", "Ban"));
                }

                if (ModelState.IsValid)
                {
                    var board = _db.Board.First(b => b.BoardId == post.BoardId);

                    if (_db.Thread.Count(t => t.BoardId == post.BoardId) >= 20)
                    {
                        return(RedirectToAction("Board", new { prefix = board.Prefix }));
                    }


                    post.AnonIpHash = ipHash;
                    if (!string.IsNullOrEmpty(post.AnonName))
                    {
                        post.AnonName = PostFormatter.GetHtmlTrimmedString(post.AnonName);
                    }

                    post.Comment       = PostFormatter.GetHtmlTrimmedString(post.Comment);
                    post.IsWrittenByOp = true;

                    if (User.Identity.IsAuthenticated)
                    {
                        var admin = _db.Admin.First(a => a.Email == User.Identity.Name);
                        post.AnonName = admin.Login;
                        post.Admin    = admin;
                    }

                    DbAccess.AddThreadToBoard(_db, ref post);

                    if (files.Count > 0)
                    {
                        var fileDirectory = Path.Combine(_env.WebRootPath, "postImages");

                        var thumbNailDirectory = Path.Combine(_env.WebRootPath, "thumbnails");

                        foreach (var file in files)
                        {
                            if (file.Length > 0)
                            {
                                switch (Path.GetExtension(file.FileName))
                                {
                                case ".jpeg":
                                case ".jpg":
                                case ".png":
                                {
                                    var imageThumbnailCreator = new ImageThumbnailCreator(file, fileDirectory, thumbNailDirectory);
                                    imageThumbnailCreator.CreateThumbnail();

                                    DbAccess.AddFilesToPost(_db, post, imageThumbnailCreator.FileInfo);

                                    break;
                                }

                                case ".gif":
                                {
                                    var gifThumbnailCreator = new GifThumbnailCreator(file, fileDirectory, thumbNailDirectory);
                                    gifThumbnailCreator.CreateThumbnail();

                                    DbAccess.AddFilesToPost(_db, post, gifThumbnailCreator.FileInfo);

                                    break;
                                }
                                }
                            }
                            else
                            {
                                ModelState.AddModelError("FileLengthNotValid", "Файл пустой.");
                            }
                        }
                    }

                    await LogIntoFile(_logDirectory, string.Concat("Added new thread: ", post.ThreadId),
                                      LoggingInformationKind.Info);

                    return(RedirectToAction("Thread", "Thread", new { id = post.ThreadId }));
                }
            }
            catch (Exception e)
            {
                await LogIntoFile(_logDirectory, string.Concat(e.Message, "\n", e.StackTrace),
                                  LoggingInformationKind.Error);

                Console.WriteLine(e);
                return(StatusCode(500));
            }

            return(RedirectToAction("Board"));
        }
예제 #14
0
        public async Task <IActionResult> Board(string prefix, int page = 1)
        {
            var ipHash = _md5.ComputeHash(HttpContext.Connection.RemoteIpAddress.GetAddressBytes())
                         .GetString();

            var anon = new Anon(ipHash, IpCheck.UserIsBanned(_db, ipHash));

            ViewBag.UserIpHash = anon.IpHash;

            ViewBag.UserIsBanned = false;

            if (anon.IsBanned)
            {
                ViewBag.UserIsBanned = anon.IsBanned;
                var ban = _db.Ban.First(b => b.AnonIpHash == anon.IpHash);
                ViewBag.BanReason = ban.Reason;
                ViewBag.BanEnd    = DateTimeOffset.FromUnixTimeSeconds(ban.Term).ToLocalTime();
            }

            ViewBag.Id = 0;

            ViewBag.Page = page;

            try
            {
                ViewBag.Board = _collection.Boards.First(brd => brd.Prefix == prefix);

                var allThreads = new List <KeyValuePair <Thread, List <KeyValuePair <Post, List <File> > > > >();

                var boards = _db.Board.Where(b => b.Prefix == prefix).Include(b => b.Thread).ToList();

                Board board;
                if (boards.Count > 0)
                {
                    board             = boards[0];
                    ViewBag.FileLimit = board.FileLimit;
                }
                else
                {
                    return(NotFound());
                }

                ViewBag.ThreadCount = board.Thread.Count;

                foreach (var thrd in board.Thread.OrderByDescending(t => t.BumpInUnixTime))
                {
                    var thread = _db.Thread.Include(t => t.Post).First(t => t.ThreadId == thrd.ThreadId);

                    if (thread != null)
                    {
                        var postFiles = new List <KeyValuePair <Post, List <File> > >();

                        if (thread.Post.Count >= 4)
                        {
                            var posts = new List <Post> {
                                thread.Post.ToArray()[0]
                            };

                            posts.AddRange(thread.Post.ToList().OrderByDescending(p => p.TimeInUnixSeconds).Take(3));

                            foreach (var post in posts)
                            {
                                var p = _db.Post
                                        .Include(pp => pp.File)
                                        .Include(pp => pp.Admin)
                                        .First(pp => pp.PostId == post.PostId);

                                postFiles.Add(new KeyValuePair <Post, List <File> >(p, p.File.ToList()));
                            }

                            allThreads.Add(
                                new KeyValuePair <Thread, List <KeyValuePair <Post, List <File> > > >(thread, postFiles));
                        }
                        else if (thread.Post.Count > 0 && thread.Post.Count <= 3)
                        {
                            var p = _db.Post
                                    .Include(pp => pp.File)
                                    .Include(pp => pp.Admin)
                                    .First(pp => pp.ThreadId == thread.ThreadId);
                            postFiles.Add(new KeyValuePair <Post, List <File> >(p, p.File.ToList()));

                            allThreads.Add(
                                new KeyValuePair <Thread, List <KeyValuePair <Post, List <File> > > >(thread, postFiles));
                        }
                    }
                }

                var pageInfo = new PageInfo(page, Constants.BOARD_PAGE_SIZE, allThreads.Count);

                var pageThreads = new List <KeyValuePair <Thread, List <KeyValuePair <Post, List <File> > > > >();

                for (var i = (page - 1) * pageInfo.PageSize; i < page * pageInfo.PageSize; i++)
                {
                    try
                    {
                        pageThreads.Add(allThreads[i]);
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        break;
                    }
                    catch (Exception e)
                    {
                        await LogIntoFile(_logDirectory, string.Concat(e.Message, "\n", e.StackTrace),
                                          LoggingInformationKind.Error);

                        return(StatusCode(500));
                    }
                }

                foreach (var pt in pageThreads)
                {
                    foreach (var pf in pt.Value)
                    {
                        pf.Key.Comment = PostFormatter.GetFormattedPostText(pf.Key);
                    }
                }

                ViewBag.PageInfo = pageInfo;

                ViewBag.BoardViewModel = pageThreads;
            }
            catch (InvalidOperationException e)
            {
                await LogIntoFile(_logDirectory, string.Concat(e.Message, "\n", e.StackTrace),
                                  LoggingInformationKind.Error);

                return(NotFound());
            }
            catch (Exception e)
            {
                await LogIntoFile(_logDirectory, string.Concat(e.Message, "\n", e.StackTrace),
                                  LoggingInformationKind.Error);

                return(StatusCode(500));
            }

            return(View());
        }