Moving to GitHub.
[platal.git] / bin / lists.rpc.py
index e9529ae..cda3511 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #***************************************************************************
-#*  Copyright (C) 2003-2010 Polytechnique.org                              *
+#*  Copyright (C) 2003-2014 Polytechnique.org                              *
 #*  http://opensource.polytechnique.org/                                   *
 #*                                                                         *
 #*  This program is free software; you can redistribute it and/or modify   *
@@ -22,6 +22,8 @@
 import base64, MySQLdb, os, getopt, sys, sha, signal, re, shutil, ConfigParser
 import MySQLdb.converters
 import SocketServer
+import errno
+import traceback
 
 sys.path.append('/usr/lib/mailman/bin')
 
@@ -67,11 +69,13 @@ def get_config(sec, val, default=None):
 
 MYSQL_USER     = get_config('Core', 'dbuser')
 MYSQL_PASS     = get_config('Core', 'dbpwd')
+MYSQL_HOST     = get_config('Core', 'dbhost')
 MYSQL_DB       = get_config('Core', 'dbdb')
 
 PLATAL_DOMAIN  = get_config('Mail', 'domain')
 PLATAL_DOMAIN2 = get_config('Mail', 'domain2', '')
 sys.stderr.write('PLATAL_DOMAIN = %s\n' % PLATAL_DOMAIN )
+sys.stderr.write("MYSQL_DB = %s\n" % MYSQL_DB)
 
 VHOST_SEP      = get_config('Lists', 'vhost_sep', '_')
 ON_CREATE_CMD  = get_config('Lists', 'on_create', '')
@@ -126,12 +130,12 @@ class BasicAuthXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
             self.end_headers()
 
     def getUser(self, uid, md5, vhost):
