search.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package tmdb
  2. import (
  3. "notabug.org/apiote/amuse/config"
  4. "notabug.org/apiote/amuse/network"
  5. "encoding/json"
  6. "net/http"
  7. "net/url"
  8. "time"
  9. "notabug.org/apiote/gott"
  10. )
  11. type SearchResults struct {
  12. Query string
  13. Page int
  14. Total_pages int `json:"total_pages"`
  15. Results []struct {
  16. Id int
  17. Media_type string `json:"media_type"`
  18. Name string
  19. Title string
  20. First_air_date_str string `json:"first_air_date"`
  21. Release_date_str string `json:"release_date"`
  22. Poster_path string `json:"poster_path"`
  23. Profile_path string `json:"profile_path"`
  24. Release_date time.Time
  25. }
  26. }
  27. func (r SearchResults) NextPage() int {
  28. return r.Page + 1
  29. }
  30. func (r SearchResults) PrevPage() int {
  31. return r.Page - 1
  32. }
  33. type Query struct {
  34. query string
  35. language string
  36. page string
  37. }
  38. func createSearchQuery(args ...interface{}) (interface{}, error) {
  39. query := args[0].(*Query)
  40. result := args[1].(*network.Result)
  41. client := &http.Client{}
  42. url :="https://api.themoviedb.org/3/search/multi?api_key="+config.TmdbApiKey+"&language="+query.language+"&query="+url.QueryEscape(query.query)+"&page="+query.page+"&include_adult=false"
  43. request, err := http.NewRequest("GET", url, nil)
  44. result.Client = client
  45. result.Request = request
  46. return gott.Tuple(args), err
  47. }
  48. func unmarshalSearchResults(args ...interface{}) (interface{}, error) {
  49. query := args[0].(*Query)
  50. result := args[1].(*network.Result)
  51. results := &SearchResults{}
  52. err := json.Unmarshal(result.Body, results)
  53. results.Query = query.query
  54. for i, result := range results.Results {
  55. if result.Name == "" {
  56. result.Name = result.Title
  57. }
  58. if result.Poster_path == "" {
  59. result.Poster_path = result.Profile_path
  60. }
  61. results.Results[i] = result
  62. }
  63. result.Result = results
  64. return gott.Tuple(args), err
  65. }
  66. func convertSearchResultsDates(args ...interface{}) (interface{}, error) {
  67. results := args[1].(*network.Result).Result.(*SearchResults)
  68. for i, result := range results.Results {
  69. if result.Release_date_str != "" {
  70. date, err := time.Parse("2006-01-02", result.Release_date_str)
  71. if err != nil {
  72. return gott.Tuple(args), err
  73. }
  74. result.Release_date = date
  75. results.Results[i] = result
  76. }
  77. if result.First_air_date_str != "" {
  78. date, err := time.Parse("2006-01-02", result.First_air_date_str)
  79. if err != nil {
  80. return gott.Tuple(args), err
  81. }
  82. result.Release_date = date
  83. results.Results[i] = result
  84. }
  85. }
  86. return gott.Tuple(args), nil
  87. }
  88. func Search(query, language, page string) (*SearchResults, error) {
  89. results, err := gott.
  90. NewResult(gott.Tuple{&Query{query, language, page}, &network.Result{}}).
  91. // todo parse query -> search (when no nigmas) |-> discover (when nigmas)
  92. Bind(createSearchQuery).
  93. Bind(network.DoRequest).
  94. Bind(network.HandleRequestError).
  95. Bind(network.ReadResponse).
  96. Bind(unmarshalSearchResults).
  97. Bind(convertSearchResultsDates).
  98. Finish()
  99. if err != nil {
  100. return &SearchResults{}, err
  101. } else {
  102. return results.(gott.Tuple)[1].(*network.Result).Result.(*SearchResults), nil
  103. }
  104. }