'zimbra邮件自动导出脚本'

今天公司让我写个邮件自动导出脚本,对于我这个代码菜鸟来说,挺自闭的,记录一下,大佬就当是个笑话

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# -*-* coding:UTF-8

import requests
import click
from urllib.parse import urlparse

def main(options):
username, password, base_url = options['username'], options['password'], options['url']
headers = {
'User-Agent': "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)",
'Content-Type': "application/soap+xml; charset=UTF-8",
}
o = urlparse(base_url)
domain = o.netloc
session = requests.session()
login_url = base_url + 'service/admin/soap/AuthRequest'
request_url = base_url + 'service/admin/soap/SearchDirectoryRequest'
data = f"""<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header><context xmlns="urn:zimbra"><userAgent name="ZimbraWebClient - GC80 (Win)"/><session id="357"/><authTokenControl voidOnExpired="1"/><format type="js"/><csrfToken>0_6790c8c2dd37ab6dc0b259c640c877ae52859389</csrfToken></context></soap:Header><soap:Body><AuthRequest xmlns="urn:zimbraAdmin"><name>{username}</name><password>{password}</password><virtualHost>{domain}</virtualHost><csrfTokenSecured>1</csrfTokenSecured></AuthRequest></soap:Body></soap:Envelope>"""
r = session.post(login_url, data=data, verify=False, headers=headers)
csrf_token = r.json()['Body']['AuthResponse']['csrfToken']['_content']
data = f"""<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header><context xmlns="urn:zimbra"><userAgent name="ZimbraWebClient - GC80 (Win)"/><session id="372"/><format type="js"/><csrfToken>{csrf_token}</csrfToken></context></soap:Header><soap:Body><SearchDirectoryRequest xmlns="urn:zimbraAdmin" offset="0" limit="50" sortBy="name" sortAscending="1" applyCos="false" applyConfig="false" attrs="displayName,zimbraId,zimbraAliasTargetId,cn,sn,zimbraMailHost,uid,zimbraCOSId,zimbraAccountStatus,zimbraLastLogonTimestamp,description,zimbraIsSystemAccount,zimbraIsDelegatedAdminAccount,zimbraIsAdminAccount,zimbraIsSystemResource,zimbraAuthTokenValidityValue,zimbraIsExternalVirtualAccount,zimbraMailStatus,zimbraIsAdminGroup,zimbraCalResType,zimbraDomainType,zimbraDomainName,zimbraDomainStatus,zimbraIsDelegatedAdminAccount,zimbraIsAdminAccount,zimbraIsSystemResource,zimbraIsSystemAccount,zimbraIsExternalVirtualAccount" types="accounts"><query>(&amp;(!(zimbraIsSystemAccount=TRUE)))</query></SearchDirectoryRequest></soap:Body></soap:Envelope>"""
r = session.post(request_url, verify=False, headers=headers, data=data)
account = r.json()['Body']['SearchDirectoryResponse']['account']
for i in account:
user = i['name'].split("@")[0]
domain1 = i['name'].split("@")[1]
if options['user'] != user and not options['all']:
continue
download_url = f'{base_url}home/{user}%40{domain1}/?fmt=tgz&filename=1&emptyname=2&charset=UTF-8&callback=ZmImportExportController.exportErrorCallback__export1'
res = session.get(download_url, verify=False)
with open("D:\%s.tar.gz" % user, 'wb') as f:
f.write(res.content)


@click.command()
@click.option('--username',"-u", help='用户账号')
@click.option('--password',"-p", help='用户密码')
@click.option('--url',"-d", help='登录地址')
@click.option('--user', help='指定用户')
@click.option('--all', help='全部用户', is_flag=True)
def cli(**kwargs):
return main(kwargs)


if __name__ == '__main__':
cli()

使用

导出指定用户邮件
python zimbra.py -u admin -p 123456 -d https://sunian.xyz:7071/ --user admin
导出所有用户邮件
python zimbra.py -u admin -p 123456 -d https://sunian.xyz:7071/ --all

对比其他师傅写的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# -*-* coding:UTF-8

import requests
import click
from urllib.parse import urlparse
from optparse import OptionParser
from requests.packages.urllib3.exceptions import InsecureRequestWarning


requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

