Skip to content

Commit

Permalink
Link hashtags to Reader when Chorus mode enabled
Browse files Browse the repository at this point in the history
instead of linking to posts only on a user's blog.

Ref T681
  • Loading branch information
thebaer committed Aug 7, 2019
1 parent 1a80cd3 commit 0c14d95
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 38 deletions.
8 changes: 4 additions & 4 deletions activitypub.go
Expand Up @@ -129,10 +129,10 @@ func handleFetchCollectionOutbox(app *App, w http.ResponseWriter, r *http.Reques
ocp := activitystreams.NewOrderedCollectionPage(accountRoot, "outbox", res.TotalPosts, p)
ocp.OrderedItems = []interface{}{}

posts, err := app.db.GetPosts(c, p, false, true, false)
posts, err := app.db.GetPosts(app.cfg, c, p, false, true, false)
for _, pp := range *posts {
pp.Collection = res
o := pp.ActivityObject()
o := pp.ActivityObject(app.cfg)
a := activitystreams.NewCreateActivity(o)
ocp.OrderedItems = append(ocp.OrderedItems, *a)
}
Expand Down Expand Up @@ -524,7 +524,7 @@ func deleteFederatedPost(app *App, p *PublicPost, collID int64) error {
}
p.Collection.hostName = app.cfg.App.Host
actor := p.Collection.PersonObject(collID)
na := p.ActivityObject()
na := p.ActivityObject(app.cfg)

// Add followers
p.Collection.ID = collID
Expand Down Expand Up @@ -570,7 +570,7 @@ func federatePost(app *App, p *PublicPost, collID int64, isUpdate bool) error {
}
}
actor := p.Collection.PersonObject(collID)
na := p.ActivityObject()
na := p.ActivityObject(app.cfg)

// Add followers
p.Collection.ID = collID
Expand Down
6 changes: 3 additions & 3 deletions app.go
Expand Up @@ -224,14 +224,14 @@ func handleViewHome(app *App, w http.ResponseWriter, r *http.Request) error {
log.Error("unable to get landing banner: %v", err)
return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not get banner: %v", err)}
}
p.Banner = template.HTML(applyMarkdown([]byte(banner.Content), ""))
p.Banner = template.HTML(applyMarkdown([]byte(banner.Content), "", app.cfg))

content, err := getLandingBody(app)
if err != nil {
log.Error("unable to get landing content: %v", err)
return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not get content: %v", err)}
}
p.Content = template.HTML(applyMarkdown([]byte(content.Content), ""))
p.Content = template.HTML(applyMarkdown([]byte(content.Content), "", app.cfg))

// Get error messages
session, err := app.sessionStore.Get(r, cookieName)
Expand Down Expand Up @@ -279,7 +279,7 @@ func handleTemplatedPage(app *App, w http.ResponseWriter, r *http.Request, t *te
return err
}
p.ContentTitle = c.Title.String
p.Content = template.HTML(applyMarkdown([]byte(c.Content), ""))
p.Content = template.HTML(applyMarkdown([]byte(c.Content), "", app.cfg))
p.PlainContent = shortPostDescription(stripmd.Strip(c.Content))
if !c.Updated.IsZero() {
p.Updated = c.Updated.Format("January 2, 2006")
Expand Down
6 changes: 3 additions & 3 deletions collections.go
Expand Up @@ -496,7 +496,7 @@ func fetchCollectionPosts(app *App, w http.ResponseWriter, r *http.Request) erro
}
}

posts, err := app.db.GetPosts(c, page, isCollOwner, false, false)
posts, err := app.db.GetPosts(app.cfg, c, page, isCollOwner, false, false)
if err != nil {
return err
}
Expand Down Expand Up @@ -730,7 +730,7 @@ func handleViewCollection(app *App, w http.ResponseWriter, r *http.Request) erro
return impart.HTTPError{http.StatusFound, redirURL}
}

coll.Posts, _ = app.db.GetPosts(c, page, cr.isCollOwner, false, false)
coll.Posts, _ = app.db.GetPosts(app.cfg, c, page, cr.isCollOwner, false, false)

