Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save felixebert/f3399305bf41fe814119629f8a560555 to your computer and use it in GitHub Desktop.
Save felixebert/f3399305bf41fe814119629f8a560555 to your computer and use it in GitHub Desktop.
/**
* 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