mirror of
				https://github.com/kovetskiy/mark.git
				synced 2025-10-31 03:37:35 +08:00 
			
		
		
		
	separate mark into packages
This commit is contained in:
		
							parent
							
								
									e27dd44bfa
								
							
						
					
					
						commit
						ada6f828ff
					
				
							
								
								
									
										174
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										174
									
								
								main.go
									
									
									
									
									
								
							| @ -11,8 +11,10 @@ import ( | |||||||
| 	"github.com/BurntSushi/toml" | 	"github.com/BurntSushi/toml" | ||||||
| 	"github.com/kovetskiy/godocs" | 	"github.com/kovetskiy/godocs" | ||||||
| 	"github.com/kovetskiy/lorg" | 	"github.com/kovetskiy/lorg" | ||||||
|  | 	"github.com/kovetskiy/mark/pkg/confluence" | ||||||
|  | 	"github.com/kovetskiy/mark/pkg/mark" | ||||||
| 	"github.com/reconquest/colorgful" | 	"github.com/reconquest/colorgful" | ||||||
| 	"github.com/reconquest/ser-go" | 	"github.com/reconquest/karma-go" | ||||||
| 	"github.com/russross/blackfriday" | 	"github.com/russross/blackfriday" | ||||||
| 	"github.com/zazab/zhash" | 	"github.com/zazab/zhash" | ||||||
| ) | ) | ||||||
| @ -87,24 +89,6 @@ Options: | |||||||
| ` | ` | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type PageInfo struct { |  | ||||||
| 	ID    string `json:"id"` |  | ||||||
| 	Title string `json:"title"` |  | ||||||
| 
 |  | ||||||
| 	Version struct { |  | ||||||
| 		Number int64 `json:"number"` |  | ||||||
| 	} `json:"version"` |  | ||||||
| 
 |  | ||||||
| 	Ancestors []struct { |  | ||||||
| 		Id    string `json:"id"` |  | ||||||
| 		Title string `json:"title"` |  | ||||||
| 	} `json:"ancestors"` |  | ||||||
| 
 |  | ||||||
| 	Links struct { |  | ||||||
| 		Full string `json:"webui"` |  | ||||||
| 	} `json:"_links"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var ( | var ( | ||||||
| 	logger = lorg.NewLog() | 	logger = lorg.NewLog() | ||||||
| ) | ) | ||||||
| @ -151,7 +135,7 @@ func main() { | |||||||
| 		logger.Fatal(err) | 		logger.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	meta, err := extractMeta(markdownData) | 	meta, err := mark.ExtractMeta(markdownData) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		logger.Fatal(err) | 		logger.Fatal(err) | ||||||
| 	} | 	} | ||||||
| @ -168,7 +152,7 @@ func main() { | |||||||
| 		logger.Fatal(err) | 		logger.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	api := NewAPI(creds.BaseURL, creds.Username, creds.Password) | 	api := confluence.NewAPI(creds.BaseURL, creds.Username, creds.Password) | ||||||
| 
 | 
 | ||||||
| 	if creds.PageID != "" && meta != nil { | 	if creds.PageID != "" && meta != nil { | ||||||
| 		logger.Warningf( | 		logger.Warningf( | ||||||
| @ -187,7 +171,7 @@ func main() { | |||||||
| 		) | 		) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var target *PageInfo | 	var target *confluence.PageInfo | ||||||
| 
 | 
 | ||||||
| 	if meta != nil { | 	if meta != nil { | ||||||
| 		page, err := resolvePage(api, meta) | 		page, err := resolvePage(api, meta) | ||||||
| @ -201,7 +185,7 @@ func main() { | |||||||
| 			logger.Fatalf("URL should provide 'pageId' GET-parameter") | 			logger.Fatalf("URL should provide 'pageId' GET-parameter") | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		page, err := api.getPageByID(creds.PageID) | 		page, err := api.GetPageByID(creds.PageID) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			logger.Fatal(err) | 			logger.Fatal(err) | ||||||
| 		} | 		} | ||||||
| @ -209,7 +193,7 @@ func main() { | |||||||
| 		target = page | 		target = page | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = api.updatePage( | 	err = api.UpdatePage( | ||||||
| 		target, | 		target, | ||||||
| 		MacroLayout{meta.Layout, [][]byte{htmlData}}.Render(), | 		MacroLayout{meta.Layout, [][]byte{htmlData}}.Render(), | ||||||
| 	) | 	) | ||||||
| @ -224,9 +208,13 @@ func main() { | |||||||
| 			creds.Username, | 			creds.Username, | ||||||
| 		) | 		) | ||||||
| 
 | 
 | ||||||
| 		err := api.setPagePermissions(target, RestrictionEdit, []Restriction{ | 		err := api.SetPagePermissions( | ||||||
| 			{User: creds.Username}, | 			target, | ||||||
| 		}) | 			confluence.RestrictionEdit, | ||||||
|  | 			[]confluence.Restriction{ | ||||||
|  | 				{User: creds.Username}, | ||||||
|  | 			}, | ||||||
|  | 		) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			logger.Fatal(err) | 			logger.Fatal(err) | ||||||
| 		} | 		} | ||||||
| @ -284,10 +272,13 @@ func compileMarkdown(markdown []byte) []byte { | |||||||
| 	return html | 	return html | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func resolvePage(api *API, meta *Meta) (*PageInfo, error) { | func resolvePage( | ||||||
| 	page, err := api.findPage(meta.Space, meta.Title) | 	api *confluence.API, | ||||||
|  | 	meta *mark.Meta, | ||||||
|  | ) (*confluence.PageInfo, error) { | ||||||
|  | 	page, err := api.FindPage(meta.Space, meta.Title) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, ser.Errorf( | 		return nil, karma.Format( | ||||||
| 			err, | 			err, | ||||||
| 			"error during finding page '%s': %s", | 			"error during finding page '%s': %s", | ||||||
| 			meta.Title, | 			meta.Title, | ||||||
| @ -300,7 +291,7 @@ func resolvePage(api *API, meta *Meta) (*PageInfo, error) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if len(ancestry) > 0 { | 	if len(ancestry) > 0 { | ||||||
| 		page, err := validateAncestry( | 		page, err := mark.ValidateAncestry( | ||||||
| 			api, | 			api, | ||||||
| 			meta.Space, | 			meta.Space, | ||||||
| 			ancestry, | 			ancestry, | ||||||
| @ -325,13 +316,13 @@ func resolvePage(api *API, meta *Meta) (*PageInfo, error) { | |||||||
| 		) | 		) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	parent, err := ensureAncestry( | 	parent, err := mark.EnsureAncestry( | ||||||
| 		api, | 		api, | ||||||
| 		meta.Space, | 		meta.Space, | ||||||
| 		meta.Parents, | 		meta.Parents, | ||||||
| 	) | 	) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, ser.Errorf( | 		return nil, karma.Format( | ||||||
| 			err, | 			err, | ||||||
| 			"can't create ancestry tree: %s; error: %s", | 			"can't create ancestry tree: %s; error: %s", | ||||||
| 			strings.Join(meta.Parents, ` > `), | 			strings.Join(meta.Parents, ` > `), | ||||||
| @ -352,9 +343,9 @@ func resolvePage(api *API, meta *Meta) (*PageInfo, error) { | |||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	if page == nil { | 	if page == nil { | ||||||
| 		page, err := api.createPage(meta.Space, parent, meta.Title, ``) | 		page, err := api.CreatePage(meta.Space, parent, meta.Title, ``) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, ser.Errorf( | 			return nil, karma.Format( | ||||||
| 				err, | 				err, | ||||||
| 				"can't create page '%s': %s", | 				"can't create page '%s': %s", | ||||||
| 				meta.Title, | 				meta.Title, | ||||||
| @ -367,117 +358,6 @@ func resolvePage(api *API, meta *Meta) (*PageInfo, error) { | |||||||
| 	return page, nil | 	return page, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func ensureAncestry( |  | ||||||
| 	api *API, |  | ||||||
| 	space string, |  | ||||||
| 	ancestry []string, |  | ||||||
| ) (*PageInfo, error) { |  | ||||||
| 	var parent *PageInfo |  | ||||||
| 
 |  | ||||||
| 	rest := ancestry |  | ||||||
| 
 |  | ||||||
| 	for i, title := range ancestry { |  | ||||||
| 		page, err := api.findPage(space, title) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, ser.Errorf( |  | ||||||
| 				err, |  | ||||||
| 				`error during finding parent page with title '%s': %s`, |  | ||||||
| 				title, |  | ||||||
| 			) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if page == nil { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		logger.Tracef("parent page '%s' exists: %s", title, page.Links.Full) |  | ||||||
| 
 |  | ||||||
| 		rest = ancestry[i:] |  | ||||||
| 		parent = page |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if parent != nil { |  | ||||||
| 		rest = rest[1:] |  | ||||||
| 	} else { |  | ||||||
| 		page, err := api.findRootPage(space) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, ser.Errorf( |  | ||||||
| 				err, |  | ||||||
| 				"can't find root page for space '%s': %s", space, |  | ||||||
| 			) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		parent = page |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if len(rest) == 0 { |  | ||||||
| 		return parent, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	logger.Debugf( |  | ||||||
| 		"empty pages under '%s' to be created: %s", |  | ||||||
| 		parent.Title, |  | ||||||
| 		strings.Join(rest, ` > `), |  | ||||||
| 	) |  | ||||||
| 
 |  | ||||||
| 	for _, title := range rest { |  | ||||||
| 		page, err := api.createPage(space, parent, title, ``) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, ser.Errorf( |  | ||||||
| 				err, |  | ||||||
| 				`error during creating parent page with title '%s': %s`, |  | ||||||
| 				title, |  | ||||||
| 			) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		parent = page |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return parent, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func validateAncestry( |  | ||||||
| 	api *API, |  | ||||||
| 	space string, |  | ||||||
| 	ancestry []string, |  | ||||||
| ) (*PageInfo, error) { |  | ||||||
| 	page, err := api.findPage(space, ancestry[len(ancestry)-1]) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if page == nil { |  | ||||||
| 		return nil, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if len(page.Ancestors) < 1 { |  | ||||||
| 		return nil, fmt.Errorf(`page '%s' has no parents`, page.Title) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if len(page.Ancestors) < len(ancestry) { |  | ||||||
| 		return nil, fmt.Errorf( |  | ||||||
| 			"page '%s' has fewer parents than specified: %s", |  | ||||||
| 			page.Title, |  | ||||||
| 			strings.Join(ancestry, ` > `), |  | ||||||
| 		) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// skipping root article title |  | ||||||
| 	for i, ancestor := range page.Ancestors[1:len(ancestry)] { |  | ||||||
| 		if ancestor.Title != ancestry[i] { |  | ||||||
| 			return nil, fmt.Errorf( |  | ||||||
| 				"broken ancestry tree; expected tree: %s; "+ |  | ||||||
| 					"encountered '%s' at position of '%s'", |  | ||||||
| 				strings.Join(ancestry, ` > `), |  | ||||||
| 				ancestor.Title, |  | ||||||
| 				ancestry[i], |  | ||||||
| 			) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return page, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func getConfig(path string) (zhash.Hash, error) { | func getConfig(path string) (zhash.Hash, error) { | ||||||
| 	configData := map[string]interface{}{} | 	configData := map[string]interface{}{} | ||||||
| 	_, err := toml.DecodeFile(path, &configData) | 	_, err := toml.DecodeFile(path, &configData) | ||||||
| @ -486,7 +366,7 @@ func getConfig(path string) (zhash.Hash, error) { | |||||||
| 			return zhash.NewHash(), err | 			return zhash.NewHash(), err | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return zhash.NewHash(), ser.Errorf( | 		return zhash.NewHash(), karma.Format( | ||||||
| 			err, | 			err, | ||||||
| 			"can't decode toml file: %s", | 			"can't decode toml file: %s", | ||||||
| 		) | 		) | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| package main | package confluence | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| @ -27,6 +27,24 @@ type API struct { | |||||||
| 	json *gopencils.Resource | 	json *gopencils.Resource | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type PageInfo struct { | ||||||
|  | 	ID    string `json:"id"` | ||||||
|  | 	Title string `json:"title"` | ||||||
|  | 
 | ||||||
|  | 	Version struct { | ||||||
|  | 		Number int64 `json:"number"` | ||||||
|  | 	} `json:"version"` | ||||||
|  | 
 | ||||||
|  | 	Ancestors []struct { | ||||||
|  | 		Id    string `json:"id"` | ||||||
|  | 		Title string `json:"title"` | ||||||
|  | 	} `json:"ancestors"` | ||||||
|  | 
 | ||||||
|  | 	Links struct { | ||||||
|  | 		Full string `json:"webui"` | ||||||
|  | 	} `json:"_links"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func NewAPI(baseURL string, username string, password string) *API { | func NewAPI(baseURL string, username string, password string) *API { | ||||||
| 	auth := &gopencils.BasicAuth{username, password} | 	auth := &gopencils.BasicAuth{username, password} | ||||||
| 
 | 
 | ||||||
| @ -40,8 +58,8 @@ func NewAPI(baseURL string, username string, password string) *API { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (api *API) findRootPage(space string) (*PageInfo, error) { | func (api *API) FindRootPage(space string) (*PageInfo, error) { | ||||||
| 	page, err := api.findPage(space, ``) | 	page, err := api.FindPage(space, ``) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, fmt.Errorf( | 		return nil, fmt.Errorf( | ||||||
| 			`can't obtain first page from space '%s': %s`, | 			`can't obtain first page from space '%s': %s`, | ||||||
| @ -64,8 +82,7 @@ func (api *API) findRootPage(space string) (*PageInfo, error) { | |||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (api *API) findPage(space string, title string) (*PageInfo, error) { | func (api *API) FindPage(space string, title string) (*PageInfo, error) { | ||||||
| 
 |  | ||||||
| 	result := struct { | 	result := struct { | ||||||
| 		Results []PageInfo `json:"results"` | 		Results []PageInfo `json:"results"` | ||||||
| 	}{} | 	}{} | ||||||
| @ -105,8 +122,7 @@ func (api *API) findPage(space string, title string) (*PageInfo, error) { | |||||||
| 	return &result.Results[0], nil | 	return &result.Results[0], nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (api *API) getPageByID(pageID string) (*PageInfo, error) { | func (api *API) GetPageByID(pageID string) (*PageInfo, error) { | ||||||
| 
 |  | ||||||
| 	request, err := api.rest.Res( | 	request, err := api.rest.Res( | ||||||
| 		"content/"+pageID, &PageInfo{}, | 		"content/"+pageID, &PageInfo{}, | ||||||
| 	).Get(map[string]string{"expand": "ancestors,version"}) | 	).Get(map[string]string{"expand": "ancestors,version"}) | ||||||
| @ -136,7 +152,7 @@ func (api *API) getPageByID(pageID string) (*PageInfo, error) { | |||||||
| 	return request.Response.(*PageInfo), nil | 	return request.Response.(*PageInfo), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (api *API) createPage( | func (api *API) CreatePage( | ||||||
| 	space string, | 	space string, | ||||||
| 	parent *PageInfo, | 	parent *PageInfo, | ||||||
| 	title string, | 	title string, | ||||||
| @ -183,7 +199,7 @@ func (api *API) createPage( | |||||||
| 	return request.Response.(*PageInfo), nil | 	return request.Response.(*PageInfo), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (api *API) updatePage( | func (api *API) UpdatePage( | ||||||
| 	page *PageInfo, newContent string, | 	page *PageInfo, newContent string, | ||||||
| ) error { | ) error { | ||||||
| 	nextPageVersion := page.Version.Number + 1 | 	nextPageVersion := page.Version.Number + 1 | ||||||
| @ -238,7 +254,7 @@ func (api *API) updatePage( | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (api *API) setPagePermissions( | func (api *API) SetPagePermissions( | ||||||
| 	page *PageInfo, | 	page *PageInfo, | ||||||
| 	operation RestrictionOperation, | 	operation RestrictionOperation, | ||||||
| 	restrictions []Restriction, | 	restrictions []Restriction, | ||||||
							
								
								
									
										120
									
								
								pkg/mark/ancestry.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								pkg/mark/ancestry.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,120 @@ | |||||||
|  | package mark | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/kovetskiy/mark/pkg/confluence" | ||||||
|  | 	"github.com/reconquest/karma-go" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func EnsureAncestry( | ||||||
|  | 	api *confluence.API, | ||||||
|  | 	space string, | ||||||
|  | 	ancestry []string, | ||||||
|  | ) (*confluence.PageInfo, error) { | ||||||
|  | 	var parent *confluence.PageInfo | ||||||
|  | 
 | ||||||
|  | 	rest := ancestry | ||||||
|  | 
 | ||||||
|  | 	for i, title := range ancestry { | ||||||
|  | 		page, err := api.FindPage(space, title) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, karma.Format( | ||||||
|  | 				err, | ||||||
|  | 				`error during finding parent page with title '%s': %s`, | ||||||
|  | 				title, | ||||||
|  | 			) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if page == nil { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		logger.Tracef("parent page '%s' exists: %s", title, page.Links.Full) | ||||||
|  | 
 | ||||||
|  | 		rest = ancestry[i:] | ||||||
|  | 		parent = page | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if parent != nil { | ||||||
|  | 		rest = rest[1:] | ||||||
|  | 	} else { | ||||||
|  | 		page, err := api.FindRootPage(space) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, karma.Format( | ||||||
|  | 				err, | ||||||
|  | 				"can't find root page for space '%s': %s", space, | ||||||
|  | 			) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		parent = page | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if len(rest) == 0 { | ||||||
|  | 		return parent, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	logger.Debugf( | ||||||
|  | 		"empty pages under '%s' to be created: %s", | ||||||
|  | 		parent.Title, | ||||||
|  | 		strings.Join(rest, ` > `), | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	for _, title := range rest { | ||||||
|  | 		page, err := api.CreatePage(space, parent, title, ``) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, karma.Format( | ||||||
|  | 				err, | ||||||
|  | 				`error during creating parent page with title '%s': %s`, | ||||||
|  | 				title, | ||||||
|  | 			) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		parent = page | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return parent, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func ValidateAncestry( | ||||||
|  | 	api *confluence.API, | ||||||
|  | 	space string, | ||||||
|  | 	ancestry []string, | ||||||
|  | ) (*confluence.PageInfo, error) { | ||||||
|  | 	page, err := api.FindPage(space, ancestry[len(ancestry)-1]) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if page == nil { | ||||||
|  | 		return nil, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if len(page.Ancestors) < 1 { | ||||||
|  | 		return nil, fmt.Errorf(`page '%s' has no parents`, page.Title) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if len(page.Ancestors) < len(ancestry) { | ||||||
|  | 		return nil, fmt.Errorf( | ||||||
|  | 			"page '%s' has fewer parents than specified: %s", | ||||||
|  | 			page.Title, | ||||||
|  | 			strings.Join(ancestry, ` > `), | ||||||
|  | 		) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// skipping root article title | ||||||
|  | 	for i, ancestor := range page.Ancestors[1:len(ancestry)] { | ||||||
|  | 		if ancestor.Title != ancestry[i] { | ||||||
|  | 			return nil, fmt.Errorf( | ||||||
|  | 				"broken ancestry tree; expected tree: %s; "+ | ||||||
|  | 					"encountered '%s' at position of '%s'", | ||||||
|  | 				strings.Join(ancestry, ` > `), | ||||||
|  | 				ancestor.Title, | ||||||
|  | 				ancestry[i], | ||||||
|  | 			) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return page, nil | ||||||
|  | } | ||||||
							
								
								
									
										90
									
								
								pkg/mark/mark.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								pkg/mark/mark.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | |||||||
|  | package mark | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/kovetskiy/lorg" | ||||||
|  | 	"github.com/kovetskiy/mark/pkg/confluence" | ||||||
|  | 	"github.com/reconquest/karma-go" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	logger lorg.Logger = lorg.NewDiscarder() | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func SetLogger(log lorg.Logger) { | ||||||
|  | 	logger = log | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func ResolvePage( | ||||||
|  | 	api *confluence.API, | ||||||
|  | 	meta *Meta, | ||||||
|  | ) (*confluence.PageInfo, error) { | ||||||
|  | 	page, err := api.FindPage(meta.Space, meta.Title) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, karma.Format( | ||||||
|  | 			err, | ||||||
|  | 			"error during finding page '%s': %s", | ||||||
|  | 			meta.Title, | ||||||
|  | 		) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ancestry := meta.Parents | ||||||
|  | 	if page != nil { | ||||||
|  | 		ancestry = append(ancestry, page.Title) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if len(ancestry) > 0 { | ||||||
|  | 		page, err := ValidateAncestry( | ||||||
|  | 			api, | ||||||
|  | 			meta.Space, | ||||||
|  | 			ancestry, | ||||||
|  | 		) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if page == nil { | ||||||
|  | 			logger.Warningf( | ||||||
|  | 				"page '%s' is not found ", | ||||||
|  | 				meta.Parents[len(ancestry)-1], | ||||||
|  | 			) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		path := meta.Parents | ||||||
|  | 		path = append(path, meta.Title) | ||||||
|  | 
 | ||||||
|  | 		logger.Debugf( | ||||||
|  | 			"resolving page path: ??? > %s", | ||||||
|  | 			strings.Join(path, ` > `), | ||||||
|  | 		) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	parent, err := EnsureAncestry( | ||||||
|  | 		api, | ||||||
|  | 		meta.Space, | ||||||
|  | 		meta.Parents, | ||||||
|  | 	) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, karma.Format( | ||||||
|  | 			err, | ||||||
|  | 			"can't create ancestry tree: %s; error: %s", | ||||||
|  | 			strings.Join(meta.Parents, ` > `), | ||||||
|  | 		) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	titles := []string{} | ||||||
|  | 	for _, page := range parent.Ancestors { | ||||||
|  | 		titles = append(titles, page.Title) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	titles = append(titles, parent.Title) | ||||||
|  | 
 | ||||||
|  | 	logger.Infof( | ||||||
|  | 		"page will be stored under path: %s > %s", | ||||||
|  | 		strings.Join(titles, ` > `), | ||||||
|  | 		meta.Title, | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	return page, nil | ||||||
|  | } | ||||||
| @ -1,4 +1,4 @@ | |||||||
| package main | package mark | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bufio" | 	"bufio" | ||||||
| @ -22,7 +22,7 @@ type Meta struct { | |||||||
| 	Layout  string | 	Layout  string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func extractMeta(data []byte) (*Meta, error) { | func ExtractMeta(data []byte) (*Meta, error) { | ||||||
| 	headerPattern := regexp.MustCompile(`\[\]:\s*#\s*\(([^:]+):\s*(.*)\)`) | 	headerPattern := regexp.MustCompile(`\[\]:\s*#\s*\(([^:]+):\s*(.*)\)`) | ||||||
| 
 | 
 | ||||||
| 	var meta *Meta | 	var meta *Meta | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Egor Kovetskiy
						Egor Kovetskiy