Add provider plugins loader
[cascardo/ipsilon.git] / ipsilon / util / data.py
1 #!/usr/bin/python
2 #
3 # Copyright (C) 2013  Simo Sorce <simo@redhat.com>
4 #
5 # see file 'COPYING' for use and warranty information
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 import os
21 import sqlite3
22 import cherrypy
23
24
25 class Store(object):
26
27     def __init__(self, path=None):
28         if path is None:
29             self._path = os.getcwd()
30         else:
31             self._path = path
32         self._admin_dbname = self._get_admin_dbname()
33         self._user_dbname = self._get_userprefs_dbname()
34
35     def _get_admin_dbname(self):
36         path = None
37         if 'admin.config.db' in cherrypy.config:
38             path = cherrypy.config['admin.config.db']
39         if not path:
40             path = os.path.join(self._path, 'adminconfig.sqlite')
41         return path
42
43     def _get_userprefs_dbname(self):
44         path = None
45         if 'user.prefs.db' in cherrypy.config:
46             path = cherrypy.config['user.prefs.db']
47         if not path:
48             path = os.path.join(self._path, 'userprefs.sqlite')
49         return path
50
51     def _load_config(self, dbname):
52         con = None
53         rows = []
54         try:
55             con = sqlite3.connect(dbname)
56             cur = con.cursor()
57             cur.executescript("""
58                 CREATE TABLE IF NOT EXISTS config(name TEXT, value TEXT)
59                 """)
60             cur.execute("SELECT * FROM config")
61             rows = cur.fetchall()
62             con.commit()
63         except sqlite3.Error, e:
64             if con:
65                 con.rollback()
66             cherrypy.log.error("Failed to load config: [%s]" % e)
67         finally:
68             if con:
69                 con.close()
70
71         conf = {}
72         for row in rows:
73             if row[0] in conf:
74                 # multivalued
75                 if conf[row[0]] is list:
76                     conf[row[0]].append(row[1])
77                 else:
78                     v = conf[row[0]]
79                     conf[row[0]] = [v, row[1]]
80             else:
81                 conf[row[0]] = row[1]
82
83         return conf
84
85     def get_admin_config(self):
86         return self._load_config(self._admin_dbname)
87
88     def _load_user_prefs(self, dbname, user):
89         con = None
90         rows = []
91         try:
92             con = sqlite3.connect(dbname)
93             cur = con.cursor()
94             cur.executescript("""
95                 CREATE TABLE IF NOT EXISTS users(name TEXT,
96                                                  option TEXT,
97                                                  value TEXT)
98                 """)
99             cur.execute("SELECT option, value FROM users "
100                         "where name = '%s'" % user)
101             rows = cur.fetchall()
102             con.commit()
103         except sqlite3.Error, e:
104             if con:
105                 con.rollback()
106             cherrypy.log.error("Failed to load %s's prefs from "
107                                "%s: [%s]" % (user, dbname, e))
108         finally:
109             if con:
110                 con.close()
111
112         conf = {}
113         for row in rows:
114             conf[row[0]] = row[1]
115
116         return conf
117
118     def get_user_preferences(self, user):
119         return self._load_user_prefs(self._user_dbname, user)
120
121     def get_plugins_config(self, facility):
122         con = None
123         rows = []
124         try:
125             con = sqlite3.connect(self._admin_dbname)
126             cur = con.cursor()
127             cur.execute("CREATE TABLE IF NOT EXISTS " +
128                         facility + " (name TEXT,option TEXT,value TEXT)")
129             cur.execute("SELECT * FROM " + facility)
130             rows = cur.fetchall()
131             con.commit()
132         except sqlite3.Error, e:
133             if con:
134                 con.rollback()
135             cherrypy.log.error("Failed to load %s config: [%s]" % (facility,
136                                                                    e))
137         finally:
138             if con:
139                 con.close()
140
141         lpo = []
142         plco = dict()
143         for row in rows:
144             if row[0] == 'global':
145                 if row[1] == 'order':
146                     lpo = row[2].split(',')
147                 continue
148             if row[0] not in plco:
149                 # one dict per provider
150                 plco[row[0]] = dict()
151
152             conf = plco[row[0]]
153             if row[1] in conf:
154                 if conf[row[1]] is list:
155                     conf[row[1]].append(row[2])
156                 else:
157                     v = conf[row[1]]
158                     conf[row[1]] = [v, row[2]]
159             else:
160                 conf[row[1]] = row[2]
161
162         return (lpo, plco)
163
164     def save_plugin_config(self, facility, plugin, options):
165         SELECT = "SELECT option, value FROM %s WHERE name=?" % facility
166         UPDATE = "UPDATE %s SET value=? WHERE name=? AND option=?" % facility
167         INSERT = "INSERT INTO %s VALUES(?,?,?)" % facility
168         con = None
169         try:
170             con = sqlite3.connect(self._admin_dbname)
171             cur = con.cursor()
172             curvals = dict()
173             for row in cur.execute(SELECT, (plugin,)):
174                 curvals[row[0]] = row[1]
175
176             for name in options:
177                 if name in curvals:
178                     cur.execute(UPDATE, (options[name], plugin, name))
179                 else:
180                     cur.execute(INSERT, (plugin, name, options[name]))
181
182             con.commit()
183         except sqlite3.Error, e:
184             if con:
185                 con.rollback()
186             cherrypy.log.error("Failed to store config: [%s]" % e)
187             raise
188         finally:
189             if con:
190                 con.close()
191
192     def get_data(self, plugin):
193         con = None
194         rows = []
195         try:
196             con = sqlite3.connect(self._admin_dbname)
197             cur = con.cursor()
198             cur.execute("CREATE TABLE IF NOT EXISTS " +
199                         plugin + "_data (id INTEGER, name TEXT, value TEXT)")
200             cur.execute("SELECT * FROM " + plugin + "_data")
201             rows = cur.fetchall()
202             con.commit()
203         except sqlite3.Error, e:
204             if con:
205                 con.rollback()
206             cherrypy.log.error("Failed to load %s data: [%s]" % (plugin, e))
207         finally:
208             if con:
209                 con.close()
210
211         data = dict()
212         for row in rows:
213             if row[0] not in data:
214                 data[row[0]] = dict()
215
216             item = data[row[0]]
217             if row[1] in item:
218                 if item[row[1]] is list:
219                     item[row[1]].append(row[2])
220                 else:
221                     v = item[row[1]]
222                     item[row[1]] = [v, row[2]]
223             else:
224                 item[row[1]] = row[2]
225
226         return data
227
228     def save_data(self, plugin, data):
229         SELECT = "SELECT name, value FROM %s_data WHERE id=?" % plugin
230         UPDATE = "UPDATE %s_data SET value=? WHERE id=? AND name=?" % plugin
231         INSERT = "INSERT INTO %s_data VALUES(?,?,?)" % plugin
232         con = None
233         try:
234             con = sqlite3.connect(self._admin_dbname)
235             cur = con.cursor()
236             for idval in data:
237                 curvals = dict()
238                 for row in cur.execute(SELECT, (idval,)):
239                     curvals[row[0]] = row[1]
240
241                 datum = data[idval]
242                 for name in datum:
243                     if name in curvals:
244                         cur.execute(UPDATE, (datum[name], idval, name))
245                     else:
246                         cur.execute(INSERT, (idval, name, datum[name]))
247
248             con.commit()
249         except sqlite3.Error, e:
250             if con:
251                 con.rollback()
252             cherrypy.log.error("Failed to store %s data: [%s]" % (plugin, e))
253             raise
254         finally:
255             if con:
256                 con.close()