"Fossies" - the Fresh Open Source Software Archive

Member "revelation-0.5.4/src/lib/datahandler/csvfile.py" (4 Oct 2020, 6121 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 "csvfile.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 # Gergely Nagy <greg@gnome.hu>
    2 #
    3 from . import base
    4 from revelation import entry
    5 
    6 import time
    7 import csv
    8 from io import StringIO
    9 
   10 
   11 class CSV(base.DataHandler):
   12     "Data handler for CSV files"
   13 
   14     name        = "Comma Separated Values (CSV)"
   15     importer    = False
   16     exporter    = True
   17     encryption  = False
   18 
   19     def __init__(self):
   20         base.DataHandler.__init__(self)
   21 
   22     def export_data(self, entrystore, password = None):
   23         "Exports data to a CSV file"
   24 
   25         # fetch and sort entries
   26         entries = []
   27         iter = entrystore.iter_nth_child(None, 0)
   28 
   29         while iter is not None:
   30             e = entrystore.get_entry(iter)
   31 
   32             if type(e) != entry.FolderEntry:
   33                 entries.append(e)
   34 
   35             iter = entrystore.iter_traverse_next(iter)
   36 
   37 
   38 
   39         stringwriter = StringIO()
   40         csvwriter = csv.writer(stringwriter, dialect="excel")
   41 
   42         keys = set()
   43         for e in entries:
   44             for f in e.fields:
   45                 keys.add(f.name)
   46 
   47         # 'Email', 'Hostname', 'Password', 'URL', 'Username'
   48         keys = sorted(keys)
   49 
   50         csvwriter.writerow(['Name', 'Type', 'Description', 'Updated'] + keys)
   51 
   52         for e in entries:
   53 
   54             values = []
   55             for key in keys:
   56                 value = ''
   57                 for field in e.fields:
   58                     if key == field.name:
   59                         value = field.value
   60                 values.append(value)
   61 
   62             updated = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(e.updated))
   63             csvwriter.writerow([e.name, e.typename, e.description, updated] + values)
   64 
   65 
   66         return stringwriter.getvalue()
   67 
   68 
   69 class Bitwarden(base.DataHandler):
   70     "Data handler for Bitwarden Web Vault (CSV file)"
   71 
   72     name        = "Bitwarden Web Vault (CSV)"
   73     importer    = False
   74     exporter    = True
   75     encryption  = False
   76 
   77     bitwarden_csv_header_keys = [
   78         'folder',
   79         'favorite',
   80         'type',
   81         'name',
   82         'notes',
   83         'fields',
   84         'login_uri',
   85         'login_username',
   86         'login_password',
   87         'login_totp',
   88     ]
   89 
   90     # revelation type -> Bitwarden type
   91     type_mapping = {
   92         'Creditcard': 'note',  # Bitwarden type 'card' exists but seems unmanaged.
   93         'Crypto Key': 'login',
   94         'Database': 'login',
   95         'Door lock': 'note',
   96         'Email': 'login',
   97         'FTP': 'login',
   98         'Generic': 'login',
   99         'Phone': 'note',
  100         'Remote Desktop': 'login',
  101         'Shell': 'login',
  102         'VNC': 'login',
  103         'Website': 'login',
  104     }
  105 
  106     # revelation field -> Bitwarden field
  107     field_mapping = {
  108         'Name': 'name',
  109         'Type': 'type',
  110         'Description': 'notes',
  111         'Updated': 'notes',
  112         'CCV number': 'notes',
  113         'Card number': 'notes',
  114         'Card type': 'notes',
  115         'Certificate': 'notes',
  116         'Code': 'notes',
  117         'Database': 'notes',
  118         'Domain': 'notes',
  119         'Email': 'notes',
  120         'Expiry date': 'notes',
  121         'Hostname': 'login_uri',
  122         'Key File': 'notes',
  123         'Location': 'notes',
  124         'PIN': 'notes',
  125         'Password': 'login_password',
  126         'Phone number': 'notes',
  127         'Port number': 'notes',
  128         'URL': 'login_uri',
  129         'Username': 'login_username',
  130     }
  131 
  132     date_format = "%Y-%m-%d %H:%M:%S"
  133 
  134     def __init__(self):
  135         base.DataHandler.__init__(self)
  136 
  137     def export_data(self, entrystore, password = None):
  138         "Exports data to a Bitwarden CSV file"
  139 
  140         # fetch and sort entries
  141         entries = []
  142         iter = entrystore.iter_nth_child(None, 0)
  143 
  144         stringwriter = StringIO()
  145         csvwriter = csv.writer(stringwriter, dialect="excel")
  146         csvwriter.writerow(self.bitwarden_csv_header_keys)
  147 
  148         while iter is not None:
  149             e = entrystore.get_entry(iter)
  150 
  151             if type(e) != entry.FolderEntry:
  152                 # Find the directory path of this item.
  153                 path = ''
  154                 parent = entrystore.iter_parent(iter)
  155                 while parent:
  156                     path = entrystore.get_entry(parent).name + '/' + path
  157                     parent = entrystore.iter_parent(parent)
  158 
  159                 values = []
  160                 for key in self.bitwarden_csv_header_keys:
  161                     # Special fields
  162                     if key == 'folder':
  163                         values.append(path)
  164                         continue
  165                     if key == 'favorite':
  166                         values.append('')
  167                         continue
  168                     if key == 'name':
  169                         values.append(e.name)
  170                         continue
  171                     if key == 'type':
  172                         values.append(self.type_mapping[e.typename])
  173                         continue
  174 
  175                     value = ''
  176 
  177                     # Add export time as a note by default.
  178                     # Add e.description as a note.
  179                     # Add revelation updated time as a note.
  180                     if key == 'notes':
  181                         now = time.strftime(self.date_format, time.localtime())
  182                         updated = time.strftime(self.date_format, time.localtime(e.updated))
  183                         value += "Exported from Revelation on %s\n" % now
  184                         value += "Last Revelation Update: %s\n" % updated
  185                         if e.description:
  186                             value += "Description: %s\n" % e.description
  187                         if e.notes != '':
  188                             value += "Revelation Notes: %s\n" % e.notes
  189 
  190                     for field in e.fields:
  191                         if key == self.field_mapping[field.name]:
  192                             if self.field_mapping[field.name] == 'notes' and field.value:
  193                                 value += '%s: %s\n' % (field.name, field.value)
  194                             else:
  195                                 value += field.value
  196                     values.append(value)
  197 
  198                 csvwriter.writerow(values)
  199 
  200             iter = entrystore.iter_traverse_next(iter)
  201 
  202         return stringwriter.getvalue()