"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