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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package classic
  2. import (
  3. "errors"
  4. "golang.org/x/net/html"
  5. "bytes"
  6. "github.com/terorie/youtube-mango/common"
  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 := common.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. println(p.v.Description)
  40. return nil
  41. }
  42. func parseLink(c *html.Node, dest *bytes.Buffer) error {
  43. // Find text
  44. if c.FirstChild == nil { return nil } // Empty link
  45. if c.FirstChild.Type != html.TextNode {
  46. return errors.New("unexpected non-text node")
  47. }
  48. text := c.FirstChild.Data
  49. // Find href
  50. for _, attr := range c.Attr {
  51. if attr.Key == "href" {
  52. switch {
  53. // hashtag
  54. case strings.HasPrefix(attr.Val, "/results"):
  55. dest.WriteString(text)
  56. // real link
  57. case strings.HasPrefix(attr.Val, "/redirect"):
  58. /*
  59. Not needed:
  60. // Decode link from href
  61. link, err := decodeLink(attr.Val)
  62. if err != nil { return err }
  63. // Escape to markdown
  64. link, err = common.MarkdownLinkEscape.ToString(link)
  65. if err != nil { return err }
  66. // Write to buffer
  67. dest.WriteString(fmt.Sprintf("[%s](%s)\n", text, link))
  68. */
  69. dest.WriteString(text)
  70. default:
  71. return errors.New("unknown link")
  72. }
  73. break
  74. }
  75. }
  76. return nil
  77. }
  78. /* Not needed
  79. func decodeLink(href string) (string, error) {
  80. url, err := url2.Parse(href)
  81. if err != nil { return "", err }
  82. query := url.Query()
  83. link := query.Get("q")
  84. if link == "" { return "", errors.New("empty link") }
  85. return link, nil
  86. }
  87. */