Refactored code and added logging
This commit is contained in:
parent
8830920900
commit
221ab214cc
11 changed files with 51 additions and 44 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -2,3 +2,4 @@ vendor
|
||||||
go-mtg-vk
|
go-mtg-vk
|
||||||
*.swp
|
*.swp
|
||||||
hosts
|
hosts
|
||||||
|
.idea
|
||||||
|
|
@ -23,11 +23,11 @@ func GetClient() *CacheClient {
|
||||||
|
|
||||||
func (client *CacheClient) Init() {
|
func (client *CacheClient) Init() {
|
||||||
client.storage = redis.NewClient(&redis.Options{
|
client.storage = redis.NewClient(&redis.Options{
|
||||||
Addr: HOST_NAME,
|
Addr: HostName,
|
||||||
Password: PASSWORD,
|
Password: Password,
|
||||||
DB: 0,
|
DB: 0,
|
||||||
})
|
})
|
||||||
client.Expiration = CACHE_EXPIRATION
|
client.Expiration = CacheExpiration
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *CacheClient) Set(key string, value string) {
|
func (client *CacheClient) Set(key string, value string) {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const HOST_NAME = "redis:6379"
|
const HostName = "redis:6379"
|
||||||
const PASSWORD = ""
|
const Password = ""
|
||||||
const CACHE_EXPIRATION = time.Hour * 24
|
const CacheExpiration = time.Hour * 24
|
||||||
|
|
|
||||||
|
|
@ -8,26 +8,26 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const SCRYFALL_URL = "https://api.scryfall.com"
|
const ScryfallUrl = "https://api.scryfall.com"
|
||||||
|
|
||||||
func GetNameByCardId(set string, number string) string {
|
func GetNameByCardId(set string, number string) string {
|
||||||
/*
|
/*
|
||||||
Note: number is string because some cards contain letters in their numbers.
|
Note: number is string because some cards contain letters in their numbers.
|
||||||
*/
|
*/
|
||||||
path := SCRYFALL_URL + "/cards/" + strings.ToLower(set) + "/" + number
|
path := ScryfallUrl + "/cards/" + strings.ToLower(set) + "/" + number
|
||||||
return GetCardByUrl(path)
|
return GetCardByUrl(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetOriginalName(name string) string {
|
func GetOriginalName(name string) string {
|
||||||
path := SCRYFALL_URL + "/cards/named?fuzzy=" + ApplyFilters(name)
|
path := ScryfallUrl + "/cards/named?fuzzy=" + ApplyFilters(name)
|
||||||
return GetCardByUrl(path)
|
return GetCardByUrl(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ApplyFilters(name string) string {
|
func ApplyFilters(name string) string {
|
||||||
/*
|
/*
|
||||||
Despite of the rules of Russian language, letter ё is replaced with e on cards
|
Despite of the rules of Russian language, letter ё is replaced with e on cards
|
||||||
Sometimes it leads to wrong search results
|
Sometimes it leads to wrong search results
|
||||||
*/
|
*/
|
||||||
name = strings.ReplaceAll(name, "ё", "е")
|
name = strings.ReplaceAll(name, "ё", "е")
|
||||||
return url.QueryEscape(name)
|
return url.QueryEscape(name)
|
||||||
}
|
}
|
||||||
|
|
@ -43,6 +43,9 @@ func GetCardByUrl(path string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
var v Card
|
var v Card
|
||||||
json.Unmarshal(data, &v)
|
err = json.Unmarshal(data, &v)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
return v.getName()
|
return v.getName()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const SCGURL = "http://www.starcitygames.com/results?name="
|
const Scgurl = "http://www.starcitygames.com/results?name="
|
||||||
|
|
||||||
func GetSCGPrices(name string) ([]CardPrice, error) {
|
func GetSCGPrices(name string) ([]CardPrice, error) {
|
||||||
preprocessedName := preprocessNameForSearch(name)
|
preprocessedName := preprocessNameForSearch(name)
|
||||||
|
|
@ -69,7 +69,7 @@ func getPriceContainers(doc *html.Node) []*html.Node {
|
||||||
func fetchPrice(price string) (float64, error) {
|
func fetchPrice(price string) (float64, error) {
|
||||||
split := strings.Split(price, "$")
|
split := strings.Split(price, "$")
|
||||||
if len(split) < 2 {
|
if len(split) < 2 {
|
||||||
return 0, errors.New("Not enough values")
|
return 0, errors.New("not enough values")
|
||||||
}
|
}
|
||||||
p := split[1]
|
p := split[1]
|
||||||
v, err := strconv.ParseFloat(p, 64)
|
v, err := strconv.ParseFloat(p, 64)
|
||||||
|
|
@ -77,9 +77,9 @@ func fetchPrice(price string) (float64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSCGUrl(name string) string {
|
func getSCGUrl(name string) string {
|
||||||
splitted := strings.Split(name, " ")
|
words := strings.Split(name, " ")
|
||||||
scgName := strings.Join(splitted, "+")
|
scgName := strings.Join(words, "+")
|
||||||
url := SCGURL + scgName
|
url := Scgurl + scgName
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ then
|
||||||
sudo docker rmi -f $TEST_IMAGE_NAME
|
sudo docker rmi -f $TEST_IMAGE_NAME
|
||||||
sudo docker build -t $TEST_IMAGE_NAME .
|
sudo docker build -t $TEST_IMAGE_NAME .
|
||||||
TEST_CONTAINER_NAME="go_mtg_vk_test_container"
|
TEST_CONTAINER_NAME="go_mtg_vk_test_container"
|
||||||
sudo docker run --rm --name $TEST_CONTAINER_NAME --network $TEST_NETWORK_NAME -e MODE="test" -e VK_TOKEN=$VK_TOKEN -e VK_SECRET_KEY=$VK_SECRET_KEY -e VK_GROUP_ID=$VK_GROUP_ID -e VK_CONFIRMATION_STRING=$VK_CONFIRMATION_STRING $TEST_IMAGE_NAME
|
sudo docker run --rm --name $TEST_CONTAINER_NAME --network $TEST_NETWORK_NAME -e MODE="test" -e VK_TOKEN="$VK_TOKEN" -e VK_SECRET_KEY="$VK_SECRET_KEY" -e VK_GROUP_ID="$VK_GROUP_ID" -e VK_CONFIRMATION_STRING="$VK_CONFIRMATION_STRING" $TEST_IMAGE_NAME
|
||||||
EXIT_CODE=$(sudo docker inspect $TEST_CONTAINER_NAME --format "{{.State.ExitCode}}")
|
EXIT_CODE=$(sudo docker inspect $TEST_CONTAINER_NAME --format "{{.State.ExitCode}}")
|
||||||
sudo docker rm -f $TEST_REDIS_NAME
|
sudo docker rm -f $TEST_REDIS_NAME
|
||||||
exit $EXIT_CODE
|
exit "$EXIT_CODE"
|
||||||
elif [[ $1 = "prod" ]]
|
elif [[ $1 = "prod" ]]
|
||||||
then
|
then
|
||||||
PROD_NETWORK_NAME="go_mtg_vk_prod_network"
|
PROD_NETWORK_NAME="go_mtg_vk_prod_network"
|
||||||
|
|
@ -26,5 +26,5 @@ then
|
||||||
PROD_CONTAINER_NAME="go_mtg_vk_prod_container"
|
PROD_CONTAINER_NAME="go_mtg_vk_prod_container"
|
||||||
sudo docker stop $PROD_CONTAINER_NAME
|
sudo docker stop $PROD_CONTAINER_NAME
|
||||||
sudo docker rm $PROD_CONTAINER_NAME
|
sudo docker rm $PROD_CONTAINER_NAME
|
||||||
sudo docker run -v /var/log/go_mtg_vk:/go/src/go-mtg-vk/logs -d -p 80:80 --network $PROD_NETWORK_NAME --restart always --name $PROD_CONTAINER_NAME -e MODE="prod" -e VK_TOKEN=$VK_TOKEN -e VK_SECRET_KEY=$VK_SECRET_KEY -e VK_GROUP_ID=$VK_GROUP_ID -e VK_CONFIRMATION_STRING=$VK_CONFIRMATION_STRING $PROD_IMAGE_NAME
|
sudo docker run -v /var/log/go_mtg_vk:/go/src/go-mtg-vk/logs -d -p 80:80 --network $PROD_NETWORK_NAME --restart always --name $PROD_CONTAINER_NAME -e MODE="prod" -e VK_TOKEN="$VK_TOKEN" -e VK_SECRET_KEY="$VK_SECRET_KEY" -e VK_GROUP_ID="$VK_GROUP_ID" -e VK_CONFIRMATION_STRING="$VK_CONFIRMATION_STRING" $PROD_IMAGE_NAME
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@ sudo docker run -d \
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock\
|
-v /var/run/docker.sock:/var/run/docker.sock\
|
||||||
-v jenkins_home_mtg_go:/var/jenkins_home\
|
-v jenkins_home_mtg_go:/var/jenkins_home\
|
||||||
--name $CONTAINER_NAME\
|
--name $CONTAINER_NAME\
|
||||||
-e VK_TOKEN=$VK_TOKEN\
|
-e VK_TOKEN="$VK_TOKEN"\
|
||||||
-e VK_SECRET_KEY=$VK_SECRET_KEY\
|
-e VK_SECRET_KEY="$VK_SECRET_KEY"\
|
||||||
-e VK_GROUP_ID=$VK_GROUP_ID\
|
-e VK_GROUP_ID="$VK_GROUP_ID"\
|
||||||
-e VK_CONFIRMATION_STRING=$VK_CONFIRMATION_STRING\
|
-e VK_CONFIRMATION_STRING="$VK_CONFIRMATION_STRING"\
|
||||||
--name $CONTAINER_NAME\
|
--name $CONTAINER_NAME\
|
||||||
$IMAGE_NAME
|
$IMAGE_NAME
|
||||||
sudo docker exec -it $CONTAINER_NAME sudo service docker start
|
sudo docker exec -it $CONTAINER_NAME sudo service docker start
|
||||||
|
|
|
||||||
3
main.go
3
main.go
|
|
@ -13,10 +13,9 @@ import (
|
||||||
func main() {
|
func main() {
|
||||||
rand.Seed(time.Now().UTC().UnixNano())
|
rand.Seed(time.Now().UTC().UnixNano())
|
||||||
logFile, _ := os.OpenFile("logs/errors.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
logFile, _ := os.OpenFile("logs/errors.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
defer logFile.Close()
|
|
||||||
|
|
||||||
log.SetOutput(logFile)
|
log.SetOutput(logFile)
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
r.POST("callback/message", vk.HandleMessage)
|
r.POST("callback/message", vk.HandleMessage)
|
||||||
r.Run(":80")
|
_ = r.Run(":80")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
const CARDSLIMIT = 8
|
const Cardslimit = 8
|
||||||
|
|
||||||
func min(a, b int) int {
|
func min(a, b int) int {
|
||||||
if a < b {
|
if a < b {
|
||||||
|
|
@ -23,20 +23,20 @@ func min(a, b int) int {
|
||||||
|
|
||||||
func HandleMessage(c *gin.Context) {
|
func HandleMessage(c *gin.Context) {
|
||||||
var req MessageRequest
|
var req MessageRequest
|
||||||
c.BindJSON(&req)
|
_ = c.BindJSON(&req)
|
||||||
if req.Secret != SECRET_KEY {
|
if req.Secret != SecretKey {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch req.Type {
|
switch req.Type {
|
||||||
case "confirmation":
|
case "confirmation":
|
||||||
handleConfirmation(c, &req)
|
handleConfirmation(c, &req)
|
||||||
case "message_new":
|
case "message_new":
|
||||||
go handleSearch(c, &req)
|
go handleSearch(&req)
|
||||||
c.String(http.StatusOK, "ok")
|
c.String(http.StatusOK, "ok")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleSearch(c *gin.Context, req *MessageRequest) {
|
func handleSearch(req *MessageRequest) {
|
||||||
cardName, err := getCardNameByCommand(req.Object.Body)
|
cardName, err := getCardNameByCommand(req.Object.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Message(req.Object.UserId, "Некорректная команда")
|
Message(req.Object.UserId, "Некорректная команда")
|
||||||
|
|
@ -51,7 +51,7 @@ func handleSearch(c *gin.Context, req *MessageRequest) {
|
||||||
log.Printf("Could not find SCG prices\n error message: %s\n card name: %s", err.Error(), cardName)
|
log.Printf("Could not find SCG prices\n error message: %s\n card name: %s", err.Error(), cardName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
elements := min(CARDSLIMIT, len(prices))
|
elements := min(Cardslimit, len(prices))
|
||||||
prices = prices[:elements]
|
prices = prices[:elements]
|
||||||
priceInfo := cardsinfo.FormatCardPrices(cardName, prices)
|
priceInfo := cardsinfo.FormatCardPrices(cardName, prices)
|
||||||
Message(req.Object.UserId, priceInfo)
|
Message(req.Object.UserId, priceInfo)
|
||||||
|
|
@ -74,7 +74,7 @@ func GetPrices(cardName string) ([]cardsinfo.CardPrice, error) {
|
||||||
client.Set(cardName, string(serialized))
|
client.Set(cardName, string(serialized))
|
||||||
return prices, nil
|
return prices, nil
|
||||||
}
|
}
|
||||||
json.Unmarshal([]byte(val), &prices)
|
_ = json.Unmarshal([]byte(val), &prices)
|
||||||
return prices, nil
|
return prices, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,7 +96,7 @@ func getCardNameByCommand(command string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleConfirmation(c *gin.Context, req *MessageRequest) {
|
func handleConfirmation(c *gin.Context, req *MessageRequest) {
|
||||||
if (req.Type == "confirmation") && (req.GroupId == GROUPID) {
|
if (req.Type == "confirmation") && (req.GroupId == GroupId) {
|
||||||
c.String(http.StatusOK, CONFIRMATION_STRING)
|
c.String(http.StatusOK, ConfirmationString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package vk
|
package vk
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
@ -8,17 +9,20 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const VKURL = "https://api.vk.com/method/messages.send"
|
const SendMessageUrl = "https://api.vk.com/method/messages.send"
|
||||||
|
|
||||||
func Message(userId int64, message string) {
|
func Message(userId int64, message string) {
|
||||||
randomId := rand.Int31()
|
randomId := rand.Int31()
|
||||||
params := []string{
|
params := []string{
|
||||||
"access_token=" + TOKEN,
|
"access_token=" + Token,
|
||||||
"peer_id=" + strconv.FormatInt(userId, 10),
|
"peer_id=" + strconv.FormatInt(userId, 10),
|
||||||
"message=" + url.QueryEscape(message),
|
"message=" + url.QueryEscape(message),
|
||||||
"v=5.95",
|
"v=5.95",
|
||||||
"random_id=" + strconv.FormatInt(int64(randomId), 10),
|
"random_id=" + strconv.FormatInt(int64(randomId), 10),
|
||||||
}
|
}
|
||||||
paramString := strings.Join(params, "&")
|
paramString := strings.Join(params, "&")
|
||||||
http.Get(VKURL + "?" + paramString)
|
resp, err := http.Get(SendMessageUrl + "?" + paramString)
|
||||||
|
if err != nil || resp.StatusCode != http.StatusOK {
|
||||||
|
log.Print("Could not send message\n user: %lld", userId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var TOKEN = os.Getenv("VK_TOKEN")
|
var Token = os.Getenv("VK_TOKEN")
|
||||||
var SECRET_KEY = os.Getenv("VK_SECRET_KEY")
|
var SecretKey = os.Getenv("VK_SECRET_KEY")
|
||||||
var GROUPID, _ = strconv.ParseInt(os.Getenv("VK_GROUP_ID"), 10, 64)
|
var GroupId, _ = strconv.ParseInt(os.Getenv("VK_GROUP_ID"), 10, 64)
|
||||||
var CONFIRMATION_STRING = os.Getenv("VK_CONFIRMATION_STRING")
|
var ConfirmationString = os.Getenv("VK_CONFIRMATION_STRING")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue