]> code.delx.au - pymsnt/blob - src/xdb.py
more tests.
[pymsnt] / src / xdb.py
1 # Copyright 2004-2005 James Bunton <james@delx.cjb.net>
2 # Licensed for distribution under the GPL version 2, check COPYING for details
3
4 import utils
5 if(utils.checkTwisted()):
6 from twisted.xish.domish import Element
7 else:
8 from tlib.domish import Element
9 from debug import LogEvent, INFO, WARN
10 import os
11 import os.path
12 import config
13 import legacy
14
15 SPOOL_UMASK = 0077
16
17
18 def unmangle(file):
19 chunks = file.split("%")
20 end = chunks.pop()
21 file = "%s@%s" % ("%".join(chunks), end)
22 return file
23
24 def mangle(jid):
25 return jid.replace("@", "%")
26
27
28 class XDB:
29 """
30 Class for storage of data.
31
32 Create one instance of the class for each XDB 'folder' you want.
33 Call request()/set() with the xdbns argument you wish to retrieve
34 """
35 def __init__(self, name, mangle=False):
36 """ Creates an XDB object. If mangle is True then any '@' signs in filenames will be changed to '%' """
37 self.name = os.path.abspath(config.spooldir) + '/' + name
38 if not os.path.exists(self.name):
39 os.makedirs(self.name)
40 self.mangle = mangle
41
42 def __getFile(self, file):
43 if(self.mangle):
44 file = mangle(file)
45
46 hash = file[0:2]
47 document = utils.parseFile(self.name + "/" + hash + "/" + file + ".xml")
48
49 return document
50
51 def __writeFile(self, file, text):
52 if(self.mangle):
53 file = mangle(file)
54
55 prev_umask = os.umask(SPOOL_UMASK)
56 hash = file[0:2]
57 pre = self.name + "/" + hash + "/"
58 if not os.path.exists(pre):
59 os.makedirs(pre)
60 f = open(pre + file + ".xml", "w")
61 f.write(text)
62 f.close()
63 os.umask(prev_umask)
64
65 def files(self):
66 """ Returns a list containing the files in the current XDB database """
67 files = []
68 for dir in os.listdir(self.name):
69 if(os.path.isdir(self.name + "/" + dir)):
70 files.extend(os.listdir(self.name + "/" + dir))
71 if self.mangle:
72 files = [unmangle(x)[:-4] for x in files]
73 else:
74 files = [x[:-4] for x in files]
75
76 while files.count(''):
77 files.remove('')
78
79 return files
80
81 def request(self, file, xdbns):
82 """ Requests a specific xdb namespace from the XDB 'file' """
83 try:
84 document = self.__getFile(file)
85 for child in document.elements():
86 if(child.getAttribute("xdbns") == xdbns):
87 return child
88 except:
89 return None
90
91 def set(self, file, xdbns, element):
92 """ Sets a specific xdb namespace in the XDB 'file' to element """
93 try:
94 element.attributes["xdbns"] = xdbns
95 document = None
96 try:
97 document = self.__getFile(file)
98 except IOError:
99 pass
100 if(not document):
101 document = Element((None, "xdb"))
102
103 # Remove the existing node (if any)
104 for child in document.elements():
105 if(child.getAttribute("xdbns") == xdbns):
106 document.children.remove(child)
107 # Add the new one
108 document.addChild(element)
109
110 self.__writeFile(file, document.toXml())
111 except IOError, e:
112 LogEvent(WARN, "", "IOError " + str(e))
113 raise
114
115 def remove(self, file):
116 """ Removes an XDB file """
117 file = self.name + "/" + file[0:2] + "/" + file + ".xml"
118 if(self.mangle):
119 file = mangle(file)
120 try:
121 os.remove(file)
122 except IOError, e:
123 LogEvent(WARN, "", "IOError " + str(e))
124 raise
125
126
127