Search in sources :

Example 1 with FormStatusEvent

use of org.opendatakit.briefcase.model.FormStatusEvent in project briefcase by opendatakit.

the class AggregateUtils method uploadFilesToServer.

public static final boolean uploadFilesToServer(ServerConnectionInfo serverInfo, URI u, String distinguishedFileTagName, File file, List<File> files, DocumentDescription description, SubmissionResponseAction action, TerminationFuture terminationFuture, FormStatus formToTransfer) {
    boolean allSuccessful = true;
    formToTransfer.setStatusString("Preparing for upload of " + description.getDocumentDescriptionType() + " with " + files.size() + " media attachments", true);
    EventBus.publish(new FormStatusEvent(formToTransfer));
    // handles case where there are no media files
    boolean first = true;
    int lastJ = 0;
    int j = 0;
    while (j < files.size() || first) {
        lastJ = j;
        first = false;
        if (terminationFuture.isCancelled()) {
            formToTransfer.setStatusString("Aborting upload of " + description.getDocumentDescriptionType() + " with " + files.size() + " media attachments", true);
            EventBus.publish(new FormStatusEvent(formToTransfer));
            return false;
        }
        HttpPost httppost = WebUtils.createOpenRosaHttpPost(u);
        long byteCount = 0L;
        // mime post
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        // add the submission file first...
        FileBody fb = new FileBody(file, ContentType.TEXT_XML);
        builder.addPart(distinguishedFileTagName, fb);
        log.info("added " + distinguishedFileTagName + ": " + file.getName());
        byteCount += file.length();
        for (; j < files.size(); j++) {
            File f = files.get(j);
            log.info("Trying file {}", f);
            String fileName = f.getName();
            int idx = fileName.lastIndexOf(".");
            String extension = "";
            if (idx != -1) {
                extension = fileName.substring(idx + 1);
            }
            // we only need to deal with the content type determination...
            if (extension.equals("xml")) {
                fb = new FileBody(f, ContentType.TEXT_XML);
                builder.addPart(f.getName(), fb);
                byteCount += f.length();
                log.info("added xml file " + f.getName());
            } else if (extension.equals("jpg")) {
                fb = new FileBody(f, ContentType.create("image/jpeg"));
                builder.addPart(f.getName(), fb);
                byteCount += f.length();
                log.info("added image file " + f.getName());
            } else if (extension.equals("3gpp")) {
                fb = new FileBody(f, ContentType.create("audio/3gpp"));
                builder.addPart(f.getName(), fb);
                byteCount += f.length();
                log.info("added audio file " + f.getName());
            } else if (extension.equals("3gp")) {
                fb = new FileBody(f, ContentType.create("video/3gpp"));
                builder.addPart(f.getName(), fb);
                byteCount += f.length();
                log.info("added video file " + f.getName());
            } else if (extension.equals("mp4")) {
                fb = new FileBody(f, ContentType.create("video/mp4"));
                builder.addPart(f.getName(), fb);
                byteCount += f.length();
                log.info("added video file " + f.getName());
            } else if (extension.equals("csv")) {
                fb = new FileBody(f, ContentType.create("text/csv"));
                builder.addPart(f.getName(), fb);
                byteCount += f.length();
                log.info("added csv file " + f.getName());
            } else if (extension.equals("xls")) {
                fb = new FileBody(f, ContentType.create("application/vnd.ms-excel"));
                builder.addPart(f.getName(), fb);
                byteCount += f.length();
                log.info("added xls file " + f.getName());
            } else {
                fb = new FileBody(f, ContentType.create("application/octet-stream"));
                builder.addPart(f.getName(), fb);
                byteCount += f.length();
                log.warn("added unrecognized file (application/octet-stream)");
            }
            // we've added at least one attachment to the request...
            if (j + 1 < files.size()) {
                if ((j - lastJ + 1) > 100 || byteCount + files.get(j + 1).length() > 10000000L) {
                    // more than 100 attachments or the next file would exceed the 10MB threshold...
                    log.info("Extremely long post is being split into multiple posts");
                    try {
                        StringBody sb = new StringBody("yes", ContentType.DEFAULT_TEXT.withCharset(Charset.forName("UTF-8")));
                        builder.addPart("*isIncomplete*", sb);
                    } catch (Exception e) {
                        log.error("impossible condition", e);
                        throw new IllegalStateException("never happens");
                    }
                    // advance over the last attachment added...
                    ++j;
                    break;
                }
            }
        }
        httppost.setEntity(builder.build());
        int[] validStatusList = { 201 };
        try {
            if (j != files.size()) {
                formToTransfer.setStatusString("Uploading " + description.getDocumentDescriptionType() + " and media files " + (lastJ + 1) + " through " + (j + 1) + " of " + files.size() + " media attachments", true);
            } else if (j == 0) {
                formToTransfer.setStatusString("Uploading " + description.getDocumentDescriptionType() + " with no media attachments", true);
            } else {
                formToTransfer.setStatusString("Uploading " + description.getDocumentDescriptionType() + " and " + (j - lastJ) + ((lastJ != 0) ? " remaining" : "") + " media attachments", true);
            }
            EventBus.publish(new FormStatusEvent(formToTransfer));
            httpRetrieveXmlDocument(httppost, validStatusList, serverInfo, false, description, action);
        } catch (XmlDocumentFetchException e) {
            allSuccessful = false;
            log.error("upload failed", e);
            formToTransfer.setStatusString("UPLOAD FAILED: " + e.getMessage(), false);
            EventBus.publish(new FormStatusEvent(formToTransfer));
            if (description.isCancelled())
                return false;
        }
    }
    return allSuccessful;
}
Also used : HttpPost(org.apache.http.client.methods.HttpPost) MultipartEntityBuilder(org.apache.http.entity.mime.MultipartEntityBuilder) FileBody(org.apache.http.entity.mime.content.FileBody) FormStatusEvent(org.opendatakit.briefcase.model.FormStatusEvent) ClientProtocolException(org.apache.http.client.ClientProtocolException) URISyntaxException(java.net.URISyntaxException) TransmissionException(org.opendatakit.briefcase.model.TransmissionException) MalformedURLException(java.net.MalformedURLException) XmlDocumentFetchException(org.opendatakit.briefcase.model.XmlDocumentFetchException) IOException(java.io.IOException) MetadataUpdateException(org.opendatakit.briefcase.model.MetadataUpdateException) UnknownHostException(java.net.UnknownHostException) XmlDocumentFetchException(org.opendatakit.briefcase.model.XmlDocumentFetchException) StringBody(org.apache.http.entity.mime.content.StringBody) File(java.io.File)

