1
#! /usr/bin/env python 
2
import gobject
3
import tinymail
4
5
import os
6
7
from gobject import GObject
8
9
from xml.dom import minidom
10
from xml.dom import getDOMImplementation
11
from xml.parsers.expat import ExpatError
12
13
from tinymail import Account, AccountStore
14
from tinymail.camel import *
15
16
from nmdevice import NMDevice
17
18
accountFields = [
19
	'name',
20
	'secure_auth_mech',
21
	'proto',
22
	'user',
23
	'hostname',
24
	'port']
25
26
ACCOUNT_ELEMENT = 'account'
27
28
class XmlAccountStore(gobject.GObject, AccountStore):
29
	"""
30
	An implementation of the account store interface
31
	that uses XML to store the user accounts.
32
	"""
33
34
	def __init__(self, filename):
35
		GObject.__init__(self)
36
		self.__accounts = []
37
		self.next_id = 0
38
		self.cacheName = filename
39
		self.__device = NMDevice()
40
41
		self.__session = SessionCamel(self)
42
		self.__session.set_initialized()
43
44
		self.__load_cache()
45
	
46
	def do_get_accounts(self, list, types):
47
		store = False
48
		transport = False
49
		if types == tinymail.ACCOUNT_STORE_STORE_ACCOUNTS:
50
			store = True
51
		elif types == tinymail.ACCOUNT_STORE_TRANSPORT_ACCOUNTS:
52
			transport = True
53
		else:
54
			store = True
55
			transport = True
56
		for account in self.__accounts:
57
			if gobject.type_is_a(account.__gtype__, tinymail.StoreAccount) and store:
58
				list.append(account)
59
			elif gobject.type_is_a(account._gtype__, tinymail.TransportAccount) and transport:
60
				list.append(account)
61
62
	def do_get_cache_dir(self):
63
		return self.cacheName
64
65
	def do_get_device(self):
66
		return self.__device
67
68
	def do_find_account(selfi, urlString):
69
		for account in self.__accounts:
70
			if account.matches_url_string(urlString):
71
				return account
72
73
	def new_account(self, *args, **kwargs):
74
		account = None
75
		if 'proto' in kwargs:
76
			proto = kwargs['proto']
77
		else:
78
			proto = 'imap'
79
		if proto == 'imap':
80
			account = CamelIMAPStoreAccount() 
81
		elif proto == 'nntp':
82
			pass
83
		elif proto == 'pop':
84
			pass
85
		elif proto == 'smtp':
86
			pass
87
88
		if account:
89
			for key, element in kwargs.items():
90
				setMethod = getattr(account, 'set_%s' % key)
91
				setMethod(element)
92
			account.set_id('%s;%d' % (kwargs['name'], self.next_id))
93
			account.set_session(self.__session)
94
			self.next_id += 1
95
			self.__accounts.append(account)
96
97
	def __load_cache(self):
98
		try:
99
			self.xmlCache = minidom.parse(self.cacheName)
100
			top = self.xmlCache.documentElement
101
			accountElements = top.getElementsByTagName(ACCOUNT_ELEMENT)
102
			for element in accountElements:
103
				accountData = self.__load_account(element)
104
				self.new_account(self, **accountData)
105
		except (IOError, ExpatError):
106
			xmlImp = getDOMImplementation()
107
			self.xmlCache = xmlImp.createDocument(None, "Tinymail_Account_Cache", None)
108
109
	def write_cache(self):
110
		file = open(self.cacheName, 'w')
111
		top = self.xmlCache.documentElement
112
		for account in self.__accounts:
113
			self.__store_account(account, self.xmlCache, top)
114
		file.write(self.xmlCache.toxml())
115
116
	def __store_account(self, account, doc, node):
117
		accElement = doc.createElement(ACCOUNT_ELEMENT)
118
		for field in accountFields:
119
			element = doc.createElement(field)
120
			getMethod = getattr(account, "get_%s" % field)
121
			if getMethod:
122
				text = doc.createTextNode(str(getMethod()))
123
				element.appendChild(text)
124
			accElement.appendChild(element)
125
		node.appendChild(accElement)
126
127
	def __load_account(self, node):
128
		accountData = {}
129
		for field in accountFields:
130
			if field == 'port':
131
				elements = node.getElementsByTagName(field)
132
				if elements[0].firstChild:
133
					accountData[field] = int(elements[0].firstChild.data)
134
			else:
135
				elements = node.getElementsByTagName(field)
136
				if elements[0].firstChild:
137
					accountData[field] = elements[0].firstChild.data
138
		return accountData
139
140
gobject.type_register(XmlAccountStore)