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