add pseudo protocol attachment://

This commit is contained in:
Egor Kovetskiy 2019-04-20 10:24:30 +03:00
parent 2abc2f122b
commit 51f28f8f06
5 changed files with 89 additions and 38 deletions

23
main.go
View File

@ -75,6 +75,7 @@ Options:
-k Lock page editing to current user only to prevent accidental -k Lock page editing to current user only to prevent accidental
manual edits over Confluence Web UI. manual edits over Confluence Web UI.
--dry-run Show resulting HTML and don't update Confluence page content. --dry-run Show resulting HTML and don't update Confluence page content.
--debug Enable debug logs.
--trace Enable trace logs. --trace Enable trace logs.
-h --help Show this screen and call 911. -h --help Show this screen and call 911.
-v --version Show version. -v --version Show version.
@ -85,7 +86,7 @@ var (
log *cog.Logger log *cog.Logger
) )
func initlog(trace bool) { func initlog(debug, trace bool) {
stderr := lorg.NewLog() stderr := lorg.NewLog()
stderr.SetIndentLines(true) stderr.SetIndentLines(true)
stderr.SetFormat( stderr.SetFormat(
@ -94,9 +95,16 @@ func initlog(trace bool) {
log = cog.NewLogger(stderr) log = cog.NewLogger(stderr)
if debug {
log.SetLevel(lorg.LevelDebug)
}
if trace { if trace {
log.SetLevel(lorg.LevelTrace) log.SetLevel(lorg.LevelTrace)
} }
mark.SetLogger(log)
confluence.SetLogger(log)
} }
func main() { func main() {
@ -109,10 +117,9 @@ func main() {
targetFile, _ = args["-f"].(string) targetFile, _ = args["-f"].(string)
dryRun = args["--dry-run"].(bool) dryRun = args["--dry-run"].(bool)
editLock = args["-k"].(bool) editLock = args["-k"].(bool)
trace = args["--trace"].(bool)
) )
initlog(trace) initlog(args["--debug"].(bool), args["--trace"].(bool))
config, err := getConfig(filepath.Join(os.Getenv("HOME"), ".config/mark")) config, err := getConfig(filepath.Join(os.Getenv("HOME"), ".config/mark"))
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
@ -129,10 +136,8 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
htmlData := mark.CompileMarkdown(markdownData)
if dryRun { if dryRun {
fmt.Println(string(htmlData)) fmt.Println(string(mark.CompileMarkdown(markdownData)))
os.Exit(0) os.Exit(0)
} }
@ -187,11 +192,15 @@ func main() {
target = page target = page
} }
err = mark.ResolveAttachments(api, target, ".", meta.Attachments) attaches, err := mark.ResolveAttachments(api, target, ".", meta.Attachments)
if err != nil { if err != nil {
log.Fatalf(err, "unable to create/update attachments") log.Fatalf(err, "unable to create/update attachments")
} }
markdownData = mark.CompileAttachmentLinks(markdownData, attaches)
htmlData := mark.CompileMarkdown(markdownData)
err = api.UpdatePage( err = api.UpdatePage(
target, target,
MacroLayout{meta.Layout, [][]byte{htmlData}}.Render(), MacroLayout{meta.Layout, [][]byte{htmlData}}.Render(),

View File

@ -239,9 +239,9 @@ func (api *API) UpdateAttachment(
return info, err return info, err
} }
//if request.Raw.StatusCode != 200 { if request.Raw.StatusCode != 200 {
return info, newErrorStatusNotOK(request) return info, newErrorStatusNotOK(request)
//} }
if len(result.Results) == 0 { if len(result.Results) == 0 {
return info, errors.New( return info, errors.New(

View File

@ -32,7 +32,7 @@ func EnsureAncestry(
break break
} }
log.Tracef(nil, "parent page %q exists: %s", title, page.Links.Full) log.Debugf(nil, "parent page %q exists: %s", title, page.Links.Full)
rest = ancestry[i:] rest = ancestry[i:]
parent = page parent = page

View File

@ -1,13 +1,14 @@
package mark package mark
import ( import (
"bytes"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"encoding/json"
"fmt"
"io" "io"
"net/url"
"os" "os"
"path/filepath" "path/filepath"
"sort"
"strings" "strings"
"github.com/kovetskiy/mark/pkg/confluence" "github.com/kovetskiy/mark/pkg/confluence"
@ -32,8 +33,8 @@ func ResolveAttachments(
page *confluence.PageInfo, page *confluence.PageInfo,
base string, base string,
names []string, names []string,
) error { ) ([]Attachment, error) {
attachs := []Attachment{} attaches := []Attachment{}
for _, name := range names { for _, name := range names {
attach := Attachment{ attach := Attachment{
Name: name, Name: name,
@ -43,7 +44,7 @@ func ResolveAttachments(
checksum, err := getChecksum(attach.Path) checksum, err := getChecksum(attach.Path)
if err != nil { if err != nil {
return karma.Format( return nil, karma.Format(
err, err,
"unable to get checksum for attachment: %q", attach.Name, "unable to get checksum for attachment: %q", attach.Name,
) )
@ -51,7 +52,7 @@ func ResolveAttachments(
attach.Checksum = checksum attach.Checksum = checksum
attachs = append(attachs, attach) attaches = append(attaches, attach)
} }
remotes, err := api.GetAttachments(page.ID) remotes, err := api.GetAttachments(page.ID)
@ -62,7 +63,7 @@ func ResolveAttachments(
existing := []Attachment{} existing := []Attachment{}
creating := []Attachment{} creating := []Attachment{}
updating := []Attachment{} updating := []Attachment{}
for _, attach := range attachs { for _, attach := range attaches {
var found bool var found bool
var same bool var same bool
for _, remote := range remotes { for _, remote := range remotes {
@ -92,21 +93,6 @@ func ResolveAttachments(
} }
} }
{
marshaledXXX, _ := json.MarshalIndent(existing, "", " ")
fmt.Printf("existing: %s\n", string(marshaledXXX))
}
{
marshaledXXX, _ := json.MarshalIndent(creating, "", " ")
fmt.Printf("creating: %s\n", string(marshaledXXX))
}
{
marshaledXXX, _ := json.MarshalIndent(updating, "", " ")
fmt.Printf("updating: %s\n", string(marshaledXXX))
}
for i, attach := range creating { for i, attach := range creating {
log.Infof(nil, "creating attachment: %q", attach.Name) log.Infof(nil, "creating attachment: %q", attach.Name)
@ -117,7 +103,7 @@ func ResolveAttachments(
attach.Path, attach.Path,
) )
if err != nil { if err != nil {
return karma.Format( return nil, karma.Format(
err, err,
"unable to create attachment %q", "unable to create attachment %q",
attach.Name, attach.Name,
@ -141,7 +127,7 @@ func ResolveAttachments(
attach.Path, attach.Path,
) )
if err != nil { if err != nil {
return karma.Format( return nil, karma.Format(
err, err,
"unable to update attachment %q", "unable to update attachment %q",
attach.Name, attach.Name,
@ -153,7 +139,53 @@ func ResolveAttachments(
updating[i] = attach updating[i] = attach
} }
return nil attaches = []Attachment{}
attaches = append(attaches, existing...)
attaches = append(attaches, creating...)
attaches = append(attaches, updating...)
return attaches, nil
}
func CompileAttachmentLinks(markdown []byte, attaches []Attachment) []byte {
links := map[string]string{}
names := []string{}
for _, attach := range attaches {
uri, err := url.ParseRequestURI(attach.Link)
if err != nil {
links[attach.Name] = strings.ReplaceAll("&", "&", attach.Link)
} else {
links[attach.Name] = uri.Path +
"?" + url.QueryEscape(uri.Query().Encode())
}
names = append(names, attach.Name)
}
// sort by length so first items will have bigger length
// it's helpful for replacing in case of following names
// attachments/a.jpg
// attachments/a.jpg.jpg
// so we replace longer and then shorter
sort.SliceStable(names, func(i, j int) bool {
return len(names[i]) > len(names[j])
})
for _, name := range names {
from := `attachment://` + name
to := links[name]
log.Debugf(nil, "replacing: %q -> %q", from, to)
markdown = bytes.ReplaceAll(
markdown,
[]byte(from),
[]byte(to),
)
}
return markdown
} }
func getChecksum(filename string) (string, error) { func getChecksum(filename string) (string, error) {

View File

@ -39,7 +39,11 @@ func (code MacroCode) Render() string {
// compileMarkdown will replace tags like <ac:rich-tech-body> with escaped // compileMarkdown will replace tags like <ac:rich-tech-body> with escaped
// equivalent, because blackfriday markdown parser replaces that tags with // equivalent, because blackfriday markdown parser replaces that tags with
// <a href="ac:rich-text-body">ac:rich-text-body</a> for whatever reason. // <a href="ac:rich-text-body">ac:rich-text-body</a> for whatever reason.
func CompileMarkdown(markdown []byte) []byte { func CompileMarkdown(
markdown []byte,
) []byte {
log.Tracef(nil, "rendering markdown:\n%s", string(markdown))
colon := regexp.MustCompile(`---BLACKFRIDAY-COLON---`) colon := regexp.MustCompile(`---BLACKFRIDAY-COLON---`)
tags := regexp.MustCompile(`<(/?\S+):(\S+)>`) tags := regexp.MustCompile(`<(/?\S+):(\S+)>`)
@ -68,15 +72,21 @@ func CompileMarkdown(markdown []byte) []byte {
blackfriday.EXTENSION_TABLES | blackfriday.EXTENSION_TABLES |
blackfriday.EXTENSION_FENCED_CODE | blackfriday.EXTENSION_FENCED_CODE |
blackfriday.EXTENSION_AUTOLINK | blackfriday.EXTENSION_AUTOLINK |
blackfriday.EXTENSION_LAX_HTML_BLOCKS |
blackfriday.EXTENSION_STRIKETHROUGH | blackfriday.EXTENSION_STRIKETHROUGH |
blackfriday.EXTENSION_SPACE_HEADERS | blackfriday.EXTENSION_SPACE_HEADERS |
blackfriday.EXTENSION_HEADER_IDS | blackfriday.EXTENSION_HEADER_IDS |
blackfriday.EXTENSION_AUTO_HEADER_IDS |
blackfriday.EXTENSION_TITLEBLOCK |
blackfriday.EXTENSION_BACKSLASH_LINE_BREAK | blackfriday.EXTENSION_BACKSLASH_LINE_BREAK |
blackfriday.EXTENSION_DEFINITION_LISTS, blackfriday.EXTENSION_DEFINITION_LISTS |
blackfriday.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK,
}, },
) )
html = colon.ReplaceAll(html, []byte(`:`)) html = colon.ReplaceAll(html, []byte(`:`))
log.Tracef(nil, "rendered markdown to html:\n%s", string(html))
return html return html
} }