private async Task SynchronizeAsync(CancellationToken cancellationToken) { var flickr = Singleton <FlickrService> .Instance.FlickrNet; var functionMode = Singleton <SettingsService> .Instance.Mode; try { CurrentOperationDescription = string.Format("Sync_ParsingFolderStatus".GetLocalized(), SyncFolder.Path); var queryOptions = new QueryOptions(CommonFileQuery.DefaultQuery, extensions) { FolderDepth = FolderDepth.Deep }; queryOptions.SetThumbnailPrefetch(ThumbnailModeSingle, ThumbnailSize, ThumbnailOptionResize); var queryResult = SyncFolder.CreateFileQueryWithOptions(queryOptions); var files = await queryResult.GetFilesAsync(); cancellationToken.ThrowIfCancellationRequested(); ProgressMax = files.Count; var photosetsList = await flickr.RetryOnFailureAsync(f => f.PhotosetsGetListAsync()); cancellationToken.ThrowIfCancellationRequested(); var photosets = photosetsList.Where(ps => !string.IsNullOrWhiteSpace(ps.Description) && ps.Description[0] == '`') .Distinct(new GenericEqualityComparer <Photoset>(ps => ps.Description)).ToDictionary(ps => ps.Description); var groupedFiles = files.GroupBy(f => Path.GetDirectoryName(f.Path)); foreach (var group in groupedFiles) { var photosetName = Path.GetFileName(group.Key); var photosetDescription = "`" + group.Key.Replace(SyncFolder.Path, "."); Dictionary <string, Photo> photos; if (photosets.TryGetValue(photosetDescription, out Photoset photoset)) { var photosCollection = await flickr.RetryOnFailureAsync(f => f.PhotosetsGetPhotosAsync(photoset.PhotosetId)); photos = photosCollection.Distinct(new GenericEqualityComparer <Photo>(p => p.Title)).ToDictionary(p => p.Title); } else { photos = new Dictionary <string, Photo>(); } foreach (var file in group) { if (photos.Remove(file.Name)) { ProgressValue++; continue; } if (functionMode != FunctionMode.DownloadOnly) { CurrentOperationDescription = string.Format("Sync_UploadingFileStatus".GetLocalized(), file.Path); var thumbnail = await file.GetThumbnailAsync(ThumbnailModeSingle, ThumbnailSize, ThumbnailOptionResize); using (var stream = thumbnail.AsStreamForRead().AsRandomAccessStream()) { await PreviewImage.SetSourceAsync(stream); } try { string photoId = null; using (var stream = (await file.OpenSequentialReadAsync()).AsStreamForRead()) { photoId = await flickr.RetryOnFailureAsync(f => f.UploadPictureAsync(stream, file.Name, file.Name, file.Path.Replace(SyncFolder.Path, "."), "", false, false, false, ContentType.Photo, SafetyLevel.None, HiddenFromSearch.Hidden)); } if (photoset == null) { CurrentOperationDescription = string.Format("Sync_CreatingPhotoSetStatus".GetLocalized(), photosetName); photoset = await flickr.RetryOnFailureAsync(f => f.PhotosetsCreateAsync(photosetName, photosetDescription, photoId)); } else { CurrentOperationDescription = string.Format("Sync_AddingFileToPhotoSet".GetLocalized(), file.Name, photosetName); await flickr.RetryOnFailureAsync(f => f.PhotosetsAddPhotoAsync(photoset.PhotosetId, photoId)); } } catch (FlickrException exception) { if (!exception.Message.Contains("Filetype was not recognised")) { throw; } } } cancellationToken.ThrowIfCancellationRequested(); ProgressValue++; } if (photos.Count > 0 && functionMode != FunctionMode.UploadOnly) { var folder = await StorageFolder.GetFolderFromPathAsync(group.Key); await DownloadPhotosAsync(flickr, folder, photos.Values, cancellationToken); } photosets.Remove(photosetDescription); } if (functionMode != FunctionMode.UploadOnly) { foreach (var photoset in photosets.Values) { var folder = await CreateFolderRecursivelyAsync(SyncFolder, photoset.Description.Substring(1), cancellationToken); var photos = await flickr.RetryOnFailureAsync(f => f.PhotosetsGetPhotosAsync(photoset.PhotosetId)); await DownloadPhotosAsync(flickr, folder, photos, cancellationToken); } } ProgressValue = ProgressMax; CurrentOperationDescription = "Sync_FinishedStatus".GetLocalized(); } catch (Exception exception) { if (!cancellationToken.IsCancellationRequested) { var msg = new MessageDialog(exception.Message, "Error"); await msg.ShowAsync(); throw; } } }