public void Should_Convert_Post_Text_To_String()
        {
            var    text = "this is my text";
            string sut  = PostText.Create(text).Value;

            sut.Should().Be(text);
        }
Beispiel #2
0
        public async Task <IHttpActionResult> PutPostText(int id, PostText postText)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            if (id != postText.Id)
            {
                return(BadRequest());
            }

            db.Entry(postText).State = EntityState.Modified;

            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!PostTextExists(id))
                {
                    return(NotFound());
                }
                else
                {
                    throw;
                }
            }

            return(StatusCode(HttpStatusCode.NoContent));
        }
Beispiel #3
0
        /// <summary>
        /// Get thread info from the provided page.
        /// </summary>
        /// <param name="page">A web page from a forum that this adapter can handle.</param>
        /// <returns>Returns thread information that can be gleaned from that page.</returns>
        public ThreadInfo GetThreadInfo(HtmlDocument page)
        {
            if (page == null)
            {
                throw new ArgumentNullException(nameof(page));
            }

            string title;
            string author = string.Empty; // vBulletin doesn't show the thread author
            int    pages  = 1;

            HtmlNode doc = page.DocumentNode.Element("html");

            // Find the page title
            title = doc.Element("head").Element("title")?.InnerText;
            title = PostText.CleanupWebString(title);

            var threadViewTab = page.GetElementbyId("thread-view-tab");

            var pageNavControls = threadViewTab?.GetDescendantWithClass("div", "pagenav-controls");

            var pageTotalSpan = pageNavControls?.GetDescendantWithClass("span", "pagetotal");

            if (pageTotalSpan != null)
            {
                pages = int.Parse(pageTotalSpan.InnerText);
            }

            ThreadInfo info = new ThreadInfo(title, author, pages);

            return(info);
        }
        public async Task <IActionResult> AddPost(AddPostTextViewModel model, IFormFile image)
        {
            ViewBag.UserId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
            if (!ModelState.IsValid || string.IsNullOrEmpty(model.postText.ShortText) ||
                string.IsNullOrEmpty(model.postText.Text))
            {
                _notification.AddWarningToastMessage("لطفا مقادیر را به درستی پر کنید");
                model.groups = (await _db.GroupRepository.GetAllAsync(a => !a.IsDeleted));
                return(View(model));
            }
            if (image != null)
            {
                model.postText.Image = await _fileManager.UploadImage(image, FileManagerType.FileType.PostTextImages);
            }
            var group    = _db.GroupRepository.GetAll().FirstOrDefault(a => a.Name == model.postText.Groups.Name);
            var PostText = new PostText()
            {
                GroupId     = group.Id,
                Image       = model.postText.Image,
                Name        = model.postText.Name,
                ShortText   = model.postText.ShortText,
                Text        = model.postText.Text,
                CreatedTime = DateTime.Now,
                UserId      = User.FindFirst(ClaimTypes.NameIdentifier).Value,
                Groups      = group
            };
            await _db.PostTextRepository.InsertAsync(PostText);

            await _db.SaveChangeAsync();

            _notification.AddSuccessToastMessage("پست شما با موفقیت ثبت شد");
            return(RedirectToAction("Index", "Home"));
        }
Beispiel #5
0
        /// <summary>
        /// Get a completed post from the provided HTML div node.
        /// </summary>
        /// <param name="li">Div node that contains the post.</param>
        /// <returns>Returns a post object with required information.</returns>
        private PostComponents GetPost(HtmlNode li, IQuest quest)
        {
            if (li == null)
            {
                throw new ArgumentNullException(nameof(li));
            }

            string author;
            string id;
            string text;
            int    number;

            id     = li.GetAttributeValue("data-pid", "");
            author = li.GetAttributeValue("data-username", "");
            number = int.Parse(li.GetAttributeValue("data-index", "0"));

            var content = li.GetChildWithClass("div", "content");

            // Get the full post text.
            text = PostText.ExtractPostText(content, n => false, Host);


            PostComponents post;

            try
            {
                post = new PostComponents(author, id, text, number);
            }
            catch
            {
                post = null;
            }

            return(post);
        }
Beispiel #6
0
 public void Delete(PostText entity)
 {
     if (_db.Entry(entity).State == EntityState.Detached)
     {
         _db.Attach(entity);
     }
     _db.PostText.Remove(entity);
 }
