diff --git a/cmd/watch.go b/cmd/watch.go index 290b58a..aac4a83 100644 --- a/cmd/watch.go +++ b/cmd/watch.go @@ -93,7 +93,7 @@ var watchCmd = &cobra.Command{ log.Debug("Destination is not Markdown; not cleaning up posts", "destination", dest.GetName()) } } - + } wg.Add(1) go func() { diff --git a/internal/platforms/blogger.go b/internal/platforms/blogger.go index 973c47c..f90efeb 100644 --- a/internal/platforms/blogger.go +++ b/internal/platforms/blogger.go @@ -117,6 +117,33 @@ func (b Blogger) Pull(options PushPullOptions) (PostData, error) { return PostData{}, fmt.Errorf("updated date not found in response or is not a string") } // result["labels"].([]interface{}) + labels := []string{} + categories := []string{} + tags := []string{} + // Assert that the labels key is a slice of interfaces + // Type assertions don't work on a per-element basis so we have to loop through the slice + labelsAsserted, ok := result["labels"].([]interface{}) + if !ok { + log.Infof("No labels found for post %s", title) + } else { + for _, tag := range labelsAsserted { + if tagStr, ok := tag.(string); ok { + labels = append(labels, tagStr) + } else { + log.Warn("Blogger label is not a string", "tag", tag) + } + } + // For each label, check if it has the category prefix + // If it does, add it to the categories slice + // Otherwise, add it to the tags slice + for _, label := range labels { + if strings.HasPrefix(label, b.CategoryPrefix) { + categories = append(categories, strings.TrimPrefix(label, b.CategoryPrefix)) + } else { + tags = append(tags, label) + } + } + } dateUpdated, err := time.Parse(time.RFC3339, rfcDateUpdated) if err != nil { return PostData{}, err @@ -173,6 +200,8 @@ func (b Blogger) Pull(options PushPullOptions) (PostData, error) { Date: date, DateUpdated: dateUpdated, Description: postDescription, + Categories: categories, + Tags: tags, CanonicalUrl: canonicalUrl, }, nil diff --git a/internal/platforms/platforms.go b/internal/platforms/platforms.go index 383b043..46b9f70 100644 --- a/internal/platforms/platforms.go +++ b/internal/platforms/platforms.go @@ -28,18 +28,17 @@ type WatchableSource interface { } type PushPullOptions struct { - AccessToken string - BlogId string - PostUrl string - Filepath string - RefreshToken string - ClientId string - ClientSecret string - LlmProvider string - LlmBaseUrl string - LlmApiKey string - LlmModel string - CategoryPrefix string + AccessToken string + BlogId string + PostUrl string + Filepath string + RefreshToken string + ClientId string + ClientSecret string + LlmProvider string + LlmBaseUrl string + LlmApiKey string + LlmModel string } type PostData struct { @@ -50,6 +49,8 @@ type PostData struct { DateUpdated time.Time // TODO: Add frontmatter descriptions Description string + Categories []string + Tags []string // Other fields that are probably needed are canonical URL, publish date, and description CanonicalUrl string } @@ -63,8 +64,9 @@ type PostData struct { // } type Blogger struct { - Name string - BlogUrl string + Name string + BlogUrl string + CategoryPrefix string // https://developers.google.com/blogger/docs/3.0/reference/posts/delete Overwrite bool GenerateLlmDescriptions bool @@ -133,11 +135,19 @@ func CreateSource(sourceMap map[string]interface{}) (Source, error) { if !ok || blogUrl == "" { return nil, fmt.Errorf("blog_url is required for blogger") } + // Check if category_prefix is set, if not, set it to null and move on + // If the value is not a string, it will be set to "category::" + categoryPrefix, ok := sourceMap["category_prefix"].(string) + if !ok || categoryPrefix == "" { + log.Warn("category_prefix is not a string or is empty. Using default", "default", "category::") + categoryPrefix = "category::" + } generateLlmDescriptions, _ := sourceMap["generate_llm_descriptions"].(bool) return &Blogger{ Name: name, BlogUrl: blogUrl, GenerateLlmDescriptions: generateLlmDescriptions, + CategoryPrefix: categoryPrefix, }, nil case "markdown": // If the content_dir is not set, set it to null as its not required