From 68df572cf29126b76c96e200b4c10c5740082b1a Mon Sep 17 00:00:00 2001 From: Skalii Date: Tue, 7 Jan 2025 20:00:33 +0200 Subject: [PATCH 1/8] fix cloud progress bar; --- .../Cloud/OACloudBackupViewController.mm | 72 +++++++++++-------- .../OAStatusBackupTableViewController.mm | 40 ++++++----- 2 files changed, 68 insertions(+), 44 deletions(-) diff --git a/Sources/Controllers/Cloud/OACloudBackupViewController.mm b/Sources/Controllers/Cloud/OACloudBackupViewController.mm index fe6ae73d93..c86b07b63d 100644 --- a/Sources/Controllers/Cloud/OACloudBackupViewController.mm +++ b/Sources/Controllers/Cloud/OACloudBackupViewController.mm @@ -72,7 +72,8 @@ @implementation OACloudBackupViewController OABackupStatus *_status; NSString *_error; - OATitleIconProgressbarCell *_backupProgressCell; + float _syncProgress; + NSIndexPath *_syncProgressCell; NSInteger _itemsSection; UIBarButtonItem *_settingsButton; @@ -108,7 +109,7 @@ - (void)setupNotificationListeners - (void)viewDidLoad { [super viewDidLoad]; - + self.navigationItem.title = OALocalizedString(@"osmand_cloud"); [self setupNotificationListeners]; [OAIAPHelper.sharedInstance checkBackupPurchase]; @@ -191,6 +192,8 @@ - (void) onRefresh - (void)generateData { + _syncProgressCell = nil; + _syncProgress = 0; _data = [[OATableDataModel alloc] init]; if (!_status) @@ -257,13 +260,14 @@ - (void)generateData if (_settingsHelper.isBackupSyncing) { - _backupProgressCell = [self getProgressBarCell]; NSDictionary *backupProgressCell = @{ - kCellTypeKey: OATitleIconProgressbarCell.getCellIdentifier, - kCellKeyKey: @"backup_progress", - @"cell": _backupProgressCell + kCellTypeKey: [OATitleIconProgressbarCell getCellIdentifier], + kCellKeyKey: @"backupProgress", + kCellIconNameKey: @"ic_custom_cloud_upload", + kCellIconTintColor: [UIColor colorNamed:ACColorNameIconColorActive] }; [backupRows addRowFromDictionary:backupProgressCell]; + _syncProgressCell = [NSIndexPath indexPathForRow:[backupRows rowCount] - 1 inSection:[_data sectionCount] - 1]; } else { @@ -398,21 +402,6 @@ - (void)generateData } } -- (OATitleIconProgressbarCell *) getProgressBarCell -{ - NSArray *nib = [[NSBundle mainBundle] loadNibNamed:[OATitleIconProgressbarCell getCellIdentifier] owner:self options:nil]; - OATitleIconProgressbarCell *resultCell = (OATitleIconProgressbarCell *)[nib objectAtIndex:0]; - [resultCell.progressBar setProgress:0.0 animated:NO]; - [resultCell.progressBar setProgressTintColor:[UIColor colorNamed:ACColorNameIconColorActive]]; - resultCell.textView.text = [OALocalizedString(@"syncing_progress") stringByAppendingString:[NSString stringWithFormat:@"%i%%", 0]]; - resultCell.textView.textColor = [UIColor colorNamed:ACColorNameTextColorPrimary]; - resultCell.imgView.image = [UIImage templateImageNamed:@"ic_custom_cloud_upload"]; - resultCell.imgView.tintColor = [UIColor colorNamed:ACColorNameIconColorActive]; - resultCell.selectionStyle = UITableViewCellSelectionStyleNone; - resultCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - return resultCell; -} - - (BOOL) shouldShowSyncButton { return _info.filteredFilesToDelete.count > 0 || _info.filteredFilesToDownload.count > 0 || _info.filteredFilesToUpload.count > 0; @@ -716,9 +705,24 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } return cell; } - else if ([cellId isEqualToString:OATitleIconProgressbarCell.getCellIdentifier]) + else if ([cellId isEqualToString:[OATitleIconProgressbarCell getCellIdentifier]]) { - return [item objForKey:@"cell"]; + OATitleIconProgressbarCell *cell = [tableView dequeueReusableCellWithIdentifier:[OATitleIconProgressbarCell getCellIdentifier]]; + if (!cell) + { + NSArray *nib = [[NSBundle mainBundle] loadNibNamed:[OATitleIconProgressbarCell getCellIdentifier] owner:self options:nil]; + cell = (OATitleIconProgressbarCell *) nib[0]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + [cell.progressBar setProgressTintColor:[UIColor colorNamed:ACColorNameIconColorActive]]; + } + if (cell) + { + [cell.progressBar setProgress:_syncProgress animated:NO]; + cell.textView.text = [OALocalizedString(@"syncing_progress") stringByAppendingString:@((int) (_syncProgress * 100)).stringValue]; + cell.imageView.image = [UIImage templateImageNamed:item.iconName]; + cell.imageView.tintColor = item.iconTintColor; + } + return cell; } return nil; } @@ -729,7 +733,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath { OATableRowData *item = [_data itemForIndexPath:indexPath]; OAStatusBackupViewController *statusBackupViewController = nil; - if ([item.key isEqualToString:@"local_changes"] || [item.key isEqualToString:@"backup_progress"] || item.rowType == EOATableRowTypeCollapsable) + if ([item.key isEqualToString:@"local_changes"] || [item.key isEqualToString:@"backupProgress"] || item.rowType == EOATableRowTypeCollapsable) { statusBackupViewController = [[OAStatusBackupViewController alloc] initWithType:EOARecentChangesLocal]; } @@ -834,11 +838,23 @@ - (void)onBackupFinished:(NSNotification *)notification - (void)onBackupProgressUpdate:(NSNotification *)notification { dispatch_async(dispatch_get_main_queue(), ^{ - float value = [notification.userInfo[@"progress"] floatValue]; - if (_backupProgressCell) + float value = roundf([notification.userInfo[@"progress"] floatValue] * 100) / 100.0; + if (fabs(_syncProgress - value) >= 0.01) { - _backupProgressCell.progressBar.progress = value; - _backupProgressCell.textView.text = [OALocalizedString(@"syncing_progress") stringByAppendingString:[NSString stringWithFormat:@"%i%%", (int) (value * 100)]]; + _syncProgress = value; + if (_syncProgressCell) + { + OATableRowData *row = [_data itemForIndexPath:_syncProgressCell]; + if (row && [row.key isEqualToString:@"backupProgress"]) + { + OATitleIconProgressbarCell *cell = (OATitleIconProgressbarCell *) [self.tblView cellForRowAtIndexPath:_syncProgressCell]; + if (cell) + { + [cell.progressBar setProgress:_syncProgress animated:NO]; + cell.textView.text = [OALocalizedString(@"syncing_progress") stringByAppendingString:@((int) (_syncProgress * 100)).stringValue]; + } + } + } } }); } diff --git a/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm b/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm index 4c4b2e68ca..8c554b3638 100644 --- a/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm +++ b/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm @@ -58,6 +58,8 @@ @implementation OAStatusBackupTableViewController OATableDataModel *_data; NSIndexPath *_lastBackupIndexPath; NSInteger _itemsSection; + float _syncProgress; + NSIndexPath *_syncProgressCell; OANetworkSettingsHelper *_settingsHelper; OABackupHelper *_backupHelper; @@ -88,6 +90,8 @@ - (void)setupNotificationListeners - (void)viewDidLoad { [super viewDidLoad]; + + _syncProgress = 0; [self setupDownloadingCellHelper]; self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0.001, 0.001)]; @@ -176,22 +180,24 @@ - (void)updateData - (void)generateData { + _syncProgressCell = nil; + _syncProgress = 0; _itemsSection = -1; _data = [[OATableDataModel alloc] init]; OATableSectionData *statusSection = [OATableSectionData sectionData]; NSString *backupTime = _backupHelper.isBackupPreparing ? OALocalizedString(@"checking_progress") : [OAOsmAndFormatter getFormattedPassedTime:OAAppSettings.sharedManager.backupLastUploadedTime.get def:OALocalizedString(@"shared_string_never")]; [OAOsmAndFormatter getFormattedPassedTime:OAAppSettings.sharedManager.backupLastUploadedTime.get def:OALocalizedString(@"shared_string_never")]; + [_data addSection:statusSection]; if ([_settingsHelper isBackupSyncing]) { OATableRowData *progressCell = [OATableRowData rowData]; [progressCell setCellType:[OATitleIconProgressbarCell getCellIdentifier]]; [progressCell setKey:@"backupProgress"]; - [progressCell setTitle:[OALocalizedString(@"syncing_progress") stringByAppendingString:[NSString stringWithFormat:@"%i%%", 0]]]; [progressCell setIconName:@"ic_custom_cloud_upload"]; [progressCell setIconTintColor:[UIColor colorNamed:ACColorNameIconColorActive]]; - [progressCell setObj:@(0.) forKey:@"progress"]; [statusSection addRow:progressCell]; + _syncProgressCell = [NSIndexPath indexPathForRow:[statusSection rowCount] - 1 inSection:[_data sectionCount] - 1]; } else { @@ -205,7 +211,6 @@ - (void)generateData kCellIconTint: @(status.iconColor) }]; } - [_data addSection:statusSection]; _lastBackupIndexPath = [NSIndexPath indexPathForRow:statusSection.rowCount - 1 inSection:_data.sectionCount - 1]; OATableSectionData *itemsSection = [OATableSectionData sectionData]; @@ -683,11 +688,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } if (cell) { - cell.textView.text = item.title; + [cell.progressBar setProgress:_syncProgress animated:NO]; + cell.textView.text = [OALocalizedString(@"syncing_progress") stringByAppendingString:@((int) (_syncProgress * 100)).stringValue]; cell.imageView.image = [UIImage templateImageNamed:item.iconName]; cell.imageView.tintColor = item.iconTintColor; - - [cell.progressBar setProgress:[[item objForKey:@"progress"] floatValue] animated:NO]; } return cell; } @@ -792,18 +796,22 @@ - (void)onBackupStarted - (void)onBackupProgressUpdate:(NSNotification *)notification { dispatch_async(dispatch_get_main_queue(), ^{ - float value = [notification.userInfo[@"progress"] floatValue]; - NSIndexPath *progressIdxPath = [NSIndexPath indexPathForRow:0 inSection:0]; - OATableRowData *row = [_data itemForIndexPath:progressIdxPath]; - if (row && [row.key isEqualToString:@"backupProgress"]) + float value = roundf([notification.userInfo[@"progress"] floatValue] * 100) / 100.0; + if (fabs(_syncProgress - value) >= 0.01) { - [row setObj:@(value) forKey:@"progress"]; - [row setTitle:[OALocalizedString(@"syncing_progress") stringByAppendingString:[NSString stringWithFormat:@"%i%%", (int) (value * 100)]]]; - OATitleIconProgressbarCell *cell = (OATitleIconProgressbarCell *) [self.tableView cellForRowAtIndexPath:progressIdxPath]; - if (cell) + _syncProgress = value; + if (_syncProgressCell) { - cell.progressBar.progress = value; - cell.textView.text = row.title; + OATableRowData *row = [_data itemForIndexPath:_syncProgressCell]; + if (row && [row.key isEqualToString:@"backupProgress"]) + { + OATitleIconProgressbarCell *cell = (OATitleIconProgressbarCell *) [self.tableView cellForRowAtIndexPath:_syncProgressCell]; + if (cell) + { + [cell.progressBar setProgress:_syncProgress animated:NO]; + cell.textView.text = [OALocalizedString(@"syncing_progress") stringByAppendingString:@((int) (_syncProgress * 100)).stringValue]; + } + } } } }); From 7026081254f4eabb4412fcaac5ee01b6c850a8a2 Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 9 Jan 2025 07:16:25 +0200 Subject: [PATCH 2/8] fix localModifiedTime; --- .../SettingsItems/OAAvoidRoadsSettingsItem.mm | 4 +- .../SettingsItems/OACollectionSettingsItem.mm | 2 + .../SettingsItems/OAFavoritesSettingsItem.mm | 13 +- .../SettingsItems/OAFileSettingsItem.mm | 4 +- .../SettingsItems/OAGlobalSettingsItem.mm | 4 +- .../OAHistoryMarkersSettingsItem.mm | 2 +- .../SettingsItems/OAMapSourcesSettingsItem.mm | 6 +- .../SettingsItems/OAMarkersSettingsItem.mm | 4 +- .../SettingsItems/OAOsmEditsSettingsItem.mm | 2 +- .../SettingsItems/OAOsmNotesSettingsItem.mm | 2 +- .../SettingsItems/OAProfileSettingsItem.mm | 4 +- .../OAQuickActionsSettingsItem.mm | 4 +- .../OASearchHistorySettingsItem.m | 2 +- .../SettingsItems/OASettingsItem.mm | 2 +- Sources/Backup/OABackupHelper.h | 2 +- Sources/Backup/OABackupHelper.mm | 4 +- Sources/Backup/OABackupImporter.m | 151 ++++++++++++------ Sources/Backup/OABackupInfoGenerationTask.m | 2 +- Sources/Backup/OACollectLocalFilesTask.m | 30 +++- Sources/Backup/OAImportBackupTask.m | 9 -- Sources/Backup/OANetworkWriter.mm | 16 +- Sources/Backup/OARemoteFile.m | 18 +-- Sources/Backup/TrashItem.swift | 4 +- .../Cloud/CloudTrashViewController.swift | 2 +- ...tatusBackupConflictDetailsViewController.m | 12 +- .../OAStatusBackupTableViewController.mm | 10 +- .../OSMEditing/OAOsmUploadGPXViewConroller.m | 2 +- Sources/Helpers/OAAvoidSpecificRoads.mm | 2 +- Sources/Helpers/OAFavoritesHelper.h | 2 + Sources/Helpers/OAFavoritesHelper.mm | 9 +- Sources/Helpers/OANetworkUtilities.h | 2 +- Sources/History/OAHistoryDB.mm | 4 +- Sources/History/OAHistoryHelper.m | 2 +- Sources/OsmEdit/OAOsmBugsDBHelper.m | 4 +- Sources/OsmEdit/OAOsmEditsDBHelper.m | 4 +- Sources/POI/OAPOIFiltersHelper.mm | 4 +- 36 files changed, 211 insertions(+), 139 deletions(-) diff --git a/Sources/Backup/LocalBackup/SettingsItems/OAAvoidRoadsSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OAAvoidRoadsSettingsItem.mm index 0f227dee57..5a36a74ab1 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OAAvoidRoadsSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OAAvoidRoadsSettingsItem.mm @@ -45,12 +45,12 @@ - (void) initialization - (long)localModifiedTime { - return _specificRoads.getLastModifiedTime; + return [_specificRoads getLastModifiedTime] * 1000; } - (void)setLocalModifiedTime:(long)localModifiedTime { - [_specificRoads setLastModifiedTime:localModifiedTime]; + [_specificRoads setLastModifiedTime:localModifiedTime / 1000]; } - (EOASettingsItemType) type diff --git a/Sources/Backup/LocalBackup/SettingsItems/OACollectionSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OACollectionSettingsItem.mm index 859962ebe2..d7125ea5ca 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OACollectionSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OACollectionSettingsItem.mm @@ -57,8 +57,10 @@ - (NSArray*) processDuplicateItems if (_items.count > 0) { for (id item in _items) + { if ([self isDuplicate:item]) [_duplicateItems addObject:item]; + } } return _duplicateItems; } diff --git a/Sources/Backup/LocalBackup/SettingsItems/OAFavoritesSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OAFavoritesSettingsItem.mm index dfe58835bf..5a36d9583d 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OAFavoritesSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OAFavoritesSettingsItem.mm @@ -110,7 +110,7 @@ - (long) localModifiedTime { NSError *err = nil; NSDictionary *attrs = [manager attributesOfItemAtPath:groupFilePath error:&err]; - return !err ? attrs.fileModificationDate.timeIntervalSince1970 : 0; + return !err ? (attrs.fileModificationDate.timeIntervalSince1970 * 1000) : 0; } NSString *favPath = OsmAndApp.instance.favoritesLegacyStorageFilename; @@ -119,7 +119,7 @@ - (long) localModifiedTime NSError *err = nil; NSDictionary *attrs = [manager attributesOfItemAtPath:favPath error:&err]; if (!err) - return attrs.fileModificationDate.timeIntervalSince1970; + return attrs.fileModificationDate.timeIntervalSince1970 * 1000; } return 0; } @@ -131,13 +131,13 @@ - (void) setLocalModifiedTime:(long)localModifiedTime NSFileManager *manager = NSFileManager.defaultManager; if (groupFilePath && [manager fileExistsAtPath:groupFilePath]) { - [manager setAttributes:@{ NSFileModificationDate : [NSDate dateWithTimeIntervalSince1970:localModifiedTime] } ofItemAtPath:groupFilePath error:nil]; + [manager setAttributes:@{ NSFileModificationDate : [NSDate dateWithTimeIntervalSince1970:localModifiedTime / 1000] } ofItemAtPath:groupFilePath error:nil]; } else { NSString *favPath = OsmAndApp.instance.favoritesLegacyStorageFilename; if ([manager fileExistsAtPath:favPath]) - [manager setAttributes:@{ NSFileModificationDate : [NSDate dateWithTimeIntervalSince1970:localModifiedTime] } ofItemAtPath:favPath error:nil]; + [manager setAttributes:@{ NSFileModificationDate : [NSDate dateWithTimeIntervalSince1970:localModifiedTime / 1000] } ofItemAtPath:favPath error:nil]; } } @@ -182,9 +182,12 @@ - (void) apply { [OAFavoritesHelper addFavorites:group.points lookupAddress:NO - sortAndSave:group == self.appliedItems.lastObject + sortAndSave:NO pointsGroup:[group toPointsGroup]]; } + [OAFavoritesHelper sortAll]; + [OAFavoritesHelper saveCurrentPointsIntoFile:NO]; + [OAFavoritesHelper loadFavorites]; } } } diff --git a/Sources/Backup/LocalBackup/SettingsItems/OAFileSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OAFileSettingsItem.mm index a066e2a2f4..0ef83cde58 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OAFileSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OAFileSettingsItem.mm @@ -395,7 +395,7 @@ - (long)localModifiedTime NSError *err = nil; NSDictionary *attrs = [manager attributesOfItemAtPath:self.filePath error:&err]; if (!err) - return attrs.fileModificationDate.timeIntervalSince1970; + return attrs.fileModificationDate.timeIntervalSince1970 * 1000; } return 0; } @@ -405,7 +405,7 @@ - (void)setLocalModifiedTime:(long)localModifiedTime NSFileManager *manager = NSFileManager.defaultManager; if ([manager fileExistsAtPath:self.filePath]) { - [manager setAttributes:@{ NSFileModificationDate : [NSDate dateWithTimeIntervalSince1970:localModifiedTime] } ofItemAtPath:self.filePath error:nil]; + [manager setAttributes:@{ NSFileModificationDate : [NSDate dateWithTimeIntervalSince1970:localModifiedTime / 1000] } ofItemAtPath:self.filePath error:nil]; } } diff --git a/Sources/Backup/LocalBackup/SettingsItems/OAGlobalSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OAGlobalSettingsItem.mm index 17a98d44f7..2efe5d772f 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OAGlobalSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OAGlobalSettingsItem.mm @@ -64,12 +64,12 @@ - (BOOL)exists - (long)localModifiedTime { - return [OAAppSettings.sharedManager getLastGloblalSettingsModifiedTime]; + return [OAAppSettings.sharedManager getLastGloblalSettingsModifiedTime] * 1000; } - (void)setLocalModifiedTime:(long)localModifiedTime { - [OAAppSettings.sharedManager setLastGlobalModifiedTime:localModifiedTime]; + [OAAppSettings.sharedManager setLastGlobalModifiedTime:localModifiedTime / 1000]; } - (long)getEstimatedSize diff --git a/Sources/Backup/LocalBackup/SettingsItems/OAHistoryMarkersSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OAHistoryMarkersSettingsItem.mm index 229c1acbb8..be78961124 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OAHistoryMarkersSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OAHistoryMarkersSettingsItem.mm @@ -69,7 +69,7 @@ - (BOOL)shouldShowDuplicates - (long)localModifiedTime { - return _historyMarkersHelper.getMarkersHistoryLastModifiedTime; + return [_historyMarkersHelper getMarkersHistoryLastModifiedTime]; } - (void)setLocalModifiedTime:(long)lastModifiedTime diff --git a/Sources/Backup/LocalBackup/SettingsItems/OAMapSourcesSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OAMapSourcesSettingsItem.mm index 8dc1a248c4..5d7c9f0daa 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OAMapSourcesSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OAMapSourcesSettingsItem.mm @@ -100,7 +100,7 @@ - (long)localModifiedTime } } } - return lastModifiedTime; + return lastModifiedTime * 1000; } - (void)setLocalModifiedTime:(long)localModifiedTime @@ -123,8 +123,8 @@ - (void)setLocalModifiedTime:(long)localModifiedTime NSDictionary *attrs = [fileManager attributesOfItemAtPath:filePath error:&err]; if (!err) { - if (attrs.fileModificationDate.timeIntervalSince1970 > localModifiedTime) - [fileManager setAttributes:@{ NSFileModificationDate : [NSDate dateWithTimeIntervalSince1970:localModifiedTime]} ofItemAtPath:filePath error:nil]; + if (attrs.fileModificationDate.timeIntervalSince1970 > localModifiedTime / 1000) + [fileManager setAttributes:@{ NSFileModificationDate : [NSDate dateWithTimeIntervalSince1970:localModifiedTime / 1000] } ofItemAtPath:filePath error:nil]; } } } diff --git a/Sources/Backup/LocalBackup/SettingsItems/OAMarkersSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OAMarkersSettingsItem.mm index 43f343d8d6..01918e6a38 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OAMarkersSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OAMarkersSettingsItem.mm @@ -75,12 +75,12 @@ - (NSString *)getPublicName - (long)localModifiedTime { - return [_destinationsHelper getMarkersLastModifiedTime]; + return [_destinationsHelper getMarkersLastModifiedTime] * 1000; } - (void)setLocalModifiedTime:(long)localModifiedTime { - [_destinationsHelper setMarkersLastModifiedTime:localModifiedTime]; + [_destinationsHelper setMarkersLastModifiedTime:localModifiedTime / 1000]; } - (void) apply diff --git a/Sources/Backup/LocalBackup/SettingsItems/OAOsmEditsSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OAOsmEditsSettingsItem.mm index 8c229f6a73..1239ed43b4 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OAOsmEditsSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OAOsmEditsSettingsItem.mm @@ -57,7 +57,7 @@ - (EOASettingsItemType) type - (long)localModifiedTime { - return [OAOsmEditsDBHelper sharedDatabase].getLastModifiedTime; + return [[OAOsmEditsDBHelper sharedDatabase] getLastModifiedTime]; } - (void)setLocalModifiedTime:(long)localModifiedTime diff --git a/Sources/Backup/LocalBackup/SettingsItems/OAOsmNotesSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OAOsmNotesSettingsItem.mm index 1ad531a4ad..077a6a9422 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OAOsmNotesSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OAOsmNotesSettingsItem.mm @@ -48,7 +48,7 @@ - (EOASettingsItemType) type - (long)localModifiedTime { - return [OAOsmBugsDBHelper sharedDatabase].getLastModifiedTime; + return [[OAOsmBugsDBHelper sharedDatabase] getLastModifiedTime]; } - (void)setLocalModifiedTime:(long)localModifiedTime diff --git a/Sources/Backup/LocalBackup/SettingsItems/OAProfileSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OAProfileSettingsItem.mm index 7a3984e5be..b124d6b8b6 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OAProfileSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OAProfileSettingsItem.mm @@ -84,12 +84,12 @@ - (void)remove - (long)localModifiedTime { - return [OAAppSettings.sharedManager getLastProfileSettingsModifiedTime:_appMode]; + return [OAAppSettings.sharedManager getLastProfileSettingsModifiedTime:_appMode] * 1000; } - (void)setLocalModifiedTime:(long)localModifiedTime { - [OAAppSettings.sharedManager setLastProfileModifiedTime:localModifiedTime mode:_appMode]; + [OAAppSettings.sharedManager setLastProfileModifiedTime:localModifiedTime / 1000 mode:_appMode]; } - (void)readFromJson:(id)json error:(NSError * _Nullable __autoreleasing *)error diff --git a/Sources/Backup/LocalBackup/SettingsItems/OAQuickActionsSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OAQuickActionsSettingsItem.mm index 2021b01081..19085665df 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OAQuickActionsSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OAQuickActionsSettingsItem.mm @@ -67,12 +67,12 @@ - (void)renameButton - (long)localModifiedTime { - return [_buttonState getLastModifiedTime]; + return [_buttonState getLastModifiedTime] * 1000; } - (void)setLocalModifiedTime:(long)localModifiedTime { - [_buttonState setLastModifiedTime:localModifiedTime]; + [_buttonState setLastModifiedTime:localModifiedTime / 1000]; } - (BOOL)exists diff --git a/Sources/Backup/LocalBackup/SettingsItems/OASearchHistorySettingsItem.m b/Sources/Backup/LocalBackup/SettingsItems/OASearchHistorySettingsItem.m index 0b2043d083..6b62c80179 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OASearchHistorySettingsItem.m +++ b/Sources/Backup/LocalBackup/SettingsItems/OASearchHistorySettingsItem.m @@ -97,7 +97,7 @@ - (long)getEstimatedItemSize:(id)item - (long)localModifiedTime { - return _searchHistoryHelper.getMarkersHistoryLastModifiedTime; + return [_searchHistoryHelper getMarkersHistoryLastModifiedTime]; } - (void)setLocalModifiedTime:(long)lastModifiedTime diff --git a/Sources/Backup/LocalBackup/SettingsItems/OASettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OASettingsItem.mm index f6fba39203..7bac449785 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OASettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OASettingsItem.mm @@ -108,7 +108,7 @@ - (long)lastModifiedTime - (void)setLastModifiedTime:(long)lastModifiedTime { - _lastModifiedTime = lastModifiedTime; + _lastModifiedTime = lastModifiedTime / 1000; } - (BOOL) applyFileName:(NSString *)fileName diff --git a/Sources/Backup/OABackupHelper.h b/Sources/Backup/OABackupHelper.h index b51e3cbb36..0293680ed5 100644 --- a/Sources/Backup/OABackupHelper.h +++ b/Sources/Backup/OABackupHelper.h @@ -114,7 +114,7 @@ static inline BOOL backupDebugLogs() lastModifiedTime:(long)lastModifiedTime listener:(id)listener; -- (void) updateFileUploadTime:(NSString *)type fileName:(NSString *)fileName uploadTime:(long)updateTime; +- (void) updateFileUploadTime:(NSString *)type fileName:(NSString *)fileName uploadTime:(long)uploadTime; - (void) updateFileMd5Digest:(NSString *)type fileName:(NSString *)fileName md5Hex:(NSString *)md5Hex; - (void) updateBackupUploadTime; diff --git a/Sources/Backup/OABackupHelper.mm b/Sources/Backup/OABackupHelper.mm index 3b7318e1a6..b9161984d7 100644 --- a/Sources/Backup/OABackupHelper.mm +++ b/Sources/Backup/OABackupHelper.mm @@ -379,9 +379,9 @@ - (void) checkRegistered throw [NSException exceptionWithName:@"UserNotRegisteredException" reason:@"User is not registered" userInfo:nil]; } -- (void) updateFileUploadTime:(NSString *)type fileName:(NSString *)fileName uploadTime:(long)updateTime +- (void) updateFileUploadTime:(NSString *)type fileName:(NSString *)fileName uploadTime:(long)uploadTime { - [_dbHelper updateFileUploadTime:type name:fileName updateTime:updateTime]; + [_dbHelper updateFileUploadTime:type name:fileName updateTime:uploadTime]; } - (void) updateFileMd5Digest:(NSString *)type fileName:(NSString *)fileName md5Hex:(NSString *)md5Hex diff --git a/Sources/Backup/OABackupImporter.m b/Sources/Backup/OABackupImporter.m index 43627b5626..94a3764698 100644 --- a/Sources/Backup/OABackupImporter.m +++ b/Sources/Backup/OABackupImporter.m @@ -243,8 +243,8 @@ - (void) importItems:(NSArray *)items if (!restoreDeleted) { [remoteFileItems enumerateKeysAndObjectsUsingBlock:^(OARemoteFile * _Nonnull key, OASettingsItem * _Nonnull obj, BOOL * _Nonnull stop) { - obj.localModifiedTime = key.clienttimems / 1000; - obj.lastModifiedTime = key.clienttimems / 1000; + obj.localModifiedTime = key.clienttimems; + obj.lastModifiedTime = key.clienttimems; }]; } @@ -272,17 +272,8 @@ - (void) importItemFile:(OARemoteFile *)remoteFile item:(OASettingsItem *)item f [item apply]; } - [_backupHelper updateFileUploadTime:remoteFile.type fileName:remoteFile.name uploadTime:remoteFile.updatetimems]; - - if ([item isKindOfClass:OAFileSettingsItem.class]) - { - NSString *itemFileName = [OABackupHelper getItemFileName:item]; - if (itemFileName.pathExtension.length == 0) - { - [_backupHelper updateFileUploadTime:[OASettingsItemType typeName:item.type] fileName:itemFileName - uploadTime:remoteFile.updatetimems]; - } - } + [self updateFileMd5Digest:remoteFile item:item]; + [self updateFileUploadTime:remoteFile item:item]; } if ([NSFileManager.defaultManager fileExistsAtPath:tempFilePath]) [NSFileManager.defaultManager removeItemAtPath:tempFilePath error:nil]; @@ -301,6 +292,49 @@ - (void) importItemFile:(OARemoteFile *)remoteFile item:(OASettingsItem *)item f } } +- (void)updateFileMd5Digest:(OARemoteFile *)remoteFile item:(OASettingsItem *)item +{ + if (![item isKindOfClass:OAFileSettingsItem.class]) + return; + + OAFileSettingsItem *settingsItem = (OAFileSettingsItem *) item; + if ([settingsItem needMd5Digest]) + { + OABackupDbHelper *dbHelper = [OABackupDbHelper sharedDatabase]; + OAUploadedFileInfo *fileInfo = [dbHelper getUploadedFileInfo:remoteFile.type name:remoteFile.name]; + NSString *lastMd5 = fileInfo != nil ? fileInfo.md5Digest : nil; + if (!lastMd5 || lastMd5.length == 0) + { + NSString *md5Digest = [OAUtilities fileMD5:settingsItem.filePath]; + if (md5Digest.length > 0) + { + [_backupHelper updateFileMd5Digest:[OASettingsItemType typeName:item.type] + fileName:remoteFile.name + md5Hex:md5Digest]; + } + } + } +} + +- (void)updateFileUploadTime:(OARemoteFile *)remoteFile item:(OASettingsItem *)item +{ + long time = remoteFile.updatetimems; + [_backupHelper updateFileUploadTime:remoteFile.type fileName:remoteFile.name uploadTime:time]; + if ([item isKindOfClass:OAFileSettingsItem.class]) + { + NSFileManager *fileManager = NSFileManager.defaultManager; + BOOL isDir = NO; + NSString *itemFileName = [OABackupHelper getFileItemName:(OAFileSettingsItem *) item]; + [fileManager fileExistsAtPath:itemFileName isDirectory:&isDir]; + if (isDir) + { + [_backupHelper updateFileUploadTime:[OASettingsItemType typeName:item.type] + fileName:itemFileName + uploadTime:time]; + } + } +} + - (NSArray *) getRemoteItems:(NSArray *)remoteFiles readItems:(BOOL)readItems restoreDeleted:(BOOL)restoreDeleted { if (remoteFiles.count == 0) @@ -314,7 +348,8 @@ - (void) importItemFile:(OARemoteFile *)remoteFile item:(OASettingsItem *)item f json[@"items"] = itemsJson; NSMutableArray *uniqueRemoteFiles = [NSMutableArray array]; - [self collectUniqueRemoteFiles:remoteFiles uniqueRemoteFiles:uniqueRemoteFiles]; + NSMutableDictionary *deletedRemoteFilesMap = [NSMutableDictionary dictionary]; + [self collectUniqueRemoteFiles:remoteFiles uniqueRemoteFiles:uniqueRemoteFiles deletedRemoteFilesMap:deletedRemoteFilesMap]; [operationLog log:@"build uniqueRemoteFiles"]; NSMutableSet *remoteInfoNames = [NSMutableSet set]; @@ -326,7 +361,8 @@ - (void) importItemFile:(OARemoteFile *)remoteFile item:(OASettingsItem *)item f remoteItemFilesMap:remoteItemFilesMap remoteInfoFilesMap:remoteInfoFilesMap remoteInfoNames:remoteInfoNames - remoteInfoFiles:remoteInfoFiles readItems:readItems]; + remoteInfoFiles:remoteInfoFiles + readItems:readItems]; [operationLog log:@"build maps"]; NSMutableArray *noInfoRemoteItemFiles = [NSMutableArray array]; @@ -334,21 +370,21 @@ - (void) importItemFile:(OARemoteFile *)remoteFile item:(OASettingsItem *)item f [operationLog log:@"build noInfoRemoteItemFiles"]; - if (readItems) - [self generateItemsJsonByDictionary:itemsJson remoteInfoFiles:remoteInfoFilesMap noInfoRemoteItemFiles:noInfoRemoteItemFiles]; - else - [self generateItemsJson:itemsJson remoteInfoFiles:remoteInfoFiles noInfoRemoteItemFiles:noInfoRemoteItemFiles]; - + if (readItems || remoteInfoFilesMap.count > 0) + [self generateItemsJson:itemsJson remoteInfoFilesMap:remoteInfoFilesMap remoteInfoFiles:remoteInfoFiles]; + if (!readItems) + [self generateItemsJson:itemsJson remoteInfoFiles:remoteInfoFiles]; + [self addRemoteFilesToJson:itemsJson noInfoRemoteItemFiles:noInfoRemoteItemFiles]; [operationLog log:@"generateItemsJson"]; OASettingsItemsFactory *itemsFactory = [[OASettingsItemsFactory alloc] initWithParsedJSON:json]; - [operationLog log:@"create setting items"]; - NSArray *settingsItemList = itemsFactory.getItems; + NSArray *settingsItemList = [itemsFactory getItems]; if (settingsItemList.count == 0) return @[]; [self updateFilesInfo:remoteItemFilesMap settingsItemList:settingsItemList restoreDeleted:restoreDeleted]; + [self updateFilesInfo:deletedRemoteFilesMap settingsItemList:settingsItemList restoreDeleted:restoreDeleted]; [items addObjectsFromArray:settingsItemList]; [operationLog log:@"updateFilesInfo"]; [operationLog finishOperation]; @@ -361,28 +397,33 @@ - (void) importItemFile:(OARemoteFile *)remoteFile item:(OASettingsItem *)item f } - (void)collectUniqueRemoteFiles:(NSArray *)remoteFiles - uniqueRemoteFiles:(NSMutableArray *)uniqueRemoteFiles { + uniqueRemoteFiles:(NSMutableArray *)uniqueRemoteFiles + deletedRemoteFilesMap:(NSMutableDictionary *)deletedRemoteFiles +{ NSMutableSet *uniqueFileIds = [[NSMutableSet alloc] init]; for (OARemoteFile *file in remoteFiles) { - if (![file isDeleted]) + NSString *fileId = [file getTypeNamePath]; + if ([file isDeleted]) { - NSString *fileId = [file getTypeNamePath]; - if (![uniqueFileIds containsObject:fileId]) - { - [uniqueFileIds addObject:fileId]; - [uniqueRemoteFiles addObject:file]; - } + NSString *fileName = [file getTypeNamePath]; + if (![fileName hasSuffix:OABackupHelper.INFO_EXT] && !deletedRemoteFiles[fileName]) + deletedRemoteFiles[fileName] = file; + } + else if (![uniqueFileIds containsObject:fileId]) + { + [uniqueFileIds addObject:fileId]; + [uniqueRemoteFiles addObject:file]; } } } - (void)processUniqueRemoteFiles:(NSArray *)uniqueRemoteFiles - remoteItemFilesMap:(NSMutableDictionary *)remoteItemFilesMap - remoteInfoFilesMap:(NSMutableDictionary *)remoteInfoFilesMap - remoteInfoNames:(NSMutableSet *)remoteInfoNames - remoteInfoFiles:(NSMutableArray *)remoteInfoFiles - readItems:(BOOL)readItems + remoteItemFilesMap:(NSMutableDictionary *)remoteItemFilesMap + remoteInfoFilesMap:(NSMutableDictionary *)remoteInfoFilesMap + remoteInfoNames:(NSMutableSet *)remoteInfoNames + remoteInfoFiles:(NSMutableArray *)remoteInfoFiles + readItems:(BOOL)readItems { NSDictionary *infoMap = [OABackupDbHelper.sharedDatabase getUploadedFileInfoMap]; OABackupInfo *backupInfo = _backupHelper.backup.backupInfo; @@ -404,7 +445,8 @@ - (void)processUniqueRemoteFiles:(NSArray *)uniqueRemoteFiles } OAUploadedFileInfo *fileInfo = infoMap[[NSString stringWithFormat:@"%@___%@", remoteFile.type, origFileName]]; long uploadTime = fileInfo != nil ? fileInfo.uploadTime : 0; - if (readItems && (uploadTime != remoteFile.updatetimems || delete)) + if ([self shouldDownloadOnCollecting:remoteFile defValue:readItems] + && (uploadTime != remoteFile.updatetimems || delete)) remoteInfoFilesMap[[_tmpFilesDir stringByAppendingPathComponent:fileName]] = remoteFile; NSString *itemFileName = [fileName stringByDeletingPathExtension]; @@ -418,6 +460,12 @@ - (void)processUniqueRemoteFiles:(NSArray *)uniqueRemoteFiles } } +- (BOOL)shouldDownloadOnCollecting:(OARemoteFile *)remoteFile defValue:(BOOL)defValue +{ + NSString *type = remoteFile.type; + return defValue || [type isEqualToString:[OASettingsItemType typeName:EOASettingsItemTypeQuickActions]]; +} + - (void)collectNoInfoRemoteItemFiles:(NSMutableArray *)noInfoRemoteItemFiles remoteItemFilesMap:(NSDictionary *)remoteItemFilesMap remoteInfoNames:(NSSet *)remoteInfoNames @@ -449,13 +497,16 @@ - (void) updateFilesInfo:(NSDictionary *)remoteFiles NSArray *foundRemoteFiles = [self getItemRemoteFiles:settingsItem remoteFiles:remoteFilesMap]; for (OARemoteFile *remoteFile in foundRemoteFiles) { - if (!restoreDeleted) - settingsItem.lastModifiedTime = remoteFile.clienttimems / 1000; remoteFile.item = settingsItem; - if ([settingsItem isKindOfClass:OAFileSettingsItem.class]) + if (![remoteFile isDeleted]) { - OAFileSettingsItem *fileSettingsItem = (OAFileSettingsItem *) settingsItem; - fileSettingsItem.size = remoteFile.filesize; + if (!restoreDeleted) + settingsItem.lastModifiedTime = remoteFile.clienttimems; + if ([settingsItem isKindOfClass:OAFileSettingsItem.class]) + { + OAFileSettingsItem *fileSettingsItem = (OAFileSettingsItem *) settingsItem; + fileSettingsItem.size = remoteFile.filesize; + } } } } @@ -497,7 +548,6 @@ - (void) updateFilesInfo:(NSDictionary *)remoteFiles - (void) generateItemsJson:(NSMutableArray *)itemsJson remoteInfoFiles:(NSArray *)remoteInfoFiles - noInfoRemoteItemFiles:(NSArray *)noInfoRemoteItemFiles { for (OARemoteFile *remoteFile in remoteInfoFiles) { @@ -526,17 +576,17 @@ - (void) generateItemsJson:(NSMutableArray *)itemsJson itemJson[@"file"] = fileName; [itemsJson addObject:itemJson]; } - [self addRemoteFilesToJson:itemsJson noInfoRemoteItemFiles:noInfoRemoteItemFiles]; } -- (void) generateItemsJsonByDictionary:(NSMutableArray *)itemsJson - remoteInfoFiles:(NSDictionary *)remoteInfoFiles - noInfoRemoteItemFiles:(NSArray *)noInfoRemoteItemFiles +- (void) generateItemsJson:(NSMutableArray *)itemsJson + remoteInfoFilesMap:(NSDictionary *)remoteInfoFilesMap + remoteInfoFiles:(NSMutableArray *)remoteInfoFiles { NSMutableArray *tasks = [NSMutableArray array]; __weak OABackupImporter *weakSelf = self; - [remoteInfoFiles enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, OARemoteFile * _Nonnull obj, BOOL * _Nonnull stop) { - [tasks addObject:[[OAFileDownloadTask alloc] initWithFilePath:key remoteFile:obj onDownloadFileListener:weakSelf]]; + [remoteInfoFilesMap enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, OARemoteFile * _Nonnull remoteFile, BOOL * _Nonnull stop) { + [tasks addObject:[[OAFileDownloadTask alloc] initWithFilePath:key remoteFile:remoteFile onDownloadFileListener:weakSelf]]; + [remoteInfoFiles removeObject:remoteFile]; }]; [_queue addOperations:tasks waitUntilFinished:YES]; @@ -544,7 +594,7 @@ - (void) generateItemsJsonByDictionary:(NSMutableArray *)itemsJson BOOL hasDownloadErrors = [self hasDownloadErrors:tasks]; if (!hasDownloadErrors) { - for (NSString *filePath in remoteInfoFiles.allKeys) + for (NSString *filePath in remoteInfoFilesMap.allKeys) { NSError *err = nil; NSData *data = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&err]; @@ -567,12 +617,11 @@ - (void) generateItemsJsonByDictionary:(NSMutableArray *)itemsJson { @throw [NSException exceptionWithName:@"IOException" reason:@"Error downloading items info" userInfo:nil]; } - [self addRemoteFilesToJson:itemsJson noInfoRemoteItemFiles:noInfoRemoteItemFiles]; } - (void) addRemoteFilesToJson:(NSMutableArray *)itemsJson noInfoRemoteItemFiles:(NSArray *)noInfoRemoteItemFiles { - NSMutableSet *fileItems = [NSMutableSet set]; +// NSMutableSet *fileItems = [NSMutableSet set]; for (OARemoteFile *remoteFile in noInfoRemoteItemFiles) { NSString *type = remoteFile.type; diff --git a/Sources/Backup/OABackupInfoGenerationTask.m b/Sources/Backup/OABackupInfoGenerationTask.m index ff0c9775f2..d2897369c3 100644 --- a/Sources/Backup/OABackupInfoGenerationTask.m +++ b/Sources/Backup/OABackupInfoGenerationTask.m @@ -83,7 +83,7 @@ - (OABackupInfo *) doInBackground OALocalFile *localFile = _localFiles[remoteFile.getTypeNamePath]; if (localFile != nil) { - BOOL fileChangedLocally = localFile.localModifiedTime > (localFile.uploadTime / 1000); + BOOL fileChangedLocally = localFile.localModifiedTime > localFile.uploadTime; BOOL fileChangedRemotely = remoteFile.updatetimems > localFile.uploadTime; if (fileChangedRemotely && fileChangedLocally) { diff --git a/Sources/Backup/OACollectLocalFilesTask.m b/Sources/Backup/OACollectLocalFilesTask.m index baaba57551..eedabbed7e 100644 --- a/Sources/Backup/OACollectLocalFilesTask.m +++ b/Sources/Backup/OACollectLocalFilesTask.m @@ -107,7 +107,11 @@ - (void) execute { fileName = f.lastPathComponent; NSDictionary *attrs = [fileManager attributesOfItemAtPath:f error:nil]; - [self createLocalFile:result item:item fileName:fileName filePath:f lastModified:attrs.fileModificationDate.timeIntervalSince1970]; + [self createLocalFile:result + item:item + fileName:fileName + filePath:f + lastModified:attrs.fileModificationDate.timeIntervalSince1970 * 1000]; } } } @@ -119,18 +123,30 @@ - (void) execute if ([filePath.pathExtension.lowerCase isEqualToString:@"sqlitedb"]) { NSDictionary *attrs = [fileManager attributesOfItemAtPath:filePath error:nil]; - [self createLocalFile:result item:item fileName:fileName filePath:filePath lastModified:attrs.fileModificationDate.timeIntervalSince1970]; + [self createLocalFile:result + item:item + fileName:fileName + filePath:filePath + lastModified:attrs.fileModificationDate.timeIntervalSince1970 * 1000]; } } else { NSDictionary *attrs = [fileManager attributesOfItemAtPath:filePath error:nil]; - [self createLocalFile:result item:item fileName:fileName filePath:filePath lastModified:attrs.fileModificationDate.timeIntervalSince1970]; + [self createLocalFile:result + item:item + fileName:fileName + filePath:filePath + lastModified:attrs.fileModificationDate.timeIntervalSince1970 * 1000]; } } else { - [self createLocalFile:result item:item fileName:fileName filePath:nil lastModified:item.lastModifiedTime]; + [self createLocalFile:result + item:item + fileName:fileName + filePath:nil + lastModified:item.lastModifiedTime]; } } dispatch_async(dispatch_get_main_queue(), ^{ @@ -160,9 +176,9 @@ - (void) createLocalFile:(NSMutableArray *)result item:(OASetting localFile.uploadTime = fileInfo.uploadTime; NSString *lastMd5 = fileInfo.md5Digest; BOOL needM5Digest = [item isKindOfClass:OAFileSettingsItem.class] - && ((OAFileSettingsItem *) item).needMd5Digest - && localFile.uploadTime < lastModifiedTime - && lastMd5.length > 0; + && ((OAFileSettingsItem *) item).needMd5Digest + && localFile.uploadTime < lastModifiedTime + && lastMd5.length > 0; if (needM5Digest && filePath && [NSFileManager.defaultManager fileExistsAtPath:filePath]) { NSString *md5 = [OAUtilities fileMD5:filePath]; diff --git a/Sources/Backup/OAImportBackupTask.m b/Sources/Backup/OAImportBackupTask.m index 5332be226c..75c63caac4 100644 --- a/Sources/Backup/OAImportBackupTask.m +++ b/Sources/Backup/OAImportBackupTask.m @@ -176,15 +176,6 @@ - (void)fetchRemoteFileInfo:(OARemoteFile *)remoteFile itemsJson:(NSMutableArray } } -- (void)updateFileUploadTime:(OAPrepareBackupResult *)backup backupHelper:(OABackupHelper *)backupHelper fileName:(NSString *)fileName item:(OASettingsItem *)item { - if (fileName) - { - OARemoteFile *remoteFile = [backup getRemoteFile:[OASettingsItemType typeName:item.type] fileName:fileName]; - if (remoteFile) - [backupHelper updateFileUploadTime:remoteFile.type fileName:remoteFile.name uploadTime:remoteFile.clienttimems]; - } -} - - (NSArray *) doInBackground { switch (_importType) { diff --git a/Sources/Backup/OANetworkWriter.mm b/Sources/Backup/OANetworkWriter.mm index ee2dfbfd57..659548ed37 100644 --- a/Sources/Backup/OANetworkWriter.mm +++ b/Sources/Backup/OANetworkWriter.mm @@ -124,7 +124,7 @@ - (NSString *) uploadItemInfo:(OASettingsItem *)item fileName:(NSString *)fileNa { _item = item; _isDirListener = NO; - return [_backupHelper uploadFile:fileName type:[OASettingsItemType typeName:item.type] data:[NSData dataWithContentsOfFile:filePath.toNSString() options:NSDataReadingMappedAlways error:NULL] size:-1 lastModifiedTime:item.lastModifiedTime * 1000 listener:self]; + return [_backupHelper uploadFile:fileName type:[OASettingsItemType typeName:item.type] data:[NSData dataWithContentsOfFile:filePath.toNSString() options:NSDataReadingMappedAlways error:NULL] size:-1 lastModifiedTime:item.lastModifiedTime listener:self]; } } return nil; @@ -177,7 +177,7 @@ - (NSString *)uploadItemFile:(OASettingsItemWriter *)itemWriter size = attrs.fileSize / 1024; } } - return [_backupHelper uploadFile:fileName type:type data:data size:(int) size lastModifiedTime:(item.lastModifiedTime * 1000) listener:self]; + return [_backupHelper uploadFile:fileName type:type data:data size:(int) size lastModifiedTime:item.lastModifiedTime listener:self]; } } @@ -229,11 +229,13 @@ - (NSString *)uploadDirWithFiles:(OASettingsItemWriter *)itemWriter // MARK: OAOnUploadFileListener -- (BOOL)isUploadCancelled { +- (BOOL)isUploadCancelled +{ return self.isCancelled; } -- (void)onFileUploadDone:(NSString *)type fileName:(NSString *)fileName uploadTime:(long)uploadTime error:(NSString *)error { +- (void)onFileUploadDone:(NSString *)type fileName:(NSString *)fileName uploadTime:(long)uploadTime error:(NSString *)error +{ if ([_item isKindOfClass:OAFileSettingsItem.class]) { OAFileSettingsItem *fileItem = (OAFileSettingsItem *) _item; @@ -253,12 +255,14 @@ - (void)onFileUploadDone:(NSString *)type fileName:(NSString *)fileName uploadTi } } -- (void)onFileUploadProgress:(NSString *)type fileName:(NSString *)fileName progress:(NSInteger)progress deltaWork:(NSInteger)deltaWork { +- (void)onFileUploadProgress:(NSString *)type fileName:(NSString *)fileName progress:(NSInteger)progress deltaWork:(NSInteger)deltaWork +{ if (_listener != nil) [_listener onItemUploadProgress:_item fileName:fileName progress:progress deltaWork:deltaWork]; } -- (void)onFileUploadStarted:(NSString *)type fileName:(NSString *)fileName work:(NSInteger)work { +- (void)onFileUploadStarted:(NSString *)type fileName:(NSString *)fileName work:(NSInteger)work +{ if (_isDirListener) { _uploadStarted = YES; diff --git a/Sources/Backup/OARemoteFile.m b/Sources/Backup/OARemoteFile.m index 469e50c93f..dc033419fb 100644 --- a/Sources/Backup/OARemoteFile.m +++ b/Sources/Backup/OARemoteFile.m @@ -79,15 +79,15 @@ - (BOOL)isEqual:(id)object OARemoteFile *that = (OARemoteFile *) object; return _identifier == that.identifier && - _userid == that.userid && - _deviceid == that.deviceid && - _filesize == that.filesize && - _updatetimems == that.updatetimems && - _clienttimems == that.clienttimems && - [_type isEqualToString:that.type] && - [_name isEqualToString:that.name] && - [_updatetime isEqual:that.updatetime] && - [_clienttime isEqual:that.clienttime]; + _userid == that.userid && + _deviceid == that.deviceid && + _filesize == that.filesize && + _updatetimems == that.updatetimems && + _clienttimems == that.clienttimems && + [_type isEqualToString:that.type] && + [_name isEqualToString:that.name] && + [_updatetime isEqual:that.updatetime] && + [_clienttime isEqual:that.clienttime]; } - (NSUInteger) hash diff --git a/Sources/Backup/TrashItem.swift b/Sources/Backup/TrashItem.swift index 33c214a58c..fcfcfb5c42 100644 --- a/Sources/Backup/TrashItem.swift +++ b/Sources/Backup/TrashItem.swift @@ -21,7 +21,7 @@ final class TrashItem: NSObject { } var time: Int { - deletedFile.updatetimems / 1000 + deletedFile.updatetimems } var name: String { @@ -34,7 +34,7 @@ final class TrashItem: NSObject { var descr: String { let deleted = localizedString("shared_string_deleted") - let formattedTime = BackupUiUtils.formatPassedTime(time: time, longPattern: "MMM d, HH:mm", shortPattern: "HH:mm", def: "") + let formattedTime = BackupUiUtils.formatPassedTime(time: time / 1000, longPattern: "MMM d, HH:mm", shortPattern: "HH:mm", def: "") return String(format: localizedString("ltr_or_rtl_combine_via_colon"), deleted, formattedTime) } diff --git a/Sources/Controllers/Cloud/CloudTrashViewController.swift b/Sources/Controllers/Cloud/CloudTrashViewController.swift index efdda9fe62..14634ad23d 100644 --- a/Sources/Controllers/Cloud/CloudTrashViewController.swift +++ b/Sources/Controllers/Cloud/CloudTrashViewController.swift @@ -148,7 +148,7 @@ final class CloudTrashViewController: OABaseNavbarViewController, OAOnPrepareBac }) for item in items { - let time: Int = item.time + let time: Int = item.time / 1000 let name = dateFormatter.string(from: Date(timeIntervalSince1970: TimeInterval(time))).capitalized var group: TrashGroup? = groups[name] if group == nil { diff --git a/Sources/Controllers/Cloud/OAStatusBackupConflictDetailsViewController.m b/Sources/Controllers/Cloud/OAStatusBackupConflictDetailsViewController.m index 91b555699c..64970aa038 100644 --- a/Sources/Controllers/Cloud/OAStatusBackupConflictDetailsViewController.m +++ b/Sources/Controllers/Cloud/OAStatusBackupConflictDetailsViewController.m @@ -160,8 +160,8 @@ - (void)generateData else if (self.delegate) { long timeMs = _recentChangesType == EOARecentChangesLocal || _recentChangesType == EOARecentChangesConflicts - ? _localFile.localModifiedTime * 1000 - : _recentChangesType == EOARecentChangesRemote && deleteOperation ? _localFile.uploadTime : _remoteFile.updatetimems; + ? _localFile.localModifiedTime + : _recentChangesType == EOARecentChangesRemote && deleteOperation ? _localFile.uploadTime : _remoteFile.updatetimems; NSString *summary = OALocalizedString(deleteOperation && _recentChangesType != EOARecentChangesLocal ? @"poi_remove_success" : @"shared_string_modified"); [itemInfoRow setDescr:[self.delegate generateTimeString:timeMs summary:summary]]; } @@ -313,9 +313,9 @@ - (OATableRowData *)populateUploadAction if (deleteOperation) { description = _recentChangesType == EOARecentChangesLocal - ? OALocalizedString(@"cloud_version_will_be_removed") - : [self.delegate generateTimeString:_localFile.localModifiedTime * 1000 - summary:OALocalizedString(@"shared_string_modified")]; + ? OALocalizedString(@"cloud_version_will_be_removed") + : [self.delegate generateTimeString:_localFile.localModifiedTime + summary:OALocalizedString(@"shared_string_modified")]; } else if (!_localFile) { @@ -323,7 +323,7 @@ - (OATableRowData *)populateUploadAction } else { - description = [self.delegate generateTimeString:_localFile.item.localModifiedTime * 1000 + description = [self.delegate generateTimeString:_localFile.item.localModifiedTime summary:OALocalizedString(@"shared_string_modified")]; if (_recentChangesType == EOARecentChangesRemote) { diff --git a/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm b/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm index 8c554b3638..cb646a896c 100644 --- a/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm +++ b/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm @@ -414,7 +414,7 @@ - (OATableRowData *)rowFromKey:(NSString *)key if (!settingsItem) settingsItem = localFile.item; } - + NSString *name = @""; if ([settingsItem isKindOfClass:OAProfileSettingsItem.class]) { @@ -436,13 +436,13 @@ - (OATableRowData *)rowFromKey:(NSString *)key { name = OALocalizedString(@"res_unknown"); } - + long timeMs = 0; if (_tableType == EOARecentChangesLocal && operation == EOABackupSyncOperationDelete) timeMs = remoteFile.clienttimems; - else if (_tableType == EOARecentChangesLocal || _tableType == EOARecentChangesConflicts) - timeMs = localFile.localModifiedTime * 1000; - else if (operation == EOABackupSyncOperationDelete) + else if (_tableType == EOARecentChangesLocal) + timeMs = localFile.localModifiedTime; + else if (_tableType == EOARecentChangesConflicts || operation == EOABackupSyncOperationDelete) timeMs = localFile.uploadTime; else timeMs = remoteFile.updatetimems; diff --git a/Sources/Controllers/Settings/OSMEditing/OAOsmUploadGPXViewConroller.m b/Sources/Controllers/Settings/OSMEditing/OAOsmUploadGPXViewConroller.m index 5e3dbf7a58..b0e3e952cc 100644 --- a/Sources/Controllers/Settings/OSMEditing/OAOsmUploadGPXViewConroller.m +++ b/Sources/Controllers/Settings/OSMEditing/OAOsmUploadGPXViewConroller.m @@ -665,7 +665,7 @@ - (void)onFileUploadDone:(NSString *)type fileName:(NSString *)fileName uploadTi [_failedFileNames addObject:fileName]; dispatch_async(dispatch_get_main_queue(), ^{ - [self setProgress: 100 fileName:fileName]; + [self setProgress:100 fileName:fileName]; }); } diff --git a/Sources/Helpers/OAAvoidSpecificRoads.mm b/Sources/Helpers/OAAvoidSpecificRoads.mm index 4ee4a9ba5e..50278088c6 100644 --- a/Sources/Helpers/OAAvoidSpecificRoads.mm +++ b/Sources/Helpers/OAAvoidSpecificRoads.mm @@ -299,7 +299,7 @@ - (void) updateListeners - (long) getLastModifiedTime { - return _lastModifiedTime.get; + return [_lastModifiedTime get]; } - (void) setLastModifiedTime:(long)lastModifiedTime diff --git a/Sources/Helpers/OAFavoritesHelper.h b/Sources/Helpers/OAFavoritesHelper.h index e0ddb25013..f03cfe4ddb 100644 --- a/Sources/Helpers/OAFavoritesHelper.h +++ b/Sources/Helpers/OAFavoritesHelper.h @@ -49,6 +49,7 @@ + (BOOL) editFavorite:(OAFavoriteItem *)item lat:(double)lat lon:(double)lon; + (BOOL) editFavorite:(OAFavoriteItem *)item lat:(double)lat lon:(double)lon description:(NSString *)description; + (void) saveCurrentPointsIntoFile; ++ (void) saveCurrentPointsIntoFile:(BOOL)async; + (void)updateGroup:(OAFavoriteGroup *)group newName:(NSString *)newName @@ -87,6 +88,7 @@ + (NSDictionary *) checkDuplicates:(OAFavoriteItem *)point; + (void) sortAll; ++ (void) loadFavorites; + (void) recalculateCachedFavPoints; + (NSArray *) getFlatBackgroundIconNamesList; diff --git a/Sources/Helpers/OAFavoritesHelper.mm b/Sources/Helpers/OAFavoritesHelper.mm index 18519a149e..68fa2af626 100644 --- a/Sources/Helpers/OAFavoritesHelper.mm +++ b/Sources/Helpers/OAFavoritesHelper.mm @@ -340,7 +340,7 @@ + (BOOL)addFavorites:(NSArray *)favorites } if (res) { - _favoritesCollection->addFavoriteLocations(favoriteLocations, sortAndSave); + _favoritesCollection->addFavoriteLocations(favoriteLocations, true); [[OAAppSettings sharedManager] setShowFavorites:YES]; if (sortAndSave) { @@ -538,6 +538,11 @@ + (void)updateGroup:(OAFavoriteGroup *)group } + (void) saveCurrentPointsIntoFile +{ + [self saveCurrentPointsIntoFile:YES]; +} + ++ (void) saveCurrentPointsIntoFile:(BOOL)async { [_favQueue cancelAllOperations]; @@ -588,7 +593,7 @@ + (void) saveCurrentPointsIntoFile [self backup]; }]; - [_favQueue addOperation:operation]; + [_favQueue addOperations:@[operation] waitUntilFinished:!async]; } + (NSArray *)getPointsFromGroups:(NSArray *)groups diff --git a/Sources/Helpers/OANetworkUtilities.h b/Sources/Helpers/OANetworkUtilities.h index 4978c2cf9d..6617e8b167 100644 --- a/Sources/Helpers/OANetworkUtilities.h +++ b/Sources/Helpers/OANetworkUtilities.h @@ -46,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN async:(BOOL)async onComplete:(nullable void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))onComplete; -+ (void) uploadFile:(NSString *)url fileName:(NSString *)fileName params:(NSDictionary *)params headers:(NSDictionary *)headers data:(NSData *)data gzip:(BOOL)gzip autorizationHeader:(NSString *)autorizationHeader progress:(OAURLSessionProgress *)progress onComplete:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))onComplete; ++ (void) uploadFile:(NSString *)url fileName:(NSString *)fileName params:(NSDictionary *)params headers:(NSDictionary *)headers data:(NSData *)data gzip:(BOOL)gzip autorizationHeader:(NSString * _Nullable)autorizationHeader progress:(OAURLSessionProgress *)progress onComplete:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))onComplete; + (BOOL) downloadFile:(NSString *)fileName url:(NSString *)url progress:(OAURLSessionProgress *)progress; diff --git a/Sources/History/OAHistoryDB.mm b/Sources/History/OAHistoryDB.mm index 5616b10ae1..3b9d69dd92 100644 --- a/Sources/History/OAHistoryDB.mm +++ b/Sources/History/OAHistoryDB.mm @@ -465,12 +465,12 @@ - (long)getMarkersHistoryLastModifiedTime lastModifiedTime = [self getDBLastModifiedTime]; [OABackupHelper setLastModifiedTime:MARKERS_HISTORY_LAST_MODIFIED_NAME lastModifiedTime:lastModifiedTime]; } - return lastModifiedTime; + return lastModifiedTime * 1000; } - (void) setMarkersHistoryLastModifiedTime:(long)lastModified { - [OABackupHelper setLastModifiedTime:MARKERS_HISTORY_LAST_MODIFIED_NAME lastModifiedTime:lastModified]; + [OABackupHelper setLastModifiedTime:MARKERS_HISTORY_LAST_MODIFIED_NAME lastModifiedTime:lastModified / 1000]; } - (long) getDBLastModifiedTime diff --git a/Sources/History/OAHistoryHelper.m b/Sources/History/OAHistoryHelper.m index 91366c930e..46e4d87a0c 100644 --- a/Sources/History/OAHistoryHelper.m +++ b/Sources/History/OAHistoryHelper.m @@ -42,7 +42,7 @@ - (instancetype)init - (long) getMarkersHistoryLastModifiedTime { - return _db.getMarkersHistoryLastModifiedTime; + return [_db getMarkersHistoryLastModifiedTime]; } - (void) setMarkersHistoryLastModifiedTime:(long)lastModified diff --git a/Sources/OsmEdit/OAOsmBugsDBHelper.m b/Sources/OsmEdit/OAOsmBugsDBHelper.m index 36cc21f1c4..fd4e9239d8 100644 --- a/Sources/OsmEdit/OAOsmBugsDBHelper.m +++ b/Sources/OsmEdit/OAOsmBugsDBHelper.m @@ -121,12 +121,12 @@ - (long)getLastModifiedTime lastModifiedTime = [self getDBLastModifiedTime]; [OABackupHelper setLastModifiedTime:OSMBUGS_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModifiedTime]; } - return lastModifiedTime; + return lastModifiedTime * 1000; } - (void) setLastModifiedTime:(long)lastModified { - [OABackupHelper setLastModifiedTime:OSMBUGS_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModified]; + [OABackupHelper setLastModifiedTime:OSMBUGS_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModified / 1000]; } - (long) getDBLastModifiedTime diff --git a/Sources/OsmEdit/OAOsmEditsDBHelper.m b/Sources/OsmEdit/OAOsmEditsDBHelper.m index d22ad7e3b3..b848956d2b 100644 --- a/Sources/OsmEdit/OAOsmEditsDBHelper.m +++ b/Sources/OsmEdit/OAOsmEditsDBHelper.m @@ -126,12 +126,12 @@ - (long)getLastModifiedTime lastModifiedTime = [self getDBLastModifiedTime]; [OABackupHelper setLastModifiedTime:OPENSTREETMAP_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModifiedTime]; } - return lastModifiedTime; + return lastModifiedTime * 1000; } - (void) setLastModifiedTime:(long)lastModified { - [OABackupHelper setLastModifiedTime:OPENSTREETMAP_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModified]; + [OABackupHelper setLastModifiedTime:OPENSTREETMAP_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModified / 1000]; } - (long) getDBLastModifiedTime diff --git a/Sources/POI/OAPOIFiltersHelper.mm b/Sources/POI/OAPOIFiltersHelper.mm index 2dc640cca6..87cfcac9f2 100644 --- a/Sources/POI/OAPOIFiltersHelper.mm +++ b/Sources/POI/OAPOIFiltersHelper.mm @@ -371,12 +371,12 @@ - (long)getLastModifiedTime lastModifiedTime = [self getDBLastModifiedTime]; [OABackupHelper setLastModifiedTime:FILTERS_LAST_MODIFIED_NAME lastModifiedTime:lastModifiedTime]; } - return lastModifiedTime; + return lastModifiedTime * 1000; } - (void) setLastModifiedTime:(long)lastModified { - [OABackupHelper setLastModifiedTime:FILTERS_LAST_MODIFIED_NAME lastModifiedTime:lastModified]; + [OABackupHelper setLastModifiedTime:FILTERS_LAST_MODIFIED_NAME lastModifiedTime:lastModified / 1000]; } - (long) getDBLastModifiedTime From 20fb0b7319e5bf5fd74d7c2063dde881c2fb8c88 Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 10 Jan 2025 13:32:21 +0200 Subject: [PATCH 3/8] sync cloud code with android; code cleanup; --- .../Backup/Commands/OADeleteFilesCommand.m | 2 + Sources/Backup/OABackupExporter.m | 54 +++++++++---------- Sources/Backup/OABackupHelper.mm | 27 ++++------ Sources/Backup/OABackupImporter.m | 37 +++++++++---- Sources/Backup/OAExportBackupTask.m | 34 ++++++------ Sources/Backup/OAImportBackupItemsTask.m | 10 ++-- Sources/Backup/OAImportBackupTask.m | 21 +++++--- Sources/Backup/OANetworkSettingsHelper.m | 23 ++++++-- Sources/Backup/OAPrepareBackupResult.m | 8 ++- Sources/Backup/OASyncBackupTask.mm | 36 ++++++------- 10 files changed, 139 insertions(+), 113 deletions(-) diff --git a/Sources/Backup/Commands/OADeleteFilesCommand.m b/Sources/Backup/Commands/OADeleteFilesCommand.m index 143049f1cd..3aeaea1053 100644 --- a/Sources/Backup/Commands/OADeleteFilesCommand.m +++ b/Sources/Backup/Commands/OADeleteFilesCommand.m @@ -28,7 +28,9 @@ - (void) onPreExecute { [super onPreExecute]; for (id listener in [self getListeners]) + { [listener onFilesDeleteStarted:_remoteFiles]; + } } - (void) doInBackground diff --git a/Sources/Backup/OABackupExporter.m b/Sources/Backup/OABackupExporter.m index f4a061a2e2..3813cdf4bc 100644 --- a/Sources/Backup/OABackupExporter.m +++ b/Sources/Backup/OABackupExporter.m @@ -88,7 +88,8 @@ @implementation OABackupExporter - (instancetype) initWithListener:(id)listener { self = [super initWithListener:nil]; - if (self) { + if (self) + { _itemsToDelete = [NSMutableArray array]; _localItemsToDelete = [NSMutableArray array]; _oldFilesToDelete = [[OAConcurrentArray alloc] init]; @@ -144,22 +145,16 @@ - (void) writeItems:(OAAbstractWriter *)writer subscriptionError = error; }]; if (subscriptionError.length > 0) - { @throw [NSException exceptionWithName:@"IOException" reason:subscriptionError userInfo:nil]; - } NSMutableArray *lightTasks = [NSMutableArray array]; NSMutableArray *heavyTasks = [NSMutableArray array]; for (OASettingsItem *item in self.getItems) { if (item.getEstimatedSize > MAX_LIGHT_ITEM_SIZE) - { [heavyTasks addObject:[[OAItemWriterTask alloc] initWithWriter:writer item:item]]; - } else - { [lightTasks addObject:[[OAItemWriterTask alloc] initWithWriter:writer item:item]]; - } } if (lightTasks.count > 0) { @@ -167,11 +162,13 @@ - (void) writeItems:(OAAbstractWriter *)writer _executor.maxConcurrentOperationCount = 10; [_executor addOperations:lightTasks waitUntilFinished:YES]; for (OAItemWriterTask *task in lightTasks) + { if (task.error) { [log finishOperation]; @throw [NSException exceptionWithName:@"IOException" reason:task.error userInfo:nil]; } + } } if (heavyTasks.count > 0) { @@ -179,11 +176,13 @@ - (void) writeItems:(OAAbstractWriter *)writer _executor.maxConcurrentOperationCount = 1; [_executor addOperations:heavyTasks waitUntilFinished:YES]; for (OAItemWriterTask *task in heavyTasks) + { if (task.error) { [log finishOperation]; @throw [NSException exceptionWithName:@"IOException" reason:task.error userInfo:nil]; } + } } [log finishOperation]; } @@ -219,15 +218,11 @@ - (void) deleteFiles:(id)listener for (OASettingsItem *item in itemsToDelete) { if ([item isEqual:remoteFile.item]) - { [remoteFiles addObject:remoteFile]; - } } } if (remoteFiles.count > 0) - { [_backupHelper deleteFilesSync:remoteFiles byVersion:NO listener:listener]; - } } } @catch (NSException *e) @@ -238,11 +233,10 @@ - (void) deleteFiles:(id)listener - (void) deleteOldFiles:(id)listener { - @try { + @try + { if (_oldFilesToDelete.countSync > 0) - { [_backupHelper deleteFilesSync:_oldFilesToDelete.asArray byVersion:YES listener:listener]; - } } @catch (NSException *e) { @@ -288,29 +282,23 @@ - (void) markOldFileForDeletion:(OASettingsItem *)item fileName:(NSString *)file // MARK: OAOnUploadItemListener -- (void)onItemFileUploadDone:(nonnull OASettingsItem *)item fileName:(nonnull NSString *)fileName uploadTime:(long)uploadTime error:(nonnull NSString *)error { +- (void)onItemFileUploadDone:(nonnull OASettingsItem *)item fileName:(nonnull NSString *)fileName uploadTime:(long)uploadTime error:(nonnull NSString *)error +{ NSString *type = [OASettingsItemType typeName:item.type]; if (error.length > 0) - { [_errors setObjectSync:error forKey:[NSString stringWithFormat:@"%@/%@", type, fileName]]; - } else - { [self markOldFileForDeletion:item fileName:fileName]; - } int p = [_dataProgress addAndGet:(APPROXIMATE_FILE_SIZE_BYTES / 1024)]; if (_listener != nil) - { [_listener updateGeneralProgress:_itemsProgress.countSync uploadedKb:(NSInteger)p]; - } } -- (void)onItemUploadDone:(nonnull OASettingsItem *)item fileName:(nonnull NSString *)fileName error:(nonnull NSString *)error { +- (void)onItemUploadDone:(nonnull OASettingsItem *)item fileName:(nonnull NSString *)fileName error:(nonnull NSString *)error +{ NSString *type = [OASettingsItemType typeName:item.type]; if (error.length > 0) - { [_errors setObjectSync:error forKey:[NSString stringWithFormat:@"%@/%@", type, fileName]]; - } [_itemsProgress addObjectSync:item]; if (_listener) { @@ -319,7 +307,8 @@ - (void)onItemUploadDone:(nonnull OASettingsItem *)item fileName:(nonnull NSStri } } -- (void)onItemUploadProgress:(nonnull OASettingsItem *)item fileName:(nonnull NSString *)fileName progress:(NSInteger)progress deltaWork:(NSInteger)deltaWork { +- (void)onItemUploadProgress:(nonnull OASettingsItem *)item fileName:(nonnull NSString *)fileName progress:(NSInteger)progress deltaWork:(NSInteger)deltaWork +{ NSInteger p = [_dataProgress addAndGet:(int) deltaWork]; if (_listener) { @@ -328,7 +317,8 @@ - (void)onItemUploadProgress:(nonnull OASettingsItem *)item fileName:(nonnull NS } } -- (void)onItemUploadStarted:(nonnull OASettingsItem *)item fileName:(nonnull NSString *)fileName work:(NSInteger)work { +- (void)onItemUploadStarted:(nonnull OASettingsItem *)item fileName:(nonnull NSString *)fileName work:(NSInteger)work +{ if (_listener) [_listener itemExportStarted:[OASettingsItemType typeName:item.type] fileName:fileName work:work]; } @@ -336,7 +326,8 @@ - (void)onItemUploadStarted:(nonnull OASettingsItem *)item fileName:(nonnull NSS // MARK: OAOnDeleteFilesListener -- (void)onFileDeleteProgress:(OARemoteFile *)file progress:(NSInteger)progress { +- (void)onFileDeleteProgress:(OARemoteFile *)file progress:(NSInteger)progress +{ int p = [_dataProgress addAndGet:(APPROXIMATE_FILE_SIZE_BYTES / 1024)]; [_itemsProgress addObjectSync:file]; if (_listener != nil) @@ -346,13 +337,16 @@ - (void)onFileDeleteProgress:(OARemoteFile *)file progress:(NSInteger)progress { } } -- (void)onFilesDeleteDone:(NSDictionary *)errors { +- (void)onFilesDeleteDone:(NSDictionary *)errors +{ } -- (void)onFilesDeleteError:(NSInteger)status message:(NSString *)message { +- (void)onFilesDeleteError:(NSInteger)status message:(NSString *)message +{ } -- (void)onFilesDeleteStarted:(NSArray *)files { +- (void)onFilesDeleteStarted:(NSArray *)files +{ } @end diff --git a/Sources/Backup/OABackupHelper.mm b/Sources/Backup/OABackupHelper.mm index b9161984d7..f37d130c1b 100644 --- a/Sources/Backup/OABackupHelper.mm +++ b/Sources/Backup/OABackupHelper.mm @@ -140,6 +140,11 @@ + (BOOL) isTokenValid:(NSString *)token [itemsForRestore addObject:restoreItem]; } } + [itemsForRestore sortUsingComparator:^NSComparisonResult(OASettingsItem *item1, OASettingsItem *item2) { + long time1 = item1.lastModifiedTime; + long time2 = item2.lastModifiedTime; + return time1 < time2 ? NSOrderedDescending : time1 > time2 ? NSOrderedAscending : NSOrderedSame; + }]; return itemsForRestore; } @@ -147,9 +152,7 @@ + (BOOL) isTokenValid:(NSString *)token { NSMutableDictionary *itemsForRestore = [NSMutableDictionary dictionary]; if (info != nil) - { [itemsForRestore addEntriesFromDictionary:[self getRemoteFilesSettingsItems:settingsItems remoteFiles:info.filteredFilesToDownload infoFiles:NO]]; - } return itemsForRestore; } @@ -207,13 +210,9 @@ + (BOOL) applyItem:(OASettingsItem *)item type:(NSString *)type name:(NSString * if ([name hasPrefix:subfolder] || subfolder.length == 0) { if (fileItem.filePath.pathExtension.length == 0 && ![itemFileName hasSuffix:@"/"]) - { return [name hasPrefix:[itemFileName stringByAppendingString:@"/"]]; - } else - { return [name hasPrefix:itemFileName]; - } } } } @@ -235,9 +234,7 @@ + (NSString *) getItemFileName:(OASettingsItem *)item fileName = item.defaultFileName; } if (fileName.length > 0 && [fileName characterAtIndex:0] == '/') - { fileName = [fileName substringFromIndex:1]; - } return fileName; } @@ -437,9 +434,7 @@ - (OACommonBoolean *) getVersionHistoryTypePref:(OAExportSettingsType *)type { NSString *fileName = remoteFile.item.fileName; if (fileName != nil && [item applyFileName:fileName]) - { [filesToUpload addObject:((OAFileSettingsItem *) remoteFile.item).filePath]; - } } } } @@ -489,9 +484,7 @@ - (void) updateOrderId:(void(^)(NSInteger status, NSString *message, NSString *e { NSString *orderId = [self getOrderId]; if (orderId.length == 0) - { return; - } NSMutableDictionary *params = [NSMutableDictionary dictionary]; params[@"email"] = [self getEmail]; params[@"orderid"] = orderId; @@ -661,9 +654,7 @@ - (NSInteger)calculateFileSize:(OARemoteFile *)remoteFile NSString *mapId = flItem.fileName.lowerCase; const auto res = _app.resourcesManager->getResourceInRepository(QString::fromNSString(mapId)); if (res) - { sz = res->size / 1024; - } } } return sz; @@ -854,13 +845,9 @@ - (NSString *) uploadFile:(NSString *)fileName } } if (error == nil && [status isEqualToString:@"ok"]) - { [self updateFileUploadTime:type fileName:fileName uploadTime:uploadTime]; - } if (listener != nil) - { [listener onFileUploadDone:type fileName:fileName uploadTime:uploadTime error:error]; - } [operationLog finishOperation:[NSString stringWithFormat:@"%@ %@ %@", type, fileName, (error ? [NSString stringWithFormat:@"Error: %@", [[OABackupError alloc] initWithError:error].getLocalizedError] : @"OK")]]; return error; } @@ -938,14 +925,18 @@ - (BOOL) isObfMapExistsOnServer:(NSString *)name - (void)onBackupPreparing { for (id listener in _prepareBackupListeners) + { [listener onBackupPreparing]; + } } - (void)onBackupPrepared:(OAPrepareBackupResult *)backupResult { _prepareBackupTask = nil; for (id listener in _prepareBackupListeners) + { [listener onBackupPrepared:backupResult]; + } } @end diff --git a/Sources/Backup/OABackupImporter.m b/Sources/Backup/OABackupImporter.m index 94a3764698..0914ed5108 100644 --- a/Sources/Backup/OABackupImporter.m +++ b/Sources/Backup/OABackupImporter.m @@ -81,7 +81,8 @@ @implementation OAFileDownloadTask - (instancetype)initWithFilePath:(NSString *)filePath remoteFile:(OARemoteFile *)remoteFile onDownloadFileListener:(id)onDownloadFileListener { self = [super init]; - if (self) { + if (self) + { _filePath = filePath; _remoteFile = remoteFile; _onDownloadFileListener = onDownloadFileListener; @@ -117,7 +118,8 @@ @implementation OAItemFileImportTask - (instancetype) initWithRemoteFile:(OARemoteFile *)remoteFile item:(OASettingsItem *)item importer:(OABackupImporter *)importer forceReadData:(BOOL)forceReadData { self = [super init]; - if (self) { + if (self) + { _remoteFile = remoteFile; _item = item; _forceReadData = forceReadData; @@ -150,7 +152,8 @@ @implementation OABackupImporter - (instancetype) initWithListener:(id)listener { self = [super init]; - if (self) { + if (self) + { _listener = listener; _backupHelper = OABackupHelper.sharedInstance; _queue = [[NSOperationQueue alloc] init]; @@ -170,7 +173,8 @@ - (OACollectItemsResult *) collectItems:(NSArray *)settingsIte __block NSString *error = nil; OAOperationLog *operationLog = [[OAOperationLog alloc] initWithOperationName:@"collectRemoteItems" debug:BACKUP_DEBUG_LOGS]; [operationLog startOperation]; - @try { + @try + { [_backupHelper downloadFileList:^(NSInteger status, NSString * _Nonnull message, NSArray * _Nonnull remoteFiles) { if (status == STATUS_SUCCESS) { @@ -180,9 +184,12 @@ - (OACollectItemsResult *) collectItems:(NSArray *)settingsIte remoteFiles = items.allKeys; } result.remoteFiles = remoteFiles; - @try { + @try + { result.items = [self getRemoteItems:remoteFiles readItems:readItems restoreDeleted:restoreDeleted]; - } @catch (NSException *e) { + } + @catch (NSException *e) + { error = e.reason; } } @@ -191,7 +198,9 @@ - (OACollectItemsResult *) collectItems:(NSArray *)settingsIte error = message; } }]; - } @catch (NSException *e) { + } + @catch (NSException *e) + { NSLog(@"Failed to collect items for backup"); } [operationLog finishOperation]; @@ -256,7 +265,8 @@ - (void) importItemFile:(OARemoteFile *)remoteFile item:(OASettingsItem *)item f OASettingsItemReader *reader = item.getReader; NSString *fileName = remoteFile.getTypeNamePath; NSString *tempFilePath = [_tmpFilesDir stringByAppendingPathComponent:fileName]; - @try { + @try + { if (reader) { NSString *errorStr = [_backupHelper downloadFile:tempFilePath remoteFile:remoteFile listener:self]; @@ -340,7 +350,8 @@ - (void)updateFileUploadTime:(OARemoteFile *)remoteFile item:(OASettingsItem *)i if (remoteFiles.count == 0) return @[]; NSMutableArray *items = [NSMutableArray array]; - @try { + @try + { OAOperationLog *operationLog = [[OAOperationLog alloc] initWithOperationName:@"getRemoteItems" debug:BACKUP_DEBUG_LOGS]; [operationLog startOperation]; NSMutableDictionary *json = [NSMutableDictionary dictionary]; @@ -541,7 +552,9 @@ - (void) updateFilesInfo:(NSDictionary *)remoteFiles } }]; for (NSString *key in toDelete) + { [remoteFiles removeObjectForKey:key]; + } } return res; } @@ -669,11 +682,13 @@ - (BOOL) hasDownloadErrors:(NSArray *)tasks // MARK: OAOnDownloadFileListener -- (BOOL)isDownloadCancelled { +- (BOOL)isDownloadCancelled +{ return self.cancelled; } -- (void)onFileDownloadDone:(NSString *)type fileName:(NSString *)fileName error:(NSString *)error { +- (void)onFileDownloadDone:(NSString *)type fileName:(NSString *)fileName error:(NSString *)error +{ [_itemsProgress addAndGet:1]; if (_listener) { diff --git a/Sources/Backup/OAExportBackupTask.m b/Sources/Backup/OAExportBackupTask.m index d1533638b6..3547e8549a 100644 --- a/Sources/Backup/OAExportBackupTask.m +++ b/Sources/Backup/OAExportBackupTask.m @@ -51,10 +51,8 @@ - (instancetype) initWithKey:(NSString *)key [_exporter addSettingsItem:item]; OAExportSettingsType *exportType = [OAExportSettingsType findBySettingsItem:item]; - if (exportType && [backupHelper getVersionHistoryTypePref:exportType].get) - { + if (exportType && ![[backupHelper getVersionHistoryTypePref:exportType] get]) [_exporter addOldItemToDelete:item]; - } } for (OASettingsItem *item in itemsToDelete) { @@ -87,7 +85,8 @@ - (NSString *)doInBackground [self publishProgress:@(itemsSize / 1024) isUploadedKb:NO]; NSString *error = nil; - @try { + @try + { [_exporter export]; } @catch (NSException *e) @@ -116,7 +115,9 @@ + (long) getEstimatedItemsSize:(NSArray *)items NSDictionary *attrs = [fileManager attributesOfItemAtPath:file error:nil]; size += attrs.fileSize + APPROXIMATE_FILE_SIZE_BYTES; } - } else { + } + else + { size += [item getEstimatedSize] + APPROXIMATE_FILE_SIZE_BYTES; } } @@ -128,9 +129,7 @@ + (long) getEstimatedItemsSize:(NSArray *)items for (OASettingsItem *item in itemsToDelete) { if ([item isEqual:remoteFile.item]) - { size += APPROXIMATE_FILE_SIZE_BYTES; - } } } for (OARemoteFile *remoteFile in remoteFilesMap.allValues) @@ -142,13 +141,9 @@ + (long) getEstimatedItemsSize:(NSArray *)items { NSString *itemFileName = item.fileName; if (itemFileName != nil && [itemFileName hasPrefix:@"/"]) - { itemFileName = [itemFileName substringFromIndex:1]; - } if ([itemFileName isEqualToString:remoteFileItem.fileName]) - { size += APPROXIMATE_FILE_SIZE_BYTES; - } } } } @@ -160,9 +155,7 @@ + (long) getEstimatedItemsSize:(NSArray *)items for (OASettingsItem *item in localItemsToDelete) { if ([item isEqual:localFile.item]) - { size += APPROXIMATE_FILE_SIZE_BYTES; - } } } } @@ -225,24 +218,29 @@ - (void) onPostExecute:(NSString *)error // MARK: OANetworkExportProgressListener -- (void)itemExportDone:(nonnull NSString *)type fileName:(nonnull NSString *)fileName { +- (void)itemExportDone:(nonnull NSString *)type fileName:(nonnull NSString *)fileName +{ [self publishProgress:[[OAItemProgressInfo alloc] initWithType:type fileName:fileName progress:0 work:0 finished:YES] isUploadedKb:NO]; } -- (void)itemExportStarted:(nonnull NSString *)type fileName:(nonnull NSString *)fileName work:(NSInteger)work { +- (void)itemExportStarted:(nonnull NSString *)type fileName:(nonnull NSString *)fileName work:(NSInteger)work +{ [self publishProgress:[[OAItemProgressInfo alloc] initWithType:type fileName:fileName progress:0 work:work finished:NO] isUploadedKb:NO]; } -- (void)networkExportDone:(nonnull NSDictionary *)errors { +- (void)networkExportDone:(nonnull NSDictionary *)errors +{ } -- (void)updateGeneralProgress:(NSInteger)uploadedItems uploadedKb:(NSInteger)uploadedKb { +- (void)updateGeneralProgress:(NSInteger)uploadedItems uploadedKb:(NSInteger)uploadedKb +{ if (self.isCancelled) [_exporter cancel]; [self publishProgress:@(uploadedKb) isUploadedKb:YES]; } -- (void)updateItemProgress:(nonnull NSString *)type fileName:(nonnull NSString *)fileName progress:(NSInteger)progress { +- (void)updateItemProgress:(nonnull NSString *)type fileName:(nonnull NSString *)fileName progress:(NSInteger)progress +{ [self publishProgress:[[OAItemProgressInfo alloc] initWithType:type fileName:fileName progress:progress work:0 finished:NO] isUploadedKb:NO]; } diff --git a/Sources/Backup/OAImportBackupItemsTask.m b/Sources/Backup/OAImportBackupItemsTask.m index bc24e1150d..d559d84050 100644 --- a/Sources/Backup/OAImportBackupItemsTask.m +++ b/Sources/Backup/OAImportBackupItemsTask.m @@ -30,7 +30,8 @@ - (instancetype) initWithImporter:(OABackupImporter *)importer restoreDeleted:(BOOL)restoreDeleted { self = [super init]; - if (self) { + if (self) + { _importer = importer; _items = items; _filesType = filesType; @@ -51,12 +52,15 @@ - (void) main - (BOOL) doInBackground { - @try { + @try + { OAPrepareBackupResult *backup = [OABackupHelper sharedInstance].backup; NSArray *remoteFiles = [backup getRemoteFiles:_filesType].allValues; [_importer importItems:_items remoteFiles:remoteFiles forceReadData:_foreceReadData restoreDeleted:_restoreDeleted]; return YES; - } @catch (NSException *exception) { + } + @catch (NSException *exception) + { NSLog(@"Failed to import items from backup"); } return NO; diff --git a/Sources/Backup/OAImportBackupTask.m b/Sources/Backup/OAImportBackupTask.m index 75c63caac4..cb2860683f 100644 --- a/Sources/Backup/OAImportBackupTask.m +++ b/Sources/Backup/OAImportBackupTask.m @@ -134,7 +134,9 @@ + (NSInteger) calculateMaxProgress OABackupHelper *backupHelper = OABackupHelper.sharedInstance; OAPrepareBackupResult *backup = backupHelper.backup; for (OARemoteFile *file in backup.backupInfo.filesToDownload) + { maxProgress += [backupHelper calculateFileSize:file]; + } return maxProgress; } @@ -178,7 +180,8 @@ - (void)fetchRemoteFileInfo:(OARemoteFile *)remoteFile itemsJson:(NSMutableArray - (NSArray *) doInBackground { - switch (_importType) { + switch (_importType) + { case EOAImportTypeCollect: case EOAImportTypeCollectAndRead: { @@ -273,7 +276,8 @@ - (void) onPostExecute:(NSArray *)items [OABackupHelper.sharedInstance.executor addOperation:task]; } - else { + else + { [_helper.importAsyncTasks removeObjectForKey:_key]; [_helper finishImport:_importListener success:NO items:@[]]; } @@ -329,25 +333,28 @@ - (void) onProgressUpdate:(OAItemProgressInfo *)info if (info.finished) [_importListener onImportItemFinished:info.type fileName:info.fileName]; else if (info.value == 0) - [_importListener onImportItemStarted:info.type fileName:info.fileName work:info.work]; + [_importListener onImportItemStarted:info.type fileName:info.fileName work:(int) info.work]; else - [_importListener onImportItemProgress:info.type fileName:info.fileName value:info.value]; + [_importListener onImportItemProgress:info.type fileName:info.fileName value:(int) info.value]; } } // MARK: OANetworkImportProgressListener -- (void)itemExportDone:(nonnull NSString *)type fileName:(nonnull NSString *)fileName { +- (void)itemExportDone:(nonnull NSString *)type fileName:(nonnull NSString *)fileName +{ [self onProgressUpdate:[[OAItemProgressInfo alloc] initWithType:type fileName:fileName progress:0 work:0 finished:YES]]; if ([self isCancelled]) _importer.cancelled = YES; } -- (void)itemExportStarted:(nonnull NSString *)type fileName:(nonnull NSString *)fileName work:(NSInteger)work { +- (void)itemExportStarted:(nonnull NSString *)type fileName:(nonnull NSString *)fileName work:(NSInteger)work +{ [self onProgressUpdate:[[OAItemProgressInfo alloc] initWithType:type fileName:fileName progress:0 work:work finished:NO]]; } -- (void)updateItemProgress:(nonnull NSString *)type fileName:(nonnull NSString *)fileName progress:(NSInteger)progress { +- (void)updateItemProgress:(nonnull NSString *)type fileName:(nonnull NSString *)fileName progress:(NSInteger)progress +{ [self onProgressUpdate:[[OAItemProgressInfo alloc] initWithType:type fileName:fileName progress:progress work:0 finished:NO]]; } diff --git a/Sources/Backup/OANetworkSettingsHelper.m b/Sources/Backup/OANetworkSettingsHelper.m index 71ab4dcb0d..8460ce12ce 100644 --- a/Sources/Backup/OANetworkSettingsHelper.m +++ b/Sources/Backup/OANetworkSettingsHelper.m @@ -40,7 +40,8 @@ + (OANetworkSettingsHelper *) sharedInstance - (instancetype) init { self = [super init]; - if (self) { + if (self) + { _backupHelper = [OABackupHelper sharedInstance]; _importAsyncTasks = [NSMutableDictionary dictionary]; _exportAsyncTasks = [NSMutableDictionary dictionary]; @@ -98,7 +99,9 @@ - (BOOL) cancelSyncTasks { BOOL cancelled = YES; for (OASyncBackupTask *syncTask in self.syncBackupTasks.allValues) + { [syncTask cancel]; + } [self.syncBackupTasks removeAllObjects]; return cancelled; } @@ -136,7 +139,9 @@ - (void) updateExportListener:(id)listener - (void) updateImportListener:(id)listener { for (OAImportBackupTask *importTask in self.importAsyncTasks.allValues) + { importTask.importListener = listener; + } } - (void) finishImport:(id)listener success:(BOOL)success items:(NSArray *)items @@ -152,7 +157,9 @@ - (NSString *) collectFormattedWarnings:(NSArray *)items { NSMutableArray *warnings = [NSMutableArray array]; for (OASettingsItem *item in items) + { [warnings addObjectsFromArray:item.warnings]; + } NSString *error = nil; if (warnings.count > 0) error = [OAUtilities formatWarnings:warnings]; @@ -243,15 +250,21 @@ - (void) syncSettingsItems:(NSString *)key { case EOABackupSyncOperationDelete: { - if (remoteFile) - [syncTask deleteItem:remoteFile.item]; + if (remoteFile && ![remoteFile isDeleted]) + { + if (remoteFile.item) + [syncTask deleteItem:remoteFile.item]; + } else if (localFile) - [syncTask deleteLocalItem:localFile.item]; + { + if (localFile.item) + [syncTask deleteLocalItem:localFile.item]; + } break; } case EOABackupSyncOperationUpload: { - if (localFile) + if (localFile && localFile.item) [syncTask uploadLocalItem:localFile.item]; break; } diff --git a/Sources/Backup/OAPrepareBackupResult.m b/Sources/Backup/OAPrepareBackupResult.m index 88035e3d23..fa5ff2d93c 100644 --- a/Sources/Backup/OAPrepareBackupResult.m +++ b/Sources/Backup/OAPrepareBackupResult.m @@ -20,7 +20,8 @@ @implementation OAPrepareBackupResult - (NSDictionary *) getRemoteFiles:(EOARemoteFilesType)type { - switch (type) { + switch (type) + { case EOARemoteFilesTypeUnique: return _uniqueRemoteFiles; case EOARemoteFilesTypeUniqueInfo: @@ -61,7 +62,8 @@ - (void)setRemoteFilesFromArray:(NSArray *)remoteFiles NSMutableDictionary *deletedRemoteFiles = [NSMutableDictionary dictionary];; NSMutableSet *uniqueFileIds = [NSMutableSet set]; [remoteFilesMap enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull fileId, OARemoteFile * _Nonnull file, BOOL * _Nonnull stop) { - if (![uniqueFileIds containsObject:fileId]) { + if (![uniqueFileIds containsObject:fileId]) + { [uniqueFileIds addObject:fileId]; if (file.isInfoFile) uniqueInfoRemoteFiles[fileId] = file; @@ -82,7 +84,9 @@ - (void)setLocalFilesFromArray:(NSArray *)localFiles { NSMutableDictionary *localFileMap = [NSMutableDictionary dictionary]; for (OALocalFile *localFile in localFiles) + { localFileMap[localFile.getTypeFileName] = localFile; + } _localFiles = localFileMap; } diff --git a/Sources/Backup/OASyncBackupTask.mm b/Sources/Backup/OASyncBackupTask.mm index 6b17d50b9d..a6fe93b5fd 100644 --- a/Sources/Backup/OASyncBackupTask.mm +++ b/Sources/Backup/OASyncBackupTask.mm @@ -31,7 +31,6 @@ @implementation OASyncBackupTask { NSString *_key; OABackupHelper *_backupHelper; - NSArray *_settingsItems; NSInteger _maxProgress; NSInteger _importProgress; NSInteger _exportProgress; @@ -45,18 +44,17 @@ @implementation OASyncBackupTask - (instancetype)initWithKey:(NSString *)key operation:(EOABackupSyncOperationType)operation { self = [super init]; - if (self) { + if (self) + { _key = key; _operation = operation; _singleOperation = operation != EOABackupSyncOperationSync; - _backupHelper = OABackupHelper.sharedInstance; - if (!_singleOperation) - [_backupHelper addPrepareBackupListener:self]; - _importProgress = 0; _exportProgress = 0; _maxProgress = 0; _cancelled = NO; + _backupHelper = OABackupHelper.sharedInstance; + [_backupHelper addPrepareBackupListener:self]; } return self; } @@ -76,16 +74,21 @@ - (void)startSync OAPrepareBackupResult *backup = _backupHelper.backup; OABackupInfo *info = backup.backupInfo; - _settingsItems = [OABackupHelper getItemsForRestore:info settingsItems:backup.settingsItems]; + NSArray *settingsItems = [OABackupHelper getItemsForRestore:info settingsItems:backup.settingsItems]; + if (_operation != EOABackupSyncOperationDownload) _maxProgress += ([self calculateExportMaxProgress] / 1024); if (_operation != EOABackupSyncOperationUpload) _maxProgress += [OAImportBackupTask calculateMaxProgress]; [NSNotificationCenter.defaultCenter postNotificationName:kBackupSyncStartedNotification object:nil]; - if (_settingsItems.count > 0 && _operation != EOABackupSyncOperationUpload) + if (settingsItems.count > 0 && _operation != EOABackupSyncOperationUpload) { - [OANetworkSettingsHelper.sharedInstance importSettings:kRestoreItemsKey items:_settingsItems filesType:EOARemoteFilesTypeUnique forceReadData:YES listener:self]; + [OANetworkSettingsHelper.sharedInstance importSettings:kRestoreItemsKey + items:settingsItems + filesType:EOARemoteFilesTypeUnique + forceReadData:YES + listener:self]; } else if (_operation != EOABackupSyncOperationDownload) { @@ -100,7 +103,7 @@ - (void)startSync - (void)execute { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ - if (!_backupHelper.isBackupPreparing) + if (![_backupHelper isBackupPreparing]) [self startSync]; }); } @@ -146,13 +149,9 @@ - (void) uploadNewItems NSArray *itemsToDelete = info.itemsToDelete; NSArray *localItemsToDelete = info.localItemsToDelete; if (itemsToUpload.count > 0 || itemsToDelete.count > 0 || localItemsToDelete.count > 0) - { [OANetworkSettingsHelper.sharedInstance exportSettings:kBackupItemsKey items:itemsToUpload itemsToDelete:itemsToDelete localItemsToDelete:localItemsToDelete listener:self]; - } else - { [self onSyncFinished:nil]; - } } @catch (NSException *e) { @@ -170,9 +169,7 @@ - (NSInteger) calculateExportMaxProgress { OAExportSettingsType *exportType = [OAExportSettingsType findBySettingsItem:item]; if (exportType && [_backupHelper getVersionHistoryTypePref:exportType].get) - { [oldItemsToDelete addObject:item]; - } } return [OAExportBackupTask getEstimatedItemsSize:info.itemsToUpload itemsToDelete:info.itemsToDelete localItemsToDelete:info.localItemsToDelete oldItemsToDelete:oldItemsToDelete]; } @@ -187,8 +184,8 @@ - (void)onBackupPrepared:(nonnull OAPrepareBackupResult *)backupResult [NSNotificationCenter.defaultCenter postNotificationName:kBackupSyncStartedNotification object:nil]; } -- (void)onBackupPreparing { - +- (void)onBackupPreparing +{ } // MARK: OAImportListener @@ -278,7 +275,8 @@ - (void)onBackupExportItemStarted:(NSString *)type fileName:(NSString *)fileName [NSNotificationCenter.defaultCenter postNotificationName:kBackupItemStartedNotification object:nil userInfo:@{@"type": type, @"name": fileName, @"work": @(work)}]; } -- (void)onBackupExportStarted { +- (void)onBackupExportStarted +{ } @end From 362049e3c7490b254dc6e1648706e9978fbbba9d Mon Sep 17 00:00:00 2001 From: Skalii Date: Tue, 14 Jan 2025 00:37:21 +0200 Subject: [PATCH 4/8] sync cloud code with android; code cleanup; --- OsmAnd.xcodeproj/project.pbxproj | 16 +- Sources/AppHost/OsmAndAppImpl.mm | 5 + Sources/AppHost/OsmAndAppProtocol.h | 1 + Sources/AppHost/SceneDelegate.mm | 2 +- Sources/Backup/BackupUtils.swift | 267 ++++++++++++++++++ .../ImportExportData/OAExportSettingsType.h | 2 +- .../ImportExportData/OAExportSettingsType.mm | 43 +-- .../Backup/LocalBackup/OASettingsImporter.mm | 73 ++--- .../SettingsItems/OAFileSettingsItem.mm | 4 +- Sources/Backup/OABackupDbHelper.m | 31 +- Sources/Backup/OABackupError.m | 3 +- Sources/Backup/OABackupExporter.m | 17 +- Sources/Backup/OABackupHelper.h | 24 +- Sources/Backup/OABackupHelper.mm | 236 +--------------- Sources/Backup/OABackupImporter.m | 5 +- Sources/Backup/OABackupInfo.h | 4 +- Sources/Backup/OABackupInfo.mm | 55 ++-- Sources/Backup/OABackupListeners.m | 3 +- Sources/Backup/OABackupStatus.m | 11 +- Sources/Backup/OACollectLocalFilesTask.m | 20 +- Sources/Backup/OAExportBackupTask.m | 4 +- ...ationTask.h => OAGenerateBackupInfoTask.h} | 2 +- ...ationTask.m => OAGenerateBackupInfoTask.m} | 20 +- Sources/Backup/OAImportBackupItemsTask.m | 4 +- Sources/Backup/OANetworkSettingsHelper.m | 2 +- Sources/Backup/OANetworkWriter.mm | 31 +- Sources/Backup/OASyncBackupTask.h | 8 +- Sources/Backup/OASyncBackupTask.mm | 37 +-- .../Cloud/OABackupTypesViewController.mm | 7 +- ...OACloudAccountVerificationViewController.m | 5 +- .../Cloud/OACloudBackupViewController.mm | 12 +- ...tatusBackupConflictDetailsViewController.m | 6 +- .../OAStatusBackupTableViewController.mm | 31 +- Sources/Controllers/OARootViewController.m | 2 +- .../OAImportSettingsViewController.mm | 2 + Sources/Helpers/OAAppSettings.m | 19 ++ Sources/History/OAHistoryDB.h | 8 +- Sources/History/OAHistoryDB.mm | 60 +++- Sources/History/OAHistoryHelper.h | 6 +- Sources/History/OAHistoryHelper.m | 17 +- Sources/OsmAnd Maps-Bridging-Header.h | 5 + Sources/OsmEdit/OAOsmBugsDBHelper.m | 17 +- Sources/OsmEdit/OAOsmEditsDBHelper.m | 17 +- Sources/POI/OAPOIFiltersHelper.mm | 15 +- Sources/Purchases/OAIAPHelper.h | 4 +- Sources/Purchases/OAIAPHelper.mm | 11 + 46 files changed, 653 insertions(+), 521 deletions(-) create mode 100644 Sources/Backup/BackupUtils.swift rename Sources/Backup/{OABackupInfoGenerationTask.h => OAGenerateBackupInfoTask.h} (92%) rename Sources/Backup/{OABackupInfoGenerationTask.m => OAGenerateBackupInfoTask.m} (95%) diff --git a/OsmAnd.xcodeproj/project.pbxproj b/OsmAnd.xcodeproj/project.pbxproj index c6fe259aa7..4e98c8d6c3 100644 --- a/OsmAnd.xcodeproj/project.pbxproj +++ b/OsmAnd.xcodeproj/project.pbxproj @@ -784,6 +784,7 @@ 46D38A9F29C39B0F000AAE0C /* OAProfilesGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 46D38A9E29C39AE8000AAE0C /* OAProfilesGroup.m */; }; 46D38AA229C39D7C000AAE0C /* OARoutingFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 46D38AA129C39D42000AAE0C /* OARoutingFile.m */; }; 46D439142AA89C1F001D85FF /* DestinationsListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D439132AA89C1F001D85FF /* DestinationsListViewController.swift */; }; + 46D5E41A2D31A3F000428227 /* BackupUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D5E4192D31A3EC00428227 /* BackupUtils.swift */; }; 46D6CF4C28452F5D007A43F9 /* OATitleDescriptionBigIconCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 46D6CF4B28452F5D007A43F9 /* OATitleDescriptionBigIconCell.xib */; }; 46DB0A632C5CEA8F001356D5 /* ConcurrentArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46DB0A622C5CEA8F001356D5 /* ConcurrentArray.swift */; }; 46DB0A7E2C5D1602001356D5 /* GradientUiHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46DB0A7D2C5D1602001356D5 /* GradientUiHelper.swift */; }; @@ -2989,7 +2990,7 @@ DAEC06042296CA7C00045298 /* ic_navbar_close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAEC06012296CA7B00045298 /* ic_navbar_close@2x.png */; }; DAEC06062296CA7C00045298 /* ic_navbar_close@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAEC06022296CA7C00045298 /* ic_navbar_close@3x.png */; }; DAECA4FA26CFE62600241B0B /* OABaseWidgetView.m in Sources */ = {isa = PBXBuildFile; fileRef = DAECA4F926CFE62600241B0B /* OABaseWidgetView.m */; }; - DAEDAAA12865A0F100CE54D0 /* OABackupInfoGenerationTask.m in Sources */ = {isa = PBXBuildFile; fileRef = DAEDAAA02865A0F100CE54D0 /* OABackupInfoGenerationTask.m */; }; + DAEDAAA12865A0F100CE54D0 /* OAGenerateBackupInfoTask.m in Sources */ = {isa = PBXBuildFile; fileRef = DAEDAAA02865A0F100CE54D0 /* OAGenerateBackupInfoTask.m */; }; DAF2F804254825BA00967935 /* map_plan_route_point_movable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAF2F7FB254825B600967935 /* map_plan_route_point_movable@3x.png */; }; DAF2F808254825BA00967935 /* map_plan_route_point_normal@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAF2F7FD254825B700967935 /* map_plan_route_point_normal@3x.png */; }; DAF2F80C254825BA00967935 /* map_plan_route_point_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAF2F7FF254825B800967935 /* map_plan_route_point_selected@2x.png */; }; @@ -4193,6 +4194,7 @@ 46D38AA029C39D36000AAE0C /* OARoutingFile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OARoutingFile.h; sourceTree = ""; }; 46D38AA129C39D42000AAE0C /* OARoutingFile.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OARoutingFile.m; sourceTree = ""; }; 46D439132AA89C1F001D85FF /* DestinationsListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DestinationsListViewController.swift; sourceTree = ""; }; + 46D5E4192D31A3EC00428227 /* BackupUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupUtils.swift; sourceTree = ""; }; 46D6CF4B28452F5D007A43F9 /* OATitleDescriptionBigIconCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = OATitleDescriptionBigIconCell.xib; sourceTree = ""; }; 46DB0A622C5CEA8F001356D5 /* ConcurrentArray.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConcurrentArray.swift; sourceTree = ""; }; 46DB0A7D2C5D1602001356D5 /* GradientUiHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientUiHelper.swift; sourceTree = ""; }; @@ -7494,8 +7496,8 @@ DAEC06022296CA7C00045298 /* ic_navbar_close@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "ic_navbar_close@3x.png"; path = "Resources/Icons/ic_navbar_close@3x.png"; sourceTree = ""; }; DAECA4F826CFE62600241B0B /* OABaseWidgetView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OABaseWidgetView.h; sourceTree = ""; }; DAECA4F926CFE62600241B0B /* OABaseWidgetView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OABaseWidgetView.m; sourceTree = ""; }; - DAEDAA9F2865A0F100CE54D0 /* OABackupInfoGenerationTask.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OABackupInfoGenerationTask.h; sourceTree = ""; }; - DAEDAAA02865A0F100CE54D0 /* OABackupInfoGenerationTask.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OABackupInfoGenerationTask.m; sourceTree = ""; }; + DAEDAA9F2865A0F100CE54D0 /* OAGenerateBackupInfoTask.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OAGenerateBackupInfoTask.h; sourceTree = ""; }; + DAEDAAA02865A0F100CE54D0 /* OAGenerateBackupInfoTask.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OAGenerateBackupInfoTask.m; sourceTree = ""; }; DAF2F7FB254825B600967935 /* map_plan_route_point_movable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "map_plan_route_point_movable@3x.png"; path = "Resources/Icons/map_plan_route_point_movable@3x.png"; sourceTree = ""; }; DAF2F7FD254825B700967935 /* map_plan_route_point_normal@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "map_plan_route_point_normal@3x.png"; path = "Resources/Icons/map_plan_route_point_normal@3x.png"; sourceTree = ""; }; DAF2F7FF254825B800967935 /* map_plan_route_point_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "map_plan_route_point_selected@2x.png"; path = "Resources/Icons/map_plan_route_point_selected@2x.png"; sourceTree = ""; }; @@ -13446,6 +13448,7 @@ DACF784127E343FF00A8A218 /* Backup */ = { isa = PBXGroup; children = ( + 46D5E4192D31A3EC00428227 /* BackupUtils.swift */, DAA9F44B27EC9E99002BB1A8 /* Commands */, DA4ABED22876D98D00B996EF /* LocalBackup */, 4657490F2B68129B0006046B /* BackupUiUtils.swift */, @@ -13461,8 +13464,8 @@ DAAC0EC22801885800867D35 /* OABackupImporter.m */, DA775B8B27E618070081B9C1 /* OABackupInfo.h */, DA775B8C27E618070081B9C1 /* OABackupInfo.mm */, - DAEDAA9F2865A0F100CE54D0 /* OABackupInfoGenerationTask.h */, - DAEDAAA02865A0F100CE54D0 /* OABackupInfoGenerationTask.m */, + DAEDAA9F2865A0F100CE54D0 /* OAGenerateBackupInfoTask.h */, + DAEDAAA02865A0F100CE54D0 /* OAGenerateBackupInfoTask.m */, DAA9F45227ECADF8002BB1A8 /* OABackupListeners.h */, DAA9F45327ECADF8002BB1A8 /* OABackupListeners.m */, DA5F77B428742E85000A2BFF /* OABackupStatus.h */, @@ -16225,7 +16228,7 @@ 46A5A3872CA5DCDA00A206C2 /* ActionAddTerrainColorSchemeViewController.swift in Sources */, 46220B702AD6D6F2006C3248 /* OABaseEditorViewController.mm in Sources */, DA5A855B26C563A900F274C7 /* OAWorldRegion.mm in Sources */, - DAEDAAA12865A0F100CE54D0 /* OABackupInfoGenerationTask.m in Sources */, + DAEDAAA12865A0F100CE54D0 /* OAGenerateBackupInfoTask.m in Sources */, 32839A372AF0F911007B5057 /* WikiImageCacheHelper.swift in Sources */, 4663AB412951CB6200D9781E /* OAInputTableViewCell.m in Sources */, DA5A83DD26C563A800F274C7 /* OAFavoriteListViewController.mm in Sources */, @@ -16978,6 +16981,7 @@ DA5A815F26C563A700F274C7 /* OALiveMonitoringHelper.m in Sources */, DA5A84B426C563A900F274C7 /* OAInstallMapillaryBottomSheetViewController.mm in Sources */, 46964F762C345448007F3938 /* ColorPaletteHelper.swift in Sources */, + 46D5E41A2D31A3F000428227 /* BackupUtils.swift in Sources */, DA5A839A26C563A800F274C7 /* OALocalResourceInfoCell.m in Sources */, DA5A823926C563A700F274C7 /* OAOsmAccountSettingsViewController.m in Sources */, DA5A815C26C563A700F274C7 /* OAPlugin.mm in Sources */, diff --git a/Sources/AppHost/OsmAndAppImpl.mm b/Sources/AppHost/OsmAndAppImpl.mm index 4aafccf2a5..aef275565b 100644 --- a/Sources/AppHost/OsmAndAppImpl.mm +++ b/Sources/AppHost/OsmAndAppImpl.mm @@ -978,6 +978,11 @@ - (void) loadRoutingFiles }); } +- (void)rescanUnmanagedStoragePaths +{ + _resourcesManager->rescanUnmanagedStoragePaths(); +} + - (MAP_STR_STR) getDefaultAttributes { MAP_STR_STR defaultAttributes; diff --git a/Sources/AppHost/OsmAndAppProtocol.h b/Sources/AppHost/OsmAndAppProtocol.h index 2c6cc645a6..b124a3a982 100644 --- a/Sources/AppHost/OsmAndAppProtocol.h +++ b/Sources/AppHost/OsmAndAppProtocol.h @@ -109,6 +109,7 @@ - (void) checkAndDownloadWeatherForecastsUpdates; - (void) loadRoutingFiles; +- (void) rescanUnmanagedStoragePaths; - (NSString *) favoritesStorageFilename:(NSString *)groupName; - (NSString *) getGroupFileName:(NSString *)groupName; diff --git a/Sources/AppHost/SceneDelegate.mm b/Sources/AppHost/SceneDelegate.mm index b461500c21..5cb88b23ce 100644 --- a/Sources/AppHost/SceneDelegate.mm +++ b/Sources/AppHost/SceneDelegate.mm @@ -435,7 +435,7 @@ - (BOOL)handleIncomingOsmAndCloudURL:(NSURL *)url if ([vc isKindOfClass:OACloudAccountVerificationViewController.class]) { - if ([OABackupHelper isTokenValid:tokenParam]) + if ([BackupUtils isTokenValid:tokenParam]) { [OABackupHelper.sharedInstance registerDevice:tokenParam]; } diff --git a/Sources/Backup/BackupUtils.swift b/Sources/Backup/BackupUtils.swift new file mode 100644 index 0000000000..bfaf5aa651 --- /dev/null +++ b/Sources/Backup/BackupUtils.swift @@ -0,0 +1,267 @@ +// +// BackupUtils.swift +// OsmAnd +// +// Created by Skalii on 10.01.2025. +// Copyright © 2025 OsmAnd. All rights reserved. +// + +import Foundation + +@objcMembers +final class BackupUtils: NSObject { + + static let backupTypePrefix = "backup_type_" + static let versionHistoryPrefix = "save_version_history_" + + static func setLastModifiedTime(_ name: String) { + setLastModifiedTime(name, lastModifiedTime: Int(NSDate().timeIntervalSince1970)) + } + + static func setLastModifiedTime(_ name: String, lastModifiedTime: Int) { + OABackupDbHelper.sharedDatabase().setLastModifiedTime(name, lastModifiedTime: Int(lastModifiedTime)) + } + + static func getLastModifiedTime(_ name: String) -> Int { + OABackupDbHelper.sharedDatabase().getLastModifiedTime(name) + } + + static func isTokenValid(_ token: String) -> Bool { + token.range(of: "^[0-9]+$", options: .regularExpression) != nil + } + + static func getItemsForRestore(_ info: OABackupInfo?, + settingsItems: [OASettingsItem]) -> [OASettingsItem] { + guard let info, let filtered = info.filteredFilesToDownload as? [OARemoteFile] else { return [] } + + var items = [OASettingsItem]() + let restoreItems = getRemoteFilesSettingsItems(settingsItems, + remoteFiles: filtered, + infoFiles: false) + for restoreItem in restoreItems.values { + if let settingsItem = restoreItem as? OACollectionSettingsItem { + settingsItem.processDuplicateItems() + settingsItem.shouldReplace = true + } + items.append(restoreItem) + } + items.sort { $0.lastModifiedTime > $1.lastModifiedTime } + return items + } + + static func getItemsMapForRestore(_ info: OABackupInfo?, + settingsItems: [OASettingsItem]) -> [OARemoteFile: OASettingsItem] { + guard let info, let filtered = info.filteredFilesToDownload as? [OARemoteFile] else { return [OARemoteFile: OASettingsItem]() } + + return getRemoteFilesSettingsItems(settingsItems, + remoteFiles: filtered, + infoFiles: false) + } + + static func getRemoteFilesSettingsItems(_ items: [OASettingsItem], + remoteFiles: [OARemoteFile], + infoFiles: Bool) -> [OARemoteFile: OASettingsItem] { + var res = [OARemoteFile: OASettingsItem]() + var files = remoteFiles + for item in items { + var processedFiles = [OARemoteFile]() + for file in files { + var name = file.name as NSString + if infoFiles && name.pathExtension == OABackupHelper.info_EXT() { + name = name.deletingPathExtension as NSString + } + + if applyItem(item, type: file.type, name: name) { + if file.item == nil { + file.item = item + } + res[file] = item + processedFiles.append(file) + } + } + files.removeAll { processedFiles.contains($0) } + } + return res + } + + static func getBackupTypePref(_ type: OAExportSettingsType) -> OACommonBoolean { + OACommonBoolean.withKey("\(backupTypePrefix)\(type.name)", defValue: true).makeGlobal() + } + + static func getVersionHistoryTypePref(_ type: OAExportSettingsType) -> OACommonBoolean { + OACommonBoolean.withKey("\(versionHistoryPrefix)\(type.name)", defValue: true).makeGlobal().makeShared() + } + + static func applyItem(_ item: OASettingsItem, type: String, name: NSString) -> Bool { + let itemFileName = getItemFileName(item) + let itemTypeName = OASettingsItemType.typeName(item.type) + if itemTypeName == type { + if name.isEqual(to: itemFileName) { + return true + } else if let fileItem = item as? OAFileSettingsItem { + let subtypeFolder = OAFileSettingsItemFileSubtype.getFolderName(fileItem.subtype) + if name.hasPrefix(subtypeFolder) || subtypeFolder.isEmpty { + var isDir: ObjCBool = false + FileManager.default.fileExists(atPath: fileItem.filePath, isDirectory: &isDir) + if isDir.boolValue, !itemFileName.hasSuffix("/") { + return name.hasPrefix("\(itemFileName)/") + } else { + return name.hasPrefix(itemFileName) + } + } + } + } + return false + } + + static func getItemFileName(_ item: OASettingsItem) -> String { + var fileName: String + if let fileItem = item as? OAFileSettingsItem { + fileName = getFileItemName(fileItem) + } else { + fileName = item.fileName + if fileName.isEmpty { + fileName = item.defaultFileName + } + } + if !fileName.isEmpty, fileName.first == "/" { + fileName.removeFirst() + } + return fileName + } + + static func getFileItemName(_ fileSettingsItem: OAFileSettingsItem) -> String { + getFileItemName(nil, fileSettingsItem: fileSettingsItem) + } + + static func getFileItemName(_ filePath: String?, + fileSettingsItem: OAFileSettingsItem) -> String { + let subtypeFolder = OAFileSettingsItemFileSubtype.getFolder(fileSettingsItem.subtype) + var fileName: String + let filePath = filePath ?? fileSettingsItem.filePath + + if subtypeFolder.isEmpty { + fileName = filePath.lastPathComponent() + } else if fileSettingsItem.subtype == .subtypeGpx { + fileName = filePath.replacingOccurrences(of: "\(subtypeFolder)/", with: "") + } else if OAFileSettingsItemFileSubtype.isMap(fileSettingsItem.subtype) { + fileName = filePath.lastPathComponent() + } else { + let index = filePath.index(of: subtypeFolder.lastPathComponent()) + if index >= 0 { + fileName = filePath.substring(from: Int(index)) + } else { + fileName = filePath.lastPathComponent() + } + } + + if !fileName.isEmpty, fileName.first == "/" { + fileName.removeFirst() + } + + return fileName + } + + static func isLimitedFilesCollectionItem(_ item: OAFileSettingsItem) -> Bool { + item.subtype == .subtypeVoice + } + + static func isDefaultObfMap(_ settingsItem: OAFileSettingsItem, + fileName: String) -> Bool { + if (OAFileSettingsItemFileSubtype.isMap(settingsItem.subtype)) { + return isObfMapExistsOnServer(fileName) + } + return false + } + + static func isObfMapExistsOnServer(_ name: String) -> Bool { + var exists = false + let params = [ + "name": name, + "type": "file" + ] + + let operationLog = OAOperationLog(operationName: "isObfMapExistsOnServer", debug: true) + operationLog?.startOperation(name) + + OANetworkUtilities.sendRequest(withUrl: "https://osmand.net/userdata/check-file-on-server", + params: params, + post: false, + async: false) { data, response, _ in + var status: Int32 + var message: String + + guard let data, let httpResponse = response as? HTTPURLResponse else { + status = STATUS_SERVER_ERROR + message = "Check obf map on server error: invalid response" + operationLog?.finishOperation("(\(status)): \(message)") + return + } + + let result = String(data: data, encoding: .utf8) ?? "" + var backupError: OABackupError? + if httpResponse.statusCode != 200 { + backupError = OABackupError(error: result) + message = "Check obf map on server error: \(String(describing: backupError?.toString()))" + status = STATUS_SERVER_ERROR + } else if !result.isEmpty { + do { + if let resultJson = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any], + let fileStatus = resultJson["status"] as? String { + exists = fileStatus == "present" + status = STATUS_SUCCESS + message = "\(name) exist: \(exists)" + } else { + message = "Send code error: unknown" + status = STATUS_SERVER_ERROR + } + } catch { + message = "Check obf map on server error: json parsing" + status = STATUS_PARSE_JSON_ERROR + } + } else { + message = "Check obf map on server error: empty response" + status = STATUS_EMPTY_RESPONSE_ERROR + } + operationLog?.finishOperation("(\(status)): \(message)") + } + + return exists + } + + static func updateCacheForItems(_ items: [OASettingsItem]) { + var updateIndexes = false + var updateRouting = false + var updateRenderers = false + var updatePoiFilters = false + var updateColorPalette = false + + for item in items { + if let fileItem = item as? OAFileSettingsItem { + updateIndexes = updateIndexes || OAFileSettingsItemFileSubtype.isMap(fileItem.subtype) + updateRouting = updateRouting || .subtypeRoutingConfig == fileItem.subtype + updateRenderers = updateRenderers || .subtypeRenderingStyle == fileItem.subtype + updateColorPalette = updateColorPalette || .subtypeColorPalette == fileItem.subtype + } else if item is OAPoiUiFilterSettingsItem || item is OAProfileSettingsItem { + updatePoiFilters = true + } + } + let app = OsmAndApp.swiftInstance() + if updateColorPalette { + app?.updateGpxTracksOnMapObservable.notifyEvent() + } + if updateIndexes { + app?.rescanUnmanagedStoragePaths() + app?.localResourcesChangedObservable.notifyEvent() + } + if updateRouting { + app?.loadRoutingFiles() + } + if updateRenderers { + OARendererRegistry.getExternalRenderers() + } + if updatePoiFilters { + OAPOIFiltersHelper.sharedInstance().loadSelectedPoiFilters() + } + } +} diff --git a/Sources/Backup/LocalBackup/ImportExportData/OAExportSettingsType.h b/Sources/Backup/LocalBackup/ImportExportData/OAExportSettingsType.h index 37a2bb8ac1..6e983a885c 100644 --- a/Sources/Backup/LocalBackup/ImportExportData/OAExportSettingsType.h +++ b/Sources/Backup/LocalBackup/ImportExportData/OAExportSettingsType.h @@ -48,7 +48,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) NSString *itemName; @property (nonatomic, readonly) NSString *title; @property (nonatomic, readonly) UIImage *icon; -@property (nonatomic, readonly) BOOL isAllowedInFreeVersion; +@property (nonatomic, readonly) BOOL isAvailableInFreeVersion; - (BOOL) isSettingsCategory; - (BOOL) isMyPlacesCategory; diff --git a/Sources/Backup/LocalBackup/ImportExportData/OAExportSettingsType.mm b/Sources/Backup/LocalBackup/ImportExportData/OAExportSettingsType.mm index 8901206134..d2de4c0b9a 100644 --- a/Sources/Backup/LocalBackup/ImportExportData/OAExportSettingsType.mm +++ b/Sources/Backup/LocalBackup/ImportExportData/OAExportSettingsType.mm @@ -158,15 +158,16 @@ - (instancetype)initWithTitle:(NSString *)title name:(NSString *)name itemName:(NSString *)itemName icon:(UIImage *)icon - isAllowedInFreeVersion:(BOOL)isAllowedInFreeVersion + isAvailableInFreeVersion:(BOOL)isAvailableInFreeVersion { self = [super init]; - if (self) { + if (self) + { _title = title; _name = name; _itemName = itemName; _icon = icon; - _isAllowedInFreeVersion = isAllowedInFreeVersion; + _isAvailableInFreeVersion = isAvailableInFreeVersion; } return self; } @@ -174,63 +175,63 @@ - (instancetype)initWithTitle:(NSString *)title + (OAExportSettingsType *)PROFILE { if (!PROFILE) - PROFILE = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_profiles") name:@"PROFILE" itemName:@"PROFILE" icon:[UIImage templateImageNamed:@"ic_custom_manage_profiles"] isAllowedInFreeVersion:YES]; + PROFILE = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_profiles") name:@"PROFILE" itemName:@"PROFILE" icon:[UIImage templateImageNamed:@"ic_custom_manage_profiles"] isAvailableInFreeVersion:YES]; return PROFILE; } + (OAExportSettingsType *)GLOBAL { if (!GLOBAL) - GLOBAL = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"general_settings_2") name:@"GLOBAL" itemName:@"GLOBAL" icon:[UIImage templateImageNamed:@"left_menu_icon_settings"] isAllowedInFreeVersion:YES]; + GLOBAL = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"general_settings_2") name:@"GLOBAL" itemName:@"GLOBAL" icon:[UIImage templateImageNamed:@"left_menu_icon_settings"] isAvailableInFreeVersion:YES]; return GLOBAL; } + (OAExportSettingsType *)QUICK_ACTIONS { if (!QUICK_ACTIONS) - QUICK_ACTIONS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_quick_actions") name:@"QUICK_ACTIONS" itemName:@"QUICK_ACTIONS" icon:[UIImage templateImageNamed:@"ic_custom_quick_action"] isAllowedInFreeVersion:NO]; + QUICK_ACTIONS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_quick_actions") name:@"QUICK_ACTIONS" itemName:@"QUICK_ACTIONS" icon:[UIImage templateImageNamed:@"ic_custom_quick_action"] isAvailableInFreeVersion:NO]; return QUICK_ACTIONS; } + (OAExportSettingsType *)POI_TYPES { if (!POI_TYPES) - POI_TYPES = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_poi_types") name:@"POI_TYPES" itemName:@"POI_UI_FILTERS" icon:[UIImage templateImageNamed:@"ic_custom_search_categories"] isAllowedInFreeVersion:NO]; + POI_TYPES = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_poi_types") name:@"POI_TYPES" itemName:@"POI_UI_FILTERS" icon:[UIImage templateImageNamed:@"ic_custom_search_categories"] isAvailableInFreeVersion:NO]; return POI_TYPES; } + (OAExportSettingsType *)AVOID_ROADS { if (!AVOID_ROADS) - AVOID_ROADS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"avoid_road") name:@"AVOID_ROADS" itemName:@"AVOID_ROADS" icon:[UIImage templateImageNamed:@"ic_custom_alert"] isAllowedInFreeVersion:NO]; + AVOID_ROADS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"avoid_road") name:@"AVOID_ROADS" itemName:@"AVOID_ROADS" icon:[UIImage templateImageNamed:@"ic_custom_alert"] isAvailableInFreeVersion:NO]; return AVOID_ROADS; } + (OAExportSettingsType *)FAVORITES { if (!FAVORITES) - FAVORITES = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"favorites_item") name:@"FAVORITES" itemName:@"FAVOURITES" icon:[UIImage templateImageNamed:@"ic_custom_my_places"] isAllowedInFreeVersion:YES]; + FAVORITES = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"favorites_item") name:@"FAVORITES" itemName:@"FAVOURITES" icon:[UIImage templateImageNamed:@"ic_custom_my_places"] isAvailableInFreeVersion:YES]; return FAVORITES; } + (OAExportSettingsType *)TRACKS { if (!TRACKS) - TRACKS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_gpx_tracks") name:@"TRACKS" itemName:@"GPX" icon:[UIImage templateImageNamed:@"ic_custom_trip"] isAllowedInFreeVersion:NO]; + TRACKS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_gpx_tracks") name:@"TRACKS" itemName:@"GPX" icon:[UIImage templateImageNamed:@"ic_custom_trip"] isAvailableInFreeVersion:NO]; return TRACKS; } + (OAExportSettingsType *)OSM_NOTES { if (!OSM_NOTES) - OSM_NOTES = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"osm_notes") name:@"OSM_NOTES" itemName:@"OSM_NOTES" icon:[UIImage templateImageNamed:@"ic_action_osm_note"] isAllowedInFreeVersion:YES]; + OSM_NOTES = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"osm_notes") name:@"OSM_NOTES" itemName:@"OSM_NOTES" icon:[UIImage templateImageNamed:@"ic_action_osm_note"] isAvailableInFreeVersion:YES]; return OSM_NOTES; } + (OAExportSettingsType *)OSM_EDITS { if (!OSM_EDITS) - OSM_EDITS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"osm_edits_title") name:@"OSM_EDITS" itemName:@"OSM_EDITS" icon:[UIImage templateImageNamed:@"ic_custom_osm_edits"] isAllowedInFreeVersion:YES]; + OSM_EDITS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"osm_edits_title") name:@"OSM_EDITS" itemName:@"OSM_EDITS" icon:[UIImage templateImageNamed:@"ic_custom_osm_edits"] isAvailableInFreeVersion:YES]; return OSM_EDITS; } @@ -242,56 +243,56 @@ + (OAExportSettingsType *)MULTIMEDIA_NOTES + (OAExportSettingsType *)ACTIVE_MARKERS { if (!ACTIVE_MARKERS) - ACTIVE_MARKERS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"map_markers") name:@"ACTIVE_MARKERS" itemName:@"ACTIVE_MARKERS" icon:[UIImage templateImageNamed:@"ic_custom_marker"] isAllowedInFreeVersion:NO]; + ACTIVE_MARKERS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"map_markers") name:@"ACTIVE_MARKERS" itemName:@"ACTIVE_MARKERS" icon:[UIImage templateImageNamed:@"ic_custom_marker"] isAvailableInFreeVersion:NO]; return ACTIVE_MARKERS; } + (OAExportSettingsType *)HISTORY_MARKERS { if (!HISTORY_MARKERS) - HISTORY_MARKERS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"markers_history") name:@"HISTORY_MARKERS" itemName:@"HISTORY_MARKERS" icon:[UIImage templateImageNamed:@"ic_custom_marker"] isAllowedInFreeVersion:NO]; + HISTORY_MARKERS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"markers_history") name:@"HISTORY_MARKERS" itemName:@"HISTORY_MARKERS" icon:[UIImage templateImageNamed:@"ic_custom_marker"] isAvailableInFreeVersion:NO]; return HISTORY_MARKERS; } + (OAExportSettingsType *)SEARCH_HISTORY { if (!SEARCH_HISTORY) - SEARCH_HISTORY = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_search_history") name:@"SEARCH_HISTORY" itemName:@"SEARCH_HISTORY" icon:[UIImage templateImageNamed:@"ic_custom_search"] isAllowedInFreeVersion:NO]; + SEARCH_HISTORY = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_search_history") name:@"SEARCH_HISTORY" itemName:@"SEARCH_HISTORY" icon:[UIImage templateImageNamed:@"ic_custom_search"] isAvailableInFreeVersion:NO]; return SEARCH_HISTORY; } + (OAExportSettingsType *)NAVIGATION_HISTORY { if (!NAVIGATION_HISTORY) - NAVIGATION_HISTORY = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"navigation_history") name:@"NAVIGATION_HISTORY" itemName:@"NAVIGATION_HISTORY" icon:[UIImage templateImageNamed:@"ic_custom_navigation"] isAllowedInFreeVersion:NO]; + NAVIGATION_HISTORY = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"navigation_history") name:@"NAVIGATION_HISTORY" itemName:@"NAVIGATION_HISTORY" icon:[UIImage templateImageNamed:@"ic_custom_navigation"] isAvailableInFreeVersion:NO]; return NAVIGATION_HISTORY; } + (OAExportSettingsType *)CUSTOM_RENDER_STYLE { if (!CUSTOM_RENDER_STYLE) - CUSTOM_RENDER_STYLE = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_rendering_style") name:@"CUSTOM_RENDER_STYLE" itemName:@"FILE" icon:[UIImage templateImageNamed:@"ic_custom_map_style"] isAllowedInFreeVersion:NO]; + CUSTOM_RENDER_STYLE = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_rendering_style") name:@"CUSTOM_RENDER_STYLE" itemName:@"FILE" icon:[UIImage templateImageNamed:@"ic_custom_map_style"] isAvailableInFreeVersion:NO]; return CUSTOM_RENDER_STYLE; } + (OAExportSettingsType *)CUSTOM_ROUTING { if (!CUSTOM_ROUTING) - CUSTOM_ROUTING = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_routing") name:@"CUSTOM_ROUTING" itemName:@"FILE" icon:[UIImage templateImageNamed:@"ic_custom_file_routing"] isAllowedInFreeVersion:NO]; + CUSTOM_ROUTING = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_routing") name:@"CUSTOM_ROUTING" itemName:@"FILE" icon:[UIImage templateImageNamed:@"ic_custom_file_routing"] isAvailableInFreeVersion:NO]; return CUSTOM_ROUTING; } + (OAExportSettingsType *)MAP_SOURCES { if (!MAP_SOURCES) - MAP_SOURCES = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"quick_action_map_source_title") name:@"MAP_SOURCES" itemName:@"MAP_SOURCES" icon:[UIImage templateImageNamed:@"ic_custom_globe_latitude"] isAllowedInFreeVersion:NO]; + MAP_SOURCES = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"quick_action_map_source_title") name:@"MAP_SOURCES" itemName:@"MAP_SOURCES" icon:[UIImage templateImageNamed:@"ic_custom_globe_latitude"] isAvailableInFreeVersion:NO]; return MAP_SOURCES; } + (OAExportSettingsType *)OFFLINE_MAPS { if (!OFFLINE_MAPS) - OFFLINE_MAPS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"offline_maps") name:@"OFFLINE_MAPS" itemName:@"FILE" icon:[UIImage templateImageNamed:@"ic_custom_map"] isAllowedInFreeVersion:NO]; + OFFLINE_MAPS = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"offline_maps") name:@"OFFLINE_MAPS" itemName:@"FILE" icon:[UIImage templateImageNamed:@"ic_custom_map"] isAvailableInFreeVersion:NO]; return OFFLINE_MAPS; } @@ -318,7 +319,7 @@ + (OAExportSettingsType *)ITINERARY_GROUPS + (OAExportSettingsType *)COLOR_DATA { if (!COLOR_DATA) - COLOR_DATA = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_colors") name:@"COLOR_DATA" itemName:@"FILE" icon:[UIImage templateImageNamed:@"ic_custom_appearance"] isAllowedInFreeVersion:NO]; + COLOR_DATA = [[OAExportSettingsType alloc] initWithTitle:OALocalizedString(@"shared_string_colors") name:@"COLOR_DATA" itemName:@"FILE" icon:[UIImage templateImageNamed:@"ic_custom_appearance"] isAvailableInFreeVersion:NO]; return COLOR_DATA; } diff --git a/Sources/Backup/LocalBackup/OASettingsImporter.mm b/Sources/Backup/LocalBackup/OASettingsImporter.mm index d7b9a8768d..7cf7dedcd0 100644 --- a/Sources/Backup/LocalBackup/OASettingsImporter.mm +++ b/Sources/Backup/LocalBackup/OASettingsImporter.mm @@ -44,6 +44,7 @@ #import "OASuggestedDownloadsItem.h" #import "OAExportAsyncTask.h" #import "OAApplicationMode.h" +#import "OsmAnd_Maps-Swift.h" #include #include @@ -71,7 +72,8 @@ @implementation OASettingsImporter - (instancetype) init { self = [super init]; - if (self) { + if (self) + { _app = [OsmAndApp instance]; _tmpFilesDir = NSTemporaryDirectory(); _tmpFilesDir = [_tmpFilesDir stringByAppendingPathComponent:kTmpProfileFolder]; @@ -224,7 +226,8 @@ @implementation OASettingsItemsFactory - (instancetype) initWithJSON:(NSString *)jsonStr { self = [super init]; - if (self) { + if (self) + { [self commonItit]; [self collectItems:jsonStr]; } @@ -234,7 +237,8 @@ - (instancetype) initWithJSON:(NSString *)jsonStr - (instancetype) initWithJSONData:(NSData *)jsonUtf8Data; { self = [super init]; - if (self) { + if (self) + { [self commonItit]; [self collectItemsFromData:jsonUtf8Data]; } @@ -244,7 +248,8 @@ - (instancetype) initWithJSONData:(NSData *)jsonUtf8Data; - (instancetype) initWithParsedJSON:(NSDictionary *)json { self = [super init]; - if (self) { + if (self) + { [self commonItit]; [self collectItemsFromDictioanry:json]; } @@ -286,7 +291,8 @@ - (void)collectItemsFromDictioanry:(NSDictionary *)json { { [items addObject:item]; } - else { + else + { items = [NSMutableArray new]; [items addObject:item]; pluginItems[pluginId] = items; @@ -530,11 +536,15 @@ - (void) onPreExecute - (NSArray *) doInBackground { - switch (_importType) { + switch (_importType) + { case EOAImportTypeCollect: - @try { + @try + { return [_importer collectItems:_filePath]; - } @catch (NSException *exception) { + } + @catch (NSException *exception) + { NSLog(@"Failed to collect items from: %@ %@", _filePath, exception); } break; @@ -553,7 +563,8 @@ - (void) onPostExecute:(NSArray *)items _items = items; else _selectedItems = items; - switch (_importType) { + switch (_importType) + { case EOAImportTypeCollect: _importDone = YES; if (_delegate) @@ -656,7 +667,8 @@ @implementation OAImportItemsAsyncTask - (instancetype) initWithFile:(NSString *)file items:(NSArray *)items { self = [super init]; - if (self) { + if (self) + { _importer = [[OASettingsImporter alloc] init]; _settingsHelper = [OASettingsHelper sharedInstance]; _file = file; @@ -688,54 +700,19 @@ - (BOOL) doInBackground { NSString *backupPath = [[tempDir stringByAppendingPathComponent:((OAProfileSettingsItem *)item).appMode.stringKey] stringByAppendingPathExtension:@"osf"]; if ([[NSFileManager defaultManager] fileExistsAtPath:backupPath]) - { [[NSFileManager defaultManager] removeItemAtPath:backupPath error:nil]; - } OAExportAsyncTask *backupTask = [[OAExportAsyncTask alloc] initWithFile:backupPath items:@[item] exportItemFiles:YES extensionsFilter:nil]; [backupTask execute]; } } return YES; } - -- (void)updateDataIfNeeded -{ - OsmAndAppInstance app = OsmAndApp.instance; - BOOL updateRoutingFiles = NO; - BOOL updateResources = NO; - BOOL updateColorPalette = NO; - for (OASettingsItem *item in _items) - { - if ([item isKindOfClass:OAFileSettingsItem.class]) - { - OAFileSettingsItem *fileItem = (OAFileSettingsItem *)item; - updateResources = updateResources || fileItem.subtype != EOASettingsItemFileSubtypeUnknown; - updateRoutingFiles = updateRoutingFiles || fileItem.subtype == EOASettingsItemFileSubtypeRoutingConfig; - updateColorPalette = updateColorPalette || fileItem.subtype == EOASettingsItemFileSubtypeColorPalette; - - if (updateResources && updateRoutingFiles && updateColorPalette) - break; - } - } - - if (updateColorPalette) - { - [app.updateGpxTracksOnMapObservable notifyEvent]; - } - if (updateRoutingFiles) - [app loadRoutingFiles]; - if (updateResources) - { - app.resourcesManager->rescanUnmanagedStoragePaths(true); - [app.localResourcesChangedObservable notifyEvent]; - } - [[OARootViewController instance].mapPanel recreateAllControls]; -} - (void) onPostExecute:(BOOL)success { - [self updateDataIfNeeded]; - + [BackupUtils updateCacheForItems:_items]; + [[OARootViewController instance].mapPanel recreateAllControls]; + if (_delegate) [_delegate onSettingsImportFinished:success items:_items]; if (self.onImportComplete) diff --git a/Sources/Backup/LocalBackup/SettingsItems/OAFileSettingsItem.mm b/Sources/Backup/LocalBackup/SettingsItems/OAFileSettingsItem.mm index 0ef83cde58..e973eb6000 100644 --- a/Sources/Backup/LocalBackup/SettingsItems/OAFileSettingsItem.mm +++ b/Sources/Backup/LocalBackup/SettingsItems/OAFileSettingsItem.mm @@ -558,7 +558,9 @@ - (OASettingsItemWriter *) getWriter - (BOOL) needMd5Digest { - return _subtype == EOASettingsItemFileSubtypeVoice || _subtype == EOASettingsItemFileSubtypeVoiceTTS; + return _subtype == EOASettingsItemFileSubtypeVoice + || _subtype == EOASettingsItemFileSubtypeVoiceTTS + || _subtype == EOASettingsItemFileSubtypeGpx; } @end diff --git a/Sources/Backup/OABackupDbHelper.m b/Sources/Backup/OABackupDbHelper.m index 5fe328a3e4..3a0dc6e634 100644 --- a/Sources/Backup/OABackupDbHelper.m +++ b/Sources/Backup/OABackupDbHelper.m @@ -30,7 +30,8 @@ @implementation OAUploadedFileInfo - (instancetype) initWithType:(NSString *)type name:(NSString *)name { self = [super init]; - if (self) { + if (self) + { _name = name; _type = type; _uploadTime = 0; @@ -42,7 +43,8 @@ - (instancetype) initWithType:(NSString *)type name:(NSString *)name - (instancetype) initWithType:(NSString *)type name:(NSString *)name uploadTime:(long)uploadTime { self = [super init]; - if (self) { + if (self) + { _name = name; _type = type; _uploadTime = uploadTime; @@ -54,7 +56,8 @@ - (instancetype) initWithType:(NSString *)type name:(NSString *)name uploadTime: - (instancetype) initWithType:(NSString *)type name:(NSString *)name md5Digest:(NSString *)md5Digest { self = [super init]; - if (self) { + if (self) + { _name = name; _type = type; _md5Digest = md5Digest; @@ -65,7 +68,8 @@ - (instancetype) initWithType:(NSString *)type name:(NSString *)name md5Digest:( - (instancetype) initWithType:(NSString *)type name:(NSString *)name uploadTime:(long)uploadTime md5Digest:(NSString *)md5Digest { self = [super init]; - if (self) { + if (self) + { _name = name; _type = type; _uploadTime = uploadTime; @@ -114,8 +118,8 @@ + (OABackupDbHelper *)sharedDatabase - (instancetype)init { self = [super init]; - if (self) { - + if (self) + { NSString *dir = [NSHomeDirectory() stringByAppendingString:@"/Library/BackupDatabase/"]; _dbFilePath = [dir stringByAppendingString:kCloudDbName]; @@ -145,27 +149,24 @@ - (void) load const char *sql_stmt = [[NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (%@ text, %@ text, %@ bigint, %@ text)", UPLOADED_FILES_TABLE_NAME, UPLOADED_FILE_COL_TYPE, UPLOADED_FILE_COL_NAME, UPLOADED_FILE_COL_UPLOAD_TIME, UPLOADED_FILE_COL_MD5_DIGEST] UTF8String]; if (sqlite3_exec(backupFilesDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK) - { NSLog(@"Failed to create table: %@", [NSString stringWithCString:errMsg encoding:NSUTF8StringEncoding]); - } - if (errMsg != NULL) sqlite3_free(errMsg); + if (errMsg != NULL) + sqlite3_free(errMsg); char *idxErrMsg; const char *create_index = [NSString stringWithFormat:@"CREATE INDEX IF NOT EXISTS %@ ON %@ (%@, %@)", UPLOADED_FILES_INDEX_TYPE_NAME, UPLOADED_FILES_TABLE_NAME, UPLOADED_FILE_COL_TYPE, UPLOADED_FILE_COL_NAME].UTF8String; if (sqlite3_exec(backupFilesDB, create_index, NULL, NULL, &idxErrMsg) != SQLITE_OK) - { NSLog(@"Failed to create index: %@", [NSString stringWithCString:idxErrMsg encoding:NSUTF8StringEncoding]); - } - if (idxErrMsg != NULL) sqlite3_free(idxErrMsg); + if (idxErrMsg != NULL) + sqlite3_free(idxErrMsg); char *modifiederrMsg; const char *modified_sql_stmt = [[NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (%@ text, %@ bigint)", LAST_MODIFIED_TABLE_NAME, LAST_MODIFIED_COL_NAME, LAST_MODIFIED_COL_MODIFIED_TIME] UTF8String]; if (sqlite3_exec(backupFilesDB, modified_sql_stmt, NULL, NULL, &modifiederrMsg) != SQLITE_OK) - { NSLog(@"Failed to create table: %@", [NSString stringWithCString:modifiederrMsg encoding:NSUTF8StringEncoding]); - } - if (modifiederrMsg != NULL) sqlite3_free(modifiederrMsg); + if (modifiederrMsg != NULL) + sqlite3_free(modifiederrMsg); sqlite3_close(backupFilesDB); } diff --git a/Sources/Backup/OABackupError.m b/Sources/Backup/OABackupError.m index 9a11cdb307..fcd29ddca8 100644 --- a/Sources/Backup/OABackupError.m +++ b/Sources/Backup/OABackupError.m @@ -15,7 +15,8 @@ @implementation OABackupError - (instancetype) initWithError:(NSString *)error { self = [super init]; - if (self) { + if (self) + { _error = error; [self parseError:error]; } diff --git a/Sources/Backup/OABackupExporter.m b/Sources/Backup/OABackupExporter.m index 3813cdf4bc..96a025d612 100644 --- a/Sources/Backup/OABackupExporter.m +++ b/Sources/Backup/OABackupExporter.m @@ -20,6 +20,7 @@ #import "OAConcurrentCollections.h" #import "OARemoteFile.h" #import "OAOperationLog.h" +#import "OsmAnd_Maps-Swift.h" #define MAX_LIGHT_ITEM_SIZE 10 * 1024 * 1024 @@ -74,7 +75,7 @@ @implementation OABackupExporter { OABackupHelper *_backupHelper; NSMutableArray *_itemsToDelete; - NSMutableArray *_localItemsToDelete; + NSMutableArray *_itemsToLocalDelete; NSMutableArray *_oldItemsToDelete; NSOperationQueue *_executor; __weak id _listener; @@ -91,7 +92,7 @@ - (instancetype) initWithListener:(id)listener if (self) { _itemsToDelete = [NSMutableArray array]; - _localItemsToDelete = [NSMutableArray array]; + _itemsToLocalDelete = [NSMutableArray array]; _oldFilesToDelete = [[OAConcurrentArray alloc] init]; _backupHelper = OABackupHelper.sharedInstance; _listener = listener; @@ -106,7 +107,7 @@ - (instancetype) initWithListener:(id)listener - (NSArray *)getLocalItemsToDelete { - return _localItemsToDelete; + return _itemsToLocalDelete; } - (NSArray *)getOldItemsToDelete @@ -121,7 +122,7 @@ - (void) addItemToDelete:(OASettingsItem *)item - (void) addLocalItemToDelete:(OASettingsItem *)item { - [_localItemsToDelete addObject:item]; + [_itemsToLocalDelete addObject:item]; } - (void) addOldItemToDelete:(OASettingsItem *)item @@ -246,15 +247,15 @@ - (void) deleteOldFiles:(id)listener - (void) deleteLocalFiles:(OAConcurrentSet *)itemsProgress dataProgress:(OAAtomicInteger *)dataProgress { - NSArray *localItemsToDelete = _localItemsToDelete; - for (OASettingsItem *item in localItemsToDelete) + NSArray *itemsToLocalDelete = _itemsToLocalDelete; + for (OASettingsItem *item in itemsToLocalDelete) { [item remove]; [itemsProgress addObjectSync:item]; if (_listener) { int p = [dataProgress addAndGet:(APPROXIMATE_FILE_SIZE_BYTES / 1024)]; - NSString *fileName = [OABackupHelper getItemFileName:item]; + NSString *fileName = [BackupUtils getItemFileName:item]; [_listener itemExportDone:[OASettingsItemType typeName:item.type] fileName:fileName]; [_listener updateGeneralProgress:itemsProgress.countSync uploadedKb:(NSInteger)p]; } @@ -272,7 +273,7 @@ - (void) markOldFileForDeletion:(OASettingsItem *)item fileName:(NSString *)file { NSString *type = [OASettingsItemType typeName:item.type]; OAExportSettingsType *exportType = [OAExportSettingsType findBySettingsItem:item]; - if (exportType != nil && ![_backupHelper getVersionHistoryTypePref:exportType].get) + if (exportType != nil && ![[BackupUtils getVersionHistoryTypePref:exportType] get]) { OARemoteFile *remoteFile = [_backupHelper.backup getRemoteFile:type fileName:fileName]; if (remoteFile != nil) diff --git a/Sources/Backup/OABackupHelper.h b/Sources/Backup/OABackupHelper.h index 0293680ed5..767d3148eb 100644 --- a/Sources/Backup/OABackupHelper.h +++ b/Sources/Backup/OABackupHelper.h @@ -35,7 +35,7 @@ static inline BOOL backupDebugLogs() return BACKUP_DEBUG_LOGS; } -@class OAExportSettingsType, OACommonBoolean, OAPrepareBackupResult, OABackupListeners, OASettingsItem, OAFileSettingsItem, OALocalFile, OARemoteFile, OABackupInfo; +@class OAExportSettingsType, OAPrepareBackupResult, OABackupListeners, OAFileSettingsItem, OALocalFile, OARemoteFile, OABackupInfo; @protocol OAOnPrepareBackupListener; @protocol OAOnDeleteFilesListener; @@ -63,17 +63,6 @@ static inline BOOL backupDebugLogs() + (OABackupHelper *)sharedInstance; -+ (NSString *) getItemFileName:(OASettingsItem *)item; -+ (NSString *) getFileItemName:(OAFileSettingsItem *)fileSettingsItem; -+ (NSString *)getFileItemName:(NSString *)filePath fileSettingsItem:(OAFileSettingsItem *)fileSettingsItem; - -+ (void) setLastModifiedTime:(NSString *)name; -+ (void) setLastModifiedTime:(NSString *)name lastModifiedTime:(long)lastModifiedTime; -+ (long) getLastModifiedTime:(NSString *)name; - -- (OACommonBoolean *) getBackupTypePref:(OAExportSettingsType *)type; -- (OACommonBoolean *) getVersionHistoryTypePref:(OAExportSettingsType *)type; - - (NSString *) getOrderId; - (NSString *) getIosId; - (NSString *) getDeviceId; @@ -127,17 +116,6 @@ static inline BOOL backupDebugLogs() - (BOOL) isBackupPreparing; - (NSDictionary *)getPreparedLocalFiles; -- (BOOL) isObfMapExistsOnServer:(NSString *)name; - - (NSInteger) calculateFileSize:(OARemoteFile *)remoteFile; -+ (BOOL) isTokenValid:(NSString *)token; - -+ (BOOL) applyItem:(OASettingsItem *)item type:(NSString *)type name:(NSString *)name; -+ (NSArray *) getItemsForRestore:(OABackupInfo *)info settingsItems:(NSArray *)settingsItems; -+ (NSDictionary *) getItemsMapForRestore:(OABackupInfo *)info settingsItems:(NSArray *)settingsItems; -+ (NSDictionary *) getRemoteFilesSettingsItems:(NSArray *)items - remoteFiles:(NSArray *)remoteFiles - infoFiles:(BOOL)infoFiles; - @end diff --git a/Sources/Backup/OABackupHelper.mm b/Sources/Backup/OABackupHelper.mm index f37d130c1b..b8963f155d 100644 --- a/Sources/Backup/OABackupHelper.mm +++ b/Sources/Backup/OABackupHelper.mm @@ -21,7 +21,7 @@ #import "OABackupError.h" #import "OABackupDbHelper.h" #import "OACollectLocalFilesTask.h" -#import "OABackupInfoGenerationTask.h" +#import "OAGenerateBackupInfoTask.h" #import "OACollectionSettingsItem.h" #import "OADeleteFilesCommand.h" #import "OAWebClient.h" @@ -54,9 +54,6 @@ static NSString *SEND_CODE_URL = [SERVER_URL stringByAppendingString:@"/userdata/send-code"]; static NSString *CHECK_CODE_URL = [SERVER_URL stringByAppendingString:@"/userdata/auth/confirm-code"]; -static NSString *BACKUP_TYPE_PREFIX = @"backup_type_"; -static NSString *VERSION_HISTORY_PREFIX = @"save_version_history_"; - @interface OABackupHelper () @end @@ -117,72 +114,6 @@ + (NSString *) CHECK_CODE_URL return CHECK_CODE_URL; } -+ (BOOL) isTokenValid:(NSString *)token -{ - return [token isMatchedByRegex:@"[0-9]+"]; -} - -+ (NSArray *) getItemsForRestore:(OABackupInfo *)info settingsItems:(NSArray *)settingsItems -{ - NSMutableArray *itemsForRestore = [NSMutableArray array]; - if (info != nil) - { - NSDictionary *restoreItems = [self getRemoteFilesSettingsItems:settingsItems remoteFiles:info.filteredFilesToDownload infoFiles:NO]; - for (OASettingsItem *restoreItem in restoreItems.allValues) - { - if ([restoreItem isKindOfClass:OACollectionSettingsItem.class]) - { - OACollectionSettingsItem *settingsItem = (OACollectionSettingsItem *) restoreItem; - [settingsItem processDuplicateItems]; - settingsItem.shouldReplace = YES; - } - if (restoreItem != nil) - [itemsForRestore addObject:restoreItem]; - } - } - [itemsForRestore sortUsingComparator:^NSComparisonResult(OASettingsItem *item1, OASettingsItem *item2) { - long time1 = item1.lastModifiedTime; - long time2 = item2.lastModifiedTime; - return time1 < time2 ? NSOrderedDescending : time1 > time2 ? NSOrderedAscending : NSOrderedSame; - }]; - return itemsForRestore; -} - -+ (NSDictionary *) getItemsMapForRestore:(OABackupInfo *)info settingsItems:(NSArray *)settingsItems -{ - NSMutableDictionary *itemsForRestore = [NSMutableDictionary dictionary]; - if (info != nil) - [itemsForRestore addEntriesFromDictionary:[self getRemoteFilesSettingsItems:settingsItems remoteFiles:info.filteredFilesToDownload infoFiles:NO]]; - return itemsForRestore; -} - -+ (NSDictionary *) getRemoteFilesSettingsItems:(NSArray *)items - remoteFiles:(NSArray *)remoteFiles - infoFiles:(BOOL)infoFiles -{ - NSMutableDictionary *res = [NSMutableDictionary dictionary]; - NSMutableArray *files = [NSMutableArray arrayWithArray:remoteFiles]; - for (OASettingsItem *item in items) - { - NSMutableArray *processedFiles = [NSMutableArray array]; - for (OARemoteFile *file in files) - { - NSString *type = file.type; - NSString *name = file.name; - if (infoFiles && [name.pathExtension isEqualToString:INFO_EXT]) - name = [name stringByDeletingPathExtension]; - - if ([self applyItem:item type:type name:name]) - { - res[file] = item; - [processedFiles addObject:file]; - } - } - [files removeObjectsInArray:processedFiles]; - } - return res; -} - + (OASettingsItem *) getRestoreItem:(NSArray *)items remoteFile:(OARemoteFile *)remoteFile { for (OASettingsItem *item in items) @@ -193,111 +124,6 @@ + (OASettingsItem *) getRestoreItem:(NSArray *)items remoteFil return nil; } -+ (BOOL) applyItem:(OASettingsItem *)item type:(NSString *)type name:(NSString *)name -{ - NSString *itemFileName = [self getItemFileName:item]; - NSString *itemTypeName = [OASettingsItemType typeName:item.type]; - if ([itemTypeName isEqualToString:type]) - { - if ([name isEqualToString:itemFileName]) - { - return YES; - } - else if ([item isKindOfClass:OAFileSettingsItem.class]) - { - OAFileSettingsItem *fileItem = (OAFileSettingsItem *) item; - NSString *subfolder = [OAFileSettingsItemFileSubtype getSubtypeFolderName:fileItem.subtype]; - if ([name hasPrefix:subfolder] || subfolder.length == 0) - { - if (fileItem.filePath.pathExtension.length == 0 && ![itemFileName hasSuffix:@"/"]) - return [name hasPrefix:[itemFileName stringByAppendingString:@"/"]]; - else - return [name hasPrefix:itemFileName]; - } - } - } - return false; -} - -+ (NSString *) getItemFileName:(OASettingsItem *)item -{ - NSString *fileName; - if ([item isKindOfClass:OAFileSettingsItem.class]) - { - OAFileSettingsItem *fileItem = (OAFileSettingsItem *) item; - fileName = [self getFileItemName:fileItem]; - } - else - { - fileName = item.fileName; - if (fileName.length == 0) - fileName = item.defaultFileName; - } - if (fileName.length > 0 && [fileName characterAtIndex:0] == '/') - fileName = [fileName substringFromIndex:1]; - return fileName; -} - - -+ (NSString *) getFileItemName:(OAFileSettingsItem *)fileSettingsItem -{ - return [self getFileItemName:nil fileSettingsItem:fileSettingsItem]; -} - -+ (NSString *)getFileItemName:(NSString *)filePath fileSettingsItem:(OAFileSettingsItem *)fileSettingsItem -{ - NSString *subtypeFolder = [OAFileSettingsItemFileSubtype getSubtypeFolder:fileSettingsItem.subtype]; - NSString *fileName; - if (!filePath) - filePath = fileSettingsItem.filePath; - - if (subtypeFolder.length == 0) - { - fileName = filePath.lastPathComponent; - } - else if (fileSettingsItem.subtype == EOASettingsItemFileSubtypeGpx) - { - fileName = [filePath stringByReplacingOccurrencesOfString:[subtypeFolder stringByAppendingString:@"/"] withString:@""]; - } - else if ([OAFileSettingsItemFileSubtype isMap:fileSettingsItem.subtype]) - { - fileName = filePath.lastPathComponent; - } - else - { - int index = [filePath indexOf:subtypeFolder.lastPathComponent]; - if (index >= 0) - fileName = [filePath substringFromIndex:index]; - else - fileName = filePath.lastPathComponent; - } - - if (fileName.length > 0 && [fileName characterAtIndex:0] == '/') - fileName = [fileName substringFromIndex:1]; - - return fileName; -} - -+ (BOOL) isLimitedFilesCollectionItem:(OAFileSettingsItem *)item -{ - return item.subtype == EOASettingsItemFileSubtypeVoice; -} - -+ (void) setLastModifiedTime:(NSString *)name -{ - [self setLastModifiedTime:name lastModifiedTime:NSDate.date.timeIntervalSince1970]; -} - -+ (void) setLastModifiedTime:(NSString *)name lastModifiedTime:(long)lastModifiedTime -{ - [OABackupDbHelper.sharedDatabase setLastModifiedTime:name lastModifiedTime:lastModifiedTime]; -} - -+ (long) getLastModifiedTime:(NSString *)name -{ - return [OABackupDbHelper.sharedDatabase getLastModifiedTime:name]; -} - + (OABackupHelper *)sharedInstance { static OABackupHelper *_sharedInstance = nil; @@ -398,16 +224,6 @@ - (void) logout [_settings.backupAccessToken resetToDefault]; } -- (OACommonBoolean *) getBackupTypePref:(OAExportSettingsType *)type -{ - return [[[OACommonBoolean withKey:[NSString stringWithFormat:@"%@%@", BACKUP_TYPE_PREFIX, type.name] defValue:YES] makeGlobal] makeShared]; -} - -- (OACommonBoolean *) getVersionHistoryTypePref:(OAExportSettingsType *)type -{ - return [[[OACommonBoolean withKey:[NSString stringWithFormat:@"%@%@", VERSION_HISTORY_PREFIX, type.name] defValue:YES] makeGlobal] makeShared]; -} - - (NSArray *) collectItemFilesForUpload:(OAFileSettingsItem *)item { NSMutableArray *filesToUpload = [NSMutableArray array]; @@ -746,7 +562,7 @@ - (void) generateBackupInfo:(NSDictionary *)localFile deletedRemoteFiles:(NSDictionary *)deletedRemoteFiles onComplete:(void(^)(OABackupInfo *backupInfo, NSString *error))onComplete { - OABackupInfoGenerationTask *task = [[OABackupInfoGenerationTask alloc] initWithLocalFiles:localFiles uniqueRemoteFiles:uniqueRemoteFiles deletedRemoteFiles:deletedRemoteFiles onComplete:onComplete]; + OAGenerateBackupInfoTask *task = [[OAGenerateBackupInfoTask alloc] initWithLocalFiles:localFiles uniqueRemoteFiles:uniqueRemoteFiles deletedRemoteFiles:deletedRemoteFiles onComplete:onComplete]; [_executor addOperation:task]; } @@ -872,54 +688,6 @@ - (void) deleteFilesSync:(NSArray *)remoteFiles byVersion:(BOOL) } } -- (BOOL) isObfMapExistsOnServer:(NSString *)name -{ - __block BOOL exists = NO; - - NSMutableDictionary *params = [NSMutableDictionary dictionary]; - params[@"name"] = name; - params[@"type"] = @"file"; - - OAOperationLog *operationLog = [[OAOperationLog alloc] initWithOperationName:@"isObfMapExistsOnServer" debug:BACKUP_TYPE_PREFIX]; - [operationLog startOperation:name]; - - [OANetworkUtilities sendRequestWithUrl:@"https://osmand.net/userdata/check-file-on-server" params:params post:NO async:NO onComplete:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { - int status; - NSString *message; - NSString *result = data ? [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] : @""; - if (((NSHTTPURLResponse *)response).statusCode != 200) - { - OABackupError *backupError = [[OABackupError alloc] initWithError:result]; - message = [NSString stringWithFormat:@"Check obf map on server error: %@", backupError.toString]; - status = STATUS_SERVER_ERROR; - } - else if (result.length > 0) - { - NSError *jsonParsingError = nil; - NSDictionary *resultJson = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonParsingError]; - if (!jsonParsingError) - { - NSString *fileStatus = resultJson[@"status"]; - exists = [fileStatus isEqualToString:@"present"]; - status = STATUS_SUCCESS; - message = [NSString stringWithFormat:@"%@ exists: %@", name, exists ? @"true" : @"false"]; - } - else - { - message = @"Check obf map on server error: json parsing"; - status = STATUS_PARSE_JSON_ERROR; - } - } - else - { - status = STATUS_EMPTY_RESPONSE_ERROR; - message = @"Check obf map on server error: empty response"; - } - [operationLog finishOperation:[NSString stringWithFormat:@"(%d): %@", status, message]]; - }]; - return exists; -} - // MARK: OAOnPrepareBackupListener - (void)onBackupPreparing diff --git a/Sources/Backup/OABackupImporter.m b/Sources/Backup/OABackupImporter.m index 0914ed5108..124fd34f05 100644 --- a/Sources/Backup/OABackupImporter.m +++ b/Sources/Backup/OABackupImporter.m @@ -22,6 +22,7 @@ #import "OAOperationLog.h" #import "OAAtomicInteger.h" #import "Localization.h" +#import "OsmAnd_Maps-Swift.h" @interface OAItemFileDownloadTask : NSOperation @@ -180,7 +181,7 @@ - (OACollectItemsResult *) collectItems:(NSArray *)settingsIte { if (settingsItems) { - NSDictionary *items = [OABackupHelper getRemoteFilesSettingsItems:settingsItems remoteFiles:remoteFiles infoFiles:YES]; + NSDictionary *items = [BackupUtils getRemoteFilesSettingsItems:settingsItems remoteFiles:remoteFiles infoFiles:YES]; remoteFiles = items.allKeys; } result.remoteFiles = remoteFiles; @@ -334,7 +335,7 @@ - (void)updateFileUploadTime:(OARemoteFile *)remoteFile item:(OASettingsItem *)i { NSFileManager *fileManager = NSFileManager.defaultManager; BOOL isDir = NO; - NSString *itemFileName = [OABackupHelper getFileItemName:(OAFileSettingsItem *) item]; + NSString *itemFileName = [BackupUtils getFileItemName:(OAFileSettingsItem *) item]; [fileManager fileExistsAtPath:itemFileName isDirectory:&isDir]; if (isDir) { diff --git a/Sources/Backup/OABackupInfo.h b/Sources/Backup/OABackupInfo.h index 093bf460bc..f5f4e09945 100644 --- a/Sources/Backup/OABackupInfo.h +++ b/Sources/Backup/OABackupInfo.h @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) NSMutableArray *itemsToUpload; @property (nonatomic) NSMutableArray *itemsToDelete; -@property (nonatomic) NSMutableArray *localItemsToDelete; +@property (nonatomic) NSMutableArray *itemsToLocalDelete; @property (nonatomic) NSMutableArray *filteredFilesToDownload; @property (nonatomic) NSMutableArray *filteredFilesToUpload; @property (nonatomic) NSMutableArray *filteredFilesToDelete; @@ -31,6 +31,8 @@ NS_ASSUME_NONNULL_BEGIN - (void) createItemCollections; +- (NSString *) toString; + @end NS_ASSUME_NONNULL_END diff --git a/Sources/Backup/OABackupInfo.mm b/Sources/Backup/OABackupInfo.mm index 78b1e86233..d24c36537f 100644 --- a/Sources/Backup/OABackupInfo.mm +++ b/Sources/Backup/OABackupInfo.mm @@ -7,31 +7,28 @@ // #import "OABackupInfo.h" -#import "OsmAndApp.h" #import "OALocalFile.h" #import "OARemoteFile.h" #import "OABackupHelper.h" #import "OAExportSettingsType.h" #import "OAIAPHelper.h" #import "OAAppSettings.h" +#import "OASettingsItem.h" +#import "OsmAnd_Maps-Swift.h" @implementation OABackupInfo -{ - OsmAndAppInstance _app; -} - (instancetype)init { self = [super init]; - if (self) { + if (self) + { _filesToDownload = [NSMutableArray array]; _filesToUpload = [NSMutableArray array]; _filesToDelete = [NSMutableArray array]; _localFilesToDelete = [NSMutableArray array]; _filesToMerge = [NSMutableArray array]; - - _app = OsmAndApp.instance; } return self; } @@ -57,29 +54,31 @@ - (void) createItemsToUpload if (item) [items addObject:item]; } - _itemsToUpload = [NSMutableArray arrayWithArray:items.allObjects]; + _itemsToUpload = [self getSortedItems:items]; } - (void) createItemsToDelete { NSMutableSet *items = [NSMutableSet set]; - for (OARemoteFile *remoteFile in _filteredFilesToDelete) { + for (OARemoteFile *remoteFile in _filteredFilesToDelete) + { OASettingsItem *item = remoteFile.item; if (item) [items addObject:item]; } - _itemsToDelete = [NSMutableArray arrayWithArray:items.allObjects]; + _itemsToDelete = [self getSortedItems:items]; } - (void) createLocalItemsToDelete { NSMutableSet *items = [NSMutableSet set]; - for (OARemoteFile *remoteFile in _filteredLocalFilesToDelete) { + for (OARemoteFile *remoteFile in _filteredLocalFilesToDelete) + { OASettingsItem *item = remoteFile.item; if (item) [items addObject:item]; } - _localItemsToDelete = [NSMutableArray arrayWithArray:items.allObjects]; + _itemsToLocalDelete = [self getSortedItems:items]; } - (void) createFilteredFilesToDownload @@ -89,14 +88,23 @@ - (void) createFilteredFilesToDownload for (OARemoteFile *remoteFile in _filesToDownload) { OAExportSettingsType *type = [OAExportSettingsType findByRemoteFile:remoteFile]; - if (type != nil && [[helper getBackupTypePref:type] get]) - { + if (type != nil && [[BackupUtils getBackupTypePref:type] get]) [files addObject:remoteFile]; - } } _filteredFilesToDownload = files; } +- (NSMutableArray *)getSortedItems:(NSSet *)settingsItems +{ + NSMutableArray *items = [NSMutableArray arrayWithArray:settingsItems.allObjects]; + [items sortUsingComparator:^NSComparisonResult(OASettingsItem *item1, OASettingsItem *item2) { + long time1 = item1.lastModifiedTime; + long time2 = item2.lastModifiedTime; + return time1 < time2 ? NSOrderedDescending : time1 > time2 ? NSOrderedAscending : NSOrderedSame; + }]; + return items; +} + - (void) createFilteredFilesToUpload { NSMutableArray *files = [NSMutableArray array]; @@ -104,10 +112,10 @@ - (void) createFilteredFilesToUpload for (OALocalFile *localFile in _filesToUpload) { OAExportSettingsType *type = [OAExportSettingsType findBySettingsItem:localFile.item]; - if (type != nil && [[helper getBackupTypePref:type] get] && (type.isAllowedInFreeVersion || [OAIAPHelper isOsmAndProAvailable])) - { + if (type != nil + && [[BackupUtils getBackupTypePref:type] get] + && [OAIAPHelper isExportTypeAvailable:type]) [files addObject:localFile]; - } } _filteredFilesToUpload = files; } @@ -119,10 +127,8 @@ - (void) createFilteredFilesToDelete for (OARemoteFile *remoteFile in _filesToDelete) { OAExportSettingsType *exportType = [OAExportSettingsType findByRemoteFile:remoteFile]; - if (exportType != nil && [[helper getBackupTypePref:exportType] get]) - { + if (exportType != nil && [[BackupUtils getBackupTypePref:exportType] get]) [files addObject:remoteFile]; - } } _filteredFilesToDelete = files; } @@ -134,10 +140,8 @@ - (void) createFilteredLocalFilesToDelete for (OALocalFile *localFile in _localFilesToDelete) { OAExportSettingsType *exportType = [OAExportSettingsType findBySettingsItem:localFile.item]; - if (exportType != nil && [[helper getBackupTypePref:exportType] get]) - { + if (exportType != nil && [OAExportSettingsType isTypeEnabled:exportType]) [files addObject:localFile]; - } } _filteredLocalFilesToDelete = files; } @@ -146,14 +150,13 @@ - (void) createFilteredFilesToMerge { NSMutableArray *files = [NSMutableArray array]; NSMutableSet *items = [NSMutableSet set]; - OABackupHelper *helper = OABackupHelper.sharedInstance; for (NSArray *pair in _filesToMerge) { OASettingsItem *item = ((OALocalFile *) pair.firstObject).item; if (![items containsObject:item]) { OAExportSettingsType *exportType = [OAExportSettingsType findByRemoteFile:pair.lastObject]; - if (exportType != nil && [[helper getBackupTypePref:exportType] get]) + if (exportType != nil && [[BackupUtils getBackupTypePref:exportType] get]) { [files addObject:pair]; [items addObject:item]; diff --git a/Sources/Backup/OABackupListeners.m b/Sources/Backup/OABackupListeners.m index 082b8e7c91..2dad9be9bd 100644 --- a/Sources/Backup/OABackupListeners.m +++ b/Sources/Backup/OABackupListeners.m @@ -21,7 +21,8 @@ @implementation OABackupListeners - (instancetype) init { self = [super init]; - if (self) { + if (self) + { _deleteFilesListeners = [NSMutableArray array]; _registerUserListeners = [NSMutableArray array]; _registerDeviceListeners = [NSMutableArray array]; diff --git a/Sources/Backup/OABackupStatus.m b/Sources/Backup/OABackupStatus.m index b167dd4235..feecba676e 100644 --- a/Sources/Backup/OABackupStatus.m +++ b/Sources/Backup/OABackupStatus.m @@ -33,7 +33,8 @@ - (instancetype) initWithStatusTitle:(NSString *)statusTitle iconColor:(NSInteger)iconColor { self = [super init]; - if (self) { + if (self) + { _statusTitle = statusTitle; _statusIconName = statusIconName; _warningIconName = warningIconName; @@ -143,20 +144,14 @@ + (OABackupStatus *) getBackupStatus:(OAPrepareBackupResult *)backup NSInteger errorCode = error.code; if (errorCode == SERVER_ERROR_CODE_SUBSCRIPTION_WAS_EXPIRED_OR_NOT_PRESENT || errorCode == STATUS_NO_ORDER_ID_ERROR) - { return OABackupStatus.SUBSCRIPTION_EXPIRED; - } } if (info != nil) { if (info.filteredFilesToMerge.count > 0) - { return OABackupStatus.CONFLICTS; - } - else if (info.itemsToUpload.count > 0 || info.itemsToDelete.count > 0 || info.localItemsToDelete.count > 0) - { + else if (info.itemsToUpload.count > 0 || info.itemsToDelete.count > 0 || info.itemsToLocalDelete.count > 0) return OABackupStatus.MAKE_BACKUP; - } } else if (!AFNetworkReachabilityManager.sharedManager.isReachable) { diff --git a/Sources/Backup/OACollectLocalFilesTask.m b/Sources/Backup/OACollectLocalFilesTask.m index eedabbed7e..2677058eda 100644 --- a/Sources/Backup/OACollectLocalFilesTask.m +++ b/Sources/Backup/OACollectLocalFilesTask.m @@ -18,6 +18,7 @@ #import "OAAppSettings.h" #import "OASettingsHelper.h" #import "OAOperationLog.h" +#import "OsmAnd_Maps-Swift.h" @implementation OACollectLocalFilesTask { @@ -52,7 +53,7 @@ - (void) execute [_operationLog log:@"getLocalItems"]; for (OASettingsItem *item in localItems) { - NSString *fileName = [OABackupHelper getItemFileName:item]; + NSString *fileName = [BackupUtils getItemFileName:item]; if ([item isKindOfClass:OAFileSettingsItem.class]) { OAFileSettingsItem *fileItem = (OAFileSettingsItem *) item; @@ -196,14 +197,19 @@ - (void) createLocalFile:(NSMutableArray *)result item:(OASetting - (NSArray *) getLocalItems { - NSMutableArray *types = [NSMutableArray arrayWithArray:[OAExportSettingsType getEnabledTypes]]; - NSMutableArray *toDelete = [NSMutableArray array]; - for (OAExportSettingsType *type in types) + NSArray *types = [self getEnabledExportTypes]; + return [OASettingsHelper.sharedInstance getFilteredSettingsItems:types addProfiles:YES doExport:YES]; +} + +- (NSArray *)getEnabledExportTypes +{ + NSMutableArray *result = [NSMutableArray array]; + for (OAExportSettingsType *exportType in [OAExportSettingsType getEnabledTypes]) { - if (![OABackupHelper.sharedInstance getBackupTypePref:type].get) - [toDelete addObject:type]; + if ([[BackupUtils getBackupTypePref:exportType] get]) + [result addObject:exportType]; } - return [OASettingsHelper.sharedInstance getFilteredSettingsItems:types addProfiles:YES doExport:YES]; + return result; } - (void) publishProgress:(OALocalFile *)localFile diff --git a/Sources/Backup/OAExportBackupTask.m b/Sources/Backup/OAExportBackupTask.m index 3547e8549a..e674456e2e 100644 --- a/Sources/Backup/OAExportBackupTask.m +++ b/Sources/Backup/OAExportBackupTask.m @@ -17,6 +17,7 @@ #import "OAPrepareBackupResult.h" #import "OARemoteFile.h" #import "OAConcurrentCollections.h" +#import "OsmAnd_Maps-Swift.h" @interface OAExportBackupTask () @@ -45,13 +46,12 @@ - (instancetype) initWithKey:(NSString *)key _listener = listener; _exporter = [[OABackupExporter alloc] initWithListener:self]; _itemsProgress = [[OAConcurrentDictionary alloc] init]; - OABackupHelper *backupHelper = OABackupHelper.sharedInstance; for (OASettingsItem *item in items) { [_exporter addSettingsItem:item]; OAExportSettingsType *exportType = [OAExportSettingsType findBySettingsItem:item]; - if (exportType && ![[backupHelper getVersionHistoryTypePref:exportType] get]) + if (exportType && ![[BackupUtils getVersionHistoryTypePref:exportType] get]) [_exporter addOldItemToDelete:item]; } for (OASettingsItem *item in itemsToDelete) diff --git a/Sources/Backup/OABackupInfoGenerationTask.h b/Sources/Backup/OAGenerateBackupInfoTask.h similarity index 92% rename from Sources/Backup/OABackupInfoGenerationTask.h rename to Sources/Backup/OAGenerateBackupInfoTask.h index 210e8e200d..69c270c2b5 100644 --- a/Sources/Backup/OABackupInfoGenerationTask.h +++ b/Sources/Backup/OAGenerateBackupInfoTask.h @@ -10,7 +10,7 @@ @class OALocalFile, OARemoteFile, OABackupInfo; -@interface OABackupInfoGenerationTask : NSOperation +@interface OAGenerateBackupInfoTask : NSOperation - (instancetype) initWithLocalFiles:(NSDictionary *)localFiles uniqueRemoteFiles:(NSDictionary *)uniqueRemoteFiles diff --git a/Sources/Backup/OABackupInfoGenerationTask.m b/Sources/Backup/OAGenerateBackupInfoTask.m similarity index 95% rename from Sources/Backup/OABackupInfoGenerationTask.m rename to Sources/Backup/OAGenerateBackupInfoTask.m index d2897369c3..5d73b80a2f 100644 --- a/Sources/Backup/OABackupInfoGenerationTask.m +++ b/Sources/Backup/OAGenerateBackupInfoTask.m @@ -1,12 +1,12 @@ // -// OABackupInfoGenerationTask.m +// OAGenerateBackupInfoTask.m // OsmAnd Maps // // Created by Paul on 24.06.2022. // Copyright © 2022 OsmAnd. All rights reserved. // -#import "OABackupInfoGenerationTask.h" +#import "OAGenerateBackupInfoTask.h" #import "OABackupInfo.h" #import "OAExportSettingsType.h" #import "OARemoteFile.h" @@ -16,7 +16,7 @@ #import "OABackupHelper.h" #import "OAOperationLog.h" -@implementation OABackupInfoGenerationTask +@implementation OAGenerateBackupInfoTask { NSDictionary *_localFiles; NSDictionary *_uniqueRemoteFiles; @@ -32,7 +32,8 @@ - (instancetype) initWithLocalFiles:(NSDictionary *)l onComplete:(void(^)(OABackupInfo *backupInfo, NSString *error))onComplete { self = [super init]; - if (self) { + if (self) + { _localFiles = localFiles; _uniqueRemoteFiles = uniqueRemoteFiles; _deletedRemoteFiles = deletedRemoteFiles; @@ -77,9 +78,7 @@ - (OABackupInfo *) doInBackground { OAExportSettingsType *exportType = [OAExportSettingsType findByRemoteFile:remoteFile]; if (exportType == nil || ![OAExportSettingsType isTypeEnabled:exportType] || remoteFile.isRecordedVoiceFile) - { continue; - } OALocalFile *localFile = _localFiles[remoteFile.getTypeNamePath]; if (localFile != nil) { @@ -96,13 +95,9 @@ - (OABackupInfo *) doInBackground else if (fileChangedRemotely) { if (remoteFile.isDeleted) - { [info.localFilesToDelete addObject:localFile]; - } else - { [info.filesToDownload addObject:remoteFile]; - } } } else if (!remoteFile.isDeleted) @@ -124,7 +119,8 @@ - (OABackupInfo *) doInBackground for (OALocalFile *localFile in _localFiles.allValues) { OAExportSettingsType *exportType = localFile.item != nil - ? [OAExportSettingsType findBySettingsItem:localFile.item] : nil; + ? [OAExportSettingsType findBySettingsItem:localFile.item] + : nil; if (exportType == nil || ![OAExportSettingsType isTypeEnabled:exportType]) continue; @@ -178,7 +174,7 @@ - (OABackupInfo *) doInBackground - (void) onPostExecute:(OABackupInfo *)backupInfo { -// operationLog.finishOperation(backupInfo.toString()); + [_operationLog finishOperation:[backupInfo toString]]; __block NSString *subscriptionError = nil; [[OABackupHelper sharedInstance] checkSubscriptions:^(NSInteger status, NSString *message, NSString *error) { if (error) diff --git a/Sources/Backup/OAImportBackupItemsTask.m b/Sources/Backup/OAImportBackupItemsTask.m index d559d84050..4616407ffc 100644 --- a/Sources/Backup/OAImportBackupItemsTask.m +++ b/Sources/Backup/OAImportBackupItemsTask.m @@ -57,11 +57,11 @@ - (BOOL) doInBackground OAPrepareBackupResult *backup = [OABackupHelper sharedInstance].backup; NSArray *remoteFiles = [backup getRemoteFiles:_filesType].allValues; [_importer importItems:_items remoteFiles:remoteFiles forceReadData:_foreceReadData restoreDeleted:_restoreDeleted]; - return YES; + return _importer.cancelled; } @catch (NSException *exception) { - NSLog(@"Failed to import items from backup"); + NSLog(@"Failed to import items from backup: %@", exception.reason); } return NO; } diff --git a/Sources/Backup/OANetworkSettingsHelper.m b/Sources/Backup/OANetworkSettingsHelper.m index 8460ce12ce..f164daed97 100644 --- a/Sources/Backup/OANetworkSettingsHelper.m +++ b/Sources/Backup/OANetworkSettingsHelper.m @@ -271,7 +271,7 @@ - (void) syncSettingsItems:(NSString *)key case EOABackupSyncOperationDownload: { if (remoteFile && remoteFile.item) - [syncTask downloadRemoteVersion:remoteFile.item filesType:filesType shouldReplace:shouldReplace restoreDeleted:restoreDeleted]; + [syncTask downloadItem:remoteFile.item type:filesType shouldReplace:shouldReplace restoreDeleted:restoreDeleted]; break; } default: diff --git a/Sources/Backup/OANetworkWriter.mm b/Sources/Backup/OANetworkWriter.mm index 659548ed37..0cc9cc9392 100644 --- a/Sources/Backup/OANetworkWriter.mm +++ b/Sources/Backup/OANetworkWriter.mm @@ -13,6 +13,7 @@ #import "OASettingsItemWriter.h" #import "OAFileSettingsItem.h" #import "OrderedDictionary.h" +#import "OsmAnd_Maps-Swift.h" #include @@ -40,7 +41,8 @@ @implementation OANetworkWriter - (instancetype)initWithListener:(id)listener { self = [super init]; - if (self) { + if (self) + { _listener = listener; _backupHelper = OABackupHelper.sharedInstance; _tmpDir = [NSTemporaryDirectory() stringByAppendingPathComponent:@"backup_upload"]; @@ -57,11 +59,12 @@ - (void)dealloc - (void)write:(OASettingsItem *)item { NSString *error = nil; - NSString *fileName = [OABackupHelper getItemFileName:item]; + NSString *fileName = [BackupUtils getItemFileName:item]; OASettingsItemWriter *itemWriter = item.getWriter; if (itemWriter != nil) { - @try { + @try + { error = [self uploadEntry:itemWriter fileName:fileName]; if (error == nil) error = [self uploadItemInfo:item fileName:[fileName stringByAppendingPathExtension:OABackupHelper.INFO_EXT]]; @@ -76,9 +79,7 @@ - (void)write:(OASettingsItem *)item error = [self uploadItemInfo:item fileName:[fileName stringByAppendingPathExtension:OABackupHelper.INFO_EXT]]; } if (_listener != nil) - { [_listener onItemUploadDone:item fileName:fileName error:error]; - } if (error != nil) { NSLog(@"OANetworkWriter error: %@", error); @@ -139,7 +140,8 @@ - (NSString *)uploadItemFile:(OASettingsItemWriter *)itemWriter fileName:(NSString *)fileName listener:(id)listener { - if ([self isCancelled]) { + if ([self isCancelled]) + { @throw [NSException exceptionWithName:@"InterruptedIOException" reason:@"Network upload was cancelled" userInfo:nil]; } else @@ -185,12 +187,7 @@ - (BOOL) shouldUseEmptyWriter:(OASettingsItemWriter *)itemWriter fileName:(NSStr { OASettingsItem *item = itemWriter.item; if ([item isKindOfClass:OAFileSettingsItem.class]) - { - if ([OAFileSettingsItemFileSubtype isMap:((OAFileSettingsItem *) item).subtype]) - { - return [_backupHelper isObfMapExistsOnServer:fileName]; - } - } + return [BackupUtils isDefaultObfMap:(OAFileSettingsItem *) item fileName:fileName]; return false; } @@ -219,7 +216,7 @@ - (NSString *)uploadDirWithFiles:(OASettingsItemWriter *)itemWriter for (NSString *file in filesToUpload) { item.filePath = file; - NSString *name = [OABackupHelper getFileItemName:file fileSettingsItem:item]; + NSString *name = [BackupUtils getFileItemName:file fileSettingsItem:item]; NSString *error = [self uploadItemFile:itemWriter fileName:name listener:self]; if (error != nil) return error; @@ -239,20 +236,14 @@ - (void)onFileUploadDone:(NSString *)type fileName:(NSString *)fileName uploadTi if ([_item isKindOfClass:OAFileSettingsItem.class]) { OAFileSettingsItem *fileItem = (OAFileSettingsItem *) _item; - NSString *itemFileName = [OABackupHelper getFileItemName:fileItem]; + NSString *itemFileName = [BackupUtils getFileItemName:fileItem]; if (itemFileName.pathExtension.length == 0) - { [_backupHelper updateFileUploadTime:[OASettingsItemType typeName:_item.type] fileName:itemFileName uploadTime:uploadTime]; - } if (fileItem.needMd5Digest && fileItem.md5Digest.length > 0) - { [_backupHelper updateFileMd5Digest:[OASettingsItemType typeName:_item.type] fileName:itemFileName md5Hex:fileItem.md5Digest]; - } } if (_listener != nil) - { [_listener onItemFileUploadDone:_item fileName:fileName uploadTime:uploadTime error:error]; - } } - (void)onFileUploadProgress:(NSString *)type fileName:(NSString *)fileName progress:(NSInteger)progress deltaWork:(NSInteger)deltaWork diff --git a/Sources/Backup/OASyncBackupTask.h b/Sources/Backup/OASyncBackupTask.h index 360b63b184..083755dc90 100644 --- a/Sources/Backup/OASyncBackupTask.h +++ b/Sources/Backup/OASyncBackupTask.h @@ -28,10 +28,10 @@ NS_ASSUME_NONNULL_BEGIN - (void) execute; - (void)uploadLocalItem:(OASettingsItem *)item; -- (void)downloadRemoteVersion:(OASettingsItem *)item - filesType:(EOARemoteFilesType)filesType - shouldReplace:(BOOL)shouldReplace - restoreDeleted:(BOOL)restoreDeleted; +- (void)downloadItem:(OASettingsItem *)item + type:(EOARemoteFilesType)filesType + shouldReplace:(BOOL)shouldReplace + restoreDeleted:(BOOL)restoreDeleted; - (void)deleteItem:(OASettingsItem *)item; - (void)deleteLocalItem:(OASettingsItem *)item; diff --git a/Sources/Backup/OASyncBackupTask.mm b/Sources/Backup/OASyncBackupTask.mm index a6fe93b5fd..486dd607e3 100644 --- a/Sources/Backup/OASyncBackupTask.mm +++ b/Sources/Backup/OASyncBackupTask.mm @@ -20,6 +20,7 @@ #import "OARemoteFile.h" #import "OsmAndApp.h" #import "OAAppSettings.h" +#import "OsmAnd_Maps-Swift.h" #include @@ -74,7 +75,7 @@ - (void)startSync OAPrepareBackupResult *backup = _backupHelper.backup; OABackupInfo *info = backup.backupInfo; - NSArray *settingsItems = [OABackupHelper getItemsForRestore:info settingsItems:backup.settingsItems]; + NSArray *settingsItems = [BackupUtils getItemsForRestore:info settingsItems:backup.settingsItems]; if (_operation != EOABackupSyncOperationDownload) _maxProgress += ([self calculateExportMaxProgress] / 1024); @@ -110,26 +111,26 @@ - (void)execute - (void)uploadLocalItem:(OASettingsItem *)item { - [OANetworkSettingsHelper.sharedInstance exportSettings:[OABackupHelper getItemFileName:item] items:@[item] itemsToDelete:@[] localItemsToDelete:@[] listener:self]; + [OANetworkSettingsHelper.sharedInstance exportSettings:[BackupUtils getItemFileName:item] items:@[item] itemsToDelete:@[] localItemsToDelete:@[] listener:self]; } -- (void)downloadRemoteVersion:(OASettingsItem *)item - filesType:(EOARemoteFilesType)filesType - shouldReplace:(BOOL)shouldReplace - restoreDeleted:(BOOL)restoreDeleted +- (void)downloadItem:(OASettingsItem *)item + type:(EOARemoteFilesType)filesType + shouldReplace:(BOOL)shouldReplace + restoreDeleted:(BOOL)restoreDeleted { [item setShouldReplace:shouldReplace]; - [OANetworkSettingsHelper.sharedInstance importSettings:[OABackupHelper getItemFileName:item] items:@[item] filesType:filesType forceReadData:YES shouldReplace:shouldReplace restoreDeleted:restoreDeleted listener:self]; + [OANetworkSettingsHelper.sharedInstance importSettings:[BackupUtils getItemFileName:item] items:@[item] filesType:filesType forceReadData:YES shouldReplace:shouldReplace restoreDeleted:restoreDeleted listener:self]; } - (void) deleteItem:(OASettingsItem *)item { - [OANetworkSettingsHelper.sharedInstance exportSettings:[OABackupHelper getItemFileName:item] items:@[] itemsToDelete:@[item] localItemsToDelete:@[] listener:self]; + [OANetworkSettingsHelper.sharedInstance exportSettings:[BackupUtils getItemFileName:item] items:@[] itemsToDelete:@[item] localItemsToDelete:@[] listener:self]; } - (void) deleteLocalItem:(OASettingsItem *)item { - [OANetworkSettingsHelper.sharedInstance exportSettings:[OABackupHelper getItemFileName:item] items:@[] itemsToDelete:@[] localItemsToDelete:@[item] listener:self]; + [OANetworkSettingsHelper.sharedInstance exportSettings:[BackupUtils getItemFileName:item] items:@[] itemsToDelete:@[] localItemsToDelete:@[item] listener:self]; } - (void)cancel @@ -147,7 +148,7 @@ - (void) uploadNewItems OABackupInfo *info = _backupHelper.backup.backupInfo; NSArray *itemsToUpload = info.itemsToUpload; NSArray *itemsToDelete = info.itemsToDelete; - NSArray *localItemsToDelete = info.localItemsToDelete; + NSArray *localItemsToDelete = info.itemsToLocalDelete; if (itemsToUpload.count > 0 || itemsToDelete.count > 0 || localItemsToDelete.count > 0) [OANetworkSettingsHelper.sharedInstance exportSettings:kBackupItemsKey items:itemsToUpload itemsToDelete:itemsToDelete localItemsToDelete:localItemsToDelete listener:self]; else @@ -168,10 +169,10 @@ - (NSInteger) calculateExportMaxProgress for (OASettingsItem *item in info.itemsToUpload) { OAExportSettingsType *exportType = [OAExportSettingsType findBySettingsItem:item]; - if (exportType && [_backupHelper getVersionHistoryTypePref:exportType].get) + if (exportType && [BackupUtils getVersionHistoryTypePref:exportType].get) [oldItemsToDelete addObject:item]; } - return [OAExportBackupTask getEstimatedItemsSize:info.itemsToUpload itemsToDelete:info.itemsToDelete localItemsToDelete:info.localItemsToDelete oldItemsToDelete:oldItemsToDelete]; + return [OAExportBackupTask getEstimatedItemsSize:info.itemsToUpload itemsToDelete:info.itemsToDelete localItemsToDelete:info.itemsToLocalDelete oldItemsToDelete:oldItemsToDelete]; } return 0; } @@ -195,17 +196,7 @@ - (void)onImportFinished:(BOOL)succeed needRestart:(BOOL)needRestart items:(NSAr if (_cancelled) return; if (succeed) - { - OsmAndAppInstance app = OsmAndApp.instance; - app.resourcesManager->rescanUnmanagedStoragePaths(); - [app.localResourcesChangedObservable notifyEvent]; - [app loadRoutingFiles]; -// reloadIndexes(items); -// AudioVideoNotesPlugin plugin = OsmandPlugin.getPlugin(AudioVideoNotesPlugin.class); -// if (plugin != null) { -// plugin.indexingFiles(true, true); -// } - } + [BackupUtils updateCacheForItems:items]; if (_singleOperation) return [self onSyncFinished:nil]; [self uploadNewItems]; diff --git a/Sources/Controllers/Cloud/OABackupTypesViewController.mm b/Sources/Controllers/Cloud/OABackupTypesViewController.mm index 3ab5fba25a..8f8dd8ea6e 100644 --- a/Sources/Controllers/Cloud/OABackupTypesViewController.mm +++ b/Sources/Controllers/Cloud/OABackupTypesViewController.mm @@ -23,6 +23,7 @@ #import "OAButtonTableViewCell.h" #import "OAIAPHelper.h" #import "OAChoosePlanHelper.h" +#import "OsmAnd_Maps-Swift.h" @implementation OABackupTypesViewController { @@ -130,7 +131,7 @@ - (void)generateData } else { - if (type.isAllowedInFreeVersion) + if (type.isAvailableInFreeVersion) { itemData[@"type"] = [OASwitchTableViewCell getCellIdentifier]; } @@ -206,7 +207,7 @@ - (void)onCellSelected - (void)onTypeSelected:(OAExportSettingsType *)type selected:(BOOL)selected view:(UIView *)view { [super onTypeSelected:type selected:selected view:view]; - [[_backupHelper getBackupTypePref:type] set:selected]; + [[BackupUtils getBackupTypePref:type] set:selected]; [_backupHelper.backup.backupInfo createItemCollections]; } @@ -261,7 +262,7 @@ - (EOARemoteFilesType)getRemoteFilesType NSMutableDictionary *selectedItemsMap = [NSMutableDictionary dictionary]; for (OAExportSettingsType *type in [OAExportSettingsType getAllValues]) { - if ([[_backupHelper getBackupTypePref:type] get]) + if ([[BackupUtils getBackupTypePref:type] get]) selectedItemsMap[type] = [self getItemsForType:type]; } return selectedItemsMap; diff --git a/Sources/Controllers/Cloud/OACloudAccountVerificationViewController.m b/Sources/Controllers/Cloud/OACloudAccountVerificationViewController.m index 65098e7f31..6ee9700d55 100644 --- a/Sources/Controllers/Cloud/OACloudAccountVerificationViewController.m +++ b/Sources/Controllers/Cloud/OACloudAccountVerificationViewController.m @@ -194,7 +194,7 @@ - (void) unfoldButtonPressed - (void) continueButtonPressed { NSString *token = [self getTextFieldValue]; - if ([OABackupHelper isTokenValid:token]) + if ([BackupUtils isTokenValid:token]) { if (_sourceType == EOACloudScreenSourceDeleteAccount) [_backupHelper checkCode:[[OAAppSettings sharedManager].backupUserEmail get] token:token]; @@ -249,7 +249,8 @@ - (void)checkStatus:(NSInteger)status message:(NSString *)message error:(OABacku self.navigationController.viewControllers = viewControllers; }]; } - else { + else + { self.errorMessage = error != nil ? error.getLocalizedError : message; [self updateScreen]; } diff --git a/Sources/Controllers/Cloud/OACloudBackupViewController.mm b/Sources/Controllers/Cloud/OACloudBackupViewController.mm index c86b07b63d..4d80b1951f 100644 --- a/Sources/Controllers/Cloud/OACloudBackupViewController.mm +++ b/Sources/Controllers/Cloud/OACloudBackupViewController.mm @@ -82,7 +82,8 @@ @implementation OACloudBackupViewController - (instancetype) initWithSourceType:(EOACloudScreenSourceType)type { self = [self init]; - if (self) { + if (self) + { _sourceType = type; } return self; @@ -91,7 +92,8 @@ - (instancetype) initWithSourceType:(EOACloudScreenSourceType)type - (instancetype)init { self = [super initWithNibName:@"OACloudBackupViewController" bundle:nil]; - if (self) { + if (self) + { _sourceType = EOACloudScreenSourceTypeDirect; } return self; @@ -294,7 +296,7 @@ - (void)generateData kCellKeyKey: @"remote_updates", kCellTitleKey: OALocalizedString(@"download_tab_updates"), kCellIconNameKey: @"ic_custom_cloud", - @"value": @([OABackupHelper getItemsMapForRestore:_info settingsItems:_backup.settingsItems].count) + @"value": @([BackupUtils getItemsMapForRestore:_info settingsItems:_backup.settingsItems].count + _info.filteredLocalFilesToDelete.count) }]; [collapsableRow addDependentRow:updatesRow]; OATableRowData *conflictsRow = [[OATableRowData alloc] initWithData:@{ @@ -414,7 +416,7 @@ - (BOOL)isActionButtonDisabled:(OATableRowData *)item if (isSyncButton) { BOOL hasInfo = _info != nil; - BOOL noChanges = _status == OABackupStatus.MAKE_BACKUP && (!hasInfo || (_info.filteredFilesToUpload.count == 0 && _info.filteredFilesToDelete.count == 0 && _info.filteredLocalFilesToDelete.count == 0 && [OABackupHelper getItemsMapForRestore:_info settingsItems:_backup.settingsItems].count == 0)); + BOOL noChanges = _status == OABackupStatus.MAKE_BACKUP && (!hasInfo || (_info.filteredFilesToUpload.count == 0 && _info.filteredFilesToDelete.count == 0 && _info.filteredLocalFilesToDelete.count == 0 && [BackupUtils getItemsMapForRestore:_info settingsItems:_backup.settingsItems].count == 0)); actionButtonDisabled = noChanges || _backupHelper.isBackupPreparing || _settingsHelper.isBackupSyncing; } return actionButtonDisabled; @@ -440,7 +442,9 @@ - (void) onCollapseButtonPressed collapsableRow.collapsed = !collapsableRow.collapsed; NSMutableArray *rowIndexes = [NSMutableArray array]; for (NSInteger i = 1; i <= collapsableRow.dependentRowsCount; i++) + { [rowIndexes addObject:[NSIndexPath indexPathForRow:(indexPath.row + i) inSection:indexPath.section]]; + } [self.tblView performBatchUpdates:^{ [self.tblView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; diff --git a/Sources/Controllers/Cloud/OAStatusBackupConflictDetailsViewController.m b/Sources/Controllers/Cloud/OAStatusBackupConflictDetailsViewController.m index 64970aa038..2ce5e84659 100644 --- a/Sources/Controllers/Cloud/OAStatusBackupConflictDetailsViewController.m +++ b/Sources/Controllers/Cloud/OAStatusBackupConflictDetailsViewController.m @@ -278,7 +278,7 @@ - (void)onRowSelected:(NSIndexPath *)indexPath if ([item boolForKey:@"enabled"]) { [self dismissViewControllerAnimated:YES completion:^{ - NSString *fileName = [OABackupHelper getItemFileName:_settingsItem]; + NSString *fileName = [BackupUtils getItemFileName:_settingsItem]; EOABackupSyncOperationType operation = EOABackupSyncOperationNone; if ([item.key isEqualToString:@"uploadLocal"]) operation = EOABackupSyncOperationUpload; @@ -304,7 +304,7 @@ - (void)onRowSelected:(NSIndexPath *)indexPath - (OATableRowData *)populateUploadAction { BOOL deleteOperation = _operation == EOABackupSyncOperationDelete; - NSString *fileName = [OABackupHelper getItemFileName:_settingsItem]; + NSString *fileName = [BackupUtils getItemFileName:_settingsItem]; BOOL enabled = [self isRowEnabled:fileName] && (_localFile || deleteOperation); NSString *title = OALocalizedString(deleteOperation ? @"upload_change" : @"upload_local_version"); NSString *description = @""; @@ -347,7 +347,7 @@ - (OATableRowData *)populateUploadAction - (OATableRowData *)populateDownloadAction { BOOL deleteOperation = _operation == EOABackupSyncOperationDelete; - NSString *fileName = [OABackupHelper getItemFileName:_settingsItem]; + NSString *fileName = [BackupUtils getItemFileName:_settingsItem]; BOOL enabled = [self isRowEnabled:fileName] && (_remoteFile || deleteOperation); NSString *description = @""; if (self.delegate) diff --git a/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm b/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm index cb646a896c..29e0e60693 100644 --- a/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm +++ b/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm @@ -238,7 +238,7 @@ - (void)generateData } if (filesByName.count > 0) { - NSDictionary *downloadItems = [OABackupHelper getItemsMapForRestore:info settingsItems:_backupHelper.backup.settingsItems]; + NSDictionary *downloadItems = [BackupUtils getItemsMapForRestore:info settingsItems:_backupHelper.backup.settingsItems]; for (OARemoteFile *remoteFile in downloadItems.allKeys) { NSString *key = [remoteFile getTypeNamePath]; @@ -258,7 +258,7 @@ - (void)generateData } else if (_tableType == EOARecentChangesRemote) { - NSDictionary *downloadItems = [OABackupHelper getItemsMapForRestore:info settingsItems:_backupHelper.backup.settingsItems]; + NSDictionary *downloadItems = [BackupUtils getItemsMapForRestore:info settingsItems:_backupHelper.backup.settingsItems]; for (OARemoteFile *remoteFile in downloadItems.allKeys) { NSString *key = [remoteFile getTypeNamePath]; @@ -300,12 +300,14 @@ - (void)generateData BOOL deleted = [it.lastObject[@"deleted"] boolValue]; EOABackupSyncOperationType operation = deleted ? EOABackupSyncOperationDelete : _tableType == EOARecentChangesLocal ? EOABackupSyncOperationUpload : EOABackupSyncOperationDownload; - [itemsSection addRow:[self rowFromKey:it.firstObject - mainTint:deleted ? [UIColor colorNamed:ACColorNameIconColorActive] : [UIColor colorNamed:ACColorNameIconColorDisabled] + OATableRowData *rowData = [self rowFromKey:it.firstObject + mainTint:deleted ? [UIColor colorNamed:ACColorNameIconColorActive] : [UIColor colorNamed:ACColorNameIconColorDisabled] secondaryColorName:deleted ? ACColorNameIconColorDisruptive : ACColorNameIconColorActive - operation:operation - localFile:it.lastObject[@"localFile"] - remoteFile:it.lastObject[@"remoteFile"]]]; + operation:operation + localFile:it.lastObject[@"localFile"] + remoteFile:it.lastObject[@"remoteFile"]]; + if (rowData) + [itemsSection addRow:rowData]; } }]; } @@ -314,9 +316,11 @@ - (void)generateData for (NSArray *items in info.filteredFilesToMerge) { NSString *key = [((OALocalFile *) items.firstObject) getTypeFileName]; - [itemsSection addRow:[self rowFromConflictItems:key - localFile:items.firstObject - remoteFile:items.lastObject]]; + OATableRowData *rowData = [self rowFromConflictItems:key + localFile:items.firstObject + remoteFile:items.lastObject]; + if (rowData) + [itemsSection addRow:rowData]; } } @@ -345,7 +349,7 @@ - (BOOL) hasItems switch (_tableType) { case EOARecentChangesRemote: - return [OABackupHelper getItemsMapForRestore:_backupHelper.backup.backupInfo settingsItems:_backupHelper.backup.settingsItems].count > 0; + return [BackupUtils getItemsMapForRestore:_backupHelper.backup.backupInfo settingsItems:_backupHelper.backup.settingsItems].count > 0; case EOARecentChangesLocal: return _backupHelper.backup.backupInfo.filteredFilesToDelete.count + _backupHelper.backup.backupInfo.filteredFilesToUpload.count > 0; default: @@ -379,6 +383,9 @@ - (OATableRowData *)rowFromConflictItems:(NSString *)key operation:EOABackupSyncOperationNone localFile:localFile remoteFile:remoteFile]; + if (!rowData) + return nil; + NSString *conflictStr = [OALocalizedString(@"cloud_conflict") stringByAppendingString:@". "]; NSMutableAttributedString *attributedDescr = [[NSMutableAttributedString alloc] initWithString:[conflictStr stringByAppendingString:rowData.descr]]; [attributedDescr addAttributes:@{ NSFontAttributeName : [UIFont scaledSystemFontOfSize:13 weight:UIFontWeightMedium], @@ -414,6 +421,8 @@ - (OATableRowData *)rowFromKey:(NSString *)key if (!settingsItem) settingsItem = localFile.item; } + if (!settingsItem) + return nil; NSString *name = @""; if ([settingsItem isKindOfClass:OAProfileSettingsItem.class]) diff --git a/Sources/Controllers/OARootViewController.m b/Sources/Controllers/OARootViewController.m index 6d817fe556..01b667143b 100644 --- a/Sources/Controllers/OARootViewController.m +++ b/Sources/Controllers/OARootViewController.m @@ -248,7 +248,7 @@ - (void) handleOsmAndCloudVerification:(NSString *)tokenParam OACloudAccountVerificationViewController *verificationVC = [[OACloudAccountVerificationViewController alloc] initWithEmail:OAAppSettings.sharedManager.backupUserEmail.get sourceType:EOACloudScreenSourceTypeSignIn]; [self.navigationController pushViewController:verificationVC animated:NO]; - if ([OABackupHelper isTokenValid:tokenParam]) + if ([BackupUtils isTokenValid:tokenParam]) { [OABackupHelper.sharedInstance registerDevice:tokenParam]; } diff --git a/Sources/Controllers/Settings/ImportExport/OAImportSettingsViewController.mm b/Sources/Controllers/Settings/ImportExport/OAImportSettingsViewController.mm index 6b8973fc87..53d8acca18 100644 --- a/Sources/Controllers/Settings/ImportExport/OAImportSettingsViewController.mm +++ b/Sources/Controllers/Settings/ImportExport/OAImportSettingsViewController.mm @@ -14,6 +14,7 @@ #import "OsmAndApp.h" #import "OAProgressTitleCell.h" #import "Localization.h" +#import "OsmAnd_Maps-Swift.h" #include @@ -179,6 +180,7 @@ - (void)onSettingsImportFinished:(BOOL)succeed items:(NSArray { if (succeed) { + [BackupUtils updateCacheForItems:items]; [self.tableView reloadData]; OAImportCompleteViewController* importCompleteVC = [[OAImportCompleteViewController alloc] initWithSettingsItems:[OASettingsHelper getSettingsToOperate:items importComplete:YES addEmptyItems:NO] fileName:_file.lastPathComponent]; [self showViewController:importCompleteVC]; diff --git a/Sources/Helpers/OAAppSettings.m b/Sources/Helpers/OAAppSettings.m index d487387d70..e9e6ab1249 100644 --- a/Sources/Helpers/OAAppSettings.m +++ b/Sources/Helpers/OAAppSettings.m @@ -4160,6 +4160,25 @@ - (instancetype) init [_profilePreferences setObject:_locationIcon forKey:@"location_icon"]; _appModeOrder = [OACommonInteger withKey:appModeOrderKey defValue:0]; + NSArray *modes = @[ + OAApplicationMode.DEFAULT, + OAApplicationMode.CAR, + OAApplicationMode.BICYCLE, + OAApplicationMode.PEDESTRIAN, + OAApplicationMode.TRUCK, + OAApplicationMode.MOTORCYCLE, + OAApplicationMode.MOPED, + OAApplicationMode.PUBLIC_TRANSPORT, + OAApplicationMode.TRAIN, + OAApplicationMode.BOAT, + OAApplicationMode.AIRCRAFT, + OAApplicationMode.SKI, + OAApplicationMode.HORSE + ]; + for (NSInteger i = 0; i < modes.count; i++) + { + [_appModeOrder setModeDefaultValue:@(i) mode:modes[i]]; + } [_profilePreferences setObject:_appModeOrder forKey:@"app_mode_order"]; _viewAngleVisibility = [[[OACommonInteger withKey:viewAngleVisibilityKey defValue:[MarkerDisplayOptionWrapper resting]] makeProfile] makeShared]; diff --git a/Sources/History/OAHistoryDB.h b/Sources/History/OAHistoryDB.h index e822408a94..e797c81f57 100644 --- a/Sources/History/OAHistoryDB.h +++ b/Sources/History/OAHistoryDB.h @@ -14,7 +14,7 @@ @interface OAHistoryDB : NSObject - (void)addPoint:(OAHistoryItem *)item; -- (void)deletePoint:(int64_t)id; +- (void)deletePoint:(OAHistoryItem *)item; - (OAHistoryItem *)getPointByName:(NSString *)name fromNavigation:(BOOL)fromNavigation; - (NSArray *)getPoints:(NSString *)selectPostfix limit:(int)limit; @@ -26,7 +26,9 @@ - (NSArray *)getPointsFromNavigation:(int)limit; - (NSInteger)getPointsCountFromNavigation; -- (long) getMarkersHistoryLastModifiedTime; -- (void) setMarkersHistoryLastModifiedTime:(long)lastModified; +- (long)getMarkersHistoryLastModifiedTime; +- (void)setMarkersHistoryLastModifiedTime:(long)lastModified; +- (long)getHistoryLastModifiedTime; +- (void)setHistoryLastModifiedTime:(long)lastModified; @end diff --git a/Sources/History/OAHistoryDB.mm b/Sources/History/OAHistoryDB.mm index 3b9d69dd92..6cd43551c3 100644 --- a/Sources/History/OAHistoryDB.mm +++ b/Sources/History/OAHistoryDB.mm @@ -15,6 +15,7 @@ #import #import "OALog.h" #import "NSData+CRC32.h" +#import "OsmAnd_Maps-Swift.h" #define TABLE_NAME @"history" #define POINT_COL_HASH @"fhash" @@ -27,6 +28,7 @@ #define POINT_COL_TYPE_NAME @"ftypename" #define POINT_COL_FROM_NAVIGATION @"ffromnavigation" +#define HISTORY_LAST_MODIFIED_NAME @"history_recents" #define MARKERS_HISTORY_LAST_MODIFIED_NAME @"map_markers_history" @implementation OAHistoryDB @@ -180,11 +182,16 @@ - (void)addPoint:(OAHistoryItem *)item sqlite3_finalize(statement); sqlite3_close(historyDB); + + if (item.hType == OAHistoryTypeDirection) + [self updateMarkersHistoryLastModifiedTime]; + else + [self updateHistoryLastModifiedTime]; } }); } -- (void)deletePoint:(int64_t)hId +- (void)deletePoint:(OAHistoryItem *)item { dispatch_async(dbQueue, ^{ sqlite3_stmt *statement; @@ -198,11 +205,15 @@ - (void)deletePoint:(int64_t)hId const char *update_stmt = [query UTF8String]; sqlite3_prepare_v2(historyDB, update_stmt, -1, &statement, NULL); - sqlite3_bind_int64(statement, 1, hId); + sqlite3_bind_int64(statement, 1, item.hId); sqlite3_step(statement); sqlite3_finalize(statement); sqlite3_close(historyDB); + if (item.hType == OAHistoryTypeDirection) + [self updateMarkersHistoryLastModifiedTime]; + else + [self updateHistoryLastModifiedTime]; } }); } @@ -459,18 +470,47 @@ - (NSInteger)getPointsCountFromNavigation - (long)getMarkersHistoryLastModifiedTime { - long lastModifiedTime = [OABackupHelper getLastModifiedTime:MARKERS_HISTORY_LAST_MODIFIED_NAME]; + return [self getHistoryLastModifiedTime:MARKERS_HISTORY_LAST_MODIFIED_NAME]; +} + +- (void)setMarkersHistoryLastModifiedTime:(long)lastModified +{ + [BackupUtils setLastModifiedTime:MARKERS_HISTORY_LAST_MODIFIED_NAME + lastModifiedTime:lastModified]; +} + +- (void)updateMarkersHistoryLastModifiedTime +{ + [BackupUtils setLastModifiedTime:MARKERS_HISTORY_LAST_MODIFIED_NAME + lastModifiedTime:(long) NSDate.now.timeIntervalSince1970]; +} + +- (long)getHistoryLastModifiedTime +{ + return [self getHistoryLastModifiedTime:HISTORY_LAST_MODIFIED_NAME]; +} + +- (void)setHistoryLastModifiedTime:(long)lastModified +{ + [BackupUtils setLastModifiedTime:HISTORY_LAST_MODIFIED_NAME + lastModifiedTime:lastModified]; +} + +- (void)updateHistoryLastModifiedTime +{ + [BackupUtils setLastModifiedTime:HISTORY_LAST_MODIFIED_NAME + lastModifiedTime:(long) NSDate.now.timeIntervalSince1970]; +} + +- (long)getHistoryLastModifiedTime:(NSString *)key +{ + long lastModifiedTime = [BackupUtils getLastModifiedTime:key]; if (lastModifiedTime == 0) { lastModifiedTime = [self getDBLastModifiedTime]; - [OABackupHelper setLastModifiedTime:MARKERS_HISTORY_LAST_MODIFIED_NAME lastModifiedTime:lastModifiedTime]; + [BackupUtils setLastModifiedTime:key lastModifiedTime:lastModifiedTime]; } - return lastModifiedTime * 1000; -} - -- (void) setMarkersHistoryLastModifiedTime:(long)lastModified -{ - [OABackupHelper setLastModifiedTime:MARKERS_HISTORY_LAST_MODIFIED_NAME lastModifiedTime:lastModified / 1000]; + return lastModifiedTime; } - (long) getDBLastModifiedTime diff --git a/Sources/History/OAHistoryHelper.h b/Sources/History/OAHistoryHelper.h index 9feaac861b..c4154f23ff 100644 --- a/Sources/History/OAHistoryHelper.h +++ b/Sources/History/OAHistoryHelper.h @@ -36,7 +36,9 @@ - (NSInteger)getPointsCountFromNavigation; - (OAHistoryItem *)getPointByName:(NSString *)name fromNavigation:(BOOL)fromNavigation; -- (long) getMarkersHistoryLastModifiedTime; -- (void) setMarkersHistoryLastModifiedTime:(long)lastModified; +- (long)getMarkersHistoryLastModifiedTime; +- (void)setMarkersHistoryLastModifiedTime:(long)lastModified; +- (long)getHistoryLastModifiedTime; +- (void)setHistoryLastModifiedTime:(long)lastModified; @end diff --git a/Sources/History/OAHistoryHelper.m b/Sources/History/OAHistoryHelper.m index 46e4d87a0c..3c307d38fd 100644 --- a/Sources/History/OAHistoryHelper.m +++ b/Sources/History/OAHistoryHelper.m @@ -50,6 +50,16 @@ - (void) setMarkersHistoryLastModifiedTime:(long)lastModified [_db setMarkersHistoryLastModifiedTime:lastModified]; } +- (long)getHistoryLastModifiedTime +{ + return [_db getHistoryLastModifiedTime]; +} + +- (void)setHistoryLastModifiedTime:(long)lastModified +{ + [_db setHistoryLastModifiedTime:lastModified]; +} + - (void)addPoint:(OAHistoryItem *)item { [_db addPoint:item]; @@ -58,15 +68,16 @@ - (void)addPoint:(OAHistoryItem *)item - (void)removePoint:(OAHistoryItem *)item { - [_db deletePoint:item.hId]; + [_db deletePoint:item]; [_historyPointRemoveObservable notifyEventWithKey:item]; } - (void)removePoints:(NSArray *)items { for (OAHistoryItem *item in items) - [_db deletePoint:item.hId]; - + { + [_db deletePoint:item]; + } [_historyPointsRemoveObservable notifyEventWithKey:items]; } diff --git a/Sources/OsmAnd Maps-Bridging-Header.h b/Sources/OsmAnd Maps-Bridging-Header.h index f2c5aeb6f0..ad7664f5b2 100644 --- a/Sources/OsmAnd Maps-Bridging-Header.h +++ b/Sources/OsmAnd Maps-Bridging-Header.h @@ -66,6 +66,8 @@ #import "OALocationIcon.h" #import "OrderedDictionary.h" #import "OAMapActions.h" +#import "OAPOIFiltersHelper.h" +#import "OARendererRegistry.h" // Widgets #import "OAMapWidgetRegistry.h" @@ -215,6 +217,9 @@ #import "OARemoteFile.h" #import "OAOperationLog.h" #import "OANetworkUtilities.h" +#import "OABackupDbHelper.h" +#import "OACollectionSettingsItem.h" +#import "OAPoiUiFilterSettingsItem.h" // Quick actions #import "OAQuickAction.h" diff --git a/Sources/OsmEdit/OAOsmBugsDBHelper.m b/Sources/OsmEdit/OAOsmBugsDBHelper.m index fd4e9239d8..ffa8d19277 100644 --- a/Sources/OsmEdit/OAOsmBugsDBHelper.m +++ b/Sources/OsmEdit/OAOsmBugsDBHelper.m @@ -12,6 +12,7 @@ #import "OALog.h" #import "OAOsmNotePoint.h" #import "OAOsmPoint.h" +#import "OsmAnd_Maps-Swift.h" #import @@ -115,18 +116,24 @@ - (void) load - (long)getLastModifiedTime { - long lastModifiedTime = [OABackupHelper getLastModifiedTime:OSMBUGS_DB_LAST_MODIFIED_NAME]; + long lastModifiedTime = [BackupUtils getLastModifiedTime:OSMBUGS_DB_LAST_MODIFIED_NAME]; if (lastModifiedTime == 0) { lastModifiedTime = [self getDBLastModifiedTime]; - [OABackupHelper setLastModifiedTime:OSMBUGS_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModifiedTime]; + [BackupUtils setLastModifiedTime:OSMBUGS_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModifiedTime]; } return lastModifiedTime * 1000; } - (void) setLastModifiedTime:(long)lastModified { - [OABackupHelper setLastModifiedTime:OSMBUGS_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModified / 1000]; + [BackupUtils setLastModifiedTime:OSMBUGS_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModified / 1000]; +} + +- (void)updateLastModifiedTime +{ + [BackupUtils setLastModifiedTime:OSMBUGS_DB_LAST_MODIFIED_NAME + lastModifiedTime:(long) NSDate.now.timeIntervalSince1970]; } - (long) getDBLastModifiedTime @@ -213,6 +220,7 @@ -(void) updateOsmBug:(long) identifier text:(NSString *)text sqlite3_step(statement); sqlite3_finalize(statement); sqlite3_close(osmBugsDB); + [self updateLastModifiedTime]; } }); [self checkOsmBugsPoints]; @@ -242,6 +250,7 @@ - (void) updateOsmBugLocation:(long long)identifier newPosition:(CLLocationCoord sqlite3_step(statement); sqlite3_finalize(statement); sqlite3_close(osmBugsDB); + [self updateLastModifiedTime]; } }); [self checkOsmBugsPoints]; @@ -274,6 +283,7 @@ -(void)addOsmbugs:(OAOsmNotePoint *)point sqlite3_step(statement); sqlite3_finalize(statement); sqlite3_close(osmBugsDB); + [self updateLastModifiedTime]; } }); [self checkOsmBugsPoints]; @@ -299,6 +309,7 @@ -(void)deleteAllBugModifications:(OAOsmNotePoint *) point sqlite3_step(statement); sqlite3_finalize(statement); sqlite3_close(osmBugsDB); + [self updateLastModifiedTime]; } }); [self checkOsmBugsPoints]; diff --git a/Sources/OsmEdit/OAOsmEditsDBHelper.m b/Sources/OsmEdit/OAOsmEditsDBHelper.m index b848956d2b..d847e20c65 100644 --- a/Sources/OsmEdit/OAOsmEditsDBHelper.m +++ b/Sources/OsmEdit/OAOsmEditsDBHelper.m @@ -15,6 +15,7 @@ #import "OAWay.h" #import "OARelation.h" #import "OAOsmPoint.h" +#import "OsmAnd_Maps-Swift.h" #import @@ -120,18 +121,24 @@ - (void) load - (long)getLastModifiedTime { - long lastModifiedTime = [OABackupHelper getLastModifiedTime:OPENSTREETMAP_DB_LAST_MODIFIED_NAME]; + long lastModifiedTime = [BackupUtils getLastModifiedTime:OPENSTREETMAP_DB_LAST_MODIFIED_NAME]; if (lastModifiedTime == 0) { lastModifiedTime = [self getDBLastModifiedTime]; - [OABackupHelper setLastModifiedTime:OPENSTREETMAP_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModifiedTime]; + [BackupUtils setLastModifiedTime:OPENSTREETMAP_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModifiedTime]; } return lastModifiedTime * 1000; } - (void) setLastModifiedTime:(long)lastModified { - [OABackupHelper setLastModifiedTime:OPENSTREETMAP_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModified / 1000]; + [BackupUtils setLastModifiedTime:OPENSTREETMAP_DB_LAST_MODIFIED_NAME lastModifiedTime:lastModified / 1000]; +} + +- (void)updateLastModifiedTime +{ + [BackupUtils setLastModifiedTime:OPENSTREETMAP_DB_LAST_MODIFIED_NAME + lastModifiedTime:(long) NSDate.now.timeIntervalSince1970]; } - (long) getDBLastModifiedTime @@ -304,6 +311,8 @@ -(void)addOpenstreetmap:(OAOpenStreetMapPoint *)point sqlite3_finalize(statement); sqlite3_close(osmEditsDB); + + [self updateLastModifiedTime]; } }); [self checkOpenstreetmapPoints]; @@ -329,6 +338,7 @@ -(void)deletePOI:(OAOpenStreetMapPoint *) point sqlite3_step(statement); sqlite3_finalize(statement); sqlite3_close(osmEditsDB); + [self updateLastModifiedTime]; } }); [self checkOpenstreetmapPoints]; @@ -358,6 +368,7 @@ - (void) updateEditLocation:(long long) editId newPosition:(CLLocationCoordinate sqlite3_step(statement); sqlite3_finalize(statement); sqlite3_close(osmEditsDB); + [self updateLastModifiedTime]; } }); [self checkOpenstreetmapPoints]; diff --git a/Sources/POI/OAPOIFiltersHelper.mm b/Sources/POI/OAPOIFiltersHelper.mm index 87cfcac9f2..e9716ef8de 100644 --- a/Sources/POI/OAPOIFiltersHelper.mm +++ b/Sources/POI/OAPOIFiltersHelper.mm @@ -26,6 +26,7 @@ #import "OAWikipediaPlugin.h" #import "OAPluginsHelper.h" #import "OAObservable.h" +#import "OsmAnd_Maps-Swift.h" static NSString* const UDF_CAR_AID = @"car_aid"; static NSString* const UDF_FOR_TOURISTS = @"for_tourists"; @@ -182,6 +183,7 @@ - (BOOL) addFilter:(OAPOIUIFilter *)p addOnlyCategories:(BOOL)addOnlyCategories } sqlite3_close(filtersDB); + [self updateLastModifiedTime]; } }); return YES; @@ -358,6 +360,7 @@ - (BOOL) deleteFilter:(NSString *)filterId sqlite3_finalize(statement); sqlite3_close(filtersDB); + [self updateLastModifiedTime]; } }); return YES; @@ -365,18 +368,24 @@ - (BOOL) deleteFilter:(NSString *)filterId - (long)getLastModifiedTime { - long lastModifiedTime = [OABackupHelper getLastModifiedTime:FILTERS_LAST_MODIFIED_NAME]; + long lastModifiedTime = [BackupUtils getLastModifiedTime:FILTERS_LAST_MODIFIED_NAME]; if (lastModifiedTime == 0) { lastModifiedTime = [self getDBLastModifiedTime]; - [OABackupHelper setLastModifiedTime:FILTERS_LAST_MODIFIED_NAME lastModifiedTime:lastModifiedTime]; + [BackupUtils setLastModifiedTime:FILTERS_LAST_MODIFIED_NAME lastModifiedTime:lastModifiedTime]; } return lastModifiedTime * 1000; } - (void) setLastModifiedTime:(long)lastModified { - [OABackupHelper setLastModifiedTime:FILTERS_LAST_MODIFIED_NAME lastModifiedTime:lastModified / 1000]; + [BackupUtils setLastModifiedTime:FILTERS_LAST_MODIFIED_NAME lastModifiedTime:lastModified / 1000]; +} + +- (void)updateLastModifiedTime +{ + [BackupUtils setLastModifiedTime:FILTERS_LAST_MODIFIED_NAME + lastModifiedTime:(long) NSDate.now.timeIntervalSince1970]; } - (long) getDBLastModifiedTime diff --git a/Sources/Purchases/OAIAPHelper.h b/Sources/Purchases/OAIAPHelper.h index 2e8d39b196..15af1f5028 100644 --- a/Sources/Purchases/OAIAPHelper.h +++ b/Sources/Purchases/OAIAPHelper.h @@ -10,7 +10,7 @@ #define kFreeMapsAvailableTotal 7 -@class OAProduct, OASubscription, OASubscriptionList, OAFunctionalAddon; +@class OAProduct, OASubscription, OASubscriptionList, OAFunctionalAddon, OAExportSettingsType; UIKIT_EXTERN NSString *const OAIAPProductsRequestSucceedNotification; UIKIT_EXTERN NSString *const OAIAPProductsRequestFailedNotification; @@ -157,6 +157,8 @@ typedef NS_ENUM(NSInteger, EOASubscriptionDuration) { + (BOOL) isSubscribedCrossPlatform; + (BOOL) isSubscribedToMapperUpdates; + (BOOL) isOsmAndProAvailable; ++ (BOOL) isExportTypeAvailable:(OAExportSettingsType *)exportType; ++ (BOOL) isBackupAvailable; + (BOOL) isFullVersionPurchased; + (BOOL) isDepthContoursPurchased; diff --git a/Sources/Purchases/OAIAPHelper.mm b/Sources/Purchases/OAIAPHelper.mm index e079102b96..b02948daaf 100644 --- a/Sources/Purchases/OAIAPHelper.mm +++ b/Sources/Purchases/OAIAPHelper.mm @@ -17,6 +17,7 @@ #import "OAObservable.h" #import "OAAppSettings.h" #import "OAProducts.h" +#import "OAExportSettingsType.h" #import NSString *const OAIAPProductsRequestSucceedNotification = @"OAIAPProductsRequestSucceedNotification"; @@ -247,6 +248,16 @@ + (BOOL) isOsmAndProAvailable //#endif } ++ (BOOL)isExportTypeAvailable:(OAExportSettingsType *)exportType +{ + return [self isBackupAvailable] || [exportType isAvailableInFreeVersion]; +} + ++ (BOOL)isBackupAvailable +{ + return [self isOsmAndProAvailable]; +} + + (long) getInstallTime { NSDate *installDate = [[NSUserDefaults standardUserDefaults] objectForKey:@"install_date"]; From de3e079fcd68e2a8a8c8fe2128d574e5884ec385 Mon Sep 17 00:00:00 2001 From: Skalii Date: Tue, 14 Jan 2025 14:06:26 +0200 Subject: [PATCH 5/8] fix open cloud status screens with sync progress; --- .../Controllers/Cloud/OACloudBackupViewController.mm | 6 +++--- .../Cloud/OAStatusBackupTableViewController.h | 2 +- .../Cloud/OAStatusBackupTableViewController.mm | 6 +++--- .../Controllers/Cloud/OAStatusBackupViewController.h | 2 +- .../Controllers/Cloud/OAStatusBackupViewController.m | 11 +++++++---- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Sources/Controllers/Cloud/OACloudBackupViewController.mm b/Sources/Controllers/Cloud/OACloudBackupViewController.mm index 4d80b1951f..f3fc8aad90 100644 --- a/Sources/Controllers/Cloud/OACloudBackupViewController.mm +++ b/Sources/Controllers/Cloud/OACloudBackupViewController.mm @@ -739,15 +739,15 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath OAStatusBackupViewController *statusBackupViewController = nil; if ([item.key isEqualToString:@"local_changes"] || [item.key isEqualToString:@"backupProgress"] || item.rowType == EOATableRowTypeCollapsable) { - statusBackupViewController = [[OAStatusBackupViewController alloc] initWithType:EOARecentChangesLocal]; + statusBackupViewController = [[OAStatusBackupViewController alloc] initWithType:EOARecentChangesLocal syncProgress:_syncProgress]; } else if ([item.key isEqualToString:@"remote_updates"]) { - statusBackupViewController = [[OAStatusBackupViewController alloc] initWithType:EOARecentChangesRemote]; + statusBackupViewController = [[OAStatusBackupViewController alloc] initWithType:EOARecentChangesRemote syncProgress:_syncProgress]; } else if ([item.key isEqualToString:@"conflicts"]) { - statusBackupViewController = [[OAStatusBackupViewController alloc] initWithType:EOARecentChangesConflicts]; + statusBackupViewController = [[OAStatusBackupViewController alloc] initWithType:EOARecentChangesConflicts syncProgress:_syncProgress]; } else if ([item.key isEqualToString:@"onTrashPressed"]) { diff --git a/Sources/Controllers/Cloud/OAStatusBackupTableViewController.h b/Sources/Controllers/Cloud/OAStatusBackupTableViewController.h index 5162455cee..df33379970 100644 --- a/Sources/Controllers/Cloud/OAStatusBackupTableViewController.h +++ b/Sources/Controllers/Cloud/OAStatusBackupTableViewController.h @@ -30,7 +30,7 @@ typedef NS_ENUM(NSInteger, EOARecentChangesType) @interface OAStatusBackupTableViewController : UITableViewController -- (instancetype)initWithTableType:(EOARecentChangesType)type; +- (instancetype)initWithTableType:(EOARecentChangesType)type syncProgress:(float)syncProgress; - (BOOL) hasItems; diff --git a/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm b/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm index 29e0e60693..080b4f1a25 100644 --- a/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm +++ b/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm @@ -66,12 +66,13 @@ @implementation OAStatusBackupTableViewController DownloadingCellCloudHelper *_downloadingCellCloudHelper; } -- (instancetype)initWithTableType:(EOARecentChangesType)type +- (instancetype)initWithTableType:(EOARecentChangesType)type syncProgress:(float)syncProgress { self = [super initWithStyle:UITableViewStyleGrouped]; if (self) { _tableType = type; + _syncProgress = syncProgress; _settingsHelper = [OANetworkSettingsHelper sharedInstance]; _backupHelper = [OABackupHelper sharedInstance]; [self setupNotificationListeners]; @@ -91,7 +92,6 @@ - (void)viewDidLoad { [super viewDidLoad]; - _syncProgress = 0; [self setupDownloadingCellHelper]; self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0.001, 0.001)]; @@ -140,6 +140,7 @@ - (void)dealloc - (void)updateData { + _syncProgress = 0; [self generateData]; [_downloadingCellCloudHelper cleanCellCache]; [self.tableView reloadData]; @@ -181,7 +182,6 @@ - (void)updateData - (void)generateData { _syncProgressCell = nil; - _syncProgress = 0; _itemsSection = -1; _data = [[OATableDataModel alloc] init]; OATableSectionData *statusSection = [OATableSectionData sectionData]; diff --git a/Sources/Controllers/Cloud/OAStatusBackupViewController.h b/Sources/Controllers/Cloud/OAStatusBackupViewController.h index b2d93fbabd..3bd941a9b4 100644 --- a/Sources/Controllers/Cloud/OAStatusBackupViewController.h +++ b/Sources/Controllers/Cloud/OAStatusBackupViewController.h @@ -11,6 +11,6 @@ @interface OAStatusBackupViewController : OACompoundViewController -- (instancetype) initWithType:(EOARecentChangesType)type; +- (instancetype) initWithType:(EOARecentChangesType)type syncProgress:(float)syncProgress; @end diff --git a/Sources/Controllers/Cloud/OAStatusBackupViewController.m b/Sources/Controllers/Cloud/OAStatusBackupViewController.m index 0230f2186e..a9176440cb 100644 --- a/Sources/Controllers/Cloud/OAStatusBackupViewController.m +++ b/Sources/Controllers/Cloud/OAStatusBackupViewController.m @@ -45,16 +45,19 @@ @implementation OAStatusBackupViewController OABackupHelper *_backupHelper; OANetworkSettingsHelper *_settingsHelper; - + float _syncProgress; + EOARecentChangesType _startType; NSInteger _prevTab; } -- (instancetype) initWithType:(EOARecentChangesType)type +- (instancetype) initWithType:(EOARecentChangesType)type syncProgress:(float)syncProgress { self = [super init]; - if (self) { + if (self) + { _startType = type; + _syncProgress = syncProgress; _settingsHelper = [OANetworkSettingsHelper sharedInstance]; _backupHelper = OABackupHelper.sharedInstance; [self setupNotificationListeners]; @@ -100,7 +103,7 @@ - (void)viewWillAppear:(BOOL)animated _controllers = [NSMutableArray array]; for (EOARecentChangesType i = 0; i <= EOARecentChangesConflicts; i++) { - [_controllers addObject:[[OAStatusBackupTableViewController alloc] initWithTableType:i]]; + [_controllers addObject:[[OAStatusBackupTableViewController alloc] initWithTableType:i syncProgress:_syncProgress]]; } [self setupPageController]; _segmentControl.selectedSegmentIndex = _startType; From 55776961a49c59e7d162ef6f370c3b984b3c233f Mon Sep 17 00:00:00 2001 From: Skalii Date: Tue, 14 Jan 2025 14:06:56 +0200 Subject: [PATCH 6/8] sync cloud code; --- Sources/Backup/OAImportBackupTask.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Backup/OAImportBackupTask.m b/Sources/Backup/OAImportBackupTask.m index cb2860683f..f2e0483ef4 100644 --- a/Sources/Backup/OAImportBackupTask.m +++ b/Sources/Backup/OAImportBackupTask.m @@ -344,8 +344,6 @@ - (void) onProgressUpdate:(OAItemProgressInfo *)info - (void)itemExportDone:(nonnull NSString *)type fileName:(nonnull NSString *)fileName { [self onProgressUpdate:[[OAItemProgressInfo alloc] initWithType:type fileName:fileName progress:0 work:0 finished:YES]]; - if ([self isCancelled]) - _importer.cancelled = YES; } - (void)itemExportStarted:(nonnull NSString *)type fileName:(nonnull NSString *)fileName work:(NSInteger)work @@ -360,6 +358,8 @@ - (void)updateItemProgress:(nonnull NSString *)type fileName:(nonnull NSString * - (void)updateGeneralProgress:(NSInteger)downloadedItems uploadedKb:(NSInteger)uploadedKb { + if ([self isCancelled]) + _importer.cancelled = YES; _generalProgress = uploadedKb; [_importListener onImportProgressUpdate:_generalProgress uploadedKb:uploadedKb]; } From 6cd418c3746c517e3d47dfc18c39542f75d6c3c9 Mon Sep 17 00:00:00 2001 From: Skalii Date: Tue, 14 Jan 2025 14:08:00 +0200 Subject: [PATCH 7/8] fix header on cloud status screens; --- .../en.lproj/Localizable.strings | 1 + .../OAStatusBackupTableViewController.mm | 61 ++++++++----------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/Resources/Localizations/en.lproj/Localizable.strings b/Resources/Localizations/en.lproj/Localizable.strings index 56c6c958b7..ce7ae2b23f 100644 --- a/Resources/Localizations/en.lproj/Localizable.strings +++ b/Resources/Localizations/en.lproj/Localizable.strings @@ -1615,6 +1615,7 @@ "res_world_map" = "World map"; "shared_string_world" = "World"; "download_tab_updates" = "Updates"; +"download_tab_conflicts" = "Unresolved"; "res_worldwide" = "Worldwide"; "res_region_map" = "Region map"; "res_updates_avail" = "Updates available"; diff --git a/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm b/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm index 080b4f1a25..da90621627 100644 --- a/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm +++ b/Sources/Controllers/Cloud/OAStatusBackupTableViewController.mm @@ -42,7 +42,6 @@ #import "OAImportBackupTask.h" #import "OAExportBackupTask.h" #import "OALocalFile.h" -#import "OATableViewCustomHeaderView.h" #import "OASizes.h" #import "OAResourcesUIHelper.h" #import "OsmAnd_Maps-Swift.h" @@ -96,7 +95,6 @@ - (void)viewDidLoad self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0.001, 0.001)]; [self generateData]; - [self.tableView registerClass:OATableViewCustomHeaderView.class forHeaderFooterViewReuseIdentifier:[OATableViewCustomHeaderView getCellIdentifier]]; } - (void)viewWillAppear:(BOOL)animated @@ -215,12 +213,15 @@ - (void)generateData OATableSectionData *itemsSection = [OATableSectionData sectionData]; OABackupInfo *info = _backupHelper.backup.backupInfo; + NSString *header = @""; if (_tableType == EOARecentChangesLocal || _tableType == EOARecentChangesRemote) { NSMutableDictionary *filesByName = [NSMutableDictionary dictionary]; if (_tableType == EOARecentChangesLocal) { + header = OALocalizedString(@"cloud_recent_changes"); + NSArray *localFiles = info.filteredFilesToUpload; for (OALocalFile *localFile in localFiles) { @@ -258,6 +259,8 @@ - (void)generateData } else if (_tableType == EOARecentChangesRemote) { + header = OALocalizedString(@"download_tab_updates"); + NSDictionary *downloadItems = [BackupUtils getItemsMapForRestore:info settingsItems:_backupHelper.backup.settingsItems]; for (OARemoteFile *remoteFile in downloadItems.allKeys) { @@ -313,6 +316,8 @@ - (void)generateData } else if (_tableType == EOARecentChangesConflicts) { + header = OALocalizedString(@"download_tab_conflicts"); + for (NSArray *items in info.filteredFilesToMerge) { NSString *key = [((OALocalFile *) items.firstObject) getTypeFileName]; @@ -334,14 +339,20 @@ - (void)generateData kCellIconNameKey: @"ic_action_cloud_smile_face_colored" }]; } + else + { + itemsSection.headerText = [NSString stringWithFormat:OALocalizedString(@"ltr_or_rtl_combine_via_dash"), + header, + @([itemsSection rowCount]).stringValue]; + } if (![_backupHelper isBackupPreparing]) { _itemsSection = _data.sectionCount; [_data addSection:itemsSection]; } - if (_itemsSection != -1 && _tableType == EOARecentChangesConflicts && itemsSection.rowCount > 1) - [_data sectionDataForIndex:_itemsSection].headerText = OALocalizedString(@"backup_conflicts_descr"); + if (_tableType == EOARecentChangesConflicts && itemsSection.rowCount > 1) + statusSection.footerText = OALocalizedString(@"backup_conflicts_descr"); } - (BOOL) hasItems @@ -587,6 +598,16 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger return [_data rowCount:section]; } +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + return [_data sectionDataForIndex:section].headerText; +} + +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section +{ + return [_data sectionDataForIndex:section].footerText; +} + - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { OATableRowData *item = [_data itemForIndexPath:indexPath]; @@ -709,38 +730,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N // MARK: UITableViewDelegate -- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section -{ - OATableViewCustomHeaderView *customHeader = [tableView dequeueReusableHeaderFooterViewWithIdentifier:[OATableViewCustomHeaderView getCellIdentifier]]; - NSString *header = [_data sectionDataForIndex:section].headerText; - if (header && section == _itemsSection && _tableType == EOARecentChangesConflicts) - { - customHeader.label.text = header; - customHeader.label.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; - [customHeader setYOffset:2.]; - return customHeader; - } - return nil; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section -{ - NSString *header = [_data sectionDataForIndex:section].headerText; - if (section == _itemsSection) - { - if (header && _tableType == EOARecentChangesConflicts) - { - return [OATableViewCustomHeaderView getHeight:header - width:tableView.bounds.size.width - xOffset:kPaddingOnSideOfContent - yOffset:2. - font:[UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]] + 15.; - } - return kHeaderHeightDefault; - } - return 0.001; -} - - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { OATableRowData *item = [_data itemForIndexPath:indexPath]; From da3da7a61f029553d848763af88b369732a40709 Mon Sep 17 00:00:00 2001 From: Skalii Date: Tue, 14 Jan 2025 15:14:48 +0200 Subject: [PATCH 8/8] fix markers history lastModifiedTime --- Sources/History/OAHistoryDB.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/History/OAHistoryDB.mm b/Sources/History/OAHistoryDB.mm index 6cd43551c3..5aea927d11 100644 --- a/Sources/History/OAHistoryDB.mm +++ b/Sources/History/OAHistoryDB.mm @@ -476,7 +476,7 @@ - (long)getMarkersHistoryLastModifiedTime - (void)setMarkersHistoryLastModifiedTime:(long)lastModified { [BackupUtils setLastModifiedTime:MARKERS_HISTORY_LAST_MODIFIED_NAME - lastModifiedTime:lastModified]; + lastModifiedTime:lastModified / 1000]; } - (void)updateMarkersHistoryLastModifiedTime @@ -510,7 +510,7 @@ - (long)getHistoryLastModifiedTime:(NSString *)key lastModifiedTime = [self getDBLastModifiedTime]; [BackupUtils setLastModifiedTime:key lastModifiedTime:lastModifiedTime]; } - return lastModifiedTime; + return lastModifiedTime * 1000; } - (long) getDBLastModifiedTime