Пример #1
0
 def handle_normal_item(self, item, record, item_path):
     """
     When the file exists, the record exists, and the remote item exists, first validate item type,
     and then compare modification time and size, and then decide what to do. If necessary, hash the file and
     compare the hashtags.
     :param onedrive_d.api.items.OneDriveItem item:
     :param onedrive_d.store.items_db.ItemRecord record:
     :param str item_path:
     """
     try:
         if item.is_folder:
             if os.path.isdir(item_path):
                 self.task_pool.add_task(
                     SynchronizeDirTask(
                         self,
                         self.local_relative_parent_path + '/' + self.name,
                         item.name))
             else:
                 self.move_and_create_dir(item, item_path)
         else:
             if not os.path.isfile(item_path):
                 self.move_and_create_file(item, item_path)
                 return
             file_size, file_mtime = self.stat_file(item_path)
             if record.item_id == item.id and record.e_tag == item.e_tag:
                 # The remote item did not change since last update of record.
                 if file_size != record.size or compare_timestamps(
                         file_mtime,
                         datetime_to_timestamp(record.modified_time)) != 0:
                     self.task_pool.add_task(
                         UploadFileTask(
                             self, self.local_relative_parent_path + '/' +
                             self.name, item.name,
                             options.NameConflictBehavior.REPLACE))
             elif record.size == file_size and compare_timestamps(
                     datetime_to_timestamp(record.modified_time), file_mtime) == 0 and record.modified_time < \
                     item.modified_time:
                 # Local item did not change since last update of record, but item was updated remotely.
                 self.task_pool.add_task(DownloadFileTask(self, item))
             elif self.check_file_hash(item, item_path, file_mtime):
                 # Both remote item and local item were changed since last update of record, but file hash
                 # still matches. Just update the record.
                 return
             else:
                 # Both remote item and local item were changed since last update of record, but we could not
                 # determine which one to keep. Just keep both.
                 self.move_and_create_file(item, item_path)
     except (OSError, IOError) as e:
         self.logger.error('An OSError occurred handling item "%s": %s.',
                           item_path, e)
Пример #2
0
 def handle_record_missing(self, item, item_path):
     """
     When the entry path exists both locally and remotely, but there is no database record, first compare entry
     types and then decide what to do next.
     :param onedrive_d.api.items.OneDriveItem item:
     :param str item_path:
     """
     if item.is_folder:
         self.move_and_create_dir(item, item_path)
     else:
         try:
             if not os.path.isfile(item_path):
                 self.move_and_create_file(item, item_path)
                 return
             file_size, file_mtime = self.stat_file(item_path)
             if file_size == item.size and compare_timestamps(
                     datetime_to_timestamp(item.modified_time), file_mtime) == 0:
                 # If local file and remote file match in terms of mtime and file size, then we assume two files
                 # are identical and just update the record.
                 self.items_store.update_item(item)
             else:
                 # When the two key properties do not match, we want to use file hashes to determine if they are
                 # identical or not.
                 if self.check_file_hash(item, item_path, file_mtime):
                     return
                 # The server does not return any hash info or the hash info does not match local file. Keep both
                 # versions and update local database.
                 self.logger.debug('No remote hash or mismatch remote hash. No local record. Keep both versions.')
                 self.move_and_create_file(item, item_path)
         except Exception as e:
             self.logger.error('An error occurred when handling "%s": %s.', item_path, e)
Пример #3
0
 def handle_normal_item(self, item, record, item_path):
     """
     When the file exists, the record exists, and the remote item exists, first validate item type,
     and then compare modification time and size, and then decide what to do. If necessary, hash the file and
     compare the hashtags.
     :param onedrive_d.api.items.OneDriveItem item:
     :param onedrive_d.store.items_db.ItemRecord record:
     :param str item_path:
     """
     try:
         if item.is_folder:
             if os.path.isdir(item_path):
                 self.task_pool.add_task(SynchronizeDirTask(self, self.local_relative_parent_path + '/' +
                                                            self.name, item.name))
             else:
                 self.move_and_create_dir(item, item_path)
         else:
             if not os.path.isfile(item_path):
                 self.move_and_create_file(item, item_path)
                 return
             file_size, file_mtime = self.stat_file(item_path)
             if record.item_id == item.id and record.e_tag == item.e_tag:
                 # The remote item did not change since last update of record.
                 if file_size != record.size or compare_timestamps(
                         file_mtime, datetime_to_timestamp(record.modified_time)) != 0:
                     self.task_pool.add_task(UploadFileTask(self, self.local_relative_parent_path + '/' +
                                                            self.name, item.name,
                                                            options.NameConflictBehavior.REPLACE))
             elif record.size == file_size and compare_timestamps(
                     datetime_to_timestamp(record.modified_time), file_mtime) == 0 and record.modified_time < \
                     item.modified_time:
                 # Local item did not change since last update of record, but item was updated remotely.
                 self.task_pool.add_task(DownloadFileTask(self, item))
             elif self.check_file_hash(item, item_path, file_mtime):
                 # Both remote item and local item were changed since last update of record, but file hash
                 # still matches. Just update the record.
                 return
             else:
                 # Both remote item and local item were changed since last update of record, but we could not
                 # determine which one to keep. Just keep both.
                 self.move_and_create_file(item, item_path)
     except (OSError, IOError) as e:
         self.logger.error('An OSError occurred handling item "%s": %s.', item_path, e)
Пример #4
0
 def handle(self):
     local_temp_path = self.local_parent_path + '/' + self.get_temp_filename()
     local_item_path = self.local_parent_path + '/' + self.item.name
     try:
         with open(local_temp_path, 'wb') as f:
             self.drive.download_file(file=f, size=self.item.size, item_id=self.item.id)
         os.rename(local_temp_path, local_item_path)
         t = datetime_to_timestamp(self.item.modified_time)
         os.utime(local_item_path, (t, t))
         self.items_store.update_item(self.item, ItemRecordStatuses.DOWNLOADED)
     except Exception as e:
         self.logger.error('Error occurred downloading to file "%s": %s.', local_item_path, e)
Пример #5
0
 def test_handle(self, mock_request):
     mock_request.get(self.drive.drive_uri + self.drive.drive_path + '/items/' + self.item.id + '/content',
                      content=b'1', status_code=codes.ok)
     m = mock.mock_open()
     with mock.patch('builtins.open', m, create=True):
         self.task.handle()
     m.assert_called_once_with(self.tmp_file_path, 'wb')
     handle = m()
     handle.write.assert_called_once_with(b'1')
     self.assertEqual(1, len(self.utime_records))
     self.assertIn(self.file_path, self.utime_records)
     ts = datetime_to_timestamp(self.item.modified_time)
     self.assertEqual((ts, ts), self.utime_records[self.file_path])
Пример #6
0
 def test_convert(self):
     self.assertEqual(self.d, onedrive_d.str_to_datetime(self.s))
     self.assertEqual(self.s, onedrive_d.datetime_to_str(self.d))
     self.assertEqual(self.t, onedrive_d.datetime_to_timestamp(self.d))
Пример #7
0
 def test_convert(self):
     self.assertEqual(self.d, onedrive_d.str_to_datetime(self.s))
     self.assertEqual(self.s, onedrive_d.datetime_to_str(self.d))
     self.assertEqual(self.t, onedrive_d.datetime_to_timestamp(self.d))