diff options
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | main.go | 12 | ||||
-rw-r--r-- | parser.go | 39 | ||||
-rw-r--r-- | templates.go | 14 |
4 files changed, 60 insertions, 9 deletions
@@ -19,3 +19,7 @@ For HTML: `http://localhost:1212/nameOfGroup` For RSS: `http://localhost:1212/nameOfGroup.rss` `nameOfGroup` is the @-name in Facebook. + +## License + +MIT. See the LICENSE file.
\ No newline at end of file @@ -46,6 +46,12 @@ type post struct { Time time.Time Link string Content string + Images []*image // list of urls +} + +type image struct { + Source string + Caption string } func (p *post) String() string { @@ -61,6 +67,12 @@ func (p *post) String() string { // time format: Mon Jan 2 15:04:05 -0700 MST 2006 s = strings.Replace(template, "{{time}}", p.Time.Format("Mon, 2 Jan 2006 15:04:05 MST"), 2) s = strings.Replace(s, "{{content}}", p.Content, 1) + var imgs string + for i := range p.Images { + imgs += `<a href="` + p.Images[i].Source + `"><img src="` + p.Images[i].Source + `" title="` + p.Images[i].Caption + `"></a>` + } + s = strings.Replace(s, "{{images}}", imgs, 1) + return s } @@ -40,7 +40,6 @@ func parse(r io.Reader) (c *channel, err error) { if n.Type == html.ElementNode && n.Data == "div" { for _, a := range n.Attr { - //if a.Key == "class" && strings.Contains(a.Val, "text_exposed_root") { if a.Key == "class" && strings.Contains(a.Val, "userContentWrapper") { var p post parseNode(n, &p) @@ -62,8 +61,9 @@ func parse(r io.Reader) (c *channel, err error) { func parseNode(n *html.Node, p *post) { if n.Type == html.ElementNode { + switch n.Data { // fetch time stamp from header - if n.Data == "abbr" { + case "abbr": for _, attr := range n.Attr { if attr.Key == "data-utime" { unix, _ := strconv.ParseInt(attr.Val, 10, 64) @@ -71,13 +71,15 @@ func parseNode(n *html.Node, p *post) { return } } - } + // skip post header with name of group and check-in - if n.Data == "h5" { + case "h5": return - } + // skip "show more" and aria-hidden stuff - if n.Data == "span" { + case "span": + fallthrough + case "a": for _, attr := range n.Attr { if attr.Key == "class" && attr.Val == "text_exposed_hide" { return @@ -86,13 +88,17 @@ func parseNode(n *html.Node, p *post) { return } } - } // parse paragraphs - if n.Data == "p" { + case "p": parseParagraph(n, p) p.Content += "\n\n" return + + // get images + case "img": + parseImage(n, p) + return } } @@ -118,3 +124,20 @@ func parseParagraph(n *html.Node, p *post) { parseParagraph(c, p) } } + +func parseImage(n *html.Node, p *post) { + img := &image{} + for _, attr := range n.Attr { + switch attr.Key { + case "src": + img.Source = attr.Val + case "alt": + fallthrough + case "title": + fallthrough + case "aria-label": + img.Caption = attr.Val + } + } + p.Images = append(p.Images, img) +} diff --git a/templates.go b/templates.go index 0537f7c..e768c60 100644 --- a/templates.go +++ b/templates.go @@ -49,6 +49,17 @@ const htmlRoot = ` word-wrap: break-word; white-space: pre-line; } + div#images { + padding-left: 1em; + } + img { + max-height: 200px; + max-width: 200px; + height: auto; + width: auto; + border-radius: 12px; + padding: 0.2em; + } </style> </head> <body> @@ -63,7 +74,7 @@ const htmlRoot = ` </main> <hr> <footer> - <small>Generated by fbfeed · <a href="/{{name}}.rss">rss feed</a></small> + <small>Generated by <a href="https://git.vty.se/fbfeed.git/about/">fbfeed</a> · <a href="/{{name}}.rss">rss feed</a></small> </footer> </body> @@ -74,5 +85,6 @@ const htmlItem = ` <article> <datetime>{{time}}</datetime> <pre>{{content}}</pre> +<div id="images">{{images}}</div> </article> ` |