Example 2 with FormStatusEvent

use of org.opendatakit.briefcase.model.FormStatusEvent in project briefcase by opendatakit.

the class ServerFetcher method downloadMediaFileIfChanged.

private void downloadMediaFileIfChanged(File mediaDir, MediaFile m, FormStatus fs) throws Exception {
    File mediaFile = new File(mediaDir, m.filename);
    if (m.hash.startsWith(MD5_COLON_PREFIX)) {
        // see if the file exists and has the same hash
        String hashToMatch = m.hash.substring(MD5_COLON_PREFIX.length());
        if (mediaFile.exists()) {
            String hash = FileSystemUtils.getMd5Hash(mediaFile);
            if (hash.equalsIgnoreCase(hashToMatch))
                return;
            mediaFile.delete();
        }
    }
    if (isCancelled()) {
        fs.setStatusString("aborting fetch of media file...", true);
        EventBus.publish(new FormStatusEvent(fs));
        throw new TransmissionException("Transfer cancelled by user.");
    }
    AggregateUtils.commonDownloadFile(serverInfo, mediaFile, m.downloadUrl);
}
Also used : TransmissionException(org.opendatakit.briefcase.model.TransmissionException) FormStatusEvent(org.opendatakit.briefcase.model.FormStatusEvent) File(java.io.File)

Example 3 with FormStatusEvent

use of org.opendatakit.briefcase.model.FormStatusEvent in project briefcase by opendatakit.

the class ServerFetcher method downloadManifestAndMediaFiles.

