=== modified file 'duplicity/backends/pydrivebackend.py' --- duplicity/backends/pydrivebackend.py 2015-05-31 19:14:43 +0000 +++ duplicity/backends/pydrivebackend.py 2015-06-10 12:26:45 +0000 @@ -21,6 +21,7 @@ import duplicity.backend from duplicity.errors import BackendException +from duplicity import log class PyDriveBackend(duplicity.backend.Backend): @@ -74,17 +75,36 @@ parent_folder_id = folder['id'] self.folder = parent_folder_id - def FilesList(self): - return self.drive.ListFile({'q': "'" + self.folder + "' in parents"}).GetList() + def FilesList(self, filename=None): + q = "('%s' in parents)" % self.folder + if filename is not None: + q += " and (title='%s')" % filename + fields = 'items(title,id,fileSize),nextPageToken' + return self.drive.ListFile({'q': q, 'fields': fields}).GetList() + + def file_by_name(self,filename): + flist = self.FilesList(filename) + flist_length = len(flist) + + if flist_length == 0: + return {'id': '', 'fileSize': -1, 'title': filename } + else: + if flist_length > 1: + log.Warn(_("PyDrive backend: filename %s is not unique in backup folder! Proceeding anyway...") % (filename)) + return flist[0] def id_by_name(self, filename): - try: - return next(item for item in self.FilesList() if item['title'] == filename)['id'] - except: - return '' + return self.file_by_name(filename)['id'] def _put(self, source_path, remote_filename): - drive_file = self.drive.CreateFile({'title': remote_filename, 'parents': [{"kind": "drive#fileLink", "id": self.folder}]}) + id = self.id_by_name(remote_filename) + if id == '': + # no existing file, make a new one + target = {'title': remote_filename, 'parents': [{"kind": "drive#fileLink", "id": self.folder}]} + else: + # upload over existing file + target = {'id': id } + drive_file = self.drive.CreateFile(target) drive_file.SetContentFile(source_path.name) drive_file.Upload() @@ -97,14 +117,12 @@ def _delete(self, filename): file_id = self.id_by_name(filename) - drive_file = self.drive.CreateFile({'id': file_id}) - drive_file.auth.service.files().delete(fileId=drive_file['id']).execute() + if id != '': + drive_file = self.drive.CreateFile({'id': file_id}) + drive_file.auth.service.files().delete(fileId=drive_file['id']).execute() def _query(self, filename): - try: - size = int((item for item in self.FilesList() if item['title'] == filename).next()['fileSize']) - except: - size = -1 + size = int(self.file_by_name(filename)['fileSize']) return {'size': size} duplicity.backend.register_backend('pydrive', PyDriveBackend)