You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

dataset.go 14 kB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
5 years ago
3 years ago
3 years ago
3 years ago
3 years ago
5 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
5 years ago
3 years ago
3 years ago
5 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. package repo
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "sort"
  7. "strconv"
  8. "strings"
  9. "unicode/utf8"
  10. "code.gitea.io/gitea/models"
  11. "code.gitea.io/gitea/modules/auth"
  12. "code.gitea.io/gitea/modules/base"
  13. "code.gitea.io/gitea/modules/context"
  14. "code.gitea.io/gitea/modules/log"
  15. "code.gitea.io/gitea/modules/setting"
  16. )
  17. const (
  18. tplIndex base.TplName = "repo/datasets/index"
  19. tplDatasetCreate base.TplName = "repo/datasets/create"
  20. tplDatasetEdit base.TplName = "repo/datasets/edit"
  21. taskstplIndex base.TplName = "repo/datasets/tasks/index"
  22. )
  23. // MustEnableDataset check if repository enable internal dataset
  24. func MustEnableDataset(ctx *context.Context) {
  25. if !ctx.Repo.CanRead(models.UnitTypeDatasets) {
  26. ctx.NotFound("MustEnableDataset", nil)
  27. return
  28. }
  29. }
  30. func newFilterPrivateAttachments(ctx *context.Context, list []*models.Attachment, repo *models.Repository) []*models.Attachment {
  31. if ctx.Repo.CanWrite(models.UnitTypeDatasets) {
  32. log.Info("can write.")
  33. return list
  34. } else {
  35. if repo.Owner == nil {
  36. repo.GetOwner()
  37. }
  38. permission := false
  39. if repo.Owner.IsOrganization() && ctx.User != nil {
  40. if repo.Owner.IsUserPartOfOrg(ctx.User.ID) {
  41. log.Info("user is member of org.")
  42. permission = true
  43. }
  44. }
  45. if !permission && ctx.User != nil {
  46. isCollaborator, _ := repo.IsCollaborator(ctx.User.ID)
  47. if isCollaborator {
  48. log.Info("Collaborator user may visit the attach.")
  49. permission = true
  50. }
  51. }
  52. var publicList []*models.Attachment
  53. for _, attach := range list {
  54. if !attach.IsPrivate {
  55. publicList = append(publicList, attach)
  56. } else {
  57. if permission {
  58. publicList = append(publicList, attach)
  59. }
  60. }
  61. }
  62. return publicList
  63. }
  64. }
  65. func QueryDataSet(ctx *context.Context) []*models.Attachment {
  66. repo := ctx.Repo.Repository
  67. dataset, err := models.GetDatasetByRepo(repo)
  68. if err != nil {
  69. log.Error("zou not found dataset 1")
  70. ctx.NotFound("GetDatasetByRepo", err)
  71. return nil
  72. }
  73. if ctx.Query("type") == "" {
  74. log.Error("zou not found type 2")
  75. ctx.NotFound("type error", nil)
  76. return nil
  77. }
  78. err = models.GetDatasetAttachments(ctx.QueryInt("type"), ctx.IsSigned, ctx.User, dataset)
  79. if err != nil {
  80. ctx.ServerError("GetDatasetAttachments", err)
  81. return nil
  82. }
  83. attachments := newFilterPrivateAttachments(ctx, dataset.Attachments, repo)
  84. ctx.Data["SortType"] = ctx.Query("sort")
  85. sort.Slice(attachments, func(i, j int) bool {
  86. return attachments[i].CreatedUnix > attachments[j].CreatedUnix
  87. })
  88. return attachments
  89. }
  90. func DatasetIndex(ctx *context.Context) {
  91. log.Info("dataset index 1")
  92. MustEnableDataset(ctx)
  93. ctx.Data["PageIsDataset"] = true
  94. ctx.Data["SortType"] = ctx.Query("sort")
  95. repo := ctx.Repo.Repository
  96. dataset, err := models.GetDatasetByRepo(repo)
  97. ctx.Data["CanWrite"] = ctx.Repo.CanWrite(models.UnitTypeDatasets)
  98. if err != nil {
  99. log.Warn("query dataset, not found.")
  100. ctx.HTML(200, tplIndex)
  101. return
  102. }
  103. cloudbrainType := -1
  104. if ctx.Query("type") != "" {
  105. cloudbrainType = ctx.QueryInt("type")
  106. }
  107. err = models.GetDatasetAttachments(cloudbrainType, ctx.IsSigned, ctx.User, dataset)
  108. if err != nil {
  109. ctx.ServerError("GetDatasetAttachments", err)
  110. return
  111. }
  112. attachments := newFilterPrivateAttachments(ctx, dataset.Attachments, repo)
  113. if ctx.Data["SortType"] == "nameAsc" {
  114. sort.Slice(attachments, func(i, j int) bool {
  115. return strings.ToLower(attachments[i].Name) < strings.ToLower(attachments[j].Name)
  116. })
  117. } else if ctx.Data["SortType"] == "nameDesc" {
  118. sort.Slice(attachments, func(i, j int) bool {
  119. return strings.ToLower(attachments[i].Name) > strings.ToLower(attachments[j].Name)
  120. })
  121. } else if ctx.Data["SortType"] == "sizeAsc" {
  122. sort.Slice(attachments, func(i, j int) bool {
  123. return attachments[i].Size < attachments[j].Size
  124. })
  125. } else if ctx.Data["SortType"] == "sizeDesc" {
  126. sort.Slice(attachments, func(i, j int) bool {
  127. return attachments[i].Size > attachments[j].Size
  128. })
  129. } else if ctx.Data["SortType"] == "timeAsc" {
  130. sort.Slice(attachments, func(i, j int) bool {
  131. return attachments[i].CreatedUnix < attachments[j].CreatedUnix
  132. })
  133. } else {
  134. sort.Slice(attachments, func(i, j int) bool {
  135. return attachments[i].CreatedUnix > attachments[j].CreatedUnix
  136. })
  137. }
  138. page := ctx.QueryInt("page")
  139. if page <= 0 {
  140. page = 1
  141. }
  142. pagesize := ctx.QueryInt("pagesize")
  143. if pagesize <= 0 {
  144. pagesize = 10
  145. }
  146. pager := context.NewPagination(len(attachments), pagesize, page, 5)
  147. pageAttachments := getPageAttachments(attachments, page, pagesize)
  148. //load attachment creator
  149. for _, attachment := range pageAttachments {
  150. uploader, _ := models.GetUserByID(attachment.UploaderID)
  151. attachment.Uploader = uploader
  152. }
  153. ctx.Data["Page"] = pager
  154. ctx.Data["Title"] = ctx.Tr("dataset.show_dataset")
  155. ctx.Data["Link"] = ctx.Repo.RepoLink + "/datasets"
  156. ctx.Data["dataset"] = dataset
  157. ctx.Data["Attachments"] = pageAttachments
  158. ctx.Data["IsOwner"] = true
  159. ctx.Data["StoreType"] = setting.Attachment.StoreType
  160. ctx.Data["Type"] = cloudbrainType
  161. renderAttachmentSettings(ctx)
  162. ctx.HTML(200, tplIndex)
  163. }
  164. func getPageAttachments(attachments []*models.Attachment, page int, pagesize int) []*models.Attachment {
  165. begin := (page - 1) * pagesize
  166. end := (page) * pagesize
  167. if begin > len(attachments)-1 {
  168. return nil
  169. }
  170. if end > len(attachments)-1 {
  171. return attachments[begin:]
  172. } else {
  173. return attachments[begin:end]
  174. }
  175. }
  176. func CreateDataset(ctx *context.Context) {
  177. MustEnableDataset(ctx)
  178. ctx.Data["PageIsDataset"] = true
  179. ctx.HTML(200, tplDatasetCreate)
  180. }
  181. func EditDataset(ctx *context.Context) {
  182. MustEnableDataset(ctx)
  183. ctx.Data["PageIsDataset"] = true
  184. datasetId, _ := strconv.ParseInt(ctx.Params(":id"), 10, 64)
  185. dataset, _ := models.GetDatasetByID(datasetId)
  186. if dataset == nil {
  187. ctx.Error(http.StatusNotFound, "")
  188. return
  189. }
  190. ctx.Data["Dataset"] = dataset
  191. ctx.HTML(200, tplDatasetEdit)
  192. }
  193. func CreateDatasetPost(ctx *context.Context, form auth.CreateDatasetForm) {
  194. dataset := &models.Dataset{}
  195. if !NamePattern.MatchString(form.Title) {
  196. ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.title_format_err")))
  197. return
  198. }
  199. if utf8.RuneCountInString(form.Description) > 1024 {
  200. ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.description_format_err", 1024)))
  201. return
  202. }
  203. dataset.RepoID = ctx.Repo.Repository.ID
  204. dataset.UserID = ctx.User.ID
  205. dataset.Category = form.Category
  206. dataset.Task = form.Task
  207. dataset.Title = form.Title
  208. dataset.License = form.License
  209. dataset.Description = form.Description
  210. dataset.DownloadTimes = 0
  211. if ctx.Repo.Repository.IsPrivate {
  212. dataset.Status = 0
  213. } else {
  214. dataset.Status = 1
  215. }
  216. err := models.CreateDataset(dataset)
  217. if err != nil {
  218. log.Error("fail to create dataset", err)
  219. ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.create_dataset_fail")))
  220. } else {
  221. ctx.JSON(http.StatusOK, models.BaseOKMessage)
  222. }
  223. }
  224. func EditDatasetPost(ctx *context.Context, form auth.EditDatasetForm) {
  225. ctx.Data["PageIsDataset"] = true
  226. ctx.Data["Title"] = ctx.Tr("dataset.edit_dataset")
  227. if !NamePattern.MatchString(form.Title) {
  228. ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.title_format_err")))
  229. return
  230. }
  231. if utf8.RuneCountInString(form.Description) > 1024 {
  232. ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.description_format_err", 1024)))
  233. return
  234. }
  235. rel, err := models.GetDatasetByID(form.ID)
  236. ctx.Data["dataset"] = rel
  237. if err != nil {
  238. log.Error("failed to query dataset", err)
  239. ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.query_dataset_fail")))
  240. return
  241. }
  242. rel.Title = form.Title
  243. rel.Description = form.Description
  244. rel.Category = form.Category
  245. rel.Task = form.Task
  246. rel.License = form.License
  247. if err = models.UpdateDataset(models.DefaultDBContext(), rel); err != nil {
  248. ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.query_dataset_fail")))
  249. }
  250. ctx.JSON(http.StatusOK, models.BaseOKMessage)
  251. }
  252. func DatasetAction(ctx *context.Context) {
  253. var err error
  254. datasetId, _ := strconv.ParseInt(ctx.Params(":id"), 10, 64)
  255. switch ctx.Params(":action") {
  256. case "star":
  257. err = models.StarDataset(ctx.User.ID, datasetId, true)
  258. case "unstar":
  259. err = models.StarDataset(ctx.User.ID, datasetId, false)
  260. }
  261. if err != nil {
  262. ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("repo.star_fail", ctx.Params(":action"))))
  263. } else {
  264. ctx.JSON(http.StatusOK, models.BaseOKMessage)
  265. }
  266. }
  267. func CurrentRepoDataset(ctx *context.Context) {
  268. page := ctx.QueryInt("page")
  269. cloudbrainType := ctx.QueryInt("type")
  270. keyword := strings.Trim(ctx.Query("q"), " ")
  271. repo := ctx.Repo.Repository
  272. var datasetIDs []int64
  273. dataset, err := models.GetDatasetByRepo(repo)
  274. if err != nil {
  275. ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("GetDatasetByRepo failed", err)))
  276. return
  277. }
  278. datasetIDs = append(datasetIDs, dataset.ID)
  279. datasets, count, err := models.Attachments(&models.AttachmentsOptions{
  280. ListOptions: models.ListOptions{
  281. Page: page,
  282. PageSize: setting.UI.DatasetPagingNum,
  283. },
  284. Keyword: keyword,
  285. NeedDatasetIDs: true,
  286. DatasetIDs: datasetIDs,
  287. Type: cloudbrainType,
  288. NeedIsPrivate: false,
  289. JustNeedZipFile: true,
  290. NeedRepoInfo: true,
  291. })
  292. if err != nil {
  293. ctx.ServerError("datasets", err)
  294. return
  295. }
  296. data, err := json.Marshal(datasets)
  297. if err != nil {
  298. log.Error("json.Marshal failed:", err.Error())
  299. ctx.JSON(200, map[string]string{
  300. "result_code": "-1",
  301. "error_msg": err.Error(),
  302. "data": "",
  303. })
  304. return
  305. }
  306. ctx.JSON(200, map[string]string{
  307. "result_code": "0",
  308. "data": string(data),
  309. "count": strconv.FormatInt(count, 10),
  310. })
  311. }
  312. func MyDatasets(ctx *context.Context) {
  313. page := ctx.QueryInt("page")
  314. cloudbrainType := ctx.QueryInt("type")
  315. keyword := strings.Trim(ctx.Query("q"), " ")
  316. uploaderID := ctx.User.ID
  317. datasets, count, err := models.Attachments(&models.AttachmentsOptions{
  318. ListOptions: models.ListOptions{
  319. Page: page,
  320. PageSize: setting.UI.DatasetPagingNum,
  321. },
  322. Keyword: keyword,
  323. NeedDatasetIDs: false,
  324. UploaderID: uploaderID,
  325. Type: cloudbrainType,
  326. NeedIsPrivate: false,
  327. JustNeedZipFile: true,
  328. NeedRepoInfo: true,
  329. RecommendOnly: ctx.QueryBool("recommend"),
  330. })
  331. if err != nil {
  332. ctx.ServerError("datasets", err)
  333. return
  334. }
  335. data, err := json.Marshal(datasets)
  336. if err != nil {
  337. log.Error("json.Marshal failed:", err.Error())
  338. ctx.JSON(200, map[string]string{
  339. "result_code": "-1",
  340. "error_msg": err.Error(),
  341. "data": "",
  342. })
  343. return
  344. }
  345. ctx.JSON(200, map[string]string{
  346. "result_code": "0",
  347. "data": string(data),
  348. "count": strconv.FormatInt(count, 10),
  349. })
  350. }
  351. func PublicDataset(ctx *context.Context) {
  352. page := ctx.QueryInt("page")
  353. cloudbrainType := ctx.QueryInt("type")
  354. keyword := strings.Trim(ctx.Query("q"), " ")
  355. datasets, count, err := models.Attachments(&models.AttachmentsOptions{
  356. ListOptions: models.ListOptions{
  357. Page: page,
  358. PageSize: setting.UI.DatasetPagingNum,
  359. },
  360. Keyword: keyword,
  361. NeedDatasetIDs: false,
  362. NeedIsPrivate: true,
  363. IsPrivate: false,
  364. Type: cloudbrainType,
  365. JustNeedZipFile: true,
  366. NeedRepoInfo: true,
  367. RecommendOnly: ctx.QueryBool("recommend"),
  368. })
  369. if err != nil {
  370. ctx.ServerError("datasets", err)
  371. return
  372. }
  373. data, err := json.Marshal(datasets)
  374. if err != nil {
  375. log.Error("json.Marshal failed:", err.Error())
  376. ctx.JSON(200, map[string]string{
  377. "result_code": "-1",
  378. "error_msg": err.Error(),
  379. "data": "",
  380. })
  381. return
  382. }
  383. ctx.JSON(200, map[string]string{
  384. "result_code": "0",
  385. "data": string(data),
  386. "count": strconv.FormatInt(count, 10),
  387. })
  388. }
  389. func MyFavoriteDataset(ctx *context.Context) {
  390. page := ctx.QueryInt("page")
  391. cloudbrainType := ctx.QueryInt("type")
  392. keyword := strings.Trim(ctx.Query("q"), " ")
  393. var datasetIDs []int64
  394. datasetStars, err := models.GetDatasetStarByUser(ctx.User)
  395. if err != nil {
  396. ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("GetDatasetStarByUser failed", err)))
  397. log.Error("GetDatasetStarByUser failed:", err.Error())
  398. ctx.JSON(200, map[string]string{
  399. "result_code": "-1",
  400. "error_msg": err.Error(),
  401. "data": "",
  402. })
  403. return
  404. }
  405. for i, _ := range datasetStars {
  406. datasetIDs = append(datasetIDs, datasetStars[i].DatasetID)
  407. }
  408. datasets, count, err := models.Attachments(&models.AttachmentsOptions{
  409. ListOptions: models.ListOptions{
  410. Page: page,
  411. PageSize: setting.UI.DatasetPagingNum,
  412. },
  413. Keyword: keyword,
  414. NeedDatasetIDs: true,
  415. DatasetIDs: datasetIDs,
  416. NeedIsPrivate: true,
  417. IsPrivate: false,
  418. Type: cloudbrainType,
  419. JustNeedZipFile: true,
  420. NeedRepoInfo: true,
  421. RecommendOnly: ctx.QueryBool("recommend"),
  422. })
  423. if err != nil {
  424. ctx.ServerError("datasets", err)
  425. return
  426. }
  427. data, err := json.Marshal(datasets)
  428. if err != nil {
  429. log.Error("json.Marshal failed:", err.Error())
  430. ctx.JSON(200, map[string]string{
  431. "result_code": "-1",
  432. "error_msg": err.Error(),
  433. "data": "",
  434. })
  435. return
  436. }
  437. ctx.JSON(200, map[string]string{
  438. "result_code": "0",
  439. "data": string(data),
  440. "count": strconv.FormatInt(count, 10),
  441. })
  442. }
  443. func GetDatasetStatus(ctx *context.Context) {
  444. var (
  445. err error
  446. )
  447. UUID := ctx.Params(":uuid")
  448. attachment, err := models.GetAttachmentByUUID(UUID)
  449. if err != nil {
  450. log.Error("GetDatasetStarByUser failed:", err.Error())
  451. ctx.JSON(200, map[string]string{
  452. "result_code": "-1",
  453. "error_msg": err.Error(),
  454. "data": "",
  455. })
  456. return
  457. }
  458. ctx.JSON(200, map[string]string{
  459. "result_code": "0",
  460. "UUID": UUID,
  461. "AttachmentStatus": fmt.Sprint(attachment.DecompressState),
  462. })
  463. }