private String downloadManifestAndMediaFiles(File mediaDir, FormStatus fs) {
    RemoteFormDefinition fd = getRemoteFormDefinition(fs);
    if (fd.getManifestUrl() == null)
        return null;
    fs.setStatusString("Fetching form manifest", true);
    EventBus.publish(new FormStatusEvent(fs));
    List<MediaFile> files = new ArrayList<>();
    AggregateUtils.DocumentFetchResult result;
    try {
        DocumentDescription formManifestDescription = new DocumentDescription("Fetch of manifest failed. Detailed reason: ", "Fetch of manifest failed ", "form manifest", terminationFuture);
        result = AggregateUtils.getXmlDocument(fd.getManifestUrl(), serverInfo, false, formManifestDescription, null);
    } catch (XmlDocumentFetchException e) {
        return e.getMessage();
    }
    try {
        files = XmlManipulationUtils.parseFormManifestResponse(result.isOpenRosaResponse, result.doc);
    } catch (ParsingException e) {
        return e.getMessage();
    }
    // OK we now have the full set of files to download...
    log.info("Downloading " + files.size() + " media files.");
    int mCount = 0;
    if (files.size() > 0) {
        for (MediaFile m : files) {
            ++mCount;
            fs.setStatusString(String.format(" (getting %1$d of %2$d media files)", mCount, files.size()), true);
            EventBus.publish(new FormStatusEvent(fs));
            try {
                downloadMediaFileIfChanged(mediaDir, m, fs);
            } catch (Exception e) {
                return e.getLocalizedMessage();
            }
        }
    }
    return null;
}
Also used : XmlDocumentFetchException(org.opendatakit.briefcase.model.XmlDocumentFetchException) DocumentDescription(org.opendatakit.briefcase.model.DocumentDescription) RemoteFormDefinition(org.opendatakit.briefcase.model.RemoteFormDefinition) FormStatusEvent(org.opendatakit.briefcase.model.FormStatusEvent) ParsingException(org.opendatakit.briefcase.model.ParsingException) ArrayList(java.util.ArrayList) URISyntaxException(java.net.URISyntaxException) FileSystemException(org.opendatakit.briefcase.model.FileSystemException) SQLException(java.sql.SQLException) SocketTimeoutException(java.net.SocketTimeoutException) TransmissionException(org.opendatakit.briefcase.model.TransmissionException) XmlDocumentFetchException(org.opendatakit.briefcase.model.XmlDocumentFetchException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) ParsingException(org.opendatakit.briefcase.model.ParsingException)

Example 4 with FormStatusEvent

use of org.opendatakit.briefcase.model.FormStatusEvent in project briefcase by opendatakit.

the class ServerUploader method subtractServerInstances.

// remove any instances already completed on server
private void subtractServerInstances(FormStatus fs, DatabaseUtils formDatabase, Set<File> instancesToUpload) {
    /*
     * The /view/submissionList interface returns the list of COMPLETED submissions
     * on the server. Fetch this list and filter out the locally-held submissions
     * with the same instanceIds.  We know the server is already content with what
     * it has, so we don't need to send any of these to the server, as that POST
     * request will be treated as a no-op.
     */
    String baseUrl = serverInfo.getUrl() + "/view/submissionList";
    String oldWebsafeCursorString = "not-empty";
    String websafeCursorString = "";
    for (; !oldWebsafeCursorString.equals(websafeCursorString); ) {
        if (isCancelled()) {
            fs.setStatusString("aborting retrieval of instanceIds of submissions on server...", true);
            EventBus.publish(new FormStatusEvent(fs));
            return;
        }
        fs.setStatusString("retrieving next chunk of instanceIds from server...", true);
        EventBus.publish(new FormStatusEvent(fs));
        Map<String, String> params = new HashMap<>();
        params.put("numEntries", Integer.toString(MAX_ENTRIES));
        params.put("formId", fs.getFormDefinition().getFormId());
        params.put("cursor", websafeCursorString);
        String fullUrl = WebUtils.createLinkWithProperties(baseUrl, params);
        // remember what we had...
        oldWebsafeCursorString = websafeCursorString;
        AggregateUtils.DocumentFetchResult result;
        try {
            DocumentDescription submissionChunkDescription = new DocumentDescription("Fetch of instanceIds (submission download chunk) failed.  Detailed error: ", "Fetch of instanceIds (submission download chunk) failed.", "submission download chunk", terminationFuture);
            result = AggregateUtils.getXmlDocument(fullUrl, serverInfo, false, submissionChunkDescription, null);
        } catch (XmlDocumentFetchException e) {
            fs.setStatusString("Not all submissions retrieved: Error fetching list of instanceIds: " + e.getMessage(), false);
            EventBus.publish(new FormStatusEvent(fs));
            return;
        }
        SubmissionChunk chunk;
        try {
            chunk = XmlManipulationUtils.parseSubmissionDownloadListResponse(result.doc);
        } catch (ParsingException e) {
            fs.setStatusString("Not all instanceIds retrieved: Error parsing the submission download chunk: " + e.getMessage(), false);
            EventBus.publish(new FormStatusEvent(fs));
            return;
        }
        websafeCursorString = chunk.websafeCursorString;
        for (String uri : chunk.uriList) {
            File f = formDatabase.hasRecordedInstance(uri);
            if (f != null) {
                instancesToUpload.remove(f);
            }
        }
    }
}
Also used : XmlDocumentFetchException(org.opendatakit.briefcase.model.XmlDocumentFetchException) DocumentDescription(org.opendatakit.briefcase.model.DocumentDescription) HashMap(java.util.HashMap) FormStatusEvent(org.opendatakit.briefcase.model.FormStatusEvent) ParsingException(org.opendatakit.briefcase.model.ParsingException) DocumentFetchResult(org.opendatakit.briefcase.util.AggregateUtils.DocumentFetchResult) SubmissionChunk(org.opendatakit.briefcase.util.ServerFetcher.SubmissionChunk) File(java.io.File)

