Read Mail Attchments in appengine using Java - google-app-engine

I am using App Engine application to receive emails to a specific list of email address ending with #my-app-id.appspotmail.com will be sent to your application.
Multipart multiPart = (Multipart) message.getContent();
BodyPart bp = multiPart.getBodyPart(0);
log.info("count is "+multiPart.getCount());
String attachFiles = "";
String messageContent = "";
for (int i = 0; i < multiPart.getCount(); i++) {
MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(i);
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
// this part is attachment
String fileName = part.getFileName();
log.info("file name is "+fileName);
} else {
// this part may be the message content
messageContent = part.getContent().toString();
}
}
I want to store the File inside a Blob store but i did not find an API for it, It is going inside the IF loop and am able to get the attachment file name. Any help will be appreciated.

You can read all the data inside the attachment part using the MimeBodyPart.getInputStream method, but you'll need to read the data yourself and create the Blob.

Related

Getting path of audio file from sdcard

In my app I tried to pass the file path from one activity to another activity using intent.In my receiving activity I got the file path as "null".But when I print the file in first activity it prints the path.From my second activity I attach that file to mail using Gmailsender.This was the code I tried,
private void startRecord()
{
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");
try
{
file.createNewFile();
OutputStream outputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
int minBufferSize = AudioRecord.getMinBufferSize(8000,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
short[] audioData = new short[minBufferSize];
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
8000,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minBufferSize);
audioRecord.startRecording();
while(recording)
{
int numberOfShort = audioRecord.read(audioData, 0, minBufferSize);
for(int i = 0; i < numberOfShort; i++)
{
dataOutputStream.writeShort(audioData[i]);
}
}
audioRecord.stop();
audioRecord.release();
dataOutputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
String audiofile;
audiofile=file.getAbsolutePath();
System.out.println("File Path::::"+audiofile);
}
Intent is,
Intent sigout=new Intent(getApplicationContext(),WeeklyendActivity.class);
sigout.putExtra("mnt/sdcard-test.pcm",audiofile);
startActivity(sigout);
In my receiving activity,
String patty=getIntent().getStringExtra("mnt/sdcard-text.pcm");
System.out.println("paathhhy frfom ::"+patty);
It prints null.Can anyone help me how to get the file path.And more thing I am not sure whether the audio would save in that file correctly?
Please anyone help me!!!Thanks in advance!
Based on your information that audioFile is a variable of type File, when you do this:
sigout.putExtra("mnt/sdcard-test.pcm",audiofile);
you are putting a File object in the extras Bundle. Then, when you try to get the extra from the Bundle you do this:
String patty=getIntent().getStringExtra("mnt/sdcard-text.pcm");
However, the object in this extra is of type File, not type String. This is why you are getting null.
If you only want to pass the name of the file, then put the extra like this:
sigout.putExtra("mnt/sdcard-test.pcm",audiofile.getAbsolutePath());

JavaMail and non-ASCII character in filenames

I can send attachments that have non-ascii filenames in JavaMail but I am not able to download them. I am getting java.io.FileNotFoundException specifically for those attachments whose file names contain non-ascii characters.
FYI: I am using something like messageBodyPart.setFileName(MimeUtility.encodeText(filename[i])) to encode the text and MimeUtility.decodeText(bodyPart.getFileName()) to decode the non-ascii file names
Is there a workaround for this?
EDIT
#Bill, here is part of my code that reads attachments. I have also added the properties.setProperty("mail.mime.decodeparameters", "true") and properties.setProperty("mail.mime.decodefilename", "true") properties in my code.
if (message[a].getContent() instanceof MimeMultipart) {
Multipart multipart = (Multipart) message[a].getContent();
for (int i = 0; i < multipart.getCount(); i++) {
bodyPart = multipart.getBodyPart(i);
disposition = bodyPart.getDisposition();
if (disposition != null && (disposition.equals(BodyPart.ATTACHMENT) || (disposition.equals(BodyPart.INLINE)))) {
DataHandler handler = bodyPart.getDataHandler();
String path = bodyPart.getFileName();
String[] str = path.split("/");
String fileName = str[str.length - 1];
String filePath = ReadConfigPropertiesFile.getPropertyValue("server.buildpath");
System.out.println(fileName);
File tempDir = new File(filePath + user);
if (!tempDir.exists()) {
tempDir.mkdir();
}
File saveFile = new File(tempDir + "/" + fileName);
int count = 0;
while (saveFile.exists()) {
count++;
saveFile = new File(tempDir + "/" + count + "_" + fileName);
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(saveFile));
byte[] buff = new byte[2048];
InputStream is = bodyPart.getInputStream();
int ret = 0;
while ((ret = is.read(buff)) > 0) {
bos.write(buff, 0, ret);
}
bos.close();
is.close();
//System.out.println(bodyPart.getContentType());
}else {
//display body (message) of the attachment;
//System.out.println(bodyPart.getContent().toString());
}
}
}
The above code raises the FileNotFoundException exception at BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(saveFile)) line and this is getting raised for the attachments whose file names are non-ascii characters (something like ሰላም.pdf). Every thing else works fine.
This answer taken from comment of #semytech (OP). It was hard to find it there, so I will add it as answer for more visibility. It helped me with hebrew filenames.
MimeBodyPart attachment = new MimeBodyPart();
attachment.setFileName(MimeUtility.encodeText(filename, "UTF-8", null));
You should never need to do the encoding or decoding yourself.
There are two sets of properties you can set to tell JavaMail to do the encoding/decoding for you:
mail.mime.encodefilename/mail.mime.decodefilename
mail.mime.encodeparameters/mail.mime.decodeparameters
See the javadocs for the javax.mail.internet package for details.
The first set uses a non-standard encoding technique, similar to what you're doing yourself. This works fine with some older mailers that use this technique.
The second set uses a MIME standard encoding technique. This version works with most modern mailers.
None of this explains why you're getting FileNotFoundException, but then you didn't provide enough detail to know what you're doing when you get the exception.

