@@ -3,6 +3,7 @@ package sharing
33import (
44 "bytes"
55 "encoding/json"
6+ "fmt"
67 "io"
78 "net/http"
89 "net/url"
@@ -14,6 +15,7 @@ import (
1415 "github.com/cozy/cozy-stack/pkg/couchdb"
1516 "github.com/cozy/cozy-stack/pkg/instance"
1617 "github.com/cozy/cozy-stack/pkg/lock"
18+ "github.com/cozy/cozy-stack/pkg/realtime"
1719 "github.com/cozy/cozy-stack/pkg/vfs"
1820 multierror "github.com/hashicorp/go-multierror"
1921)
@@ -81,14 +83,45 @@ func (s *Sharing) InitialUpload(inst *instance.Instance, m *Member) error {
8183 return err
8284 }
8385 if ! more {
84- return nil
86+ return s . sendInitialEndNotif ( inst , m )
8587 }
8688 }
8789
8890 s .pushJob (inst , "share-upload" )
8991 return nil
9092}
9193
94+ // sendInitialEndNotif sends a notification to the recipient that the initial
95+ // sync is finished
96+ func (s * Sharing ) sendInitialEndNotif (inst * instance.Instance , m * Member ) error {
97+ u , err := url .Parse (m .Instance )
98+ if err != nil {
99+ return err
100+ }
101+ c := s .FindCredentials (m )
102+ if c == nil {
103+ return ErrInvalidSharing
104+ }
105+ opts := & request.Options {
106+ Method : http .MethodDelete ,
107+ Scheme : u .Scheme ,
108+ Domain : u .Host ,
109+ Path : fmt .Sprintf ("/sharings/%s/initial" , s .SID ),
110+ Headers : request.Headers {
111+ "Authorization" : "Bearer " + c .AccessToken .AccessToken ,
112+ },
113+ }
114+ res , err := request .Req (opts )
115+ if err != nil {
116+ return err
117+ }
118+ res .Body .Close ()
119+ if res .StatusCode / 100 != 2 {
120+ return ErrInternalServerError
121+ }
122+ return nil
123+ }
124+
92125// UploadTo uploads one file to the given member. It returns false if there
93126// are no more files to upload to this member currently.
94127func (s * Sharing ) UploadTo (inst * instance.Instance , m * Member ) (bool , error ) {
@@ -517,9 +550,52 @@ func (s *Sharing) UploadNewFile(inst *instance.Instance, target *FileDocWithRevi
517550 Debugf ("Cannot create file: %s" , err )
518551 return err
519552 }
553+ if s .NbFiles > 0 {
554+ defer s .countReceivedFiles (inst )
555+ }
520556 return copyFileContent (inst , file , body )
521557}
522558
559+ // countReceivedFiles counts the number of files received during the initial
560+ // sync, and pushs an event to the real-time system with this count
561+ func (s * Sharing ) countReceivedFiles (inst * instance.Instance ) {
562+ count := 0
563+ var req = & couchdb.ViewRequest {
564+ Key : s .SID ,
565+ IncludeDocs : true ,
566+ }
567+ var res couchdb.ViewResponse
568+ err := couchdb .ExecView (inst , consts .SharedDocsBySharingID , req , & res )
569+ if err == nil {
570+ for _ , row := range res .Rows {
571+ var doc SharedRef
572+ if err = json .Unmarshal (row .Doc , & doc ); err != nil {
573+ continue
574+ }
575+ if doc .Infos [s .SID ].Binary {
576+ count ++
577+ }
578+ }
579+ }
580+
581+ if count >= s .NbFiles {
582+ if err = s .EndInitial (inst ); err != nil {
583+ inst .Logger ().WithField ("nspace" , "sharing" ).
584+ Errorf ("Can't save sharing %v: %s" , s , err )
585+ }
586+ return
587+ }
588+
589+ doc := couchdb.JSONDoc {
590+ Type : consts .SharingsInitialSync ,
591+ M : map [string ]interface {}{
592+ "_id" : s .SID ,
593+ "count" : count ,
594+ },
595+ }
596+ realtime .GetHub ().Publish (inst , realtime .EventUpdate , doc , nil )
597+ }
598+
523599// UploadExistingFile is used to receive new content for an existing file.
524600//
525601// Note: if file was renamed + its content has changed, we modify the content
0 commit comments