/code/rest/alien_controller.go

https://github.com/eyebluecn/tank · Go · 351 lines · 251 code · 82 blank · 18 comment · 53 complexity · 66900646bb0bfbaf7d190ed7ed6af40b MD5 · raw file

  1. package rest
  2. import (
  3. "github.com/eyebluecn/tank/code/core"
  4. "github.com/eyebluecn/tank/code/tool/result"
  5. "github.com/eyebluecn/tank/code/tool/util"
  6. "net/http"
  7. "regexp"
  8. "strconv"
  9. "time"
  10. )
  11. type AlienController struct {
  12. BaseController
  13. uploadTokenDao *UploadTokenDao
  14. downloadTokenDao *DownloadTokenDao
  15. matterDao *MatterDao
  16. matterService *MatterService
  17. imageCacheDao *ImageCacheDao
  18. imageCacheService *ImageCacheService
  19. alienService *AlienService
  20. shareService *ShareService
  21. }
  22. func (this *AlienController) Init() {
  23. this.BaseController.Init()
  24. b := core.CONTEXT.GetBean(this.uploadTokenDao)
  25. if c, ok := b.(*UploadTokenDao); ok {
  26. this.uploadTokenDao = c
  27. }
  28. b = core.CONTEXT.GetBean(this.downloadTokenDao)
  29. if c, ok := b.(*DownloadTokenDao); ok {
  30. this.downloadTokenDao = c
  31. }
  32. b = core.CONTEXT.GetBean(this.matterDao)
  33. if c, ok := b.(*MatterDao); ok {
  34. this.matterDao = c
  35. }
  36. b = core.CONTEXT.GetBean(this.matterService)
  37. if c, ok := b.(*MatterService); ok {
  38. this.matterService = c
  39. }
  40. b = core.CONTEXT.GetBean(this.imageCacheDao)
  41. if c, ok := b.(*ImageCacheDao); ok {
  42. this.imageCacheDao = c
  43. }
  44. b = core.CONTEXT.GetBean(this.imageCacheService)
  45. if c, ok := b.(*ImageCacheService); ok {
  46. this.imageCacheService = c
  47. }
  48. b = core.CONTEXT.GetBean(this.alienService)
  49. if c, ok := b.(*AlienService); ok {
  50. this.alienService = c
  51. }
  52. b = core.CONTEXT.GetBean(this.shareService)
  53. if c, ok := b.(*ShareService); ok {
  54. this.shareService = c
  55. }
  56. }
  57. func (this *AlienController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) {
  58. routeMap := make(map[string]func(writer http.ResponseWriter, request *http.Request))
  59. routeMap["/api/alien/fetch/upload/token"] = this.Wrap(this.FetchUploadToken, USER_ROLE_USER)
  60. routeMap["/api/alien/fetch/download/token"] = this.Wrap(this.FetchDownloadToken, USER_ROLE_USER)
  61. routeMap["/api/alien/confirm"] = this.Wrap(this.Confirm, USER_ROLE_USER)
  62. routeMap["/api/alien/upload"] = this.Wrap(this.Upload, USER_ROLE_GUEST)
  63. routeMap["/api/alien/crawl/token"] = this.Wrap(this.CrawlToken, USER_ROLE_GUEST)
  64. routeMap["/api/alien/crawl/direct"] = this.Wrap(this.CrawlDirect, USER_ROLE_USER)
  65. return routeMap
  66. }
  67. //handle some special routes, eg. params in the url.
  68. func (this *AlienController) HandleRoutes(writer http.ResponseWriter, request *http.Request) (func(writer http.ResponseWriter, request *http.Request), bool) {
  69. path := request.URL.Path
  70. //match /api/alien/preview/{uuid}/{filename} (response header not contain content-disposition)
  71. reg := regexp.MustCompile(`^/api/alien/preview/([^/]+)/([^/]+)$`)
  72. strs := reg.FindStringSubmatch(path)
  73. if len(strs) == 3 {
  74. var f = func(writer http.ResponseWriter, request *http.Request) {
  75. this.Preview(writer, request, strs[1], strs[2])
  76. }
  77. return f, true
  78. }
  79. //match /api/alien/download/{uuid}/{filename} (response header contain content-disposition)
  80. reg = regexp.MustCompile(`^/api/alien/download/([^/]+)/([^/]+)$`)
  81. strs = reg.FindStringSubmatch(path)
  82. if len(strs) == 3 {
  83. var f = func(writer http.ResponseWriter, request *http.Request) {
  84. this.Download(writer, request, strs[1], strs[2])
  85. }
  86. return f, true
  87. }
  88. return nil, false
  89. }
  90. //fetch a upload token for guest. Guest can upload file with this token.
  91. func (this *AlienController) FetchUploadToken(writer http.ResponseWriter, request *http.Request) *result.WebResult {
  92. filename := request.FormValue("filename")
  93. expireTimeStr := request.FormValue("expireTime")
  94. privacyStr := request.FormValue("privacy")
  95. sizeStr := request.FormValue("size")
  96. //store dir path
  97. dirPath := request.FormValue("dirPath")
  98. filename = CheckMatterName(request, filename)
  99. var expireTime time.Time
  100. if expireTimeStr == "" {
  101. panic(result.BadRequest("time format error"))
  102. } else {
  103. expireTime = util.ConvertDateTimeStringToTime(expireTimeStr)
  104. }
  105. if expireTime.Before(time.Now()) {
  106. panic(result.BadRequest("expire time cannot before now"))
  107. }
  108. var privacy = false
  109. if privacyStr == TRUE {
  110. privacy = true
  111. }
  112. var size int64
  113. if sizeStr == "" {
  114. panic(result.BadRequest("file size cannot be null"))
  115. } else {
  116. var err error
  117. size, err = strconv.ParseInt(sizeStr, 10, 64)
  118. if err != nil {
  119. panic(result.BadRequest("file size error"))
  120. }
  121. if size < 1 {
  122. panic(result.BadRequest("file size error"))
  123. }
  124. }
  125. user := this.checkUser(request)
  126. dirMatter := this.matterService.CreateDirectories(request, user, dirPath)
  127. uploadToken := &UploadToken{
  128. UserUuid: user.Uuid,
  129. FolderUuid: dirMatter.Uuid,
  130. MatterUuid: "",
  131. ExpireTime: expireTime,
  132. Filename: filename,
  133. Privacy: privacy,
  134. Size: size,
  135. Ip: util.GetIpAddress(request),
  136. }
  137. uploadToken = this.uploadTokenDao.Create(uploadToken)
  138. return this.Success(uploadToken)
  139. }
  140. //user confirm a file whether uploaded successfully.
  141. func (this *AlienController) Confirm(writer http.ResponseWriter, request *http.Request) *result.WebResult {
  142. matterUuid := request.FormValue("matterUuid")
  143. if matterUuid == "" {
  144. panic(result.BadRequest("matterUuid cannot be null"))
  145. }
  146. user := this.checkUser(request)
  147. matter := this.matterDao.CheckByUuid(matterUuid)
  148. if matter.UserUuid != user.Uuid {
  149. panic(result.BadRequest("matter not belong to you"))
  150. }
  151. return this.Success(matter)
  152. }
  153. //a guest upload a file with a upload token.
  154. func (this *AlienController) Upload(writer http.ResponseWriter, request *http.Request) *result.WebResult {
  155. //allow cors.
  156. this.allowCORS(writer)
  157. if request.Method == "OPTIONS" {
  158. //nil means empty response body.
  159. return nil
  160. }
  161. uploadTokenUuid := request.FormValue("uploadTokenUuid")
  162. file, handler, err := request.FormFile("file")
  163. this.PanicError(err)
  164. defer func() {
  165. e := file.Close()
  166. this.PanicError(e)
  167. }()
  168. if uploadTokenUuid == "" {
  169. panic(result.BadRequest("uploadTokenUuid cannot be null"))
  170. }
  171. uploadToken := this.uploadTokenDao.CheckByUuid(uploadTokenUuid)
  172. if uploadToken.ExpireTime.Before(time.Now()) {
  173. panic(result.BadRequest("uploadToken has expired"))
  174. }
  175. user := this.userDao.CheckByUuid(uploadToken.UserUuid)
  176. err = request.ParseMultipartForm(32 << 20)
  177. this.PanicError(err)
  178. if handler.Filename != uploadToken.Filename {
  179. panic(result.BadRequest("filename doesn't the one in uploadToken"))
  180. }
  181. if handler.Size != uploadToken.Size {
  182. panic(result.BadRequest("file size doesn't the one in uploadToken"))
  183. }
  184. dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, user)
  185. matter := this.matterService.Upload(request, file, user, dirMatter, uploadToken.Filename, uploadToken.Privacy)
  186. //expire the upload token.
  187. uploadToken.ExpireTime = time.Now()
  188. this.uploadTokenDao.Save(uploadToken)
  189. return this.Success(matter)
  190. }
  191. //crawl a url with uploadToken. guest can visit this method.
  192. func (this *AlienController) CrawlToken(writer http.ResponseWriter, request *http.Request) *result.WebResult {
  193. //allow cors.
  194. this.allowCORS(writer)
  195. if request.Method == "OPTIONS" {
  196. //nil means empty response body.
  197. return nil
  198. }
  199. uploadTokenUuid := request.FormValue("uploadTokenUuid")
  200. url := request.FormValue("url")
  201. if uploadTokenUuid == "" {
  202. panic(result.BadRequest("uploadTokenUuid cannot be null"))
  203. }
  204. uploadToken := this.uploadTokenDao.CheckByUuid(uploadTokenUuid)
  205. if uploadToken.ExpireTime.Before(time.Now()) {
  206. panic(result.BadRequest("uploadToken has expired"))
  207. }
  208. user := this.userDao.CheckByUuid(uploadToken.UserUuid)
  209. dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, user)
  210. matter := this.matterService.AtomicCrawl(request, url, uploadToken.Filename, user, dirMatter, uploadToken.Privacy)
  211. //expire the upload token.
  212. uploadToken.ExpireTime = time.Now()
  213. this.uploadTokenDao.Save(uploadToken)
  214. return this.Success(matter)
  215. }
  216. //crawl a url directly. only user can visit this method.
  217. func (this *AlienController) CrawlDirect(writer http.ResponseWriter, request *http.Request) *result.WebResult {
  218. filename := request.FormValue("filename")
  219. privacyStr := request.FormValue("privacy")
  220. dirPath := request.FormValue("dirPath")
  221. url := request.FormValue("url")
  222. filename = CheckMatterName(request, filename)
  223. var privacy bool
  224. if privacyStr == TRUE {
  225. privacy = true
  226. }
  227. user := this.checkUser(request)
  228. dirMatter := this.matterService.CreateDirectories(request, user, dirPath)
  229. matter := this.matterService.AtomicCrawl(request, url, filename, user, dirMatter, privacy)
  230. return this.Success(matter)
  231. }
  232. //fetch a download token for guest. Guest can download file with this token.
  233. func (this *AlienController) FetchDownloadToken(writer http.ResponseWriter, request *http.Request) *result.WebResult {
  234. matterUuid := request.FormValue("matterUuid")
  235. expireTimeStr := request.FormValue("expireTime")
  236. if matterUuid == "" {
  237. panic(result.BadRequest("matterUuid cannot be null."))
  238. }
  239. user := this.checkUser(request)
  240. matter := this.matterDao.CheckByUuid(matterUuid)
  241. if matter.UserUuid != user.Uuid {
  242. panic(result.BadRequest("matter not belong to you"))
  243. }
  244. var expireTime time.Time
  245. if expireTimeStr == "" {
  246. panic(result.BadRequest("time format error"))
  247. } else {
  248. expireTime = util.ConvertDateTimeStringToTime(expireTimeStr)
  249. }
  250. if expireTime.Before(time.Now()) {
  251. panic(result.BadRequest("expire time cannot before now"))
  252. }
  253. downloadToken := &DownloadToken{
  254. UserUuid: user.Uuid,
  255. MatterUuid: matterUuid,
  256. ExpireTime: expireTime,
  257. Ip: util.GetIpAddress(request),
  258. }
  259. downloadToken = this.downloadTokenDao.Create(downloadToken)
  260. return this.Success(downloadToken)
  261. }
  262. //preview a file.
  263. func (this *AlienController) Preview(writer http.ResponseWriter, request *http.Request, uuid string, filename string) {
  264. this.alienService.PreviewOrDownload(writer, request, uuid, filename, false)
  265. }
  266. //download a file.
  267. func (this *AlienController) Download(writer http.ResponseWriter, request *http.Request, uuid string, filename string) {
  268. this.alienService.PreviewOrDownload(writer, request, uuid, filename, true)
  269. }