Google Drive Upload with Optional Query Parameters - OCR - java

About Google Drive, in this Document, Google says there are 3 types of uploadType:
We have the media, multipart and resumable, as it says in the image above.
Also, in the same Document mentioned, Google give a example on Java, explaining how to upload an File into Google Drive.
public class MyClass {
private static File insertFile(Drive service, String title, String description,
String parentId, String mimeType, String filename) {
// File's metadata.
File body = new File();
body.setTitle(title);
body.setDescription(description);
body.setMimeType(mimeType);
// Set the parent folder.
if (parentId != null && parentId.length() > 0) {
body.setParents(
Arrays.asList(new ParentReference().setId(parentId)));
}
// File's content.
java.io.File fileContent = new java.io.File(filename);
FileContent mediaContent = new FileContent(mimeType, fileContent);
try {
File file = service.files().insert(body, mediaContent).execute();
// Uncomment the following line to print the File ID.
// System.out.println("File ID: " + file.getId());
return file;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
}
// ...
}
I want to set an Optional Query Parameter, as explained in the image. I can't find how to set the ocr and ocrLanguage in the java SDK of Google Drive. The example of upload above, don't have this parameter to set, also, is not clear what uploadType this java example uses to Upload.

You can use generic set property method
File body = new File();
body.setTitle(title);
body.set("ocr",true);
body.set("ocrLanguage", "zh");

Related

Spring Boot + AWS S3: Unable to delete files in the bucket

i am new to AWS, and my first module i try to learn is S3 for file storage.
Uploading works fine, the problem is with deleting.So when i upload a file i store the string version of the name of the file in AWS bucket mybucket and the whole URL in mysql database like this
-> https://mybucket.s3.eu-west-2.amazonaws.com/what.png
The problem with deleting is that even if i pass the whole URL in this case https://mybucket.s3.eu-west-2.amazonaws.com/what.png to the delete method, the method goes to each steps successfully, telling me that the file has been succesfully deleted but when i check the bucket, the file is still there.I have tried searching around here for a similar issue, but couldn't find something that could help me understand what the problem is.here is the code
#Service
public class AmazonS3ClientServiceImpl {
private String awsS3AudioBucket; //bucket name
private AmazonS3 amazonS3; // s3 object which uploads file
private static final Logger logger = LoggerFactory.getLogger(AmazonS3ClientServiceImpl.class);
#Autowired
public AmazonS3ClientServiceImpl(Region awsRegion, AWSCredentialsProvider awsCredentialsProvider, String awsS3AudioBucket) {
this.amazonS3 = AmazonS3ClientBuilder.standard()
.withCredentials(awsCredentialsProvider)
.withRegion(awsRegion.getName()).build();
this.awsS3AudioBucket = awsS3AudioBucket;
}
public String uploadFileToS3Bucket(MultipartFile multipartFile, boolean enablePublicReadAccess) {
String uploadedfile = ""; // the file path which is on s3
String fileName = multipartFile.getOriginalFilename();
try {
//creating the file in the server (temporarily)
File file = new File(fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(multipartFile.getBytes());
fos.close();
PutObjectRequest putObjectRequest = new PutObjectRequest(this.awsS3AudioBucket, fileName, file);
if (enablePublicReadAccess) {
putObjectRequest.withCannedAcl(CannedAccessControlList.PublicRead);
}
this.amazonS3.putObject(putObjectRequest);
uploadedfile = String.valueOf(this.amazonS3.getUrl(awsS3AudioBucket, fileName));
System.out.println(this.amazonS3.getUrl(awsS3AudioBucket, fileName));
System.out.println(uploadedfile);
//removing the file created in the server
file.delete();
} catch (IOException | AmazonServiceException ex) {
logger.error("error [" + ex.getMessage() + "] occurred while uploading [" + fileName + "] ");
}
return uploadedfile;
}
public void deleteFileFromS3Bucket(String fileName) {
LOGGER.info("Deleting file with name= " + fileName);
final DeleteObjectRequest deleteObjectRequest = new DeleteObjectRequest(this.awsS3AudioBucket, fileName);
amazonS3.deleteObject(deleteObjectRequest);
LOGGER.info("File deleted successfully");
}
and when i call the deletemethod i use this
#GetMapping("/dashboard/showposts/delete/{id}")
public String deletePost(#PathVariable("id") Long id, Model model) {
System.out.println("GOT HERE");
//Retrieving Post image name
Post post = postService.findBydId(id);
String imageName = post.getImage();
System.out.println(imageName);
//Deleting image from S3 bucket
amazonClient.deleteFileFromS3Bucket(imageName);
//Deleting post from db
postService.detelePost(id);
String success = "Successfully deleted post with Id" + id;
model.addAttribute("success", success);
return "redirect:/admin/dashboard/showposts";
}
Any help would be greatly appreciated.
L.E For anyone having the same issue and searching for a quick answer.You have to pass only the string image name to the delete method not the whole URL.
You aren't checking the response returned from amazonS3.deleteObject() to see if it was actually successful or not. It is probably returning a failure status.
I'm guessing the root issue is that you are passing the full URL to the delete method, instead of just the path to the file within S3. For example with this URL: https://mybucket.s3.eu-west-2.amazonaws.com/what.png the S3 object path is simply what.png.
The simplest answer is to use the URL class. Something like:
URL url = null;
try {
url = new URL("https://mybucket.s3.eu-west-2.amazonaws.com/some/path/what.png");
} catch (MalformedURLException e) {
e.printStackTrace();
}
System.out.println( "file is \""+ url.getFile() + "\"" );
output would be "/some/path/what.png". You can remove the first "/" character to use for the key.
Aws S3 is eventual consistent. You might delete object and s3 list that object in browser . So it take few seconds or less to delete .
Please refer this link

Downloading Thymeleaf template from S3

I am currently storing and downloading my Thymeleaf templates in S3.
I am using the following function to retrieve the Template from S3:
public String getTemplateFile(String name, File localFile) {
ObjectMetadata object = s3Client.getObject(new GetObjectRequest(connectionProperties.getBucket(), name), localFile);
boolean success = localFile.exists() && localFile.canRead();
return localFile.getPath();
}
After doing this the file is successfully downloaded in the desired location.
But when trying to access the file from the FlyingSaucer PDF generator the file doesn't exist, despite it is already downloaded in FILE_LOCATION_PATH. (I can open the file... the file is there but the function doesn't see it)
String xHtmlStringDocument =
convertHtmlToXhtml(templateEngine
.process(FILE_LOCATION_PATH,
initializeLetterHtmlTemplateContext(letter)));
When I run the program again and again I get the same result. But when I STOP the program and RUN it AGAIN then everything works because the file form the last execution is now recognized by the program.
This sounds to me like an asynchronous function issue.
Does anybody know how can I fix this?
Thanks in advance.
EDITED (following suggestion)
New function: Same result:
(And the file was created, the Download from S3 was successful)
java.io.FileNotFoundException: ClassLoader resource "static/templates/template.html" could not be resolved
public String getTemplateFileN(String name, File localFile) throws IOException {
S3Object fullObject = null;
InputStream in = null;
try {
fullObject = s3Client.getObject(new GetObjectRequest(connectionProperties.getBucket(), name));
System.out.println("Content-Type: " + fullObject.getObjectMetadata().getContentType());
System.out.println("Content: ");
displayTextInputStream(fullObject.getObjectContent());
in = fullObject.getObjectContent();
System.out.println(localFile.toPath());
Files.copy(in, localFile.toPath());
} //then later
finally {
// To ensure that the network connection doesn't remain open, close any open input streams.
if (fullObject != null) {
fullObject.close();
}
if (in != null) {
in.close();
}
}
return localFile.getPath();
}
Checking javadoc
https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html#getObject-com.amazonaws.services.s3.model.GetObjectRequest-java.io.File-
I see not method signature ObjectMetadata getObject(GetObjectRequest getObjectRequest,String file)
There is
ObjectMetadata getObject(GetObjectRequest getObjectRequest,
File destinationFile)
Where you provide File (not String) as second argument. Make sure the file is not opened for write before you try reading it!

Writing Arabic text annotation in pdf

I have a problem to update a pdf file with arabic text annotation
the pdf has been changed ( size has been changed)
and when I try to open the pdf with acrobat reader the text annotation is not displayed
and when I try to change the fill color of the annotation it has been displayed
I use this code in angular
const blob = new Blob([content], { type: "application/pdf ; charset=utf-8" });
const reader = new FileReader();
reader.readAsDataURL(blob); this.formData.append('files', blob,fileName);
and I use this java code to update the pdf file
public String storeFile(MultipartFile file) {
// Normalize file name
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
try {
// Check if the file's name contains invalid characters
if(fileName.contains("..")) {
throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
}
// Copy file to the target location (Replacing existing file with the same name)
Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
//add owners permission
perms.add(PosixFilePermission.OWNER_READ);
perms.add(PosixFilePermission.OWNER_WRITE);
perms.add(PosixFilePermission.OWNER_EXECUTE);
Path targetLocation = this.fileStorageLocation.resolve(fileName);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
return fileName;
} catch (IOException ex) {
throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
}
}

How to find the original MIME type of a file while uploading it?

I have to find the original content type(MIME Type) of a file at the time of Uploading.
I want to allow only PDF files, But if i am renaming an .exe fiel to .pdf flie, its type is showing pdf.
I want to restrict these kind of files.
I am using the following code:
if (!fileMultipart.getContentType().equalsIgnoreCase("application/pdf")) {
msg = "Only pdf files are allowed.";
System.out.println("Only pdf files are allowed.");
}
Also some online tools are available to find the original content type. I tried using http://www.checkfiletype.com/ and it works.
The file content type is determined by the user-agent/browser on upload. As you already know, this can be spoofed, or incorrect. There really isn't more you can do with just the file's content type.
An alternative is to do more checking after you have verified the content type by attempting to open the PDF for reading using iText, PDFBox, or some similar library. If you can't open the file then you can let the user know there's a problem with it.
public boolean isPDF(String fileName) {
File file = new File(fileName);
System.out.println("file upload isExist " + file.exists());
boolean result = false;
//Scanner input = null;
try {
Scanner input = new Scanner(new FileReader(file));
System.out.println("fileScanner input " + input);
while (input.hasNextLine()) {
final String checkline = input.nextLine();
if (checkline.contains("%PDF-")) {
// a match!
result = true;
break;
}
}
} catch (FileNotFoundException ex) {
System.out.println("file upload is not valid " + file);
Logger.getLogger(UploadContractorFile.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("file upload final result " + result);
return result;
}

Google drive - java.io.FileNotFoundException: document.txt (No such file or directory)

I am using the code from the Google Drive API examples to insert a file in Drive which is failing with java.io.FileNotFoundException: document.txt (No such file or directory). I have commented out code that creates a folder in Drive and this works without any problems. So I am authenticated ok. Where am I going wrong.
Kind regards,
Ian.
public void saveToDrive(ServletContext sc){
GoogleCredential googleCredential = getGoogleApiCredential(sc);
Drive service = getDriveService(googleCredential);
String parentId = null;
try {
About about = service.about().get().execute();
System.out.println("Current user name: " + about.getName());
System.out.println("Root folder ID:" + about.getRootFolderId());
parentId = about.getRootFolderId();
System.out.println("Total quota (bytes): " + about.getQuotaBytesTotal());
System.out.println("Used quota (bytes): " + about.getQuotaBytesUsed());
}catch (IOException e){
}
File body = new File();
body.setTitle("Doc title");
body.setDescription("A toast document");
body.setMimeType("application/vnd.google-apps.file");
body.setParents(Arrays.asList(new ParentReference().setId(parentId)));
java.io.File fileContent = new java.io.File("document.txt");
FileContent mediaContent = new FileContent("plain/text", fileContent);
//File body = new File();
//body.setTitle("title");
//body.setMimeType("application/vnd.google-apps.folder");
try {
//File file = service.files().insert(body).execute();
File file = service.files().insert(body, mediaContent).execute();
logger.severe("File id: " + file.getId());
} catch (IOException e) {
logger.severe(e.toString());
}
}
I don't have time to completely re-run your scenario, but you may be able to test it with a method I use (so it is tested). The only obvious difference is that I stick THE SAME MIME TYPE in both 'body' and 'content'. Yours are different. Also I don't know what your 'about.getRootFolderId()' produces. You may try to stick "root" string there just to test it.
/**********************************************************************
* create file/folder in GOODrive
* #param prnId parent's ID, (null or "root") for root
* #param titl file name
* #param mime file mime type (optional)
* #param file file (with content) to create
* #return file id / null on fail
*/
static String create(String prnId, String titl, String mime, java.io.File file) {
String rsid = null;
if (mGOOSvc != null && titl != null && file != null) {
File meta = new File();
meta.setParents(Arrays.asList(new ParentReference().setId(prnId == null ? "root" : prnId)));
meta.setTitle(titl);
if (mime != null)
meta.setMimeType(mime);
File gFl = mGOOSvc.files().insert(meta, new FileContent(mime, file)).execute();
if (gFl != null && gFl.getId() != null)
rsid = gFl.getId();
}
return rsid;
}
It is taken from a working CRUD demo here.
Good Luck

Categories