mirror of
https://github.com/rclone/rclone.git
synced 2026-01-19 17:03:57 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfdb48c864 | ||
|
|
14567952b3 | ||
|
|
2b052671e2 |
@@ -261,9 +261,11 @@ Bugs
|
|||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
---------
|
---------
|
||||||
|
* v1.07 - 2014-12-23
|
||||||
|
* google cloud storage: fix memory leak
|
||||||
* v1.06 - 2014-12-12
|
* v1.06 - 2014-12-12
|
||||||
* Fix "Couldn't find home directory" on OSX
|
* Fix "Couldn't find home directory" on OSX
|
||||||
* Add tenant parameter for swift
|
* swift: Add tenant parameter
|
||||||
* Use new location of Google API packages
|
* Use new location of Google API packages
|
||||||
* v1.05 - 2014-08-09
|
* v1.05 - 2014-08-09
|
||||||
* Improved tests and consequently lots of minor fixes
|
* Improved tests and consequently lots of minor fixes
|
||||||
|
|||||||
@@ -2,34 +2,34 @@
|
|||||||
title: "Rclone downloads"
|
title: "Rclone downloads"
|
||||||
description: "Download rclone binaries for your OS."
|
description: "Download rclone binaries for your OS."
|
||||||
type: page
|
type: page
|
||||||
date: "2014-12-12"
|
date: "2014-12-23"
|
||||||
---
|
---
|
||||||
|
|
||||||
Rclone Download v1.06
|
Rclone Download v1.07
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
* Windows
|
* Windows
|
||||||
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.06-windows-386.zip)
|
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.07-windows-386.zip)
|
||||||
* [AMD64 - 64 Bit](http://downloads.rclone.org/rclone-v1.06-windows-amd64.zip)
|
* [AMD64 - 64 Bit](http://downloads.rclone.org/rclone-v1.07-windows-amd64.zip)
|
||||||
* OSX
|
* OSX
|
||||||
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.06-osx-386.zip)
|
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.07-osx-386.zip)
|
||||||
* [AMD64 - 64 Bit](http://downloads.rclone.org/rclone-v1.06-osx-amd64.zip)
|
* [AMD64 - 64 Bit](http://downloads.rclone.org/rclone-v1.07-osx-amd64.zip)
|
||||||
* Linux
|
* Linux
|
||||||
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.06-linux-386.zip)
|
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.07-linux-386.zip)
|
||||||
* [AMD64 - 64 Bit](http://downloads.rclone.org/rclone-v1.06-linux-amd64.zip)
|
* [AMD64 - 64 Bit](http://downloads.rclone.org/rclone-v1.07-linux-amd64.zip)
|
||||||
* [ARM - 32 Bit](http://downloads.rclone.org/rclone-v1.06-linux-arm.zip)
|
* [ARM - 32 Bit](http://downloads.rclone.org/rclone-v1.07-linux-arm.zip)
|
||||||
* FreeBSD
|
* FreeBSD
|
||||||
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.06-freebsd-386.zip)
|
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.07-freebsd-386.zip)
|
||||||
* [AMD64 - 64 Bit](http://downloads.rclone.org/rclone-v1.06-freebsd-amd64.zip)
|
* [AMD64 - 64 Bit](http://downloads.rclone.org/rclone-v1.07-freebsd-amd64.zip)
|
||||||
* [ARM - 32 Bit](http://downloads.rclone.org/rclone-v1.06-freebsd-arm.zip)
|
* [ARM - 32 Bit](http://downloads.rclone.org/rclone-v1.07-freebsd-arm.zip)
|
||||||
* NetBSD
|
* NetBSD
|
||||||
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.06-netbsd-386.zip)
|
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.07-netbsd-386.zip)
|
||||||
* [AMD64 - 64 Bit](http://downloads.rclone.org/rclone-v1.06-netbsd-amd64.zip)
|
* [AMD64 - 64 Bit](http://downloads.rclone.org/rclone-v1.07-netbsd-amd64.zip)
|
||||||
* [ARM - 32 Bit](http://downloads.rclone.org/rclone-v1.06-netbsd-arm.zip)
|
* [ARM - 32 Bit](http://downloads.rclone.org/rclone-v1.07-netbsd-arm.zip)
|
||||||
* OpenBSD
|
* OpenBSD
|
||||||
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.06-openbsd-386.zip)
|
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.07-openbsd-386.zip)
|
||||||
* [AMD64 - 64 Bit](http://downloads.rclone.org/rclone-v1.06-openbsd-amd64.zip)
|
* [AMD64 - 64 Bit](http://downloads.rclone.org/rclone-v1.07-openbsd-amd64.zip)
|
||||||
* Plan 9
|
* Plan 9
|
||||||
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.06-plan9-386.zip)
|
* [386 - 32 Bit](http://downloads.rclone.org/rclone-v1.07-plan9-386.zip)
|
||||||
|
|
||||||
Older downloads can be found [here](http://downloads.rclone.org/)
|
Older downloads can be found [here](http://downloads.rclone.org/)
|
||||||
|
|||||||
@@ -52,12 +52,15 @@ Choose a number from below, or type in your own value
|
|||||||
* Memset Memstore UK v2
|
* Memset Memstore UK v2
|
||||||
5) https://auth.storage.memset.com/v2.0
|
5) https://auth.storage.memset.com/v2.0
|
||||||
auth> 1
|
auth> 1
|
||||||
|
Tenant name - optional
|
||||||
|
tenant>
|
||||||
Remote config
|
Remote config
|
||||||
--------------------
|
--------------------
|
||||||
[remote]
|
[remote]
|
||||||
user = user_name
|
user = user_name
|
||||||
key = password_or_api_key
|
key = password_or_api_key
|
||||||
auth = https://auth.api.rackspacecloud.com/v1.0
|
auth = https://auth.api.rackspacecloud.com/v1.0
|
||||||
|
tenant =
|
||||||
--------------------
|
--------------------
|
||||||
y) Yes this is OK
|
y) Yes this is OK
|
||||||
e) Edit this remote
|
e) Edit this remote
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"mime"
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -603,30 +602,6 @@ func (f *FsDrive) ListDir() fs.DirChan {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// seekWrapper wraps an io.Reader with a basic Seek for
|
|
||||||
// code.google.com/p/google-api-go-client/googleapi
|
|
||||||
// to detect the length (see getReaderSize function)
|
|
||||||
type seekWrapper struct {
|
|
||||||
in io.Reader
|
|
||||||
size int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read bytes from the object - see io.Reader
|
|
||||||
func (file *seekWrapper) Read(p []byte) (n int, err error) {
|
|
||||||
return file.in.Read(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seek - minimal implementation for Google Drive's length detection
|
|
||||||
func (file *seekWrapper) Seek(offset int64, whence int) (int64, error) {
|
|
||||||
switch whence {
|
|
||||||
case os.SEEK_CUR:
|
|
||||||
return 0, nil
|
|
||||||
case os.SEEK_END:
|
|
||||||
return file.size, nil
|
|
||||||
}
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put the object
|
// Put the object
|
||||||
//
|
//
|
||||||
// This assumes that the object doesn't not already exists - if you
|
// This assumes that the object doesn't not already exists - if you
|
||||||
@@ -663,7 +638,7 @@ func (f *FsDrive) Put(in io.Reader, remote string, modTime time.Time, size int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make the API request to upload metadata and file data.
|
// Make the API request to upload metadata and file data.
|
||||||
in = &seekWrapper{in: in, size: size}
|
in = &fs.SeekWrapper{In: in, Size: size}
|
||||||
info, err = f.svc.Files.Insert(info).Media(in).Do()
|
info, err = f.svc.Files.Insert(info).Media(in).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return o, fmt.Errorf("Upload failed: %s", err)
|
return o, fmt.Errorf("Upload failed: %s", err)
|
||||||
@@ -872,7 +847,7 @@ func (o *FsObjectDrive) Update(in io.Reader, modTime time.Time, size int64) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make the API request to upload metadata and file data.
|
// Make the API request to upload metadata and file data.
|
||||||
in = &seekWrapper{in: in, size: size}
|
in = &fs.SeekWrapper{In: in, Size: size}
|
||||||
info, err := o.drive.svc.Files.Update(info.Id, info).SetModifiedDate(true).Media(in).Do()
|
info, err := o.drive.svc.Files.Update(info.Id, info).SetModifiedDate(true).Media(in).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Update failed: %s", err)
|
return fmt.Errorf("Update failed: %s", err)
|
||||||
|
|||||||
39
fs/seekwrapper.go
Normal file
39
fs/seekwrapper.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package fs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SeekWrapper wraps an io.Reader with a basic Seek method which
|
||||||
|
// returns the Size attribute.
|
||||||
|
//
|
||||||
|
// This is used for google.golang.org/api/googleapi/googleapi.go
|
||||||
|
// to detect the length (see getReaderSize function)
|
||||||
|
//
|
||||||
|
// Without this the getReaderSize function reads the entire file into
|
||||||
|
// memory to find its length.
|
||||||
|
type SeekWrapper struct {
|
||||||
|
In io.Reader
|
||||||
|
Size int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read bytes from the object - see io.Reader
|
||||||
|
func (file *SeekWrapper) Read(p []byte) (n int, err error) {
|
||||||
|
return file.In.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seek - minimal implementation for Google API length detection
|
||||||
|
func (file *SeekWrapper) Seek(offset int64, whence int) (int64, error) {
|
||||||
|
switch whence {
|
||||||
|
case os.SEEK_CUR:
|
||||||
|
return 0, nil
|
||||||
|
case os.SEEK_END:
|
||||||
|
return file.Size, nil
|
||||||
|
}
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interfaces that SeekWrapper implements
|
||||||
|
var _ io.Reader = (*SeekWrapper)(nil)
|
||||||
|
var _ io.Seeker = (*SeekWrapper)(nil)
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
package fs
|
package fs
|
||||||
|
|
||||||
const Version = "v1.06"
|
const Version = "v1.07"
|
||||||
|
|||||||
@@ -359,8 +359,9 @@ func (f *FsStorage) ListDir() fs.DirChan {
|
|||||||
// The new object may have been created if an error is returned
|
// The new object may have been created if an error is returned
|
||||||
func (f *FsStorage) Put(in io.Reader, remote string, modTime time.Time, size int64) (fs.Object, error) {
|
func (f *FsStorage) Put(in io.Reader, remote string, modTime time.Time, size int64) (fs.Object, error) {
|
||||||
// Temporary FsObject under construction
|
// Temporary FsObject under construction
|
||||||
fs := &FsObjectStorage{storage: f, remote: remote}
|
o := &FsObjectStorage{storage: f, remote: remote}
|
||||||
return fs, fs.Update(in, modTime, size)
|
in = &fs.SeekWrapper{In: in, Size: size}
|
||||||
|
return o, o.Update(in, modTime, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mkdir creates the bucket if it doesn't exist
|
// Mkdir creates the bucket if it doesn't exist
|
||||||
@@ -562,6 +563,7 @@ func (o *FsObjectStorage) Update(in io.Reader, modTime time.Time, size int64) er
|
|||||||
Updated: modTime.Format(timeFormatOut), // Doesn't get set
|
Updated: modTime.Format(timeFormatOut), // Doesn't get set
|
||||||
Metadata: metadataFromModTime(modTime),
|
Metadata: metadataFromModTime(modTime),
|
||||||
}
|
}
|
||||||
|
in = &fs.SeekWrapper{In: in, Size: size}
|
||||||
newObject, err := o.storage.svc.Objects.Insert(o.storage.bucket, &object).Media(in).Name(object.Name).PredefinedAcl(o.storage.objectAcl).Do()
|
newObject, err := o.storage.svc.Objects.Insert(o.storage.bucket, &object).Media(in).Name(object.Name).PredefinedAcl(o.storage.objectAcl).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
Reference in New Issue
Block a user