summaryrefslogtreecommitdiff
path: root/scripts/get_external_link_rank.go
diff options
context:
space:
mode:
authorEltrac <hi@guhub.cn>2025-10-21 19:38:43 +0800
committerEltrac <hi@guhub.cn>2025-10-21 19:38:43 +0800
commit377a72b003cf5b3dbd2b9120965337ed4a98ade7 (patch)
tree4b4e407d8c1e3555402e9343696f6579c679c11b /scripts/get_external_link_rank.go
parente09fd5cf7551c8016fc46cf73cc801ed287da6f0 (diff)
refactor(build): separate link scanning logic
Generation of both internal link graph and external link rank used to be done in one single script. Now it's separated for maintenance. Former-commit-id: 7d308beee2359afe39582ed6182f085250768f3f
Diffstat (limited to 'scripts/get_external_link_rank.go')
-rw-r--r--scripts/get_external_link_rank.go73
1 files changed, 73 insertions, 0 deletions
diff --git a/scripts/get_external_link_rank.go b/scripts/get_external_link_rank.go
new file mode 100644
index 00000000..780bb5ec
--- /dev/null
+++ b/scripts/get_external_link_rank.go
@@ -0,0 +1,73 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/fs"
+ "net/url"
+ "os"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strings"
+)
+
+func main() {
+ externalLinks := countExternalLinks("content")
+ writeJSON("data/externallinks.json", externalLinks)
+ fmt.Println("✅ External link rank data generated.")
+}
+
+// countExternalLinks scans markdown files and counts occurrences of each external domain.
+func countExternalLinks(root string) [][2]interface{} {
+ linkRegex := regexp.MustCompile(`https?://[^\s)>"']+`)
+ counts := make(map[string]int)
+
+ filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
+ if err != nil || d.IsDir() || !strings.HasSuffix(path, ".md") {
+ return nil
+ }
+ data, err := os.ReadFile(path)
+ if err != nil {
+ return nil
+ }
+ matches := linkRegex.FindAllString(string(data), -1)
+ for _, match := range matches {
+ u, err := url.Parse(match)
+ if err == nil && u.Host != "" && u.Host != "image.guhub.cn" {
+ counts[u.Host]++
+ }
+ }
+ return nil
+ })
+
+ // convert map to sorted array
+ type kv struct {
+ Key string
+ Value int
+ }
+ var list []kv
+ for k, v := range counts {
+ list = append(list, kv{k, v})
+ }
+ sort.Slice(list, func(i, j int) bool { return list[i].Value > list[j].Value })
+
+ result := make([][2]interface{}, len(list))
+ for i, kv := range list {
+ result[i] = [2]interface{}{kv.Key, kv.Value}
+ }
+ return result
+}
+
+// writeJSON writes the result to file with indentation.
+func writeJSON(path string, data interface{}) {
+ file, err := os.Create(path)
+ if err != nil {
+ fmt.Println("Error:", err)
+ return
+ }
+ defer file.Close()
+ enc := json.NewEncoder(file)
+ enc.SetIndent("", " ")
+ enc.Encode(data)
+}