11import fnmatch
2+ import hashlib
23import json
34import logging
45import os
@@ -166,26 +167,52 @@ def upload_files(
166167 filter_glob : str ,
167168 throw_on_error : bool = False ,
168169 show_progress : bool = False ,
170+ force : bool = False ,
169171 job_id : str = "" ,
170172 ) -> List [Dict ]:
171173 """Upload files to a QFieldCloud project"""
172174 if not filter_glob :
173175 filter_glob = "*"
174176
175- files = self .list_local_files (project_path , filter_glob )
177+ local_files = self .list_local_files (project_path , filter_glob )
176178
177- if not files :
178- return files
179+ # we should always upload all package files
180+ if upload_type == FileTransferType .PACKAGE :
181+ force = True
179182
180- for file in files :
183+ files_to_upload = []
184+ if force :
185+ files_to_upload = local_files
186+ else :
187+ remote_files = self .list_remote_files (project_id )
188+
189+ if len (remote_files ) == 0 :
190+ files_to_upload = local_files
191+ else :
192+ for local_file in local_files :
193+ remote_file = None
194+ for f in remote_files :
195+ if f ["name" ] == local_file ["name" ]:
196+ remote_file = f
197+ break
198+
199+ md5sum = self ._get_md5sum (local_file ["absolute_filename" ])
200+ if remote_file and remote_file ["md5sum" ] == md5sum :
201+ continue
202+
203+ files_to_upload .append (local_file )
204+
205+ if not files_to_upload :
206+ return files_to_upload
207+
208+ for file in files_to_upload :
181209 try :
182- local_filename = Path (file ["name" ])
183- remote_filename = local_filename .relative_to (project_path )
210+ local_filename = Path (file ["absolute_filename" ])
184211 self .upload_file (
185212 project_id ,
186213 upload_type ,
187214 local_filename ,
188- remote_filename ,
215+ file [ "name" ] ,
189216 show_progress ,
190217 job_id ,
191218 )
@@ -199,7 +226,7 @@ def upload_files(
199226 else :
200227 continue
201228
202- return files
229+ return local_files
203230
204231 def upload_file (
205232 self ,
@@ -584,9 +611,11 @@ def list_local_files(
584611 if str (path .relative_to (root_path )).startswith ("." ):
585612 continue
586613
614+ relative_name = path .relative_to (root_path )
587615 files .append (
588616 {
589- "name" : str (path ),
617+ "name" : str (relative_name ),
618+ "absolute_filename" : str (path ),
590619 "status" : FileTransferStatus .PENDING ,
591620 "error" : None ,
592621 }
@@ -651,3 +680,14 @@ def _request(
651680 raise QfcRequestException (response ) from err
652681
653682 return response
683+
684+ def _get_md5sum (self , filename : str ) -> str :
685+ """Calculate sha256sum of a file"""
686+ BLOCKSIZE = 65536
687+ hasher = hashlib .md5 ()
688+ with open (filename , "rb" ) as f :
689+ buf = f .read (BLOCKSIZE )
690+ while len (buf ) > 0 :
691+ hasher .update (buf )
692+ buf = f .read (BLOCKSIZE )
693+ return hasher .hexdigest ()
0 commit comments