data.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. package service
  2. import (
  3. "context"
  4. "encoding/json"
  5. "strconv"
  6. "strings"
  7. "time"
  8. "go-common/app/admin/ep/saga/model"
  9. "go-common/app/admin/ep/saga/service/utils"
  10. "go-common/library/log"
  11. "github.com/xanzy/go-gitlab"
  12. )
  13. /*-------------------------------------- sync issue ----------------------------------------*/
  14. // SyncAllIssues ...
  15. func (s *Service) SyncAllIssues(projectID int) (totalPage, totalNum int, err error) {
  16. var (
  17. //syncAllTime = conf.Conf.Property.SyncData.SyncAllTime
  18. syncAllTime = false
  19. issues []*gitlab.Issue
  20. resp *gitlab.Response
  21. since *time.Time
  22. until *time.Time
  23. )
  24. if !syncAllTime {
  25. since, until = utils.CalSyncTime()
  26. }
  27. for page := 1; ; page++ {
  28. totalPage++
  29. if issues, resp, err = s.gitlab.ListProjectIssues(projectID, page, since, until); err != nil {
  30. return
  31. }
  32. for _, issue := range issues {
  33. var (
  34. issueAssignees string
  35. issueLabels string
  36. issueTimeStats string
  37. milestoneID int
  38. )
  39. if issue.Milestone != nil {
  40. milestoneID = issue.Milestone.ID
  41. }
  42. issueAssigneesByte, _ := json.Marshal(issue.Assignees)
  43. issueAssignees = string(issueAssigneesByte)
  44. issueLabelsByte, _ := json.Marshal(issue.Labels)
  45. issueLabels = string(issueLabelsByte)
  46. issueTimeStatsByte, _ := json.Marshal(issue.TimeStats)
  47. issueTimeStats = string(issueTimeStatsByte)
  48. issueDB := &model.StatisticsIssues{
  49. ProjectID: projectID,
  50. IssueID: issue.ID,
  51. IssueIID: issue.IID,
  52. MilestoneID: milestoneID,
  53. Description: issue.Description,
  54. State: issue.State,
  55. Assignees: issueAssignees,
  56. Upvotes: issue.Upvotes,
  57. Downvotes: issue.Downvotes,
  58. Labels: issueLabels,
  59. Title: issue.Title,
  60. UpdatedAt: issue.UpdatedAt,
  61. CreatedAt: issue.CreatedAt,
  62. ClosedAt: issue.ClosedAt,
  63. Subscribed: issue.Subscribed,
  64. UserNotesCount: issue.UserNotesCount,
  65. DueDate: issue.DueDate,
  66. WebURL: issue.WebURL,
  67. TimeStats: issueTimeStats,
  68. Confidential: issue.Confidential,
  69. Weight: issue.Weight,
  70. DiscussionLocked: issue.DiscussionLocked,
  71. IssueLinkID: issue.IssueLinkID,
  72. }
  73. if issue.Author != nil {
  74. issueDB.AuthorID = issue.Author.ID
  75. issueDB.AuthorName = issue.Author.Name
  76. }
  77. if issue.Assignee != nil {
  78. issueDB.AssigneeID = issue.Assignee.ID
  79. issueDB.AssigneeName = issue.Assignee.Name
  80. }
  81. if len(issueDB.Description) > model.MessageMaxLen {
  82. issueDB.Description = issueDB.Description[0 : model.MessageMaxLen-1]
  83. }
  84. if err = s.SaveDatabaseIssue(issueDB); err != nil {
  85. log.Error("issue Save Database err: projectID(%d), IssueID(%d)", projectID, issue.ID)
  86. err = nil
  87. continue
  88. }
  89. totalNum++
  90. }
  91. if resp.NextPage == 0 {
  92. break
  93. }
  94. }
  95. return
  96. }
  97. // SaveDatabaseIssue ...
  98. func (s *Service) SaveDatabaseIssue(issueDB *model.StatisticsIssues) (err error) {
  99. var total int
  100. if total, err = s.dao.HasIssue(issueDB.ProjectID, issueDB.IssueID); err != nil {
  101. log.Error("SaveDatabaseIssue HasIssue(%+v)", err)
  102. return
  103. }
  104. // update found row
  105. if total == 1 {
  106. if err = s.dao.UpdateIssue(issueDB.ProjectID, issueDB.IssueID, issueDB); err != nil {
  107. if strings.Contains(err.Error(), model.DatabaseErrorText) {
  108. issueDB.Title = strconv.QuoteToASCII(issueDB.Title)
  109. issueDB.Description = strconv.QuoteToASCII(issueDB.Description)
  110. issueDB.Title = utils.Unicode2Chinese(issueDB.Title)
  111. issueDB.Description = utils.Unicode2Chinese(issueDB.Description)
  112. }
  113. if err = s.dao.UpdateIssue(issueDB.ProjectID, issueDB.IssueID, issueDB); err != nil {
  114. log.Error("SaveDatabaseIssue UpdateIssue(%+v)", err)
  115. return
  116. }
  117. }
  118. return
  119. } else if total > 1 {
  120. // found repeated row, this situation will not exist under normal
  121. log.Warn("SaveDatabaseIssue issue has more rows(%d)", total)
  122. return
  123. }
  124. // insert row now
  125. if err = s.dao.CreateIssue(issueDB); err != nil {
  126. if strings.Contains(err.Error(), model.DatabaseErrorText) {
  127. issueDB.Title = strconv.QuoteToASCII(issueDB.Title)
  128. issueDB.Description = strconv.QuoteToASCII(issueDB.Description)
  129. issueDB.Title = utils.Unicode2Chinese(issueDB.Title)
  130. issueDB.Description = utils.Unicode2Chinese(issueDB.Description)
  131. }
  132. if err = s.dao.CreateIssue(issueDB); err != nil {
  133. log.Error("SaveDatabaseIssue CreateIssue(%+v)", err)
  134. return
  135. }
  136. }
  137. return
  138. }
  139. /*-------------------------------------- sync note ----------------------------------------*/
  140. // SyncProjectNotes ...
  141. func (s *Service) SyncProjectNotes(c context.Context, projectID int) (totalPage, totalNum int, err error) {
  142. var (
  143. //syncAllTime = conf.Conf.Property.SyncData.SyncAllTime
  144. syncAllTime = false
  145. resp *gitlab.Response
  146. projectInfo *model.ProjectInfo
  147. mrs []*model.StatisticsMrs
  148. notes []*gitlab.Note
  149. since *time.Time
  150. until *time.Time
  151. )
  152. if projectInfo, err = s.dao.ProjectInfoByID(projectID); err != nil {
  153. return
  154. }
  155. if !syncAllTime {
  156. since, until = utils.CalSyncTime()
  157. }
  158. if mrs, err = s.dao.MRByProjectID(c, projectID, since, until); err != nil {
  159. return
  160. }
  161. for _, mr := range mrs {
  162. for page := 1; ; page++ {
  163. totalPage++
  164. if notes, resp, err = s.gitlab.ListMRNotes(c, projectID, mr.MRIID, page); err != nil {
  165. return
  166. }
  167. for _, note := range notes {
  168. var (
  169. notePosition string
  170. notePositionByte []byte
  171. )
  172. if notePositionByte, err = json.Marshal(note.Position); err != nil {
  173. return
  174. }
  175. notePosition = string(notePositionByte)
  176. noteDB := &model.StatisticsNotes{
  177. ProjectID: projectID,
  178. ProjectName: projectInfo.Name,
  179. MrIID: mr.MRIID,
  180. NoteID: note.ID,
  181. Body: note.Body,
  182. Attachment: note.Attachment,
  183. Title: note.Title,
  184. FileName: note.FileName,
  185. AuthorID: note.Author.ID,
  186. AuthorName: note.Author.Name,
  187. System: note.System,
  188. ExpiresAt: note.ExpiresAt,
  189. UpdatedAt: note.UpdatedAt,
  190. CreatedAt: note.CreatedAt,
  191. NoteableID: note.NoteableID,
  192. NoteableType: note.NoteableType,
  193. Position: notePosition,
  194. Resolvable: note.Resolvable,
  195. Resolved: note.Resolved,
  196. ResolvedByID: note.ResolvedBy.ID,
  197. ResolvedByName: note.ResolvedBy.Username,
  198. NoteableIID: note.NoteableIID,
  199. }
  200. if err = s.SaveDatabaseNote(c, noteDB); err != nil {
  201. log.Error("note Save Database err: projectID(%d), NoteID(%d)", projectID, note.ID)
  202. err = nil
  203. continue
  204. }
  205. totalNum++
  206. }
  207. if resp.NextPage == 0 {
  208. break
  209. }
  210. }
  211. }
  212. return
  213. }
  214. // HandleNoteDBError ...
  215. func (s *Service) HandleNoteDBError(c context.Context, noteDB *model.StatisticsNotes, errText string) (note *model.StatisticsNotes) {
  216. if strings.Contains(errText, model.DatabaseErrorText) {
  217. noteDB.Title = strconv.QuoteToASCII(noteDB.Title)
  218. noteDB.Body = strconv.QuoteToASCII(noteDB.Body)
  219. noteDB.Title = utils.Unicode2Chinese(noteDB.Title)
  220. noteDB.Body = utils.Unicode2Chinese(noteDB.Body)
  221. if len(noteDB.Body) > model.MessageMaxLen {
  222. noteDB.Body = noteDB.Body[0 : model.MessageMaxLen-1]
  223. }
  224. } else if strings.Contains(errText, model.DatabaseMaxLenthErrorText) {
  225. noteDB.Body = noteDB.Body[0 : model.MessageMaxLen-1]
  226. }
  227. return noteDB
  228. }
  229. // SaveDatabaseNote ...
  230. func (s *Service) SaveDatabaseNote(c context.Context, noteDB *model.StatisticsNotes) (err error) {
  231. var total int
  232. if total, err = s.dao.HasNote(c, noteDB.ProjectID, noteDB.NoteID); err != nil {
  233. log.Error("SaveDatabaseNote HasNote(%+v)", err)
  234. return
  235. }
  236. // update found row
  237. if total == 1 {
  238. if err = s.dao.UpdateNote(c, noteDB.ProjectID, noteDB.NoteID, noteDB); err != nil {
  239. noteDB = s.HandleNoteDBError(c, noteDB, err.Error())
  240. if err = s.dao.UpdateNote(c, noteDB.ProjectID, noteDB.NoteID, noteDB); err != nil {
  241. log.Error("SaveDatabaseNote UpdateNote(%+v)", err)
  242. return
  243. }
  244. }
  245. return
  246. } else if total > 1 {
  247. // found repeated row, this situation will not exist under normal
  248. log.Warn("SaveDatabaseNote Note has more rows(%d)", total)
  249. return
  250. }
  251. // insert row now
  252. if err = s.dao.CreateNote(c, noteDB); err != nil {
  253. noteDB = s.HandleNoteDBError(c, noteDB, err.Error())
  254. if err = s.dao.CreateNote(c, noteDB); err != nil {
  255. log.Error("SaveDatabaseNote CreateNote(%+v)", err)
  256. return
  257. }
  258. }
  259. return
  260. }
  261. /*-------------------------------------- sync emoji ----------------------------------------*/
  262. // SyncProjectAwardEmoji ...
  263. func (s *Service) SyncProjectAwardEmoji(c context.Context, projectID int) (totalPage, totalNum int, err error) {
  264. var (
  265. //syncAllTime = conf.Conf.Property.SyncData.SyncAllTime
  266. syncAllTime = false
  267. resp *gitlab.Response
  268. projectInfo *model.ProjectInfo
  269. mrs []*model.StatisticsMrs
  270. awardEmojis []*gitlab.AwardEmoji
  271. since *time.Time
  272. until *time.Time
  273. )
  274. if projectInfo, err = s.dao.ProjectInfoByID(projectID); err != nil {
  275. return
  276. }
  277. if !syncAllTime {
  278. since, until = utils.CalSyncTime()
  279. }
  280. if mrs, err = s.dao.MRByProjectID(c, projectID, since, until); err != nil {
  281. return
  282. }
  283. for _, mr := range mrs {
  284. for page := 1; ; page++ {
  285. totalPage++
  286. if awardEmojis, resp, err = s.gitlab.ListMRAwardEmoji(projectID, mr.MRIID, page); err != nil {
  287. return
  288. }
  289. for _, awardEmoji := range awardEmojis {
  290. awardEmojiDB := &model.StatisticsMRAwardEmojis{
  291. ProjectID: projectID,
  292. ProjectName: projectInfo.Name,
  293. MrIID: mr.MRIID,
  294. AwardEmojiID: awardEmoji.ID,
  295. Name: awardEmoji.Name,
  296. UserID: awardEmoji.User.ID,
  297. UserName: awardEmoji.User.Name,
  298. CreatedAt: awardEmoji.CreatedAt,
  299. UpdatedAt: awardEmoji.UpdatedAt,
  300. AwardableID: awardEmoji.AwardableID,
  301. AwardableType: awardEmoji.AwardableType,
  302. }
  303. if err = s.SaveDatabaseAwardEmoji(c, awardEmojiDB); err != nil {
  304. log.Error("awardEmoji Save Database err: projectID(%d), AwardEmojiID(%d)", projectID, awardEmoji.ID)
  305. err = nil
  306. continue
  307. }
  308. totalNum++
  309. }
  310. if resp.NextPage == 0 {
  311. break
  312. }
  313. }
  314. }
  315. return
  316. }
  317. // SaveDatabaseAwardEmoji ...
  318. func (s *Service) SaveDatabaseAwardEmoji(c context.Context, awardEmojiDB *model.StatisticsMRAwardEmojis) (err error) {
  319. var total int
  320. if total, err = s.dao.HasMRAwardEmoji(c, awardEmojiDB.ProjectID, awardEmojiDB.MrIID, awardEmojiDB.AwardEmojiID); err != nil {
  321. log.Error("SaveDatabaseAwardEmoji HasAwardEmoji(%+v)", err)
  322. return
  323. }
  324. // update found row
  325. if total == 1 {
  326. if err = s.dao.UpdateMRAwardEmoji(c, awardEmojiDB.ProjectID, awardEmojiDB.MrIID, awardEmojiDB.AwardEmojiID, awardEmojiDB); err != nil {
  327. log.Error("SaveDatabaseAwardEmoji UpdateAwardEmoji(%+v)", err)
  328. }
  329. return
  330. } else if total > 1 {
  331. // found repeated row, this situation will not exist under normal
  332. log.Warn("SaveDatabaseAwardEmoji Note has more rows(%d)", total)
  333. return
  334. }
  335. // insert row now
  336. if err = s.dao.CreateMRAwardEmoji(c, awardEmojiDB); err != nil {
  337. log.Error("SaveDatabaseAwardEmoji CreateAwardEmoji(%+v)", err)
  338. return
  339. }
  340. return
  341. }
  342. /*-------------------------------------- sync Discussion ----------------------------------------*/
  343. // SyncProjectDiscussion ...
  344. func (s *Service) SyncProjectDiscussion(c context.Context, projectID int) (totalPage, totalNum int, err error) {
  345. var (
  346. //syncAllTime = conf.Conf.Property.SyncData.SyncAllTime
  347. syncAllTime = false
  348. resp *gitlab.Response
  349. projectInfo *model.ProjectInfo
  350. mrs []*model.StatisticsMrs
  351. discussions []*gitlab.Discussion
  352. since *time.Time
  353. until *time.Time
  354. )
  355. if projectInfo, err = s.dao.ProjectInfoByID(projectID); err != nil {
  356. return
  357. }
  358. if !syncAllTime {
  359. since, until = utils.CalSyncTime()
  360. }
  361. if mrs, err = s.dao.MRByProjectID(c, projectID, since, until); err != nil {
  362. return
  363. }
  364. for _, mr := range mrs {
  365. for page := 1; ; page++ {
  366. totalPage++
  367. if discussions, resp, err = s.gitlab.ListMRDiscussions(projectID, mr.MRIID, page); err != nil {
  368. return
  369. }
  370. for _, discussion := range discussions {
  371. var (
  372. notesArray []int
  373. notesByte []byte
  374. notes string
  375. )
  376. if discussion.Notes != nil {
  377. for _, note := range discussion.Notes {
  378. notesArray = append(notesArray, note.ID)
  379. }
  380. }
  381. if notesByte, err = json.Marshal(notesArray); err != nil {
  382. notes = model.JsonMarshalErrorText
  383. } else {
  384. notes = string(notesByte)
  385. }
  386. discussionDB := &model.StatisticsDiscussions{
  387. ProjectID: projectID,
  388. ProjectName: projectInfo.Name,
  389. MrIID: mr.MRIID,
  390. DiscussionID: discussion.ID,
  391. IndividualNote: discussion.IndividualNote,
  392. Notes: notes,
  393. }
  394. if err = s.SaveDatabaseDiscussion(c, discussionDB); err != nil {
  395. log.Error("discussion Save Database err: projectID(%d), DiscussionID(%s)", projectID, discussion.ID)
  396. err = nil
  397. continue
  398. }
  399. totalNum++
  400. }
  401. if resp.NextPage == 0 {
  402. break
  403. }
  404. }
  405. }
  406. return
  407. }
  408. // SaveDatabaseDiscussion ...
  409. func (s *Service) SaveDatabaseDiscussion(c context.Context, discussionDB *model.StatisticsDiscussions) (err error) {
  410. var total int
  411. if total, err = s.dao.HasDiscussion(c, discussionDB.ProjectID, discussionDB.MrIID, discussionDB.DiscussionID); err != nil {
  412. log.Error("SaveDatabaseDiscussion HasDiscussion(%+v)", err)
  413. return
  414. }
  415. // update found row
  416. if total == 1 {
  417. if err = s.dao.UpdateDiscussion(c, discussionDB.ProjectID, discussionDB.MrIID, discussionDB.DiscussionID, discussionDB); err != nil {
  418. log.Error("SaveDatabaseDiscussion UpdateDiscussion(%+v)", err)
  419. }
  420. return
  421. } else if total > 1 {
  422. // found repeated row, this situation will not exist under normal
  423. log.Warn("SaveDatabaseDiscussion Note has more rows(%d)", total)
  424. return
  425. }
  426. // insert row now
  427. if err = s.dao.CreateDiscussion(c, discussionDB); err != nil {
  428. log.Error("SaveDatabaseDiscussion CreateDiscussion(%+v)", err)
  429. return
  430. }
  431. return
  432. }