// Serve collection
displayPage := CollectionPage{
Expand Down Expand Up @@ -825,7 +825,7 @@ func handleViewCollectionTag(app *App, w http.ResponseWriter, r *http.Request) e

coll := newDisplayCollection(c, cr, page)

coll.Posts, _ = app.db.GetPostsTagged(c, tag, page, cr.isCollOwner)
coll.Posts, _ = app.db.GetPostsTagged(app.cfg, c, tag, page, cr.isCollOwner)
if coll.Posts != nil && len(*coll.Posts) == 0 {
return ErrCollectionPageNotFound
}
Expand Down
13 changes: 7 additions & 6 deletions database.go
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/writeas/web-core/log"
"github.com/writeas/web-core/query"
"github.com/writeas/writefreely/author"
"github.com/writeas/writefreely/config"
"github.com/writeas/writefreely/key"
)

Expand Down Expand Up @@ -105,8 +106,8 @@ type writestore interface {
ClaimPosts(userID int64, collAlias string, posts *[]ClaimPostRequest) (*[]ClaimPostResult, error)

GetPostsCount(c *CollectionObj, includeFuture bool)
GetPosts(c *Collection, page int, includeFuture, forceRecentFirst, includePinned bool) (*[]PublicPost, error)
GetPostsTagged(c *Collection, tag string, page int, includeFuture bool) (*[]PublicPost, error)
GetPosts(cfg *config.Config, c *Collection, page int, includeFuture, forceRecentFirst, includePinned bool) (*[]PublicPost, error)
GetPostsTagged(cfg *config.Config, c *Collection, tag string, page int, includeFuture bool) (*[]PublicPost, error)

GetAPFollowers(c *Collection) (*[]RemoteUser, error)
GetAPActorKeys(collectionID int64) ([]byte, []byte)
Expand Down Expand Up @@ -1067,7 +1068,7 @@ func (db *datastore) GetPostsCount(c *CollectionObj, includeFuture bool) {
// It will return future posts if `includeFuture` is true.
// It will include only standard (non-pinned) posts unless `includePinned` is true.
// TODO: change includeFuture to isOwner, since that's how it's used
func (db *datastore) GetPosts(c *Collection, page int, includeFuture, forceRecentFirst, includePinned bool) (*[]PublicPost, error) {
func (db *datastore) GetPosts(cfg *config.Config, c *Collection, page int, includeFuture, forceRecentFirst, includePinned bool) (*[]PublicPost, error) {
collID := c.ID

cf := c.NewFormat()
Expand Down Expand Up @@ -1112,7 +1113,7 @@ func (db *datastore) GetPosts(c *Collection, page int, includeFuture, forceRecen
break
}
p.extractData()
p.formatContent(c, includeFuture)
p.formatContent(cfg, c, includeFuture)

posts = append(posts, p.processPost())
}
Expand All @@ -1128,7 +1129,7 @@ func (db *datastore) GetPosts(c *Collection, page int, includeFuture, forceRecen
// given tag.
// It will return future posts if `includeFuture` is true.
// TODO: change includeFuture to isOwner, since that's how it's used
func (db *datastore) GetPostsTagged(c *Collection, tag string, page int, includeFuture bool) (*[]PublicPost, error) {
func (db *datastore) GetPostsTagged(cfg *config.Config, c *Collection, tag string, page int, includeFuture bool) (*[]PublicPost, error) {
collID := c.ID

cf := c.NewFormat()
Expand Down Expand Up @@ -1176,7 +1177,7 @@ func (db *datastore) GetPostsTagged(c *Collection, tag string, page int, include
break
}
p.extractData()
p.formatContent(c, includeFuture)
p.formatContent(cfg, c, includeFuture)

posts = append(posts, p.processPost())
}
Expand Down
2 changes: 1 addition & 1 deletion export.go
Expand Up @@ -118,7 +118,7 @@ func compileFullExport(app *App, u *User) *ExportUser {
var collObjs []CollectionObj
for _, c := range *colls {
co := &CollectionObj{Collection: c}
co.Posts, err = app.db.GetPosts(&c, 0, true, false, true)
co.Posts, err = app.db.GetPosts(app.cfg, &c, 0, true, false, true)
if err != nil {
log.Error("unable to get collection posts: %v", err)
}
Expand Down
6 changes: 3 additions & 3 deletions feed.go
Expand Up @@ -55,9 +55,9 @@ func ViewFeed(app *App, w http.ResponseWriter, req *http.Request) error {

tag := mux.Vars(req)["tag"]
if tag != "" {
coll.Posts, _ = app.db.GetPostsTagged(c, tag, 1, false)
coll.Posts, _ = app.db.GetPostsTagged(app.cfg, c, tag, 1, false)
} else {
coll.Posts, _ = app.db.GetPosts(c, 1, false, true, false)
coll.Posts, _ = app.db.GetPosts(app.cfg, c, 1, false, true, false)
}

author := ""
Expand Down Expand Up @@ -94,7 +94,7 @@ func ViewFeed(app *App, w http.ResponseWriter, req *http.Request) error {
Title: title,
Link: &Link{Href: permalink},
Description: "<![CDATA[" + stripmd.Strip(p.Content) + "]]>",
Content: applyMarkdown([]byte(p.Content), ""),
Content: applyMarkdown([]byte(p.Content), "", app.cfg),
Author: &Author{author, ""},
Created: p.Created,
Updated: p.Updated,
Expand Down
23 changes: 14 additions & 9 deletions postrender.go
Expand Up @@ -16,6 +16,7 @@ import (
stripmd "github.com/writeas/go-strip-markdown"
"github.com/writeas/saturday"
"github.com/writeas/web-core/stringmanip"
"github.com/writeas/writefreely/config"
"github.com/writeas/writefreely/parse"
"html"
"html/template"
Expand All @@ -34,27 +35,27 @@ var (
markeddownReg = regexp.MustCompile("<p>(.+)</p>")
)

func (p *Post) formatContent(c *Collection, isOwner bool) {
func (p *Post) formatContent(cfg *config.Config, c *Collection, isOwner bool) {
baseURL := c.CanonicalURL()
if !isSingleUser {
baseURL = "/" + c.Alias + "/"
}
p.HTMLTitle = template.HTML(applyBasicMarkdown([]byte(p.Title.String)))
p.HTMLContent = template.HTML(applyMarkdown([]byte(p.Content), baseURL))
p.HTMLContent = template.HTML(applyMarkdown([]byte(p.Content), baseURL, cfg))
if exc := strings.Index(string(p.Content), "<!--more-->"); exc > -1 {
p.HTMLExcerpt = template.HTML(applyMarkdown([]byte(p.Content[:exc]), baseURL))
p.HTMLExcerpt = template.HTML(applyMarkdown([]byte(p.Content[:exc]), baseURL, cfg))
}
}

func (p *PublicPost) formatContent(isOwner bool) {
p.Post.formatContent(&p.Collection.Collection, isOwner)
func (p *PublicPost) formatContent(cfg *config.Config, isOwner bool) {
p.Post.formatContent(cfg, &p.Collection.Collection, isOwner)
}

func applyMarkdown(data []byte, baseURL string) string {
return applyMarkdownSpecial(data, false, baseURL)
func applyMarkdown(data []byte, baseURL string, cfg *config.Config) string {
return applyMarkdownSpecial(data, false, baseURL, cfg)
}

func applyMarkdownSpecial(data []byte, skipNoFollow bool, baseURL string) string {
func applyMarkdownSpecial(data []byte, skipNoFollow bool, baseURL string, cfg *config.Config) string {
mdExtensions := 0 |
blackfriday.EXTENSION_TABLES |
blackfriday.EXTENSION_FENCED_CODE |
Expand All @@ -74,7 +75,11 @@ func applyMarkdownSpecial(data []byte, skipNoFollow bool, baseURL string) string
md := blackfriday.Markdown([]byte(data), blackfriday.HtmlRenderer(htmlFlags, "", ""), mdExtensions)
if baseURL != "" {
// Replace special text generated by Markdown parser
md = []byte(hashtagReg.ReplaceAll(md, []byte("<a href=\""+baseURL+"tag:$1\" class=\"hashtag\"><span>#</span><span class=\"p-category\">$1</span></a>")))
tagPrefix := baseURL + "tag:"
if cfg.App.Chorus {
tagPrefix = "/read/t/"
}
md = []byte(hashtagReg.ReplaceAll(md, []byte("<a href=\""+tagPrefix+"$1\" class=\"hashtag\"><span>#</span><span class=\"p-category\">$1</span></a>")))
}
// Strip out bad HTML
policy := getSanitizationPolicy()
Expand Down
13 changes: 7 additions & 6 deletions posts.go
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/writeas/web-core/i18n"
"github.com/writeas/web-core/log"
"github.com/writeas/web-core/tags"
"github.com/writeas/writefreely/config"
"github.com/writeas/writefreely/page"
"github.com/writeas/writefreely/parse"
)
Expand Down Expand Up @@ -376,7 +377,7 @@ func handleViewPost(app *App, w http.ResponseWriter, r *http.Request) error {
Direction: d,
}
if !isRaw {
post.HTMLContent = template.HTML(applyMarkdown([]byte(content), ""))
post.HTMLContent = template.HTML(applyMarkdown([]byte(content), "", app.cfg))
}
}

Expand Down Expand Up @@ -1032,7 +1033,7 @@ func fetchPost(app *App, w http.ResponseWriter, r *http.Request) error {
}

p.Collection = &CollectionObj{Collection: *coll}
po := p.ActivityObject()
po := p.ActivityObject(app.cfg)
po.Context = []interface{}{activitystreams.Namespace}
return impart.RenderActivityJSON(w, po, http.StatusOK)
}
Expand Down Expand Up @@ -1067,7 +1068,7 @@ func (p *PublicPost) CanonicalURL() string {
return p.Collection.CanonicalURL() + p.Slug.String
}

func (p *PublicPost) ActivityObject() *activitystreams.Object {
func (p *PublicPost) ActivityObject(cfg *config.Config) *activitystreams.Object {
o := activitystreams.NewArticleObject()
o.ID = p.Collection.FederatedAPIBase() + "api/posts/" + p.ID
o.Published = p.Created
Expand All @@ -1078,7 +1079,7 @@ func (p *PublicPost) ActivityObject() *activitystreams.Object {
}
o.Name = p.DisplayTitle()
if p.HTMLContent == template.HTML("") {
p.formatContent(false)
p.formatContent(cfg, false)
}
o.Content = string(p.HTMLContent)
if p.Language.Valid {
Expand Down Expand Up @@ -1330,14 +1331,14 @@ func viewCollectionPost(app *App, w http.ResponseWriter, r *http.Request) error
fmt.Fprint(w, p.Content)
} else if strings.Contains(r.Header.Get("Accept"), "application/activity+json") {
p.extractData()
ap := p.ActivityObject()
ap := p.ActivityObject(app.cfg)
ap.Context = []interface{}{activitystreams.Namespace}
return impart.RenderActivityJSON(w, ap, http.StatusOK)
} else {
p.extractData()
p.Content = strings.Replace(p.Content, "<!--more-->", "", 1)
// TODO: move this to function
p.formatContent(cr.isCollOwner)
p.formatContent(app.cfg, cr.isCollOwner)
tp := struct {
*PublicPost
page.StaticPage
Expand Down
4 changes: 2 additions & 2 deletions read.go
Expand Up @@ -100,7 +100,7 @@ func (app *App) FetchPublicPosts() (interface{}, error) {
}

p.extractData()
p.HTMLContent = template.HTML(applyMarkdown([]byte(p.Content), ""))
p.HTMLContent = template.HTML(applyMarkdown([]byte(p.Content), "", app.cfg))
fp := p.processPost()
if isCollectionPost {
fp.Collection = &CollectionObj{Collection: *c}
Expand Down Expand Up @@ -295,7 +295,7 @@ func viewLocalTimelineFeed(app *App, w http.ResponseWriter, req *http.Request) e
Title: title,
Link: &Link{Href: permalink},
Description: "<![CDATA[" + stripmd.Strip(p.Content) + "]]>",
Content: applyMarkdown([]byte(p.Content), ""),
Content: applyMarkdown([]byte(p.Content), "", app.cfg),
Author: &Author{author, ""},
Created: p.Created,
Updated: p.Updated,
Expand Down
2 changes: 1 addition & 1 deletion sitemap.go
Expand Up @@ -66,7 +66,7 @@ func handleViewSitemap(app *App, w http.ResponseWriter, r *http.Request) error {
host = c.CanonicalURL()

sm := buildSitemap(host, pre)
posts, err := app.db.GetPosts(c, 0, false, false, false)
posts, err := app.db.GetPosts(app.cfg, c, 0, false, false, false)
if err != nil {
log.Error("Error getting posts: %v", err)
return err
Expand Down

0 comments on commit 0c14d95

Please sign in to comment.