Beispiel #7
0
 public void Update(PostText entity)
 {
     if (_db.Entry(entity).State == EntityState.Detached)
     {
         _db.PostText.Attach(entity);
     }
     _db.Entry(entity).State = EntityState.Modified;
 }
Beispiel #8
0
 private void UORTButton_Click(object sender, EventArgs e)
 {
     if (ActiveStatus != null)
     {
         PostText.Text = "RT @" + ActiveStatus.User.ScreenName + ": " + ActiveStatus.Text;
         PostText.Select(0, 0);
     }
 }
Beispiel #9
0
        /// <summary>
        /// Get a completed post from the provided HTML list item node.
        /// </summary>
        /// <param name="li">List item node that contains the post.</param>
        /// <returns>Returns a post object with required information.</returns>
        private PostComponents GetPost(HtmlNode li)
        {
            if (li == null)
            {
                throw new ArgumentNullException(nameof(li));
            }

            string author = "";
            string id     = "";
            string text   = "";
            int    number = 0;

            // ID
            id = li.Id.Substring("post_".Length);

            // Number
            var postCount = li.OwnerDocument.GetElementbyId($"postcount{id}");

            if (postCount != null)
            {
                number = int.Parse(postCount.GetAttributeValue("name", "0"));
            }


            HtmlNode postDetails = li.Elements("div").FirstOrDefault(n => n.GetAttributeValue("class", "") == "postdetails");

            if (postDetails != null)
            {
                // Author
                HtmlNode userinfo = postDetails.GetChildWithClass("div", "userinfo");
                HtmlNode username = userinfo?.GetChildWithClass("a", "username");
                author = PostText.CleanupWebString(username?.InnerText);

                // Text
                string postMessageId = "post_message_" + id;

                var message = li.OwnerDocument.GetElementbyId(postMessageId)?.Element("blockquote");

                // Predicate filtering out elements that we don't want to include
                var exclusion = PostText.GetClassExclusionPredicate("bbcode_quote");

                // Get the full post text.
                text = PostText.ExtractPostText(message, exclusion, Host);
            }

            PostComponents post;

            try
            {
                post = new PostComponents(author, id, text, number);
            }
            catch
            {
                post = null;
            }

            return(post);
        }
Beispiel #10
0
        /// <summary>
        /// Get thread info from the provided page.
        /// </summary>
        /// <param name="page">A web page from a forum that this adapter can handle.</param>
        /// <returns>Returns thread information that can be gleaned from that page.</returns>
        public ThreadInfo GetThreadInfo(HtmlDocument page)
        {
            if (page == null)
            {
                throw new ArgumentNullException(nameof(page));
            }

            string title;
            string author;
            int    pages;

            HtmlNode doc = page.DocumentNode;

            // Find the page title
            title = PostText.CleanupWebString(doc.Element("html").Element("head")?.Element("title")?.InnerText);

            // Find a common parent for other data
            HtmlNode pageContent = GetPageContent(page, PageType.Thread);

            if (pageContent == null)
            {
                throw new InvalidOperationException("Cannot find content on page.");
            }

            // Find the thread author
            HtmlNode titleBar = pageContent.GetDescendantWithClass("titleBar");

            // Non-thread pages (such as threadmark pages) won't have a title bar.
            if (titleBar == null)
            {
                throw new InvalidOperationException("Not a valid forum thread.");
            }

            var pageDesc = page.GetElementbyId("pageDescription");

            var authorNode = pageDesc?.GetChildWithClass("username");

            author = PostText.CleanupWebString(authorNode?.InnerText);

            // Find the number of pages in the thread
            var    pageNavLinkGroup = pageContent.GetDescendantWithClass("div", "pageNavLinkGroup");
            var    pageNav          = pageNavLinkGroup?.GetChildWithClass("PageNav");
            string lastPage         = pageNav?.GetAttributeValue("data-last", "");

            if (string.IsNullOrEmpty(lastPage))
            {
                pages = 1;
            }
            else
            {
                pages = Int32.Parse(lastPage);
            }

            // Create a ThreadInfo object to hold the acquired information.
            ThreadInfo info = new ThreadInfo(title, author, pages);

            return(info);
        }
Beispiel #11
0
    public void Post(PostText post)
    {
        GameObject postInstance = SpawnPost(textPostPototype);

        postInstance.transform.SetSiblingIndex(0);
        postInstance.transform.Find("ProfilePic").GetComponent <Image>().sprite = post.Author.ProfilePic;
        postInstance.transform.Find("Name").GetComponent <Text>().text          = post.Author.name;
        postInstance.transform.Find("Message").GetComponent <Text>().text       = post.Text;
    }
