Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add register event && Add friendship && Add FileBox #20

Merged
merged 10 commits into from
Apr 13, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions examples/ding-dong-bot.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package main

import (
"fmt"

"github.com/wechaty/go-wechaty/wechaty"
"fmt"
"github.com/wechaty/go-wechaty/wechaty"
"github.com/wechaty/go-wechaty/wechaty-puppet/schemas"
"github.com/wechaty/go-wechaty/wechaty/user"
)

func main() {
_ = wechaty.NewWechaty().
OnScan(func(qrCode, status string) {
fmt.Printf("Scan QR Code to login: %s\nhttps://api.qrserver.com/v1/create-qr-code/?data=%s\n", status, qrCode)
}).
OnLogin(func(user string) { fmt.Printf("User %s logined\n", user) }).
OnMessage(func(message string) { fmt.Printf("Message: %s\n", message) }).
Start()
_ = wechaty.NewWechaty().
OnScan(func(qrCode string, status schemas.ScanStatus, data string) {
fmt.Printf("Scan QR Code to login: %v\nhttps://api.qrserver.com/v1/create-qr-code/?data=%s\n", status, qrCode)
}).
OnLogin(func(user string) {
fmt.Printf("User %s logined\n", user)
}).
OnMessage(func(message *user.Message) {
fmt.Println(fmt.Printf("Message: %v\n", message))
}).
Start()
}
10 changes: 8 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ module github.com/wechaty/go-wechaty
go 1.14

require (
github.com/bitly/go-simplejson v0.5.0
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/hashicorp/golang-lru v0.5.4
github.com/otiai10/opengraph v1.1.1
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/tools v0.0.0-20200402223321-bcf690261a44 // indirect
github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086
github.com/tuotoo/qrcode v0.0.0-20190222102259-ac9c44189bf2
github.com/willf/bitset v1.1.10 // indirect
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b // indirect
k8s.io/apimachinery v0.18.0
k8s.io/client-go v11.0.0+incompatible
)
159 changes: 159 additions & 0 deletions wechaty-puppet/file-box/file_box.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package file_box

import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"github.com/bitly/go-simplejson"
"github.com/tuotoo/qrcode"
helper_functions "github.com/wechaty/go-wechaty/wechaty-puppet/helper-functions"
"io/ioutil"
"mime"
"os"
"path/filepath"
)

type fileImplInterface interface {
toJSONMap() map[string]interface{}
toBytes() ([]byte, error)
}

// FileBox struct
type FileBox struct {
fileImpl fileImplInterface
name string
metadata map[string]interface{}
boxType FileBoxType
fileBytes []byte
mimeType string
}

func newFileBox(common *FileBoxJsonObjectCommon, fileImpl fileImplInterface) *FileBox {
return &FileBox{
fileImpl: fileImpl,
name: common.Name,
metadata: common.Metadata,
boxType: common.BoxType,
mimeType: mime.TypeByExtension(filepath.Ext(common.Name)),
}
}

func NewFileBoxFromJSONString(s string) (*FileBox, error) {
newJson, err := simplejson.NewJson([]byte(s))
if err != nil {
return nil, err
}
boxType, err := newJson.Get("boxType").Int64()
if err != nil {
return nil, err
}
switch boxType {
case FileBoxTypeBase64:
fileBoxStruct := new(FileBoxJsonObjectBase64)
if err := json.Unmarshal([]byte(s), fileBoxStruct); err != nil {
return nil, err
}
return NewFileBoxFromJSONObjectBase64(fileBoxStruct), nil
case FileBoxTypeQRCode:
fileBoxStruct := new(FileBoxJsonObjectQRCode)
if err := json.Unmarshal([]byte(s), fileBoxStruct); err != nil {
return nil, err
}
return NewFileBoxFromJSONObjectQRCode(fileBoxStruct), nil
case FileBoxTypeUrl:
fileBoxStruct := new(FileBoxJsonObjectUrl)
if err := json.Unmarshal([]byte(s), fileBoxStruct); err != nil {
return nil, err
}
return NewFileBoxFromJSONObjectUrl(fileBoxStruct), nil
default:
return nil, errors.New("invalid value boxType")
}
}

