person.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. package tmdb
  2. import (
  3. "notabug.org/apiote/amuse/config"
  4. "notabug.org/apiote/amuse/network"
  5. "encoding/json"
  6. "net/http"
  7. "sort"
  8. "time"
  9. "notabug.org/apiote/gott"
  10. )
  11. type Credits struct {
  12. Cast []struct {
  13. Id int
  14. Media_type string `json:"media_type"`
  15. Poster_path string `json:"poster_path"`
  16. Backdrop_path string `json:"backdrop_path"`
  17. Popularity float64
  18. Character string
  19. Title string
  20. Name string
  21. First_air_date_str string `json:"first_air_date"`
  22. Release_date_str string `json:"release_date"`
  23. Release_date time.Time
  24. }
  25. Crew []struct {
  26. Id int
  27. Media_type string `json:"media_type"`
  28. Poster_path string `json:"poster_path"`
  29. Job string
  30. Title string
  31. Name string
  32. First_air_date_str string `json:"first_air_date"`
  33. Release_date_str string `json:"release_date"`
  34. Release_date time.Time
  35. }
  36. }
  37. type Person struct {
  38. Etag string
  39. Birthday_str string `json:"birthday"`
  40. Birthday time.Time `json:"-"`
  41. Deathday_str string `json:"deathday"`
  42. Deathday time.Time `json:"-"`
  43. Name string
  44. Biography string
  45. Place_of_birth string `json:"place_of_birth"`
  46. Profile_path string `json:"profile_path"`
  47. Backdrop_path string
  48. Source string
  49. Credits Credits `json:"combined_credits"`
  50. }
  51. func createPersonRequest(args ...interface{}) (interface{}, error) {
  52. request := args[0].(*network.Request)
  53. result := args[1].(*network.Result)
  54. client := &http.Client{}
  55. httpRequest, err := http.NewRequest("GET", "https://api.themoviedb.org/3/person/"+request.Id+"?api_key="+config.TmdbApiKey+"&language="+request.Language+"&append_to_response=combined_credits", nil)
  56. result.Client = client
  57. result.Request = httpRequest
  58. return gott.Tuple(args), err
  59. }
  60. func unmarshalPerson(args ...interface{}) (interface{}, error) {
  61. id := args[0].(*network.Request).Id
  62. result := args[1].(*network.Result)
  63. person := &Person{}
  64. err := json.Unmarshal(result.Body, person)
  65. person.Etag = result.Etag
  66. person.Source = "https://themoviedb.org/person/" + id
  67. result.Result = person
  68. return gott.Tuple(args), err
  69. }
  70. func convertPersonBirthDate(args ...interface{}) (interface{}, error) {
  71. person := args[1].(*network.Result).Result.(*Person)
  72. var (
  73. date time.Time
  74. err error
  75. )
  76. if person.Birthday_str != "" {
  77. date, err = time.Parse("2006-01-02", person.Birthday_str)
  78. person.Birthday = date
  79. }
  80. return gott.Tuple(args), err
  81. }
  82. func convertPersonDeathDate(args ...interface{}) (interface{}, error) {
  83. person := args[1].(*network.Result).Result.(*Person)
  84. var (
  85. date time.Time
  86. err error
  87. )
  88. if person.Deathday_str != "" {
  89. date, err = time.Parse("2006-01-02", person.Deathday_str)
  90. person.Deathday = date
  91. }
  92. return gott.Tuple(args), err
  93. }
  94. func convertJobsDates(args ...interface{}) (interface{}, error) {
  95. person := args[1].(*network.Result).Result.(*Person)
  96. for i, character := range person.Credits.Cast {
  97. if character.Release_date_str != "" {
  98. date, err := time.Parse("2006-01-02", character.Release_date_str)
  99. character.Release_date = date
  100. if err != nil {
  101. return gott.Tuple(args), err
  102. }
  103. }
  104. if character.First_air_date_str != "" {
  105. date, err := time.Parse("2006-01-02", character.First_air_date_str)
  106. character.Release_date = date
  107. if err != nil {
  108. return gott.Tuple(args), err
  109. }
  110. }
  111. person.Credits.Cast[i] = character
  112. }
  113. for i, job := range person.Credits.Crew {
  114. if job.Release_date_str != "" {
  115. date, err := time.Parse("2006-01-02", job.Release_date_str)
  116. job.Release_date = date
  117. if err != nil {
  118. return gott.Tuple(args), err
  119. }
  120. }
  121. if job.First_air_date_str != "" {
  122. date, err := time.Parse("2006-01-02", job.First_air_date_str)
  123. job.Release_date = date
  124. if err != nil {
  125. return gott.Tuple(args), err
  126. }
  127. }
  128. person.Credits.Crew[i] = job
  129. }
  130. return gott.Tuple(args), nil
  131. }
  132. func convertJobsNames(args ...interface{}) interface{} {
  133. person := args[1].(*network.Result).Result.(*Person)
  134. for i, character := range person.Credits.Cast {
  135. if character.Title == "" {
  136. character.Title = character.Name
  137. }
  138. person.Credits.Cast[i] = character
  139. }
  140. for i, job := range person.Credits.Crew {
  141. if job.Title == "" {
  142. job.Title = job.Name
  143. }
  144. person.Credits.Crew[i] = job
  145. }
  146. return gott.Tuple(args)
  147. }
  148. func sortJobs(args ...interface{}) interface{} {
  149. person := args[1].(*network.Result).Result.(*Person)
  150. sort.Slice(person.Credits.Cast, func(i, j int) bool {
  151. isBefore := person.Credits.Cast[i].Release_date.Before(person.Credits.Cast[j].Release_date)
  152. return (!isBefore || person.Credits.Cast[i].Release_date.IsZero()) &&
  153. (isBefore || !person.Credits.Cast[j].Release_date.IsZero())
  154. })
  155. sort.Slice(person.Credits.Crew, func(i, j int) bool {
  156. isBefore := person.Credits.Crew[i].Release_date.Before(person.Credits.Crew[j].Release_date)
  157. return (!isBefore || person.Credits.Crew[i].Release_date.IsZero()) &&
  158. (isBefore || !person.Credits.Crew[j].Release_date.IsZero())
  159. })
  160. return gott.Tuple(args)
  161. }
  162. func getBackdrop(args ...interface{}) interface{} {
  163. person := args[1].(*network.Result).Result.(*Person)
  164. maxPopularity := 0.0
  165. backdropPath := ""
  166. for _, f := range person.Credits.Cast {
  167. if f.Popularity > maxPopularity {
  168. backdropPath = f.Backdrop_path
  169. maxPopularity = f.Popularity
  170. }
  171. }
  172. person.Backdrop_path = backdropPath
  173. return gott.Tuple(args)
  174. }
  175. func GetPerson(id, language, etag string) (*Person, error) {
  176. person, err := gott.
  177. NewResult(gott.Tuple{&network.Request{Id: id, Etag: etag, Language: language}, &network.Result{}}).
  178. Bind(createPersonRequest).
  179. Map(network.AddHeaders).
  180. Bind(network.DoRequest).
  181. Bind(network.HandleRequestError).
  182. Bind(network.ReadResponse).
  183. Bind(unmarshalPerson).
  184. Bind(convertPersonBirthDate).
  185. Bind(convertPersonDeathDate).
  186. Bind(convertJobsDates).
  187. Map(convertJobsNames).
  188. Map(sortJobs).
  189. Map(getBackdrop).
  190. Finish()
  191. if err != nil {
  192. return &Person{}, err
  193. } else {
  194. return person.(gott.Tuple)[1].(*network.Result).Result.(*Person), nil
  195. }
  196. }