add line webhook router
This commit is contained in:
parent
9d9fe262f4
commit
4726070ea5
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
||||
config.yml
|
||||
*.swp
|
||||
modules/schema/static.go
|
||||
|
14
Dockerfile
Normal file
14
Dockerfile
Normal file
@ -0,0 +1,14 @@
|
||||
FROM golang:1.11-alpine3.8 as builder
|
||||
WORKDIR /go/src/git.trj.tw/golang/mtgbot
|
||||
RUN apk add --no-cache make git \
|
||||
&& go get -u github.com/otakukaze/go-bindata/...
|
||||
COPY . .
|
||||
RUN make
|
||||
|
||||
FROM alpine:latest
|
||||
RUN apk add --no-cache ca-certificates
|
||||
WORKDIR /data
|
||||
COPY --from=builder /go/src/git.trj.tw/golang/mtgbot/mtgbot /usr/bin
|
||||
COPY config.sample.yml config.yml
|
||||
EXPOSE 10230
|
||||
CMD ["/usr/bin/mtgbot", "-f", "/data/config.yml", "-dbtool"]
|
9
Makefile
Normal file
9
Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
.PHONY: clean build
|
||||
|
||||
build:
|
||||
go-bindata -pkg schema -ignore .git -o modules/schema/static.go schema/
|
||||
GOOS=linux go build -o mtgbot -ldflags "-s -w" .
|
||||
|
||||
clean:
|
||||
rm -rf mtgbot && go clean
|
@ -1,4 +1,4 @@
|
||||
port: 10231
|
||||
port: 10230
|
||||
|
||||
line:
|
||||
access:
|
||||
|
43
go.mod
43
go.mod
@ -2,51 +2,24 @@ module git.trj.tw/golang/mtgbot
|
||||
|
||||
require (
|
||||
git.trj.tw/golang/utils v0.0.0-20181219032659-b1a8bce04189
|
||||
github.com/alecthomas/gometalinter v2.0.12+incompatible // indirect
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
|
||||
github.com/cosiner/argv v0.0.1 // indirect
|
||||
github.com/davidrjenni/reftools v0.0.0-20180914123528-654d0ba4f96d // indirect
|
||||
github.com/derekparker/delve v1.1.0 // indirect
|
||||
github.com/dustin/go-broadcast v0.0.0-20171205050544-f664265f5a66 // indirect
|
||||
github.com/fatih/gomodifytags v0.0.0-20180914191908-141225bf62b6 // indirect
|
||||
github.com/fatih/motion v0.0.0-20180408211639-218875ebe238 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 // indirect
|
||||
github.com/gin-gonic/autotls v0.0.0-20180426091246-be87bd5ef97b // indirect
|
||||
github.com/gin-gonic/gin v1.3.0
|
||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf // indirect
|
||||
github.com/jessevdk/go-assets v0.0.0-20160921144138-4f4301a06e15 // indirect
|
||||
github.com/josharian/impl v0.0.0-20180228163738-3d0f908298c4 // indirect
|
||||
github.com/golang/protobuf v1.2.0 // indirect
|
||||
github.com/jmoiron/sqlx v1.2.0
|
||||
github.com/json-iterator/go v1.1.5 // indirect
|
||||
github.com/jstemmer/gotags v1.4.1 // indirect
|
||||
github.com/kisielk/errcheck v1.1.0 // indirect
|
||||
github.com/klauspost/asmfmt v1.2.0 // indirect
|
||||
github.com/koron/iferr v0.0.0-20180615142939-bb332a3b1d91 // indirect
|
||||
github.com/manucorporat/stats v0.0.0-20180402194714-3ba42d56d227 // indirect
|
||||
github.com/lib/pq v1.0.0
|
||||
github.com/mattn/go-isatty v0.0.4 // indirect
|
||||
github.com/mdempsky/gocode v0.0.0-20181212191131-9c77a290fde2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/nicksnyder/go-i18n v1.10.0 // indirect
|
||||
github.com/pelletier/go-toml v1.2.0 // indirect
|
||||
github.com/peterh/liner v1.1.0 // indirect
|
||||
github.com/rogpeppe/godef v1.1.1 // indirect
|
||||
github.com/sirupsen/logrus v1.2.0 // indirect
|
||||
github.com/spf13/cobra v0.0.3 // indirect
|
||||
github.com/spf13/pflag v1.0.3 // indirect
|
||||
github.com/stamblerre/gocode v0.0.0-20181212030458-2f9d39d8f31d // indirect
|
||||
github.com/thinkerou/favicon v0.1.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.2.2 // indirect
|
||||
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2 // indirect
|
||||
github.com/zmb3/gogetdoc v0.0.0-20181208215853-c5ca8f4d4936 // indirect
|
||||
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 // indirect
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 // indirect
|
||||
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1 // indirect
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3 // indirect
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
|
||||
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6 // indirect
|
||||
golang.org/x/tools v0.0.0-20181221235234-d00ac6d27372 // indirect
|
||||
google.golang.org/grpc v1.17.0 // indirect
|
||||
gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20180810215634-df19058c872c // indirect
|
||||
google.golang.org/appengine v1.1.0 // indirect
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.2
|
||||
honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3 // indirect
|
||||
)
|
||||
|
118
go.sum
118
go.sum
@ -1,136 +1,48 @@
|
||||
9fans.net/go v0.0.0-20181112161441-237454027057 h1:OcHlKWkAMJEF1ndWLGxp5dnJQkYM/YImUOvsBoz6h5E=
|
||||
9fans.net/go v0.0.0-20181112161441-237454027057/go.mod h1:diCsxrliIURU9xsYtjCp5AbpQKqdhKmf0ujWDUSkfoY=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
git.trj.tw/golang/utils v0.0.0-20181219032659-b1a8bce04189 h1:KHFlWRVFd5NIsnnFSy090+k6kT7KRotxUPTsho6F9lk=
|
||||
git.trj.tw/golang/utils v0.0.0-20181219032659-b1a8bce04189/go.mod h1:yE+qbsUsijCTdwsaQRkPT1CXYk7ftMzXsCaaYx/0QI0=
|
||||
github.com/alecthomas/gometalinter v2.0.12+incompatible h1:RBUbc8pKtqRoVCymENDl7cpWS9Ht5XNnwwk0cKjpteI=
|
||||
github.com/alecthomas/gometalinter v2.0.12+incompatible/go.mod h1:qfIpQGGz3d+NmgyPBqv+LSh50emm1pt72EtcX2vKYQk=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cosiner/argv v0.0.1 h1:2iAFN+sWPktbZ4tvxm33Ei8VY66FPCxdOxpncUGpAXE=
|
||||
github.com/cosiner/argv v0.0.1/go.mod h1:p/NrK5tF6ICIly4qwEDsf6VDirFiWWz0FenfYBwJaKQ=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davidrjenni/reftools v0.0.0-20180914123528-654d0ba4f96d h1:aRvyac5PN1NEfcANJ1tfs8GMs5I9OXsVeg0FJkpXOys=
|
||||
github.com/davidrjenni/reftools v0.0.0-20180914123528-654d0ba4f96d/go.mod h1:8o/GRMvsb9VyFbSEZGXfa0dkSXml4G23W0D/h9FksWM=
|
||||
github.com/derekparker/delve v1.1.0 h1:icd65nMp7s2HiLz6y/6RCVXBdoED3xxYLwX09EMaRCc=
|
||||
github.com/derekparker/delve v1.1.0/go.mod h1:pMSZMfp0Nhbm8qdZJkuE/yPGOkLpGXLS1I4poXQpuJU=
|
||||
github.com/dustin/go-broadcast v0.0.0-20171205050544-f664265f5a66 h1:QnnoVdChKs+GeTvN4rPYTW6b5U6M3HMEvQ/+x4IGtfY=
|
||||
github.com/dustin/go-broadcast v0.0.0-20171205050544-f664265f5a66/go.mod h1:kTEh6M2J/mh7nsskr28alwLCXm/DSG5OSA/o31yy2XU=
|
||||
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
|
||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||
github.com/fatih/gomodifytags v0.0.0-20180914191908-141225bf62b6 h1:iXJdM8Uob6EPOG/PFr5q0J124ysiZdJfACHqICBb3b8=
|
||||
github.com/fatih/gomodifytags v0.0.0-20180914191908-141225bf62b6/go.mod h1:p2/x7bnOQsbq/deXsDIlj2yLiKFGPkD2nuoYqwn8R4Y=
|
||||
github.com/fatih/motion v0.0.0-20180408211639-218875ebe238 h1:Qo4RxRMFag+fvDqQ6A3MblYBormptQUZ1ssOtV+EeQ8=
|
||||
github.com/fatih/motion v0.0.0-20180408211639-218875ebe238/go.mod h1:pseIrV+t9A4+po+KJ1LheSnYH8m1qs6WhKx2zFiGi9I=
|
||||
github.com/fatih/structtag v1.0.0 h1:pTHj65+u3RKWYPSGaU290FpI/dXxTaHdVwVwbcPKmEc=
|
||||
github.com/fatih/structtag v1.0.0/go.mod h1:IKitwq45uXL/yqi5mYghiD3w9H6eTOvI9vnk8tXMphA=
|
||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 h1:AzN37oI0cOS+cougNAV9szl6CVoj2RYwzS3DpUQNtlY=
|
||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-gonic/autotls v0.0.0-20180426091246-be87bd5ef97b h1:dm/NYytoj7p8Jc6zMvyRz3PCQrTTCXnVRvEzyBcM890=
|
||||
github.com/gin-gonic/autotls v0.0.0-20180426091246-be87bd5ef97b/go.mod h1:vwfeXwKgEIWq63oVfwaBjoByS4dZzYbHHROHjV4IjNY=
|
||||
github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs=
|
||||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg=
|
||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
|
||||
github.com/jessevdk/go-assets v0.0.0-20160921144138-4f4301a06e15 h1:cW/amwGEJK5MSKntPXRjX4dxs/nGxGT8gXKIsKFmHGc=
|
||||
github.com/jessevdk/go-assets v0.0.0-20160921144138-4f4301a06e15/go.mod h1:Fdm/oWRW+CH8PRbLntksCNtmcCBximKPkVQYvmMl80k=
|
||||
github.com/josharian/impl v0.0.0-20180228163738-3d0f908298c4 h1:gmIVMdGlVf5e6Yo6+ZklxdOrvtOvyrAjJyXAbmOznyo=
|
||||
github.com/josharian/impl v0.0.0-20180228163738-3d0f908298c4/go.mod h1:t4Tr0tn92eq5ISef4cS5plFAMYAqZlAXtgUcKE6y8nw=
|
||||
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE=
|
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jstemmer/gotags v1.4.1 h1:aWIyXsU3lTDqhsEC49MP85p2cUUWr2ptvdGNqqGA3r4=
|
||||
github.com/jstemmer/gotags v1.4.1/go.mod h1:b6J3X0bsLbR4C5SgSx3V3KjuWTtmRzcmWPbTkWZ49PA=
|
||||
github.com/kisielk/errcheck v1.1.0 h1:ZqfnKyx9KGpRcW04j5nnPDgRgoXUeLh2YFBeFzphcA0=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/asmfmt v1.2.0 h1:zwsyBYgEdabg32alMful/5pRtMTcR5C5w1LKNg9OD78=
|
||||
github.com/klauspost/asmfmt v1.2.0/go.mod h1:RAoUvqkWr2rUa2I19qKMEVZQe4BVtcHGTMCUOcCU2Lg=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/koron/iferr v0.0.0-20180615142939-bb332a3b1d91 h1:hunjgdb3b21ZdRmzDPXii0EcnHpjH7uCP+kODoE1JH0=
|
||||
github.com/koron/iferr v0.0.0-20180615142939-bb332a3b1d91/go.mod h1:C2tFh8w3I6i4lnUJfoBx2Hwku3mgu4wPNTtUNp1i5KI=
|
||||
github.com/manucorporat/stats v0.0.0-20180402194714-3ba42d56d227 h1:KIaAZ/V+/0/6BOULrmBQ9T1ed8BkKqGIjIKW923nJuo=
|
||||
github.com/manucorporat/stats v0.0.0-20180402194714-3ba42d56d227/go.mod h1:ruMr5t05gVho4tuDv0PbI0Bb8nOxc/5Y6JzRHe/yfA0=
|
||||
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4=
|
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mdempsky/gocode v0.0.0-20181212191131-9c77a290fde2 h1:OqIVo8a2x2U2cn0+W044cmL3kSdCX5Rc7kRnK3ZRyAI=
|
||||
github.com/mdempsky/gocode v0.0.0-20181212191131-9c77a290fde2/go.mod h1:hltEC42XzfMNgg0S1v6JTywwra2Mu6F6cLR03debVQ8=
|
||||
github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/nicksnyder/go-i18n v1.10.0 h1:5AzlPKvXBH4qBzmZ09Ua9Gipyruv6uApMcrNZdo96+Q=
|
||||
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterh/liner v1.1.0 h1:f+aAedNJA6uk7+6rXsYBnhdo4Xux7ESLe+kcuVUF5os=
|
||||
github.com/peterh/liner v1.1.0/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/godef v1.1.1 h1:NujOtt9q9vIClRTB3sCZpavac+NMRaIayzrcz1h4fSE=
|
||||
github.com/rogpeppe/godef v1.1.1/go.mod h1:oEo1eMy1VUEHUzUIX4F7IqvMJRiz9UId44mvnR8oPlQ=
|
||||
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stamblerre/gocode v0.0.0-20181212030458-2f9d39d8f31d h1:Bpu5DolLksGPpggDvoP5l9aruCElc6a47pHOSWwL74A=
|
||||
github.com/stamblerre/gocode v0.0.0-20181212030458-2f9d39d8f31d/go.mod h1:EM2T8YDoTCvGXbEpFHxarbpv7VE26QD1++Cb1Pbh7Gs=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/thinkerou/favicon v0.1.0 h1:eWMISKTpHq2G8HOuKn7ydD55j5DDehx94b0C2y8ABMs=
|
||||
github.com/thinkerou/favicon v0.1.0/go.mod h1:HL7Pap5kOluZv1ku34pZo/AJ44GaxMEPFZ3pmuexV2s=
|
||||
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2 h1:EICbibRW4JNKMcY+LsWmuwob+CRS1BmdRdjphAm9mH4=
|
||||
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/zmb3/gogetdoc v0.0.0-20181208215853-c5ca8f4d4936 h1:+We2eeE8UuACEPcT7Ez1/yK0MN6SAqzy6S2JPxJTycQ=
|
||||
github.com/zmb3/gogetdoc v0.0.0-20181208215853-c5ca8f4d4936/go.mod h1:ofmGw6LrMypycsiWcyug6516EXpIxSbZ+uI9ppGypfY=
|
||||
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 h1:Pn8fQdvx+z1avAi7fdM2kRYWQNxGlavNDSyzrQg2SsU=
|
||||
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1 h1:rJm0LuqUjoDhSk2zO9ISMSToQxGz7Os2jRiOL8AWu4c=
|
||||
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3 h1:eH6Eip3UpmR+yM/qI9Ijluzb1bNv/cAU/n+6l8tRSis=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6 h1:IcgEB62HYgAhX0Nd/QrVgZlxlcyxbGQHElLUhW2X4Fo=
|
||||
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180824175216-6c1c5e93cdc1/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181130195746-895048a75ecf/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181207195948-8634b1ecd393/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181221235234-d00ac6d27372 h1:zWPUEY/PjVHT+zO3L8OfkjrtIjf55joTxn/RQP/AjOI=
|
||||
golang.org/x/tools v0.0.0-20181221235234-d00ac6d27372/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/grpc v1.17.0 h1:TRJYBgMclJvGYn2rIMjj+h9KtMt5r1Ij7ODVRIZkwhk=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20180810215634-df19058c872c h1:vTxShRUnK60yd8DZU+f95p1zSLj814+5CuEh7NjF2/Y=
|
||||
gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20180810215634-df19058c872c/go.mod h1:3HH7i1SgMqlzxCcBmUHW657sD4Kvv9sC3HpL3YukzwA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3 h1:LyX67rVB0kBUFoROrQfzKwdrYLH1cRzHibxdJW85J1c=
|
||||
honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
12
main.go
12
main.go
@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"git.trj.tw/golang/mtgbot/models"
|
||||
"git.trj.tw/golang/mtgbot/modules/cmd"
|
||||
"git.trj.tw/golang/mtgbot/modules/config"
|
||||
"git.trj.tw/golang/mtgbot/modules/options"
|
||||
"git.trj.tw/golang/mtgbot/router/routes"
|
||||
@ -24,6 +26,14 @@ func main() {
|
||||
}
|
||||
conf := config.GetConf()
|
||||
|
||||
if opts.DBTool {
|
||||
cmd.DBTool()
|
||||
}
|
||||
|
||||
// init database connection
|
||||
db := models.NewDB()
|
||||
defer db.Close()
|
||||
|
||||
// register session object types
|
||||
regTypes()
|
||||
|
||||
@ -34,4 +44,6 @@ func main() {
|
||||
|
||||
func regTypes() {
|
||||
gob.Register(map[string]interface{}{})
|
||||
gob.Register(models.Cards{})
|
||||
gob.Register(models.Sets{})
|
||||
}
|
||||
|
146
models/cards.go
Normal file
146
models/cards.go
Normal file
@ -0,0 +1,146 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
// Cards -
|
||||
type Cards struct {
|
||||
ID string `db:"id" cc:"id"`
|
||||
Name string `db:"name" cc:"name"`
|
||||
CMC float32 `db:"cmc" cc:"cmc"`
|
||||
ManaCost string `db:"mana_cost" cc:"mana_cost"`
|
||||
Set string `db:"set" cc:"set"`
|
||||
Text string `db:"text" cc:"text"`
|
||||
Layout string `db:"layout" cc:"layout"`
|
||||
ImageURL string `db:"image_url" cc:"image_url"`
|
||||
Loyalty string `db:"loyalty" cc:"loyalty"`
|
||||
Type string `db:"type" cc:"type"`
|
||||
Number string `db:"number" cc:"number"`
|
||||
Power string `db:"power" cc:"power"`
|
||||
Toughness string `db:"toughness" cc:"toughness"`
|
||||
Names []string `db:"names" cc:"names"`
|
||||
Colors []string `db:"colors" cc:"colors"`
|
||||
ColorIdentity []string `db:"color_identity" cc:"color_identity"`
|
||||
Types []string `db:"types" cc:"types"`
|
||||
Subtypes []string `db:"subtypes" cc:"subtypes"`
|
||||
Supertypes []string `db:"supertypes" cc:"supertypes"`
|
||||
}
|
||||
|
||||
// order opts
|
||||
const (
|
||||
CardSearchOrderByName OrderStr = `c."name" asc`
|
||||
CardSearchOrderByNameDesc = `c."name" desc`
|
||||
CardSearchOrderByCMC = `c."cmc" asc`
|
||||
CardSearchOrderByCMCDesc = `c."cmc" desc"`
|
||||
)
|
||||
|
||||
// CardSearchCMC -
|
||||
type CardSearchCMC struct {
|
||||
Op OpStr
|
||||
Val float32
|
||||
}
|
||||
|
||||
// ListCardsOpts -
|
||||
type ListCardsOpts struct {
|
||||
OrderBy OrderStr
|
||||
Name string
|
||||
CMC *CardSearchCMC
|
||||
Set string
|
||||
Types []string
|
||||
Limit int
|
||||
Offset int
|
||||
}
|
||||
|
||||
// CountCards -
|
||||
func CountCards(arg ListCardsOpts) (c int, err error) {
|
||||
c = 0
|
||||
query := `select count(*) as count from "public"."cards" c`
|
||||
where := struct {
|
||||
Name string `db:"name"`
|
||||
CMC float32 `db:"name"`
|
||||
Set string `db:"set"`
|
||||
}{}
|
||||
|
||||
whereStr := []string{}
|
||||
if len(arg.Name) > 0 {
|
||||
where.Name = arg.Name
|
||||
whereStr = append(whereStr, `c."name" = :name`)
|
||||
}
|
||||
if len(arg.Set) > 0 {
|
||||
where.Set = arg.Set
|
||||
whereStr = append(whereStr, `c."set" = :set`)
|
||||
}
|
||||
if arg.CMC != nil {
|
||||
where.CMC = arg.CMC.Val
|
||||
whereStr = append(whereStr, fmt.Sprintf(`c."cmc" %s :cmc`, arg.CMC.Op))
|
||||
}
|
||||
|
||||
wStr := ""
|
||||
if len(whereStr) > 0 {
|
||||
wStr = fmt.Sprintf("where %s", strings.Join(whereStr, " and "))
|
||||
}
|
||||
|
||||
query = fmt.Sprintf("%s %s",
|
||||
query,
|
||||
wStr)
|
||||
q, a, err := sqlx.Named(query, where)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
err = x.Get(&c, q, a...)
|
||||
return
|
||||
}
|
||||
|
||||
// ListCards -
|
||||
func ListCards(arg ListCardsOpts) (cards []*Cards, err error) {
|
||||
if arg.Limit < 1 {
|
||||
arg.Limit = 1
|
||||
}
|
||||
if arg.Offset < 0 {
|
||||
arg.Offset = 0
|
||||
}
|
||||
query := `select c.id, c.name, c.cmc, c.mana_cost, c.text, c.layout, c.image_url, c.loyalty,
|
||||
c.type, c.number, c.power, c.toughness, c.set from "public"."cards" c`
|
||||
where := struct {
|
||||
Name string `db:"name"`
|
||||
CMC float32 `db:"cmc"`
|
||||
Set string `db:"set"`
|
||||
}{}
|
||||
whereStr := []string{}
|
||||
if len(arg.Name) > 0 {
|
||||
where.Name = arg.Name
|
||||
whereStr = append(whereStr, `c."name" = :name`)
|
||||
}
|
||||
if len(arg.Set) > 0 {
|
||||
where.Set = arg.Set
|
||||
whereStr = append(whereStr, `c."set" = :set`)
|
||||
}
|
||||
if arg.CMC != nil {
|
||||
where.CMC = arg.CMC.Val
|
||||
whereStr = append(whereStr, fmt.Sprintf(`c."cmc" %s :cmc`, arg.CMC.Op))
|
||||
}
|
||||
|
||||
wStr := ""
|
||||
if len(whereStr) > 0 {
|
||||
wStr = fmt.Sprintf("where %s", strings.Join(whereStr, " and "))
|
||||
}
|
||||
|
||||
query = fmt.Sprintf("%s %s %s %s",
|
||||
query,
|
||||
wStr,
|
||||
arg.OrderBy,
|
||||
fmt.Sprintf("limit %d offset %d", arg.Limit, arg.Offset))
|
||||
q, a, err := sqlx.Named(query, where)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = x.Select(&cards, q, a...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
72
models/models.go
Normal file
72
models/models.go
Normal file
@ -0,0 +1,72 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"git.trj.tw/golang/mtgbot/modules/config"
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
var x *sqlx.DB
|
||||
|
||||
// NewDB -
|
||||
func NewDB() *sqlx.DB {
|
||||
var err error
|
||||
conf := config.GetConf()
|
||||
userPassStr := conf.Database.User
|
||||
if len(conf.Database.Pass) > 0 {
|
||||
userPassStr += ":" + conf.Database.Pass
|
||||
}
|
||||
|
||||
connStr := fmt.Sprintf("postgres://%s@%s/%s?sslmode=disable", userPassStr, conf.Database.Host, conf.Database.DB)
|
||||
|
||||
x, err = sqlx.Connect("postgres", connStr)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
x.SetMaxIdleConns(10)
|
||||
x.SetMaxOpenConns(100)
|
||||
err = x.Ping()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return x
|
||||
}
|
||||
|
||||
// String - get string ptr
|
||||
func String(s string) *string {
|
||||
return &s
|
||||
}
|
||||
|
||||
// Int - get int ptr
|
||||
func Int(i int) *int {
|
||||
return &i
|
||||
}
|
||||
|
||||
// OrderStr -
|
||||
type OrderStr string
|
||||
|
||||
func (o OrderStr) String() string {
|
||||
return string(o)
|
||||
}
|
||||
|
||||
// OpStr -
|
||||
type OpStr string
|
||||
|
||||
func (s OpStr) String() string {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
// Op var
|
||||
const (
|
||||
SearchOpEq OpStr = "="
|
||||
SearchOpNeq = "!="
|
||||
SearchOpLt = "<"
|
||||
SearchOpLte = "<="
|
||||
SearchOpGt = ">"
|
||||
SearchOpGte = ">="
|
||||
)
|
114
models/sets.go
Normal file
114
models/sets.go
Normal file
@ -0,0 +1,114 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
// Sets - product set
|
||||
type Sets struct {
|
||||
Code string `db:"code" cc:"code"`
|
||||
Name string `db:"name" cc:"name"`
|
||||
ReleaseDate time.Time `db:"release_date" cc:"release_date"`
|
||||
}
|
||||
|
||||
// ListSetsOpts -
|
||||
type ListSetsOpts struct {
|
||||
OrderBy OrderStr
|
||||
Code []string
|
||||
Limit, Offset int
|
||||
}
|
||||
|
||||
// order opts
|
||||
const (
|
||||
SetSearchOrderByName OrderStr = `s."name" asc`
|
||||
SetSearchOrderByNameDesc = `s."name" desc`
|
||||
)
|
||||
|
||||
// CountSets -
|
||||
func CountSets(arg ListSetsOpts) (c int, err error) {
|
||||
c = 0
|
||||
query := `select count(*) as count from "public"."sets" s`
|
||||
|
||||
where := struct {
|
||||
Code []string `db:"code"`
|
||||
}{}
|
||||
whereStr := []string{}
|
||||
|
||||
if len(arg.Code) > 0 {
|
||||
where.Code = arg.Code
|
||||
whereStr = append(whereStr, `s."code" in (:code)`)
|
||||
}
|
||||
|
||||
wStr := ""
|
||||
if len(whereStr) > 0 {
|
||||
wStr = fmt.Sprintf(`where %s`, strings.Join(whereStr, " and "))
|
||||
}
|
||||
|
||||
query = fmt.Sprintf("%s %s", query, wStr)
|
||||
|
||||
query, args, err := sqlx.Named(query, where)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
query, args, err = sqlx.In(query, args)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
query = x.Rebind(query)
|
||||
|
||||
err = x.Get(&c, query, args...)
|
||||
return
|
||||
}
|
||||
|
||||
// ListSets -
|
||||
func ListSets(arg ListSetsOpts) (sets []*Sets, err error) {
|
||||
if arg.Limit < 1 {
|
||||
arg.Limit = 1
|
||||
}
|
||||
if arg.Offset < 0 {
|
||||
arg.Offset = 0
|
||||
}
|
||||
query := `select s.code, s.name, s.release_date from "public"."sets" s`
|
||||
|
||||
where := struct {
|
||||
Code []string `db:"code"`
|
||||
}{}
|
||||
whereStr := []string{}
|
||||
|
||||
if len(arg.Code) > 0 {
|
||||
where.Code = arg.Code
|
||||
whereStr = append(whereStr, `s."code" in (:code)`)
|
||||
}
|
||||
|
||||
wStr := ""
|
||||
if len(whereStr) > 0 {
|
||||
wStr = fmt.Sprintf("where %s", strings.Join(whereStr, " and "))
|
||||
}
|
||||
|
||||
query = fmt.Sprintf("%s %s %s %s",
|
||||
query,
|
||||
wStr,
|
||||
arg.OrderBy,
|
||||
fmt.Sprintf("limit %d offset %d", arg.Limit, arg.Offset))
|
||||
|
||||
query, args, err := sqlx.Named(query, where)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query, args, err = sqlx.In(query, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query = x.Rebind(query)
|
||||
|
||||
err = x.Select(&sets, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
72
modules/apimsg/apimsg.go
Normal file
72
modules/apimsg/apimsg.go
Normal file
@ -0,0 +1,72 @@
|
||||
package apimsg
|
||||
|
||||
// ResObject -
|
||||
type ResObject struct {
|
||||
Status int
|
||||
Obj interface{}
|
||||
}
|
||||
|
||||
var objs = map[string]*ResObject{
|
||||
"Success": &ResObject{
|
||||
Status: 200,
|
||||
Obj: map[string]string{
|
||||
"message": "success",
|
||||
},
|
||||
},
|
||||
"InternalError": &ResObject{
|
||||
Status: 500,
|
||||
Obj: map[string]string{
|
||||
"message": "internal error",
|
||||
},
|
||||
},
|
||||
"NotFound": &ResObject{
|
||||
Status: 400,
|
||||
Obj: map[string]string{
|
||||
"message": "not found",
|
||||
},
|
||||
},
|
||||
"DataFormat": &ResObject{
|
||||
Status: 400,
|
||||
Obj: map[string]string{
|
||||
"message": "data format error",
|
||||
},
|
||||
},
|
||||
"LoginFirst": &ResObject{
|
||||
Status: 401,
|
||||
Obj: map[string]string{
|
||||
"message": "login first",
|
||||
},
|
||||
},
|
||||
"Forbidden": &ResObject{
|
||||
Status: 403,
|
||||
Obj: map[string]string{
|
||||
"message": "forbidden",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// GetRes -
|
||||
func GetRes(name string, msg interface{}) *ResObject {
|
||||
obj, ok := objs[name]
|
||||
if !ok {
|
||||
obj = objs["InternalError"]
|
||||
}
|
||||
|
||||
resobj := &ResObject{}
|
||||
resobj.Status = obj.Status
|
||||
switch msg.(type) {
|
||||
case string:
|
||||
tmp := make(map[string]string)
|
||||
tmp["message"] = msg.(string)
|
||||
resobj.Obj = tmp
|
||||
break
|
||||
case map[string]interface{}:
|
||||
case map[string]string:
|
||||
resobj.Obj = msg
|
||||
break
|
||||
default:
|
||||
resobj.Obj = obj.Obj
|
||||
}
|
||||
|
||||
return resobj
|
||||
}
|
@ -1 +1,84 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"log"
|
||||
|
||||
"git.trj.tw/golang/mtgbot/models"
|
||||
"git.trj.tw/golang/mtgbot/modules/schema"
|
||||
)
|
||||
|
||||
// DBTool - run db deploy
|
||||
func DBTool() {
|
||||
db := models.NewDB()
|
||||
defer db.Close()
|
||||
|
||||
if db == nil {
|
||||
log.Fatal(errors.New("database object is nil"))
|
||||
}
|
||||
|
||||
dbver, err := schema.ReadVersions()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
version := -1
|
||||
vcExists := false
|
||||
|
||||
// check version_ctrl table exists
|
||||
row := db.QueryRowx(`select exists(select 1 from "information_schema"."tables" where "table_schema" = $1 and "table_name" = $2) as exists`, "public", "version_ctrl")
|
||||
err = row.Scan(&vcExists)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if vcExists {
|
||||
row := db.QueryRowx(`select max(version) as version from "public"."version_ctrl"`)
|
||||
err := row.Scan(&version)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("Database Schema Version is ", version)
|
||||
var vers []schema.VersionInfo
|
||||
for _, v := range dbver.Versions {
|
||||
if v.Version > version {
|
||||
vers = append(vers, v)
|
||||
}
|
||||
}
|
||||
if len(vers) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
tx, err := db.Beginx()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, v := range vers {
|
||||
log.Printf("Run Version: %d, FileName: %s\n", v.Version, v.File)
|
||||
query, err := schema.ReadSchema(v.File)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// run schema file
|
||||
_, err = tx.Exec(query)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// insert version data
|
||||
_, err = tx.Exec(`insert into "public"."version_ctrl" ("version", "str") values ($1, $2)`, v.Version, query)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
package context
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
import "github.com/gin-gonic/gin/binding"
|
||||
import (
|
||||
"git.trj.tw/golang/mtgbot/modules/apimsg"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// Context - custom http context
|
||||
type Context struct {
|
||||
@ -31,3 +34,39 @@ func (c *Context) BindData(i interface{}) error {
|
||||
func (c *Context) CustomRes(status int, msg interface{}) {
|
||||
c.AbortWithStatusJSON(status, msg)
|
||||
}
|
||||
|
||||
// LoginFirst -
|
||||
func (c *Context) LoginFirst(msg interface{}) {
|
||||
obj := apimsg.GetRes("LoginFirst", msg)
|
||||
c.AbortWithStatusJSON(obj.Status, obj.Obj)
|
||||
}
|
||||
|
||||
// NotFound -
|
||||
func (c *Context) NotFound(msg interface{}) {
|
||||
obj := apimsg.GetRes("NotFound", msg)
|
||||
c.AbortWithStatusJSON(obj.Status, obj.Obj)
|
||||
}
|
||||
|
||||
// DataFormat -
|
||||
func (c *Context) DataFormat(msg interface{}) {
|
||||
obj := apimsg.GetRes("DataFormat", msg)
|
||||
c.AbortWithStatusJSON(obj.Status, obj.Obj)
|
||||
}
|
||||
|
||||
// Forbidden -
|
||||
func (c *Context) Forbidden(msg interface{}) {
|
||||
obj := apimsg.GetRes("Forbidden", msg)
|
||||
c.AbortWithStatusJSON(obj.Status, obj.Obj)
|
||||
}
|
||||
|
||||
// Success -
|
||||
func (c *Context) Success(msg interface{}) {
|
||||
obj := apimsg.GetRes("Success", msg)
|
||||
c.AbortWithStatusJSON(obj.Status, obj.Obj)
|
||||
}
|
||||
|
||||
// ServerError -
|
||||
func (c *Context) ServerError(msg interface{}) {
|
||||
obj := apimsg.GetRes("InternalError", msg)
|
||||
c.AbortWithStatusJSON(obj.Status, obj.Obj)
|
||||
}
|
||||
|
70
modules/lineobj/lineobj.go
Normal file
70
modules/lineobj/lineobj.go
Normal file
@ -0,0 +1,70 @@
|
||||
package lineobj
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// SourceObject -
|
||||
type SourceObject struct {
|
||||
Type string `json:"type" cc:"type"`
|
||||
UserID string `json:"userId" cc:"userId"`
|
||||
GroupID string `json:"groupId" cc:"groupId"`
|
||||
}
|
||||
|
||||
// EventObject -
|
||||
type EventObject struct {
|
||||
Source *SourceObject `json:"source" cc:"source"`
|
||||
Type string `json:"type" cc:"type"`
|
||||
Timestamp int64 `json:"timestamp" cc:"timestamp"`
|
||||
ReplyToken string `json:"replyToken" cc:"replyToken"`
|
||||
Message map[string]interface{} `json:"message" cc:"message"`
|
||||
}
|
||||
|
||||
// HookEvent -
|
||||
type HookEvent struct {
|
||||
Events []*EventObject `json:"events"`
|
||||
}
|
||||
|
||||
// ParseWebhookBody -
|
||||
func ParseWebhookBody(b []byte) *HookEvent {
|
||||
if len(b) == 0 {
|
||||
return nil
|
||||
}
|
||||
evt := &HookEvent{}
|
||||
err := json.Unmarshal(b, evt)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return evt
|
||||
}
|
||||
|
||||
// MessageEvent -
|
||||
func MessageEvent(e *EventObject) {
|
||||
switch e.Type {
|
||||
case "message":
|
||||
// TODO
|
||||
break
|
||||
default:
|
||||
fmt.Printf("line webhook type not match (%v)", e.Type)
|
||||
}
|
||||
}
|
||||
|
||||
func messageType(e *EventObject) {
|
||||
msg := e.Message
|
||||
mtype, ok := msg["type"]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if t, ok := mtype.(string); ok {
|
||||
switch t {
|
||||
case "text":
|
||||
// TODO
|
||||
break
|
||||
case "iamge":
|
||||
// TODO
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
44
modules/schema/schema.go
Normal file
44
modules/schema/schema.go
Normal file
@ -0,0 +1,44 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// DBVersion -
|
||||
type DBVersion struct {
|
||||
Versions []VersionInfo `json:"versions"`
|
||||
Test []VersionInfo `json:"test"`
|
||||
}
|
||||
|
||||
// VersionInfo -
|
||||
type VersionInfo struct {
|
||||
File string `json:"file"`
|
||||
Version int `json:"version"`
|
||||
}
|
||||
|
||||
// ReadVersions -
|
||||
func ReadVersions() (dbver DBVersion, err error) {
|
||||
f, err := Asset("schema/dbVersion.db")
|
||||
if err != nil {
|
||||
return dbver, err
|
||||
}
|
||||
err = json.Unmarshal(f, &dbver)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadSchema -
|
||||
func ReadSchema(name string) (q string, err error) {
|
||||
if len(name) == 0 {
|
||||
return "", errors.New("name is empty")
|
||||
}
|
||||
|
||||
f, err := Asset(fmt.Sprintf("schema/%s", name))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
q = string(f)
|
||||
return
|
||||
}
|
93
router/line/line.go
Normal file
93
router/line/line.go
Normal file
@ -0,0 +1,93 @@
|
||||
package line
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"io/ioutil"
|
||||
|
||||
"git.trj.tw/golang/mtgbot/modules/config"
|
||||
"git.trj.tw/golang/mtgbot/modules/context"
|
||||
"git.trj.tw/golang/mtgbot/modules/lineobj"
|
||||
)
|
||||
|
||||
// GetRawBody -
|
||||
func GetRawBody(c *context.Context) {
|
||||
byteBody, err := ioutil.ReadAll(c.Request.Body)
|
||||
if err != nil {
|
||||
c.DataFormat("body read fail")
|
||||
return
|
||||
}
|
||||
|
||||
c.Set("rawbody", byteBody)
|
||||
c.Next()
|
||||
}
|
||||
|
||||
// VerifyLine -
|
||||
func VerifyLine(c *context.Context) {
|
||||
rawbody, ok := c.Get("rawbody")
|
||||
if !ok {
|
||||
c.DataFormat("body read fail")
|
||||
return
|
||||
}
|
||||
|
||||
var raw []byte
|
||||
if raw, ok = rawbody.([]byte); !ok {
|
||||
c.DataFormat("body type error")
|
||||
return
|
||||
}
|
||||
|
||||
sign := c.GetHeader("X-Line-Signature")
|
||||
if len(sign) == 0 {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
conf := config.GetConf()
|
||||
|
||||
hash := hmac.New(sha256.New, []byte(conf.Line.Secret))
|
||||
_, err := hash.Write(raw)
|
||||
if err != nil {
|
||||
c.ServerError(nil)
|
||||
return
|
||||
}
|
||||
|
||||
hashSign := base64.StdEncoding.EncodeToString(hash.Sum(nil))
|
||||
if hashSign != sign {
|
||||
c.CustomRes(403, map[string]string{
|
||||
"message": "sign verify fail",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
|
||||
// LineWebhook -
|
||||
func LineWebhook(c *context.Context) {
|
||||
rawbody, ok := c.Get("rawbody")
|
||||
if !ok {
|
||||
c.DataFormat("body read fail")
|
||||
return
|
||||
}
|
||||
|
||||
var raw []byte
|
||||
if raw, ok = rawbody.([]byte); !ok {
|
||||
c.DataFormat("body type error")
|
||||
return
|
||||
}
|
||||
|
||||
events := lineobj.ParseWebhookBody(raw)
|
||||
if events == nil {
|
||||
c.ServerError(nil)
|
||||
return
|
||||
}
|
||||
|
||||
if len(events.Events) > 0 {
|
||||
for _, v := range events.Events {
|
||||
go lineobj.MessageEvent(v)
|
||||
}
|
||||
}
|
||||
|
||||
c.Success(nil)
|
||||
}
|
@ -1,6 +1,10 @@
|
||||
package routes
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
import (
|
||||
"git.trj.tw/golang/mtgbot/modules/context"
|
||||
"git.trj.tw/golang/mtgbot/router/line"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
var r *gin.Engine
|
||||
|
||||
@ -16,4 +20,8 @@ func SetRoutes(r *gin.Engine) {
|
||||
r.GET("/", func(c *gin.Context) {
|
||||
c.String(200, "Hello")
|
||||
})
|
||||
|
||||
r.POST("/line", context.PatchCtx(line.GetRawBody), context.PatchCtx(line.VerifyLine), context.PatchCtx(line.LineWebhook))
|
||||
r.POST("/line/", context.PatchCtx(line.GetRawBody), context.PatchCtx(line.VerifyLine), context.PatchCtx(line.LineWebhook))
|
||||
|
||||
}
|
||||
|
6
schema/dbVersion.json
Normal file
6
schema/dbVersion.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"versions": [
|
||||
{"file": "main.sql", "version": 1}
|
||||
],
|
||||
"test": []
|
||||
}
|
158
schema/main.sql
Normal file
158
schema/main.sql
Normal file
@ -0,0 +1,158 @@
|
||||
--
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
-- Dumped from database version 10.6 (Debian 10.6-1.pgdg90+1)
|
||||
-- Dumped by pg_dump version 10.6 (Debian 10.6-1.pgdg90+1)
|
||||
|
||||
SET statement_timeout = 0;
|
||||
SET lock_timeout = 0;
|
||||
SET idle_in_transaction_session_timeout = 0;
|
||||
SET client_encoding = 'UTF8';
|
||||
SET standard_conforming_strings = on;
|
||||
SELECT pg_catalog.set_config('search_path', '', false);
|
||||
SET check_function_bodies = false;
|
||||
SET client_min_messages = warning;
|
||||
SET row_security = off;
|
||||
|
||||
ALTER TABLE IF EXISTS ONLY public.sets DROP CONSTRAINT IF EXISTS sets_pk;
|
||||
ALTER TABLE IF EXISTS ONLY public.cards DROP CONSTRAINT IF EXISTS cards_pk;
|
||||
DROP TABLE IF EXISTS public.version_ctrl;
|
||||
DROP TABLE IF EXISTS public.sets;
|
||||
DROP TABLE IF EXISTS public.cards;
|
||||
DROP EXTENSION IF EXISTS "uuid-ossp";
|
||||
DROP EXTENSION IF EXISTS plpgsql;
|
||||
DROP SCHEMA IF EXISTS public;
|
||||
--
|
||||
-- Name: public; Type: SCHEMA; Schema: -; Owner: -
|
||||
--
|
||||
|
||||
CREATE SCHEMA public;
|
||||
|
||||
|
||||
--
|
||||
-- Name: SCHEMA public; Type: COMMENT; Schema: -; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON SCHEMA public IS 'standard public schema';
|
||||
|
||||
|
||||
--
|
||||
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: -
|
||||
--
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
|
||||
|
||||
|
||||
--
|
||||
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
|
||||
|
||||
|
||||
--
|
||||
-- Name: uuid-ossp; Type: EXTENSION; Schema: -; Owner: -
|
||||
--
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA public;
|
||||
|
||||
|
||||
--
|
||||
-- Name: EXTENSION "uuid-ossp"; Type: COMMENT; Schema: -; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON EXTENSION "uuid-ossp" IS 'generate universally unique identifiers (UUIDs)';
|
||||
|
||||
|
||||
SET default_tablespace = '';
|
||||
|
||||
SET default_with_oids = false;
|
||||
|
||||
--
|
||||
-- Name: cards; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.cards (
|
||||
id uuid DEFAULT public.uuid_generate_v4() NOT NULL,
|
||||
name character varying(1024) DEFAULT ''::character varying NOT NULL,
|
||||
cmc double precision DEFAULT 0 NOT NULL,
|
||||
mana_cost character varying(64) DEFAULT ''::character varying NOT NULL,
|
||||
text character varying(2048) DEFAULT ''::character varying NOT NULL,
|
||||
layout character varying(32) DEFAULT ''::character varying NOT NULL,
|
||||
image_url character varying(1024) DEFAULT ''::character varying NOT NULL,
|
||||
loyalty character varying(32) DEFAULT ''::character varying NOT NULL,
|
||||
type character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
number character varying(32) DEFAULT ''::character varying NOT NULL,
|
||||
power character varying(32) DEFAULT ''::character varying NOT NULL,
|
||||
toughness character varying(32) DEFAULT ''::character varying NOT NULL,
|
||||
set character varying(32) DEFAULT ''::character varying NOT NULL,
|
||||
names text[] DEFAULT ARRAY[]::text[] NOT NULL,
|
||||
colors text[] DEFAULT ARRAY[]::text[] NOT NULL,
|
||||
color_identity text[] DEFAULT ARRAY[]::text[] NOT NULL,
|
||||
types text[] DEFAULT ARRAY[]::text[] NOT NULL,
|
||||
supertypes text[] DEFAULT ARRAY[]::text[] NOT NULL,
|
||||
subtypes text[] DEFAULT ARRAY[]::text[] NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: sets; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.sets (
|
||||
code character varying(32) NOT NULL,
|
||||
name character varying(128) NOT NULL,
|
||||
release_date date
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: version_ctrl; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.version_ctrl (
|
||||
version integer DEFAULT 0 NOT NULL,
|
||||
str character varying(4096) DEFAULT ''::character varying NOT NULL,
|
||||
ctime timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Data for Name: cards; Type: TABLE DATA; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Data for Name: sets; Type: TABLE DATA; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Data for Name: version_ctrl; Type: TABLE DATA; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Name: cards cards_pk; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.cards
|
||||
ADD CONSTRAINT cards_pk PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: sets sets_pk; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.sets
|
||||
ADD CONSTRAINT sets_pk PRIMARY KEY (code);
|
||||
|
||||
|
||||
--
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
Loading…
Reference in New Issue
Block a user