Forked from alanpoulain/AndroidEmailExtractor.groovy
Last active
August 23, 2017 08:58
-
-
Save felixebert/f3399305bf41fe814119629f8a560555 to your computer and use it in GitHub Desktop.
Android email extraction from backup - see http://leanjavaengineering.wordpress.com/2014/06/10/android-email-extraction-to-eml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copying and distribution of this file, with or without modification, | |
* are permitted in any medium without royalty provided the copyright | |
* notice and this notice are preserved. This file is offered as-is, | |
* without any warranty. | |
* | |
* Script to take an Android ADB email dump and process emails to .eml RFC822 | |
* format files. Does not handle attachments/multipart at present. | |
* | |
* <em>Notes:</em> | |
* Configured for a specific account and the Sent items mailbox | |
* in the 1st query. | |
* | |
* @author Robin Bramley (c) 2014 | |
* @author Alan Poulain | |
* @author Felix Ebert | |
*/ | |
import groovy.sql.Sql | |
import javax.mail.* | |
import javax.mail.internet.* | |
@Grapes([ | |
@Grab(group = 'org.xerial', module = 'sqlite-jdbc', version = '3.7.2'), | |
@GrabConfig(systemClassLoader = true) | |
]) | |
@Grapes( | |
@Grab(group = 'com.icegreen', module = 'greenmail', version = '1.3') | |
) | |
// lazy way of pulling in JavaMail & Glasgow JAF (showing my age?) | |
import java.sql.* | |
// Utility to convert addresses into InternetAddress[] | |
def convertAddresses = { inList -> | |
def cleanListStr = "" | |
def i = 0 | |
def dirtyList = inList.tokenize('\u0001') // split on SOH | |
dirtyList.each { | |
if (it.contains("@")) { | |
// Set list separator when required | |
if (i > 0) { | |
cleanListStr += ',' | |
} | |
// Clear any text, we'll just use the email address | |
if (it.contains('\u0002')) { // STX | |
def stxIndex = it.indexOf(2) | |
it = it.substring(0, stxIndex) | |
} | |
cleanListStr += it | |
i++ | |
} | |
} | |
try { | |
return InternetAddress.parse(cleanListStr, false) // strict | |
} catch (Exception e) { | |
println e | |
e.printStackTrace(System.out) | |
return InternetAddress.parse("[email protected]") | |
} | |
} | |
// Connection handles for finally block | |
def sql, sqlBody | |
try { | |
def props = new Properties() | |
// Get mail session | |
def session = Session.getDefaultInstance(props) | |
// Get the DBs | |
sql = Sql.newInstance('jdbc:sqlite:EmailProvider.db', 'org.sqlite.JDBC') | |
sqlBody = Sql.newInstance('jdbc:sqlite:EmailProviderBody.db', 'org.sqlite.JDBC') | |
// Get the headers | |
sql.eachRow(""" | |
SELECT _id AS msgKey, timeStamp, subject, messageId, fromList, toList, ccList, bccList, replyToList | |
FROM Message | |
ORDER BY timeStamp ASC | |
""") { row -> | |
try { | |
def msgKey = row.msgKey | |
// Get the message body | |
def body = sqlBody.firstRow("SELECT htmlContent, textContent, textReply FROM Body WHERE messageKey = ${msgKey}") | |
// Construct the email | |
def rawMsg = "\n\n########\nRaw:\n" | |
def msg = new MimeMessage(session) | |
if (row.fromList) { | |
msg.setFrom(convertAddresses(row.fromList).first()) | |
rawMsg += "From: " + row.fromList + "\n" | |
} | |
if (row.subject) { | |
msg.setSubject(row.subject) | |
} | |
msg.setSentDate(new Date(row.timeStamp)) | |
if (row.toList) { | |
rawMsg += "To: " + row.toList + "\n" | |
msg.setRecipients(Message.RecipientType.TO, convertAddresses(row.toList)) | |
} | |
if (row.ccList) { | |
rawMsg += "CC: " + row.ccList + "\n" | |
msg.setRecipients(Message.RecipientType.CC, convertAddresses(row.ccList)) | |
} | |
if (row.bccList) { | |
rawMsg += "BCC: " + row.ccList + "\n" | |
msg.setRecipients(Message.RecipientType.BCC, convertAddresses(row.bccList)) | |
} | |
// Set the HTML content if it exists | |
if (body) { | |
if (body.htmlContent) { | |
def contentType = 'text/html' | |
msg.setContent(body.htmlContent + rawMsg, contentType) | |
} else if (body.textContent) { | |
msg.setText(body.textContent + rawMsg) | |
} | |
} else { | |
msg.setText("Empty Body" + rawMsg) | |
} | |
// Write out the email | |
new File("${row.timestamp}-${msgKey}.eml").withOutputStream { os -> | |
msg.writeTo(os) | |
} | |
} catch (Exception e) { | |
println e | |
e.printStackTrace(System.out) | |
if (row && row.msgKey) { | |
println row.msgKey | |
} | |
} | |
} | |
} catch (Exception e) { | |
println e | |
e.printStackTrace(System.out) | |
} finally { | |
if (sql) { | |
sql.close() | |
} | |
if (sqlBody) { | |
sqlBody.close() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment