Skip to content

Commit 4ba9676

Browse files
committed
Add cmd to get new and update existing questions
Add sqlite3 methods to store/update Stack Exchange questions and users. To get new questions from configured Stack Exchange site run `slackoverflow stackexchange questions --get` To update information about already recorded questions run `slackoverflow stackexchange questions --update` Execute previous 2 together run `slackoverflow stackexchange questions --all`
1 parent 0a002cc commit 4ba9676

12 files changed

+1141
-64
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
package slackoverflow
2+
3+
import (
4+
"time"
5+
6+
"github.com/aframevr/slackoverflow/sqlite3"
7+
"github.com/aframevr/slackoverflow/stackexchange"
8+
"github.com/aframevr/slackoverflow/std"
9+
)
10+
11+
type cmdStackExchangeQuestions struct {
12+
GetNewQuestions bool `long:"get" description:"Get new questions from configured Stack Exchange Site"`
13+
UpdateQuestions bool `long:"update" description:"Update information about existing questions"`
14+
All bool `long:"all" description:"Get new questions and update information about existing questions"`
15+
}
16+
17+
func (cse *cmdStackExchangeQuestions) Execute(args []string) error {
18+
19+
// Refresh the session before running this command and make sure that Slack Overflow is configured
20+
slackoverflow.SessionRefresh()
21+
22+
if !slackoverflow.config.StackExchange.Enabled {
23+
Notice("Running Stack Exchange related commands is disabled in configuration file. Skipping.")
24+
return nil
25+
}
26+
27+
// Get new questions from configured Stack Exchange Site
28+
if cse.GetNewQuestions {
29+
cse.getNewQuestions()
30+
}
31+
32+
// Get new questions from configured Stack Exchange Site
33+
if cse.UpdateQuestions {
34+
cse.updateQuestions()
35+
}
36+
37+
// Get new questions from configured Stack Exchange Site
38+
if cse.All {
39+
cse.getNewQuestions()
40+
cse.updateQuestions()
41+
}
42+
43+
return nil
44+
}
45+
46+
// Get new Questions
47+
func (cse *cmdStackExchangeQuestions) getNewQuestions() {
48+
Info("Stack Exchange: Checking for new questions.")
49+
50+
question := sqlite3.StackExchangeQuestion{}.Latest()
51+
52+
// Check do we already have some questions do obtain from_date for next request
53+
if question.QID == 0 {
54+
Notice("There are no questions in database,")
55+
Info("That is ok if current execution is first time you run slackoverflow")
56+
Info("Or there are no questions tagged with %s on site %s",
57+
slackoverflow.config.StackExchange.SearchAdvanced["tagged"],
58+
slackoverflow.config.StackExchange.Site,
59+
)
60+
question.CreationDate = time.Now().UTC().Add(-24 * time.Hour)
61+
}
62+
63+
Debug("Checking new questions since %s", question.CreationDate.String())
64+
65+
// Check for New Questions from Stack Exchange
66+
searchAdvanced := slackoverflow.StackExchange.SearchAdvanced()
67+
68+
// Set it here so that it is allowed to override by config
69+
searchAdvanced.Parameters.Set("site", slackoverflow.config.StackExchange.Site)
70+
71+
// Set all parameters from config
72+
for param, value := range slackoverflow.config.StackExchange.SearchAdvanced {
73+
searchAdvanced.Parameters.Set(param, value)
74+
}
75+
searchAdvanced.Parameters.Set("fromdate", question.CreationDate.Unix()+1)
76+
77+
// Output query as table
78+
if slackoverflow.Debugging() {
79+
searchAdvanced.DrawQuery()
80+
}
81+
82+
fetchQuestions := true
83+
84+
for fetchQuestions {
85+
Info("Fetching page %d", searchAdvanced.GetCurrentPageNr())
86+
std.Hr()
87+
if results, err := searchAdvanced.Get(); results {
88+
// Questions recieved
89+
for _, q := range searchAdvanced.Result.Items {
90+
std.Body("Question: %s", q.Title)
91+
std.Body("Url: %s", q.ShareLink)
92+
newq := std.NewTable("Question ID", "Time", "Answers", "Comments", "Score", "Views", "Username")
93+
newq.AddRow(
94+
q.QID,
95+
time.Unix(q.CreationDate, 0).UTC().Format("15:04:05 Mon Jan _2 2006"),
96+
q.AnswerCount,
97+
q.CommentCount,
98+
q.Score,
99+
q.ViewCount,
100+
q.Owner.DisplayName,
101+
)
102+
newq.Print()
103+
cse.syncQuestion(q)
104+
std.Hr()
105+
}
106+
if err != nil {
107+
fetchQuestions = false
108+
Error(err.Error())
109+
}
110+
std.Hr()
111+
}
112+
113+
// Done go to next page
114+
if searchAdvanced.HasMore() {
115+
searchAdvanced.NextPage()
116+
} else {
117+
fetchQuestions = false
118+
Ok("There are no more new questions.")
119+
}
120+
}
121+
Info(
122+
"Stack Exchange Quota usage (%d/%d)",
123+
slackoverflow.StackExchange.GetQuotaRemaining(),
124+
slackoverflow.StackExchange.GetQuotaMax(),
125+
)
126+
}
127+
128+
// Get new Questions
129+
func (cse *cmdStackExchangeQuestions) updateQuestions() {
130+
Info("Stack Exchange: Updating existing questions.")
131+
132+
questionIds, questionIdsCount := sqlite3.StackExchangeQuestion{}.TrackedIds(
133+
slackoverflow.config.StackExchange.QuestionsToWatch)
134+
135+
// Check do we already have some questions do obtain from_date for next request
136+
if questionIdsCount == 0 {
137+
Notice("There are no questions in database,")
138+
Info("That is ok if current execution is first time you run slackoverflow")
139+
Info("and this case run 'slackoverflow stackechange guestions' --get first")
140+
}
141+
142+
Debug("Checking updates for %d questions. Max to be tracked (%d)",
143+
questionIdsCount, slackoverflow.config.StackExchange.QuestionsToWatch)
144+
145+
// Check for New Questions from Stack Exchange
146+
updateQuestions := slackoverflow.StackExchange.Questions()
147+
148+
// Set it here so that it is allowed to override by config
149+
updateQuestions.Parameters.Set("site", slackoverflow.config.StackExchange.Site)
150+
151+
for param, value := range slackoverflow.config.StackExchange.Questions {
152+
updateQuestions.Parameters.Set(param, value)
153+
}
154+
155+
// Output query as table
156+
if slackoverflow.Debugging() {
157+
updateQuestions.DrawQuery(questionIds)
158+
}
159+
160+
fetchQuestions := true
161+
162+
for fetchQuestions {
163+
Info("Fetching page %d", updateQuestions.GetCurrentPageNr())
164+
std.Hr()
165+
if results, err := updateQuestions.Get(questionIds); results {
166+
// Questions recieved
167+
for _, q := range updateQuestions.Result.Items {
168+
std.Body("Question: %s", q.Title)
169+
std.Body("Url: %s", q.ShareLink)
170+
newq := std.NewTable("Question ID", "Time", "Answers", "Comments", "Score", "Views", "Username")
171+
newq.AddRow(
172+
q.QID,
173+
time.Unix(q.CreationDate, 0).UTC().Format("15:04:05 Mon Jan _2 2006"),
174+
q.AnswerCount,
175+
q.CommentCount,
176+
q.Score,
177+
q.ViewCount,
178+
q.Owner.DisplayName,
179+
)
180+
newq.Print()
181+
cse.syncQuestion(q)
182+
std.Hr()
183+
}
184+
if err != nil {
185+
fetchQuestions = false
186+
Error(err.Error())
187+
}
188+
std.Hr()
189+
}
190+
191+
// Done go to next page
192+
if updateQuestions.HasMore() {
193+
updateQuestions.NextPage()
194+
} else {
195+
fetchQuestions = false
196+
Ok("There are no more questions to update.")
197+
}
198+
}
199+
Info(
200+
"Stack Exchange Quota usage (%d/%d)",
201+
slackoverflow.StackExchange.GetQuotaRemaining(),
202+
slackoverflow.StackExchange.GetQuotaMax(),
203+
)
204+
}
205+
206+
// Store new questions
207+
func (cse *cmdStackExchangeQuestions) syncQuestion(q stackexchange.QuestionObj) {
208+
var ok string
209+
var err error
210+
// Create or Update user
211+
ok, err = sqlite3.StackExchangeUser{}.SyncShallowUser(q.Owner)
212+
if err != nil {
213+
Error(err.Error())
214+
} else {
215+
Ok(ok)
216+
}
217+
// Create or Update user
218+
ok, err = sqlite3.StackExchangeQuestion{}.SyncFromSite(q, slackoverflow.config.StackExchange.Site)
219+
if err != nil {
220+
Error(err.Error())
221+
} else {
222+
Ok(ok)
223+
}
224+
}

slackoverflow/cmd-stackexchange.go

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package slackoverflow
2+
3+
// slackoverflow stackexchange
4+
type cmdStackExchange struct {
5+
Questions cmdStackExchangeQuestions `command:"questions" description:"Work with stackexchange questions based on the qobfiuration"`
6+
}

slackoverflow/commands.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ type Commands struct {
2222
// Run slackoverflow run
2323
Run cmdRun `command:"run" description:"Run SlackOverflow once."`
2424

25-
// Start slackoverflow start
25+
// Slack slackoverflow slack
2626
Slack cmdSlack `command:"slack" description:"Slack related commands see slackoverflow slack --help for more info."`
2727

28+
// Stack Exchange slackoverflow stackexchange
29+
StackExchange cmdStackExchange `command:"stackexchange" description:"Stack Exchange related commands see slackoverflow stackexchange --help for more info."`
30+
2831
// Start slackoverflow start
2932
Start cmdStart `command:"start" description:"Start SlackOverflow daemon."`
3033

sqlite3/stacexchange-question.go

-53
This file was deleted.

0 commit comments

Comments
 (0)