def test_sync_removes_unmatched(self): """ Test `sync` is able to copy files from src to dst and removes unmatched files from dst. """ with tempfile.TemporaryDirectory() as src_tmp_dir_path: with tempfile.TemporaryDirectory() as dst_tmp_dir_path: with open(os.path.join(src_tmp_dir_path, self.COPY_FILE), "w"): pass dst_dir_path = os.path.join(dst_tmp_dir_path, self.DST_DIR) os.makedirs(dst_dir_path) with open(os.path.join(dst_dir_path, self.DST_FILE), "w"): pass sync = Sync( FAKE_MTP_DETAILS, src_tmp_dir_path, os.path.join(dst_tmp_dir_path, self.DST_DIR), unmatched=REMOVE, ) sync.set_source_abs() sync.set_destination_abs() sync.sync() self.assertTrue( os.path.exists( os.path.join(dst_tmp_dir_path, self.DST_DIR, self.COPY_FILE))) self.assertFalse( os.path.exists(os.path.join(dst_dir_path, self.DST_FILE)))
def test_sync_no_data(self, mock_get_sync_data, mock_do_sync): """ Test 'sync' ends early if there are no files to synchronize. """ mock_get_sync_data.return_value = [{"src_dir_fls": []}] sync = Sync(FAKE_MTP_DETAILS, "/tmp", "Card/Music") sync.set_source_abs() sync.set_destination_abs() sync.sync() mock_do_sync.assert_not_called()
def test_sync_to_device_unmatched(mtp, tmpdir, tmpfiles, tmpdir_device_remove, unmatched_action): """ :unmatched_action == SYNCHRONIZE Test if Sync.sync() really sync files from computer to device and sync back to computer file(s) that are only on the device. :unmatched_action == REMOVE Test if Sync.sync() really sync files from computer to device and remove files that are only on the device. """ tmpfiles_names = set([os.path.basename(tmpf) for tmpf in tmpfiles]) # # create parent directory and copy a new file to the device # destination directory; this copied file will be the unmatched file, i.e. # a file that is present only in the destination directory unmatched = 'test.test' dst_pth = os.path.join(mtp[1], DEVICE_DESTINATION_TEST_DIR) gvfs.mkdir(dst_pth) dst_file = os.path.join(dst_pth, unmatched) gvfs.cp(src=COMPUTER_SOURCE_FILE, dst=dst_file) sync = Sync(mtp, tmpdir, DEVICE_DESTINATION_TEST_DIR, unmatched=unmatched_action) # NOQA sync.set_source_abs() sync.set_destination_abs() sync.sync() # # exclude the unmatched file from synchronized files as it was already in # the destination directory synced_files = [syncf for syncf in os.listdir(sync.destination_abs) if syncf != unmatched] assert synced_files for synced_file in synced_files: synced_file = os.path.basename(synced_file) assert synced_file in tmpfiles_names # # test if unmatched_action works as expected if unmatched_action == SYNCHRONIZE: # unmatched file should be synchronized to the source directory assert unmatched in os.listdir(sync.source_abs) elif unmatched_action == REMOVE: # unmatched file should be removed from the destination directory assert unmatched not in os.listdir(sync.destination_abs)
def test_sync_to_device(mtp, tmpdir, tmpfiles, tmpdir_device_remove): """ Test if Sync.sync() really sync files from computer to device """ tmpfiles_names = set([os.path.basename(tmpf) for tmpf in tmpfiles]) sync = Sync(mtp, tmpdir, DEVICE_DESTINATION_TEST_DIR) sync.set_source_abs() sync.set_destination_abs() sync.sync() synced_files = os.listdir(sync.destination_abs) assert synced_files for synced_file in synced_files: synced_file = os.path.basename(synced_file) assert synced_file in tmpfiles_names
def test_sync_ignore_unmatched( self, mock_handle_destination_dir_data, mock_get_sync_data, mock_do_sync, ): """ Test 'sync' ignores unmatched files. """ mock_get_sync_data.return_value = [FAKE_SYNC_DATA] sync = Sync(FAKE_MTP_DETAILS, "/tmp", "Card/Music") sync.set_source_abs() sync.set_destination_abs() sync.sync() mock_do_sync.assert_called_once_with(FAKE_SYNC_DATA) mock_handle_destination_dir_data.assert_not_called()
def test_sync_handle_unmatched( self, mock_handle_destination_dir_data, mock_get_sync_data, mock_do_sync, ): """ Test 'sync' handles (removes, in this case) unmatched files. """ mock_get_sync_data.return_value = [FAKE_SYNC_DATA] sync = Sync(FAKE_MTP_DETAILS, "/tmp", "Card/Music", unmatched=REMOVE) sync.set_source_abs() sync.set_destination_abs() sync.sync() mock_do_sync.assert_called_once_with(FAKE_SYNC_DATA) mock_handle_destination_dir_data.assert_called_once_with( FAKE_SYNC_DATA)
def main(): args = parser.parse_args() usb_bus, device = find_device.get_connection_details(vendor=args.vendor, model=args.model) mtp_details = find_device.get_mtp_details(usb_bus, device) sync = Sync( mtp_details=mtp_details, source=args.source, destination=args.destination, unmatched=args.unmatched, overwrite_existing=args.overwrite, verbose=args.verbose, ignore_file_types=args.ignore_file_type, ) sync.set_source_abs() sync.set_destination_abs() sync.sync()
def test_sync_to_device_overwrite(mtp, tmpdir, tmpfiles, tmpdir_device_remove, overwrite): """ :overwrite == True Test if Sync.sync() overwrites existing files :overwrite == False Test if Sync.sync() does not overwrite existing files """ def _get_modification_times(): sync_dict = {} for synced_file in os.listdir(sync.destination_abs): abs_pth = os.path.join(sync.destination_abs, synced_file) sync_dict[synced_file] = time.ctime(os.path.getmtime(abs_pth)) return sync_dict sync = Sync(mtp, tmpdir, DEVICE_DESTINATION_TEST_DIR, overwrite_existing=overwrite) # NOQA sync.set_source_abs() sync.set_destination_abs() sync.sync() first_sync = _get_modification_times() time.sleep(2) sync.sync() second_sync = _get_modification_times() for synced_file in first_sync: if overwrite: assert first_sync[synced_file] < second_sync[synced_file] else: assert first_sync[synced_file] == second_sync[synced_file]
def test_sync_to_computer(mtp, tmpdir, tmpfiles, tmpdir_device_remove): """ Test if Sync.sync() really sync files from device to computer """ tmpfiles_names = set([os.path.basename(tmpf) for tmpf in tmpfiles]) # # first move tmpfiles to the device device_source = os.path.join(mtp[1], DEVICE_DESTINATION_TEST_DIR) if not os.path.exists(device_source): gvfs.mkdir(device_source) for tmpfile in tmpfiles: gvfs.mv(tmpfile, os.path.join(mtp[1], device_source)) moved_files = os.listdir(device_source) assert moved_files for moved_file in moved_files: moved_file = os.path.basename(moved_file) assert moved_file in tmpfiles_names # # then sync them back to computer sync = Sync(mtp, device_source, tmpdir) sync.set_source_abs() sync.set_destination_abs() sync.sync() synced_files = os.listdir(sync.destination_abs) assert synced_files for synced_file in synced_files: synced_file = os.path.basename(synced_file) assert synced_file in tmpfiles_names
def test_sync_default(self): """ Test `sync` is able to copy files from src to dst and ignores unmatched files from dst. """ with tempfile.TemporaryDirectory() as src_tmp_dir_path: with tempfile.TemporaryDirectory() as dst_tmp_dir_path: with open(os.path.join(src_tmp_dir_path, self.COPY_FILE), "w"): pass sync = Sync( FAKE_MTP_DETAILS, src_tmp_dir_path, os.path.join(dst_tmp_dir_path, self.DST_DIR), ) sync.set_source_abs() sync.set_destination_abs() sync.sync() self.assertTrue( os.path.exists( os.path.join(dst_tmp_dir_path, self.DST_DIR, self.COPY_FILE)))
def run(args): """ Run pysyncdroid. :argument args: command line arguments namespace :type args: object """ try: usb_bus_id, device_id = get_connection_details(args.vendor, args.model) mtp_details = get_mtp_details(usb_bus_id, device_id) except DeviceException as exc: return str(exc) try: sources, destinations = parse_sync_info(args) except (argparse.ArgumentError, MappingFileException) as exc: return str(exc) for source, destination in zip(sources, destinations): source = source.strip() destination = destination.strip() sync = Sync( mtp_details=mtp_details, source=source, destination=destination, verbose=args.verbose, unmatched=args.unmatched, overwrite_existing=args.overwrite, ignore_file_types=args.ignore_file_type, ) sync.set_source_abs() sync.set_destination_abs() sync.sync()