Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117749397
massmigrate.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
4 KB
Referenced Files
None
Subscribers
None
massmigrate.py
View Options
#!/bin/env python3
# This script allows mass migrating pst files.
# Usage ./massmigrate.py
# --input ./input/
# --output ./output/
# --password $password
# --imap ssl://$domain:993 --dav https://$domain/iRony
#
# It requires an input and an output directory.
#
# The input directory contains files to import in the format:
# username@hostname.pst
#
# The output directory will receive all processed pst files.
import
subprocess
import
argparse
import
glob
import
shutil
import
os
import
time
from
threading
import
Thread
from
queue
import
Queue
def
transform_file
(
file
):
dir_path
,
filename
=
os
.
path
.
split
(
os
.
path
.
realpath
(
file
))
removepst
=
False
if
'.zip'
in
file
:
username
=
filename
.
replace
(
'.zip'
,
''
)
parts
=
username
.
split
(
'.'
)
username
=
f
"{parts[1]}.{parts[2]}@{parts[0].lower()}.domain.com"
result
=
subprocess
.
run
(
f
"unzip {filename}"
,
shell
=
True
,
cwd
=
dir_path
)
if
result
.
returncode
!=
0
:
return
None
,
None
,
None
,
None
removepst
=
True
filename
=
f
"{parts[1]}.{parts[2]}.pst"
else
:
username
=
filename
.
replace
(
'.pst'
,
''
)
return
dir_path
,
filename
,
username
,
removepst
def
import_file
(
file
,
password
,
imap_uri
,
dav_uri
,
type_filter
,
type_blacklist
):
image
=
"migrate"
start
=
time
.
time
()
dir_path
,
filename
,
username
,
removepst
=
transform_file
(
file
)
if
not
username
:
print
(
f
"Failed to extract the file {file}"
)
return
False
print
(
"Starting "
+
username
)
DOCKER_OPTIONS
=
' '
.
join
([
"--network=host"
,
"--rm"
,
"-ti"
,
"-v"
,
f
"{dir_path}:/opt/app-root/input/"
,
"-w"
,
"/opt/app-root/src"
,
])
cmdargs
=
[
"./artisan"
,
"migrate:userdata"
,
f
"--importpst=/opt/app-root/input/{filename}"
,
f
"--username={username} --password={password}"
,
"--subscribe --debug"
,
f
"--davUrl={dav_uri}"
,
f
"--imapUrl={imap_uri}"
,
"--exclude-target='Sync Issues (This computer only)'"
,
"--exclude-target='Drafts (This computer only)'"
,
"--exclude-target='Sync Issues*'"
,
"--exclude-target='Recoverable Items*'"
,
]
if
type_filter
:
cmdargs
.
append
(
f
"--type-filter='{type_filter}'"
)
if
type_blacklist
:
cmdargs
.
append
(
f
"--type-blacklist='{type_blacklist}'"
)
CMD
=
' '
.
join
(
cmdargs
)
with
open
(
f
"output/{username}.log"
,
'w'
)
as
logfile
:
result
=
subprocess
.
run
(
f
"podman run {DOCKER_OPTIONS} {image} {CMD}"
,
shell
=
True
,
text
=
True
,
stderr
=
subprocess
.
STDOUT
,
stdout
=
logfile
)
executionTime
=
time
.
time
()
-
start
print
(
f
"Finished {username} in {executionTime}s"
)
if
removepst
:
os
.
remove
(
f
"{dir_path}/{filename}"
)
return
not
result
.
returncode
return
1
def
main
():
parser
=
argparse
.
ArgumentParser
(
"usage: %prog [options]"
)
parser
.
add_argument
(
"--input"
,
help
=
"Input directory"
)
parser
.
add_argument
(
"--output"
,
help
=
"Output directory"
)
parser
.
add_argument
(
"--password"
,
help
=
"User password to use for all files"
)
parser
.
add_argument
(
"--imap"
,
help
=
"IMAP URI"
)
parser
.
add_argument
(
"--dav"
,
help
=
"DAV URI"
)
parser
.
add_argument
(
"--typefilter"
,
help
=
"Folder type whitelist (not a list)"
)
parser
.
add_argument
(
"--typeblacklist"
,
help
=
"Folder type blacklist (not a list)"
)
options
=
parser
.
parse_args
()
input_dir
=
os
.
path
.
expanduser
(
options
.
input
)
output_dir
=
os
.
path
.
expanduser
(
options
.
output
)
q
=
Queue
()
for
file
in
glob
.
glob
(
f
"{input_dir}*"
):
q
.
put
(
file
)
def
worker
():
while
True
:
file
=
q
.
get
()
if
import_file
(
file
,
options
.
password
,
options
.
imap
,
options
.
dav
,
options
.
typefilter
,
options
.
typeblacklist
):
shutil
.
move
(
file
,
output_dir
+
os
.
path
.
basename
(
file
))
else
:
print
(
f
"Failed to import {file}"
)
q
.
task_done
()
for
_i
in
range
(
3
):
Thread
(
target
=
worker
,
daemon
=
True
)
.
start
()
q
.
join
()
print
(
"Processing finished"
)
if
__name__
==
"__main__"
:
main
()
File Metadata
Details
Attached
Mime Type
text/x-script.python
Expires
Sat, Apr 4, 1:35 AM (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18821936
Default Alt Text
massmigrate.py (4 KB)
Attached To
Mode
rK kolab
Attached
Detach File
Event Timeline