Beispiel #12
0
        /// <summary>
        /// Get thread info from the provided page.
        /// </summary>
        /// <param name="page">A web page from a forum that this adapter can handle.</param>
        /// <returns>Returns thread information that can be gleaned from that page.</returns>
        public ThreadInfo GetThreadInfo(HtmlDocument page)
        {
            if (page == null)
            {
                throw new ArgumentNullException(nameof(page));
            }

            string title;
            string author = string.Empty;
            int    pages  = 1;

            HtmlNode doc = page.DocumentNode.Element("html");

            // Find the page title
            title = PostText.CleanupWebString(doc.Element("head")?.Element("title")?.InnerText);

            // Find the number of pages
            var pagebody = page.GetElementbyId("page-body");

            if (pagebody != null)
            {
                // Different versions of the forum have different methods of showing page numbers

                var topicactions = pagebody.GetChildWithClass("topic-actions");
                if (topicactions != null)
                {
                    var    pagination     = topicactions.GetChildWithClass("pagination");
                    string paginationText = pagination?.InnerText;
                    if (paginationText != null)
                    {
                        Regex pageOf = new Regex(@"Page\s*\d+\s*of\s*(?<pages>\d+)");
                        Match m      = pageOf.Match(paginationText);
                        if (m.Success)
                        {
                            pages = int.Parse(m.Groups["pages"].Value);
                        }
                    }
                }
                else
                {
                    var actionbar  = pagebody.GetChildWithClass("action-bar");
                    var pagination = actionbar?.GetChildWithClass("pagination");

                    var ul           = pagination?.Element("ul");
                    var lastPageLink = ul?.Elements("li")?.LastOrDefault(n => !n.GetAttributeValue("class", "").Split(' ').Contains("next"));

                    if (lastPageLink != null)
                    {
                        pages = int.Parse(lastPageLink.InnerText);
                    }
                }
            }

            ThreadInfo info = new ThreadInfo(title, author, pages);

            return(info);
        }
Beispiel #13
0
        public async Task <IHttpActionResult> GetPostText(int id)
        {
            PostText postText = await db.PostTexts.FindAsync(id);

            if (postText == null)
            {
                return(NotFound());
            }

            return(Ok(postText));
        }
        public void Same_String_Should_Create_The_Same_Post_Text()
        {
            var text1 = PostText.Create("this is my text").Value;
            var text2 = PostText.Create("this is my text").Value;

            using (new AssertionScope())
            {
                text1.Should().Be(text2);
                text1.GetHashCode().Equals(text2.GetHashCode()).Should().BeTrue();
            }
        }
        public void Different_Strings_Should_Create_Different_Post_Texts()
        {
            var text1 = PostText.Create("this is my text").Value;
            var text2 = PostText.Create("this is my other text").Value;

            using (new AssertionScope())
            {
                text1.Should().NotBe(text2);
                text1.GetHashCode().Equals(text2.GetHashCode()).Should().BeFalse();
            }
        }
Beispiel #16
0
        public async Task <IHttpActionResult> PostPostText(PostText postText)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            db.PostTexts.Add(postText);
            await db.SaveChangesAsync();

            return(CreatedAtRoute("DefaultApi", new { id = postText.Id }, postText));
        }
