You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

parsedescription.go 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package apiclassic
  2. import (
  3. "errors"
  4. "golang.org/x/net/html"
  5. "bytes"
  6. "github.com/terorie/yt-mango/net"
  7. "strings"
  8. )
  9. const descriptionSelector = "#eow-description"
  10. func (p *parseInfo) parseDescription() error {
  11. // Find description root
  12. descNode := p.doc.Find(descriptionSelector).First()
  13. if len(descNode.Nodes) == 0 { return errors.New("could not find description") }
  14. // Markdown text
  15. var buffer bytes.Buffer
  16. // Enumerate nodes
  17. for c := descNode.Nodes[0].FirstChild; c != nil; c = c.NextSibling {
  18. switch c.Type {
  19. case html.TextNode:
  20. // FIXME: "&amp;lt;" gets parsed to => "<"
  21. // Write text to buffer, escaping markdown
  22. err := net.MarkdownTextEscape.ToBuffer(c.Data, &buffer)
  23. if err != nil { return err }
  24. case html.ElementNode:
  25. switch c.Data {
  26. // Newline
  27. case "br":
  28. err := buffer.WriteByte(0x0a)
  29. if err != nil { return err }
  30. // Link
  31. case "a":
  32. err := parseLink(c, &buffer)
  33. if err != nil { return err }
  34. }
  35. }
  36. }
  37. // Save description
  38. p.v.Description = buffer.String()
  39. return nil
  40. }
  41. func parseLink(c *html.Node, dest *bytes.Buffer) error {
  42. // Find text
  43. if c.FirstChild == nil { return nil } // Empty link
  44. if c.FirstChild.Type != html.TextNode {
  45. return errors.New("unexpected non-text node")
  46. }
  47. text := c.FirstChild.Data
  48. // Find href
  49. for _, attr := range c.Attr {
  50. if attr.Key == "href" {
  51. switch {
  52. // hashtag
  53. case strings.HasPrefix(attr.Val, "/results"):
  54. dest.WriteString(text)
  55. // real link
  56. case strings.HasPrefix(attr.Val, "/redirect"):
  57. /*
  58. Not needed:
  59. // Decode link from href
  60. link, err := decodeLink(attr.Val)
  61. if err != nil { return err }
  62. // Escape to markdown
  63. link, err = net.MarkdownLinkEscape.ToString(link)
  64. if err != nil { return err }
  65. // Write to buffer
  66. dest.WriteString(fmt.Sprintf("[%s](%s)\n", text, link))
  67. */
  68. dest.WriteString(text)
  69. default:
  70. return errors.New("unknown link")
  71. }
  72. break
  73. }
  74. }
  75. return nil
  76. }
  77. /* Not needed
  78. func decodeLink(href string) (string, error) {
  79. url, err := url2.Parse(href)
  80. if err != nil { return "", err }
  81. query := url.Query()
  82. link := query.Get("q")
  83. if link == "" { return "", errors.New("empty link") }
  84. return link, nil
  85. }
  86. */