usage = "usage: python %prog --url https://example.com:7071/ --username admin --password admin --user (zhangsan|All)"
parser = OptionParser(usage=usage)
parser.add_option("-d", "--url", dest="url",
help="the zombra admin url, like https://example.com:7071/")
parser.add_option("-u", "--username", dest="username",
help="zimbra admin login username, like admin")
parser.add_option("-p", "--password", dest="password",
help="zimbra admin login password, like admin")
parser.add_option("--user", dest="user",
help="the user mail you want to export, like admin or All(export all users email)")

(options, args) = parser.parse_args()


def main():

username, password, base_url = options.username, options.password, options.url
headers = {
'User-Agent': "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)",
'Content-Type': "application/soap+xml; charset=UTF-8",
}
o = urlparse(base_url)
domain = o.netloc.split(':')[0]
session = requests.session()
login_url = base_url + 'service/admin/soap/AuthRequest'
request_url = base_url + 'service/admin/soap/SearchDirectoryRequest'
data = f"""<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header><context xmlns="urn:zimbra"><userAgent name="ZimbraWebClient - GC80 (Win)"/><session id="357"/><authTokenControl voidOnExpired="1"/><format type="js"/><csrfToken>0_6790c8c2dd37ab6dc0b259c640c877ae52859389</csrfToken></context></soap:Header><soap:Body><AuthRequest xmlns="urn:zimbraAdmin"><name>{username}</name><password>{password}</password><virtualHost>{domain}</virtualHost><csrfTokenSecured>1</csrfTokenSecured></AuthRequest></soap:Body></soap:Envelope>"""
r = session.post(login_url, data=data, verify=False, headers=headers)
csrf_token = r.json()['Body']['AuthResponse']['csrfToken']['_content']
data = f"""<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header><context xmlns="urn:zimbra"><userAgent name="ZimbraWebClient - GC80 (Win)"/><session id="372"/><format type="js"/><csrfToken>{csrf_token}</csrfToken></context></soap:Header><soap:Body><SearchDirectoryRequest xmlns="urn:zimbraAdmin" offset="0" limit="50" sortBy="name" sortAscending="1" applyCos="false" applyConfig="false" attrs="displayName,zimbraId,zimbraAliasTargetId,cn,sn,zimbraMailHost,uid,zimbraCOSId,zimbraAccountStatus,zimbraLastLogonTimestamp,description,zimbraIsSystemAccount,zimbraIsDelegatedAdminAccount,zimbraIsAdminAccount,zimbraIsSystemResource,zimbraAuthTokenValidityValue,zimbraIsExternalVirtualAccount,zimbraMailStatus,zimbraIsAdminGroup,zimbraCalResType,zimbraDomainType,zimbraDomainName,zimbraDomainStatus,zimbraIsDelegatedAdminAccount,zimbraIsAdminAccount,zimbraIsSystemResource,zimbraIsSystemAccount,zimbraIsExternalVirtualAccount" types="accounts"><query>(&amp;(!(zimbraIsSystemAccount=TRUE)))</query></SearchDirectoryRequest></soap:Body></soap:Envelope>"""
r = session.post(request_url, verify=False, headers=headers, data=data)
account = r.json()['Body']['SearchDirectoryResponse']['account']
# all user
if options.user == 'All':
for i in account:
try:
user = i['name'].split("@")[0]
print(user + ' is exporting')
domain1 = i['name'].split("@")[1]
download_url = f'{base_url}home/{user}%40{domain1}/?fmt=tgz&filename=1&emptyname=2&charset=UTF-8&callback=ZmImportExportController.exportErrorCallback__export1'
res = session.get(download_url, verify=False)

with open("%s.tar.gz" % user, 'wb') as f:
f.write(res.content)
print(user + ' export done')
except Exception as e:
print(user + ' export fail')
print(e)
# single user
else:
print(options.user + ' is exporting')
download_url = f'{base_url}home/{options.user}%40{domain}/?fmt=tgz&filename=1&emptyname=2&charset=UTF-8&callback=ZmImportExportController.exportErrorCallback__export1'
res = session.get(download_url, verify=False)
with open("%s.tar.gz" % options.user, 'wb') as f:
f.write(res.content)
print(options.user + ' export done')


def cli():
return main()


if __name__ == '__main__':
if not options.url or not options.username or not options.password or not options.user:
parser.error("options error, please use -h or --help to get help")
else:
cli()
# print(1)