Beispiel #17
0
        /// <summary>
        /// Get a completed post from the provided HTML div node.
        /// </summary>
        /// <param name="div">Div node that contains the post.</param>
        /// <returns>Returns a post object with required information.</returns>
        private PostComponents GetPost(HtmlNode div, IQuest quest)
        {
            if (div == null)
            {
                throw new ArgumentNullException(nameof(div));
            }

            string author = "";
            string id;
            string text;
            int    number = 0;

            // id="p12345"
            id = div.Id.Substring(1);


            var inner        = div.GetChildWithClass("div", "inner");
            var postbody     = inner.GetChildWithClass("div", "postbody");
            var authorNode   = postbody.GetChildWithClass("p", "author");
            var authorStrong = authorNode.Descendants("strong").FirstOrDefault();
            var authorAnchor = authorStrong.Element("a");

            author = PostText.CleanupWebString(authorAnchor.InnerText);

            // No way to get the post number??


            // Get the full post text.  Two different layout variants.
            var content = postbody.GetChildWithClass("div", "content");

            if (content == null)
            {
                content = postbody.Elements("div").FirstOrDefault(n => n.Id.StartsWith("post_content", StringComparison.Ordinal));
            }

            text = PostText.ExtractPostText(content, n => false, Host);


            PostComponents post;

            try
            {
                post = new PostComponents(author, id, text, number);
            }
            catch
            {
                post = null;
            }

            return(post);
        }
        private async void ChangeSuggestList()
        {
            if (!(PostText.Contains("@") || PostText.Contains("#")))
            {
                return;
            }
            ObservableCollection <string> resultSuggest = new ObservableCollection <string>();
            await Task.Run(() =>
            {
                int mIndex = PostText.LastIndexOf('@');
                int hIndex = PostText.LastIndexOf('#');

                if (mIndex > hIndex)
                {
                    var s       = PostText.Split('@');
                    string name = s[s.Count() - 1];

                    int i = 0;
                    foreach (var n in MentionSuggestSourceList.Where(q => q.StartsWith(name)).Select(q => q))
                    {
                        resultSuggest.Add("@" + n);
                        if (i > 10)
                        {
                            break;
                        }
                        i++;
                    }
                }
                else if (mIndex < hIndex)
                {
                    var s       = PostText.Split('#');
                    string name = s[s.Count() - 1];
                    int i       = 0;
                    foreach (var n in HashSuggestSourceList.Where(q => q.StartsWith(name)).Select(q => q))
                    {
                        resultSuggest.Add("#" + n);
                        if (i > 10)
                        {
                            break;
                        }
                        i++;
                    }
                }
            });

            SuggestList.Clear();
            foreach (var r in resultSuggest)
            {
                SuggestList.Add(r);
            }
        }
Beispiel #19
0
        public async Task <IHttpActionResult> DeletePostText(int id)
        {
            PostText postText = await db.PostTexts.FindAsync(id);

            if (postText == null)
            {
                return(NotFound());
            }

            db.PostTexts.Remove(postText);
            await db.SaveChangesAsync();

            return(Ok(postText));
        }
        public JsonResult Post(PostText postText)
        {
            TextToScroll text = new TextToScroll(postText.Text, postText.R, postText.G, postText.B, postText.Iterations);

            if (_scrollingText.IsScrolling)
            {
                _scrollingText.AddText(text);
            }
            else
            {
                _scrollingText.ScrollText(text);
            }
            return(new JsonResult(text.Text));
        }
Beispiel #21
0
    private void Update()
    {
        if (postImage != null)
        {
            feed.Post(postImage);
            postImage = null;
        }

        if (postText != null)
        {
            feed.Post(postText);
            postText = null;
        }
    }
Beispiel #22
0
        public async Task <Result <int> > Handle(EditPostCommand request, CancellationToken cancellationToken)
        {
            using (var tx = _session.BeginTransaction())
            {
                var editor = await _session.LoadAsync <User>(request.UserID, cancellationToken);

                var postToEdit = await _session.QueryOver <Post>()
                                 .Fetch(SelectMode.ChildFetch, p => p.Author)
                                 .Where(p => p.ID == request.PostID)
                                 .SingleOrDefaultAsync(cancellationToken);

                if (!postToEdit.CanBeEditedBy(editor))
                {
                    _logger.Warning("User [{NickName}({UserID})] tried to edit post {PostID} but he wasn't allowed to.",
                                    editor.Nickname,
                                    request.UserID,
                                    request.PostID);
                    return(Result.Failure <int>($"You're not allowed to edit post {postToEdit.ID}."));
                }

                postToEdit.UpdateText(PostText.Create(request.Text).Value);
                postToEdit.UpdatePicture(Picture.Create(request.PictureRawBytes, postToEdit.Picture.Identifier).Value);
                try
                {
                    await _session.SaveAsync(postToEdit, cancellationToken);

                    await tx.CommitAsync(cancellationToken);

                    _logger.Information("User [{Nickname}({UserID})] edited post {PostID}.",
                                        editor.Nickname,
                                        request.UserID,
                                        request.PostID);

                    return(Result.Success(postToEdit.ID));
                }
                catch (ADOException ex)
                {
                    await tx.RollbackAsync(cancellationToken);

                    _logger.Error("Failed to edit post {PostID} for user [{Nickname}({UserID})]. Error message: {ErrorMessage}",
                                  request.PostID,
                                  editor.Nickname,
                                  request.UserID,
                                  ex.Message);

                    return(Result.Failure <int>(ex.Message));
                }
            }
        }