func NewFileBoxFromJSONObjectBase64(data *FileBoxJsonObjectBase64) *FileBox {
return newFileBox(data.FileBoxJsonObjectCommon, newFileBoxBase64(data.Base64))
}

func NewFileBoxFromJSONObjectUrl(data *FileBoxJsonObjectUrl) *FileBox {
return newFileBox(data.FileBoxJsonObjectCommon, NewFileBoxUrl(data.RemoteUrl, data.Headers))
}

func NewFileBoxFromJSONObjectQRCode(data *FileBoxJsonObjectQRCode) *FileBox {
return newFileBox(data.FileBoxJsonObjectCommon, NewFileBoxQRCode(data.QrCode))
}

func (fb *FileBox) ToJSONString() (string, error) {
jsonMap := map[string]interface{}{
"name": fb.name,
"metadata": fb.metadata,
"boxType": fb.boxType,
}
implJsonMap := fb.fileImpl.toJSONMap()
for k, v := range implJsonMap {
jsonMap[k] = v
}
marshal, err := json.Marshal(jsonMap)
return string(marshal), err
}

func (fb *FileBox) ToFile(filePath string, overwrite bool) error {
if filePath == "" {
filePath = fb.name
}
path, err := os.Getwd()
if err != nil {
return err
}
fullPath := filepath.Join(path, filePath)
if !overwrite && helper_functions.FileExists(fullPath) {
return os.ErrExist
}
fileBytes, err := fb.ToBytes()
if err != nil {
return err
}
return ioutil.WriteFile(filePath, fileBytes, os.ModePerm)
}

func (fb *FileBox) ToBytes() ([]byte, error) {
if fb.fileBytes != nil {
return fb.fileBytes, nil
}
toBytes, err := fb.fileImpl.toBytes()
if err != nil {
return nil, err
}
fb.fileBytes = toBytes
return fb.fileBytes, nil
}

func (fb *FileBox) ToBase64() (string, error) {
fileBytes, err := fb.ToBytes()
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(fileBytes), nil
}

func (fb *FileBox) ToDataURL() (string, error) {
toBase64, err := fb.ToBase64()
if err != nil {
return "", nil
}
return fmt.Sprintf("data:%s;base64,%s", fb.mimeType, toBase64), nil
}

func (fb *FileBox) ToQrCode() (string, error) {
fileBytes, err := fb.ToBytes()
if err != nil {
return "", err
}
decode, err := qrcode.Decode(bytes.NewReader(fileBytes))
if err != nil {
return "", nil
}
return decode.Content, nil
}
27 changes: 27 additions & 0 deletions wechaty-puppet/file-box/file_box_base64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package file_box

import (
"encoding/base64"
)

type fileBoxBase64 struct {
base64Data string
}

func newFileBoxBase64(base64Data string) *fileBoxBase64 {
return &fileBoxBase64{base64Data: base64Data}
}

func (fb *fileBoxBase64) toJSONMap() map[string]interface{} {
return map[string]interface{}{
"base64": fb.base64Data,
}
}

func (fb *fileBoxBase64) toBytes() ([]byte, error) {
dec, err := base64.StdEncoding.DecodeString(fb.base64Data)
if err != nil {
return nil, err
}
return dec, nil
}
27 changes: 27 additions & 0 deletions wechaty-puppet/file-box/file_box_qrcode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package file_box

import (
"github.com/skip2/go-qrcode"
)

type fileBoxQRCode struct {
qrCode string
}

func NewFileBoxQRCode(qrCode string) *fileBoxQRCode {
return &fileBoxQRCode{qrCode: qrCode}
}

func (fb *fileBoxQRCode) toJSONMap() map[string]interface{} {
return map[string]interface{}{
"qrCode": fb.qrCode,
}
}

