cackle-import-comments
/
main.go
174 строки · 4.9 Кб
1package main
2
3import (
4"encoding/json"
5"fmt"
6"io/ioutil"
7"log"
8"net/http"
9"os"
10"strconv"
11"time"
12
13"github.com/joho/godotenv"
14)
15
16type Channel struct {
17Id int `json:"id"`
18Channel string `json:"channel"`
19Url string `json:"url"`
20Title string `json:"title"`
21Created int64 `json:"created"`
22Count int `json:"count"` //вообще там всегда вроде 0, но добавил для совместимости
23}
24
25type Author struct {
26ID int `json:"id"`
27Name string `json:"name"`
28Avatar string `json:"avatar"`
29Www string `json:"www"`
30Provider string `json:"provider"`
31OpenID string `json:"openId"`
32Verify bool `json:"verify"`
33Notify bool `json:"notify"`
34}
35
36type Comment struct {
37ID int `json:"id"`
38SiteID int `json:"siteId"`
39ParentID int `json:"parentId"`
40Path []int `json:"path"`
41Message string `json:"message"`
42Rating int `json:"rating"`
43Status string `json:"status"`
44Created int64 `json:"created"`
45Author Author `json:"author"`
46Chan Channel `json:"chan"`
47IP string `json:"ip"`
48Modified string `json:"modified"`
49}
50
51func main() {
52log.Println("Start import comments from cackle.me...")
53err := godotenv.Load(".env")
54if err != nil {
55log.Fatal("Error loading .env file")
56}
57log.Printf("Get channels from widget ID: %s", os.Getenv("ID"))
58timeout, err := strconv.Atoi(os.Getenv("TIMEOUT"))
59if err != nil || timeout <= 0 {
60timeout = 5
61}
62// читаем каналы (по сути это список страниц, к которым есть комментарии)
63apiUrlChannels := fmt.Sprintf("http://cackle.me/api/3.0/comment/chan/list.json?id=%s&siteApiKey=%s&accountApiKey=%s",
64os.Getenv("ID"), os.Getenv("SITE_API_KEY"), os.Getenv("ACCOUNT_API_KEY"))
65//log.Println(apiUrlChannels)
66page := 0
67var allChannels []Channel
68for { //цикл по получению списка каналов, следуя рекомендации сервиса запросы делаются с паузами и по 100 шт
69count, channels, err := getChannels(apiUrlChannels, page)
70if err != nil {
71log.Fatal(err)
72}
73log.Printf("Get channels, iteration %d, count %d\n", page+1, len(channels))
74page++
75allChannels = append(allChannels, channels...)
76if count < 100 {
77break
78}
79time.Sleep(time.Duration(timeout) * time.Second)
80}
81log.Printf("All channels count %d\n", len(allChannels))
82log.Printf("Saving all channels to file...")
83
84file, err := json.MarshalIndent(allChannels, "", " ")
85if err != nil {
86log.Fatal(err)
87}
88err = ioutil.WriteFile("channels.json", file, 0644)
89if err != nil {
90log.Fatal(err)
91}
92log.Printf("Done\n")
93//читаем комментарии
94log.Println("Getting comments...")
95apiUrlComments := fmt.Sprintf("http://cackle.me/api/3.0/comment/list.json?id=%s&siteApiKey=%s&accountApiKey=%s",
96os.Getenv("ID"), os.Getenv("SITE_API_KEY"), os.Getenv("ACCOUNT_API_KEY"))
97var allComments []Comment
98for index, channel := range allChannels {
99log.Printf("Get comments from channel id %d (%d from %d),\n URL: %s\n Title: %s\n", channel.Id, index, len(allChannels), channel.Url, channel.Title)
100commentId := 0
101currentCount := 0
102for {
103time.Sleep(time.Duration(timeout) * time.Second)
104count, comments, err := getComments(apiUrlComments, channel.Channel, commentId)
105log.Println("Get block with count: ", count)
106currentCount += count
107if err != nil {
108log.Println(err)
109break
110} else {
111allComments = append(allComments, comments...)
112if count < 100 {
113commentId = 0
114} else {
115commentId = comments[99].ID
116}
117}
118if commentId == 0 {
119break
120}
121}
122log.Printf("Count comments: %d", currentCount)
123currentCount = 0
124}
125log.Println("Done...")
126log.Printf("All comments count %d\n", len(allComments))
127log.Printf("Saving all comments to file...")
128file, err = json.MarshalIndent(allComments, "", " ")
129if err != nil {
130log.Fatal(err)
131}
132err = ioutil.WriteFile("comments.json", file, 0644)
133if err != nil {
134log.Fatal(err)
135}
136log.Println("Done...")
137}
138
139func getChannels(baseApiUrl string, page int) (count int, channels []Channel, err error) {
140if page > 0 {
141baseApiUrl = baseApiUrl + fmt.Sprintf("&page=%d", page)
142}
143response, err := http.Get(baseApiUrl)
144if err != nil {
145return 0, nil, err
146}
147var result map[string][]Channel
148err = json.NewDecoder(response.Body).Decode(&result)
149if err != nil {
150return 0, nil, err
151}
152count = len(result["chans"])
153channels = result["chans"]
154err = nil
155return
156}
157
158func getComments(baseApiUrl string, channel string, commentId int) (count int, comments []Comment, err error) {
159baseApiUrl = baseApiUrl + fmt.Sprintf("&chan=%s", channel) + fmt.Sprintf("&commentId=%s", commentId)
160
161response, err := http.Get(baseApiUrl)
162if err != nil {
163return 0, nil, err
164}
165var result map[string][]Comment
166err = json.NewDecoder(response.Body).Decode(&result)
167if err != nil {
168return 0, nil, err
169}
170count = len(result["comments"])
171comments = result["comments"]
172err = nil
173return
174}
175