0a7ee50de0690868a31c51c8d3ba60528f7dc5d9
[platal.git] / upgrade / 0.0.0_to_0.9.0 / to_mailman.py
1 #!/usr/bin/env python
2 #***************************************************************************
3 #* Copyright (C) 2003-2013 Polytechnique.org *
4 #* http://opensource.polytechnique.org/ *
5 #* *
6 #* This program is free software; you can redistribute it and/or modify *
7 #* it under the terms of the GNU General Public License as published by *
8 #* the Free Software Foundation; either version 2 of the License, or *
9 #* (at your option) any later version. *
10 #* *
11 #* This program is distributed in the hope that it will be useful, *
12 #* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 #* GNU General Public License for more details. *
15 #* *
16 #* You should have received a copy of the GNU General Public License *
17 #* along with this program; if not, write to the Free Software *
18 #* Foundation, Inc., *
19 #* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 #***************************************************************************
21
22 import base64, MySQLdb, os, getopt, sys, MySQLdb.converters, sha
23 from pwd import getpwnam
24 from grp import getgrnam
25
26 from SimpleXMLRPCServer import SimpleXMLRPCServer
27 from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
28
29 import paths
30 from Mailman import MailList
31 from Mailman import Utils
32 from Mailman import Message
33 from Mailman import Errors
34 from Mailman import mm_cfg
35 from Mailman import i18n
36 from Mailman.UserDesc import UserDesc
37 from Mailman.ListAdmin import readMessage
38
39 #-------------------------------------------------------------------------------
40 # helpers
41 #
42
43 def connectDB():
44 db = MySQLdb.connect(
45 db='x4dat',
46 user=mm_cfg.MYSQL_USER,
47 passwd=mm_cfg.MYSQL_PASS,
48 unix_socket='/var/run/mysqld/mysqld.sock')
49 db.ping()
50 return db.cursor()
51
52 def set_options(vhost,listname,opts,vals):
53 try:
54 mlist = MailList.MailList(vhost+'-'+listname)
55 except:
56 return 0
57 try:
58 for (k,v) in vals.iteritems():
59 if k not in opts:
60 continue
61 if k == 'default_member_moderation':
62 for member in mlist.getMembers():
63 mlist.setMemberOption(member, mm_cfg.Moderate, int(v))
64 t = type(mlist.__dict__[k])
65 if t is bool: mlist.__dict__[k] = bool(v)
66 elif t is int: mlist.__dict__[k] = int(v)
67 elif t is str: mlist.__dict__[k] = Utils.uncanonstr(v,'fr')
68 else: mlist.__dict__[k] = v
69 mlist.Save()
70 mlist.Unlock()
71 return 1
72 except:
73 mlist.Unlock()
74 raise
75 return 0
76
77 def mass_subscribe(vhost,listname,users):
78 try:
79 mlist = MailList.MailList(vhost+'-'+listname)
80 except:
81 return 0
82 try:
83 members = mlist.getRegularMemberKeys()
84 added = []
85 for user in users:
86 name, forlife = user;
87 if forlife+'@polytechnique.org' in members:
88 continue
89 userd = UserDesc(forlife+'@polytechnique.org', name, None, 0)
90 mlist.ApprovedAddMember(userd, 0, 0)
91 added.append( (userd.fullname, userd.address) )
92 mlist.Save()
93 finally:
94 mlist.Unlock()
95 return added
96
97 def add_owner(vhost,listname,forlife):
98 try:
99 mlist = MailList.MailList(vhost+'-'+listname)
100 except:
101 return 0
102 try:
103 if forlife+'@polytechnique.org' not in mlist.owner:
104 mlist.owner.append(forlife+'@polytechnique.org')
105 mlist.Save()
106 finally:
107 mlist.Unlock()
108 return True
109
110 #-------------------------------------------------------------------------------
111 # admin procedures [ check.php ]
112 #
113
114 check_opts = {
115 'acceptable_aliases' : '',
116 'admin_immed_notify' : True,
117 'administrivia' : True,
118 'anonymous_list' : False,
119 'autorespond_admin' : False,
120 'autorespond_postings' : False,
121 'autorespond_requests' : False,
122 'available_languages' : ['fr'],
123 'ban_list' : [],
124 'bounce_matching_headers' : '',
125 'bounce_processing' : False,
126 'convert_html_to_plaintext' : False,
127 'digestable' : False,
128 'digest_is_default' : False,
129 'discard_these_nonmembers' : [],
130 'emergency' : False,
131 'encode_ascii_prefixes' : 2,
132 'filter_content' : False,
133 'first_strip_reply_to' : False,
134 'forward_auto_discards' : True,
135 'header_filter_rules' : [],
136 'hold_these_nonmembers' : [],
137 'include_list_post_header' : False,
138 'include_rfc2369_headers' : False,
139 'new_member_options' : 256,
140 'nondigestable' : True,
141 'obscure_addresses' : True,
142 'preferred_language' : 'fr',
143 'reject_these_nonmembers' : [],
144 'reply_goes_to_list' : 0,
145 'reply_to_address' : '',
146 'require_explicit_destination' : False,
147 'send_reminders' : 0,
148 'send_welcome_msg' : True,
149 'topics_enabled' : False,
150 'umbrella_list' : False,
151 'unsubscribe_policy' : 0,
152 }
153
154 def check_options(vhost,listname,correct=False):
155 try:
156 mlist = MailList.MailList(vhost+'-'+listname)
157 except:
158 return 0
159 try:
160 options = { }
161 for (k,v) in check_opts.iteritems():
162 if mlist.__dict__[k] != v:
163 options[k] = v,mlist.__dict__[k]
164 if correct: mlist.__dict__[k] = v
165 if mlist.real_name != listname:
166 options['real_name'] = listname, mlist.real_name
167 if correct: mlist.real_name = listname
168 if mlist.host_name != vhost:
169 options['real_name'] = vhost, mlist.host_name
170 if correct: mlist.host_name = vhost
171 if correct: mlist.Save()
172 mlist.Unlock()
173 return (details,options)
174 except:
175 mlist.Unlock()
176 return 0
177
178 #-------------------------------------------------------------------------------
179 # admin procedures [ soptions.php ]
180 #
181
182 def create_list(vhost,listname,desc,advertise,modlevel,inslevel,owners,members):
183 name = vhost+'-'+listname;
184 if Utils.list_exists(name):
185 return 0
186
187 mlist = MailList.MailList()
188 try:
189 oldmask = os.umask(002)
190 pw = sha.new('foobar').hexdigest()
191 try:
192 mlist.Create(name, owners[0], pw)
193 finally:
194 os.umask(oldmask)
195
196 mlist.real_name = listname
197 mlist.host_name = vhost
198 mlist.description = desc
199
200 mlist.advertised = int(advertise) > 0
201 mlist.default_member_moderation = int(modlevel) is 2
202 mlist.generic_nonmember_action = int(modlevel) > 0
203 mlist.subscribe_policy = 2 * (int(inslevel) is 1)
204
205 mlist.owner = owners
206
207 mlist.subject_prefix = '['+listname+'] '
208 mlist.max_message_size = 0
209
210 mlist.Save()
211 mlist.Unlock()
212 check_options(vhost,listname,True)
213 mass_subscribe(vhost,listname,members)
214 except:
215 raise
216 return 0
217 return 1
218
219 uid = getpwnam(mm_cfg.MAILMAN_USER)[2]
220 gid = getgrnam(mm_cfg.MAILMAN_GROUP)[2]
221
222 if not os.getuid():
223 os.setregid(gid,gid)
224 os.setreuid(uid,uid)
225
226 if ( os.getuid() is not uid ) or ( os.getgid() is not gid):
227 sys.exit(0)
228
229 opts, args = getopt.getopt(sys.argv[1:], 'f')
230 for o, a in opts:
231 if o == '-f' and os.fork():
232 sys.exit(0)
233
234 mysql = connectDB()
235
236 #-------------------- LOGIC ---------------------
237
238 mysql.execute ("""SELECT a.id, a.alias, d.topic, d.bienvenue,
239 FIND_IN_SET('publique',d.type) AND NOT FIND_IN_SET('promo',d.type) AS advertised,
240 (1-FIND_IN_SET('freeins',d.type)) AS inslevel,
241 (1-FIND_IN_SET('libre',d.type))*2 AS modlevel
242 FROM aliases AS a
243 INNER JOIN listes_def AS d USING(id)
244 WHERE a.type='liste'""")
245 lists = mysql.fetchall()
246 i=0
247 l=len(lists)
248
249 for id,alias,desc,welcome,advertise,inslevel,modlevel in lists:
250 mysql.execute ( """SELECT a.alias
251 FROM auth_user_md5 AS u
252 INNER JOIN aliases AS a ON ( a.id=u.user_id AND a.type='a_vie' )
253 INNER JOIN listes_mod AS m ON ( m.idu=u.user_id AND m.idl='%i' )""" %(id) )
254 owners = map(lambda x: x[0]+'@polytechnique.org', mysql.fetchall())
255 if owners == []: owners = ['listes@m4x.org']
256 if desc.startswith('ADMIN/'): owners=[mm_cfg.ADMIN_ML_OWNER]
257 mysql.execute ( """SELECT CONCAT(u.prenom, ' ',u.nom),a.alias
258 FROM auth_user_md5 AS u
259 INNER JOIN aliases AS a ON ( a.id=u.user_id AND a.type='a_vie' )
260 INNER JOIN listes_ins AS m ON ( m.idu=u.user_id AND m.idl='%i' )""" %(id) )
261 members = mysql.fetchall()
262 create_list('polytechnique.org',alias,desc,advertise,modlevel,inslevel,owners,members)
263 set_options('polytechnique.org',alias,['welcome_msg'],{'welcome_msg':welcome})
264 i = i+1
265 print ("""[%3i/%i] '%s' created""" %(i,l,alias))
266
267 # vim:set et: