def main(): options, _ = zarafa.parser().parse_args() server = zarafa.Server(options) # TODO: use optparse to figure this out? if not server.options.auth_user: print 'No user specified' if not server.options.folders: print 'No folder specified' else: user = zarafa.Server().user(server.options.auth_user) folder = user.store.folders().next() # First Folder print 'Monitoring folder %s of %s for update and delete events' % ( folder, user.fullname) # Create mapping for item in folder.items(): ITEM_MAPPING[item.sourcekey] = item print 'Mapping of items and sourcekey complete' folder_state = folder.state new_state = folder.sync(Importer(), folder_state) # from last known state while True: new_state = folder.sync(Importer(), folder_state) # from last known state if new_state != folder_state: folder_state = new_state time.sleep(1)
def main(): server = zarafa.Server() user = zarafa.Server().user(server.options.auth_user) header = urwid.Text('inbox') footer = urwid.Text(FOOT1) mail = Mail(user.store.outbox) mailbox = MailBox(user.store.inbox, mail) columns = urwid.Columns([('fixed', 32, mailbox), mail], 1) frame = urwid.Frame(urwid.AttrWrap(columns, 'body'), header=urwid.AttrMap(header, 'headfoot'), footer=urwid.AttrMap(footer, 'headfoot')) mailbox.cols = mail.cols = columns mailbox.footer = mail.footer = footer urwid.MainLoop(frame, PALETTE).run()
def main(): options, args = opt_args() if not options.user or not options.days: print 'Please use:\n %s --user <username> --days <days> ' % (sys.argv[0]) sys.exit(1) daysbeforedeleted = datetime.datetime.now() - timedelta(days=int(options.days)) user = zarafa.Server(options).user(options.user) print 'Running script for \'%s\'' % user.name pbar = None if options.wastebasket: folder = user.store.wastebasket if options.progressbar: pbar = progressbar(folder, daysbeforedeleted) count = deleteitems(options, folder, daysbeforedeleted, pbar) if options.progressbar: pbar.finish() print 'Deleted %s item(s) for user \'%s\' in folder \'%s\'' % (count, user.name, folder.name) if options.junk: folder = user.store.junk if options.progressbar: pbar = progressbar(folder, daysbeforedeleted) count = deleteitems(options, folder, daysbeforedeleted, pbar) if options.progressbar: pbar.finish() print 'Deleted %s item(s) for user \'%s\' in folder \'%s\'' % (count, user.name, folder.name)
def main(): options, args = opt_args() if not args: print 'You must specify the amount of days!' sys.exit(1) try: val = int(args[0]) except ValueError: return sys.exit("Days not specified as a number!") for user in zarafa.Server(options=options).users(parse=True): print 'Running for user:'******'Folder:', folder.name for item in folder.items(): if not item.received: continue if item.received < datetime.today() - timedelta( days=int(args[0])): if options.verbose: print 'Item:', item.subject, 'Received:', datetime.today( ) - item.received else: print 'Item:', item.subject if options.modify: folder.delete([item])
def main(): options, args = opt_args() assert args, 'You must specify the amount of days!' try: val = int(args[0]) except ValueError: return sys.exit("Days not specify as a number!") for user in zarafa.Server(options=options).users(parse=True): print 'Running for user:'******'Folder:', folder.name for item in folder.items(): if not item.received: continue if item.received.date() < datetime.date.today( ) - datetime.timedelta(days=int(args[0])): if options.verbose: print 'Item:', item.subject, 'Received:', getMailAge( item.prop( PR_MESSAGE_DELIVERY_TIME).mapi_value.unixtime) else: print 'Item:', item.subject if options.modify: folder.delete([item])
def main(): print 'zarafa-search-xapian-compact started' server = zarafa.Server() index_path = zarafa.Config(None, 'search').get('index_path') if len(sys.argv) > 1: stores = [server.store(arg) for arg in sys.argv[1:]] else: stores = server.stores() for store in stores: try: dbpath = os.path.join(index_path, server.guid+'-'+store.guid) print 'compact:', dbpath if os.path.isdir(dbpath): with open('%s.lock' % dbpath, 'w') as lockfile: # do not index at the same time fcntl.flock(lockfile.fileno(), fcntl.LOCK_EX) shutil.rmtree(dbpath+'.compact', ignore_errors=True) subprocess.call(['xapian-compact', dbpath, dbpath+'.compact']) # quickly swap in compacted database shutil.move(dbpath, dbpath+'.old') shutil.move(dbpath+'.compact', dbpath) shutil.rmtree(dbpath+'.old') else: print 'WARNING: does not (yet) exist (new user?)' print except Exception, e: print 'ERROR' traceback.print_exc(e)
def testPOP3List(self): user = zarafa.Server(auth_user=auth_user, auth_pass=auth_pass).user(auth_user) user.inbox.create_item(subject='test', body='test') client = self.logonPOP3() self.assertIn('+OK 1 messages', client.list())
def main(): for user in zarafa.Server().users(parse=True): print 'user:'******'regular: count=%s size=%s %s%s' % ( str(folder.count).ljust(8), str(folder.size).ljust(10), folder.depth * ' ', folder.name)
def main(): options, args = opt_args() restorefoldername = "Zarafa Restored Folders" ipmsubtree = {} # Always correct values, as we look for the IPM_SUBTREE. entryidstore = {} # IPM_SUBTREE_ENTRYID values on user.store, could be incorrect. for user in zarafa.Server(options).users(parse=True): restoredfolders = False print "Processing user: %s" % user.name try: entryidstore[user.name] = user.store.mapiobj.GetProps([PR_IPM_SUBTREE_ENTRYID], 0)[0].Value.encode("hex").upper() except: continue for folder in user.store.folders(system=True): if folder.name == "IPM_SUBTREE": if user.name not in ipmsubtree.keys(): ipmsubtree[user.name] = folder.entryid if entryidstore[user.name] != ipmsubtree[user.name]: if options.dryrun: print "!! Script running in dry-run mode, nothing will be modified." print "- Incorrect IPM_SUBTREE is set: '%s'" % entryidstore[user.name] print "* Updating IPM_SUBTREE_ENTRYID to: '%s'" % ipmsubtree[user.name] if ipmsubtree[user.name]: if not options.dryrun: user.store.mapiobj.SetProps([SPropValue(PR_IPM_SUBTREE_ENTRYID, ipmsubtree[user.name].decode("hex"))]) if ipmsubtree[user.name] and entryidstore[user.name] and options.move: srcfld = user.store.folder(entryidstore[user.name]) dstfld = user.store.folder(ipmsubtree[user.name]) print "* Copying source folder '%s' to '%s'" % (srcfld.name, dstfld.name) if not options.dryrun: try: if user.store.folder(restorefoldername): resfolder = user.store.folder(restorefoldername) restoredfolders = True except zarafa.ZarafaNotFoundException: restorefolder = dstfld.create_folder(restorefoldername) resfolder = user.store.folder(restorefolder.entryid) restoredfolders = True if restoredfolders: if resfolder: srcfld.move(srcfld, resfolder) else: print "- Unable to move '%s' into '%s'" % (srcfld.name, dstfld.name) elif not ipmsubtree[user.name]: print "- No IPM_SUBTREE present, does the user have a store?"
def main(): options, args = opt_args(help=False) if options.user: oof = zarafa.Server(options).user(options.user).outofoffice if options.user and options.mode is None and options.subject is None and options.message is None: if oof.enabled: print "User %s:\nOut of Office: enabled" % (options.user) else: print "User %s:\nOut of Office: disabled" % (options.user) print "Subject: %s" % (oof.subject) print "Message: %s" % (oof.message) if oof.start: print "Start time: %s" % (oof.start) if oof.end: print "End time: %s" % (oof.end) else: if options.mode == 'enable': if not options.start: oof.start = None if not options.end: oof.end = None oof.enabled = True print "User %s: Enabled Out of Office" % (options.user) if options.mode == 'disable': oof.enabled = False print "User %s: Disabled Out of Office" % (options.user) if options.subject: oof.subject = options.subject print "User %s: Set subject to (%s)" % (options.user, options.subject) if options.message: oof.message = options.message print "User %s: Set message to (%s)" % (options.user, options.message) if options.start: print options.start else: opt_args(help=True)
def main(): s = zarafa.Server() for user in s.users(remote=False): print 'user:'******' folder: count=%s size=%s %s%s' % ( str(folder.count).ljust(8), str(folder.size).ljust(10), folder.depth * ' ', folder.name) folder.mbox(maildir)
def main(): options, args = opt_args() users = list(zarafa.Server(options).users()) width = 0.35 # the width of the bars fig, ax = plt.subplots() ind = range(0, len(users)) data = [b2m(user.store.size) for user in users] rects1 = ax.bar(ind, data, width, color='r') data = [len(list(user.store.folders())) for user in users] rects2 = ax.bar([offset + width for offset in ind], data, width, color='g') data = [ sum(folder.count for folder in user.store.folders()) for user in users ] rects3 = ax.bar([offset + width * 2 for offset in ind], data, width, color='b') ax.legend((rects1[0], rects2[0], rects3[0]), ('Store size (Mb)', 'Folders', 'Items')) ax.set_ylabel('Values') ax.set_title('Store size, Folder, Items per user') ax.set_xticks([offset + width for offset in ind]) ax.set_xticklabels([user.name for user in users]) def autolabel(rects): # attach some text labels for rect in rects: height = rect.get_height() ax.text(rect.get_x() + rect.get_width() / 2., 1.05 * height, '%d' % int(height), ha='center', va='bottom') autolabel(rects1) autolabel(rects2) autolabel(rects3) if options.save: plt.savefig(options.save) else: plt.show()
def main(): options, args = opt_args() if not (len(options.users) or options.all) or not options.after: print 'Run `zarafa-clean-deleted-items.py --help` for parameters' return else: if options.modify: action = ['Delete', 'Deleted'] else: action = ['Found', 'Detected'] count, size = 0, 0 conn = zarafa.Server(options=options) for user in conn.users(): if options.verbose: print 'Scanning user [%s] [%s and Subfolders]' % (user.name, user.store.wastebasket.name) wastefolders = [user.store.wastebasket.entryid] for wastefolder in user.store.wastebasket.folders(): wastefolders.append(wastefolder.entryid) for folder in wastefolders: for item in user.store.folder(folder).items(): if item.received: if item.received.date() < (datetime.date.today() - datetime.timedelta(days=options.after)): if options.verbose: print '\t %s in Folder: [%s] Date: [%s] Subject: [%s]' % ( action[0], getattr(user.folder(folder), 'path', 'name'), item.received.date(), item.subject) if options.modify: try: user.store.wastebasket.delete(item) except Exception as e: if options.verbose: print '\tDeleting failed error : [%s]' % e count += 1 size += item.size print '%s : [%s]' % (action[1], count), 'Approximately size freed: [%s Mb]' % b2m(size)
def main(): global delcounter learncounter = 0 (users, allusers, remoteusers, autolearn, autodelete, deleteafter, spamcommand) = getconfig() z = zarafa.Server() if allusers and not users: users = [] for user in z.users(remote=remoteusers): users.append(user.name) for username in users: try: user = z.user(username) for item in user.store.junk.items(): if autolearn: if (not item.header('x-spam-flag')) or ( item.header('x-spam-flag') == 'NO'): print "%s : untagged spam [Subject: %s]" % ( user.name, item.subject) try: p = subprocess.Popen(spamcommand, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) learn, output_err = p.communicate(item.eml()) except: print 'failed to run [%s] [%s]' % (SPAM, output_err) if learn: print "%s : learned [%s]" % (user.name, learn.rstrip('\n')) delmsg = 'delete after learn' deletejunk(user, item, delmsg) learncounter += 1 continue if autodelete: if item.received.date() < ( datetime.date.today() - datetime.timedelta(days=deleteafter)): delmsg = 'autodelete' deletejunk(user, item, delmsg) except Exception as error: print "%s : Unable to open store/item : [%s] [%s]" % ( username, username, error) continue print "Summary learned %d items, deleted %d items" % (learncounter, delcounter)
def main(): options, args = opt_args() if options.system: table = PR_EC_STATSTABLE_SYSTEM elif options.users: table = PR_EC_STATSTABLE_USERS elif options.company: table = PR_EC_STATSTABLE_COMPANY elif options.servers: table = PR_EC_STATSTABLE_SERVERS else: return table = zarafa.Server(options).table(table) if options.dump: print table.csv() else: print table.text()
def main(): options, args = opt_args() users = list(zarafa.Server(options).users()) data = [] fig, ax = plt.subplots() if options.store: data = {user.name: b2m(user.store.size) for user in users} plt.ylabel('Store size (Mb)') elif options.plotfolders: # TODO: add mail only flag? data = {user.name: len(list(user.store.folders())) for user in users} plt.ylabel('Folders') elif options.items: data ={user.name: sum(folder.count for folder in user.store.folders()) for user in users} plt.ylabel('Items') else: return if options.sort: ax.plot(sorted(data.values())) users = sorted(data, key=data.__getitem__) else: ax.plot(data.values()) plt.xlabel('Users') # TODO: find a more elegant solution labels = [item.get_text() for item in ax.get_xticklabels()] for i, user in enumerate(users): if options.sort: labels[i] = user else: labels[i] = user.name ax.set_xticklabels(labels) if options.save: plt.savefig(options.save) else: plt.show()
def main(): options, args = opt_args() if options.system: table = PR_EC_STATSTABLE_SYSTEM elif options.users: table = PR_EC_STATSTABLE_USERS elif options.company: table = PR_EC_STATSTABLE_COMPANY elif options.servers: table = PR_EC_STATSTABLE_SERVERS else: return try: table = zarafa.Server(options).table(table) if options.dump: print table.csv(delimiter=';') else: print table.text() except MAPIErrorNotFound: print 'Unable to open requested statistics table'
def main(): options, args = opt_args() if not options.user: sys.exit('Please use:\n %s --user <username> ' % (sys.argv[0])) user = zarafa.Server(options).user(options.user) try: print 'Create folder %s' % options.foldername user.store.subtree.create_folder(options.foldername) print 'Change %s to %s ' % (options.foldername, options.Type) user.folder( options.foldername).container_class = 'IPF.%s' % options.Type entryid = binascii.hexlify( getprop(user.store.folder(options.foldername), 0x0FF90102)) print entryid if 'Appointment' in options.Type: user.store.root.prop(0x36d00102L).set_value( binascii.unhexlify(entryid)) if 'Journal' in options.Type: user.store.root.prop(0x36d20102L).set_value( binascii.unhexlify(entryid)) if 'Tasks' in options.Type: user.store.root.prop(0x36d40102L).set_value( binascii.unhexlify(entryid)) if 'Contact' in options.Type: user.store.root.prop(0x36d10102L).set_value( binascii.unhexlify(entryid)) if 'Note' in options.Type: user.store.root.prop(0x36d30102L).set_value( binascii.unhexlify(entryid)) if 'Drafts' in options.Type: user.store.root.prop(0x36d70102L).set_value( binascii.unhexlify(entryid)) print 'Restore entryid for %s' % options.foldername except: print "can't create folder"
def main(): options, args = opt_args(help=False) if options.user: oof = zarafa.Server(options).user(options.user).outofoffice if options.user and options.mode is None and options.subject is None and options.message is None: if oof.enabled: print "User %s: Out of Office is enabled" % (options.user) else: print "User %s: Out of Office is disabled" % (options.user) print "User %s: Subject: (%s)" % (options.user, oof.subject) print "User %s: Message: (%s)" % (options.user, oof.message) else: if options.mode == 'enable': oof.enabled = True print "User %s: Enabled Out of Office" % (options.user) if options.mode == 'disable': oof.enabled = False print "User %s: Disabled Out of Office" % (options.user) if options.subject: oof.subject = options.subject print "User %s: Set subject to (%s)" % (options.user, options.subject) if options.message: oof.message = options.message print "User %s: Set message to (%s)" % (options.user, options.message) else: opt_args(help=True)
def main(): global nr_error options, args = zarafa.parser('cskpUPmvu').parse_args() server = zarafa.Server() if len(args) == 1 and os.path.isdir(args[0]): data = [] for filename in sorted(glob.glob(args[0] + '/*/account.settings')): print 'ACCOUNT:', filename data.append(('{\nRealName = "%s";\n' % filename.split(os.path.sep)[-2]) + file(filename).read() + '\n}') elif args: data = [file(arg).read() for arg in args] else: data = [TEST_ACCOUNT] for d in data: try: account = cgon.loads(d.strip()) process_account(account, server, options) except Exception, e: print traceback.format_exc(e) nr_error += 1
def main(): options, args = opt_args() zarafa.Server(options).users().next().store.calendar.create_item( ics=file(options.ics).read())
import zarafa from MAPI.Tags import PR_SUBJECT server = zarafa.Server() for item in server.user('user1').store.inbox: if item.stubbed: print 'all properties:' for prop in item.props(): print 'id=%s, idname=%s, type=%s, typename=%s, value=%r, named=%s, guid=%s, namespace=%s, name=%s, kind=%s, kindname=%s' % ( hex(prop.id_), prop.idname, prop.type_, prop.typename, repr(prop.value)[:20], prop.named, prop.guid, prop.namespace, prop.name, prop.kind, prop.kindname) print 'archive properties:' for prop in item.props(namespace='archive'): print prop.name, repr(prop.value) print 'pr_subject:' print item.prop(PR_SUBJECT) print 'archive:stubbed:' print item.prop('archive:stubbed') break
import zarafa options, args = zarafa.parser('skpmcuf').parse_args() assert args, 'please specify search pattern' for user in zarafa.Server().users(parse=True): print "Running for user:"******"Folder:", folder.name for item in folder.items(): if args[0].lower() in item.subject.lower(): print "Deleting:", item if options.modify: folder.delete([item])
def main(argv = None): parser = NagiosArgumentParser("Sending and Receiving Mail via MAPI Test") parser.add_argument("-s", dest="server", help="the zarafa server", metavar="server") parser.add_argument("-u", dest="username", help="testmailaccount username", metavar="username") parser.add_argument("-p", dest="password", help="password for the testmailaccount", metavar="password") parser.add_argument("-H", dest="hostname", help="hostname for the testmailaccount", metavar="hostname") parser.add_timeout() args = parser.parse_args() if args.username is None: print "You need the parameter -u for the username" nagios_exit(STATE_UNKNOWN) if args.server is None: print "You need the parameter -s for the zarafa server" nagios_exit(STATE_UNKNOWN) if args.hostname is None: print "You need the parameter -H for the hostname of the mail receivers address" nagios_exit(STATE_UNKNOWN) if args.password is None: # We just use an empty password and inform the user if verbose output is set if args.verbose_1: print "No password given, using empty password instead" args.password = "" if args.timeout is None: # No timeout given, use default (20) if args.verbose_1: print "No timeout given, using default (20 seconds)" args.timeout = 20.0 # f*ck you zarafapackage, you won't get my script arguments.. these are MINE... # sane comment: the zarafa package always trys to use the args and stops with an error if there are unrecognized or 'wrong' parameters while len(sys.argv) > 1: sys.argv.remove(sys.argv[1]) if args.verbose_2: print "Parameters:" print "Timeout: ", args.timeout print "Username: "******"Password: "******"Server: ", args.server print "host: ", args.hostname testmail_subject = 'Einladung zum Superschurkengeheimversteck #' + str(random.random()); ################################################################################################################# # Part 1: Sending a test mail # ################################################################################################################# receiver_address = args.username + '@' + args.hostname if args.verbose_1: print "Test mail subject: ", testmail_subject print "Mail receiver address: ", receiver_address try: zarafa_server = zarafa.Server(server_socket=args.server, auth_user=args.username, auth_pass=args.password) user_outbox = zarafa_server.user(args.username).store.outbox if args.verbose_1: print "Sending the testmail" user_outbox.create_item(subject=testmail_subject, to=receiver_address, body='This is an official MAPI-Testmail, do not read any further ... I said do NOT read ... whatever').send() except zarafa.ZarafaException as e: print "CRITICAL ERROR: ZarafaException: ", e nagios_exit(STATE_CRITICAL) # theres no function for closing the session, so it should get closed when the object is deleted after the last reference was used.. which should be somewhere here or later if args.verbose_1: print "Waiting ", args.timeout, " seconds now" time.sleep(args.timeout) ################################################################################################################# # Part 2: Check for the sended mail # ################################################################################################################# if args.verbose_1: print "Starting session for user ", args.username, " now" try: user_store = zarafa.Server(server_socket=args.server, auth_user=args.username, auth_pass=args.password).user(args.username).store user_inbox = user_store.inbox user_sentmail = user_store.sentmail inbox_mails = user_inbox.items() sent_mails = user_sentmail.items() except MAPIError, err: if err.hr == MAPI_E_LOGIN_FAILED: print "CRITICAL ERROR: Login failed. Check credentials" nagios_exit(STATE_CRITICAL) elif err.hr == MAPI_E_NETWORK_ERROR: print "CRITICAL ERROR: Connection failed" nagios_exit(STATE_CRITICAL)
def setUp(self): self.server = zarafa.Server(auth_user=auth_user, auth_pass=auth_pass)
#!/usr/bin/env python import zarafa from MAPI.Tags import * import base64 z = zarafa.Server() def main(): for user in z.users(remote=True): for item in user.store.root.associated.items(): fname = user.name if item.prop(PR_MESSAGE_CLASS_W): if item.prop(PR_MESSAGE_CLASS_W).value.lower( ) == 'webapp.security.private': with open(fname + '.p12', 'w') as f: f.write(base64.b64decode(item.body.text)) if item.prop(PR_MESSAGE_CLASS_W).value.lower( ) == 'webapp.security.public': with open(fname + '.pub.pem', 'w') as f: f.write(base64.b64decode(item.body.text)) if __name__ == '__main__': main()
def main(): global delcounter learncounter = 0 hamlearncounter = 0 (users, allusers, remoteusers, autolearn, autodelete, deleteafter, spamcommand, hamfolder, hammarkertoremove, hamfoldercreate, hamcommand, hamlimit) = getconfig() z = zarafa.Server() if allusers and not users: users = [] for user in z.users(remote=remoteusers): users.append(user.name) for username in users: try: user = z.user(username) inboxelements = 0 try: nospamFolder = user.store.folder(hamfolder) except: if(hamfoldercreate): print "%s : create ham folder [%s]" % (user.name, hamfolder) nospamFolder = user.store.subtree.create_folder(hamfolder) else: print "%s : has not ham folder [%s]" % (user.name, hamfolder) continue p = re.compile(hammarkertoremove) for item in nospamFolder.items(): if (hamlimit > 0 and inboxelements > hamlimit): break if autolearn: if (item.header('x-spam-flag') and item.header('x-spam-flag') == 'YES'): inboxelements += 1 print "%s : tagged spam in inbox [Subject: %s]" % (user.name, item.subject) try: hp = subprocess.Popen(shlex.split(hamcommand), stdin=subprocess.PIPE, stdout=subprocess.PIPE) learn, ham_output_error = hp.communicate(item.eml()) except: print "failed to run [HAM] [%s]" % ham_output_err if learn: item.subject=p.sub('',item.subject) nospamFolder.move(item, user.store.inbox) print "%s : learned [%s]" % (user.name, learn.rstrip('\n')) hamlearncounter += 1 continue for item in user.store.junk.items(): if autolearn: if (not item.header('x-spam-flag')) or (item.header('x-spam-flag') == 'NO'): print "%s : untagged spam [Subject: %s]" % (user.name, item.subject) try: p = subprocess.Popen(shlex.split(spamcommand), stdin=subprocess.PIPE, stdout=subprocess.PIPE) learn, output_err = p.communicate(item.eml()) except: print 'failed to run [%s] [%s]' % (SPAM, output_err) if learn: print "%s : learned [%s]" % (user.name, learn.rstrip('\n')) delmsg = 'delete after learn' deletejunk(user, item, delmsg) learncounter += 1 continue if autodelete: if item.received.date() < (datetime.date.today()-datetime.timedelta(days=deleteafter)): delmsg = 'autodelete' deletejunk(user, item, delmsg) except Exception as error: print "%s : Unable to open store/item : [%s] [%s]" % (username, username, error) continue print "Summary learned %d SPAM items %d HAM items, deleted %d items" % (learncounter, hamlearncounter, delcounter)
#!/usr/bin/env python import zarafa fname = 'Sent Items' for user in zarafa.Server().users(): try: if user.store.folder(fname): for item in user.store.folder(fname): attachments = [ attach.filename for attach in item.attachments() ] if not attachments: continue try: for to in item.recipients(): if to.addrtype == 'SMTP': print "%s folder: '%s' subject: '%s' attachments: '%s' email: '%s'" % ( user.name, fname, item.subject, ', '.join(attachments), to.email) if to.addrtype == 'ZARAFA': print "%s folder: '%s' subject: '%s' attachments: '%s' user: '******'" % ( user.name, fname, item.subject, ', '.join(attachments), to.name) except: pass except zarafa.ZarafaException: pass