please find python imap script below i use to make csv files etc
it will search all folders, sub folders etc and make a file based on
display name and email address, i had started on a dav cal format but
csv is all that is supported at this time. it was also designed to
import hotmail address books for conversion?
was origionally intended to import to thunderbird.
it will give you a starting point.
#!/usr/local/bin/python2
# encoding: utf-8
import sys, os, socket,traceback
import getopt,base64
import time,datetime
from datetime import date
import select
from urllib import unquote_plus
import psycopg2,imaplib
from email.header import decode_header
import imaplib2
from threading import *
from lib import *
from optparse import OptionParser
USAGE_TEXT = '''\
usage: %%prog %s[options]
'''
parser = OptionParser(usage=USAGE_TEXT % '', version='0.4')
parser.add_option("-e", "--email", dest="email_address", help="Email
Adress to Process")
parser.add_option("-o", "--outlook", dest="hotmail_import_from",
help="Filespec for Hotmail Address Book")
parser.add_option("-p", "--password", dest="password", help="Email
Account Password")
parser.add_option("-f", "--filespec", dest="file_out", default =
'addressbook.csv', help="Output File")
parser.add_option("-v", "--vcard", dest="vcard", default = False, action
= 'store_true', help="Output File type vCard")
options, args = parser.parse_args()
if options.email_address == None :
print 'No Email Specified ..., Exiting'
sys.exit()
if options.password == None : #Go get the password
print 'Email Account Not Found, Exiting ....'
sys.exit()
print 'Processing Email : %s' %options.email_address
print 'Sending To : %s' %options.file_out
print 'Processing Hotmail Addressbook : %s' %options.hotmail_import_from
print 'Logging in to Account : %s with Password : %s\n\n'
%(options.email_address,options.password)
# Set the following two lines to your creds and server
M = imaplib2.IMAP4("mail.local.scom.ca")
status = M.login(options.email_address,options.password)
# We need to get out of the AUTH state, so we just select
# the INBOX.
if 'OK' not in status :
print 'Bad Username or Password : %s / %s'
%(options.uemail_address,options.password)
sys.exit()
address_book = []
#Ok import hotmail address book into system if avaliable
if options.hotmail_import_from != None : #go get the file in csv format
f = open(options.hotmail_import_from,'r')
data = f.read()
f.close
#Now start importing the data
data = data.split('\r\n')
#print data
#sys.exit()
for n in range ( 1,len(data) ) :
entry = data[n]
entry = entry.split(',')
#print
#print n,entry[0]
try :
email_address = entry[8].lower()
display_name = entry[0] + ' ' + entry[2]
print 'Importing Email : %s'
%email_address
print 'Importing Display Adress : %s' %display_name
#sys.exit()
b = []
b.append( email_address )
b.append( display_name )
b.append( display_name.split(' ')[0] )
try :
b.append( display_name.split(' ')[1] )
except:
b.append( display_name )
except :
pass
#sys.exit()
#Go get the folder list
for i in M.list()[1]:
mbox = (i.split('"/" ')[1])
print '\nProcessing Mbox : %s' %mbox
select_mbox = M.select(mbox)
if 'OK' not in select_mbox :
print 'Error on MBOX : %s, skipping ...' %mbox
continue
#sys.exit()
result, data = M.search(None, "ALL")
ids = data[0] # data is a list.
id_list = ids.split() # ids is a space separated string
#print id_list
#print
#print
#Ok process each email one at a time trying to look up a match
for ii in range( 0,len(id_list) ):
id = id_list[ii]
print
print 'Processing Message ID Number : %s' %str(id)
result, message_header = M.fetch(id, '(BODY.PEEK[HEADER])')
#print message_header
print
#print
message_header = str(message_header[0]).split('\\r\\n')
print 'Message Header for ID : %s:\n' %id
for n in range (0,len(message_header)) :
a = message_header[n]
if a[0:4] == 'To: ' or a[0:6] == 'From: ' :
if 'To: ' in a :
a = a.split('To: ')[1]
else :
a = a.split('From: ')[1]
print '\nFound Email Address Data : %s' %a
if '<' in a and '>' in a : #ok we have
a header that has a Display Address
display_name =
a.split('<')[0].rstrip()
print display_name
email_address =
str(a.split('<')[1].split('>')[0])
print email_address
else :
email_address = str (a)
display_name = email_address
#Do i need to decode UTF?/ISO-1
if '=?utf-8' in email_address or \
'=?ISO-8859-1?' in
email_address or \
'=?iso-8859-1?' in
email_address or \
'=?Windows-1252?' in
email_address or \
'=?UTF-8' in email_address :
#found a utf/iso header to decode)
print 'Decoding UTF-8 Email
Address ...'
email_address =
decode_header(email_address)
if '=?ISO-8859-1?' in
email_address or '=?iso-8859-1?' in email_address :
email_address =
email_address.decode('iso-8859-1').encode('utf8') #convert iso->>utf
if '=?Windows-1252?' in
email_address :
email_address =
email_address.decode('Windows-1252').encode('utf8') #convert windows->>utf
email_address =
utftoascii(email_address).ascii
if '=?utf-8?' in display_name or \
'=?ISO-8859-1?' in display_name
or \
'=?iso-8859-1?' in display_name
or \
'=?Windows-1252?' in
display_name or \
'=?UTF-8' in display_name :
#found a utf header to decode)
print 'Decoding UTF-8 Display
Name : %s' %display_name
#Dump the quotes
display_name =
display_name.replace('"','')
print 'Non-Quoted Display Name
UTF? : %s' %display_name
display_name =
decode_header(display_name)
print display_name
if '=?ISO-8859-1?' in
display_name or '=?iso-8859-1?' in display_name :
display_name =
display_name.decode('iso-8859-1').encode('utf8') #convert iso->>utf
#print 'Converted from
ISO : %s' %display_name
if '=?Windows-1252?' in
display_name :
display_name =
display_name.decode('Windows-1252').encode('utf8') #convert iso->>utf
#print 'Converted from
Windows-1252 : %s' %display_name
display_name =
utftoascii(display_name[0][0]).ascii
print 'UTF->ASCII : %s'
%display_name
display_name = ''.join([x for x
in display_name if ord(x) < 127])
print 'Display Name (Stripped)
: %s' %display_name
#sys.exit()
email_address =
str(email_address.split(',')[0]).lower() #just get the first email address?
display_name = display_name.replace('"','')
display_name = display_name.replace("'","")
#Now check email address is spam/valid etc
if 'bounces' in email_address or \
'noreply' in email_address or \
'no-reply' in email_address or \
'+' in email_address or \
len(email_address.split('@')[0]) > 32 :
continue
#print 'Looking for : %s'
%email_address
#print 'With Display Name : %s'
%display_name
#sys.exit()
#if email_address != 'clau...@edgetec.ca' :
# continue
#go see if email already in array, if
so skip, if email in array but no display (same as email), update display
skip = False
for nx in range(0,len(address_book)) :
#Go get current entries
add_data = address_book[nx]
#print 'With Email Info : %s'
%add_data[0]
#print 'With Display Info : %s'
%add_data[1]
if add_data[0] == email_address
: #found a duplicate email address, go see if we need display
if add_data[1] !=
email_address :
skip = True
#print 'Found
Email Address but Display Name Seems OK'
break
else : #ok found email,
update display_name, then break
#print 'Email
Address Found, Processing Better Display Name'
address_book[nx][1] = display_name
skip = True
break
sys.exit()
if skip == True :
#Skip dup entry
continue
email_address = email_address.split(',')[0]
if display_name == '' :
display_name = email_address
email_address = email_address.split(',')[0]
if display_name == '' or email_address
== '' :
print 'Blank EMail or Display
Name, Skipping ....'
continue
print '\nCreating Address Book Entry
with :\n\nEmail : %s\nDisplay Name : %s'
%(email_address,display_name)
if display_name[0] == '=' :
print 'Break Bad'
sys.exit()
b = []
b.append( email_address )
b.append( display_name )
b.append( display_name.split(' ')[0] )
try :
b.append( display_name.split('
')[1] )
except:
b.append( display_name )
#print b
address_book.append(b)
#print address_book
M.logout()
#print address_book
#Write the Address Book
#Am i making a Vcard file ?
if options.vcard == True : # yes
f = open(options.file_out,'w')
else : #CSV File
f = open(options.file_out,'w')
f.write('Primary Email\tDisplay Name\tFirst Name\tLast Name\n')
for n in range(0,len(address_book)) :
f.write(str( address_book[n][0] + '\t' +
address_book[n][1] + '\t' + address_book[n][2] + '\t' +
address_book[n][3] + '\n') ) #tab delimited
f.close()
'''
VCARD Formats
BEGIN:VCARD
VERSION:3.0
PRODID:-//Apple Inc.//iOS 17.0//EN
N:Hanna;Ed;;;
FN:Ed Hanna
ITEM1.EMAIL;TYPE=work;PREF=1:ed.ha...@eks.ca
ITEM2.EMAIL;TYPE=work:ed.ha...@electrokinetic.ca
ITEM3.TEL;TYPE=pref:16133792289
ITEM3.X-ABLABEL:Cottage
ITEM4.TEL:1 (647) 256-3460
ITEM4.X-ABLABEL:DSS Management
TEL;TYPE=HOME,VOICE:1 (647) 256-3472
ITEM5.TEL:+14035372392
ITEM5.X-ABLABEL:Calgary
TEL;TYPE=IPHONE,CELL,VOICE:+19057670409
ITEM6.ADR;TYPE=HOME,pref:;;;;;;Canada
ITEM6.X-ABADR:ca
ITEM7.URL;TYPE=pref:https://maps.apple.com/?ll=44.489801,-77.027956&q=Dropp
ed%20Pin&t=h
ITEM7.X-ABLABEL:_$!<HomePage>!$_
UID:621429c9-f0d8-4dc0-bc8b-6561176e85b1
X-IMAGETYPE:PHOTO
REV:20230802T165327Z
EMAIL;TYPE=work:ed.ha...@dssmgmt.com
EMAIL;TYPE=work:ed.ha...@ekst.ca
EMAIL;TYPE=work:ed.ha...@ek-solutions.ca
END:VCARD
'''
Thanks - Paul Kudla (Manager SCOM.CA Internet Services Inc.)
Have A Happy Sunday !!!
Scom.ca Internet Services <http://www.scom.ca>
004-1009 Byron Street South
Whitby, Ontario - Canada
L1N 4S3
Toronto 416.642.7266
Main 1.866.411.7266
Fax 1.888.892.7266
Email p...@scom.ca
On 2024-07-01 12:55 a.m., Aki Tuomi via dovecot wrote:
On 01/07/2024 04:01 EEST Austin Witmer via dovecot <dovecot@dovecot.org> wrote:
Hello all!
Is there a quick and easy way to search through an entire mailbox for a user on
my dovecot server and glean all the “from” email addresses?
This user would like a record of all the email addresses who have contacted him.
Thanks in advance for your ideas.
Austin Witmer
doveadm fetch -u user hdr.from all
Aki
_______________________________________________
dovecot mailing list -- dovecot@dovecot.org
To unsubscribe send an email to dovecot-le...@dovecot.org
_______________________________________________
dovecot mailing list -- dovecot@dovecot.org
To unsubscribe send an email to dovecot-le...@dovecot.org