作者 唐旭辉

更新filestore

@@ -63,6 +63,7 @@ func (this *BaseController) Valid(obj interface{}) (result bool, msg *protocol.R @@ -63,6 +63,7 @@ func (this *BaseController) Valid(obj interface{}) (result bool, msg *protocol.R
63 msg = protocol.BadRequestParam(2) 63 msg = protocol.BadRequestParam(2)
64 return 64 return
65 } 65 }
  66 +
66 return 67 return
67 } 68 }
68 69
@@ -72,24 +73,6 @@ func (this *BaseController) Resp(msg *protocol.ResponseMessage) { @@ -72,24 +73,6 @@ func (this *BaseController) Resp(msg *protocol.ResponseMessage) {
72 this.ServeJSON() 73 this.ServeJSON()
73 } 74 }
74 75
75 -//GenMessage genarate a response message  
76 -// func (this *BaseController) GenMessage(rsp interface{}, err error) *protocol.ResponseMessage {  
77 -// var msg *protocol.ResponseMessage  
78 -// if err == nil {  
79 -// msg = protocol.ReturnResponse(0)  
80 -// msg.Data = rsp  
81 -// return msg  
82 -// }  
83 -// //log.Error(err)  
84 -// if e, ok := err.(common.Error); ok {  
85 -// msg = protocol.ReturnResponse(e.Code)  
86 -// msg.Data = rsp  
87 -// return msg  
88 -// }  
89 -// msg = protocol.ReturnResponse(1)  
90 -// return msg  
91 -// }  
92 -  
93 //获取请求头信息 76 //获取请求头信息
94 func GetRequestHeader(ctx *context.Context) *protocol.RequestHeader { 77 func GetRequestHeader(ctx *context.Context) *protocol.RequestHeader {
95 h := &protocol.RequestHeader{} 78 h := &protocol.RequestHeader{}
@@ -6,9 +6,10 @@ require ( @@ -6,9 +6,10 @@ require (
6 github.com/astaxie/beego v1.10.0 6 github.com/astaxie/beego v1.10.0
7 github.com/go-sql-driver/mysql v1.4.1 7 github.com/go-sql-driver/mysql v1.4.1
8 github.com/gorilla/websocket v1.4.1 8 github.com/gorilla/websocket v1.4.1
  9 + github.com/klauspost/cpuid v1.2.1 // indirect
9 github.com/prometheus/client_golang v1.1.0 10 github.com/prometheus/client_golang v1.1.0
10 - github.com/prometheus/common v0.6.0  
11 - github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect 11 + github.com/satori/go.uuid v1.2.0
  12 + github.com/sony/sonyflake v1.0.0
12 gitlab.fjmaimaimai.com/mmm-go/gocomm v0.0.1 13 gitlab.fjmaimaimai.com/mmm-go/gocomm v0.0.1
13 google.golang.org/appengine v1.6.2 // indirect 14 google.golang.org/appengine v1.6.2 // indirect
14 ) 15 )
1 package filestore 1 package filestore
2 2
3 -//IFileStore TODO文件存储相关 3 +import (
  4 + "errors"
  5 + "fmt"
  6 + "io"
  7 + "mime/multipart"
  8 + "os"
  9 + "path"
  10 +
  11 + "github.com/sony/sonyflake"
  12 +)
  13 +
  14 +var (
  15 + ImageFilePath string
  16 + VoiceFilePath string
  17 + VideoFilePath string
  18 +)
  19 +
  20 +func init() {
  21 + //TODO 初始化文件存储路径,建议手动创建
  22 + ImageFilePath = ""
  23 + VoiceFilePath = ""
  24 + VideoFilePath = ""
  25 + // ValidatePath(ImageFilePath)
  26 + // ValidatePath(VoiceFilePath)
  27 + // ValidatePath(VideoFilePath)
  28 +}
  29 +
  30 +//IFileStore 文件存储相关
4 type IFileStore interface { 31 type IFileStore interface {
5 - Auth() error //在获取文件前进行对请求进行检查  
6 - ReadFile() (string, error) //实际获取文件操作  
7 StoreFile() (string, error) //实际存储文件操作 32 StoreFile() (string, error) //实际存储文件操作
8 - DeleteFile() error  
9 } 33 }
10 34
11 -// type LocalFileStore struct {  
12 -// } 35 +type IFileReader interface {
  36 + ReadFileSrc(id int64) (string, error) //实际获取文件链接
  37 +}
  38 +
  39 +func ValidateFileExt(fileExt string) bool {
  40 + allowExt := map[string]bool{
  41 + "jpg": true,
  42 + "png": true,
  43 + "mp3": true,
  44 + }
  45 + if _, ok := allowExt[fileExt]; ok {
  46 + return true
  47 + }
  48 + return false
  49 +}
  50 +
  51 +func NewFileStore(fHeader *multipart.FileHeader) (IFileStore, error) {
  52 + filename := fHeader.Filename
  53 + fileExt := path.Ext(filename)
  54 + if ok := ValidateFileExt(fileExt); !ok {
  55 + return nil, errors.New("ValidateFileExt fail")
  56 + }
  57 + var filestore IFileStore
  58 + switch fileExt {
  59 + case "jpg", "png":
  60 + filestore = NewImageFileStore(fHeader, fileExt)
  61 + case "mp3":
  62 + filestore = NewVideoFileStore(fHeader, fileExt)
  63 + }
  64 + return filestore, nil
  65 +}
  66 +
  67 +func NewReader(filetype string) (IFileReader, error) {
  68 + var filestore IFileReader
  69 + switch filetype {
  70 + case "imgage":
  71 + filestore = &ImageFileStore{}
  72 + case "mp3":
  73 + filestore = &VideoFileStore{}
  74 + default:
  75 + return nil, fmt.Errorf("err:filetype is %s", filetype)
  76 + }
  77 + return filestore, nil
  78 +}
  79 +
  80 +//ImageFileStore 图片文件
  81 +type ImageFileStore struct {
  82 + fHeader *multipart.FileHeader
  83 + fileType string
  84 + size int
  85 +}
  86 +
  87 +var (
  88 + _ IFileStore = &ImageFileStore{}
  89 +)
  90 +
  91 +func NewImageFileStore(fHeader *multipart.FileHeader, filetype string) *ImageFileStore {
  92 + return &ImageFileStore{
  93 + fHeader: fHeader,
  94 + fileType: filetype,
  95 + }
  96 +}
  97 +func (f ImageFileStore) StoreFile() (string, error) {
  98 + storePath := fmt.Sprintf("%s%s.%s", ImageFilePath, randomName(), f.fileType)
  99 + tempFile, err := f.fHeader.Open()
  100 + if err != nil {
  101 + return "", err
  102 + }
  103 + defer tempFile.Close()
  104 + if err = SaveToFile(storePath, tempFile); err != nil {
  105 + return "", err
  106 + }
  107 + //数据库操作
  108 + return storePath, nil
  109 +}
