From eb29127be9daeb841e341ea32dad9da424540460 Mon Sep 17 00:00:00 2001 From: David Mason Date: Wed, 5 Sep 2012 09:54:31 +1000 Subject: [PATCH] add pot file download to source documents page --- .../org/zanata/rest/service/FileService.java | 92 +++++++++++++++---- .../src/main/resources/messages.properties | 1 + .../src/main/webapp/iteration/files.xhtml | 2 +- .../main/webapp/iteration/source_files.xhtml | 9 +- 4 files changed, 79 insertions(+), 25 deletions(-) diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java index a836cc33cc..0057a19285 100644 --- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java +++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java @@ -66,8 +66,9 @@ @Consumes( { MediaType.APPLICATION_OCTET_STREAM }) public class FileService implements FileResource { - public static final String RAW_DOWNLOAD_TEMPLATE = "/raw/{projectSlug}/{iterationSlug}"; + public static final String SOURCE_DOWNLOAD_TEMPLATE = "/source/{projectSlug}/{iterationSlug}/{fileType}"; + private static final String RAW_DOCUMENT = "raw"; private static final String SUBSTITUTE_APPROVED_AND_FUZZY = "half-baked"; private static final String SUBSTITUTE_APPROVED = "baked"; @@ -86,17 +87,34 @@ public class FileService implements FileResource @In private ResourceUtils resourceUtils; + /** + * Downloads a single source file. + * + * @param projectSlug + * @param iterationSlug + * @param fileType use 'raw' for original source if available, or 'pot' to + * generate pot from source strings + * @param docId + * @return response with status code 404 if the document is not found, 415 if + * fileType is not valid for the document, otherwise 200 with + * attached document. + */ @GET - @Path(RAW_DOWNLOAD_TEMPLATE) - // /file/raw/{projectSlug}/{iterationSlug}?docId={docId} - public Response downloadRawFile( @PathParam("projectSlug") String projectSlug, - @PathParam("iterationSlug") String iterationSlug, - @QueryParam("docId") String docId) + @Path(SOURCE_DOWNLOAD_TEMPLATE) + // /file/source/{projectSlug}/{iterationSlug}/{fileType}?docId={docId} + public Response downloadSourceFile( @PathParam("projectSlug") String projectSlug, + @PathParam("iterationSlug") String iterationSlug, + @PathParam("fileType") String fileType, + @QueryParam("docId") String docId) { final Response response; - HDocument document = this.documentDAO.getByProjectIterationAndDocId(projectSlug, iterationSlug, docId); + HDocument document = documentDAO.getByProjectIterationAndDocId(projectSlug, iterationSlug, docId); - if( document != null && translationFileServiceImpl.hasPersistedDocument(projectSlug, iterationSlug, document.getPath(), document.getName())) + if( document == null ) + { + response = Response.status(Status.NOT_FOUND).build(); + } + else if (RAW_DOCUMENT.equals(fileType) && translationFileServiceImpl.hasPersistedDocument(projectSlug, iterationSlug, document.getPath(), document.getName())) { InputStream fileContents = translationFileServiceImpl.streamDocument(projectSlug, iterationSlug, document.getPath(), document.getName()); StreamingOutput output = new InputStreamStreamingOutput(fileContents); @@ -104,9 +122,17 @@ public Response downloadRawFile( @PathParam("projectSlug") String projectSlug, .header("Content-Disposition", "attachment; filename=\"" + document.getName() + "\"") .entity(output).build(); } + else if ("pot".equals(fileType)) + { + Resource res = resourceUtils.buildResource(document); + StreamingOutput output = new POTStreamingOutput(res); + response = Response.ok() + .header("Content-Disposition", "attachment; filename=\"" + document.getName() + ".pot\"") + .entity(output).build(); + } else { - response = Response.status(Status.NOT_FOUND).build(); + response = Response.status(Status.UNSUPPORTED_MEDIA_TYPE).build(); } return response; } @@ -114,16 +140,25 @@ public Response downloadRawFile( @PathParam("projectSlug") String projectSlug, /** * Downloads a single translation file. * + * To download a preview-document or translated document where a raw source + * document is available, use fileType 'half_baked' and 'baked' respectively. + * * @param projectSlug Project identifier. * @param iterationSlug Project iteration identifier. - * @param locale Translations for this locale will be contained in the downloaded document. - * @param fileExtension File type to be downloaded. (Options: 'po') + * @param locale Translations for this locale will be contained in the + * downloaded document. + * @param fileType File type to be downloaded. (Options: 'po', 'half_baked', + * 'baked') * @param docId Document identifier to fetch translations for. - * @return The following response status codes will be returned from this operation:
- * OK(200) - A translation file in the requested format with translations for the requested document in a - * project, iteration and locale.
- * NOT FOUND(404) - If a document is not found with the given parameters.
- * INTERNAL SERVER ERROR(500) - If there is an unexpected error in the server while performing this operation. + * @return The following response status codes will be returned from this + * operation:
+ * OK(200) - A translation file in the requested format with + * translations for the requested document in a project, iteration + * and locale.
+ * NOT FOUND(404) - If a document is not found with the given + * parameters.
+ * INTERNAL SERVER ERROR(500) - If there is an unexpected error in + * the server while performing this operation. */ @Override @GET @@ -132,7 +167,7 @@ public Response downloadRawFile( @PathParam("projectSlug") String projectSlug, public Response downloadTranslationFile( @PathParam("projectSlug") String projectSlug, @PathParam("iterationSlug") String iterationSlug, @PathParam("locale") String locale, - @PathParam("fileType") String fileExtension, + @PathParam("fileType") String fileType, @QueryParam("docId") String docId ) { final Response response; @@ -142,7 +177,7 @@ public Response downloadTranslationFile( @PathParam("projectSlug") String projec { response = Response.status(Status.NOT_FOUND).build(); } - else if ("po".equals(fileExtension)) + else if ("po".equals(fileType)) { final Set extensions = new HashSet(); extensions.add("gettext"); @@ -158,7 +193,7 @@ else if ("po".equals(fileExtension)) .header("Content-Disposition", "attachment; filename=\"" + document.getName() + ".po\"") .entity(output).build(); } - else if ( (SUBSTITUTE_APPROVED.equals(fileExtension) || SUBSTITUTE_APPROVED_AND_FUZZY.equals(fileExtension)) + else if ( (SUBSTITUTE_APPROVED.equals(fileType) || SUBSTITUTE_APPROVED_AND_FUZZY.equals(fileType)) && translationFileServiceImpl.hasPersistedDocument(projectSlug, iterationSlug, document.getPath(), document.getName())) { final Set extensions = Collections.emptySet(); @@ -167,7 +202,7 @@ else if ( (SUBSTITUTE_APPROVED.equals(fileExtension) || SUBSTITUTE_APPROVED_AND_ // Filter to only provide translated targets. "Preview" downloads include fuzzy. // Using new list is used as transRes list appears not to be a modifiable implementation. Map translations = new HashMap(); - boolean useFuzzy = SUBSTITUTE_APPROVED_AND_FUZZY.equals(fileExtension); + boolean useFuzzy = SUBSTITUTE_APPROVED_AND_FUZZY.equals(fileType); for (TextFlowTarget target : transRes.getTextFlowTargets()) { if (target.getState() == ContentState.Approved || (useFuzzy && target.getState() == ContentState.NeedReview)) @@ -265,6 +300,23 @@ public void write(OutputStream output) throws IOException, WebApplicationExcepti } } + private class POTStreamingOutput implements StreamingOutput + { + private Resource resource; + + public POTStreamingOutput(Resource resource) + { + this.resource = resource; + } + + @Override + public void write(OutputStream output) throws IOException, WebApplicationException + { + PoWriter2 writer = new PoWriter2(); + writer.writePot(output, "UTF-8", resource); + } + } + private class InputStreamStreamingOutput implements StreamingOutput { private InputStream input; diff --git a/zanata-war/src/main/resources/messages.properties b/zanata-war/src/main/resources/messages.properties index d0413fff39..45783e4f0f 100644 --- a/zanata-war/src/main/resources/messages.properties +++ b/zanata-war/src/main/resources/messages.properties @@ -304,6 +304,7 @@ jsf.iteration.files.ConfirmDownloadAllFiles=Your download will be prepared and m jsf.iteration.files.ContentType=Content Type jsf.iteration.files.DocumentPath=Document Path jsf.iteration.files.dotpo=.po +jsf.iteration.files.dotpot=.pot jsf.iteration.files.Download=Download jsf.iteration.files.DownloadAllFiles=Download All Files (zip) jsf.iteration.files.LocaleId=Locale Id diff --git a/zanata-war/src/main/webapp/iteration/files.xhtml b/zanata-war/src/main/webapp/iteration/files.xhtml index dea5a1dd26..91e23d3a34 100644 --- a/zanata-war/src/main/webapp/iteration/files.xhtml +++ b/zanata-war/src/main/webapp/iteration/files.xhtml @@ -292,7 +292,7 @@ #{messages['jsf.Upload']} Document #{messages['jsf.iteration.files.Download']} - - - - + + + + +