mirror of https://github.com/perkeep/perkeep.git
implemented go client.RemoveBlobs; no idea if it works yet
This commit is contained in:
parent
4de2eb4ebd
commit
16c672506b
|
@ -145,7 +145,7 @@ func doPass(sc, dc *client.Client, passNum int) (retErr os.Error) {
|
|||
bytesCopied += pr.Size
|
||||
}
|
||||
if *flagRemoveSource {
|
||||
if err = sc.Remove(sb.BlobRef); err != nil {
|
||||
if err = sc.RemoveBlob(sb.BlobRef); err != nil {
|
||||
errorCount++
|
||||
log.Printf("Failed to delete %s from source: %v", sb.BlobRef, err)
|
||||
}
|
||||
|
|
|
@ -17,15 +17,93 @@ limitations under the License.
|
|||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"camli/blobref"
|
||||
"fmt"
|
||||
// "http"
|
||||
"http"
|
||||
"io"
|
||||
"json"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Remove removes the blob. An error is returned if the blob was failed to
|
||||
// be removed. Removal of a non-existent blob isn't an error.
|
||||
func (c *Client) Remove(b *blobref.BlobRef) os.Error {
|
||||
url := fmt.Sprintf("%s/camli/post", c.server)
|
||||
return os.NewError(fmt.Sprintf("NOT IMPLEMENTED remove of %s to %s", b, url))
|
||||
type removeResponse struct {
|
||||
removed []string
|
||||
}
|
||||
|
||||
// Remove the list of blobs. An error is returned if the server failed to
|
||||
// remove a blob. Removing a non-existent blob isn't an error.
|
||||
func (c *Client) RemoveBlobs(blobs []*blobref.BlobRef) os.Error {
|
||||
url := fmt.Sprintf("%s/camli/remove", c.server)
|
||||
params := make(map[string][]string) // "blobN" -> BlobRefStr
|
||||
needsDelete := make(map[string]bool) // BlobRefStr -> true
|
||||
for n, b := range blobs {
|
||||
key := fmt.Sprintf("blob%v", n)
|
||||
params[key] = []string{b.String()}
|
||||
needsDelete[b.String()] = true
|
||||
}
|
||||
body := http.EncodeQuery(params)
|
||||
|
||||
req := new(http.Request)
|
||||
req.Method = "POST"
|
||||
req.ProtoMajor = 1
|
||||
req.ProtoMinor = 1
|
||||
req.Close = true
|
||||
req.Header = http.Header(make(map[string][]string))
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Add("Content-Length", strconv.Itoa(len(body)))
|
||||
if c.HasAuthCredentials() {
|
||||
req.Header.Add("Authorization", c.authHeader())
|
||||
}
|
||||
req.URL, _ = http.ParseURL(url)
|
||||
req.RawURL = url
|
||||
req.Body = nopCloser{strings.NewReader(body)}
|
||||
req.ContentLength = int64(len(body))
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
|
||||
if err != nil {
|
||||
return os.NewError(fmt.Sprintf("Got status code %d from blobserver for remove %s", resp.StatusCode, body))
|
||||
}
|
||||
|
||||
// The only valid HTTP responses are 200.
|
||||
if resp.StatusCode != 200 {
|
||||
return os.NewError(fmt.Sprintf("Invalid http response %d in remove response", resp.StatusCode))
|
||||
}
|
||||
|
||||
// TODO: LimitReader here for paranoia
|
||||
buf := new(bytes.Buffer)
|
||||
io.Copy(buf, resp.Body)
|
||||
resp.Body.Close()
|
||||
var remResp removeResponse
|
||||
if jerr := json.Unmarshal(buf.Bytes(), &remResp); jerr != nil {
|
||||
return jerr
|
||||
}
|
||||
for _, value := range remResp.removed {
|
||||
needsDelete[value] = false, false
|
||||
}
|
||||
|
||||
if len(needsDelete) > 0 {
|
||||
return os.NewError(fmt.Sprintf("Failed to remove blobs %s", strings.Join(stringKeys(needsDelete), ", ")))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove the single blob. An error is returned if the server failed to remove
|
||||
// the blob. Removing a non-existent blob isn't an error.
|
||||
func (c *Client) RemoveBlob(b *blobref.BlobRef) os.Error {
|
||||
return c.RemoveBlobs([]*blobref.BlobRef{b})
|
||||
}
|
||||
|
||||
func stringKeys(v interface{}) (s []string) {
|
||||
m, ok := v.(map[string]interface{})
|
||||
if !ok {
|
||||
panic("Wrong type")
|
||||
}
|
||||
s = make([]string, 0, len(m))
|
||||
for key, _ := range m {
|
||||
s = append(s, key)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue