import 365
authorunknown <william.ngom@auf.org>
Fri, 25 Aug 2017 12:52:11 +0000 (08:52 -0400)
committerunknown <william.ngom@auf.org>
Fri, 25 Aug 2017 12:52:11 +0000 (08:52 -0400)
contact-import.ps1 [new file with mode: 0644]
convert_vcf.py [new file with mode: 0644]

diff --git a/contact-import.ps1 b/contact-import.ps1
new file mode 100644 (file)
index 0000000..68c8555
--- /dev/null
@@ -0,0 +1,15 @@
+
+
+param([string]$Path);
+$ContactLists = Get-ChildItem -Path $Path -Filter *.csv
+write-host ("== Importation des carnets d'adresse....")
+foreach ($ContactList in $ContactLists) {
+    #Save key-value pairs in a hashtable
+    $UserAccountName = $ContactList.Name.Split(" ")[0]
+    $UserContactFile = $Path + "\" +$ContactList.Name
+    #Get content
+    write-host ("==== Début importation compte : " + $UserAccountName + " / " + $UserContactFile)
+    Import-ContactList -CSV -CSVData ([System.IO.File]::ReadAllBytes($UserContactFile)) -Identity $UserAccountName
+    write-host ("==== Fin")
+}
+write-host ("== Fin d'importation des carnets d'adresse !")
\ No newline at end of file
diff --git a/convert_vcf.py b/convert_vcf.py
new file mode 100644 (file)
index 0000000..675f913
--- /dev/null
@@ -0,0 +1,502 @@
+#!/usr/bin/python2.5
+# coding: utf-8
+"""
+       Initial project
+
+       VcfToCsvConverter v0.3 - Converts VCF/VCARD files into CSV
+       Copyright (C) 2009 Petar Strinic (http://petarstrinic.com)
+       Contributor -- Dave Dartt
+
+       This program is free software: you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation, either version 3 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program.        If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+import os
+import re
+import sys
+import shutil
+import glob
+import codecs
+import mysql.connector
+from optparse import OptionParser, Option 
+
+config = {
+    'user': 'root',
+    'password': '',
+    'host': '127.0.0.1',
+    'database': 'auf',
+       'use_unicode' : 'True', 
+       'charset' : 'utf8'
+}
+
+class MyOption(Option):
+       ACTIONS = Option.ACTIONS + ("extend",)
+       STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
+       TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
+       ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
+       def take_action(self, action, dest, opt, value, values, parser):
+               if action == "extend":
+                       lvalue = value.split(",")
+                       values.ensure_value(dest, []).extend(lvalue)
+               else:
+                       Option.take_action(self, action, dest, opt, value, values, parser)
+
+class VcfToCsvConverter:
+       def __outputQuote(self):
+               if self.quote == True:
+                       self.output += '"'
+
+       def __output(self, text):
+               self.__outputQuote();
+               self.output += text
+               self.__outputQuote();
+               self.output += self.delimiter
+
+       def __trace(self, text):
+               if self.trace == True:
+                       print (text)
+
+       def __resetRow(self):
+               self.addressCount = { 'HOME' : 1, 'WORK' : 1 }
+               self.telephoneCount = { 'HOME PHONE' : 1, 'WORK PHONE' : 1, 'MOBILE PHONE' : 1, 'HOME FAX' : 1, 'WORK FAX' : 1 }
+               self.emailCount = { 'HOME' : 1, 'WORK' : 1 }
+               array = {}
+               for k in self.columns:
+                       array[ k ] = '';
+               return array
+
+       def __endLine(self):
+               for k in self.columns:
+                       try:
+                               self.__output(self.data[ k ])
+                       except KeyError:
+                               self.output += self.delimiter
+               self.output += "\r\n"
+               self.data = self.__resetRow()
+
+       def __getfilenames(self):
+               try:
+                       if os.path.isdir(self.inputPath):
+                               self.inputFileArray = glob.glob(os.path.join(self.inputPath, '*.vcf'))
+                       else:
+                               print ("Invalid path please try again")
+                               sys.exit(2)
+               except IOError:
+                       print ("Directory is empty or does not contain any vcard format files.")
+                       sys.exit(2)
+
+       def __parseFile(self):
+               self.__getfilenames()
+               outFile = codecs.open(self.outputFile, mode='w', encoding='utf-8')  
+               outFile.write(u'\ufeff')
+               
+               for NewFileName in self.inputFileArray:
+                       try:
+                               if self.verbose:
+                                       print ("Processing .... %s\n" % NewFileName)
+
+                               inFile = codecs.open(NewFileName, mode='r', encoding='utf-8')
+                               theLine = inFile.readline()
+                               for theLine in inFile:
+                                       self.__parseLine(theLine)
+
+                               inFile.close()
+                       except IOError:
+                               print ("error opening file during read operation via path: %s\n" % NewFileName)
+                               sys.exit(2)
+
+               outFile.write(self.output)      
+               outFile.close()
+
+       def __parseLine(self, theLine):
+               theLine = theLine.strip()
+               if len(theLine) < 1:
+                       pass
+               elif re.match('^BEGIN:VCARD', theLine):
+                       pass
+               elif re.match('^END:VCARD', theLine):
+                       self.__endLine()
+               else:
+                       self.__processLine(theLine.split(":"))
+                       self.data['URL'] = 'YO'
+
+       def __processLine(self, pieces):
+               
+               pre = pieces[0].split(";")
+               if re.match('item.*', pre[0].split(".")[0], re.I) != None:
+                       try:
+                               pre[0] = pre[0].split(".")[1]
+                       except IndexError:
+                               self.__trace("item pre0 split: %s " % pre[0].split("."));
+
+               if pre[0] == 'VERSION':
+                       pass
+               elif pre[0] == 'N':
+                       self.__processName(pre, pieces[1])
+               elif pre[0] == 'FN':
+                       pass
+               elif pre[0] == 'NICKNAME':
+                       self.__processSingleValue('NICKNAME', pre, pieces[1])
+               elif pre[0] == 'TITLE':
+                       self.__processSingleValue('TITLE', pre, pieces[1])
+               elif pre[0] == 'BDAY':
+                       self.__processSingleValue('BIRTHDAY', pre, pieces[1])
+               elif pre[0] == 'ORG':
+                       self.__processOrganization(pre, pieces[1])
+               elif pre[0] == 'ROLE':
+                       self.__processSingleValue('ROLE', pre, pieces[1])
+               elif pre[0] == 'GEO':
+                       self.__processSingleValue('GEOCODE', pre, pieces[1])
+               elif pre[0] == 'MAILER':
+                       pass
+               elif pre[0] == 'TZ':
+                       pass
+               elif pre[0] == 'ADR':
+                       self.__processAddress(pre, pieces[1])
+               elif pre[0] == 'LOGO':
+                       pass
+               elif pre[0] == 'PHOTO':
+                       pass
+               elif pre[0] == 'TEL':
+                       self.__processTelephone(pre, pieces[1:])
+               elif pre[0] == 'EMAIL':
+                       self.__processEmail(pre, pieces[1:])
+               elif pre[0] == 'AGENT':
+                       pass
+               elif pre[0] == 'NOTE':
+                       self.__processSingleValue('NOTE', pre, pieces[1])
+               elif pre[0] == 'REV':
+                       pass
+               elif pre[0] == 'URL':
+                       self.__processSingleValue('URL', pre, ":".join(pieces[1:]))
+               elif pre[0] == 'UID':
+                       pass
+               elif pre[0] == 'X-AIM':
+                       pass
+               elif pre[0] == 'X-ICQ':
+                       pass
+               elif pre[0] == 'X-JABBER':
+                       pass
+               elif pre[0] == 'X-MSN':
+                       pass
+               elif pre[0] == 'X-YAHOO':
+                       pass
+               elif pre[0] == 'X-SKYPE-USERNAME':
+                       pass
+               elif pre[0] == 'X-GADUGADU':
+                       pass
+               elif pre[0] == 'X-GROUPWISE':
+                       pass
+
+       def __processEmail(self, pre, p):
+               self.__trace("__processEmail: %s %s" % (pre, p))
+               hwm = "WORK"
+               #if (re.search('work',(",").join(pre[1:]), re.I) != None) :
+               #       hwm = "WORK"
+               self.__trace("__email type: %s" % hwm)
+               if self.emailCount[hwm] <= self.maxEmails:
+                       self.data["%s EMAIL %s" % (hwm, self.emailCount[hwm])] = p[0]
+                       self.__trace("__email %s %s: %s" % (hwm, self.emailCount[hwm], p[0]))
+                       
+                       self.emailCount[hwm] += 1
+               else:
+                       self.data['WARNING'] += ("Maximum number of %s emails reached, discarded: %s. " % (hwm, p[0]))
+
+       def __processTelephone(self, pre, p):
+               self.__trace("__processTelephone: %s %s" % (pre, p))
+               telephoneType = "PHONE"
+               hwm = "HOME"
+               if re.search('work',(",").join(pre[1:]), re.I) != None:
+                       hwm = "WORK"
+               elif re.search('cell',(",").join(pre[1:]), re.I) != None:
+                       hwm = "MOBILE"
+
+               if re.search('fax',(",").join(pre[1:]), re.I) != None:
+                       telephoneType = "FAX"
+
+               self.__trace("_telephone number = %s" % p[0])
+               self.__trace("_telephone type: %s" % "%s %s %s" % (hwm, telephoneType, self.telephoneCount["%s %s" % (hwm, telephoneType)]))
+
+               if self.telephoneCount[("%s PHONE" % hwm)] <= self.maxTelephones:
+                       self.data["%s %s %s" % (hwm, telephoneType, self.telephoneCount["%s %s" % (hwm, telephoneType)])] = p[0]
+                       self.telephoneCount["%s %s" % (hwm, telephoneType)] += 1
+               else:
+                       self.data['WARNING'] += ("Maximum number of %s telephones reached, discarded: %s. " % (hwm, p[0]))
+
+       def __processAddress(self, pre, p):
+               self.__trace("__processAddress: %s %s" % (pre, p))
+               self.__trace("_ADDRESS: %s" % (p))
+               try:
+                       (a, b, address, city, state, zip, country ) = p.split(";")
+               except ValueError:
+                       (a, b, address, city, state, zip ) = p.split(";")
+                       country = '';
+
+               addressType = "HOME"
+               try:
+                       (a,addressTypes) = pre[1].split("=");
+                       self.__trace("_addressTypes: %s " % addressTypes)
+                       if "work" in (addressTypes.lower()).split(","):
+                               self.__trace("_work address");
+                               addressType = "WORK"
+
+               except ValueError:
+                       self.__trace("_home address")
+
+               self.__trace(self.addressCount);
+               self.__trace(self.addressCount[addressType]);
+
+               if self.addressCount[addressType] <= self.maxAddresses:
+                       self.data["%s ADDRESS %s" % (addressType, self.addressCount[addressType])] = address
+                       self.data["%s CITY %s" % (addressType, self.addressCount[addressType])] = city
+                       self.data["%s STATE %s" % (addressType, self.addressCount[addressType])] = state
+                       self.data["%s ZIP %s" % (addressType, self.addressCount[addressType])] = zip
+                       self.data["%s COUNTRY %s" % (addressType, self.addressCount[addressType])] = country
+                       self.addressCount[addressType] += 1
+               else:
+                       self.data['WARNING'] += ("Maximum number of %s addresses reached, discarded: %s. " % (addressType, p))
+
+       def __processSingleValue(self, valueType, pre, p):
+               self.__trace("__processSingleValue: %s %s %s" % (valueType, pre, p))
+               self.__trace("_%s: %s" % (valueType,p))
+               if valueType == 'FORMATTED NAME':
+                       p = p.replace('\,', ' ')
+                       self.data[valueType] = p
+               if valueType == 'ORGANIZATION':
+                       self.data[valueType] = p.replace(';', '')                       
+               else:
+                       self.data[valueType] = p
+
+       def __processName(self, pre, p):
+               self.__trace("__processName: %s %s" % (pre, p))
+               p = p.replace('\,', ';')  
+               part = len(p.split(";"))
+               ln=fn=mi=pr=po= ''
+               if part==1:
+                       ln = p.split(";")
+               elif part==2:
+                       ( ln, fn ) = p.split(";")
+               elif part==3:
+                       ( ln, fn, mi) = p.split(";")
+               elif part==4:
+                       ( ln, fn, mi, pr) = p.split(";")
+               elif part>=5:
+                       ( ln, fn, mi, pr, po ) = p.split(";")
+
+               self.data['NAME PREFIX'] = pr
+               self.data['NAME FIRST'] = fn
+               self.data['NAME MIDDLE'] = mi
+               self.data['NAME LAST'] = ln
+               self.data['NAME POSTFIX'] = po
+       
+       def __processOrganization(self, pre, p):
+               part = len(p.split(";"))
+               company=office=departement= ''
+               if part==1:
+                       company = p.split(";")
+               elif part==2:
+                       ( company, office ) = p.split(";")
+               elif part>=3:
+                       ( company, office, departement) = p.split(";", 2)
+
+               self.data['ORGANIZATION'] = company
+               self.data['OFFICE LOCATION'] = office
+               self.data['DEPARTEMENT'] = departement
+
+       def __init__(self, inputFilePath, outputFileName, delimiter, quote, trace, verbose):
+               self.trace = trace
+               self.addressCount = { 'HOME' : 1, 'WORK' : 1 }
+               self.telephoneCount = { 'HOME PHONE' : 1, 'WORK PHONE' : 1, 'MOBILE PHONE' : 1, 'HOME FAX' : 1, 'WORK FAX' : 1 }
+               self.emailCount = { 'HOME' : 1, 'WORK' : 1 }
+               self.data = {}
+               self.verbose = verbose
+               self.quote = quote
+               self.delimiter = delimiter
+               self.output = ''
+               self.inputPath = inputFilePath
+               self.inputFileArray = None
+               self.outputFile = outputFileName
+               self.maxAddresses = 3
+               self.maxTelephones = 3
+               self.maxEmails = 3
+               self.columns = ( 
+                       'NAME PREFIX', 'NAME FIRST', 'NAME MIDDLE', 'NAME LAST','NAME POSTFIX', 'NICKNAME', 'BIRTHDAY',
+                       'ORGANIZATION', 'OFFICE LOCATION', 'DEPARTEMENT',
+                       'TITLE', 'ROLE', 
+                       'HOME ADDRESS 1', 'HOME CITY 1', 'HOME STATE 1', 'HOME ZIP 1', 'HOME COUNTRY 1',
+                       'HOME ADDRESS 2', 'HOME CITY 2', 'HOME STATE 2', 'HOME ZIP 2', 'HOME COUNTRY 2',
+                       'HOME ADDRESS 3', 'HOME CITY 3', 'HOME STATE 3', 'HOME ZIP 3', 'HOME COUNTRY 3',
+                       'WORK ADDRESS 1', 'WORK CITY 1', 'WORK STATE 1', 'WORK ZIP 1', 'WORK COUNTRY 1',
+                       'WORK ADDRESS 2', 'WORK CITY 2', 'WORK STATE 2', 'WORK ZIP 2', 'WORK COUNTRY 2',
+                       'WORK ADDRESS 3', 'WORK CITY 3', 'WORK STATE 3', 'WORK ZIP 3', 'WORK COUNTRY 3',
+                       'HOME PHONE 1', 'HOME PHONE 2', 'HOME PHONE 3',
+                       'WORK PHONE 1', 'WORK PHONE 2', 'WORK PHONE 3',
+                       'HOME FAX 1', 'HOME FAX 2', 'HOME FAX 3',
+                       'WORK FAX 1', 'WORK FAX 2', 'WORK FAX 3',
+                       'MOBILE PHONE 1', 'MOBILE PHONE 2', 'MOBILE PHONE 3',
+                       'HOME EMAIL 1', 'HOME EMAIL 2', 'HOME EMAIL 3',
+                       'WORK EMAIL 1', 'WORK EMAIL 2', 'WORK EMAIL 3',
+                       'NOTE', 'URL')
+               self.colums_map={
+                       'NAME PREFIX': 'Title',
+                       'NAME FIRST': 'First Name',
+                       'NAME MIDDLE': 'Middle Name',
+                       'NAME LAST': 'Last Name',
+                       'NAME POSTFIX': 'Suffix',
+                       'NICKNAME': 'Nickname',
+                       'BIRTHDAY': 'Birthday',
+                       'ORGANIZATION': 'Company',
+                       'ORGANIZATION': 'Department', 
+                       'OFFICE LOCATION': 'Office Location',
+                       'DEPARTEMENT': 'Departement',
+                       'TITLE': 'Job Title',
+                       'ROLE': 'Role',
+                       # Home Adress
+                       'HOME ADDRESS 1': 'Home Street',
+                       'HOME CITY 1': 'Home City',
+                       'HOME STATE 1': 'Home State',
+                       'HOME ZIP 1': 'Home Postal Code',
+                       'HOME COUNTRY 1': 'Home Country/Region',
+                       'HOME ADDRESS 2': 'Home Street 2',
+                       'HOME CITY 2': 'Home City 2',
+                       'HOME STATE 2': 'Home State 2',
+                       'HOME ZIP 2': 'Home Postal Code 2',
+                       'HOME COUNTRY 2': 'Home Country/Region 2',
+                       'HOME ADDRESS 3': 'Home Street 3',
+                       'HOME CITY 3': 'Home City 3',
+                       'HOME STATE 3': 'Home State 3',
+                       'HOME ZIP 3': 'Home Postal Code 3',
+                       'HOME COUNTRY 3': 'Home Country/Region 3',
+                       # Home Phone                    
+                       'HOME PHONE 1': 'Home Phone',
+                       'HOME PHONE 2': 'Home Phone 2',
+                       'HOME PHONE 3': 'Home Phone 3',
+                       # Home Fax      
+                       'HOME FAX 1': 'Home Fax',
+                       'HOME FAX 2': 'Home Fax 2',
+                       'HOME FAX 3': 'Home Fax 3',
+                       # Home Email    
+                       'HOME EMAIL 1': 'Home E-mail',
+                       'HOME EMAIL 2': 'Home E-mail 2',
+                       'HOME EMAIL 3': 'Home E-mail 3',
+                       # Business Adress
+                       'WORK ADDRESS 1': 'Business Street',
+                       'WORK CITY 1': 'Business City',
+                       'WORK STATE 1': 'Business State',
+                       'WORK ZIP 1': 'Business Postal Code',
+                       'WORK COUNTRY 1': 'Business Country/Region',
+                       'WORK ADDRESS 2': 'Business Street 2',
+                       'WORK CITY 2': 'Business City 2',
+                       'WORK STATE 2': 'Business State 2',
+                       'WORK ZIP 2': 'Business Postal Code 2',
+                       'WORK COUNTRY 2': 'Business Country/Region 2',
+                       'WORK ADDRESS 3': 'Business Street 3',
+                       'WORK CITY 3': 'Business City 3',
+                       'WORK STATE 3': 'Business State 3',
+                       'WORK ZIP 3': 'Business Postal Code 3',
+                       'WORK COUNTRY 3': 'Business Country/Region 3',
+                       # Business Phone        
+                       'WORK PHONE 1': 'Business Phone',
+                       'WORK PHONE 2': 'Business Phone 2',
+                       'WORK PHONE 3': 'Business Phone 3',
+                       # Business Fax                          
+                       'WORK FAX 1': 'Business Fax',
+                       'WORK FAX 2': 'Business Fax 2',
+                       'WORK FAX 3': 'Business Fax 3',
+                       # Business Email                                
+                       'WORK EMAIL 1': 'E-mail Address',
+                       'WORK EMAIL 2': 'E-mail 2 Address',
+                       'WORK EMAIL 3': 'E-mail 3 Address',
+                       # Mobile Phone                          
+                       'MOBILE PHONE 1': 'Mobile Phone',
+                       'MOBILE PHONE 2': 'Car Phone',
+                       'MOBILE PHONE 3': 'Other Phone',
+                       # Other         
+                       'NOTE': 'Notes',
+                       'URL': 'Personal Web Page'}
+
+               self.data = self.__resetRow()
+               for k in self.columns:
+                       self.__output(self.colums_map[k])
+
+               self.output += "\r\n"
+               self.__parseFile()
+
+
+
+def main():
+       usa = "usage: python ./%prog -p<pathname> -o<filename> -d<option> -q -v"
+       ver = "%prog v0.3.000 2009-11-25 - by Petar Strinic http://petarstrinic.com contributions of code snippets by Dave Dartt"
+       des = "This program was designed to take the information within a vcard and export it's contents to a csv file for easy import into other address book clients."
+       parser = OptionParser(option_class=MyOption, usage=usa, version=ver, description=des)
+       parser.add_option("-d", "--delim", action="store", dest="delimiter", default="\t", help="Delimiter to use: comma, semicolon, tab (default is tab)")
+       parser.add_option("-q", "--quote", action="store_true", dest="quote", default=False, help="Double quote the output strings (default is off)")
+       parser.add_option("-v", "--verbose", action="store_false", dest="verbose", default=True, help="Show processing information (default is on)")
+       parser.add_option("--trace", action="store_true", dest="trace", default=False, help="Displays a ton of debugging information.")
+       (options, args) = parser.parse_args()
+       
+       delimiter = options.delimiter
+       if options.delimiter == "comma":
+               delimiter = ","
+       elif options.delimiter == "semicolon":
+               delimiter = ";"
+
+       cnx =mysql.connector.connect(**config)
+       cursor = cnx.cursor()
+       query = ("SELECT c_folder_id, c_path, c_path1, c_path2, c_path3, c_path4, c_foldername,SUBSTRING_INDEX(c_location, '/', -1) FROM sogo_folder_info WHERE c_folder_type='Contact' and ( c_path2='pierre-richard.thomas' or c_path2='jean-christophe.andre' )") #  
+       cursor.execute(query)
+       groupe_contacts = cursor.fetchall()
+       for groupe_contact in groupe_contacts:
+               print(groupe_contact[7])
+               query = ("SELECT c_name, c_content FROM %s WHERE c_deleted IS NULL" % groupe_contact[7])
+
+               try:
+                       cursor.execute(query)
+                       contacts = cursor.fetchall()
+                       
+               except mysql.connector.Error as err:
+                       print("{}".format(err))
+                       continue
+
+               dir_name = '.'+groupe_contact[1]
+               dir_name = dir_name.replace('/Users','/SoGo/vcards')
+               if os.path.exists(dir_name):
+                       shutil.rmtree(dir_name)
+
+               os.makedirs(dir_name)
+
+               for contact in contacts:
+
+                       if contact[0][-4:]!='.vcf':
+                               file = open((dir_name+'/'+groupe_contact[3]+'-'+contact[0]+'.vcf'), mode='w', encoding='utf-8')
+                       else: 
+                               file = open((dir_name+'/'+groupe_contact[3]+'-'+contact[0]), mode='w', encoding='utf-8')
+
+                       file.write(contact[1]) 
+                       file.close()
+
+               contact_csv = './SoGo/'+groupe_contact[3]+'@auf.org '+groupe_contact[4]+' '+groupe_contact[6]+'.csv'
+               print(contact_csv)
+               print(dir_name)
+               VcfToCsvConverter(dir_name, contact_csv, delimiter, options.quote, options.trace, options.verbose)
+
+
+       cursor.close()
+       cnx.close()
+       sys.exit(0)
+
+
+if __name__ == "__main__":
+       main()
+