use of org.datatransferproject.types.common.models.photos.PhotoModel in project data-transfer-project by google.
the class KoofrPhotosExporter method export.
@Override
public ExportResult<PhotosContainerResource> export(UUID jobId, TokensAndUrlAuthData authData, Optional<ExportInformation> exportInformation) throws CopyExceptionWithFailureReason {
Preconditions.checkNotNull(authData);
KoofrClient koofrClient = koofrClientFactory.create(authData);
KoofrMediaExport export = new KoofrMediaExport(koofrClient, monitor);
try {
export.export();
List<PhotoAlbum> exportAlbums = export.getPhotoAlbums();
List<PhotoModel> exportPhotos = export.getPhotos();
PhotosContainerResource containerResource = new PhotosContainerResource(exportAlbums, exportPhotos);
return new ExportResult<>(ExportResult.ResultType.END, containerResource, null);
} catch (IOException e) {
return new ExportResult<>(e);
}
}
use of org.datatransferproject.types.common.models.photos.PhotoModel in project data-transfer-project by google.
the class KoofrPhotosImporterTest method testImportItemFromURL.
@Test
public void testImportItemFromURL() throws Exception {
// blank.jpg generated using
// convert -size 1x1 xc:white blank.jpg
// exiftool "-CreateDate=2020:08:03 11:55:24" blank.jpg
final byte[] blankBytes = IOUtils.toByteArray(getClass().getClassLoader().getResourceAsStream("blank.jpg"));
server.enqueue(new MockResponse().setResponseCode(200).setBody("123"));
server.enqueue(new MockResponse().setResponseCode(200).setBody("4567"));
final Buffer blankBuffer = new Buffer();
blankBuffer.write(blankBytes);
server.enqueue(new MockResponse().setResponseCode(200).setBody(blankBuffer));
blankBuffer.close();
server.enqueue(new MockResponse().setResponseCode(200).setBody("89"));
server.enqueue(new MockResponse().setResponseCode(200).setBody("0"));
when(client.ensureRootFolder()).thenReturn("/root");
when(executor.getCachedValue(eq("id1"))).thenReturn("/root/Album 1");
when(executor.getCachedValue(eq("id2"))).thenReturn("/root/Album");
when(client.fileExists("/root/Album 1/pic1.jpg")).thenReturn(false);
when(client.fileExists("/root/Album 1/pic2.png")).thenReturn(true);
when(client.fileExists("/root/Album 1/2020-08-03 11.55.24 pic3.jpg")).thenReturn(false);
when(client.fileExists("/root/Album 1/2020-08-17 11.55.24 pic4.jpg")).thenReturn(false);
when(client.fileExists("/root/Album/pic5.jpg")).thenReturn(false);
String description1000 = new String(new char[1000]).replace("\0", "a");
String description1001 = new String(new char[1001]).replace("\0", "a");
UUID jobId = UUID.randomUUID();
PortabilityJob job = mock(PortabilityJob.class);
when(jobStore.findJob(jobId)).thenReturn(job);
Collection<PhotoAlbum> albums = ImmutableList.of(new PhotoAlbum("id1", "Album 1", "This is a fake album"), new PhotoAlbum("id2", "", description1001));
Collection<PhotoModel> photos = ImmutableList.of(new PhotoModel("pic1.jpg", server.url("/1.jpg").toString(), null, "image/jpeg", "p1", "id1", false, null), new PhotoModel("pic2.png", server.url("/2.png").toString(), "fine art", "image/png", "p2", "id1", false, null), new PhotoModel("pic3.jpg", server.url("/3.jpg").toString(), "A pic with EXIF", "image/jpeg", "p3", "id1", false, null), new PhotoModel("pic4.jpg", server.url("/4.jpg").toString(), "A pic with uploaded time", "image/jpeg", "p4", "id1", false, new SimpleDateFormat("yyyy:MM:dd HH:mm:ss").parse("2020:08:17 11:55:24")), new PhotoModel("pic5.jpg", server.url("/5.jpg").toString(), description1001, "image/jpeg", "p5", "id2", false, null));
PhotosContainerResource resource = spy(new PhotosContainerResource(albums, photos));
importer.importItem(jobId, executor, authData, resource);
InOrder clientInOrder = Mockito.inOrder(client);
verify(resource).transmogrify(any(KoofrTransmogrificationConfig.class));
clientInOrder.verify(client).ensureRootFolder();
clientInOrder.verify(client).ensureFolder("/root", "Album 1");
clientInOrder.verify(client).addDescription("/root/Album 1", "This is a fake album");
clientInOrder.verify(client).ensureFolder("/root", "Album");
clientInOrder.verify(client).addDescription("/root/Album", description1000);
clientInOrder.verify(client).fileExists(eq("/root/Album 1/pic1.jpg"));
clientInOrder.verify(client).uploadFile(eq("/root/Album 1"), eq("pic1.jpg"), any(), eq("image/jpeg"), isNull(), isNull());
clientInOrder.verify(client).fileExists(eq("/root/Album 1/pic2.png"));
clientInOrder.verify(client).fileExists(eq("/root/Album 1/2020-08-03 11.55.24 pic3.jpg"));
clientInOrder.verify(client).uploadFile(eq("/root/Album 1"), eq("2020-08-03 11.55.24 pic3.jpg"), any(), eq("image/jpeg"), eq(new SimpleDateFormat("yyyy:MM:dd HH:mm:ss").parse("2020:08:03 11:55:24")), eq("A pic with EXIF"));
clientInOrder.verify(client).uploadFile(eq("/root/Album 1"), eq("2020-08-17 11.55.24 pic4.jpg"), any(), eq("image/jpeg"), eq(new SimpleDateFormat("yyyy:MM:dd HH:mm:ss").parse("2020:08:17 11:55:24")), eq("A pic with uploaded time"));
clientInOrder.verify(client).fileExists(eq("/root/Album/pic5.jpg"));
clientInOrder.verify(client).uploadFile(eq("/root/Album"), eq("pic5.jpg"), any(), eq("image/jpeg"), isNull(), eq(description1000));
clientInOrder.verifyNoMoreInteractions();
}
use of org.datatransferproject.types.common.models.photos.PhotoModel in project data-transfer-project by google.
the class TwitterPhotosExporter method export.
@Override
public ExportResult<PhotosContainerResource> export(UUID jobId, TokenSecretAuthData authData, Optional<ExportInformation> exportInformation) {
Twitter twitterApi = TwitterApiWrapper.getInstance(appCredentials, authData);
int pageNumber = 1;
if (exportInformation.isPresent()) {
IntPaginationToken pageToken = (IntPaginationToken) exportInformation.get().getPaginationData();
if (pageToken != null && pageToken.getStart() > 1) {
pageNumber = pageToken.getStart();
}
}
Paging paging = new Paging(pageNumber, PAGE_SIZE);
try {
String page = "" + pageNumber;
long id = twitterApi.getId();
monitor.debug(() -> format("Getting tweets for %s (page %s)", id, page));
ResponseList<Status> statuses = twitterApi.getUserTimeline(id, paging);
List<PhotoModel> photos = new ArrayList<>();
for (Status status : statuses) {
boolean hasMedia = status.getMediaEntities().length > 0;
if (hasMedia && !status.isRetweet()) {
for (MediaEntity mediaEntity : status.getMediaEntities()) {
photos.add(new PhotoModel("Twitter Photo " + mediaEntity.getId(), mediaEntity.getMediaURL(), status.getText(), null, Long.toString(status.getId()), null, false));
}
}
}
boolean moreData = statuses.size() == PAGE_SIZE;
return new ExportResult<>(moreData ? ResultType.CONTINUE : ResultType.END, new PhotosContainerResource(null, photos), moreData ? new ContinuationData(new IntPaginationToken(pageNumber + 1)) : null);
} catch (TwitterException e) {
return new ExportResult<>(e);
}
}
use of org.datatransferproject.types.common.models.photos.PhotoModel in project data-transfer-project by google.
the class SmugMugPhotosImporterTest method importStoresAlbumInJobStore.
@Test
public void importStoresAlbumInJobStore() throws Exception {
// setup test objects
UUID jobId = UUID.randomUUID();
PhotoAlbum photoAlbum1 = new PhotoAlbum("albumId1", "albumName1", "albumDescription1");
PhotoModel photoModel1 = new PhotoModel("PHOTO_TITLE", "FETCHABLE_URL", "PHOTO_DESCRIPTION", "MEDIA_TYPE", "photoId1", photoAlbum1.getId(), false);
PhotoModel photoModel2 = new PhotoModel("PHOTO_TITLE", "FETCHABLE_URL", "PHOTO_DESCRIPTION", "MEDIA_TYPE", "photoId2", photoAlbum1.getId(), false);
PhotoModel photoModel3 = new PhotoModel("PHOTO_TITLE", "FETCHABLE_URL", "PHOTO_DESCRIPTION", "MEDIA_TYPE", "photoId3", photoAlbum1.getId(), false);
PhotosContainerResource photosContainerResource1 = new PhotosContainerResource(Collections.singletonList(photoAlbum1), ImmutableList.of());
PhotosContainerResource photosContainerResource2 = new PhotosContainerResource(ImmutableList.of(), ImmutableList.of(photoModel1, photoModel2, photoModel3));
SmugMugAlbum smugMugAlbum1 = new SmugMugAlbum("date", photoAlbum1.getDescription(), photoAlbum1.getName(), "privacy", "albumUri1", "urlname", "weburi");
String overflowAlbumName = smugMugAlbum1.getName() + " (1)";
SmugMugAlbum smugMugAlbum2 = new SmugMugAlbum("date", photoAlbum1.getDescription(), overflowAlbumName, "privacy", "albumUri2", "urlname", "weburi");
SmugMugAlbumResponse mockAlbumResponse1 = new SmugMugAlbumResponse(smugMugAlbum1.getUri(), "Locator", "LocatorType", smugMugAlbum1);
SmugMugAlbumResponse mockAlbumResponse2 = new SmugMugAlbumResponse(smugMugAlbum2.getUri(), "Locator", "LocatorType", smugMugAlbum2);
when(smugMugInterface.createAlbum(eq(smugMugAlbum1.getName()))).thenReturn(mockAlbumResponse1);
when(smugMugInterface.createAlbum(eq(smugMugAlbum2.getName()))).thenReturn(mockAlbumResponse2);
SmugMugImageUploadResponse smugMugUploadImageResponse = new SmugMugImageUploadResponse("imageUri", "albumImageUri", new ImageInfo("imageUri", "albumImageUri", "statusImageReplaceUri", "url"));
when(smugMugInterface.uploadImage(any(), any(), any())).thenReturn(smugMugUploadImageResponse);
when(smugMugInterface.getImageAsStream(any())).thenReturn(bufferedInputStream);
// Run test
SmugMugPhotosImporter importer = new SmugMugPhotosImporter(smugMugInterface, config, jobStore, new AppCredentials("key", "secret"), mock(ObjectMapper.class), monitor);
ImportResult result = importer.importItem(jobId, EXECUTOR, new TokenSecretAuthData("token", "secret"), photosContainerResource1);
result = importer.importItem(jobId, EXECUTOR, new TokenSecretAuthData("token", "secret"), photosContainerResource2);
// Verify
ArgumentCaptor<String> photoUrlsCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> albumNamesCaptor = ArgumentCaptor.forClass(String.class);
verify(smugMugInterface, atLeastOnce()).createAlbum(albumNamesCaptor.capture());
verify(smugMugInterface, atLeastOnce()).getImageAsStream(photoUrlsCaptor.capture());
List<String> capturedAlbumNames = albumNamesCaptor.getAllValues();
assertTrue(capturedAlbumNames.contains(smugMugAlbum1.getName()));
assertTrue(capturedAlbumNames.contains(smugMugAlbum2.getName()));
List<String> capturedPhotoUrls = photoUrlsCaptor.getAllValues();
assertTrue(capturedPhotoUrls.contains(photoModel1.getFetchableUrl()));
assertTrue(capturedPhotoUrls.contains(photoModel2.getFetchableUrl()));
assertTrue(capturedPhotoUrls.contains(photoModel3.getFetchableUrl()));
String overflowAlbumId = photoAlbum1.getId() + "-overflow-1";
assertThat((String) EXECUTOR.getCachedValue(photoAlbum1.getId())).isEqualTo(smugMugAlbum1.getUri());
assertThat((String) EXECUTOR.getCachedValue(overflowAlbumId)).isEqualTo(smugMugAlbum2.getUri());
SmugMugPhotoTempData tempData1 = new SmugMugPhotoTempData(photoAlbum1.getId(), smugMugAlbum1.getName(), smugMugAlbum1.getDescription(), smugMugAlbum1.getUri(), 2, overflowAlbumId);
SmugMugPhotoTempData tempData2 = new SmugMugPhotoTempData(overflowAlbumId, smugMugAlbum2.getName(), smugMugAlbum2.getDescription(), smugMugAlbum2.getUri(), 1, null);
assertThat(jobStore.findData(jobId, String.format(TEMP_DATA_FORMAT, photoAlbum1.getId()), SmugMugPhotoTempData.class).toString()).isEqualTo(tempData1.toString());
assertThat(jobStore.findData(jobId, String.format(TEMP_DATA_FORMAT, overflowAlbumId), SmugMugPhotoTempData.class).toString()).isEqualTo(tempData2.toString());
}
use of org.datatransferproject.types.common.models.photos.PhotoModel in project data-transfer-project by google.
the class SmugMugPhotosExporter method exportPhotos.
private ExportResult<PhotosContainerResource> exportPhotos(IdOnlyContainerResource containerResource, StringPaginationToken paginationData, SmugMugInterface smugMugInterface, UUID jobId) throws IOException {
List<PhotoModel> photoList = new ArrayList<>();
// Make request to SmugMug
String photoInfoUri;
if (paginationData != null) {
String token = paginationData.getToken();
Preconditions.checkState(token.startsWith(PHOTO_TOKEN_PREFIX), "Invalid pagination token " + token);
photoInfoUri = token.substring(PHOTO_TOKEN_PREFIX.length());
} else {
photoInfoUri = containerResource.getId();
}
SmugMugAlbumImageResponse albumImageList;
try {
albumImageList = smugMugInterface.getListOfAlbumImages(photoInfoUri + "!images");
} catch (IOException e) {
monitor.severe(() -> "Unable to get SmugMugAlbumImageResponse");
throw e;
}
// Set up continuation data
StringPaginationToken pageToken = null;
if (albumImageList.getPageInfo().getNextPage() != null) {
pageToken = new StringPaginationToken(PHOTO_TOKEN_PREFIX + albumImageList.getPageInfo().getNextPage());
}
ContinuationData continuationData = new ContinuationData(pageToken);
// Make list of photos - images may be empty if the album provided is empty
List<SmugMugImage> images = albumImageList.getAlbumImages() == null ? ImmutableList.of() : albumImageList.getAlbumImages();
for (SmugMugImage albumImage : images) {
if (!albumImage.isPhoto()) {
continue;
}
String title = albumImage.getTitle();
if (Strings.isNullOrEmpty(title)) {
title = albumImage.getFileName();
}
PhotoModel model = new PhotoModel(title, albumImage.getArchivedUri(), albumImage.getCaption(), getMimeType(albumImage.getFormat()), albumImage.getArchivedUri(), containerResource.getId(), true);
InputStream inputStream = smugMugInterface.getImageAsStream(model.getFetchableUrl());
jobStore.create(jobId, model.getFetchableUrl(), inputStream);
photoList.add(model);
}
PhotosContainerResource resource = new PhotosContainerResource(null, photoList);
// Get result type
ResultType resultType = ResultType.CONTINUE;
if (pageToken == null) {
resultType = ResultType.END;
}
return new ExportResult<>(resultType, resource, continuationData);
}
Aggregations