serie.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. package libamuse
  2. import (
  3. "notabug.org/apiote/amuse/accounts"
  4. "notabug.org/apiote/amuse/datastructure"
  5. "notabug.org/apiote/amuse/db"
  6. "notabug.org/apiote/amuse/tmdb"
  7. "fmt"
  8. "sort"
  9. "strings"
  10. "time"
  11. "notabug.org/apiote/gott"
  12. )
  13. func min(a, b int) int {
  14. if a > b {
  15. return b
  16. } else {
  17. return a
  18. }
  19. }
  20. func getTvSerie(args ...interface{}) (interface{}, error) {
  21. data := args[0].(*RequestData)
  22. result := args[1].(*Result)
  23. languages := result.languages
  24. tvSerie, err := tmdb.GetSerie(data.id, languages[0].String())
  25. result.result = tvSerie
  26. return gott.Tuple(args), err
  27. }
  28. func getSeasons(args ...interface{}) (interface{}, error) {
  29. result := args[1].(*Result)
  30. tvSerie := result.result.(*tmdb.TvSerie)
  31. languages := result.languages
  32. seasons, err := tmdb.GetSeasons(tvSerie, languages[0].String())
  33. tvSerie.Seasons = seasons
  34. return gott.Tuple(args), err
  35. }
  36. func getSeason(args ...interface{}) (interface{}, error) {
  37. result := args[1].(*Result)
  38. itemId := args[3].(string)
  39. id := strings.Split(itemId, "/")
  40. var seasonNumber int
  41. fmt.Sscanf(id[1][1:3], "%d", &seasonNumber)
  42. tvSerie := result.result.(*tmdb.TvSerie)
  43. languages := result.languages
  44. season, err := tmdb.GetSeason(tvSerie, languages[0].String(), seasonNumber)
  45. tvSerie.Seasons = make([]tmdb.Season, seasonNumber+1)
  46. tvSerie.Seasons[seasonNumber] = season
  47. return gott.Tuple(args), err
  48. }
  49. func mergeCredits(args ...interface{}) (interface{}, error) {
  50. result := args[1].(*Result)
  51. mergedCast := map[string]tmdb.ShowCastEntry{}
  52. mergedCrew := map[string]tmdb.ShowCrewEntry{}
  53. tvSerie := result.result.(*tmdb.TvSerie)
  54. for _, person := range tvSerie.Credits.Cast {
  55. mergedCast[person.Name+person.Character] = person
  56. }
  57. for _, season := range tvSerie.Seasons {
  58. for _, person := range season.Credits.Cast {
  59. mergedCast[person.Name+person.Character] = person
  60. }
  61. }
  62. for _, person := range tvSerie.Credits.Crew {
  63. mergedCrew[person.Name+person.Job] = person
  64. }
  65. for _, season := range tvSerie.Seasons {
  66. for _, person := range season.Credits.Crew {
  67. mergedCrew[person.Name+person.Job] = person
  68. }
  69. }
  70. tvSerie.Credits.Cast = []tmdb.ShowCastEntry{}
  71. for _, value := range mergedCast {
  72. tvSerie.Credits.Cast = append(tvSerie.Credits.Cast, value)
  73. }
  74. sort.Slice(tvSerie.Credits.Cast, func(i, j int) bool {
  75. return tvSerie.Credits.Cast[i].Character < tvSerie.Credits.Cast[j].Character
  76. })
  77. tvSerie.Credits.Crew = []tmdb.ShowCrewEntry{}
  78. for _, value := range mergedCrew {
  79. tvSerie.Credits.Crew = append(tvSerie.Credits.Crew, value)
  80. }
  81. sort.Slice(tvSerie.Credits.Crew, func(i, j int) bool {
  82. return tvSerie.Credits.Crew[i].Job < tvSerie.Credits.Crew[j].Job
  83. })
  84. return gott.Tuple(args), nil
  85. }
  86. func renderSerie(args ...interface{}) interface{} {
  87. result := args[1].(*Result)
  88. tvSerie := result.result.(*tmdb.TvSerie)
  89. result.page = result.renderer.RenderTvSerie(tvSerie, result.languages)
  90. return gott.Tuple(args)
  91. }
  92. func countAllEpisodes(args ...interface{}) interface{} {
  93. result := args[1].(*Result)
  94. tvSerie := result.result.(*tmdb.TvSerie)
  95. for _, season := range tvSerie.Seasons {
  96. tvSerie.AllEpisodes += len(season.Episodes)
  97. }
  98. return gott.Tuple(args)
  99. }
  100. func calculateProgress(args ...interface{}) (interface{}, error) {
  101. result := args[1].(*Result)
  102. tvSerie := result.result.(*tmdb.TvSerie)
  103. if result.user.IsEmpty() {
  104. return gott.Tuple(args), nil
  105. }
  106. experiences, err := db.GetItemExperiences(result.user.Username, tvSerie.Id, datastructure.ItemTypeTvserie)
  107. var (
  108. watched int
  109. skipped int
  110. watchedAndSkipped int
  111. )
  112. for _, e := range experiences {
  113. isWatched := false
  114. for _, t := range e {
  115. if !t.IsZero() {
  116. isWatched = true
  117. break
  118. }
  119. }
  120. if isWatched {
  121. watched += 1
  122. } else {
  123. skipped += 1
  124. }
  125. watchedAndSkipped += 1
  126. }
  127. if tvSerie.AllEpisodes > 0 {
  128. tvSerie.Progress = min(watched*100/(tvSerie.AllEpisodes-skipped), 100)
  129. }
  130. tvSerie.WatchedEpisodes = watched
  131. tvSerie.SkippedEpisodes = skipped
  132. return gott.Tuple(args), err
  133. }
  134. func findNextEpisode(args ...interface{}) (interface{}, error) {
  135. result := args[1].(*Result)
  136. tvSerie := result.result.(*tmdb.TvSerie)
  137. if result.user.IsEmpty() {
  138. return gott.Tuple(args), nil
  139. }
  140. experiences, err := db.GetItemExperiences(result.user.Username, tvSerie.Id, datastructure.ItemTypeTvserie)
  141. for _, season := range tvSerie.Seasons {
  142. for _, episode := range season.Episodes {
  143. id := tvSerie.Id + "/" + episode.Episode_code
  144. if len(experiences[id]) == 0 {
  145. tvSerie.Next_episode_to_watch = episode
  146. return gott.Tuple(args), err
  147. }
  148. }
  149. }
  150. return gott.Tuple(args), err
  151. }
  152. func setSpoilers(args ...interface{}) interface{} {
  153. result := args[1].(*Result)
  154. tvSerie := result.result.(*tmdb.TvSerie)
  155. nextEpisode := tvSerie.Next_episode_to_watch
  156. nextCode := nextEpisode.Episode_code
  157. if nextCode == "" {
  158. if tvSerie.WatchedEpisodes > 0 {
  159. nextCode = "S99E99"
  160. } else {
  161. nextCode = "S01E01"
  162. }
  163. }
  164. nextDate := nextEpisode.Air_date
  165. if nextDate.IsZero() {
  166. if tvSerie.WatchedEpisodes > 0 {
  167. nextDate = time.Now()
  168. } else {
  169. for _, season := range tvSerie.Seasons {
  170. if season.Season_number == 1 && len(season.Episodes) > 0 {
  171. nextDate = season.Episodes[0].Air_date
  172. }
  173. }
  174. }
  175. }
  176. for s := 0; s < len(tvSerie.Seasons); s++ {
  177. for e := 0; e < len(tvSerie.Seasons[s].Episodes); e++ {
  178. episode := &(tvSerie.Seasons[s].Episodes[e])
  179. if episode.Air_date.After(nextDate) ||
  180. (episode.Air_date == nextDate && episode.Episode_code > nextCode) {
  181. episode.ContainsSpoilers = true
  182. }
  183. }
  184. }
  185. episode := &(tvSerie.Last_episode_to_air)
  186. if episode.Air_date.After(nextDate) ||
  187. (episode.Air_date == nextDate && episode.Episode_code > nextCode) {
  188. episode.ContainsSpoilers = true
  189. }
  190. return gott.Tuple(args)
  191. }
  192. func getEpisodesExperiences(args ...interface{}) (interface{}, error) {
  193. result := args[1].(*Result)
  194. tvSerie := result.result.(*tmdb.TvSerie)
  195. if result.user.IsEmpty() {
  196. return gott.Tuple(args), nil
  197. }
  198. experiences, err := db.GetItemExperiences(result.user.Username, tvSerie.Id, datastructure.ItemTypeTvserie)
  199. for s, season := range tvSerie.Seasons {
  200. for e, episode := range season.Episodes {
  201. id := tvSerie.Id + "/" + episode.Episode_code
  202. tvSerie.Seasons[s].Episodes[e].Experiences = experiences[id]
  203. }
  204. }
  205. return gott.Tuple(args), err
  206. }
  207. func ShowTvSerie(id, etag, language, mimetype string, auth accounts.Authentication) (string, error) {
  208. auth.Necessary = false
  209. request := &RequestData{id: id, language: language, mimetype: mimetype, auth: auth}
  210. r, err := gott.
  211. NewResult(gott.Tuple{request, &Result{}}).
  212. Bind(parseLanguage).
  213. Bind(verifyToken).
  214. Bind(getTvSerie).
  215. Bind(getSeasons).
  216. Bind(getBasedOn).
  217. Bind(mergeCredits).
  218. Bind(isOnWantList).
  219. Bind(updateCache).
  220. Map(countAllEpisodes).
  221. Bind(calculateProgress).
  222. Bind(findNextEpisode).
  223. Bind(getEpisodesExperiences).
  224. Map(setSpoilers).
  225. Bind(createRenderer).
  226. Map(renderSerie).
  227. Finish()
  228. if err != nil {
  229. return "", err
  230. } else {
  231. return r.(gott.Tuple)[1].(*Result).page, nil
  232. }
  233. }