Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package download
- import (
- "archive/zip"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "time"
- "github.com/nu7hatch/gouuid"
- "upper.io/db.v3"
- "go.evanpurkhiser.com/tunedex/data"
- )
- // An ArchiveJob includes details about an archiving job.
- type ArchiveJob struct {
- Name string
- Tracks []data.Track
- // Completed is a channel that will be written into when the job has
- // successfully finished archving all files and is ready to be requested.
- Completed <-chan bool
- // Error is a channel that will be written into if there are any problems
- // while creating the archive.
- Error <-chan error
- // Progress is a channel that will be written into when a file has finished
- // being added into the in progress archive.
- Progress <-chan *Track
- // Cancel may be written into to stop the archiving job.
- Cancel chan<- bool
- // archiveFile is the temporary file that the archive is written to.
- archiveFile *os.File
- }
- // Archiver is a service object which when given a list of file hashes, will
- // lookup the tracks and archive them into a ZIP file. This zip file may then
- // be requested after all tracks have been fully archived.
- //
- // If a file is not requested after a given interval, it will be removed and
- // can no longer be requested.
- type Archiver struct {
- // AllowedRequestInterval specifies how long to store the archive between
- // when it has been created and when it is requested.
- AllowedRequestInterval time.Duration
- // TrackCollection is the database upper.io db.Collection implementation
- // that may be queried on.
- TrackCollection db.Collection
- // inProgress tracks current in progress of in flight archive jobs.
- inProgress map[string]*ArchiveJob
- }
- // Create constructs an ArchiveJob and being the background archiving process.
- func (a *Archiver) Create(fileHashs []string) (*ArchiveJob, error) {
- tracks := []data.Track{}
- err := a.TrackCollection.Find("file_hash IN ?", fileHashs).All(&tracks)
- if err != nil {
- return nil, err
- }
- trackCount := len(tracks)
- if trackCount == 0 {
- return nil, fmt.Errorf("Could not find specified tracks to archive")
- }
- name, err := uuid.NewV4()
- if err != nil {
- return nil, err
- }
- file, err := ioutil.TempFile("", name)
- if err != nil {
- return nil, err
- }
- job := &ArchiveJob{
- Name: name,
- Tracks: tracks,
- Completed: make(chan bool, 1),
- Cancel: make(chan bool, 1),
- Error: make(chan error, 1),
- Progress: make(chan string, trackCount),
- archiveFile: file,
- }
- a.inProgress[job.Name] = job
- go a.archive(job)
- return job, nil
- }
- func (a *Archiver) archive(job *ArchiveJob) {
- zipFile := zip.NewWriter(job.archiveFile)
- // Copy the file list into the zip
- for _, track := range job.Tracks {
- zipPart, err := zipFile.Create(track.FilePath)
- if err != nil {
- job.Error <- err
- return
- }
- file, err := os.Open(track.FilePath)
- if err != nil {
- job.Error <- err
- return
- }
- io.Copy(zipPart, file)
- file.Close()
- job.Progress <- track
- }
- job.Completed <- true
- }
- func (a *Archiver) RequestArchive(job *ArchiveJob) *os.File {
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement