collection.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. package movies
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. "sync"
  8. )
  9. type Collection struct {
  10. Movies []*Movie
  11. movieMap map[string]*Movie
  12. Lists []*List
  13. listMap map[string]*List
  14. Files *FileSource
  15. mutex sync.RWMutex
  16. hasChanged bool
  17. }
  18. func Import(filename string) (*Collection, error) {
  19. b, err := ioutil.ReadFile(filename)
  20. if err != nil {
  21. return nil, err
  22. }
  23. var c Collection
  24. if err := json.Unmarshal(b, &c); err != nil {
  25. return nil, err
  26. }
  27. c.movieMap = make(map[string]*Movie)
  28. for _, m := range c.Movies {
  29. m.FillFromOMDB()
  30. c.movieMap[m.IMDBID] = m
  31. }
  32. c.listMap = make(map[string]*List)
  33. for _, l := range c.Lists {
  34. c.listMap[l.ID] = l
  35. }
  36. return &c, nil
  37. }
  38. func (c *Collection) Export(filename string) error {
  39. c.mutex.RLock()
  40. defer c.mutex.RUnlock()
  41. b, err := json.Marshal(c)
  42. if err != nil {
  43. return err
  44. }
  45. err = ioutil.WriteFile(filename, b, 0644)
  46. if err != nil {
  47. return err
  48. }
  49. c.hasChanged = false
  50. return nil
  51. }
  52. func (c *Collection) Add(m *Movie) {
  53. c.mutex.Lock()
  54. defer c.mutex.Unlock()
  55. c.hasChanged = true
  56. for _, present := range c.Movies {
  57. if m.IMDBID == present.IMDBID {
  58. present.OMDB = m.OMDB
  59. present.FillFromOMDB()
  60. return
  61. }
  62. }
  63. c.Movies = append(c.Movies, m)
  64. c.movieMap[m.IMDBID] = m
  65. }
  66. func (c *Collection) HasChanged() bool {
  67. return c.hasChanged
  68. }
  69. func (c *Collection) Get(imdbID string) (*Movie, bool) {
  70. c.mutex.RLock()
  71. defer c.mutex.RUnlock()
  72. m, ok := c.movieMap[imdbID]
  73. return m, ok
  74. }
  75. func (c *Collection) Update(m *Movie) {
  76. c.mutex.Lock()
  77. defer c.mutex.Unlock()
  78. c.movieMap[m.IMDBID] = m
  79. found := false
  80. for i := range c.Movies {
  81. if c.Movies[i].IMDBID == m.IMDBID {
  82. c.Movies[i] = m
  83. found = true
  84. break
  85. }
  86. }
  87. if !found {
  88. c.Movies = append(c.Movies, m)
  89. }
  90. c.hasChanged = true
  91. }
  92. func (c *Collection) GetList(listID string) (*List, bool) {
  93. c.mutex.RLock()
  94. defer c.mutex.RUnlock()
  95. l, ok := c.listMap[listID]
  96. return l, ok
  97. }
  98. func (c *Collection) AddList(id, title string) error {
  99. c.mutex.Lock()
  100. defer c.mutex.Unlock()
  101. c.hasChanged = true
  102. for _, present := range c.Lists {
  103. if id == present.ID {
  104. return fmt.Errorf("there is already a list with id %q", id)
  105. }
  106. }
  107. l := &List{
  108. ID: id,
  109. Title: title,
  110. }
  111. c.Lists = append(c.Lists, l)
  112. c.listMap[l.ID] = l
  113. return nil
  114. }
  115. func (c *Collection) UpdateList(l *List) {
  116. c.mutex.Lock()
  117. defer c.mutex.Unlock()
  118. c.listMap[l.ID] = l
  119. found := false
  120. for i := range c.Lists {
  121. if c.Lists[i].ID == l.ID {
  122. c.Lists[i] = l
  123. found = true
  124. break
  125. }
  126. }
  127. if !found {
  128. c.Lists = append(c.Lists, l)
  129. }
  130. c.hasChanged = true
  131. }
  132. func (c *Collection) AllFiles() []string {
  133. if c.Files == nil {
  134. return nil
  135. }
  136. return c.Files.Files
  137. }
  138. func (c *Collection) SearchFiles(query string) []string {
  139. return c.Files.Search(query)
  140. }
  141. func (c *Collection) ScanFiles(root string) error {
  142. c.mutex.Lock()
  143. defer c.mutex.Unlock()
  144. if c.Files == nil {
  145. c.Files = &FileSource{}
  146. }
  147. if err := c.Files.Scan(os.Getenv("FILE_ROOT")); err != nil {
  148. return err
  149. }
  150. c.hasChanged = true
  151. return nil
  152. }