func (c Controller) chunkExists(fid string, hash string) bool { chunkCount, err := models.Chunks(c.DB, qm.Where("file_id=$1 and hash=$2", fid, hash)).Count() if err != nil { c.Error("Failed to look up chunk count", err) return false } return chunkCount > 0 }
func (c Controller) checkFinished(f *models.File) { chunks, err := models.Chunks(c.DB, qm.Where("file_id=$1", f.ID)).All() if err != nil { c.Error("Failed to lookup chunks", "Error", err) return } completedChunks := len(chunks) requiredChunks := f.NumChunks fmt.Println("Completed Chunks:", completedChunks) fmt.Println("Required:", requiredChunks) if completedChunks != requiredChunks { c.Info( "File not finished", "Received", completedChunks, "Total", requiredChunks, ) return } go func() { c.wsFileIDsLock.RLock() wsID := c.wsFileIDs[f.ID] c.wsFileIDsLock.RUnlock() err = processors.CompleteFile(c.Dependencies, f) if err != nil { c.Error("Failed to finish file", "error", err, "name", f.Name, "id", f.ID) return } if len(wsID) > 0 { c.Info("Sending WS msg", "ws", wsID) c.WS.WriteClient(wsID, "file:completed", f) } else { c.Info("No WS ID") } c.Info("Finished File", "name", f.Name, "id", f.ID) }() }
// BuildFile builds a file from chunks. func BuildFile(deps dependencies.Dependencies, f *models.File) (io.ReadSeeker, error) { chunks, err := models.Chunks( deps.DB, qm.Where("file_id=$1", f.ID), qm.OrderBy("position asc"), ).All() var hashes []string for _, c := range chunks { hashes = append(hashes, c.Hash) } if ok, err := chunksExist(hashes); !ok { deps.Error("Missing chunks!", "id", f.ID, "name", f.Name) return nil, err } if err != nil { fmt.Println("Failed to find chunks for file:", f.ID) return nil, err } fs := deps.Fs fullFilePath := filepath.Join("files", f.Hash) fullFile, err := fs.Create(fullFilePath) if err != nil { fmt.Println("Failed because", err) return nil, err } defer fullFile.Close() fullFileBuffer := &bytes.Buffer{} mw := io.MultiWriter(fullFile, fullFileBuffer) for _, c := range chunks { fmt.Println("pos:", c.Position) path := filepath.Join("files", "chunks", c.Hash) chunkData, err := fs.Open(path) if err != nil { fmt.Println("chunk Failed because", err) return nil, err } _, err = io.Copy(mw, chunkData) chunkData.Close() if err != nil { fmt.Println("Failed to copy chunk to full file") } } fmt.Println("Finished building file") // for _, c := range chunks { // path := filepath.Join("files", "chunks", c.Hash) // if err != nil { // fmt.Println("Failed to delete chunk entry:", c.ID) // } // fs.Remove(path) // } bs := bytes.NewReader(fullFileBuffer.Bytes()) return bs, nil }