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)
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)
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()
def setUp(self): DropboxSettings.get_solo() DropboxSettings.objects.all().update(access_token='FAKE')
def setUp(self): self.instance = DropboxSettings().get_solo()
def setUp(self): DropboxSettings.get_solo().update( access_token='1234', next_sync=timezone.now() )
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())