2014-07-28 19:26:10 +00:00
|
|
|
package pointer
|
2013-10-04 15:22:32 +00:00
|
|
|
|
|
|
|
import (
|
2014-07-28 23:41:16 +00:00
|
|
|
"errors"
|
2014-06-03 15:08:58 +00:00
|
|
|
"github.com/github/git-media/gitmedia"
|
|
|
|
"github.com/github/git-media/gitmediaclient"
|
2013-10-04 15:22:32 +00:00
|
|
|
"io"
|
2013-11-05 15:26:58 +00:00
|
|
|
"os"
|
2013-10-04 15:22:32 +00:00
|
|
|
)
|
|
|
|
|
2014-08-07 14:53:13 +00:00
|
|
|
func Smudge(writer io.Writer, ptr *Pointer, cb gitmedia.CopyCallback) error {
|
2014-08-06 21:40:24 +00:00
|
|
|
mediafile, err := gitmedia.LocalMediaPath(ptr.Oid)
|
2014-06-05 19:05:02 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2013-10-04 15:22:32 +00:00
|
|
|
|
2014-07-28 23:11:39 +00:00
|
|
|
if stat, statErr := os.Stat(mediafile); statErr != nil || stat == nil {
|
2014-08-07 14:53:13 +00:00
|
|
|
err = downloadFile(writer, ptr, mediafile, cb)
|
2013-11-06 16:41:57 +00:00
|
|
|
} else {
|
2014-08-07 14:53:13 +00:00
|
|
|
err = readLocalFile(writer, ptr, mediafile, cb)
|
2013-11-05 15:26:58 +00:00
|
|
|
}
|
|
|
|
|
2014-07-28 19:35:25 +00:00
|
|
|
if err != nil {
|
2014-08-06 21:40:24 +00:00
|
|
|
return &SmudgeError{ptr.Oid, mediafile, err.Error()}
|
2014-07-28 19:35:25 +00:00
|
|
|
} else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-07 14:53:13 +00:00
|
|
|
func downloadFile(writer io.Writer, ptr *Pointer, mediafile string, cb gitmedia.CopyCallback) error {
|
2014-08-07 16:25:26 +00:00
|
|
|
reader, size, err := gitmediaclient.Get(mediafile)
|
2014-07-28 19:35:25 +00:00
|
|
|
if err != nil {
|
2014-07-28 23:41:16 +00:00
|
|
|
return errors.New("client: " + err.Error())
|
2014-07-28 19:35:25 +00:00
|
|
|
}
|
|
|
|
defer reader.Close()
|
|
|
|
|
2014-08-07 16:25:26 +00:00
|
|
|
if ptr.Size == 0 {
|
|
|
|
ptr.Size = size
|
|
|
|
}
|
|
|
|
|
2014-08-06 21:40:24 +00:00
|
|
|
mediaWriter, err := newFile(mediafile, ptr.Oid)
|
2014-07-28 19:35:25 +00:00
|
|
|
if err != nil {
|
2014-07-28 23:41:16 +00:00
|
|
|
return errors.New("open: " + err.Error())
|
2014-07-28 19:35:25 +00:00
|
|
|
}
|
|
|
|
|
2014-07-28 23:57:42 +00:00
|
|
|
_, copyErr := io.Copy(mediaWriter, reader)
|
2014-07-28 20:31:30 +00:00
|
|
|
closeErr := mediaWriter.Close()
|
|
|
|
|
|
|
|
if copyErr != nil {
|
2014-07-28 23:41:16 +00:00
|
|
|
return errors.New("write: " + copyErr.Error())
|
2014-07-28 20:31:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if closeErr != nil {
|
2014-07-28 23:41:16 +00:00
|
|
|
return errors.New("close: " + closeErr.Error())
|
2014-07-28 20:31:30 +00:00
|
|
|
}
|
|
|
|
|
2014-07-28 23:57:42 +00:00
|
|
|
file, err := os.Open(mediaWriter.Path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2014-08-07 14:53:13 +00:00
|
|
|
_, err = gitmedia.CopyWithCallback(writer, file, ptr.Size, cb)
|
2014-07-28 23:57:42 +00:00
|
|
|
return err
|
2014-07-28 19:35:25 +00:00
|
|
|
}
|
|
|
|
|
2014-08-07 14:53:13 +00:00
|
|
|
func readLocalFile(writer io.Writer, ptr *Pointer, mediafile string, cb gitmedia.CopyCallback) error {
|
2014-07-28 19:35:25 +00:00
|
|
|
reader, err := os.Open(mediafile)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer reader.Close()
|
|
|
|
|
2014-08-07 16:25:26 +00:00
|
|
|
if ptr.Size == 0 {
|
|
|
|
if stat, _ := os.Stat(mediafile); stat != nil {
|
|
|
|
ptr.Size = stat.Size()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-07 14:53:13 +00:00
|
|
|
_, err = gitmedia.CopyWithCallback(writer, reader, ptr.Size, cb)
|
2013-11-06 16:41:57 +00:00
|
|
|
return err
|
2013-10-04 15:22:32 +00:00
|
|
|
}
|
2013-10-22 18:09:06 +00:00
|
|
|
|
|
|
|
type SmudgeError struct {
|
2014-07-28 19:37:57 +00:00
|
|
|
Oid string
|
2013-10-22 18:09:06 +00:00
|
|
|
Filename string
|
|
|
|
ErrorMessage string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *SmudgeError) Error() string {
|
|
|
|
return e.ErrorMessage
|
|
|
|
}
|