func (fb *fileBoxQRCode) toBytes() ([]byte, error) {
qr, err := qrcode.New(fb.qrCode, qrcode.Medium)
if err != nil {
return nil, err
}
return qr.PNG(256)
}
92 changes: 92 additions & 0 deletions wechaty-puppet/file-box/file_box_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package file_box

import (
"encoding/base64"
"io/ioutil"
"log"
"os"
"reflect"
"testing"
)

func TestFileBox_ToFile(t *testing.T) {
expect := "test content"
fileBox := NewFileBoxFromJSONObjectBase64(&FileBoxJsonObjectBase64{
FileBoxJsonObjectCommon: &FileBoxJsonObjectCommon{
Name: "test.text",
Metadata: nil,
BoxType: FileBoxTypeBase64,
},
Base64: base64.StdEncoding.EncodeToString([]byte(expect)),
})
const filename = "testdata/test.text"
t.Run("toFile success", func(t *testing.T) {
err := fileBox.ToFile(filename, true)
if err != nil {
log.Fatal(err)
}
file, err := os.Open(filename)
if err != nil {
log.Fatal(err)
}
got, err := ioutil.ReadAll(file)
if err != nil {
log.Fatal(err)
}
if expect != string(got) {
log.Fatalf("got %s expect %s", got, expect)
}
})
t.Run("file exists", func(t *testing.T) {
err := fileBox.ToFile(filename, false)
if err != os.ErrExist {
log.Fatalf("got %s expect %s", err, os.ErrExist)
}
})
}

func TestNewFileBoxFromJSONString(t *testing.T) {
tests := []struct {
jsonString string
expectFileImpl reflect.Type
}{
{
jsonString: `{
"name":"test.png",
"metadata": null,
"boxType":1,
"base64":"dGVzdCBjb250ZW50"
}`,
expectFileImpl: reflect.TypeOf(new(fileBoxBase64)),
},
{
jsonString: `{
"name":"test.png",
"metadata": null,
"boxType":2,
"remoteUrl":"http://www.example.com",
"header":null
}`,
expectFileImpl: reflect.TypeOf(new(fileBoxUrl)),
},
{
jsonString: `{
"name":"test.png",
"metadata": null,
"boxType":3,
"qrCode":"test content"
}`,
expectFileImpl: reflect.TypeOf(new(fileBoxQRCode)),
},
}
for _, t := range tests {
fileBox, err := NewFileBoxFromJSONString(t.jsonString)
if err != nil {
log.Fatal(err)
}
gotReflectType := reflect.TypeOf(fileBox.fileImpl)
if gotReflectType != t.expectFileImpl {
log.Fatalf("got %v expect %v", gotReflectType, t.expectFileImpl)
}
}
}
37 changes: 37 additions & 0 deletions wechaty-puppet/file-box/file_box_url.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package file_box

import (
helper_functions "github.com/wechaty/go-wechaty/wechaty-puppet/helper-functions"
"io/ioutil"
"net/http"
)

type fileBoxUrl struct {
remoteUrl string
headers http.Header
}

func NewFileBoxUrl(remoteUrl string, headers http.Header) *fileBoxUrl {
return &fileBoxUrl{remoteUrl: remoteUrl, headers: headers}
}

func (fb *fileBoxUrl) toJSONMap() map[string]interface{} {
return map[string]interface{}{
"headers": fb.headers,
"remoteUrl": fb.remoteUrl,
}
}

func (fb *fileBoxUrl) toBytes() ([]byte, error) {
request, err := http.NewRequest(http.MethodGet, fb.remoteUrl, nil)
if err != nil {
return nil, err
}
request.Header = fb.headers
response, err := helper_functions.HttpClient.Do(request)
if err != nil {
return nil, err
}
defer response.Body.Close()
return ioutil.ReadAll(response.Body)
}
1 change: 1 addition & 0 deletions wechaty-puppet/file-box/testdata/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test.text
Loading