Search in sources :

Example 1 with OperationLog

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;
}
Also used : IProgress(net.osmand.IProgress) HashMap(java.util.HashMap) OperationLog(net.osmand.OperationLog) UnsupportedEncodingException(java.io.UnsupportedEncodingException) AbstractProgress(net.osmand.plus.settings.backend.backup.AbstractProgress) NonNull(androidx.annotation.NonNull)

Example 2 with OperationLog

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);
    }
}
Also used : InAppPurchaseHelper(net.osmand.plus.inapp.InAppPurchaseHelper) OperationLog(net.osmand.OperationLog) JSONException(org.json.JSONException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException)

Example 3 with OperationLog

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;
}
Also used : OsmandApplication(net.osmand.plus.OsmandApplication) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) OperationLog(net.osmand.OperationLog) UploadedFileInfo(net.osmand.plus.backup.BackupDbHelper.UploadedFileInfo) SettingsItemReader(net.osmand.plus.settings.backend.backup.SettingsItemReader) SettingsItem(net.osmand.plus.settings.backend.backup.items.SettingsItem) GpxSettingsItem(net.osmand.plus.settings.backend.backup.items.GpxSettingsItem) FileSettingsItem(net.osmand.plus.settings.backend.backup.items.FileSettingsItem) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) SettingsItemsFactory(net.osmand.plus.settings.backend.backup.SettingsItemsFactory) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) IOException(java.io.IOException) JSONObject(org.json.JSONObject) File(java.io.File) NonNull(androidx.annotation.NonNull)

Example 4 with OperationLog

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();
}
Also used : SettingsItem(net.osmand.plus.settings.backend.backup.items.SettingsItem) ArrayList(java.util.ArrayList) OperationLog(net.osmand.OperationLog) IOException(java.io.IOException)

Example 5 with OperationLog

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);
}
Also used : AsyncTask(android.os.AsyncTask) ArrayList(java.util.ArrayList) OperationLog(net.osmand.OperationLog) UploadedFileInfo(net.osmand.plus.backup.BackupDbHelper.UploadedFileInfo) ExportSettingsType(net.osmand.plus.settings.backend.ExportSettingsType) Pair(android.util.Pair) SuppressLint(android.annotation.SuppressLint)

Aggregations

OperationLog (net.osmand.OperationLog)13 HashMap (java.util.HashMap)9 ArrayList (java.util.ArrayList)6 JSONException (org.json.JSONException)6 SuppressLint (android.annotation.SuppressLint)5 IOException (java.io.IOException)5 JSONObject (org.json.JSONObject)5 NonNull (androidx.annotation.NonNull)4 SettingsItem (net.osmand.plus.settings.backend.backup.items.SettingsItem)4 UploadedFileInfo (net.osmand.plus.backup.BackupDbHelper.UploadedFileInfo)3 FileSettingsItem (net.osmand.plus.settings.backend.backup.items.FileSettingsItem)3 GpxSettingsItem (net.osmand.plus.settings.backend.backup.items.GpxSettingsItem)3 AsyncTask (android.os.AsyncTask)2 Nullable (androidx.annotation.Nullable)2 File (java.io.File)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 BackupError (net.osmand.plus.backup.BackupError)2 ExportSettingsType (net.osmand.plus.settings.backend.ExportSettingsType)2 AbstractProgress (net.osmand.plus.settings.backend.backup.AbstractProgress)2 JSONArray (org.json.JSONArray)2