Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions cmd/mark2note/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -835,18 +835,29 @@ func absolutePath(path string) string {

func buildAutoPublishXHSOptions(renderOpts Options, renderResult app.Result) (app.PublishOptions, error) {
imagePaths := nonEmptyStrings(renderResult.ImagePaths)
validateImagesDone := timing.Stage("cmd.buildAutoPublishXHSOptions.validate_images", timing.Field("images", len(imagePaths)))
if len(imagePaths) == 0 {
return app.PublishOptions{}, fmt.Errorf("no generated PNG files found")
err := fmt.Errorf("no generated PNG files found")
validateImagesDone(err)
return app.PublishOptions{}, err
}
for _, imagePath := range imagePaths {
if _, err := os.Stat(imagePath); err != nil {
if errors.Is(err, os.ErrNotExist) {
return app.PublishOptions{}, fmt.Errorf("generated PNG file not found: %s", imagePath)
if _, statErr := os.Stat(imagePath); statErr != nil {
if errors.Is(statErr, os.ErrNotExist) {
err := fmt.Errorf("generated PNG file not found: %s", imagePath)
validateImagesDone(err)
return app.PublishOptions{}, err
}
return app.PublishOptions{}, fmt.Errorf("generated PNG file unavailable: %s: %v", imagePath, err)
err := fmt.Errorf("generated PNG file unavailable: %s: %v", imagePath, statErr)
validateImagesDone(err)
return app.PublishOptions{}, err
}
}
validateImagesDone(nil)

readMarkdownDone := timing.Stage("cmd.buildAutoPublishXHSOptions.read_markdown")
markdownBytes, err := readFile(renderOpts.InputPath)
readMarkdownDone(err)
if err != nil {
return app.PublishOptions{}, fmt.Errorf("%w: %v", app.ErrReadMarkdown, err)
}
Expand All @@ -865,25 +876,43 @@ func buildAutoPublishXHSOptions(renderOpts Options, renderResult app.Result) (ap
ConfigPath: renderOpts.ConfigPath,
ChromePathChanged: renderOpts.ChromePathChanged,
}

loadConfigDone := timing.Stage("cmd.buildAutoPublishXHSOptions.load_config")
cfg, err := loadPublishXHSConfig(cliOpts.ConfigPath, true)
loadConfigDone(err)
if err != nil {
return app.PublishOptions{}, err
}

generateTitleDone := timing.Stage("cmd.buildAutoPublishXHSOptions.generate_title")
title, err = buildAutoPublishXHSTitle(*cfg, markdown, title)
generateTitleDone(err)
if err != nil {
return app.PublishOptions{}, err
}
cliOpts.Title = title

topicSource := "ai"
if len(renderOpts.XHSTags) > 0 {
topicSource = "manual"
}
generateTopicsDone := timing.Stage("cmd.buildAutoPublishXHSOptions.generate_topics", timing.Field("source", topicSource))
topics, err := buildAutoPublishXHSTopics(*cfg, markdown, title, renderOpts.XHSTags)
generateTopicsDone(err)
if err != nil {
return app.PublishOptions{}, err
}
cliOpts.Tags = topics

buildContentDone := timing.Stage("cmd.buildAutoPublishXHSOptions.build_content", timing.Field("content_mode", renderOpts.XHSContentMode))
content, err := buildAutoPublishXHSContent(renderOpts, renderResult)
buildContentDone(err)
if err != nil {
return app.PublishOptions{}, fmt.Errorf("build xhs publish content: %w", err)
}
cliOpts.Content = content

mergeDefaultsDone := timing.Stage("cmd.buildAutoPublishXHSOptions.merge_defaults")
if renderOpts.XHSModeChanged {
cliOpts.Mode = strings.TrimSpace(renderOpts.XHSMode)
cliOpts.ModeChanged = true
Expand Down Expand Up @@ -911,9 +940,14 @@ func buildAutoPublishXHSOptions(renderOpts Options, renderResult app.Result) (ap
cliOpts.AllowContentCopyChanged = true
}
publishOpts := mergePublishXHSDefaults(cliOpts, cfg)
mergeDefaultsDone(nil)

validateOptionsDone := timing.Stage("cmd.buildAutoPublishXHSOptions.validate_options")
if err := validatePublishXHSOptions(publishOpts); err != nil {
validateOptionsDone(err)
return app.PublishOptions{}, err
}
validateOptionsDone(nil)
return publishOpts, nil
}

Expand Down
42 changes: 42 additions & 0 deletions cmd/mark2note/main_publish_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/walker1211/mark2note/internal/app"
"github.com/walker1211/mark2note/internal/config"
"github.com/walker1211/mark2note/internal/timing"
"github.com/walker1211/mark2note/internal/xhs"
)

Expand Down Expand Up @@ -710,6 +711,47 @@ func TestRunAutoPublishXHSUsesManualTagsWithoutTopicGeneration(t *testing.T) {
}
}

func TestBuildAutoPublishXHSOptionsReportsTopicGenerationTiming(t *testing.T) {
originalReadFile := readFile
originalLoadConfig := loadConfig
originalBuildPublishTopics := buildPublishTopics
defer func() {
readFile = originalReadFile
loadConfig = originalLoadConfig
buildPublishTopics = originalBuildPublishTopics
}()

var timingOutput bytes.Buffer
oldTimingOutput := timing.SetOutput(&timingOutput)
defer timing.SetOutput(oldTimingOutput)

imagePath := filepath.Join(t.TempDir(), "p01-cover.png")
if err := os.WriteFile(imagePath, []byte("png"), 0o644); err != nil {
t.Fatalf("WriteFile() error = %v", err)
}
readFile = func(path string) ([]byte, error) {
return []byte("# 标题\n\n正文"), nil
}
loadConfig = func(path string) (*config.Config, error) {
enabled := true
return &config.Config{XHS: config.XHSCfg{Publish: config.XHSPublishCfg{Account: "walker", TopicGeneration: config.XHSTopicGenerationCfg{Enabled: &enabled}}}}, nil
}
buildPublishTopics = func(cfg *config.Config, markdown string, title string) ([]string, error) {
return []string{"AI新闻", "科技日报"}, nil
}

_, err := buildAutoPublishXHSOptions(Options{InputPath: "article.md", ConfigPath: "configs/config.yaml"}, app.Result{ImagePaths: []string{imagePath}})
if err != nil {
t.Fatalf("buildAutoPublishXHSOptions() error = %v", err)
}
output := timingOutput.String()
for _, want := range []string{"stage=cmd.buildAutoPublishXHSOptions.generate_topics", "source=ai", "status=ok"} {
if !strings.Contains(output, want) {
t.Fatalf("timing output missing %q:\n%s", want, output)
}
}
}

func TestRunAutoPublishXHSRejectsDisabledTopicGenerationWithoutManualTags(t *testing.T) {
originalReadFile := readFile
originalLoadConfig := loadConfig
Expand Down