#!/usr/bin/python
"""
Script to convert user accounts and aliases from vpopmail
to Postfix + MySQL setup. Actually just creates .sql inserts
in two files, users and aliases.

Only includes easily changeable variables for most common options
if you want to edit advanced options, or SQL table properties, go ahead
and search & change the lines in code, it's not too long.

Usage: 
	Change variables in top of the script and run it.

TODO:
	Add traversal of vpopmails sub domain directories (domains/[0-99])

Author: Joona Hoikkala, joona@kuori.org
"""
import dircache
import math
from sys import exit

# where to write errors on users...
error_filename = "/home/spectre/vpp/rrors.txt"

# where to find domains 
domain_basedir = "/home/vpopmail/domains"

# vpasswd filename
vpasswd_filename = "vpasswd"

# save resulting .sql as 
sql_user_filename = "/home/spectre/vpp//sql_users.sql"
sql_alias_filename = "/home/spectre/vpp/sql_alias.sql"

#sqlfh = open(sql_filename,'w')

class domainlist:
	def __init__(self, targetdir):
		dirlist = dircache.listdir(targetdir)
		dirlist = dirlist[:]
		dircache.annotate(targetdir,dirlist)
		self.nodes = dirlist
		self.directories = [i for i in self.nodes if i[-1] == '/']
		self.basedir = targetdir
		self._traversedirs_()

	def _traversedirs_(self):
		for i in self.directories:
			rows = self.parsevpasswd(self.basedir+"/"+i+vpasswd_filename)
			self._createsqllist_(rows,i[:-1])
			self._createaliaslist_(self.basedir+"/"+i,i[:-1])		

	def _createaliaslist_(self,dirpath,domain):
		adfh = open(sql_alias_filename,'a')
		dlist = dircache.listdir(dirpath)
		dlist = dlist[:]
		dircache.annotate(dirpath,dlist)
		for i in dlist:
			if i[:-1] == "/":
				continue
			elif i[:-1] == "~":
				continue
			elif i[0:7] != ".qmail-":
				continue

			aliasname = i[7:].replace(':','.')+"@"+domain
			alias_dest = self._readaliasfile_(dirpath+"/"+i)
			
			for i in alias_dest:
				s = "INSERT INTO alias (source, destination) VALUES('"+aliasname+"','"+i+"');\n"
				adfh.write(s)

		adfh.close()
	
	def _readaliasfile_(self,filepath):
		result = []
		afh = open(filepath,'r')
		for line in afh:
			line = line.rstrip('\n')
			if line[0] == "&":
				result.append(line[1:])
			elif line[0] == "/":
				rl = line.split('/')
				em = rl[-1]+"@"+rl[-2]
				result.append(em)
		afh.close()
		return result

	def _createsqllist_(self,vpwlist,domain):
		sql_usersfh = open(sql_user_filename,'a')
		for i in vpwlist:
			if (i[6] == "NOQUOTA"):
				quota = "0"
			else:
				quota = i[6]
			
			if (i.__len__ < 7 or i[7] == ""):
				errfh = open(error_filename,'a')
				errfh.write("Error processing user: "+i[1]+"@"+domain+" , no cleartext password\n")
				errfh.close()
				continue;
				
			if (i[0] == "postmaster"):
				self.postmaster = i[0]
				self.postmaster_pw = i[7]
				
			sqlstring = "INSERT INTO mailbox (username, password, name, maildir, quota, domain, created, modified, active)"+\
					"values('"+i[0]+"@"+domain+"',"+\
					"'"+i[7]+"',"+\
						"'"+i[4]+"',"+\
						"'"+domain+"/"+i[0]+"/',"+\
						"'3000',"+\
						"'"+domain+"',"+\
						"NOW(),"+\
						"NOW(),"+\
						"'1');\n"
			sql_usersfh.write(sqlstring)
						
                sqldomain = "INSERT INTO domain (domain, description, aliases, mailboxes, maxquota, transport,"+\
                            " backupmx, created, modified, active) values("+\
                            "'"+domain+"',"+\
                            "'"+domain+"',"+\
                            "'200',"+\
                            "'200',"+\
                            "'5000',"+\
                            "'virtual',"+\
                            "'0',"+\
                            "NOW(),"+\
                            "NOW(),"+\
                            "'1');\n"
		
		sqladmin = "INSERT INTO admin (username, password, created, modified, active) values("+\
			   "'"+self.postmaster+"@"+domain+"',"+\
			   "'"+self.postmaster_pw+"',"+\
			   "NOW(),"+\
			   "NOW(),"+\
			   "'1');\n"

		sqldomainadmin = "INSERT INTO domain_admins (username, domain, created, active) values("+\
				 "'"+self.postmaster+"@"+domain+"',"+\
				 "'"+domain+"',"+\
				 "NOW(),"+\
				 "'1');\n"
				 
		sql_usersfh.write(sqladmin)
		sql_usersfh.write(sqldomainadmin)
		sql_usersfh.write(sqldomain)
		sql_usersfh.close()

	def parsevpasswd(self,vpasswd_filename):
		vpwline = []
		try:
			vfh = open(vpasswd_filename,'r')
			
		except IOError:
			print "Sorry, file: "+vpasswd_filename+" could not be found or read, check permissions"
			exit(1)

		for line in vfh:
			line = line.rstrip('\n')
			vpwline.append(line.split(':'))
		
		vfh.close()
		return vpwline


taa = domainlist(domain_basedir)

