Skip to content

Commit

Permalink
init func
Browse files Browse the repository at this point in the history
  • Loading branch information
xiexianbin committed Apr 7, 2022
1 parent 01d1b90 commit a830c56
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 25 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@ a golang client to optimize [hugo](https://www.xiexianbin.cn/tags/hugo/) seo by
go install github.com/xiexianbin/gseo
```

## Use

- google auth

```
cat ~/.gseo/client_secret.json
{"installed":{"client_id":"1017408311257-hq3j99vk9ludpoff862mnp52v36nv4gc.apps.googleusercontent.com","project_id":"adept-button-344010","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"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","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
```

- init

```
gseo init
```

## dev

- debug
Expand All @@ -16,6 +31,25 @@ go install github.com/xiexianbin/gseo
go test -v -run TestClient google/client_test.go
```

- local run

```
$ make go-build
> Building binary...
# default args
$ ./bin/gseo render --content /Users/xiexianbin/workspace/code/github.com/xiexianbin/note.seo/content --position 10 --ctr 0 --impressions 10 --clicks 0.1 --max 8 --dryrun true
# my args 1
$ ./bin/gseo render --content /Users/xiexianbin/workspace/code/github.com/xiexianbin/note.seo/content --position 10 --ctr 0 --impressions 100 --clicks 0.3 --max 8
https://www.xiexianbin.cn/windows/tools/2018-08-19-windows-tcping/
- tcping windows
update markdownFilePath /Users/xiexianbin/workspace/code/github.com/xiexianbin/note.seo/content/windows/tools/2018-08-19-windows-tcping.md, keywords [tcping windows] done.
# my args 1
$ ./bin/gseo render --content /Users/xiexianbin/workspace/code/github.com/xiexianbin/note.seo/content --position 0 --ctr 0 --impressions 1 --clicks 0 --max 8 --dryrun true
```

## ref

- https://developers.google.com/webmaster-tools/about
Expand Down
10 changes: 5 additions & 5 deletions cmd/keyword.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ var keywordCmd = &cobra.Command{
Long: "download hugo post keywords from Google Search Console API, and cache it in `./.gseo/` dir",
Run: func(cmd *cobra.Command, args []string) {
if site == "" {
fmt.Println("site is unknown, use `gseo sites` get sites!")
fmt.Println("site is unknown, use `-s xxx`, get sites cmd is `gseo sites`!")
os.Exit(1)
}
if last <= 0 {
Expand All @@ -51,8 +51,8 @@ var keywordCmd = &cobra.Command{
os.Exit(1)
}
searchanalyticsqueryrequest := searchconsole.SearchAnalyticsQueryRequest{
StartDate: utils.LastDate(last),
EndDate: utils.TodayDate(),
StartDate: utils.LastDate(last),
EndDate: utils.TodayDate(),
Dimensions: []string{"PAGE", "QUERY"},
}
rows := sc.Query(site, &searchanalyticsqueryrequest)
Expand All @@ -67,15 +67,15 @@ var keywordCmd = &cobra.Command{
// open File
fileName := utils.GetCacheFile()
file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0666)
if err != nil{
if err != nil {
fmt.Println("Open file err =", err)
return
}
defer file.Close()

// write to file
n, err := file.Write(_rows)
if err != nil{
if err != nil {
fmt.Println("Write file err =", err)
return
}
Expand Down
71 changes: 56 additions & 15 deletions cmd/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ import (
"google.golang.org/api/searchconsole/v1"
"io/ioutil"
"os"
"strings"

"github.com/spf13/cobra"
)

var contentPath string
var clicks float64
var ctr float64
var impressions float64
var position float64
var max int64
var max int
var dryrun bool

type T struct {
Impressions int `json:"impressions"`
Expand All @@ -42,14 +45,28 @@ type T struct {
var renderCmd = &cobra.Command{
Use: "render",
Short: "render hugo post markdown files",
Long: `render hugo post markdown files.`,
Long: `render hugo post markdown files.
default args is:
gseo render --content PATH_OF_HUGO_CONTENT --position 10 --ctr 0 --impressions 100 --clicks 0.3 --max 8 --dryrun
`,
Run: func(cmd *cobra.Command, args []string) {
if contentPath == "" {
fmt.Println("content path not special.")
os.Exit(1)
}
if utils.IsDir(contentPath) == false {
fmt.Println("content path not exists.")
os.Exit(1)
}
if strings.HasSuffix(contentPath, "/") {
contentPath = strings.TrimRight(contentPath, "/")
}
if ctr < 0 || ctr > 1 {
fmt.Println("0 <= ctr <= 1.")
os.Exit(1)
}
if max <= 0 {
fmt.Println("max must >= 1")
if max < -1 || max == 0 {
fmt.Println("max must >= 1 or must = -1")
os.Exit(1)
}

Expand All @@ -63,23 +80,45 @@ var renderCmd = &cobra.Command{

byteValue, _ := ioutil.ReadAll(file)
var oldResult []*searchconsole.ApiDataRow
_= json.Unmarshal(byteValue, &oldResult)
_ = json.Unmarshal(byteValue, &oldResult)

newResult := utils.ParserSearchAnalyticsQuery(oldResult)
//r, _ := json.Marshal(newResult)
//fmt.Println(r)
for url, item := range newResult {
fmt.Println(fmt.Sprintf("%s", url))
var count int64
count = 0
count := 0
var keywords []string
for k, v := range item {
if v.Clicks >= clicks && v.Ctr >= ctr && v.Impressions >= impressions && v.Position >= position{
fmt.Println(fmt.Sprintf(" - %s", k))
count ++
if v.Clicks >= clicks && v.Ctr >= ctr && v.Impressions >= impressions && v.Position >= position {
keywords = append(keywords, k)
count++
}
if count >= max && max != -1 {
break
}
}

if len(keywords) == 0 {
continue
}

fmt.Println(fmt.Sprintf("%s", url))
for _, k := range keywords {
fmt.Println(fmt.Sprintf(" - %s", k))
}

if dryrun == false {
markdownFilePath, err := utils.GetMarkdownFileByURL(url, contentPath)
if err != nil {
fmt.Printf(err.Error())
continue
}
if count >= max {

err = utils.UpdateKeywords(markdownFilePath, keywords)
if err != nil {
fmt.Printf(err.Error())
break
}

fmt.Printf("update markdownFilePath %s, keywords %v done.\n", markdownFilePath, keywords)
}
}
},
Expand All @@ -97,9 +136,11 @@ func init() {
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// renderCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
renderCmd.Flags().StringVarP(&contentPath, "content", "", "", "hugo content path")
renderCmd.Flags().Float64VarP(&clicks, "clicks", "k", 0, ">=clicks to render seo.")
renderCmd.Flags().Float64VarP(&ctr, "ctr", "c", 0.3, "ctr = clicks / impressions to render seo, and 0 <= ctr <= 1.")
renderCmd.Flags().Float64VarP(&impressions, "impressions", "i", 100, ">=impressions to render seo.")
renderCmd.Flags().Float64VarP(&position, "position", "p", 10, ">=position to render seo.")
renderCmd.Flags().Int64VarP(&max, "max", "m", 8, "max seo items.")
renderCmd.Flags().IntVarP(&max, "max", "m", 8, "max seo items, -1 is un-limit.")
renderCmd.Flags().BoolVarP(&dryrun, "dryrun", "r", false, "dry run mode.")
}
6 changes: 3 additions & 3 deletions cmd/sites.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"google.golang.org/api/option"
"google.golang.org/api/searchconsole/v1"

"github.com/xiexianbin/gseo/googleapi"
"github.com/xiexianbin/gseo/googleapi"
"github.com/xiexianbin/gseo/utils/logger"
)

Expand All @@ -35,14 +35,14 @@ var sitesCmd = &cobra.Command{
Long: `site list.`,
Run: func(cmd *cobra.Command, args []string) {
ctx, client := googleapi.Client()
searchconsoleService, err := searchconsole.NewService(
searchConsoleService, err := searchconsole.NewService(
ctx,
option.WithHTTPClient(client))
if err != nil {
log.Fatalf("Unable to retrieve Search Console client: %v", err)
}

siteList := searchconsoleService.Sites.List()
siteList := searchConsoleService.Sites.List()
sitesListResponse, err := siteList.Do()
logger.Debug("sitesListResponse is: %v", sitesListResponse)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ require (
github.com/spf13/viper v1.10.1
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
google.golang.org/api v0.63.0
gopkg.in/yaml.v2 v2.4.0
)
44 changes: 42 additions & 2 deletions utils/markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"fmt"
"gopkg.in/yaml.v2"
"io/ioutil"
"net/url"
"path/filepath"
"runtime"
"strings"
)
Expand All @@ -29,6 +31,33 @@ type PostYaml struct {
Tags []string `json:"tags"`
}

func GetMarkdownFileByURL(permalink, contentPath string) (path string, err error) {
u, err := url.Parse(permalink)
if err != nil {
panic(err)
}

relURL := u.Path
if strings.HasPrefix(relURL, "/categories/") || strings.HasPrefix(relURL, "/tags/") {
return "", fmt.Errorf("could not find markdownd file for %s in %s", permalink, contentPath)
}

var markdownFilePath string
tmpDir := filepath.Join(contentPath, relURL)
if IsDir(tmpDir) {
markdownFilePath = fmt.Sprintf("%s/_index.md", tmpDir)
} else {
tmpDir = strings.TrimRight(tmpDir, "/")
markdownFilePath = fmt.Sprintf("%s.md", tmpDir)
}

if IsFile(markdownFilePath) {
return markdownFilePath, nil
}

return "", fmt.Errorf("could not find markdownd file for %s in %s", permalink, contentPath)
}

func ParsePostKeysAndTags(filename string) (*PostYaml, error) {
var postYaml PostYaml
buf, err := ioutil.ReadFile(filename)
Expand All @@ -43,13 +72,13 @@ func ParsePostKeysAndTags(filename string) (*PostYaml, error) {
return &postYaml, nil
}

func UpdateKeywords(filename string, newKeywords []string) error {
func UpdateKeywords(filename string, keywords []string) error {
postYaml, err := ParsePostKeysAndTags(filename)
if err != nil {
return err
}

if len(newKeywords) == 0 {
if len(keywords) == 0 {
return nil
}

Expand All @@ -60,6 +89,17 @@ func UpdateKeywords(filename string, newKeywords []string) error {
oldStr = "keywords:\\n - " + strings.Join(postYaml.Keywords, "\\n - ")
}

newKeywords := postYaml.Keywords
for _, key := range keywords {
if IsContain(postYaml.Tags, key) || IsContain(newKeywords, key) {
continue
}
newKeywords = append(newKeywords, key)
}

if len(newKeywords) == 0 {
return nil
}
newStr := "keywords:\\n - " + strings.Join(newKeywords, "\\n - ")

var cmd string
Expand Down
10 changes: 10 additions & 0 deletions utils/markdown_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ import (
"testing"
)

func TestGetMarkdownFileByURL(t *testing.T) {

markdownFilePath, err := GetMarkdownFileByURL("https://www.xiexianbin.cn/program/go/tinygo/", "/Users/xiexianbin/workspace/code/github.com/xiexianbin/note.seo/content")
if err != nil {
return
}

fmt.Println("markdownFilePath", markdownFilePath)
}

func TestParsePostKeysAndTags(t *testing.T) {
filename := "./samples/test-1.md"
postYaml, err := ParsePostKeysAndTags(filename)
Expand Down
25 changes: 25 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ import (
"time"
)

func IsDir(path string) bool {
s, err := os.Stat(path)
if err != nil {
return false
}
return s.IsDir()
}

func IsFile(path string) bool {
s, err := os.Stat(path)
if err != nil {
return false
}
return !s.IsDir()
}

func ReadFromCmd(tips string) (string, error) {
fmt.Printf("%s", tips)
reader := bufio.NewReader(os.Stdin)
Expand Down Expand Up @@ -85,3 +101,12 @@ func SortMap(m map[string]float64) []string {

return r
}

func IsContain(items []string, item string) bool {
for _, eachItem := range items {
if eachItem == item {
return true
}
}
return false
}
1 change: 1 addition & 0 deletions vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,5 @@ google.golang.org/protobuf/types/known/timestamppb
# gopkg.in/ini.v1 v1.66.2
gopkg.in/ini.v1
# gopkg.in/yaml.v2 v2.4.0
## explicit
gopkg.in/yaml.v2

0 comments on commit a830c56

Please sign in to comment.