person.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. package tmdb
  2. import (
  3. "notabug.org/apiote/amuse/network"
  4. "notabug.org/apiote/amuse/utils"
  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. Character string
  17. Title string
  18. Name string
  19. First_air_date_str string `json:"first_air_date"`
  20. Release_date_str string `json:"release_date"`
  21. Release_date time.Time
  22. }
  23. Crew []struct {
  24. Id int
  25. Media_type string `json:"media_type"`
  26. Poster_path string `json:"poster_path"`
  27. Job string
  28. Title string
  29. Name string
  30. First_air_date_str string `json:"first_air_date"`
  31. Release_date_str string `json:"release_date"`
  32. Release_date time.Time
  33. }
  34. }
  35. type Person struct {
  36. Etag string
  37. Birthday_str string `json:"birthday"`
  38. Birthday time.Time `json:"-"`
  39. Deathday_str string `json:"deathday"`
  40. Deathday time.Time `json:"-"`
  41. Name string
  42. Biography string
  43. Place_of_birth string `json:"place_of_birth"`
  44. Profile_path string `json:"profile_path"`
  45. Source string
  46. Credits Credits `json:"combined_credits"`
  47. }
  48. func createPersonRequest(args ...interface{}) (interface{}, error) {
  49. request := args[0].(*network.Request)
  50. result := args[1].(*network.Result)
  51. client := &http.Client{}
  52. httpRequest, err := http.NewRequest("GET", "https://api.themoviedb.org/3/person/"+request.Id+"?api_key="+API_KEY+"&language="+request.Language+"&append_to_response=combined_credits", nil)
  53. result.Client = client
  54. result.Request = httpRequest
  55. return gott.Tuple(args), err
  56. }
  57. func unmarshalPerson(args ...interface{}) (interface{}, error) {
  58. id := args[0].(*network.Request).Id
  59. result := args[1].(*network.Result)
  60. person := &Person{}
  61. err := json.Unmarshal(result.Body, person)
  62. person.Etag = result.Etag
  63. person.Source = "https://themoviedb.org/person/" + id
  64. result.Result = person
  65. return gott.Tuple(args), err
  66. }
  67. func convertPersonDates(args ...interface{}) (interface{}, error) {
  68. person := args[1].(*network.Result).Result.(*Person)
  69. var err error
  70. if person.Birthday_str != "" {
  71. date, err2 := time.Parse("2006-01-02", person.Birthday_str)
  72. person.Birthday = date
  73. err = utils.Or(err, err2)
  74. }
  75. if person.Deathday_str != "" {
  76. date, err2 := time.Parse("2006-01-02", person.Deathday_str)
  77. person.Deathday = date
  78. err = utils.Or(err, err2)
  79. }
  80. return gott.Tuple(args), err
  81. }
  82. func convertJobsDates(args ...interface{}) (interface{}, error) {
  83. person := args[1].(*network.Result).Result.(*Person)
  84. var err error
  85. for i, character := range person.Credits.Cast {
  86. if character.Release_date_str != "" {
  87. date, err2 := time.Parse("2006-01-02", character.Release_date_str)
  88. character.Release_date = date
  89. err = utils.Or(err, err2)
  90. }
  91. if character.First_air_date_str != "" {
  92. date, err2 := time.Parse("2006-01-02", character.First_air_date_str)
  93. character.Release_date = date
  94. err = utils.Or(err, err2)
  95. }
  96. person.Credits.Cast[i] = character
  97. }
  98. for i, job := range person.Credits.Crew {
  99. if job.Release_date_str != "" {
  100. date, err2 := time.Parse("2006-01-02", job.Release_date_str)
  101. job.Release_date = date
  102. err = utils.Or(err, err2)
  103. }
  104. if job.First_air_date_str != "" {
  105. date, err2 := time.Parse("2006-01-02", job.First_air_date_str)
  106. job.Release_date = date
  107. err = utils.Or(err, err2)
  108. }
  109. person.Credits.Crew[i] = job
  110. }
  111. return gott.Tuple(args), err
  112. }
  113. func convertJobsNames(args ...interface{}) interface{} {
  114. person := args[1].(*network.Result).Result.(*Person)
  115. for i, character := range person.Credits.Cast {
  116. if character.Title == "" {
  117. character.Title = character.Name
  118. }
  119. person.Credits.Cast[i] = character
  120. }
  121. for i, job := range person.Credits.Crew {
  122. if job.Title == "" {
  123. job.Title = job.Name
  124. }
  125. person.Credits.Crew[i] = job
  126. }
  127. return gott.Tuple(args)
  128. }
  129. func sortJobs(args ...interface{}) interface{} {
  130. person := args[1].(*network.Result).Result.(*Person)
  131. sort.Slice(person.Credits.Cast, func(i, j int) bool {
  132. isBefore := person.Credits.Cast[i].Release_date.Before(person.Credits.Cast[j].Release_date)
  133. return (!isBefore || person.Credits.Cast[i].Release_date.IsZero()) &&
  134. (isBefore || !person.Credits.Cast[j].Release_date.IsZero())
  135. })
  136. sort.Slice(person.Credits.Crew, func(i, j int) bool {
  137. isBefore := person.Credits.Crew[i].Release_date.Before(person.Credits.Crew[j].Release_date)
  138. return (!isBefore || person.Credits.Crew[i].Release_date.IsZero()) &&
  139. (isBefore || !person.Credits.Crew[j].Release_date.IsZero())
  140. })
  141. return gott.Tuple(args)
  142. }
  143. func GetPerson(id, language, etag string) (*Person, error) {
  144. person, err := gott.
  145. NewResult(gott.Tuple{&network.Request{Id: id, Etag: etag, Language: language}, &network.Result{}}).
  146. Bind(createPersonRequest).
  147. Map(network.AddHeaders).
  148. Bind(network.DoRequest).
  149. Bind(network.HandleRequestError).
  150. Bind(network.ReadResponse).
  151. Bind(unmarshalPerson).
  152. Bind(convertPersonDates).
  153. Bind(convertJobsDates).
  154. Map(convertJobsNames).
  155. Map(sortJobs).
  156. Finish()
  157. if err != nil {
  158. return &Person{}, err
  159. } else {
  160. return person.(gott.Tuple)[1].(*network.Result).Result.(*Person), nil
  161. }
  162. }