-        res = mysql_fetchone ("""SELECT  a.full_name, IF(aa.alias IS NULL, a.email, CONCAT(aa.alias, '@%s')),
+        res = mysql_fetchone ("""SELECT  a.full_name, IF(s.email IS NULL, a.email, CONCAT(s.email, '@%s')),
                                          IF (a.is_admin, 'admin',
                                                          IF(FIND_IN_SET('lists', at.perms) OR FIND_IN_SET('lists', a.user_perms), 'lists', NULL))
                                    FROM  accounts AS a
                              INNER JOIN  account_types AS at ON (at.type = a.type)
-                              LEFT JOIN  aliases  AS aa ON (a.uid = aa.uid AND aa.type = 'a_vie')
+                              LEFT JOIN  email_source_account AS s ON (s.uid = a.uid AND s.type = 'forlife')
                                   WHERE  a.uid = '%s' AND a.password = '%s' AND a.state = 'active'
                                   LIMIT  1""" \
                               % (PLATAL_DOMAIN, uid, md5))
@@ -148,7 +152,7 @@ class BasicAuthXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
             userdesc = UserDesc(forlife, name, None, 0)
             return (userdesc, perms, vhost)
         else:
-            print "no user found for uid: %s, passwd: %s" % (uid, md5)
+            print >> sys.stderr, "no user found for uid: %s, passwd: %s" % (uid, md5)
             return None
 
 ################################################################################
@@ -164,8 +168,9 @@ def connectDB():
             db=MYSQL_DB,
             user=MYSQL_USER,
             passwd=MYSQL_PASS,
-            unix_socket='/var/run/mysqld/mysqld.sock')
+            host=MYSQL_HOST)
     db.ping()
+    db.autocommit(True)
     return db.cursor()
 
 def mysql_fetchone(query):
@@ -198,11 +203,10 @@ def to_forlife(email):
         mbox = email
         fqdn = PLATAL_DOMAIN
     if ( fqdn == PLATAL_DOMAIN ) or ( fqdn == PLATAL_DOMAIN2 ):
-        res = mysql_fetchone("""SELECT  CONCAT(f.alias, '@%s'), a.full_name
+        res = mysql_fetchone("""SELECT  CONCAT(s1.email, '@%s'), a.full_name
                                   FROM  accounts AS a
-                            INNER JOIN  aliases  AS f  ON (f.uid = a.uid AND f.type = 'a_vie')
-                            INNER JOIN  aliases  AS aa ON (aa.uid = a.uid AND aa.alias = '%s'
-                                                           AND a.type != 'homonyme')
+                            INNER JOIN  email_source_account AS s1 ON (a.uid = s1.uid AND s1.type = 'forlife')
+                            INNER JOIN  email_source_account AS s2 ON (a.uid = s2.uid AND s2.email = '%s')
                                  WHERE  a.state = 'active'
                                  LIMIT  1""" \
                               % (PLATAL_DOMAIN, mbox))
@@ -242,7 +246,7 @@ def list_call_dispatcher(method, userdesc, perms, vhost, *arg):
         @root:  the handler requires site admin rights
     """
     try:
-        print "calling method: %s" % method
+        print >> sys.stderr, "calling method: %s" % method
         if has_annotation(method, "root") and perms != "admin":
             return 0
         if has_annotation(method, "mlist"):
@@ -273,6 +277,7 @@ def list_call_locked(method, userdesc, perms, mlist, edit, *arg):
         mlist.Unlock()
         return ret
     except Exception, e:
+        traceback.print_exc(file=sys.stderr)
         sys.stderr.write('Exception in locked call %s: %s\n' % (method.__name__, str(e)))
         mlist.Unlock()
         return 0
@@ -297,7 +302,7 @@ def get_list_info(userdesc, perms, mlist, front_page=0):
         if not is_member and (mlist.subscribe_policy > 1):
             is_pending = list_call_locked(is_subscription_pending, userdesc, perms, mlist, False)
             if is_pending is 0:
-                return 0
+                return None
 
         host = mlist.internal_name().split(VHOST_SEP)[0].lower()
         details = {
@@ -413,7 +418,11 @@ def get_members(userdesc, perms, mlist):
     """ List the members of a list.
             @mlist
     """
-    details, members = get_list_info(userdesc, perms, mlist)
+    infos = get_list_info(userdesc, perms, mlist)
+    if infos is None:
+        # Do not return None, this is not serializable
+        return 0
+    details, members = infos
     members.sort()
     members = map(lambda member: (get_name(member), member), members)
     return (details, members, mlist.owner)
@@ -458,6 +467,10 @@ def mass_subscribe(userdesc, perms, mlist, users):
             @edit
             @admin
     """
+    if isinstance(users, dict):
+        users = users.values()
+    if not isinstance(users, list):
+        raise Exception("userlist must be a list")
     members = mlist.getRegularMemberKeys()
     added = []
     for user in users:
@@ -560,6 +573,11 @@ def handle_request(userdesc, perms, mlist, id, value, comment):
             @edit
             @admin
     """
+    # Force encoding to mailman's default for french, since this is what
+    # Mailman will use internally
+    # LC_DESCRIPTIONS is a dict of lang => (name, charset, direction) tuples.
+    encoding = mm_cfg.LC_DESCRIPTIONS['fr'][1]
+    comment = comment.encode(encoding, 'replace')
     mlist.HandleRequest(int(id), int(value), comment)
     return 1
 
@@ -879,14 +897,18 @@ def create_list(userdesc, perms, vhost, listname, desc, advertise, modlevel, ins
     """
     name = vhost.lower() + VHOST_SEP + listname.lower();
     if Utils.list_exists(name):
+        print >> sys.stderr, "List ", name, " already exists"
         return 0
 
     owner = []
     for o in owners:
-        email = to_forlife(o)[0]
+        email = to_forlife(o)
+        print >> sys.stderr, "owner in list", o, email
+        email = email[0]
         if email is not None:
             owner.append(email)
     if len(owner) is 0:
+        print >> sys.stderr, "No owner found in ", owners
         return 0
 
     mlist = MailList.MailList()