@@ -2,6 +2,7 @@ package internxt
22
33import (
44 "context"
5+ "errors"
56 "fmt"
67 "io"
78 "path"
@@ -11,6 +12,7 @@ import (
1112 "github.com/StarHack/go-internxt-drive/auth"
1213 "github.com/StarHack/go-internxt-drive/buckets"
1314 config "github.com/StarHack/go-internxt-drive/config"
15+ "github.com/StarHack/go-internxt-drive/files"
1416 "github.com/StarHack/go-internxt-drive/folders"
1517 "github.com/rclone/rclone/fs"
1618 "github.com/rclone/rclone/fs/config/configmap"
@@ -20,13 +22,6 @@ import (
2022 "github.com/rclone/rclone/lib/dircache"
2123)
2224
23- // Options holds configuration options for this interface
24- type Options struct {
25- Endpoint string `flag:"endpoint" help:"API endpoint"`
26- Email string `flag:"email" help:"Internxt account email"`
27- Password string `flag:"password" help:"Internxt account password"`
28- }
29-
3025// Register with Fs
3126func init () {
3227 fs .Register (& fs.RegInfo {
@@ -49,6 +44,13 @@ func init() {
4944 }})
5045}
5146
47+ // Options holds configuration options for this interface
48+ type Options struct {
49+ Endpoint string `flag:"endpoint" help:"API endpoint"`
50+ Email string `flag:"email" help:"Internxt account email"`
51+ Password string `flag:"password" help:"Internxt account password"`
52+ }
53+
5254// Fs represents an Internxt remote
5355type Fs struct {
5456 name string
@@ -62,6 +64,38 @@ type Fs struct {
6264 rootFile * folders.File
6365}
6466
67+ // Object holds the data for a remote file object
68+ type Object struct {
69+ f * Fs
70+ remote string
71+ id string
72+ uuid string
73+ size int64
74+ modTime time.Time
75+ }
76+
77+ // Name of the remote (as passed into NewFs)
78+ func (f * Fs ) Name () string { return f .name }
79+
80+ // Root of the remote (as passed into NewFs)
81+ func (f * Fs ) Root () string { return f .root }
82+
83+ // String converts this Fs to a string
84+ func (f * Fs ) String () string { return f .name + ":" + f .root }
85+
86+ // Features returns the optional features of this Fs
87+ func (f * Fs ) Features () * fs.Features {
88+ return & fs.Features {ReadMetadata : false , CanHaveEmptyDirectories : true }
89+ }
90+
91+ // Hashes returns type of hashes supported by Internxt
92+ func (f * Fs ) Hashes () hash.Set {
93+ return hash .NewHashSet ()
94+ }
95+
96+ // Precision returns the precision of mtime that the server responds
97+ func (f * Fs ) Precision () time.Duration { return time .Microsecond }
98+
6599// NewFs constructs an Fs from the path
66100func NewFs (ctx context.Context , name , root string , m configmap.Mapper ) (fs.Fs , error ) {
67101 opt := new (Options )
@@ -128,23 +162,6 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
128162 return f , nil
129163}
130164
131- // Name of the remote (as passed into NewFs)
132- func (f * Fs ) Name () string { return f .name }
133-
134- // Root of the remote (as passed into NewFs)
135- func (f * Fs ) Root () string { return f .root }
136-
137- // String converts this Fs to a string
138- func (f * Fs ) String () string { return f .name + ":" + f .root }
139-
140- // Precision returns the precision of mtime that the server responds
141- func (f * Fs ) Precision () time.Duration { return time .Microsecond }
142-
143- // Features returns the optional features of this Fs
144- func (f * Fs ) Features () * fs.Features {
145- return & fs.Features {ReadMetadata : false , CanHaveEmptyDirectories : true }
146- }
147-
148165// Mkdir creates a new directory
149166func (f * Fs ) Mkdir (ctx context.Context , dir string ) error {
150167 _ , err := f .dirCache .FindDir (ctx , dir , true )
@@ -296,11 +313,6 @@ func (f *Fs) Copy(ctx context.Context, src, dst fs.Object) error {
296313// DirCacheFlush flushes the dir cache (not implemented)
297314func (f * Fs ) DirCacheFlush (ctx context.Context ) {}
298315
299- // Hashes returns type of hashes supported by Internxt
300- func (f * Fs ) Hashes () hash.Set {
301- return hash .NewHashSet ()
302- }
303-
304316// NewObject creates a new object
305317func (f * Fs ) NewObject (ctx context.Context , remote string ) (fs.Object , error ) {
306318 if f .rootIsFile {
@@ -330,3 +342,101 @@ func (f *Fs) NewObject(ctx context.Context, remote string) (fs.Object, error) {
330342 }
331343 return nil , fs .ErrorObjectNotFound
332344}
345+
346+ // newObjectWithFile returns a new object by file info
347+ func newObjectWithFile (f * Fs , remote string , file * folders.File ) fs.Object {
348+ size , _ := file .Size .Int64 ()
349+ return & Object {
350+ f : f ,
351+ remote : remote ,
352+ id : file .FileID ,
353+ uuid : file .UUID ,
354+ size : size ,
355+ modTime : file .ModificationTime ,
356+ }
357+ }
358+
359+ // newObjectWithMetaFile returns a new object by meta file info
360+ func newObjectWithMetaFile (f * Fs , remote string , file * buckets.CreateMetaResp ) fs.Object {
361+ size , _ := file .Size .Int64 ()
362+ return & Object {
363+ f : f ,
364+ remote : remote ,
365+ uuid : file .UUID ,
366+ size : size ,
367+ modTime : time .Now (),
368+ }
369+ }
370+
371+ // Fs returns the parent Fs
372+ func (o * Object ) Fs () fs.Info {
373+ return o .f
374+ }
375+
376+ // String returns the remote path
377+ func (o * Object ) String () string {
378+ return o .remote
379+ }
380+
381+ // Remote returns the remote path
382+ func (o * Object ) Remote () string {
383+ return o .remote
384+ }
385+
386+ // Size is the file length
387+ func (o * Object ) Size () int64 {
388+ return o .size
389+ }
390+
391+ // ModTime is the last modified time (read-only)
392+ func (o * Object ) ModTime (ctx context.Context ) time.Time {
393+ return o .modTime
394+ }
395+
396+ // Hash returns the hash value (not implemented)
397+ func (o * Object ) Hash (ctx context.Context , t hash.Type ) (string , error ) {
398+ return "" , errors .New ("not implemented" )
399+ }
400+
401+ // Storable returns if this object is storable
402+ func (o * Object ) Storable () bool {
403+ return true
404+ }
405+
406+ // SetModTime sets the modified time
407+ func (o * Object ) SetModTime (ctx context.Context , t time.Time ) error {
408+ return errors .New ("not implemented" )
409+ }
410+
411+ // Open opens a file for streaming
412+ func (o * Object ) Open (ctx context.Context , options ... fs.OpenOption ) (io.ReadCloser , error ) {
413+ return buckets .DownloadFileStream (o .f .cfg , o .id )
414+ }
415+
416+ // Update updates an existing file
417+ func (o * Object ) Update (ctx context.Context , in io.Reader , src fs.ObjectInfo , options ... fs.OpenOption ) error {
418+ parentDir , _ := path .Split (o .remote )
419+ parentDir = strings .Trim (parentDir , "/" )
420+ folderUUID , err := o .f .dirCache .FindDir (ctx , parentDir , false )
421+ if err != nil {
422+ return err
423+ }
424+
425+ if err := files .DeleteFile (o .f .cfg , o .uuid ); err != nil {
426+ return err
427+ }
428+
429+ meta , err := buckets .UploadFileStream (o .f .cfg , folderUUID , path .Base (o .remote ), in , src .Size ())
430+ if err != nil {
431+ return err
432+ }
433+ o .uuid = meta .UUID
434+ o .size = src .Size ()
435+ o .modTime = time .Now ()
436+ return nil
437+ }
438+
439+ // Remove deletes a file
440+ func (o * Object ) Remove (ctx context.Context ) error {
441+ return files .DeleteFile (o .f .cfg , o .uuid )
442+ }
0 commit comments