Advertisement
Guest User

Untitled

a guest
Mar 24th, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.98 KB | None | 0 0
  1. package download
  2.  
  3. import (
  4. "archive/zip"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "os"
  9. "time"
  10.  
  11. "github.com/nu7hatch/gouuid"
  12. "upper.io/db.v3"
  13.  
  14. "go.evanpurkhiser.com/tunedex/data"
  15. )
  16.  
  17. // An ArchiveJob includes details about an archiving job.
  18. type ArchiveJob struct {
  19. Name string
  20. Tracks []data.Track
  21.  
  22. // Completed is a channel that will be written into when the job has
  23. // successfully finished archving all files and is ready to be requested.
  24. Completed <-chan bool
  25.  
  26. // Error is a channel that will be written into if there are any problems
  27. // while creating the archive.
  28. Error <-chan error
  29.  
  30. // Progress is a channel that will be written into when a file has finished
  31. // being added into the in progress archive.
  32. Progress <-chan *Track
  33.  
  34. // Cancel may be written into to stop the archiving job.
  35. Cancel chan<- bool
  36.  
  37. // archiveFile is the temporary file that the archive is written to.
  38. archiveFile *os.File
  39. }
  40.  
  41. // Archiver is a service object which when given a list of file hashes, will
  42. // lookup the tracks and archive them into a ZIP file. This zip file may then
  43. // be requested after all tracks have been fully archived.
  44. //
  45. // If a file is not requested after a given interval, it will be removed and
  46. // can no longer be requested.
  47. type Archiver struct {
  48. // AllowedRequestInterval specifies how long to store the archive between
  49. // when it has been created and when it is requested.
  50. AllowedRequestInterval time.Duration
  51.  
  52. // TrackCollection is the database upper.io db.Collection implementation
  53. // that may be queried on.
  54. TrackCollection db.Collection
  55.  
  56. // inProgress tracks current in progress of in flight archive jobs.
  57. inProgress map[string]*ArchiveJob
  58. }
  59.  
  60. // Create constructs an ArchiveJob and being the background archiving process.
  61. func (a *Archiver) Create(fileHashs []string) (*ArchiveJob, error) {
  62. tracks := []data.Track{}
  63.  
  64. err := a.TrackCollection.Find("file_hash IN ?", fileHashs).All(&tracks)
  65. if err != nil {
  66. return nil, err
  67. }
  68.  
  69. trackCount := len(tracks)
  70.  
  71. if trackCount == 0 {
  72. return nil, fmt.Errorf("Could not find specified tracks to archive")
  73. }
  74.  
  75. name, err := uuid.NewV4()
  76. if err != nil {
  77. return nil, err
  78. }
  79.  
  80. file, err := ioutil.TempFile("", name)
  81. if err != nil {
  82. return nil, err
  83. }
  84.  
  85. job := &ArchiveJob{
  86. Name: name,
  87. Tracks: tracks,
  88. Completed: make(chan bool, 1),
  89. Cancel: make(chan bool, 1),
  90. Error: make(chan error, 1),
  91. Progress: make(chan string, trackCount),
  92. archiveFile: file,
  93. }
  94.  
  95. a.inProgress[job.Name] = job
  96.  
  97. go a.archive(job)
  98.  
  99. return job, nil
  100. }
  101.  
  102. func (a *Archiver) archive(job *ArchiveJob) {
  103. zipFile := zip.NewWriter(job.archiveFile)
  104.  
  105. // Copy the file list into the zip
  106. for _, track := range job.Tracks {
  107. zipPart, err := zipFile.Create(track.FilePath)
  108. if err != nil {
  109. job.Error <- err
  110. return
  111. }
  112.  
  113. file, err := os.Open(track.FilePath)
  114. if err != nil {
  115. job.Error <- err
  116. return
  117. }
  118.  
  119. io.Copy(zipPart, file)
  120. file.Close()
  121.  
  122. job.Progress <- track
  123. }
  124.  
  125. job.Completed <- true
  126.  
  127. }
  128.  
  129. func (a *Archiver) RequestArchive(job *ArchiveJob) *os.File {
  130.  
  131. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement