movieStats.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package model
  2. import (
  3. "crawler/config"
  4. "crawler/service"
  5. "net/url"
  6. "regexp"
  7. "strconv"
  8. )
  9. type MovieStatsModel struct {
  10. SearchBoxOfficeParams
  11. SearchBoxOfficeList
  12. BoxOfficeInfo
  13. MovieStatsTable
  14. }
  15. // 박스오피스 검색 변수
  16. type SearchBoxOfficeParams struct {
  17. ServiceKey string `form:"serviceKey" url:"serviceKey" binding:"required"`
  18. NumOfRows int `form:"numOfRows" url:"numOfRows,omitempty"`
  19. PageNo int `form:"pageNo" url:"pageNo,omitempty"`
  20. }
  21. // 박스오피스 응답 변수
  22. type SearchBoxOfficeList struct {
  23. Response struct {
  24. Header struct {
  25. ResultCode string `json:"resultCode"`
  26. ResultMsg string `json:"resultMsg"`
  27. } `json:"header"`
  28. Body struct {
  29. Items struct {
  30. Item []BoxOfficeInfo `json:"item"`
  31. } `json:"items"`
  32. NumOfRows string `json:"numOfRows"`
  33. PageNo string `json:"pageNo"`
  34. TotalCount string `json:"totalCount"`
  35. } `json:"body"`
  36. } `json:"response"`
  37. }
  38. type BoxOfficeInfo struct {
  39. Title string `json:"title"`
  40. AlternativeTitle string `json:"alternativeTitle"`
  41. Creator string `json:"creator"`
  42. RegDate string `json:"regDate"`
  43. CollectionDb string `json:"collectionDb"`
  44. SubjectCategory string `json:"subjectCategory"`
  45. SubjectKeyword string `json:"subjectKeyword"`
  46. Extent string `json:"extent"`
  47. Description string `json:"description"`
  48. SpatialCoverage string `json:"spatialCoverage"`
  49. Temporal string `json:"temporal"`
  50. Person string `json:"person"`
  51. Language string `json:"language"`
  52. SourceTitle string `json:"sourceTitle"`
  53. ReferenceIdentifier string `json:"referenceIdentifier"`
  54. Rights string `json:"rights"`
  55. CopyrightOthers string `json:"copyrightOthers"`
  56. Url string `json:"url"`
  57. Contributor string `json:"contributor"`
  58. }
  59. type MovieStatsTable struct {
  60. StatsID int
  61. MovieCd *string
  62. MovieNm *string
  63. ShowDt *int
  64. SaleAcc int
  65. AudiAcc int
  66. ScrnCnt int
  67. ShowCnt int
  68. RegDate *string
  69. CreatedAt string
  70. }
  71. func (this *MovieStatsModel) Insert(list []BoxOfficeInfo) error {
  72. if len(list) <= 0 {
  73. return nil
  74. }
  75. var (
  76. db = service.DB_MOVIEW
  77. conn = db.SQLDB
  78. query = `
  79. INSERT INTO tb_movie_stats (
  80. movie_cd, movie_nm, show_dt, sale_acc, audi_acc, scrn_cnt, show_cnt, reg_date, updated_at, created_at
  81. )
  82. VALUES
  83. `
  84. vals = []interface{}{}
  85. dup string
  86. )
  87. for _, row := range list {
  88. query += `(?, ?, ?, ?, ?, ?, ?, ?, NULL, NOW()),`
  89. data := this.DataFilter(row)
  90. vals = append(vals,
  91. data.MovieCd, data.MovieNm, data.ShowDt, data.SaleAcc, data.AudiAcc, data.ScrnCnt, data.ShowCnt, data.RegDate)
  92. dup += `movie_cd = VALUES(movie_cd), movie_nm = VALUES(movie_nm), show_dt = VALUES(show_dt),
  93. sale_acc = VALUES(sale_acc), audi_acc = VALUES(audi_acc), scrn_cnt = VALUES(scrn_cnt),
  94. show_cnt = VALUES(show_cnt), reg_date = VALUES(reg_date), updated_at = NOW(),`
  95. }
  96. query = query[0 : len(query)-1]
  97. dup = dup[0 : len(dup)-1]
  98. query += ` ON DUPLICATE KEY UPDATE ` + dup
  99. _, _ = conn.Exec("LOCK TABLE tb_movie_stats READ;")
  100. stmt, err := conn.Prepare(query)
  101. if err != nil {
  102. db.SetErrorLog(err, query)
  103. return err
  104. }
  105. defer stmt.Close()
  106. _, err = stmt.Exec(vals...)
  107. if err != nil {
  108. db.SetErrorLog(err, query)
  109. return err
  110. }
  111. _, _ = conn.Exec("UNLOCK TABLES;")
  112. db.SetGeneralLog(config.GL_ACTION_WRITE, query, "insert movie stats")
  113. return nil
  114. }
  115. func (this *MovieStatsModel) IsExists(movieCd string) bool {
  116. var (
  117. db = service.DB_MOVIEW
  118. conn = db.SQLDB
  119. query = "SELECT IF(COUNT(*) <= 0, 0, 1) AS `exists` FROM tb_movie_stats WHERE movie_cd = ?;"
  120. exists = false
  121. )
  122. err := conn.QueryRow(query, movieCd).Scan(&exists)
  123. if err != nil {
  124. db.SetErrorLog(err, query)
  125. return exists
  126. }
  127. db.SetGeneralLog(config.GL_ACTION_SELECT, query, "select exists movie stats")
  128. return exists
  129. }
  130. func (this *MovieStatsModel) Update(list []BoxOfficeInfo) error {
  131. if len(list) <= 0 {
  132. return nil
  133. }
  134. var (
  135. db = service.DB_MOVIEW
  136. conn = db.SQLDB
  137. query = `
  138. UPDATE tb_movie_stats SET
  139. movie_cd = ?, movie_nm = ?, show_dt = ?, sale_acc = ?, audi_acc = ?,
  140. scrn_cnt = ?, show_cnt = ?, reg_date = ?, updated_at = NOW()
  141. WHERE movie_cd = ?;
  142. `
  143. )
  144. for _, row := range list {
  145. data := this.DataFilter(row)
  146. _, err := conn.Exec(query,
  147. data.MovieCd, data.MovieNm, data.ShowDt, data.SaleAcc, data.AudiAcc, data.ScrnCnt, data.ShowCnt, data.RegDate, data.MovieCd)
  148. if err != nil {
  149. db.SetErrorLog(err, query)
  150. return err
  151. }
  152. }
  153. db.SetGeneralLog(config.GL_ACTION_MODIFY, query, "update movie stats")
  154. return nil
  155. }
  156. func (this *MovieStatsModel) DataFilter(row BoxOfficeInfo) MovieStatsTable {
  157. var result MovieStatsTable
  158. query, err := url.ParseQuery(row.Url)
  159. if err != nil {
  160. return result
  161. }
  162. var (
  163. movieCd = query.Get("dtCd")
  164. showDt = query.Get("showdt")
  165. )
  166. result.MovieCd = &movieCd
  167. if row.Title != "" {
  168. result.MovieNm = &row.Title
  169. } else {
  170. result.MovieNm = nil
  171. }
  172. if showDt != "" {
  173. s, _ := strconv.Atoi(query.Get("showdt"))
  174. result.ShowDt = &s
  175. } else {
  176. result.ShowDt = nil
  177. }
  178. // 매출액, 관객수, 스크린수, 상영횟수
  179. re := regexp.MustCompile("[0-9]+")
  180. stats := re.FindAllString(row.Description, -1)
  181. if stats[0] != "" {
  182. s, _ := strconv.Atoi(stats[0])
  183. result.SaleAcc = s
  184. }
  185. if stats[1] != "" {
  186. s, _ := strconv.Atoi(stats[1])
  187. result.AudiAcc = s
  188. }
  189. if stats[2] != "" {
  190. s, _ := strconv.Atoi(stats[2])
  191. result.ScrnCnt = s
  192. }
  193. if stats[3] != "" {
  194. s, _ := strconv.Atoi(stats[3])
  195. result.ShowCnt = s
  196. }
  197. if row.RegDate != "" {
  198. result.RegDate = &row.RegDate
  199. } else {
  200. result.RegDate = nil
  201. }
  202. return result
  203. }