get email attatchment for POP 3 received as winmail.dat

When I try to get attatchment from POP 3 mail, I am getting them as winmail.dat, not the original attached file name. How can I get the original file name?
for (int i = 0; i < multipart.getCount(); i++)
{
BodyPart bodyPart = multipart.getBodyPart(i);
if(!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()))
{
//do something
}
else
{
bodyPart.getFileName(); // here only get the winmail.dat
}
}
This is part of the Exchange Settings, and sadly you going to need to extract the original contents from the WinMail.dat using JTNEF.
"The Java TNEF package is an open source code implementation of a TNEF message handler, which can be used as a command-line utility or integrated into Java-based mail applications to extract the original message content."
This is found on the JavaMail's third party tools.
As alternative and what looks simpler is POI-HMEF
Sample extraction:
public void extract(String winmailFilename, String directoryName) throws Exception {
HMEFContentsExtractor ext = new HMEFContentsExtractor(new File(winmailFilename));
File dir = new File(directoryName);
File rtf = new File(dir, "message.rtf");
if(! dir.exists()) {
throw new FileNotFoundException("Output directory " + dir.getName() + " not found");
}
System.out.println("Extracting...");
ext.extractMessageBody(rtf);
ext.extractAttachments(dir);
System.out.println("Extraction completed");
}
There is also a sample for printing the contents here.

how to remove request header from HttpInputStream

I need help with a servlet.
I need to read a inputStream in one request and write a tiff file.
The inputStream come with request header and i dont know how remove that bytes and write only the file.
See initial bytes from the writen file.
-qF3PFkB8oQ-OnPe9HVzkqFtLeOnz7S5Be
Content-Disposition: form-data; name=""; filename=""
Content-Type: application/octet-stream; charset=ISO-8859-1
Content-Transfer-Encoding: binary
I want to remove that and write only bytes from the tiff file.
PS: sender of file its not me.
I'm not sure why you're not using HttpServletRequest's getInputStream() method to get the content without its headers, either way you have the option to start reading the input stream and ignoring the content until you find two consecutive CRLF's, which defines the end of the headers.
One way of doing that is like this:
String headers = new java.util.Scanner(inputStream).next("\\r\\n\\r\\n");
// Read rset of input stream
Apache commons solve 90% of your problems... only need know what keywords use in search :)
"parse multipart request"
and google say:
http://www.oreillynet.com/onjava/blog/2006/06/parsing_formdata_multiparts.html
int boundaryIndex = contentType.indexOf("boundary=");
byte[] boundary = (contentType.substring(boundaryIndex + 9)).getBytes();
ByteArrayInputStream input = new ByteArrayInputStream(buffer.getBytes());
MultipartStream multipartStream = new MultipartStream(input, boundary);
boolean nextPart = multipartStream.skipPreamble();
while(nextPart) {
String headers = multipartStream.readHeaders();
System.out.println("Headers: " + headers);
ByteArrayOutputStream data = new ByteArrayOutputStream();
multipartStream.readBodyData(data);
System.out.println(new String(data.toByteArray());
nextPart = multipartStream.readBoundary();
}
For me I use annotation and parameter like this:
#Consumes(MediaType.APPLICATION_OCTET_STREAM)
public Response testUpload(File uploadedInputStream)
And then I can read the file content with:
byte[] totalBytes = Files.readAllBytes(Paths.get(uploadedInputStream.toURI()));
Then I have to ignore the first 4 lines, also the end-of-content part, like this:
int headerLen = 0;
int index = 0;
while(totalBytes[index] != '\n' && index < totalBytes.length) {
headerLen++;
index++;
}
//ignore next three line
for (int i = 0; i < 3; i++) {
index++;
while (totalBytes[index] != '\n' && index < totalBytes.length) {
index++;
}
}
index++;
out.write(totalBytes, index, totalBytes.length - index - (headerLen+3));
out.flush();
out.close();

javamail: why is text/plain attachment matter returned by getContent, and not from InputStream?

In trying to download mail with attachments from gmail, my test mail includes a text file as attachment.
The attachment part returns Text attachment content-type, and even the filename correctly. But the loop condition over attachment InputStream is never non-zero.
After a bit of trial and error it turned out that the content for text/plain is available using the getContent method for the part (in the case below introducing the call
att_mbp.getContent()
returned the content in the attached text file)
if (BodyPart.ATTACHMENT.equalsIgnoreCase(att_mbp.getDisposition())) {
att_mbp.getContentType();
// process each attachment
// read the filename
file = att_mbp.getFileName();
InputStream stream = att_mbp.getInputStream();
BufferedInputStream br = new BufferedInputStream(stream);
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(file));
while (br.available() > 0) {
// this loop is never executed for text/plain
bout.write(br.read());
}
bout.flush();
bout.close();
}
My question is - Why is the text/plain attachment body only available from getContent(), and not from the attached InputStream instance too?
Ok. I finally figured it out.
The call to available () always returns 0.
The code worked when I modified it as follows
int dataByte;
while( ( dataByte = br.read() ) > 0 ){
bout.write( dataByte );
}
According to javadoc, descendants of InputStream should override available. It looks like this is not the case here.

Resources