Pulling in changes from skeleton
[multilist] / src / libspeichern.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 """
5 This file is part of Multilist.
6
7 Multilist 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 Multilist 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 Multilist.  If not, see <http://www.gnu.org/licenses/>.
19
20 Copyright (C) 2008 Christoph Würstle
21 """
22
23 from __future__ import with_statement
24
25 import sys
26 import os
27 import time
28 import sqlite3
29 import shelve
30 import string
31 import shutil
32 import logging
33
34 try:
35         _
36 except NameError:
37         _ = lambda x: x
38
39
40 _moduleLogger = logging.getLogger(__name__)
41
42
43 class Speichern(object):
44
45         def __init__(self):
46                 home_dir = os.path.expanduser('~')
47                 filename = os.path.join(home_dir, ".multilist.dat")
48                 self.d = shelve.open(filename)
49                 self.openDB()
50
51         def openDB(self):
52                 try:
53                         self.cur.close()
54                 except:
55                         pass
56                 try:
57                         self.conn.close()
58                 except:
59                         pass
60
61                 db = self.ladeDirekt("datenbank")
62                 if db == "":
63                         home_dir = os.path.expanduser('~')
64                         db = os.path.join(home_dir, "multilist.s3db")
65
66                 datum = time.strftime("%Y-%m-%d--", (time.localtime(time.time())))+str(int(time.time()))+"--"
67                 if os.path.exists(db) and os.path.exists(os.path.dirname(db)+os.sep+"backup"):
68                         try:
69                                 shutil.copyfile(db, str(os.path.dirname(db))+os.sep+"backup"+os.sep+datum+os.path.basename(db))
70                         except:
71                                 _moduleLogger.info("Achtung Backup-Datei NICHT (!!!) angelegt!")
72
73                 self.conn = sqlite3.connect(db)
74                 self.cur = self.conn.cursor()
75                 try:
76                         sql = "CREATE TABLE logtable (id INTEGER PRIMARY KEY AUTOINCREMENT, pcdatum INTEGER , sql TEXT, param TEXT, host TEXT, rowid TEXT)"
77                         self.cur.execute(sql)
78                         self.conn.commit()
79                 except:
80                         pass
81
82                 #Add rowid line (not in old versions included)
83                 try:
84                         sql = "ALTER TABLE logtable ADD rowid TEXT"
85                         self.cur.execute(sql)
86                         self.conn.commit()
87                 except:
88                         pass
89
90         def close(self):
91                 try:
92                         self.d.close()
93                 except:
94                         pass
95                 try:
96                         self.cur.close()
97                 except:
98                         pass
99                 try:
100                         self.conn.close()
101                 except:
102                         pass
103                 _moduleLogger.info("Alle Daten gespeichert")
104
105         def __del__(self):
106                 self.close()
107
108         def speichereDirekt(self, schluessel, daten):
109                 try:
110                         self.d[schluessel] = daten
111                 except ValueError:
112                         _moduleLogger.exception("Why oh why do we do this?")
113                 _moduleLogger.info("speichereDirekt "+str(schluessel)+" "+str(daten)+" lesen: "+str(self.d[schluessel]))
114
115         def ladeDirekt(self, schluessel, default = ""):
116                 try:
117                         if self.d.has_key(schluessel):
118                                 data = self.d[schluessel]
119                                 return data
120                         else:
121                                 return default
122                 except ValueError:
123                         _moduleLogger.exception(
124                                 "Why did '%s' cause the problem? (returning default '%s')" % (schluessel, default)
125                         )
126                         return default
127
128         def speichereSQL(self, sql, tupel = None, commit = True, host = "self", log = True, pcdatum = None, rowid = ""):
129                 try:
130                         programSQLError = True
131                         if tupel is None:
132                                 self.cur.execute(sql)
133                         else:
134                                 self.cur.execute(sql, tupel)
135                         programSQLError = False
136
137                         if log:
138                                 strtupel = []
139                                 if tupel is not None:
140                                         for t in tupel:
141                                                 strtupel.append(str(t))
142
143                                 if pcdatum is None:
144                                         pcdatum = int(time.time())
145                                 self.cur.execute("INSERT INTO logtable ( pcdatum, sql, param, host, rowid ) VALUES (?, ?, ?, ?, ?)", (pcdatum, sql, string.join(strtupel, " <<Tren-ner>> "), host, str(rowid) ))
146                         if commit:
147                                 self.conn.commit()
148                         return True
149                 except:
150                         s = str(sys.exc_info())
151                         if s.find(" already exists") == -1:
152                                 if programSQLError:
153                                         _moduleLogger.error("speichereSQL-Exception "+str(sys.exc_info())+" "+str(sql)+" "+str(tupel))
154                                 else:
155                                         _moduleLogger.error("speichereSQL-Exception in Logging!!!! :"+str(sys.exc_info())+" "+str(sql)+" "+str(tupel))
156                         return False
157
158         def commitSQL(self):
159                 self.conn.commit()
160
161         def ladeSQL(self, sql, tupel = None):
162                 try:
163                         if tupel is None:
164                                 self.cur.execute(sql)
165                         else:
166                                 self.cur.execute(sql, tupel)
167                         return self.cur.fetchall()
168                 except:
169                         _moduleLogger.error("ladeSQL-Exception "+str(sys.exc_info())+" "+str(sql)+" "+str(tupel))
170                         return ()
171
172         def ladeHistory(self, sql_condition, param_condition):
173                 sql = "SELECT * FROM logtable WHERE sql LIKE '%"+str(sql_condition)+"%' AND param LIKE '%"+str(param_condition)+"%'"
174                 rows = self.ladeSQL(sql)
175
176                 erg = []
177                 for row in rows:
178                         datum = time.strftime("%d.%m.%y %H:%M:%S", (time.localtime(row[1])))
179                         erg.append([row[1], datum, row[2], row[3], row[3].split(" <<Tren-ner>> ")])
180
181                 return erg
182
183         def delHistory(self, sql_condition, param_condition, exceptTheLastXSeconds = 0):
184                 pcdatum = int(time.time())-exceptTheLastXSeconds
185                 sql = "DELETE FROM logtable WHERE sql LIKE '%"+str(sql_condition)+"%' AND param LIKE '%"+str(param_condition)+"%' AND pcdatum<?"
186                 self.speichereSQL(sql, (pcdatum, ))
187
188         def delHistoryWithRowID(self, rowid, sql_condition = " ", exceptTheLastXSeconds = 0):
189                 pcdatum = int(time.time())-exceptTheLastXSeconds
190                 sql = "DELETE FROM logtable WHERE rowid = ? AND pcdatum<? AND sql LIKE '%"+str(sql_condition)+"%'"
191                 self.speichereSQL(sql, (rowid, pcdatum, ))