13 110
14 -// type XXXFileStore struct {  
15 -// } 111 +func (f ImageFileStore) ReadFileSrc(id int64) (string, error) {
  112 + //数据库操作
  113 + return "", nil
  114 +}
  115 +
  116 +//VoiceFileStore 音频文件
  117 +type VideoFileStore struct {
  118 + fHeader *multipart.FileHeader
  119 + size int
  120 + fileType string
  121 +}
  122 +
  123 +var (
  124 + _ IFileStore = &VideoFileStore{}
  125 +)
  126 +
  127 +func NewVideoFileStore(fHeader *multipart.FileHeader, filetype string) *VideoFileStore {
  128 + return &VideoFileStore{
  129 + fHeader: fHeader,
  130 + fileType: filetype,
  131 + }
  132 +}
  133 +
  134 +func (f VideoFileStore) StoreFile() (string, error) {
  135 + storePath := fmt.Sprintf("%s%s.%s", ImageFilePath, randomName(), f.fileType)
  136 + tempFile, err := f.fHeader.Open()
  137 + if err != nil {
  138 + return "", err
  139 + }
  140 + defer tempFile.Close()
  141 + if err = SaveToFile(storePath, tempFile); err != nil {
  142 + return "", err
  143 + }
  144 + //数据库操作
  145 + return storePath, nil
  146 +}
  147 +
  148 +func (f VideoFileStore) ReadFileSrc(id int64) (string, error) {
  149 + //数据库操作
  150 + return "", nil
  151 +}
  152 +
  153 +var sf = sonyflake.NewSonyflake(sonyflake.Settings{})
  154 +
  155 +func randomName() string {
  156 + num, _ := sf.NextID()
  157 + return fmt.Sprintf("%d", num)
  158 +}
  159 +
  160 +func ValidatePath(s string) error {
  161 + info, err := os.Stat(s)
  162 + if err != nil {
  163 + return err
  164 + }
  165 + if ok := info.IsDir(); ok {
  166 + return nil
  167 + }
  168 + return errors.New("path must be directory")
  169 +}
  170 +
  171 +func SaveToFile(storePath string, rd io.Reader) error {
  172 + openf, err := os.OpenFile(storePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
  173 + if err != nil {
  174 + return err
  175 + }
  176 + defer openf.Close()
  177 + io.Copy(openf, rd)
  178 + return nil
  179 +}