Beispiel #23
0
        /// <summary>
        /// Parser for PostText
        /// </summary>
        /// <returns>Parsed PostText</returns>
        public PostText ParsePostText()
        {
            PostText postText = new PostText();

            //Skip > token
            NextToken(">", "> TextChar* \"", '>');

            //Parse text
            postText.SetText(ParseTextChars());

            //Skip " token
            NextToken("\"", "> TextChar* \"", '"');

            return(postText);
        }
Beispiel #24
0
 public void ShowActiveStatus()
 {
     if (ActiveStatus != null)
     {
         PostText.Text = "@" + ActiveStatus.User.ScreenName + " ";
         PostText.Select(PostText.Text.Length - 1, 0);
         var th = new System.Threading.Thread(new System.Threading.ThreadStart(() =>
         {
             Invoke(new Action(() =>
             {
                 ActiveStatusView.SmallImageList = new ImageList();
             }));
             string uri = ActiveStatus.User.ProfileImageLocation;
             using (WebClient wc = new WebClient())
             {
                 using (Stream stream = wc.OpenRead(uri))
                 {
                     Bitmap bitmap = new Bitmap(stream);
                     Invoke(new Action(() => ActiveStatusView.SmallImageList.Images.Add(ActiveStatus.User.ScreenName, bitmap)));
                 }
             }
             var i = new ListViewItem(new[] { ActiveStatus.User.ScreenName, ActiveStatus.Text }, ActiveStatus.User.ScreenName);
             Invoke(new Action(() =>
             {
                 ActiveStatusView.Items.Clear();
                 ActiveStatusView.Items.Add(i);
             }));
         }));
         th.Start();
     }
     else
     {
         new Task(() =>
         {
             Invoke(new Action(() =>
             {
                 ActiveStatusView.SmallImageList = new ImageList();
             }));
             var i = new ListViewItem(new[] { "null", "null" });
             Invoke(new Action(() =>
             {
                 ActiveStatusView.Items.Clear();
                 ActiveStatusView.Items.Add(i);
             }));
         }).Start();
     }
 }
Beispiel #25
0
        /// <summary>
        /// Parser for TextTail
        /// </summary>
        /// <returns>Parsed TextTail</returns>
        public TextTail ParseTextTail()
        {
            TextTail textTail = null;

            //Skip > token
            NextToken(">", "> embedding tailsymbol", '>');

            //Parse text first to make type determination possible
            String parsedText = ParseTextChars();

            //Determine TextTail type
            if (EmbeddingTokenStream.HasNext() && EmbeddingTokenStream.Peek(1).GetValue().ToString() == "\"")
            {   //PostTextTail
                //Set PostText
                PostText postText = new PostText();
                postText.SetText(parsedText);

                //Create PostTextTail and fill it
                PostTextTail postTextTail = new PostTextTail();
                postTextTail.SetPostText(postText);

                //Skip Closing "
                NextToken("\"", "\"", '\"');

                textTail = postTextTail;
            }
            else
            {   //MidTextTail
                //Skip closing < tag of PreText
                NextToken("<", "< closing PreText", '<');

                //Set MidText
                MidText midText = new MidText();
                midText.SetText(parsedText);

                //Create MidTextTail object and fill it
                MidTextTail midTextTail = new MidTextTail();
                midTextTail.SetMidText(midText);
                midTextTail.SetEmbed(ParseEmbed());
                midTextTail.SetTextTail(ParseTextTail());

                textTail = midTextTail;
            }

            return(textTail);
        }
Beispiel #26
0
 public JsonPostText(PostText text)
 {
     // Set...
     if (text != null)
     {
         Id       = text.Id;
         Type     = text.Type;
         Title    = text.Title;
         Number   = text.Number;
         Revision = text.Revision;
         //TODO: When inserting a new post, don't encode the text,
         //      not usefull since we're decoding it before send to the client.
         //      Vérifier que les données ne sont pas deja encodé quand elle sont reçut du client d'edition.
         Value  = WebUtility.HtmlDecode(text.Value);
         PostId = text.Post?.Id ?? 0;
     }
 }