Example 5 with FormStatusEvent

use of org.opendatakit.briefcase.model.FormStatusEvent in project briefcase by opendatakit.

the class TransferFromODK method doResolveOdkCollectFormDefinition.

/**
 * Given the OdkCollectFormDefinition within the FormStatus argument, try to match it up
 * with an existing Briefcase storage form definition, or create a new Briefcase storage
 * form definition for it.
 *
 * @param fs the form transfer status object for an ODK Collect form definition.
 * @return the Briefcase storage form definition.
 */
private BriefcaseFormDefinition doResolveOdkCollectFormDefinition(FormStatus fs) {
    fs.setStatusString("resolving against briefcase form definitions", true);
    EventBus.publish(new FormStatusEvent(fs));
    OdkCollectFormDefinition formDef = (OdkCollectFormDefinition) fs.getFormDefinition();
    File odkFormDefFile = formDef.getFormDefinitionFile();
    BriefcaseFormDefinition briefcaseLfd;
    // copy form definition files from ODK to briefcase (scratch area)
    try {
        briefcaseLfd = BriefcaseFormDefinition.resolveAgainstBriefcaseDefn(odkFormDefFile, true);
        if (briefcaseLfd.needsMediaUpdate()) {
            File destinationFormMediaDir;
            try {
                destinationFormMediaDir = FileSystemUtils.getMediaDirectory(briefcaseLfd.getFormDirectory());
            } catch (FileSystemException e) {
                String msg = "unable to create media folder";
                log.error(msg, e);
                fs.setStatusString(msg + ": " + e.getMessage(), false);
                EventBus.publish(new FormStatusEvent(fs));
                return null;
            }
            // compose the ODK media directory...
            final String odkFormName = odkFormDefFile.getName().substring(0, odkFormDefFile.getName().lastIndexOf("."));
            String odkMediaName = odkFormName + "-media";
            File odkFormMediaDir = new File(odkFormDefFile.getParentFile(), odkMediaName);
            if (odkFormMediaDir.exists()) {
                FileUtils.copyDirectory(odkFormMediaDir, destinationFormMediaDir);
            }
            briefcaseLfd.clearMediaUpdate();
        }
    } catch (Exception e) {
        String msg = "unable to copy form definition and/or media folder";
        log.error(msg, e);
        fs.setStatusString(msg + ": " + e.getMessage(), false);
        EventBus.publish(new FormStatusEvent(fs));
        return null;
    }
    return briefcaseLfd;
}
Also used : FileSystemException(org.opendatakit.briefcase.model.FileSystemException) FormStatusEvent(org.opendatakit.briefcase.model.FormStatusEvent) BriefcaseFormDefinition(org.opendatakit.briefcase.model.BriefcaseFormDefinition) OdkCollectFormDefinition(org.opendatakit.briefcase.model.OdkCollectFormDefinition) File(java.io.File) FileSystemException(org.opendatakit.briefcase.model.FileSystemException) IOException(java.io.IOException) SQLException(java.sql.SQLException) ParsingException(org.opendatakit.briefcase.model.ParsingException)

Aggregations

FormStatusEvent (org.opendatakit.briefcase.model.FormStatusEvent)12 File (java.io.File)10 IOException (java.io.IOException)5 SQLException (java.sql.SQLException)5 DocumentDescription (org.opendatakit.briefcase.model.DocumentDescription)5 FileSystemException (org.opendatakit.briefcase.model.FileSystemException)5 ParsingException (org.opendatakit.briefcase.model.ParsingException)5 TransmissionException (org.opendatakit.briefcase.model.TransmissionException)5 BriefcaseFormDefinition (org.opendatakit.briefcase.model.BriefcaseFormDefinition)4 XmlDocumentFetchException (org.opendatakit.briefcase.model.XmlDocumentFetchException)4 URISyntaxException (java.net.URISyntaxException)3 ArrayList (java.util.ArrayList)3 FormStatus (org.opendatakit.briefcase.model.FormStatus)3 RemoteFormDefinition (org.opendatakit.briefcase.model.RemoteFormDefinition)3 SocketTimeoutException (java.net.SocketTimeoutException)2 URI (java.net.URI)2 HashMap (java.util.HashMap)2 ExecutionException (java.util.concurrent.ExecutionException)2 OdkCollectFormDefinition (org.opendatakit.briefcase.model.OdkCollectFormDefinition)2 FileOutputStream (java.io.FileOutputStream)1