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)))
Esempio n. 2
0
    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()
Esempio n. 3
0
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)
Esempio n. 4
0
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
Esempio n. 5
0
    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()
Esempio n. 6
0
    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)
Esempio n. 7
0
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()
Esempio n. 8
0
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]
Esempio n. 9
0
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
Esempio n. 10
0
    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)))
Esempio n. 11
0
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()