use of net.osmand.OperationLog in project Osmand by osmandapp.
the class BackupHelper method downloadFile.
@NonNull
String downloadFile(@NonNull File file, @NonNull RemoteFile remoteFile, @Nullable OnDownloadFileListener listener) throws UserNotRegisteredException {
checkRegistered();
OperationLog operationLog = new OperationLog("downloadFile " + file.getName(), DEBUG);
String error;
String type = remoteFile.getType();
String fileName = remoteFile.getName();
try {
Map<String, String> params = new HashMap<>();
params.put("deviceid", getDeviceId());
params.put("accessToken", getAccessToken());
params.put("name", fileName);
params.put("type", type);
StringBuilder sb = new StringBuilder(DOWNLOAD_FILE_URL);
boolean firstParam = true;
for (Entry<String, String> entry : params.entrySet()) {
sb.append(firstParam ? "?" : "&").append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8"));
firstParam = false;
}
IProgress progress = new AbstractProgress() {
private int work = 0;
private int progress = 0;
private int deltaProgress = 0;
@Override
public void startWork(int work) {
if (listener != null) {
this.work = work > 0 ? work : 1;
listener.onFileDownloadStarted(type, fileName, work);
}
}
@Override
public void progress(int deltaWork) {
if (listener != null) {
deltaProgress += deltaWork;
if ((deltaProgress > (work / 100)) || ((progress + deltaProgress) >= work)) {
progress += deltaProgress;
listener.onFileDownloadProgress(type, fileName, progress, deltaProgress);
deltaProgress = 0;
}
}
}
@Override
public boolean isInterrupted() {
if (listener != null) {
return listener.isDownloadCancelled();
}
return super.isInterrupted();
}
};
progress.startWork((int) (remoteFile.getFilesize() / 1024));
error = AndroidNetworkUtils.downloadFile(sb.toString(), file, true, progress);
} catch (UnsupportedEncodingException e) {
error = "UnsupportedEncodingException";
}
if (listener != null) {
listener.onFileDownloadDone(type, fileName, error);
}
operationLog.finishOperation();
return error;
}
use of net.osmand.OperationLog in project Osmand by osmandapp.
the class BackupHelper method checkSubscriptions.
void checkSubscriptions(@Nullable OnUpdateSubscriptionListener listener) {
boolean subscriptionActive = false;
InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper();
if (purchaseHelper != null) {
OperationLog operationLog = new OperationLog("checkSubscriptions", DEBUG);
String error = "";
try {
subscriptionActive = purchaseHelper.checkBackupSubscriptions();
} catch (Exception e) {
error = e.getMessage();
}
operationLog.finishOperation(subscriptionActive + " " + error);
}
if (subscriptionActive) {
if (listener != null) {
listener.onUpdateSubscription(STATUS_SUCCESS, "Subscriptions have been checked successfully", null);
}
} else {
updateOrderId(listener);
}
}
use of net.osmand.OperationLog in project Osmand by osmandapp.
the class BackupImporter method getRemoteItems.
@NonNull
private List<SettingsItem> getRemoteItems(@NonNull List<RemoteFile> remoteFiles, boolean readItems) throws IllegalArgumentException, IOException {
if (remoteFiles.isEmpty()) {
return Collections.emptyList();
}
List<SettingsItem> items = new ArrayList<>();
try {
OperationLog operationLog = new OperationLog("getRemoteItems", BackupHelper.DEBUG);
operationLog.startOperation();
JSONObject json = new JSONObject();
JSONArray itemsJson = new JSONArray();
json.put("items", itemsJson);
Map<File, RemoteFile> remoteInfoFilesMap = new HashMap<>();
Map<String, RemoteFile> remoteItemFilesMap = new HashMap<>();
List<RemoteFile> remoteInfoFiles = new ArrayList<>();
Set<String> remoteInfoNames = new HashSet<>();
List<RemoteFile> noInfoRemoteItemFiles = new ArrayList<>();
OsmandApplication app = backupHelper.getApp();
File tempDir = FileUtils.getTempDir(app);
List<RemoteFile> uniqueRemoteFiles = new ArrayList<>();
Set<String> uniqueFileIds = new TreeSet<>();
for (RemoteFile rf : remoteFiles) {
String fileId = rf.getTypeNamePath();
if (uniqueFileIds.add(fileId) && !rf.isDeleted()) {
uniqueRemoteFiles.add(rf);
}
}
operationLog.log("build uniqueRemoteFiles");
Map<String, UploadedFileInfo> infoMap = backupHelper.getDbHelper().getUploadedFileInfoMap();
BackupInfo backupInfo = backupHelper.getBackup().getBackupInfo();
List<RemoteFile> filesToDelete = backupInfo != null ? backupInfo.filesToDelete : Collections.emptyList();
for (RemoteFile remoteFile : uniqueRemoteFiles) {
String fileName = remoteFile.getTypeNamePath();
if (fileName.endsWith(INFO_EXT)) {
boolean delete = false;
String origFileName = remoteFile.getName().substring(0, remoteFile.getName().length() - INFO_EXT.length());
for (RemoteFile file : filesToDelete) {
if (file.getName().equals(origFileName)) {
delete = true;
break;
}
}
UploadedFileInfo fileInfo = infoMap.get(remoteFile.getType() + "___" + origFileName);
long uploadTime = fileInfo != null ? fileInfo.getUploadTime() : 0;
if (readItems && (uploadTime != remoteFile.getClienttimems() || delete)) {
remoteInfoFilesMap.put(new File(tempDir, fileName), remoteFile);
}
String itemFileName = fileName.substring(0, fileName.length() - INFO_EXT.length());
remoteInfoNames.add(itemFileName);
remoteInfoFiles.add(remoteFile);
} else if (!remoteItemFilesMap.containsKey(fileName)) {
remoteItemFilesMap.put(fileName, remoteFile);
}
}
operationLog.log("build maps");
for (Entry<String, RemoteFile> remoteFileEntry : remoteItemFilesMap.entrySet()) {
String itemFileName = remoteFileEntry.getKey();
RemoteFile remoteFile = remoteFileEntry.getValue();
boolean hasInfo = false;
for (String remoteInfoName : remoteInfoNames) {
if (itemFileName.equals(remoteInfoName) || itemFileName.startsWith(remoteInfoName + "/")) {
hasInfo = true;
break;
}
}
if (!hasInfo && !remoteFile.isRecordedVoiceFile()) {
noInfoRemoteItemFiles.add(remoteFile);
}
}
operationLog.log("build noInfoRemoteItemFiles");
if (readItems) {
generateItemsJson(itemsJson, remoteInfoFilesMap, noInfoRemoteItemFiles);
} else {
generateItemsJson(itemsJson, remoteInfoFiles, noInfoRemoteItemFiles);
}
operationLog.log("generateItemsJson");
SettingsItemsFactory itemsFactory = new SettingsItemsFactory(app, json);
operationLog.log("create setting items");
List<SettingsItem> settingsItemList = itemsFactory.getItems();
if (settingsItemList.isEmpty()) {
return Collections.emptyList();
}
updateFilesInfo(remoteItemFilesMap, settingsItemList);
items.addAll(settingsItemList);
operationLog.log("updateFilesInfo");
if (readItems) {
Map<RemoteFile, SettingsItemReader<? extends SettingsItem>> remoteFilesForRead = new HashMap<>();
for (SettingsItem item : settingsItemList) {
if (item.shouldReadOnCollecting()) {
List<RemoteFile> foundRemoteFiles = getItemRemoteFiles(item, remoteItemFilesMap);
for (RemoteFile remoteFile : foundRemoteFiles) {
SettingsItemReader<? extends SettingsItem> reader = item.getReader();
if (reader != null) {
remoteFilesForRead.put(remoteFile, reader);
}
}
}
}
Map<File, RemoteFile> remoteFilesForDownload = new HashMap<>();
for (RemoteFile remoteFile : remoteFilesForRead.keySet()) {
String fileName = remoteFile.getTypeNamePath();
remoteFilesForDownload.put(new File(tempDir, fileName), remoteFile);
}
if (!remoteFilesForDownload.isEmpty()) {
downloadAndReadItemFiles(remoteFilesForRead, remoteFilesForDownload);
}
operationLog.log("readItems");
}
operationLog.finishOperation();
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Error reading items", e);
} catch (JSONException e) {
throw new IllegalArgumentException("Error parsing items", e);
} catch (IOException e) {
throw new IOException(e);
}
return items;
}
use of net.osmand.OperationLog in project Osmand by osmandapp.
the class BackupExporter method writeItems.
@Override
protected void writeItems(@NonNull AbstractWriter writer) throws IOException {
OperationLog log = new OperationLog("writeItems", true);
log.startOperation();
StringBuilder subscriptionError = new StringBuilder();
backupHelper.checkSubscriptions((status, message, err) -> {
if (err != null) {
subscriptionError.append(err);
}
});
if (subscriptionError.length() > 0) {
throw new IOException(subscriptionError.toString());
}
List<ItemWriterTask> lightTasks = new ArrayList<>();
List<ItemWriterTask> heavyTasks = new ArrayList<>();
for (SettingsItem item : getItems()) {
if (item.getEstimatedSize() > MAX_LIGHT_ITEM_SIZE) {
heavyTasks.add(new ItemWriterTask(writer, item));
} else {
lightTasks.add(new ItemWriterTask(writer, item));
}
}
if (!lightTasks.isEmpty()) {
executor = new ThreadPoolTaskExecutor<>(null);
executor.setInterruptOnError(true);
executor.run(lightTasks);
if (!executor.getExceptions().isEmpty()) {
log.finishOperation();
Throwable t = executor.getExceptions().values().iterator().next();
throw new IOException(t.getMessage(), t);
}
}
if (!heavyTasks.isEmpty()) {
executor = new ThreadPoolTaskExecutor<>(1, null);
executor.setInterruptOnError(true);
executor.run(heavyTasks);
if (!executor.getExceptions().isEmpty()) {
log.finishOperation();
Throwable t = executor.getExceptions().values().iterator().next();
throw new IOException(t.getMessage(), t);
}
}
log.finishOperation();
}
use of net.osmand.OperationLog in project Osmand by osmandapp.
the class BackupHelper method generateBackupInfo.
@SuppressLint("StaticFieldLeak")
void generateBackupInfo(@NonNull final Map<String, LocalFile> localFiles, @NonNull final Map<String, RemoteFile> uniqueRemoteFiles, @NonNull final Map<String, RemoteFile> deletedRemoteFiles, @Nullable final OnGenerateBackupInfoListener listener) {
OperationLog operationLog = new OperationLog("generateBackupInfo", DEBUG, 200);
operationLog.startOperation();
AsyncTask<Void, Void, BackupInfo> task = new AsyncTask<Void, Void, BackupInfo>() {
@Override
protected BackupInfo doInBackground(Void... voids) {
BackupInfo info = new BackupInfo();
/*
operationLog.log("=== localFiles ===");
for (LocalFile localFile : localFiles.values()) {
operationLog.log(localFile.toString());
}
operationLog.log("=== localFiles ===");
operationLog.log("=== uniqueRemoteFiles ===");
for (RemoteFile remoteFile : uniqueRemoteFiles.values()) {
operationLog.log(remoteFile.toString());
}
operationLog.log("=== uniqueRemoteFiles ===");
operationLog.log("=== deletedRemoteFiles ===");
for (RemoteFile remoteFile : deletedRemoteFiles.values()) {
operationLog.log(remoteFile.toString());
}
operationLog.log("=== deletedRemoteFiles ===");
*/
List<RemoteFile> remoteFiles = new ArrayList<>(uniqueRemoteFiles.values());
remoteFiles.addAll(deletedRemoteFiles.values());
for (RemoteFile remoteFile : remoteFiles) {
ExportSettingsType exportType = ExportSettingsType.getExportSettingsTypeForRemoteFile(remoteFile);
if (exportType == null || !ExportSettingsType.isTypeEnabled(exportType) || remoteFile.isRecordedVoiceFile()) {
continue;
}
LocalFile localFile = localFiles.get(remoteFile.getTypeNamePath());
if (localFile != null) {
long remoteUploadTime = remoteFile.getClienttimems();
long localUploadTime = localFile.uploadTime;
if (remoteFile.isDeleted()) {
info.localFilesToDelete.add(localFile);
} else if (remoteUploadTime == localUploadTime) {
if (localUploadTime < localFile.localModifiedTime) {
info.filesToUpload.add(localFile);
info.filesToDownload.add(remoteFile);
}
} else {
info.filesToMerge.add(new Pair<>(localFile, remoteFile));
info.filesToDownload.add(remoteFile);
}
long localFileSize = localFile.file == null ? 0 : localFile.file.length();
long remoteFileSize = remoteFile.getFilesize();
if (remoteFileSize > 0 && localFileSize > 0 && localFileSize != remoteFileSize && !info.filesToDownload.contains(remoteFile)) {
info.filesToDownload.add(remoteFile);
}
}
if (localFile == null && !remoteFile.isDeleted()) {
UploadedFileInfo fileInfo = dbHelper.getUploadedFileInfo(remoteFile.getType(), remoteFile.getName());
// suggest to remove only if file exists in db
if (fileInfo != null) {
info.filesToDelete.add(remoteFile);
}
info.filesToDownload.add(remoteFile);
}
}
for (LocalFile localFile : localFiles.values()) {
ExportSettingsType exportType = localFile.item != null ? ExportSettingsType.getExportSettingsTypeForItem(localFile.item) : null;
if (exportType == null || !ExportSettingsType.isTypeEnabled(exportType)) {
continue;
}
boolean hasRemoteFile = uniqueRemoteFiles.containsKey(localFile.getTypeFileName());
if (!hasRemoteFile) {
boolean isEmpty = localFile.item instanceof CollectionSettingsItem<?> && ((CollectionSettingsItem<?>) localFile.item).isEmpty();
if (!isEmpty) {
info.filesToUpload.add(localFile);
}
}
}
info.createItemCollections(app);
operationLog.log("=== filesToUpload ===");
for (LocalFile localFile : info.filesToUpload) {
operationLog.log(localFile.toString());
}
operationLog.log("=== filesToUpload ===");
operationLog.log("=== filesToDownload ===");
for (RemoteFile remoteFile : info.filesToDownload) {
operationLog.log(remoteFile.toString());
}
operationLog.log("=== filesToDownload ===");
operationLog.log("=== filesToDelete ===");
for (RemoteFile remoteFile : info.filesToDelete) {
operationLog.log(remoteFile.toString());
}
operationLog.log("=== filesToDelete ===");
operationLog.log("=== filesToMerge ===");
for (Pair<LocalFile, RemoteFile> filePair : info.filesToMerge) {
operationLog.log("LOCAL=" + filePair.first.toString() + " REMOTE=" + filePair.second.toString());
}
operationLog.log("=== filesToMerge ===");
return info;
}
@Override
protected void onPostExecute(BackupInfo backupInfo) {
operationLog.finishOperation(backupInfo.toString());
if (listener != null) {
listener.onBackupInfoGenerated(backupInfo, null);
}
}
};
task.executeOnExecutor(executor);
}
Aggregations