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