#!/opt/osstech/bin/python2.7
# encoding: utf-8

# googleapps-emaillist-csvadd
# - Email list create to Google Apps by reading CSV file
# Copyright (C) TAKEDA Yasuma @ Open Source Solution Technology Co. Ltd.
#
# License: GNU General Public License version 2 or later
# Date: 2009-11-27, since 2008-10-21

import os, sys, csv, datetime, getopt, string

# from Google
import gdata.apps.service

# from OSSTech
import googleappsutils.domain

# Command Option
# -d domain name of Google Apps(Must)
# -f csv file (Must)
# -l directory of result file
# -s directory of summary file

# CSV Format
# |groupname|     |     |     |
# |group1   |user1|user2|user3|
# |group2   |user1|user2|

def usage():
    sys.stderr.write("Usage:" + sys.argv[0] + " -d <domain> -f <csvfile> [ -l <resultfile>] [-s <summaryfile>]\n")
    sys.exit(1)

def main():
    domain = None
    csvfile = None
    resultfile = None
    summaryfile = None

    # Parse options
    try:
        (opts, args) = getopt.getopt(sys.argv[1:], "d:f:l:s:")
    except getopt.GetoptError:
        sys.stderr.write("Error : Invalid Option\n")
        usage()

    for (opt, value) in opts:
        if opt == "-d":
            domain = value
        if opt == "-f":
            csvfile = value
        if opt == "-l":
            resultfile = value
        if opt == "-s":
            summaryfile = value

    if domain == None or csvfile == None:
        usage()
    
    # try to open csv file.
    try:
        csvFd = open(csvfile, 'r')
    except Exception, e:
        sys.stderr.write("Error : Failed to open csvfile.\n")
        sys.stderr.write(str(e) + "\n")
        sys.exit(1)

    # Read configuration of google
    gDomain = googleappsutils.domain.Domain()
    try:
        gDomain.readConfig(domain)
    except Exception, e:
        sys.stderr.write("Error : Invalid configuration [" + domain + "]\n")
        sys.stderr.write(str(e))
        sys.exit(1)

    # Setup result files
    type = "groupadd"
    now = datetime.datetime.now()    
    baseFileName = gDomain.getBaseFilename(now, type, domain)
    if resultfile == None:
        resultfile = gDomain.resultDir + baseFileName + "-result.csv"
    if summaryfile == None:
        summaryfile = gDomain.summaryDir + baseFileName + ".summary"

    try:
        resultFd = open(resultfile, "w")
        summaryFd = open(summaryfile, "w")
    except Exception, e:
        sys.stderr.write("Error : Failed to open file.\n")
        sys.stderr.write(str(e))
        sys.exit(1)

        # Read entries from csv file
    try:
        reader = csv.reader(csvFd)
    except Exception , e:
        sys.stderr.write("Error : Failed to read entry from csv file.\n")
        sys.stderr.write(str(e)+"\n")
        sys.exit(1)
    
    # Connect to Google Apps
    try:
        service = gdata.apps.service.AppsService(gDomain.admin,gDomain.adminPass, gDomain.domain)
        service.ProgrammaticLogin()
    except Exception, e:
        sys.stderr.write("Error : Failed to connect to Google Apps.\n" + str(e)+ "\n")
        sys.exit(1)



    # Handle eache entries
    r = 0 # counter of row. 0 is header
    header = []
    ml_handle = 0
    ml_error = 0
    ml_success = 0
    u_success = 0
    u_error = 0

    for row in reader:
        listname = ""
        noerror = True
        if len(row) == 0:
            # skip empty line
            continue
        if r == 0:
            # check col=0 is "groupname"
            r += 1
            n = 0
            for col in row:
                if n == 0:
                    if not col == "groupname":
                        sys.stderr.write("Error : groupname header entry is missing.\n")
                        sys.exit(1)
                n += 1
            
        else:
            r += 1
            ml_handle += 1            
            n = 0
            for col in row:
                if n == 0:
                    # create email list
                    created = False
                    groupname = col
                    try:
                        groupinfo = service.RetrieveEmailList(groupname)
                        resultFd.write("%s,ALready Exists\n" % groupname)
                    except gdata.apps.service.AppsForYourDomainException , e:
                        if e.error_code == 1301:
                            service.CreateEmailList(groupname)
                            resultFd.write("%s,OK\n" % groupname)
                            ml_success += 1
                        else:
                            resultFd.write("%s,%s\n" % (groupname, errstr.str(e.error_code)))
                            ml_error += 1
                    except:
                            resultFd.write("%s,%s\n" % (groupname, "unkown error"))
                            ml_error += 1
                else:
                    recipient = col
                    # Email Listにユーザーを登録
                    try:
                        if string.find(col, '@') >= 0:
                            recipient = col
                        else:
                            recipient = "%s@%s" % (col, gDomain.domain)
                        service.AddRecipientToEmailList(recipient, groupname)
                        u_success += 1
                        resultFd.write(" %s,OK\n" % recipient)
                    except gdata.apps.service.AppsForYourDomainException, e:
                        resultFd.write(" %s,%s\n" % (recipient, e.reason))
                        u_error += 1
                    except:
                        resultFd.write(" %s,%s\n" % (recipient, "unknown error"))
                        u_error += 1
                        
                n += 1


        resultFd.flush()
        r += 1
    # End of for loop

    # Create summary
    msg = "%d groups are handled.\n" % ml_handle
    summaryFd.write(msg)
    msg = "Success to create: %d group entries.\n" % ml_success
    summaryFd.write(msg)
    msg = "Fail to create: %d group entries.\n" % ml_error
    summaryFd.write(msg)
    msg = "Success to add: %d user entries.\n" % u_success
    summaryFd.write(msg)
    msg = "Fail to add: %d user entries.\n" % u_error
    summaryFd.write(msg)
    sys.exit(0)


main()
