"Fossies" - the Fresh Open Source Software Archive 
Member "revelation-0.5.4/src/lib/io.py" (4 Oct 2020, 6031 Bytes) of package /linux/privat/revelation-0.5.4.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "io.py" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
0.5.3_vs_0.5.4.
1 #
2 # Revelation - a password manager for GNOME 2
3 # http://oss.codepoet.no/revelation/
4 # $Id$
5 #
6 # Module for IO-related functionality
7 #
8 #
9 # Copyright (c) 2003-2006 Erik Grinaker
10 #
11 # This program is free software; you can redistribute it and/or
12 # modify it under the terms of the GNU General Public License
13 # as published by the Free Software Foundation; either version 2
14 # of the License, or (at your option) any later version.
15 #
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
20 #
21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, write to the Free Software
23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #
25
26 from . import datahandler
27
28 import os.path, re
29 from gi.repository import Gio, GObject, GLib
30
31 class DataFile(GObject.GObject):
32 "Handles data files"
33
34 def __init__(self, handler):
35 GObject.GObject.__init__(self)
36
37 self.__uri = None
38 self.__handler = None
39 self.__password = None
40 self.__monitorhandle = None
41
42 self.set_handler(handler)
43
44
45 def __str__(self):
46 return self.get_file() or ""
47
48
49 def __cb_monitor(self, monitor_uri, info_uri, event, data = None):
50 "Callback for file monitoring"
51 if event == Gio.FileMonitorEvent.CHANGED:
52 self.emit("content-changed", self.get_file())
53
54
55 def __monitor(self, file):
56 "Starts monitoring a file"
57
58 self.__monitor_stop()
59
60 if file != None:
61 self.__monitorhandle = file_monitor(file, self.__cb_monitor)
62
63
64 def __monitor_stop(self):
65 "Stops monitoring the current file"
66
67 if self.__monitorhandle != None:
68 file_monitor_cancel(self.__monitorhandle)
69 self.__monitorhandle = None
70
71
72 def close(self):
73 "Closes the current file"
74
75 self.set_password(None)
76 self.set_file(None)
77
78
79 def get_file(self):
80 "Gets the current file"
81
82 return self.__uri and re.sub("^file://", "", str(self.__uri)) or None
83
84
85 def get_handler(self):
86 "Gets the current handler"
87
88 return self.__handler
89
90
91 def get_password(self):
92 "Gets the current password"
93
94 return self.__password
95
96
97 def load(self, file, password = None, pwgetter = None):
98 "Loads a file"
99
100 file = file_normpath(file)
101 data = file_read(file)
102
103 if self.__handler is None:
104 self.__handler = datahandler.detect_handler(data)()
105
106 self.__handler.check(data)
107
108 if self.__handler.encryption == True and password is None and pwgetter != None:
109 password = pwgetter()
110
111 entrystore = self.__handler.import_data(data, password)
112
113 self.set_password(password)
114 self.set_file(file)
115
116 return entrystore
117
118
119 def save(self, entrystore, file, password = None):
120 "Saves an entrystore to a file"
121
122 self.__monitor_stop()
123 file_write(file, self.__handler.export_data(entrystore, password))
124
125 # need to use idle_add() to avoid notifying about current save
126 GLib.idle_add(lambda: self.__monitor(file))
127
128 self.set_password(password)
129 self.set_file(file)
130
131
132 def set_file(self, file):
133 "Sets the current file"
134
135 uri = file is not None and file_normpath(file) or None
136
137 if self.__uri != uri:
138 self.__uri = uri
139 self.emit("changed", file)
140
141 self.__monitor(file)
142
143
144 def set_handler(self, handler):
145 "Sets and initializes the current data handler"
146
147 self.__handler = handler is not None and handler() or None
148
149
150 def set_password(self, password):
151 "Sets the password for the current file"
152
153 self.__password = password
154
155
156 GObject.type_register(DataFile)
157 GObject.signal_new("changed", DataFile, GObject.SignalFlags.ACTION,
158 GObject.TYPE_BOOLEAN, (str,))
159 GObject.signal_new("content-changed", DataFile, GObject.SignalFlags.ACTION,
160 GObject.TYPE_BOOLEAN, (str,))
161
162
163
164 def file_exists(file):
165 "Checks if a file exists"
166
167 if file is None:
168 return False
169
170 return Gio.File.new_for_path(file).query_exists()
171
172
173 def file_is_local(file):
174 "Checks if a file is on a local filesystem"
175
176 if file is None:
177 return False
178
179 return Gio.File.new_for_path(file).get_uri_scheme() == 'file'
180
181
182 def file_monitor(file, callback):
183 "Starts monitoring a file"
184
185 try:
186 handle = Gio.File.new_for_path(file).monitor_file(Gio.FileMonitorFlags.NONE, None)
187 handle.connect('changed', callback)
188 return handle
189 except GLib.GError:
190 return None
191
192
193 def file_monitor_cancel(handle):
194 "Cancels file monitoring"
195
196 handle.cancel()
197
198
199 def file_normpath(file):
200 "Normalizes a file path"
201
202 if file in ( None, "" ):
203 return ""
204
205 file = re.sub("^file:/{,2}", "", file)
206 file = os.path.expanduser(file)
207
208 if not re.match("^[a-zA-Z]+://", file) and file[0] != "/":
209 file = os.path.abspath(file)
210
211 # Does URI() do anything useful with the input? -thomas jenkins
212 #return re.sub("^file:/{,2}", "", str(gnomevfs.URI(file)))
213 return file
214
215
216 def file_read(file):
217 "Reads data from a file"
218
219 try:
220 if file is None:
221 raise IOError
222
223 ok, contents, etag = Gio.File.new_for_path(file).load_contents()
224 return contents
225
226 except GLib.GError:
227 raise IOError
228
229
230 def file_write(file, data):
231 "Writes data to file"
232
233 try:
234 if file is None:
235 raise IOError
236
237 if data is None:
238 data = ""
239
240 if isinstance(data, str):
241 data = data.encode()
242
243 ok, etag = Gio.File.new_for_path(file).replace_contents(data, None, True, Gio.FileCreateFlags.REPLACE_DESTINATION, None)
244 return ok
245
246 except GLib.GError:
247 raise IOError
248