def test_sync(self, now_mock, upload_chunked_mock):
        now_mock.return_value = timezone.make_aware(timezone.datetime(2016, 1, 1))

        old_latest_sync = timezone.now() - timezone.timedelta(weeks=1)
        dropbox_settings = DropboxSettings.get_solo()
        dropbox_settings.latest_sync = old_latest_sync
        dropbox_settings.save()

        self.assertFalse(upload_chunked_mock.called)
        self.assertIsNotNone(DropboxSettings.get_solo().access_token)

        dsmr_backup.services.dropbox.sync()
        self.assertTrue(upload_chunked_mock.called)
        self.assertNotEqual(DropboxSettings.get_solo().latest_sync, old_latest_sync)
Example #2
0
def upload_chunked(file_path):
    """ Uploads a file in chucks to Dropbox, allowing it to resume on (connection) failure. """
    dropbox_settings = DropboxSettings.get_solo()
    file_name = os.path.split(file_path)[-1]

    # From Dropbox docs.
    retries = 3
    client = DropboxClient(dropbox_settings.access_token)

    size = os.stat(file_path).st_size
    file_handle = open(file_path, 'rb')

    uploader = client.get_chunked_uploader(file_handle, size)

    while uploader.offset < size:
        try:
            uploader.upload_chunked(chunk_size=1 * 1024 * 1024)
        except rest.ErrorResponse:   # pragma: no cover
            retries -= 1  # pragma: no cover

            if retries == 0:  # pragma: no cover
                raise IOError("Failed to upload to dropbox")  # pragma: no cover

    # This will commit the file and persist it in Dropbox. Due to rotating backups we MUST override.
    uploader.finish(file_name, overwrite=True)
    def test_sync_disabled(self, upload_chunked_mock):
        dropbox_settings = DropboxSettings.get_solo()
        dropbox_settings.access_token = None
        dropbox_settings.save()

        self.assertFalse(upload_chunked_mock.called)

        dsmr_backup.services.dropbox.sync()
        self.assertFalse(upload_chunked_mock.called)
 def get_context_data(self, **kwargs):
     context_data = super(Configuration, self).get_context_data(**kwargs)
     context_data['api_settings'] = APISettings.get_solo()
     context_data['consumption_settings'] = ConsumptionSettings.get_solo()
     context_data['datalogger_settings'] = DataloggerSettings.get_solo()
     context_data['frontend_settings'] = FrontendSettings.get_solo()
     context_data['weather_settings'] = WeatherSettings.get_solo()
     context_data['backup_settings'] = BackupSettings.get_solo()
     context_data['dropbox_settings'] = DropboxSettings.get_solo()
     context_data['mindergas_settings'] = MinderGasSettings.get_solo()
     return context_data
    def test_sync_latest_sync(self, now_mock, get_backup_directory_mock):
        """ Test whether syncs are limited to intervals. """
        now_mock.return_value = timezone.make_aware(timezone.datetime(2016, 1, 1))

        dropbox_settings = DropboxSettings.get_solo()
        dropbox_settings.latest_sync = timezone.now() + timezone.timedelta(minutes=1)
        dropbox_settings.save()

        self.assertFalse(get_backup_directory_mock.called)

        dsmr_backup.services.dropbox.sync()
        self.assertFalse(get_backup_directory_mock.called)
    def test_sync_last_modified(self, now_mock, upload_chunked_mock, get_backup_directory_mock):
        """ Test whether syncs are skipped when file was not modified. """
        now_mock.return_value = timezone.make_aware(timezone.datetime(2016, 1, 1))

        dropbox_settings = DropboxSettings.get_solo()
        dropbox_settings.latest_sync = timezone.now() - timezone.timedelta(weeks=1)
        dropbox_settings.save()

        with tempfile.TemporaryDirectory() as temp_dir:
            get_backup_directory_mock.return_value = temp_dir
            temp_file = tempfile.NamedTemporaryFile(dir=temp_dir, delete=False)
            temp_file.write(b'Meh.')
            temp_file.flush()

            # 1420070400: 01 Jan 2015 00:00:00 GMT
            os.utime(temp_file.name, times=(1420070400, 1420070400))
            self.assertFalse(upload_chunked_mock.called)

            # File should be ignored, as it's modification timestamp is before latest sync.
            dsmr_backup.services.dropbox.sync()
            self.assertFalse(upload_chunked_mock.called)
Example #7
0
def sync():
    dropbox_settings = DropboxSettings.get_solo()

    # Skip when either no token was entered.
    if not dropbox_settings.access_token:
        return

    #  Or when we already synced within the last hour.
    next_sync_interval = None

    if dropbox_settings.latest_sync:
        next_sync_interval = dropbox_settings.latest_sync + timezone.timedelta(
            hours=settings.DSMR_DROPBOX_SYNC_INTERVAL
        )

    if next_sync_interval and timezone.now() < next_sync_interval:
        return

    backup_directory = dsmr_backup.services.backup.get_backup_directory()

    # Just check for modified files since the last sync.
    for (_, _, filenames) in os.walk(backup_directory):
        for current_file in filenames:
            current_file_path = os.path.join(backup_directory, current_file)
            file_stats = os.stat(current_file_path)

            # Ignore empty files.
            if file_stats.st_size == 0:
                continue

            last_modified = timezone.datetime.fromtimestamp(file_stats.st_mtime)
            last_modified = timezone.make_aware(last_modified)

            # Ignore when file was not altered since last sync.
            if dropbox_settings.latest_sync and last_modified < dropbox_settings.latest_sync:
                continue

            upload_chunked(file_path=current_file_path)

    DropboxSettings.objects.update(latest_sync=timezone.now())
 def setUp(self):
     dropbox_settings = DropboxSettings.get_solo()
     dropbox_settings.access_token = 'FAKE'
     dropbox_settings.save()
Example #9
0
 def setUp(self):
     dropbox_settings = DropboxSettings.get_solo()
     dropbox_settings.access_token = 'FAKE'
     dropbox_settings.save()
Example #10
0
 def setUp(self):
     DropboxSettings.get_solo()
     DropboxSettings.objects.all().update(access_token='FAKE')
Example #11
0
 def setUp(self):
     self.instance = DropboxSettings().get_solo()
Example #12
0
 def setUp(self):
     DropboxSettings.get_solo().update(
         access_token='1234',
         next_sync=timezone.now()
     )
Example #13
0
 def test_check_dropbox_sync_disabled(self):
     DropboxSettings.get_solo().update(
         access_token=None,
         next_sync=timezone.now() - timezone.timedelta(minutes=1)
     )
     self.assertIsNone(check_dropbox_sync())