Beispiel #27
0
        /// <summary>
        /// Get thread info from the provided page.
        /// </summary>
        /// <param name="page">A web page from a forum that this adapter can handle.</param>
        /// <returns>Returns thread information that can be gleaned from that page.</returns>
        public ThreadInfo GetThreadInfo(HtmlDocument page)
        {
            if (page == null)
            {
                throw new ArgumentNullException(nameof(page));
            }

            string title;
            string author = string.Empty; // vBulletin doesn't show thread authors
            int    pages  = 1;

            HtmlNode doc = page.DocumentNode;

            // Find the page title
            title = doc.Element("html").Element("head").Element("title")?.InnerText;
            title = PostText.CleanupWebString(title);

            // Get the number of pages from the navigation elements
            var paginationTop = page.GetElementbyId("pagination_top");

            var paginationForm = paginationTop.Element("form");

            // If there is no form, that means there's only one page in the thread.
            if (paginationForm != null)
            {
                var firstSpan  = paginationForm.Element("span");
                var firstSpanA = firstSpan?.Element("a");
                var pagesText  = firstSpanA?.InnerText;

                if (pagesText != null)
                {
                    Regex pageNumsRegex = new Regex(@"Page \d+ of (?<pages>\d+)");
                    Match m             = pageNumsRegex.Match(pagesText);
                    if (m.Success)
                    {
                        pages = int.Parse(m.Groups["pages"].Value);
                    }
                }
            }

            ThreadInfo info = new ThreadInfo(title, author, pages);

            return(info);
        }
Beispiel #28
0
        public PostDTO AddPost(IFormFile file, Post post)
        {
            CompletePostDTO completePost = new CompletePostDTO()
            {
                FileInPost = file,
                Post       = post
            };

            IPostHandler textPost  = new PostText(postRepository, unitOfWork);
            IPostHandler imagePost = new PostImage(postRepository, unitOfWork, cloudinary);
            IPostHandler videoPost = new PostVideo(postRepository, unitOfWork, cloudinary);

            textPost.SetNextPostType(imagePost);
            imagePost.SetNextPostType(videoPost);

            textPost.EvaluatePost(completePost);

            return(mapper.Map <PostDTO>(post));
        }
Beispiel #29
0
 private void PostText_KeyUp(object sender, KeyEventArgs e)
 {
     if (CommandHandled || Tweeted)
     {
         try
         {
             PostText.SelectionStart--;
             PostText.Text           = PostText.Text.Remove(PostText.SelectionStart, 1);
             PostText.Text           = PostText.Text.Replace("\n", "").Replace("\r", "");
             PostText.SelectionStart = PostText.Text.Length;
             PostText.Update();
         }
         catch
         {
         }
         finally
         {
             CommandHandled = Tweeted = false;
         }
     }
 }
Beispiel #30
0
        /// <summary>
        /// Get thread info from the provided page.
        /// </summary>
        /// <param name="page">A web page from a forum that this adapter can handle.</param>
        /// <returns>Returns thread information that can be gleaned from that page.</returns>
        public ThreadInfo GetThreadInfo(HtmlDocument page)
        {
            if (page == null)
            {
                throw new ArgumentNullException(nameof(page));
            }

            string title;
            string author = string.Empty; // vBulletin doesn't show thread authors
            int    pages  = 1;

            HtmlNode doc = page.DocumentNode.Element("html");

            // Find the page title
            title = PostText.CleanupWebString(doc.Element("head")?.Element("title")?.InnerText);

            // If there's no pagenav div, that means there's no navigation to alternate pages,
            // which means there's only one page in the thread.
            var pageNavDiv = doc.GetDescendantWithClass("div", "pagenav");

            if (pageNavDiv != null)
            {
                var vbMenuControl = pageNavDiv.GetDescendantWithClass("td", "vbmenu_control");

                if (vbMenuControl != null)
                {
                    Regex pageNumsRegex = new Regex(@"Page \d+ of (?<pages>\d+)");

                    Match m = pageNumsRegex.Match(vbMenuControl.InnerText);
                    if (m.Success)
                    {
                        pages = int.Parse(m.Groups["pages"].Value);
                    }
                }
            }

            ThreadInfo info = new ThreadInfo(title, author, pages);

            return(info);
        }
 private void SaveTextInDB(string directory, int GroupId)
 {
     var model = new PostText();
     model.GroupId = GroupId;
     model.Text = directory;
     ServiceStack.Data.IDbConnectionFactory dbFactory = new OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["db"].ConnectionString, MySqlDialect.Provider);
     using (IDbConnection db = dbFactory.Open())
     {
         db.Save<PostText>(model);
     }
 }