for release 3.14.1
[claws.git] / tools / tbird2claws.py
1 #!/usr/bin/python
2
3 # Script name : tbird2claws.py
4 # Script purpose : Integrate a Thunderbird folder tree to Claws Mail
5 # Author : Aleksandar Urosevic aka Urke MMI <urke@gmx.net>
6 # Licence : GPL
7 # Author: Rodrigo Dias Arruda Senra
8
9 #The script receives two parameters from command-line:
10 #<Thunderbird folder path> <Claws Mail folder path>
11
12 #Best way to use it is to go to inside yout Thunderbird
13 #root mailfolder directory and invoke it as:
14
15 #<path>\python2.4 <path>\tbird2claws.py . <path to
16 #claws-mail>\Mail
17
18 import os
19 import sys
20 from imp import reload
21
22 __author__ = 'Rodrigo Senra <rsenra@acm.org>'
23 __date__ =  '2005-03-23'
24 __version__ =  '0.3'
25
26 __doc__ = r"""
27 This module integrates your Mozilla Thunderbird 1.0 tree to
28 your Claws Mail MH mailbox tree.
29
30 The script receives two parameters from command-line:
31  <Thunderbird folder path> <Claws Mail folder path>
32
33 Best way to use it is to go to inside your Thunderbird
34 root mailfolder directory and invoke it as:
35
36   <path>\python2.4 <path>\tbird2syl.py . <path to claws mail>\Mail
37
38 This idiom will avoid the creation of the folder Thunderbird inside
39 your Claws Mail folder tree.
40
41 If the names of your directories match in both trees, files should
42 be placed in the correct folder.
43
44 This is an alpha release, so it may be a little rough around the edges.
45 Nevertheless, I used it with great success to convert a very large and
46 deep folder tree.
47
48 Please, do backup your claws-mail (destination) folder tree before trying
49 this out. Live safe and die old!
50
51 This code is released in the public domain.
52 """
53
54 def harvest_offsets(filepath):
55     """Given the filepath, this runs through the file finding
56     the number of the line where a message begins.
57     
58     The function returns a list of integers corresponding to
59     the beginning of messages.
60     """ 
61     offsets = []
62     i = 0
63     state = 'begin'
64     for i,line in enumerate(open(filepath)):
65         if line.startswith('From - ') and state!='found_head':
66            offsets.append(i)
67            continue
68 #        elif line.startswith('Return-Path') and state=='found_head':
69 #           state = 'found_offset'
70 #           offsets.append(i)
71 #           continue
72     offsets.append(i)
73     return offsets
74
75 def make_messages(outputdir, filepath, offsets, start):
76     """Given a filepath holding several messages in Thunderbird format,
77     extract the messages and create individual files for them, inside
78     outputdir with appropriate the appropriate naming scheme.
79     """ 
80     if not os.path.exists(outputdir):
81         os.makedirs(outputdir)
82     if not os.path.exists(filepath):
83         raise Exception('Cannot find message file  %s'%(filepath))
84     lines = open(filepath).readlines()
85     aux = offsets[:]
86     msgoffs = zip(offsets[:-1], aux[1:])
87     for i,j in msgoffs:
88        fd  = open(os.path.join(outputdir,"%d"%start),"w")
89        fd.write(''.join(lines[i:j-1])) #-1 to remove first from line
90        fd.close()
91        start +=1
92
93 def process_file(filepath, outputdir):
94     """Integrates a Thunderbird message file into a claws-mail message directory.
95     """  
96     offs = harvest_offsets(filepath)
97     make_messages(outputdir, filepath, offs, 1)
98
99 def clean_path(path):
100     """Rename all directories and subdirectories <X>.sbd to <X>
101     """
102     l = []
103     f = os.path.basename(path)
104     while f and f != "":
105         if f.endswith('.sbd'): 
106             f = f[:-4]
107         l.append(f)
108         path = os.path.dirname(path)
109         f = os.path.basename(path)
110     l.reverse()
111     r = os.path.join(*l)
112     return r
113
114
115
116 def convert_tree(in_treepath, out_treepath):
117     """Traverse your thunderbird tree, converting each message file found into
118     a claws-mail message directory.
119     """
120     for path,subs,files in os.walk(in_treepath):
121         outpath = clean_path(path)
122         if files:
123             for f in [x for x in files if not x.endswith('.msf')]:
124                 process_file(os.path.join(path,f),
125                              os.path.join(out_treepath,outpath,f))
126
127 if __name__=='__main__':
128     if len(sys.argv)<3:
129         print (__doc__)
130     else:
131         if sys.version[0] == '2':
132             reload(sys)
133             sys.setdefaultencoding('utf8')
134         convert_tree(sys.argv[1], sys.argv[2])