├── .cz.toml ├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── codeql-analysis.yml │ ├── commitlint.yml │ ├── gradle.yml │ └── release.yml ├── .gitignore ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Documentation ├── Developer.md ├── Glossary.md ├── Integration.md ├── JettyApiSpec.yaml ├── Keys.md ├── Overview.md ├── Publishing.md ├── README.md └── RunningLocally.md ├── LICENSE ├── README.md ├── build.gradle ├── client-rest ├── angular.json ├── build.gradle ├── e2e │ ├── protractor.conf.js │ ├── src │ │ ├── app.e2e-spec.ts │ │ └── app.po.ts │ └── tsconfig.e2e.json ├── package-lock.json ├── package.json ├── proxy.conf.json ├── src │ ├── app │ │ ├── app.component.html │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── app.routing.ts │ │ ├── data │ │ │ ├── data-types.service.ts │ │ │ ├── data.component.html │ │ │ ├── data.component.ts │ │ │ └── index.ts │ │ ├── progress │ │ │ ├── index.ts │ │ │ ├── progress.component.html │ │ │ ├── progress.component.ts │ │ │ ├── progress.guard.ts │ │ │ └── progress.service.ts │ │ ├── start │ │ │ ├── index.ts │ │ │ ├── start.component.html │ │ │ └── start.component.ts │ │ ├── transfer │ │ │ ├── auth-callback.component.ts │ │ │ ├── create-transfer.component.html │ │ │ ├── create-transfer.component.ts │ │ │ ├── index.ts │ │ │ ├── initiate-transfer.component.html │ │ │ ├── initiate-transfer.component.ts │ │ │ └── transfer.service.ts │ │ ├── transport │ │ │ ├── index.ts │ │ │ └── transport.functions.ts │ │ ├── types │ │ │ ├── create-transfer-job.ts │ │ │ ├── data-types.ts │ │ │ ├── generate-service-auth-data.ts │ │ │ ├── get-reserved-worker.ts │ │ │ ├── index.ts │ │ │ ├── reserve-worker.ts │ │ │ ├── reserved-worker.ts │ │ │ ├── service-auth-data.ts │ │ │ ├── start-transfer-job.ts │ │ │ ├── transfer-job.ts │ │ │ └── transfer-services.ts │ │ └── util │ │ │ ├── arrays.ts │ │ │ └── index.ts │ ├── assets │ │ └── .gitkeep │ ├── browserslist │ ├── environments │ │ ├── .gitignore │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── karma.conf.js │ ├── main.ts │ ├── polyfills.ts │ ├── sass │ │ ├── _progress-indicator.scss │ │ └── styles.scss │ ├── test-keys │ │ ├── server.crt │ │ └── server.key │ ├── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ └── tslint.json ├── tsconfig.json └── tslint.json ├── config └── checkstyle │ └── checkstyle.xml ├── distributions ├── README.md ├── api-default │ └── build.gradle ├── common │ └── k8s │ │ ├── README.md │ │ ├── api-deployment.yaml │ │ ├── api-service.yaml │ │ └── transfer-deployment.yaml ├── demo-google-deployment │ ├── README.md │ ├── api │ │ └── build.gradle │ ├── bin │ │ ├── .gitignore │ │ ├── build_and_deploy_static_content.sh │ │ ├── encrypt_and_upload_secrets.sh │ │ ├── iam-policy.json │ │ ├── init_project_vars_example.sh │ │ └── setup_gke_environment.sh │ ├── resources │ │ ├── config │ │ │ ├── api.yaml │ │ │ ├── common.yaml │ │ │ └── environments │ │ │ │ └── qa │ │ │ │ └── index.html │ │ └── log4j.properties │ └── transfer │ │ └── build.gradle ├── demo-server │ ├── .gitignore │ ├── build.gradle │ ├── env.secrets.template │ └── src │ │ ├── config │ │ ├── client │ │ │ └── nginx.conf │ │ └── demo │ │ │ └── supervisord.conf │ │ └── main │ │ └── resources │ │ ├── config │ │ ├── common.yaml │ │ ├── retry │ │ │ └── default.yaml │ │ └── transfer.yaml │ │ ├── demo-selfsigned-keystore.jks │ │ └── log4j.properties └── transfer-default │ └── build.gradle ├── extensions ├── README.md ├── auth │ ├── portability-auth-apple │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── auth │ │ │ │ └── apple │ │ │ │ ├── AppleAuthServiceExtension.java │ │ │ │ ├── AppleOAuthConfig.java │ │ │ │ └── package-info.java │ │ │ └── resources │ │ │ ├── META-INF.services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ │ │ └── config │ │ │ └── retry │ │ │ └── default.yaml │ ├── portability-auth-daybook │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── auth │ │ │ │ └── daybook │ │ │ │ ├── DaybookAuthServiceExtension.java │ │ │ │ ├── DaybookOAuthConfig.java │ │ │ │ └── package-info.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ ├── portability-auth-deezer │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── auth │ │ │ │ └── deezer │ │ │ │ ├── DeezerAuthServiceExtension.java │ │ │ │ ├── DeezerOAuthConfig.java │ │ │ │ └── package-info.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ ├── portability-auth-facebook │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── auth │ │ │ │ └── facebook │ │ │ │ ├── FacebookAuthServiceExtension.java │ │ │ │ ├── FacebookOAuthConfig.java │ │ │ │ └── package-info.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ ├── portability-auth-flickr │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── auth │ │ │ │ │ └── flickr │ │ │ │ │ ├── FlickrAuthServiceExtension.java │ │ │ │ │ └── FlickrOAuthConfig.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── datatransferproject │ │ │ └── auth │ │ │ └── flickr │ │ │ └── FlickrAuthDataGeneratorTest.java │ ├── portability-auth-google │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── auth │ │ │ │ └── google │ │ │ │ ├── BloggerAuthServiceExtension.java │ │ │ │ ├── BloggerOAuthConfig.java │ │ │ │ ├── GoogleAuthServiceExtension.java │ │ │ │ ├── GoogleOAuthConfig.java │ │ │ │ └── package-info.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ ├── portability-auth-harness-microsoft │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── org │ │ │ └── datatransferproject │ │ │ └── auth │ │ │ └── microsoft │ │ │ └── harness │ │ │ ├── AuthTestDriver.java │ │ │ └── TestHelper.java │ ├── portability-auth-imgur │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org.datatransferproject.auth.imgur │ │ │ │ ├── ImgurAuthServiceExtension.java │ │ │ │ ├── ImgurOAuthConfig.java │ │ │ │ └── package-info.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ ├── portability-auth-instagram │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── auth │ │ │ │ └── instagram │ │ │ │ ├── InstagramAuthServiceExtension.java │ │ │ │ └── InstagramOAuthConfig.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ ├── portability-auth-koofr │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── auth │ │ │ │ └── koofr │ │ │ │ ├── KoofrAuthServiceExtension.java │ │ │ │ ├── KoofrOAuthConfig.java │ │ │ │ └── package-info.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ ├── portability-auth-microsoft │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── auth │ │ │ │ └── microsoft │ │ │ │ ├── MicrosoftAuthServiceExtension.java │ │ │ │ ├── MicrosoftOAuthConfig.java │ │ │ │ └── package-info.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ ├── portability-auth-offline-demo │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── auth │ │ │ │ └── offline │ │ │ │ ├── OfflineDemoAuthDataGenerator.java │ │ │ │ └── OfflineDemoAuthServiceExtension.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ ├── portability-auth-rememberthemilk │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── auth │ │ │ │ └── rememberthemilk │ │ │ │ ├── RememberTheMilkAuthDataGenerator.java │ │ │ │ ├── RememberTheMilkAuthServiceExtension.java │ │ │ │ ├── RememberTheMilkSignatureGenerator.java │ │ │ │ └── model │ │ │ │ ├── AuthElement.java │ │ │ │ └── RememberTheMilkResponse.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ ├── portability-auth-smugmug │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── auth │ │ │ │ └── smugmug │ │ │ │ ├── SmugMugAuthServiceExtension.java │ │ │ │ └── SmugMugOAuthConfig.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ ├── portability-auth-spotify │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── auth │ │ │ │ └── spotify │ │ │ │ ├── SpotifyAuthServiceExtension.java │ │ │ │ ├── SpotifyOAuthConfig.java │ │ │ │ └── package-info.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension │ └── portability-auth-twitter │ │ ├── build.gradle │ │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── datatransferproject │ │ │ └── auth │ │ │ └── twitter │ │ │ ├── TwitterAuthServiceExtension.java │ │ │ └── TwitterOAuthConfig.java │ │ └── resources │ │ └── META-INF │ │ └── services │ │ └── org.datatransferproject.spi.api.auth.extension.AuthServiceExtension ├── cloud │ ├── portability-cloud-google │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── cloud │ │ │ │ │ └── google │ │ │ │ │ ├── GoogleAppCredentialStore.java │ │ │ │ │ ├── GoogleAppSecretDecrypter.java │ │ │ │ │ ├── GoogleCloudExtension.java │ │ │ │ │ ├── GoogleCloudExtensionModule.java │ │ │ │ │ ├── GoogleCloudIdempotentImportExecutor.java │ │ │ │ │ ├── GoogleCloudIdempotentImportExecutorExtension.java │ │ │ │ │ ├── GoogleCloudUtils.java │ │ │ │ │ ├── GoogleCredentialException.java │ │ │ │ │ ├── GoogleDtpInternalMetricExtension.java │ │ │ │ │ ├── GoogleDtpInternalMetricRecorder.java │ │ │ │ │ ├── GoogleJobStore.java │ │ │ │ │ ├── GoogleTempFileStore.java │ │ │ │ │ ├── StackdriverMonitor.java │ │ │ │ │ ├── StackdriverMonitorExtension.java │ │ │ │ │ └── package-info.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ ├── org.datatransferproject.api.launcher.MonitorExtension │ │ │ │ ├── org.datatransferproject.spi.cloud.extension.CloudExtension │ │ │ │ ├── org.datatransferproject.spi.service.extension.ServiceExtension │ │ │ │ └── org.datatransferproject.spi.transfer.idempotentexecutor.IdempotentImportExecutorExtension │ │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── datatransferproject │ │ │ └── cloud │ │ │ └── google │ │ │ ├── GoogleCloudIdempotentImportExecutorTest.java │ │ │ ├── GoogleCloudModuleTest.java │ │ │ └── GoogleJobStoreTest.java │ ├── portability-cloud-local │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── cloud │ │ │ │ │ └── local │ │ │ │ │ ├── LocalAppCredentialStore.java │ │ │ │ │ ├── LocalCloudExtension.java │ │ │ │ │ ├── LocalJobStore.java │ │ │ │ │ ├── LocalTempFileStore.java │ │ │ │ │ └── package-info.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.cloud.extension.CloudExtension │ │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── datatransferproject │ │ │ └── cloud │ │ │ └── local │ │ │ └── LocalJobStoreTest.java │ └── portability-cloud-microsoft │ │ ├── build.gradle │ │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── datatransferproject │ │ │ └── cloud │ │ │ └── microsoft │ │ │ ├── cosmos │ │ │ ├── AzureDtpInternalMetricExtension.java │ │ │ ├── AzureDtpInternalMetricRecorder.java │ │ │ ├── AzureKeyVaultStore.java │ │ │ ├── AzureTableStore.java │ │ │ ├── DataWrapper.java │ │ │ ├── MicrosoftCloudExtension.java │ │ │ ├── MicrosoftStorageException.java │ │ │ └── TableStoreConfiguration.java │ │ │ └── package-info.java │ │ └── resources │ │ └── META-INF │ │ └── services │ │ ├── org.datatransferproject.spi.cloud.extension.CloudExtension │ │ └── org.datatransferproject.spi.service.extension.ServiceExtension ├── config │ └── portability-config-yaml │ │ ├── build.gradle │ │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── config │ │ │ │ └── yaml │ │ │ │ ├── YamlSettingsExtension.java │ │ │ │ └── package-info.java │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.config.extension.SettingsExtension │ │ └── test │ │ ├── java │ │ └── org │ │ │ └── datatransferproject │ │ │ └── config │ │ │ └── yaml │ │ │ └── YamlSettingsExtensionTest.java │ │ └── resources │ │ ├── api-1.yaml │ │ └── api-2.yaml ├── copier │ └── portability-stack-copier │ │ ├── build.gradle │ │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── datatransferproject │ │ │ └── copier │ │ │ └── stack │ │ │ ├── PortabilityStackInMemoryDataCopier.java │ │ │ ├── PortabilityStackInMemoryDataCopierExtension.java │ │ │ └── package-info.java │ │ └── resources │ │ └── META-INF │ │ └── services │ │ └── org.datatransferproject.transfer.copier.InMemoryDataCopierExtension ├── data-transfer │ ├── portability-data-transfer-apple │ │ ├── Readme.md │ │ ├── build.gradle │ │ ├── idea.gradle │ │ ├── proto.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── datatransfer │ │ │ │ │ └── apple │ │ │ │ │ ├── AppleBaseInterface.java │ │ │ │ │ ├── AppleInterfaceFactory.java │ │ │ │ │ ├── AppleTransferExtension.java │ │ │ │ │ ├── constants │ │ │ │ │ ├── AppleConstants.java │ │ │ │ │ ├── AppleMusicConstants.java │ │ │ │ │ ├── ApplePhotosConstants.java │ │ │ │ │ ├── AuditKeys.java │ │ │ │ │ └── Headers.java │ │ │ │ │ ├── exceptions │ │ │ │ │ ├── AppleContentException.java │ │ │ │ │ └── AppleHttpCopyException.java │ │ │ │ │ ├── http │ │ │ │ │ └── TokenRefresher.java │ │ │ │ │ ├── music │ │ │ │ │ ├── AppleMusicImporter.java │ │ │ │ │ ├── AppleMusicInterface.java │ │ │ │ │ └── data │ │ │ │ │ │ └── converters │ │ │ │ │ │ └── AppleMusicPlaylistConverter.java │ │ │ │ │ ├── photos │ │ │ │ │ ├── AppleMediaImporter.java │ │ │ │ │ ├── AppleMediaInterface.java │ │ │ │ │ ├── ApplePhotosImporter.java │ │ │ │ │ ├── AppleVideosImporter.java │ │ │ │ │ ├── DownUpResult.java │ │ │ │ │ └── streaming │ │ │ │ │ │ └── StreamingContentClient.java │ │ │ │ │ └── signals │ │ │ │ │ ├── AppleSignalHandler.java │ │ │ │ │ └── AppleSignalInterface.java │ │ │ ├── proto │ │ │ │ ├── ImportMusicPlaylists.proto │ │ │ │ └── ImportPhotos.proto │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ └── test │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── datatransfer │ │ │ │ └── apple │ │ │ │ ├── http │ │ │ │ ├── FakeSynchronousSubscriber.java │ │ │ │ └── TokenRefresherTest.java │ │ │ │ ├── music │ │ │ │ ├── AppleMusicImporterTest.java │ │ │ │ └── data │ │ │ │ │ └── converters │ │ │ │ │ └── AppleMusicPlaylistConverterTest.java │ │ │ │ ├── photos │ │ │ │ ├── AppleImporterTestBase.java │ │ │ │ ├── AppleMediaImporterTest.java │ │ │ │ ├── ApplePhotosImporterTest.java │ │ │ │ ├── AppleVideosImporterTest.java │ │ │ │ ├── StreamingUtils.java │ │ │ │ └── TestConstants.java │ │ │ │ └── signals │ │ │ │ ├── AppleSignalHandlerTest.java │ │ │ │ └── AppleSignalInterfaceTest.java │ │ │ └── resources │ │ │ └── mockito-extensions │ │ │ └── org.mockito.plugins.MockMaker │ ├── portability-data-transfer-backblaze │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── datatransfer │ │ │ │ │ └── backblaze │ │ │ │ │ ├── BackblazeTransferExtension.java │ │ │ │ │ ├── common │ │ │ │ │ ├── BackblazeDataTransferClient.java │ │ │ │ │ ├── BackblazeDataTransferClientFactory.java │ │ │ │ │ ├── BackblazeS3ClientFactory.java │ │ │ │ │ └── BaseBackblazeS3ClientFactory.java │ │ │ │ │ ├── exception │ │ │ │ │ └── BackblazeCredentialsException.java │ │ │ │ │ ├── package-info.java │ │ │ │ │ ├── photos │ │ │ │ │ └── BackblazePhotosImporter.java │ │ │ │ │ └── videos │ │ │ │ │ └── BackblazeVideosImporter.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ └── test │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── datatransfer │ │ │ │ └── backblaze │ │ │ │ ├── common │ │ │ │ └── BackblazeDataTransferClientTest.java │ │ │ │ ├── photos │ │ │ │ └── BackblazePhotosImporterTest.java │ │ │ │ └── videos │ │ │ │ └── BackblazeVideosImporterTest.java │ │ │ └── resources │ │ │ └── test.txt │ ├── portability-data-transfer-daybook │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── transfer │ │ │ │ │ └── daybook │ │ │ │ │ ├── DaybookTransferExtension.java │ │ │ │ │ ├── package-info.java │ │ │ │ │ ├── photos │ │ │ │ │ └── DaybookPhotosImporter.java │ │ │ │ │ └── social │ │ │ │ │ └── DaybookPostsImporter.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── datatransferproject │ │ │ └── transfer │ │ │ └── daybook │ │ │ ├── photos │ │ │ └── DaybookPhotosImporterTest.java │ │ │ └── social │ │ │ └── DaybookPostsImporterTest.java │ ├── portability-data-transfer-deezer │ │ ├── Readme.md │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── transfer │ │ │ │ └── deezer │ │ │ │ ├── DeezerApi.java │ │ │ │ ├── DeezerTransferExtension.java │ │ │ │ ├── model │ │ │ │ ├── Album.java │ │ │ │ ├── Artist.java │ │ │ │ ├── Error.java │ │ │ │ ├── InsertResponse.java │ │ │ │ ├── PlaylistDetails.java │ │ │ │ ├── PlaylistSummary.java │ │ │ │ ├── PlaylistsResponse.java │ │ │ │ ├── Track.java │ │ │ │ ├── TrackCollection.java │ │ │ │ └── User.java │ │ │ │ └── playlists │ │ │ │ ├── DeezerPlaylistExporter.java │ │ │ │ └── DeezerPlaylistImporter.java │ │ │ └── resources │ │ │ ├── META-INF │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ └── config │ │ │ └── deezer.yaml │ ├── portability-data-transfer-facebook │ │ ├── Readme.md │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── transfer │ │ │ │ │ └── facebook │ │ │ │ │ ├── FacebookTransferExtension.java │ │ │ │ │ ├── photos │ │ │ │ │ ├── FacebookPhotosExporter.java │ │ │ │ │ ├── FacebookPhotosInterface.java │ │ │ │ │ └── RestFbFacebookPhotos.java │ │ │ │ │ ├── utils │ │ │ │ │ └── FacebookTransferUtils.java │ │ │ │ │ └── videos │ │ │ │ │ ├── FacebookVideosExporter.java │ │ │ │ │ ├── FacebookVideosImporter.java │ │ │ │ │ ├── FacebookVideosInterface.java │ │ │ │ │ └── RestFbFacebookVideos.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ └── test │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── transfer │ │ │ │ └── facebook │ │ │ │ ├── photos │ │ │ │ └── FacebookPhotosExporterTest.java │ │ │ │ └── videos │ │ │ │ ├── FacebookVideosExporterTest.java │ │ │ │ └── FacebookVideosImporterTest.java │ │ │ └── resources │ │ │ └── test.jpeg │ ├── portability-data-transfer-flickr │ │ ├── Readme.md │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── datatransfer │ │ │ │ │ └── flickr │ │ │ │ │ ├── FlickrTransferExtension.java │ │ │ │ │ ├── media │ │ │ │ │ └── FlickrMediaImporter.java │ │ │ │ │ └── photos │ │ │ │ │ ├── FlickrPhotosExporter.java │ │ │ │ │ ├── FlickrPhotosImporter.java │ │ │ │ │ ├── FlickrTempPhotoData.java │ │ │ │ │ └── FlickrUtils.java │ │ │ └── resources │ │ │ │ ├── META-INF │ │ │ │ └── services │ │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ │ └── config │ │ │ │ └── flickr.yaml │ │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── datatransferproject │ │ │ └── datatransfer │ │ │ └── flickr │ │ │ ├── FlickrTestUtils.java │ │ │ ├── media │ │ │ └── FlickrMediaImporterTest.java │ │ │ └── photos │ │ │ ├── FlickrPhotosExporterTest.java │ │ │ └── FlickrPhotosImporterTest.java │ ├── portability-data-transfer-generic │ │ ├── README.md │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── datatransfer │ │ │ │ └── generic │ │ │ │ ├── BlobIdToName.java │ │ │ │ ├── BlobbySerializer.java │ │ │ │ ├── CalendarSerializer.java │ │ │ │ ├── ContainerSerializer.java │ │ │ │ ├── GenericFileImporter.java │ │ │ │ ├── GenericImporter.java │ │ │ │ ├── GenericPayload.java │ │ │ │ ├── GenericTransferConstants.java │ │ │ │ ├── GenericTransferExtension.java │ │ │ │ ├── ImportableData.java │ │ │ │ ├── ImportableFileData.java │ │ │ │ ├── MediaSerializer.java │ │ │ │ ├── SocialPostsSerializer.java │ │ │ │ └── auth │ │ │ │ └── OAuthTokenManager.java │ │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── datatransferproject │ │ │ └── datatransfer │ │ │ └── generic │ │ │ ├── BlobIdToNameTest.java │ │ │ ├── BlobbySerializerSimulationTest.java │ │ │ ├── BlobbySerializerTest.java │ │ │ ├── CalendarSerializerTest.java │ │ │ ├── GenericFileImporterTest.java │ │ │ ├── GenericImportSerializerTestBase.java │ │ │ ├── GenericImporterTest.java │ │ │ ├── MediaSerializerTest.java │ │ │ ├── SocialPostsSerializerTest.java │ │ │ └── auth │ │ │ └── OAuthTokenManagerTest.java │ ├── portability-data-transfer-google │ │ ├── Readme.md │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── datatransfer │ │ │ │ │ └── google │ │ │ │ │ ├── BloggerTransferExtension.java │ │ │ │ │ ├── GoogleTransferExtension.java │ │ │ │ │ ├── blogger │ │ │ │ │ └── GoogleBloggerImporter.java │ │ │ │ │ ├── calendar │ │ │ │ │ ├── GoogleCalendarExporter.java │ │ │ │ │ └── GoogleCalendarImporter.java │ │ │ │ │ ├── common │ │ │ │ │ ├── FailedToListAlbumsException.java │ │ │ │ │ ├── FailedToListMediaItemsException.java │ │ │ │ │ ├── GoogleCredentialFactory.java │ │ │ │ │ ├── GoogleErrorLogger.java │ │ │ │ │ ├── GooglePhotosImportUtils.java │ │ │ │ │ ├── GoogleStaticObjects.java │ │ │ │ │ ├── InvalidExportedItemException.java │ │ │ │ │ └── gphotos │ │ │ │ │ │ └── GPhotosUpload.java │ │ │ │ │ ├── contacts │ │ │ │ │ ├── GoogleContactsExporter.java │ │ │ │ │ └── GoogleContactsImporter.java │ │ │ │ │ ├── drive │ │ │ │ │ ├── DriveExporter.java │ │ │ │ │ ├── DriveFolderMapping.java │ │ │ │ │ └── DriveImporter.java │ │ │ │ │ ├── gplus │ │ │ │ │ └── GooglePlusExporter.java │ │ │ │ │ ├── mail │ │ │ │ │ ├── GoogleMailExporter.java │ │ │ │ │ └── GoogleMailImporter.java │ │ │ │ │ ├── media │ │ │ │ │ ├── GoogleMediaExporter.java │ │ │ │ │ └── GoogleMediaImporter.java │ │ │ │ │ ├── mediaModels │ │ │ │ │ ├── AlbumListResponse.java │ │ │ │ │ ├── BatchMediaItemResponse.java │ │ │ │ │ ├── GoogleAlbum.java │ │ │ │ │ ├── GoogleMediaItem.java │ │ │ │ │ ├── MediaItemSearchResponse.java │ │ │ │ │ ├── MediaMetadata.java │ │ │ │ │ ├── NewMediaItem.java │ │ │ │ │ ├── NewMediaItemResult.java │ │ │ │ │ ├── NewMediaItemUpload.java │ │ │ │ │ ├── Photo.java │ │ │ │ │ ├── SimpleMediaItem.java │ │ │ │ │ ├── Status.java │ │ │ │ │ └── Video.java │ │ │ │ │ ├── music │ │ │ │ │ ├── GoogleMusicExporter.java │ │ │ │ │ ├── GoogleMusicHttpApi.java │ │ │ │ │ ├── GoogleMusicImporter.java │ │ │ │ │ └── GooglePlaylistInsertionToken.java │ │ │ │ │ ├── musicModels │ │ │ │ │ ├── BatchPlaylistItemRequest.java │ │ │ │ │ ├── BatchPlaylistItemResponse.java │ │ │ │ │ ├── GoogleArtist.java │ │ │ │ │ ├── GooglePlaylist.java │ │ │ │ │ ├── GooglePlaylistItem.java │ │ │ │ │ ├── GoogleRelease.java │ │ │ │ │ ├── GoogleTrack.java │ │ │ │ │ ├── ImportPlaylistItemRequest.java │ │ │ │ │ ├── ImportPlaylistRequest.java │ │ │ │ │ ├── NewPlaylistItemResult.java │ │ │ │ │ ├── PlaylistExportResponse.java │ │ │ │ │ ├── PlaylistItemExportResponse.java │ │ │ │ │ └── Status.java │ │ │ │ │ ├── package-info.java │ │ │ │ │ ├── photos │ │ │ │ │ ├── GooglePhotosExporter.java │ │ │ │ │ ├── GooglePhotosImporter.java │ │ │ │ │ ├── GooglePhotosInterface.java │ │ │ │ │ └── PhotoResult.java │ │ │ │ │ ├── tasks │ │ │ │ │ ├── GoogleTasksExporter.java │ │ │ │ │ └── GoogleTasksImporter.java │ │ │ │ │ └── videos │ │ │ │ │ ├── GoogleVideosExporter.java │ │ │ │ │ ├── GoogleVideosImporter.java │ │ │ │ │ ├── GoogleVideosInterface.java │ │ │ │ │ └── VideoResult.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ └── test │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── datatransfer │ │ │ │ └── google │ │ │ │ ├── calendar │ │ │ │ ├── GoogleCalendarExporterTest.java │ │ │ │ └── GoogleCalendarImporterTest.java │ │ │ │ ├── common │ │ │ │ └── GoogleErrorLoggerTest.java │ │ │ │ ├── contacts │ │ │ │ ├── GoogleContactsExportConversionTest.java │ │ │ │ ├── GoogleContactsExporterTest.java │ │ │ │ ├── GoogleContactsImportConversionTest.java │ │ │ │ └── GoogleContactsImporterTest.java │ │ │ │ ├── mail │ │ │ │ ├── GoogleMailExporterTest.java │ │ │ │ └── GoogleMailImporterTest.java │ │ │ │ ├── media │ │ │ │ ├── GoogleMediaExporterTest.java │ │ │ │ └── GoogleMediaImporterTest.java │ │ │ │ ├── mediaModels │ │ │ │ ├── AlbumListResponseTest.java │ │ │ │ ├── BatchMediaItemResponseTest.java │ │ │ │ ├── GoogleAlbumTest.java │ │ │ │ ├── GoogleMediaItemTest.java │ │ │ │ ├── MediaItemSearchResponseTest.java │ │ │ │ ├── MediaMetadataTest.java │ │ │ │ ├── PhotoTest.java │ │ │ │ ├── StatusTest.java │ │ │ │ └── VideoTest.java │ │ │ │ ├── music │ │ │ │ ├── GoogleMusicExporterTest.java │ │ │ │ └── GoogleMusicImporterTest.java │ │ │ │ ├── photos │ │ │ │ ├── GooglePhotosExporterTest.java │ │ │ │ ├── GooglePhotosImporterTest.java │ │ │ │ └── PhotoResultSerializationTest.java │ │ │ │ ├── tasks │ │ │ │ └── GoogleTasksExporterTest.java │ │ │ │ └── videos │ │ │ │ ├── GoogleVideosExporterTest.java │ │ │ │ ├── GoogleVideosImporterTest.java │ │ │ │ └── VideoResultSerializationTest.java │ │ │ └── resources │ │ │ └── mockito-extensions │ │ │ └── org.mockito.plugins.MockMaker │ ├── portability-data-transfer-imgur │ │ ├── Readme.md │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── datatransfer │ │ │ │ │ └── imgur │ │ │ │ │ ├── ImgurTransferExtension.java │ │ │ │ │ └── photos │ │ │ │ │ ├── ImgurPhotosExporter.java │ │ │ │ │ └── ImgurPhotosImporter.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ └── test │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── transfer │ │ │ │ └── imgur │ │ │ │ └── photos │ │ │ │ └── ImgurPhotoExporterTest.java │ │ │ └── resources │ │ │ ├── album_1_images.json │ │ │ ├── albums.json │ │ │ ├── all_images.json │ │ │ ├── page1.json │ │ │ └── page2.json │ ├── portability-data-transfer-instagram │ │ ├── Readme.md │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── transfer │ │ │ │ │ └── instagram │ │ │ │ │ ├── InstagramTransferExtension.java │ │ │ │ │ └── photos │ │ │ │ │ ├── InstagramPhotoExporter.java │ │ │ │ │ └── model │ │ │ │ │ ├── Caption.java │ │ │ │ │ ├── ImageData.java │ │ │ │ │ ├── ImageObject.java │ │ │ │ │ ├── MediaFeedData.java │ │ │ │ │ ├── MediaResponse.java │ │ │ │ │ └── Meta.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── datatransferproject │ │ │ └── transfer │ │ │ └── instagram │ │ │ └── photos │ │ │ └── InstagramPhotoExporterTest.java │ ├── portability-data-transfer-koofr │ │ ├── README.md │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── transfer │ │ │ │ │ └── koofr │ │ │ │ │ ├── KoofrTransferExtension.java │ │ │ │ │ ├── KoofrTransmogrificationConfig.java │ │ │ │ │ ├── common │ │ │ │ │ ├── ApiErrorDetails.java │ │ │ │ │ ├── FilesFile.java │ │ │ │ │ ├── FilesListRecursiveItem.java │ │ │ │ │ ├── InputStreamRequestBody.java │ │ │ │ │ ├── KoofrClient.java │ │ │ │ │ ├── KoofrClientFactory.java │ │ │ │ │ ├── KoofrCredentialFactory.java │ │ │ │ │ └── KoofrMediaExport.java │ │ │ │ │ ├── exceptions │ │ │ │ │ └── KoofrClientIOException.java │ │ │ │ │ ├── package-info.java │ │ │ │ │ ├── photos │ │ │ │ │ ├── KoofrPhotosExporter.java │ │ │ │ │ └── KoofrPhotosImporter.java │ │ │ │ │ └── videos │ │ │ │ │ ├── KoofrVideosExporter.java │ │ │ │ │ └── KoofrVideosImporter.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ └── test │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── transfer │ │ │ │ └── koofr │ │ │ │ ├── KoofrTransmogrificationConfigTest.java │ │ │ │ ├── common │ │ │ │ ├── Fixtures.java │ │ │ │ └── KoofrClientTest.java │ │ │ │ ├── photos │ │ │ │ ├── KoofrPhotosExporterTest.java │ │ │ │ └── KoofrPhotosImporterTest.java │ │ │ │ └── videos │ │ │ │ ├── KoofrVideosExporterTest.java │ │ │ │ └── KoofrVideosImporterTest.java │ │ │ └── resources │ │ │ ├── blank.jpg │ │ │ └── listrecursive.jsonl │ ├── portability-data-transfer-mastodon │ │ ├── Readme.md │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── transfer │ │ │ │ └── mastodon │ │ │ │ ├── model │ │ │ │ ├── Account.java │ │ │ │ └── Status.java │ │ │ │ └── social │ │ │ │ ├── MastodonActivityExport.java │ │ │ │ ├── MastodonActivityImport.java │ │ │ │ └── MastodonHttpUtilities.java │ │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── datatransferproject │ │ │ └── transfer │ │ │ └── mastodon │ │ │ └── contacts │ │ │ └── ManualTest.java │ ├── portability-data-transfer-microsoft │ │ ├── Readme.md │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── transfer │ │ │ │ │ └── microsoft │ │ │ │ │ ├── DataChunk.java │ │ │ │ │ ├── MicrosoftApiResponse.java │ │ │ │ │ ├── MicrosoftTransferExtension.java │ │ │ │ │ ├── MicrosoftTransmogrificationConfig.java │ │ │ │ │ ├── StreamChunker.java │ │ │ │ │ ├── calendar │ │ │ │ │ ├── MicrosoftCalendarExporter.java │ │ │ │ │ └── MicrosoftCalendarImporter.java │ │ │ │ │ ├── common │ │ │ │ │ ├── MicrosoftCredentialFactory.java │ │ │ │ │ └── RequestHelper.java │ │ │ │ │ ├── contacts │ │ │ │ │ ├── MicrosoftContactsExporter.java │ │ │ │ │ └── MicrosoftContactsImporter.java │ │ │ │ │ ├── driveModels │ │ │ │ │ ├── MicrosoftDriveFolder.java │ │ │ │ │ ├── MicrosoftDriveItem.java │ │ │ │ │ ├── MicrosoftDriveItemsResponse.java │ │ │ │ │ ├── MicrosoftFileMetadata.java │ │ │ │ │ ├── MicrosoftPhotoMetadata.java │ │ │ │ │ ├── MicrosoftSpecialFolder.java │ │ │ │ │ └── MicrosoftVideoMetadata.java │ │ │ │ │ ├── media │ │ │ │ │ ├── MicrosoftMediaExporter.java │ │ │ │ │ ├── MicrosoftMediaImporter.java │ │ │ │ │ └── MicrosoftMediaInterface.java │ │ │ │ │ ├── offline │ │ │ │ │ └── MicrosoftOfflineDataExporter.java │ │ │ │ │ ├── package-info.java │ │ │ │ │ ├── photos │ │ │ │ │ ├── MicrosoftPhotosExporter.java │ │ │ │ │ ├── MicrosoftPhotosImporter.java │ │ │ │ │ └── MicrosoftPhotosInterface.java │ │ │ │ │ ├── spi │ │ │ │ │ └── types │ │ │ │ │ │ └── MicrosoftOfflineData.java │ │ │ │ │ ├── transformer │ │ │ │ │ ├── TransformConstants.java │ │ │ │ │ ├── TransformResult.java │ │ │ │ │ ├── TransformerContext.java │ │ │ │ │ ├── TransformerService.java │ │ │ │ │ ├── TransformerServiceImpl.java │ │ │ │ │ ├── calendar │ │ │ │ │ │ ├── ToCalendarAttendeeModelTransformer.java │ │ │ │ │ │ ├── ToCalendarEventModelTransformer.java │ │ │ │ │ │ ├── ToCalendarEventTimeTransformer.java │ │ │ │ │ │ ├── ToCalendarModelTransformer.java │ │ │ │ │ │ ├── ToGraphCalendarTransformer.java │ │ │ │ │ │ └── ToGraphEventTransformer.java │ │ │ │ │ ├── common │ │ │ │ │ │ └── TransformerHelper.java │ │ │ │ │ └── contacts │ │ │ │ │ │ ├── ToGraphAddressTransformer.java │ │ │ │ │ │ ├── ToGraphContactTransformer.java │ │ │ │ │ │ ├── ToVCardAddressTransformer.java │ │ │ │ │ │ └── ToVCardTransformer.java │ │ │ │ │ └── types │ │ │ │ │ └── GraphPagination.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── datatransferproject │ │ │ └── transfer │ │ │ └── microsoft │ │ │ ├── MicrosoftApiResponseTest.java │ │ │ ├── StreamChunkerTest.java │ │ │ ├── helper │ │ │ ├── MockJobStore.java │ │ │ └── TestTransformerContext.java │ │ │ ├── integration │ │ │ ├── LocalExportTestRunner.java │ │ │ ├── LocalImportTestRunner.java │ │ │ ├── MicrosoftCalendarExportTest.java │ │ │ └── MicrosoftCalendarImportTest.java │ │ │ ├── media │ │ │ ├── MicrosoftMediaExporterTest.java │ │ │ └── MicrosoftMediaImporterTest.java │ │ │ ├── photos │ │ │ ├── MicrosoftPhotosExporterTest.java │ │ │ └── MicrosoftPhotosImporterTest.java │ │ │ └── transformer │ │ │ └── calendar │ │ │ ├── ToCalendarAttendeeModelTransformerTest.java │ │ │ ├── ToCalendarEventModelTransformerTest.java │ │ │ ├── ToCalendarEventTimeTransformerTest.java │ │ │ └── ToCalendarModelTransformerTest.java │ ├── portability-data-transfer-offline-demo │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── transfer │ │ │ │ └── offline │ │ │ │ ├── OfflineDemoImporter.java │ │ │ │ └── OfflineDemoTransferExtension.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ ├── portability-data-transfer-rememberthemilk │ │ ├── Readme.md │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── transfer │ │ │ │ │ └── rememberthemilk │ │ │ │ │ ├── RememberTheMilkTransferExtension.java │ │ │ │ │ ├── model │ │ │ │ │ └── tasks │ │ │ │ │ │ ├── Error.java │ │ │ │ │ │ ├── GetListResponse.java │ │ │ │ │ │ ├── GetListsResponse.java │ │ │ │ │ │ ├── ListAddResponse.java │ │ │ │ │ │ ├── ListInfo.java │ │ │ │ │ │ ├── Notes.java │ │ │ │ │ │ ├── RememberTheMilkResponse.java │ │ │ │ │ │ ├── Task.java │ │ │ │ │ │ ├── TaskList.java │ │ │ │ │ │ ├── TaskSeries.java │ │ │ │ │ │ ├── TaskUpdateResponse.java │ │ │ │ │ │ ├── Tasks.java │ │ │ │ │ │ ├── TimelineCreateResponse.java │ │ │ │ │ │ └── Transaction.java │ │ │ │ │ └── tasks │ │ │ │ │ ├── RememberTheMilkService.java │ │ │ │ │ ├── RememberTheMilkSignatureGenerator.java │ │ │ │ │ ├── RememberTheMilkTasksExporter.java │ │ │ │ │ └── RememberTheMilkTasksImporter.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── datatransferproject │ │ │ └── transfer │ │ │ └── rememberthemilk │ │ │ ├── model │ │ │ └── tasks │ │ │ │ └── ModelTest.java │ │ │ └── tasks │ │ │ └── RememberTheMilkSignatureGeneratorTest.java │ ├── portability-data-transfer-smugmug │ │ ├── Readme.md │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── datatransferproject │ │ │ │ │ └── transfer │ │ │ │ │ └── smugmug │ │ │ │ │ ├── SmugMugInterface.java │ │ │ │ │ ├── SmugMugTransferExtension.java │ │ │ │ │ ├── SmugMugTransmogrificationConfig.java │ │ │ │ │ ├── media │ │ │ │ │ └── SmugMugMediaImporter.java │ │ │ │ │ └── photos │ │ │ │ │ ├── SmugMugOauthApi.java │ │ │ │ │ ├── SmugMugPhotoTempData.java │ │ │ │ │ ├── SmugMugPhotosExporter.java │ │ │ │ │ ├── SmugMugPhotosImporter.java │ │ │ │ │ └── model │ │ │ │ │ ├── SmugMugAlbum.java │ │ │ │ │ ├── SmugMugAlbumImageResponse.java │ │ │ │ │ ├── SmugMugAlbumInfoResponse.java │ │ │ │ │ ├── SmugMugAlbumResponse.java │ │ │ │ │ ├── SmugMugAlbumsResponse.java │ │ │ │ │ ├── SmugMugImage.java │ │ │ │ │ ├── SmugMugImageUploadResponse.java │ │ │ │ │ ├── SmugMugPageInfo.java │ │ │ │ │ ├── SmugMugResponse.java │ │ │ │ │ ├── SmugMugUrl.java │ │ │ │ │ ├── SmugMugUser.java │ │ │ │ │ └── SmugMugUserResponse.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── datatransferproject │ │ │ └── transfer │ │ │ └── smugmug │ │ │ ├── media │ │ │ └── SmugMugMediaImporterTest.java │ │ │ └── photos │ │ │ ├── SmugMugInterfaceTest.java │ │ │ └── SmugMugPhotosImporterTest.java │ ├── portability-data-transfer-spotify │ │ ├── Readme.md │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── transfer │ │ │ │ └── spotify │ │ │ │ ├── SpotifyTransferExtension.java │ │ │ │ └── playlists │ │ │ │ ├── SpotifyPlaylistExporter.java │ │ │ │ └── SpotifyPlaylistImporter.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension │ └── portability-data-transfer-twitter │ │ ├── Readme.md │ │ ├── build.gradle │ │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── datatransferproject │ │ │ └── transfer │ │ │ └── twitter │ │ │ ├── TwitterApiWrapper.java │ │ │ ├── TwitterPhotosExporter.java │ │ │ ├── TwitterPhotosImporter.java │ │ │ └── TwitterTransferExtension.java │ │ └── resources │ │ └── META-INF │ │ └── services │ │ └── org.datatransferproject.spi.transfer.extension.TransferExtension ├── security │ ├── portability-security-cleartext │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── datatransferproject │ │ │ │ └── security │ │ │ │ └── cleartext │ │ │ │ ├── ClearTextAuthDataDecryptService.java │ │ │ │ ├── ClearTextKeyGenerator.java │ │ │ │ ├── ClearTextPublicKeySerializer.java │ │ │ │ └── ClearTextSecurityExtension.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── org.datatransferproject.spi.transfer.security.SecurityExtension │ └── portability-security-jwe │ │ ├── build.gradle │ │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── datatransferproject │ │ │ └── security │ │ │ └── jwe │ │ │ ├── JWEAuthDataDecryptService.java │ │ │ ├── JWEKeyGenerator.java │ │ │ ├── JWEPublicKeySerializer.java │ │ │ └── JWESecurityExtension.java │ │ └── resources │ │ └── META-INF │ │ └── services │ │ └── org.datatransferproject.spi.transfer.security.SecurityExtension └── transport │ └── portability-transport-jettyrest │ ├── build.gradle │ └── src │ └── main │ ├── java │ └── org │ │ └── datatransferproject │ │ └── transport │ │ └── jettyrest │ │ ├── JettyRestExtension.java │ │ ├── http │ │ ├── JettyMonitor.java │ │ └── JettyTransport.java │ │ └── rest │ │ ├── DataTypesController.java │ │ ├── JerseyTransportBinder.java │ │ ├── RESTConstants.java │ │ ├── TransferController.java │ │ └── TransferServicesController.java │ └── resources │ └── META-INF │ └── services │ └── org.datatransferproject.spi.service.extension.ServiceExtension ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── libraries ├── README.md ├── auth │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── datatransferproject │ │ └── auth │ │ ├── OAuth1Config.java │ │ ├── OAuth1DataGenerator.java │ │ ├── OAuth1ServiceExtension.java │ │ ├── OAuth2Config.java │ │ ├── OAuth2DataGenerator.java │ │ ├── OAuth2ServiceExtension.java │ │ ├── OAuth2TokenResponse.java │ │ └── OAuthUtils.java ├── config │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── datatransferproject │ │ └── config │ │ ├── ConfigUtils.java │ │ ├── FlagBindingModule.java │ │ └── extension │ │ ├── SettingsExtension.java │ │ └── SettingsExtensionLoader.java └── security │ ├── build.gradle │ └── src │ └── main │ └── java │ └── org │ └── datatransferproject │ └── security │ ├── AesSymmetricKeyGenerator.java │ ├── CryptoTransformation.java │ ├── Decrypter.java │ ├── DecrypterFactory.java │ ├── DecrypterImpl.java │ ├── Encrypter.java │ ├── EncrypterFactory.java │ ├── EncrypterImpl.java │ └── SymmetricKeyGenerator.java ├── package-lock.json ├── portability-api-launcher ├── build.gradle └── src │ └── main │ └── java │ └── org │ └── datatransferproject │ ├── api │ └── launcher │ │ ├── AbstractExtension.java │ │ ├── BootExtension.java │ │ ├── Constants.java │ │ ├── DelegatingExtensionContext.java │ │ ├── DtpInternalMetricRecorder.java │ │ ├── ExtensionContext.java │ │ ├── Flag.java │ │ ├── JobAwareMonitor.java │ │ ├── MetricRecorder.java │ │ ├── Monitor.java │ │ ├── MonitorExtension.java │ │ ├── SystemExtension.java │ │ ├── TypeManager.java │ │ └── Version.java │ └── launcher │ ├── metrics │ ├── LoggingDtpInternalMetricRecorder.java │ └── ServiceAwareMetricRecorder.java │ ├── monitor │ ├── ConsoleMonitor.java │ ├── MonitorLoader.java │ ├── MultiplexMonitor.java │ └── events │ │ └── EventCode.java │ └── types │ └── TypeManagerImpl.java ├── portability-api ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── datatransferproject │ │ └── api │ │ ├── ApiExtensionContext.java │ │ ├── ApiMain.java │ │ ├── ApiServicesModule.java │ │ ├── action │ │ ├── ActionUtils.java │ │ ├── datatype │ │ │ └── DataTypesAction.java │ │ └── transfer │ │ │ ├── CreateTransferJobAction.java │ │ │ ├── GenerateServiceAuthDataAction.java │ │ │ ├── GetReservedWorkerAction.java │ │ │ ├── GetTransferJobAction.java │ │ │ ├── GetTransferServicesAction.java │ │ │ ├── ReserveWorkerAction.java │ │ │ ├── StartTransferJobAction.java │ │ │ └── TransferServicesActionModule.java │ │ ├── auth │ │ └── PortabilityAuthServiceProviderRegistry.java │ │ ├── package-info.java │ │ └── token │ │ └── JWTTokenManager.java │ └── test │ └── java │ └── org │ └── datatransferproject │ └── api │ ├── action │ └── datatype │ │ └── DataTypesActionTest.java │ └── auth │ └── PortabilityAuthServiceExtensionRegistryTest.java ├── portability-bootstrap-vm ├── build.gradle └── src │ └── main │ └── java │ └── org │ └── datatransferproject │ └── bootstrap │ └── vm │ └── SingleVMMain.java ├── portability-spi-api ├── README.md ├── build.gradle └── src │ └── main │ └── java │ └── org │ └── datatransferproject │ ├── api │ └── action │ │ └── Action.java │ └── spi │ └── api │ ├── auth │ ├── AuthDataGenerator.java │ ├── AuthServiceProviderRegistry.java │ └── extension │ │ └── AuthServiceExtension.java │ ├── package-info.java │ ├── token │ └── TokenManager.java │ ├── transport │ ├── DiscardingStreamCounter.java │ ├── FileStreamer.java │ ├── JobFileStream.java │ ├── RemoteFileStreamer.java │ ├── TransportBinder.java │ └── UrlGetStreamer.java │ └── types │ └── AuthFlowConfiguration.java ├── portability-spi-cloud ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── datatransferproject │ │ └── spi │ │ └── cloud │ │ ├── connection │ │ └── ConnectionProvider.java │ │ ├── extension │ │ ├── CloudExtension.java │ │ ├── CloudExtensionLoader.java │ │ └── CloudExtensionModule.java │ │ ├── package-info.java │ │ ├── storage │ │ ├── AppCredentialStore.java │ │ ├── CryptoKeyStore.java │ │ ├── JobStore.java │ │ ├── JobStoreWithValidator.java │ │ └── TemporaryPerJobDataStore.java │ │ └── types │ │ ├── JobAuthorization.java │ │ └── PortabilityJob.java │ └── test │ └── java │ └── org │ └── datatransferproject │ └── spi │ └── cloud │ ├── connection │ └── ConnectionProviderTest.java │ └── types │ └── PortabilityJobTest.java ├── portability-spi-service ├── build.gradle └── src │ └── main │ └── java │ └── org │ └── datatransferproject │ └── spi │ └── service │ └── extension │ └── ServiceExtension.java ├── portability-spi-transfer ├── README.md ├── build.gradle └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── datatransferproject │ │ │ └── spi │ │ │ └── transfer │ │ │ ├── extension │ │ │ └── TransferExtension.java │ │ │ ├── hooks │ │ │ ├── DefaultJobHooks.java │ │ │ ├── JobHooks.java │ │ │ ├── JobHooksExtension.java │ │ │ ├── JobHooksLoader.java │ │ │ └── MultiplexJobHooks.java │ │ │ ├── i18n │ │ │ ├── AbstractMultilingualDictionary.java │ │ │ ├── BaseMultilingualDictionary.java │ │ │ ├── BaseMultilingualString.java │ │ │ └── MultilingualString.java │ │ │ ├── idempotentexecutor │ │ │ ├── CachingExecutor.java │ │ │ ├── IdempotentImportExecutor.java │ │ │ ├── IdempotentImportExecutorExtension.java │ │ │ ├── IdempotentImportExecutorLoader.java │ │ │ ├── ImportFunction.java │ │ │ ├── InMemoryIdempotentImportExecutor.java │ │ │ ├── InMemoryIdempotentImportExecutorExtension.java │ │ │ ├── ItemImportResult.java │ │ │ └── RetryingInMemoryIdempotentImportExecutor.java │ │ │ ├── package-info.java │ │ │ ├── provider │ │ │ ├── ExportResult.java │ │ │ ├── Exporter.java │ │ │ ├── ImportResult.java │ │ │ ├── Importer.java │ │ │ ├── SignalHandler.java │ │ │ ├── SignalRequest.java │ │ │ ├── TransferCompatibilityProvider.java │ │ │ └── converter │ │ │ │ ├── AnyToAnyExporter.java │ │ │ │ ├── AnyToAnyImporter.java │ │ │ │ ├── MediaExporterDecorator.java │ │ │ │ └── MediaImporterDecorator.java │ │ │ ├── security │ │ │ ├── AuthDataDecryptService.java │ │ │ ├── PublicKeySerializer.java │ │ │ ├── SecurityException.java │ │ │ ├── SecurityExtension.java │ │ │ ├── SecurityExtensionLoader.java │ │ │ └── TransferKeyGenerator.java │ │ │ ├── store │ │ │ └── TransferStore.java │ │ │ └── types │ │ │ ├── ContinuationData.java │ │ │ ├── CopyException.java │ │ │ ├── CopyExceptionWithFailureReason.java │ │ │ ├── DestinationMemoryFullException.java │ │ │ ├── DestinationNotFoundException.java │ │ │ ├── FailureReasons.java │ │ │ ├── IdOnlyResource.java │ │ │ ├── InvalidTokenException.java │ │ │ ├── PermissionDeniedException.java │ │ │ ├── SessionInvalidatedException.java │ │ │ ├── TempMediaData.java │ │ │ ├── UnconfirmedUserException.java │ │ │ ├── UploadErrorException.java │ │ │ ├── UpstreamApiUnexpectedResponseException.java │ │ │ ├── UserCheckpointedException.java │ │ │ └── signals │ │ │ └── JobLifeCycle.java │ └── resources │ │ ├── MultilingualStringsBundle.properties │ │ ├── MultilingualStringsBundle_ar.properties │ │ ├── MultilingualStringsBundle_cs.properties │ │ ├── MultilingualStringsBundle_de.properties │ │ ├── MultilingualStringsBundle_el.properties │ │ ├── MultilingualStringsBundle_es.properties │ │ ├── MultilingualStringsBundle_fr.properties │ │ ├── MultilingualStringsBundle_id.properties │ │ ├── MultilingualStringsBundle_it.properties │ │ ├── MultilingualStringsBundle_ja.properties │ │ ├── MultilingualStringsBundle_ms.properties │ │ ├── MultilingualStringsBundle_pt.properties │ │ ├── MultilingualStringsBundle_ru.properties │ │ ├── MultilingualStringsBundle_sk.properties │ │ ├── MultilingualStringsBundle_tl.properties │ │ ├── MultilingualStringsBundle_uk.properties │ │ └── MultilingualStringsBundle_zh.properties │ └── test │ └── java │ └── org │ └── datatransferproject │ └── spi │ └── transfer │ ├── i18n │ └── MultilingualDictionaryTest.java │ ├── idempotentexecutor │ ├── ItemImportResultTest.java │ └── RetryingInMemoryIdempotentImporterExecutorTest.java │ ├── provider │ ├── ExportResultTest.java │ ├── ImportResultTest.java │ ├── TransferCompatibilityProviderTest.java │ └── converter │ │ ├── AnyToAnyExporterTest.java │ │ ├── AnyToAnyImporterTest.java │ │ ├── MediaExporterDecoratorTest.java │ │ └── MediaImporterDecoratorTest.java │ └── types │ └── ContinuationDataTest.java ├── portability-test-utilities ├── build.gradle └── src │ └── main │ └── java │ └── org │ └── datatransferproject │ └── test │ └── types │ ├── FakeIdempotentImportExecutor.java │ └── ObjectMapperFactory.java ├── portability-transfer ├── README.md ├── build.gradle ├── settings.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── datatransferproject │ │ └── transfer │ │ ├── Annotations.java │ │ ├── CallableExporter.java │ │ ├── CallableImporter.java │ │ ├── CallableSizeCalculator.java │ │ ├── CredsTimeoutException.java │ │ ├── JobCancelWatchingService.java │ │ ├── JobMetadata.java │ │ ├── JobPoller.java │ │ ├── JobPollingService.java │ │ ├── JobProcessor.java │ │ ├── Worker.java │ │ ├── WorkerExtensionContext.java │ │ ├── WorkerMain.java │ │ ├── WorkerModule.java │ │ └── copier │ │ ├── InMemoryDataCopier.java │ │ ├── InMemoryDataCopierClassLoader.java │ │ ├── InMemoryDataCopierExtension.java │ │ ├── PortabilityAbstractInMemoryDataCopier.java │ │ └── PortabilityInMemoryDataCopier.java │ └── test │ └── java │ └── org │ └── datatransferproject │ └── transfer │ ├── CallableSizeCalculatorTest.java │ ├── JobPollingServiceTest.java │ ├── JobProcessorTest.java │ ├── WorkerModuleTest.java │ └── copier │ └── PortabilityInMemoryDataCopierTest.java ├── portability-types-client ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── datatransferproject │ │ └── types │ │ └── client │ │ ├── datatype │ │ ├── DataTypes.java │ │ └── GetDataTypes.java │ │ ├── package-info.java │ │ └── transfer │ │ ├── CreateTransferJob.java │ │ ├── GenerateServiceAuthData.java │ │ ├── GetReservedWorker.java │ │ ├── GetTransferJob.java │ │ ├── GetTransferServices.java │ │ ├── ReserveWorker.java │ │ ├── ReservedWorker.java │ │ ├── ServiceAuthData.java │ │ ├── StartTransferJob.java │ │ ├── TransferJob.java │ │ └── TransferServices.java │ └── test │ └── java │ └── org │ └── datatransferproject │ └── types │ └── client │ └── transfer │ ├── CreateTransferJobTest.java │ └── TransferJobTest.java ├── portability-types-common ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── datatransferproject │ │ └── types │ │ └── common │ │ ├── DownloadableFile.java │ │ ├── DownloadableItem.java │ │ ├── ExportInformation.java │ │ ├── Fileable.java │ │ ├── FolderItem.java │ │ ├── ImportableItem.java │ │ ├── IntPaginationToken.java │ │ ├── PaginationData.java │ │ ├── PortabilityCommon.java │ │ ├── PortableType.java │ │ ├── StringPaginationToken.java │ │ └── models │ │ ├── ContainerResource.java │ │ ├── CreativeWork.java │ │ ├── DataModel.java │ │ ├── DataVertical.java │ │ ├── DateRangeContainerResource.java │ │ ├── FavoriteInfo.java │ │ ├── IdOnlyContainerResource.java │ │ ├── ItemResource.java │ │ ├── MediaObject.java │ │ ├── README.md │ │ ├── Thing.java │ │ ├── TransmogrificationConfig.java │ │ ├── blob │ │ ├── BlobbyStorageContainerResource.java │ │ ├── DigitalDocumentWrapper.java │ │ └── DtpDigitalDocument.java │ │ ├── calendar │ │ ├── CalendarAttendeeModel.java │ │ ├── CalendarContainerResource.java │ │ ├── CalendarEventModel.java │ │ ├── CalendarModel.java │ │ ├── Property.java │ │ └── RecurrenceRule.java │ │ ├── contacts │ │ └── ContactsModelWrapper.java │ │ ├── mail │ │ ├── MailContainerModel.java │ │ ├── MailContainerResource.java │ │ └── MailMessageModel.java │ │ ├── media │ │ ├── MediaAlbum.java │ │ └── MediaContainerResource.java │ │ ├── music │ │ ├── MusicContainerResource.java │ │ ├── MusicGroup.java │ │ ├── MusicPlaylist.java │ │ ├── MusicPlaylistItem.java │ │ ├── MusicRecording.java │ │ └── MusicRelease.java │ │ ├── photos │ │ ├── PhotoAlbum.java │ │ ├── PhotoModel.java │ │ └── PhotosContainerResource.java │ │ ├── playlists │ │ ├── CreativeWork.java │ │ ├── MusicAlbum.java │ │ ├── MusicGroup.java │ │ ├── MusicPlaylist.java │ │ ├── MusicRecording.java │ │ └── PlaylistContainerResource.java │ │ ├── social │ │ ├── SocialActivityActor.java │ │ ├── SocialActivityAttachment.java │ │ ├── SocialActivityAttachmentType.java │ │ ├── SocialActivityContainerResource.java │ │ ├── SocialActivityLocation.java │ │ ├── SocialActivityModel.java │ │ └── SocialActivityType.java │ │ ├── tasks │ │ ├── TaskContainerResource.java │ │ ├── TaskListModel.java │ │ └── TaskModel.java │ │ └── videos │ │ ├── VideoAlbum.java │ │ ├── VideoModel.java │ │ └── VideosContainerResource.java │ └── test │ └── java │ └── org │ └── datatransferproject │ └── types │ └── common │ └── models │ ├── DataVerticalTest.java │ ├── DateRangeContainerResourceTest.java │ ├── blob │ └── BlobbyStorageContainerResourceTest.java │ ├── calendar │ └── CalendarContainerResourceTest.java │ ├── mail │ └── MailContainerResourceTest.java │ ├── media │ └── MediaContainerResourceTest.java │ ├── music │ └── MusicContainerResourceTest.java │ ├── photos │ ├── PhotoAlbumTest.java │ └── PhotosContainerResourceTest.java │ ├── social │ └── SocialActivityContainerResourceTest.java │ ├── tasks │ └── TaskContainerResourceTest.java │ └── videos │ └── VideosContainerResourceTest.java ├── portability-types-transfer ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── datatransferproject │ │ └── types │ │ └── transfer │ │ ├── auth │ │ ├── AppCredentials.java │ │ ├── AuthData.java │ │ ├── AuthDataPair.java │ │ ├── CookiesAndUrlAuthData.java │ │ ├── TokenAuthData.java │ │ ├── TokenSecretAuthData.java │ │ └── TokensAndUrlAuthData.java │ │ ├── errors │ │ └── ErrorDetail.java │ │ ├── package-info.java │ │ ├── retry │ │ ├── ExponentialBackoffSkipStrategy.java │ │ ├── ExponentialBackoffStrategy.java │ │ ├── NoRetryStrategy.java │ │ ├── RetryException.java │ │ ├── RetryMapping.java │ │ ├── RetryStrategy.java │ │ ├── RetryStrategyLibrary.java │ │ ├── RetryingCallable.java │ │ ├── SkipRetryStrategy.java │ │ ├── UniformRetrySkipStrategy.java │ │ └── UniformRetryStrategy.java │ │ └── serviceconfig │ │ ├── TransferServiceConfig.java │ │ └── TransferServiceConfigSpecification.java │ └── test │ └── java │ └── org │ └── datatransferproject │ └── types │ └── transfer │ └── auth │ └── AuthDataSerializationTest.java ├── scripts └── docker_push.sh └── settings.gradle /.cz.toml: -------------------------------------------------------------------------------- 1 | [tool.commitizen] 2 | name = "cz_conventional_commits" 3 | tag_format = "v$version" 4 | version_scheme = "semver" 5 | version_provider = "scm" 6 | update_changelog_on_bump = false 7 | changelog_start_rev = "v1.0.0" 8 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.c text 7 | *.h text 8 | *.java text 9 | *.gradle text 10 | *.properties text 11 | *.gradle text 12 | 13 | # Declare files that will always have CRLF line endings on checkout. 14 | *.sln text eol=crlf 15 | 16 | # Denote all files that are truly binary and should not be modified. 17 | *.png binary 18 | *.jpg binary 19 | 20 | package-lock.json -diff -merge 21 | package-lock.json linguist-generated=true 22 | 23 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | # Always increase the version requirement 8 | # to match the new version. 9 | versioning-strategy: increase 10 | commit-message: 11 | prefix: "fix" 12 | prefix-development: "build" 13 | include: "scope" 14 | -------------------------------------------------------------------------------- /.github/workflows/commitlint.yml: -------------------------------------------------------------------------------- 1 | name: Lint PR Title 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize, edited] 6 | 7 | jobs: 8 | commitlint: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - name: "Install commitizen" 13 | run: pip install --user -U commitizen 14 | - name: "Lint the PR title" 15 | env: 16 | TITLE: ${{ github.event.pull_request.title }} 17 | run: cz check --message "${TITLE}" || { echo "see https://github.com/dtinit/data-transfer-project/blob/master/Documentation/Publishing.md#semantic-versioning-and-conventional-commits" >&2; exit 1; } 18 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: Java CI with Gradle 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Set up JDK 11 20 | uses: actions/setup-java@v4 21 | with: 22 | java-version: '11' 23 | distribution: 'adopt' 24 | cache: gradle 25 | - name: Grant execute permission for gradlew 26 | run: chmod +x gradlew 27 | - name: Build and Test with Gradle 28 | run: ./gradlew build test 29 | -------------------------------------------------------------------------------- /Documentation/README.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | This folder contains documentation for contributing to and running the Data Transfer Project. 4 | 5 | * [Overview.md](Overview.md) - a high level summary of the project 6 | 7 | * [Developer.md](Developer.md) - developer setup and core framework development 8 | 9 | * [RunningLocally.md](RunningLocally.md) - a quick start to running DTP locally with our demo Docker image 10 | 11 | * [Integration.md](Integration.md) - integrating a new service, data type, and/or hosting platform 12 | 13 | * [Keys.md](Keys.md) - our philosophy for how DTP interacts with service provider APIs 14 | 15 | * [Glossary.md](Glossary.md) - a glossary of recommended terms to use in DTP UIs 16 | -------------------------------------------------------------------------------- /client-rest/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './src/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome', 13 | chromeOptions: { 14 | args: ["--disable-dev-shm-usage", "--headless", "--disable-gpu", "--no-sandbox", "--disable-extensions"] 15 | } 16 | }, 17 | directConnect: true, 18 | baseUrl: 'http://localhost:4200/', 19 | framework: 'jasmine', 20 | jasmineNodeOpts: { 21 | showColors: true, 22 | defaultTimeoutInterval: 30000, 23 | print: function() {} 24 | }, 25 | onPrepare() { 26 | require('ts-node').register({ 27 | project: require('path').join(__dirname, './tsconfig.e2e.json') 28 | }); 29 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /client-rest/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('workspace-project App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('Data Transfer Project Demo'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /client-rest/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h3')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /client-rest/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /client-rest/proxy.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "/api/*": { 3 | "target": "https://localhost:8080/", 4 | "secure": false, 5 | "logLevel": "debug" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /client-rest/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |
{@link FailureReasons} is intended to assist in keeping implementations of this class 10 | * accessible. 11 | * 12 | *
Note if an exception case is needed to express multiple classes of distinct failuiure cases, 13 | * then deriving from {@link CopyException} instead is probably better. 14 | */ 15 | public abstract class CopyExceptionWithFailureReason extends CopyException { 16 | 17 | public CopyExceptionWithFailureReason(String message, Throwable cause) { 18 | super(message, cause); 19 | } 20 | 21 | @Nonnull 22 | public abstract String getFailureReason(); 23 | } 24 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/java/org/datatransferproject/spi/transfer/types/FailureReasons.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.spi.transfer.types; 2 | 3 | public enum FailureReasons { 4 | CREDS_TIMEOUT("CREDS_TIMEOUT"), 5 | DESTINATION_FULL("DESTINATION_FULL"), 6 | INVALID_TOKEN("INVALID_TOKEN"), 7 | PERMISSION_DENIED("PERMISSION_DENIED"), 8 | SESSION_INVALIDATED("SESSION_INVALIDATED"), 9 | UNCONFIRMED_USER("UNCONFIRMED_USER"), 10 | UPLOAD_ERROR("UPLOAD_ERROR"), 11 | USER_CHECKPOINTED("USER_CHECKPOINTED"), 12 | DESTINATION_NOT_FOUND("DESTINATION_NOT_FOUND"), 13 | UPSTREAM_API_UNEXPECTED_RESPONSE_EXCEPTION("UPSTREAM_API_UNEXPECTED_RESPONSE_EXCEPTION"); 14 | private final String string; 15 | 16 | FailureReasons(String string) { 17 | this.string = string; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return string; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/java/org/datatransferproject/spi/transfer/types/InvalidTokenException.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.spi.transfer.types; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | public class InvalidTokenException extends CopyExceptionWithFailureReason { 6 | 7 | public InvalidTokenException(String message, Throwable cause) { 8 | super(message, cause); 9 | } 10 | 11 | @Nonnull 12 | @Override 13 | public String getFailureReason() { 14 | return FailureReasons.INVALID_TOKEN.toString(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/java/org/datatransferproject/spi/transfer/types/PermissionDeniedException.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.spi.transfer.types; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | public class PermissionDeniedException extends CopyExceptionWithFailureReason { 6 | 7 | public PermissionDeniedException(String message, Throwable cause) { 8 | super(message, cause); 9 | } 10 | 11 | @Nonnull 12 | @Override 13 | public String getFailureReason() { 14 | return FailureReasons.PERMISSION_DENIED.toString(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/java/org/datatransferproject/spi/transfer/types/SessionInvalidatedException.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.spi.transfer.types; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | public class SessionInvalidatedException extends CopyExceptionWithFailureReason { 6 | 7 | public SessionInvalidatedException(String message, Throwable cause) { 8 | super(message, cause); 9 | } 10 | 11 | @Nonnull 12 | @Override 13 | public String getFailureReason() { 14 | return FailureReasons.SESSION_INVALIDATED.toString(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/java/org/datatransferproject/spi/transfer/types/UnconfirmedUserException.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.spi.transfer.types; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | public class UnconfirmedUserException extends CopyExceptionWithFailureReason { 6 | 7 | public UnconfirmedUserException(String message, Throwable cause) { 8 | super(message, cause); 9 | } 10 | 11 | @Nonnull 12 | @Override 13 | public String getFailureReason() { 14 | return FailureReasons.UNCONFIRMED_USER.toString(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/java/org/datatransferproject/spi/transfer/types/UploadErrorException.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.spi.transfer.types; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | public class UploadErrorException extends CopyExceptionWithFailureReason { 6 | 7 | public UploadErrorException(String message, Throwable cause) { 8 | super(message, cause); 9 | } 10 | 11 | @Nonnull 12 | @Override 13 | public String getFailureReason() { 14 | return FailureReasons.UPLOAD_ERROR.toString(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/java/org/datatransferproject/spi/transfer/types/UpstreamApiUnexpectedResponseException.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.spi.transfer.types; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | public class UpstreamApiUnexpectedResponseException extends CopyExceptionWithFailureReason { 6 | 7 | public UpstreamApiUnexpectedResponseException(String message, Throwable cause) { 8 | super(message, cause); 9 | } 10 | 11 | @Nonnull 12 | @Override 13 | public String getFailureReason() { 14 | return FailureReasons.UPSTREAM_API_UNEXPECTED_RESPONSE_EXCEPTION.toString(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/java/org/datatransferproject/spi/transfer/types/UserCheckpointedException.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.spi.transfer.types; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | public class UserCheckpointedException extends CopyExceptionWithFailureReason { 6 | 7 | public UserCheckpointedException(String message, Throwable cause) { 8 | super(message, cause); 9 | } 10 | 11 | @Nonnull 12 | @Override 13 | public String getFailureReason() { 14 | return FailureReasons.USER_CHECKPOINTED.toString(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=Copy of {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_ar.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=\u0646\u0633\u062E\u0629 \u0645\u0646 {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_cs.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=Kopie {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_de.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=Kopie von {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_el.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=\u0391\u03BD\u03C4\u03AF\u03B3\u03C1\u03B1\u03C6\u03BF {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_es.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=Copia de {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_fr.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=Texte de {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_id.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=Teks {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_it.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=Copia di {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_ja.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof={0}\u306E\u30B3\u30D4\u30FC 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_ms.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=Salinan {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_pt.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=Copy de {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_ru.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=\u041A\u043E\u043F\u0438\u044F {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_sk.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=K\u00F3pia s\u00FAboru {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_tl.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=Kopya ng {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_uk.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof=\u041A\u043E\u043F\u0456\u044F {0} 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/main/resources/MultilingualStringsBundle_zh.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021 The Data Transfer Project Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | copyof={0}\u526F\u672C 17 | -------------------------------------------------------------------------------- /portability-spi-transfer/src/test/java/org/datatransferproject/spi/transfer/provider/ExportResultTest.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.spi.transfer.provider; 2 | 3 | import static org.datatransferproject.spi.transfer.provider.ExportResult.ResultType.CONTINUE; 4 | import static org.datatransferproject.spi.transfer.provider.ExportResult.ResultType.END; 5 | import static org.datatransferproject.spi.transfer.provider.ExportResult.ResultType.ERROR; 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | 8 | import org.datatransferproject.spi.transfer.provider.ExportResult.ResultType; 9 | import org.junit.jupiter.api.Test; 10 | 11 | public class ExportResultTest { 12 | 13 | @Test 14 | public void resultTypeMerge() { 15 | assertEquals(ERROR, ResultType.merge(ERROR, END)); 16 | assertEquals(ERROR, ResultType.merge(END, ERROR)); 17 | assertEquals(CONTINUE, ResultType.merge(END, CONTINUE)); 18 | assertEquals(CONTINUE, ResultType.merge(CONTINUE, END)); 19 | assertEquals(END, ResultType.merge(END, END)); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /portability-test-utilities/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 The Data Transfer Project Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | dependencies { 19 | compile project(':portability-spi-transfer') 20 | } 21 | -------------------------------------------------------------------------------- /portability-test-utilities/src/main/java/org/datatransferproject/test/types/FakeIdempotentImportExecutor.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.test.types; 2 | 3 | import org.datatransferproject.api.launcher.Monitor; 4 | import org.datatransferproject.spi.transfer.idempotentexecutor.InMemoryIdempotentImportExecutor; 5 | 6 | /** Unit-test friendly, fully-functional IdempotentImportExecutor, entirely in memory. */ 7 | // TODO migrate tests constructing InMemoryIdempotentImportExecutor to this class to avoid future 8 | // noise where we have to touch every test (should InMemoryIdempotentImportExecutor start doing 9 | // something unfriendly to tests). 10 | public class FakeIdempotentImportExecutor extends InMemoryIdempotentImportExecutor { 11 | // TODO figure out how to get Gradle to let us mock(Monitor.class) ourselves here? 12 | private static final Monitor fakeMonitor = new Monitor() {}; 13 | 14 | public FakeIdempotentImportExecutor() { 15 | super(FakeIdempotentImportExecutor.fakeMonitor); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /portability-test-utilities/src/main/java/org/datatransferproject/test/types/ObjectMapperFactory.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.test.types; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 5 | 6 | /** */ 7 | public final class ObjectMapperFactory { 8 | 9 | private ObjectMapperFactory() {} 10 | 11 | public static ObjectMapper createObjectMapper() { 12 | ObjectMapper objectMapper = new ObjectMapper(); 13 | objectMapper.registerModule(new JavaTimeModule()); 14 | return objectMapper; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /portability-transfer/README.md: -------------------------------------------------------------------------------- 1 | # portability-transfer 2 | 3 | This folder contains the binary for the Worker server used by DTP. 4 | 5 | DTP has two servers: the API, and the Worker. The [API server](../portability-api) 6 | exposes DTP's API (hence the name). This allows clients to submit jobs, 7 | and check job statuses. The Worker does the actual transfer 8 | of the data. 9 | -------------------------------------------------------------------------------- /portability-transfer/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'portability-transfer' 2 | -------------------------------------------------------------------------------- /portability-transfer/src/main/java/org/datatransferproject/transfer/CredsTimeoutException.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.transfer; 2 | 3 | import java.util.UUID; 4 | 5 | public class CredsTimeoutException extends RuntimeException { 6 | private UUID jobId; 7 | 8 | public CredsTimeoutException(String message, UUID jobId) { 9 | super(message); 10 | this.jobId = jobId; 11 | } 12 | 13 | public UUID getJobId() { 14 | return jobId; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /portability-transfer/src/main/java/org/datatransferproject/transfer/copier/InMemoryDataCopierExtension.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Data Transfer Project Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.datatransferproject.transfer.copier; 18 | 19 | import org.datatransferproject.api.launcher.BootExtension; 20 | 21 | public interface InMemoryDataCopierExtension extends BootExtension { 22 | Class extends InMemoryDataCopier> getInMemoryDataCopierClass(); 23 | } 24 | -------------------------------------------------------------------------------- /portability-types-client/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 The Data Transfer Project Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | plugins { 19 | id 'maven' 20 | id 'signing' 21 | } 22 | 23 | dependencies { 24 | compile project(":portability-types-common") 25 | compile("io.swagger:swagger-annotations:${swaggerVersion}") 26 | testCompile("com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}") 27 | } 28 | 29 | configurePublication(project) 30 | -------------------------------------------------------------------------------- /portability-types-client/src/main/java/org/datatransferproject/types/client/datatype/GetDataTypes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 The Data Transfer Project Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.datatransferproject.types.client.datatype; 17 | 18 | /** A request to list data types available for export and import. */ 19 | public class GetDataTypes {} 20 | -------------------------------------------------------------------------------- /portability-types-client/src/main/java/org/datatransferproject/types/client/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 The Data Transfer Project Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /** 17 | * Defines the data transfer client model objects. Model objects represent the system data 18 | * resources a client has access to. 19 | */ 20 | package org.datatransferproject.types.client; 21 | -------------------------------------------------------------------------------- /portability-types-client/src/main/java/org/datatransferproject/types/client/transfer/ReserveWorker.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.types.client.transfer; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import io.swagger.annotations.ApiModelProperty; 6 | 7 | /** Request to reserve a worker to process a transfer job. */ 8 | public class ReserveWorker { 9 | private final String id; 10 | 11 | @JsonCreator 12 | public ReserveWorker(@JsonProperty(value = "id", required = true) String id) { 13 | this.id = id; 14 | } 15 | 16 | @ApiModelProperty(value = "The id of the job for which we are requesting a worker", dataType = "string", 17 | required = true) 18 | public String getId() { 19 | return id; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /portability-types-common/src/main/java/org/datatransferproject/types/common/DownloadableFile.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.types.common; 2 | 3 | public interface DownloadableFile extends DownloadableItem, FolderItem { } 4 | -------------------------------------------------------------------------------- /portability-types-common/src/main/java/org/datatransferproject/types/common/DownloadableItem.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.types.common; 2 | 3 | /** 4 | * Represent an item we can download through a URL and store in a temporary storage. 5 | * 6 | *
PhotoModel is a good example. Often, we check if the item is in the job store and download it 7 | * if it isn't. 8 | */ 9 | public interface DownloadableItem extends ImportableItem { 10 | 11 | /** Remote or local URL used to download and identify an item. */ 12 | String getFetchableUrl(); 13 | 14 | boolean isInTempStore(); 15 | } 16 | -------------------------------------------------------------------------------- /portability-types-common/src/main/java/org/datatransferproject/types/common/Fileable.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.types.common; 2 | 3 | /** 4 | * Represent an item we expect to be recognizable as an ordinary file on someone's computer. 5 | */ 6 | public interface Fileable { 7 | /** 8 | * Returns a standard MIME-type string one would expect to find if they inspected the downloaded 9 | * version of this file with standard tools on their PC. 10 | * 11 | * See https://en.wikipedia.org/wiki/Media_type 12 | * 13 | * NOTE: this should match {@link MediaObject#getEncodingFormat} behavior. 14 | */ 15 | String getMimeType(); 16 | } 17 | -------------------------------------------------------------------------------- /portability-types-common/src/main/java/org/datatransferproject/types/common/FolderItem.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.types.common; 2 | 3 | /** 4 | * Represent an item that belongs to some user-visible (and possibly user-defined) collection 5 | * like a folder on a filesystem, an album in a photo album, etc. 6 | */ 7 | public interface FolderItem extends Fileable { 8 | /** Returns the unique ID of the parent container this item lives in. */ 9 | String getFolderId(); 10 | } 11 | -------------------------------------------------------------------------------- /portability-types-common/src/main/java/org/datatransferproject/types/common/ImportableItem.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.types.common; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import javax.annotation.Nonnull; 5 | import javax.annotation.Nullable; 6 | 7 | public interface ImportableItem { 8 | 9 | @JsonIgnore 10 | @Nonnull 11 | String getIdempotentId(); 12 | 13 | @JsonIgnore 14 | @Nullable 15 | default String getName() { 16 | return null; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /portability-types-common/src/main/java/org/datatransferproject/types/common/IntPaginationToken.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.types.common; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonTypeName; 6 | import org.datatransferproject.types.common.PaginationData; 7 | 8 | /** Numeric pagination data. */ 9 | @JsonTypeName("org.dataportability:NumberPagination") 10 | public class IntPaginationToken extends PaginationData { 11 | private final int start; 12 | 13 | /** 14 | * Ctor. 15 | * 16 | * @param start the number the next page starts on. 17 | */ 18 | @JsonCreator 19 | public IntPaginationToken(@JsonProperty("start") int start) { 20 | this.start = start; 21 | } 22 | 23 | public int getStart() { 24 | return start; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /portability-types-common/src/main/java/org/datatransferproject/types/common/PaginationData.java: -------------------------------------------------------------------------------- 1 | package org.datatransferproject.types.common; 2 | 3 | /** 4 | * Contains pagination data for an export operation. 5 | * 6 | *
Concrete subtypes must use {@link com.fasterxml.jackson.annotation.JsonTypeName} to specify a
7 | * type descriminator used for deserialization.
8 | */
9 |
10 | import com.fasterxml.jackson.annotation.JsonSubTypes;
11 | import com.fasterxml.jackson.annotation.JsonTypeInfo;
12 |
13 | @JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
14 | @JsonSubTypes({
15 | @JsonSubTypes.Type(IntPaginationToken.class),
16 | @JsonSubTypes.Type(StringPaginationToken.class)
17 | })
18 | public abstract class PaginationData extends PortableType {}
19 |
--------------------------------------------------------------------------------
/portability-types-common/src/main/java/org/datatransferproject/types/common/PortabilityCommon.java:
--------------------------------------------------------------------------------
1 | package org.datatransferproject.types.common;
2 |
3 | public class PortabilityCommon {
4 | /** The protocol used for authorization. */
5 | public enum AuthProtocol {
6 | UNKNOWN,
7 | OAUTH_1,
8 | OAUTH_2,
9 | CUSTOM
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/portability-types-common/src/main/java/org/datatransferproject/types/common/StringPaginationToken.java:
--------------------------------------------------------------------------------
1 | package org.datatransferproject.types.common;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 | import com.fasterxml.jackson.annotation.JsonTypeName;
6 | import org.datatransferproject.types.common.PaginationData;
7 |
8 | /**
9 | * String pagination data.
10 | */
11 | @JsonTypeName("org.dataportability:StringPagination")
12 | public class StringPaginationToken extends PaginationData {
13 | private final String token;
14 |
15 | /**
16 | * Ctor.
17 | *
18 | * @param token the token to get the next page
19 | */
20 | @JsonCreator
21 | public StringPaginationToken(@JsonProperty("token") String token) {
22 | this.token = token;
23 | }
24 |
25 | public String getToken() {
26 | return token;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/portability-types-common/src/main/java/org/datatransferproject/types/common/models/DataModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 The Data Transfer Project Authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.datatransferproject.types.common.models;
17 |
18 | import java.util.Map;
19 | import org.datatransferproject.types.common.PortableType;
20 |
21 | /** The base data model type. */
22 | public abstract class DataModel extends PortableType {
23 | public Map Concrete subtypes must use {@link com.fasterxml.jackson.annotation.JsonTypeName} to specify a
9 | * type descriminator used for deserialization.
10 | */
11 | public abstract class ItemResource extends DataModel {
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/portability-types-common/src/main/java/org/datatransferproject/types/common/models/contacts/ContactsModelWrapper.java:
--------------------------------------------------------------------------------
1 | package org.datatransferproject.types.common.models.contacts;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 | import org.datatransferproject.types.common.models.DataModel;
6 |
7 | /** A collection of contacts as serialized vCards. */
8 | public class ContactsModelWrapper extends DataModel {
9 | private final String vCards;
10 |
11 | @JsonCreator
12 | public ContactsModelWrapper(@JsonProperty("vCards") String vCards) {
13 | this.vCards = vCards;
14 | }
15 |
16 | public String getVCards() {
17 | return vCards;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/portability-types-common/src/main/java/org/datatransferproject/types/common/models/playlists/CreativeWork.java:
--------------------------------------------------------------------------------
1 | package org.datatransferproject.types.common.models.playlists;
2 |
3 | /**
4 | * POJO of https://schema.org/CreativeWork
5 | */
6 | public class CreativeWork {
7 | // NOTE: only a subset of fields are used so far, feel free to add more fields from the spec as
8 | // needed.
9 | protected String headline;
10 |
11 | public CreativeWork(String headline) {
12 | this.headline = headline;
13 | }
14 |
15 | public String headline() {
16 | return headline;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/portability-types-common/src/main/java/org/datatransferproject/types/common/models/playlists/MusicAlbum.java:
--------------------------------------------------------------------------------
1 | package org.datatransferproject.types.common.models.playlists;
2 |
3 | import org.datatransferproject.types.common.models.CreativeWork;
4 | /**
5 | * POJO https://schema.org/MusicAlbum
6 | */
7 | public class MusicAlbum extends CreativeWork {
8 | // NOTE: only a subset of fields are used so far, feel free to add more fields from the spec as
9 | // needed.
10 |
11 | public MusicAlbum(String identifier, String headline) {
12 | super(identifier);
13 | setHeadline(headline);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/portability-types-common/src/main/java/org/datatransferproject/types/common/models/playlists/MusicGroup.java:
--------------------------------------------------------------------------------
1 | package org.datatransferproject.types.common.models.playlists;
2 |
3 | /**
4 | * POJO for https://schema.org/MusicGroup
5 | */
6 | public class MusicGroup {
7 | // NOTE: only a subset of fields are used so far, feel free to add more fields from the spec as
8 | // needed.
9 | private String headline;
10 |
11 | public MusicGroup(String headline) {
12 | this.headline = headline;
13 | }
14 |
15 | public String getHeadline() {
16 | return headline;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/portability-types-common/src/main/java/org/datatransferproject/types/common/models/playlists/MusicPlaylist.java:
--------------------------------------------------------------------------------
1 | package org.datatransferproject.types.common.models.playlists;
2 |
3 | import com.google.common.collect.ImmutableList;
4 | import org.datatransferproject.types.common.models.CreativeWork;
5 |
6 | public class MusicPlaylist extends CreativeWork {
7 | // NOTE: only a subset of fields are used so far, feel free to add more fields from the spec as
8 | // needed.
9 | private ImmutableList