"Fossies" - the Fresh Open Source Software Archive

Member "revelation-0.5.4/src/lib/datahandler/xhtml.py" (4 Oct 2020, 14561 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 "xhtml.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 exporting to XHTML files
    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 base
   27 from revelation import config, entry
   28 
   29 import gettext, time
   30 
   31 _ = gettext.gettext
   32 
   33 
   34 IMAGEPATH   = "https://revelation.olasagasti.info/static"
   35 
   36 
   37 class XHTML(base.DataHandler):
   38     "Data handler for XHTML export"
   39 
   40     name        = "XHTML / CSS"
   41     importer    = False
   42     exporter    = True
   43     encryption  = False
   44 
   45 
   46     def __init__(self):
   47         base.DataHandler.__init__(self)
   48 
   49 
   50     def __generate_css(self):
   51         "Generates a CSS for the XHTML document"
   52 
   53         css = """
   54         /* containers */
   55         body {
   56             margin: 20px 10px;
   57             padding: 0px;
   58 
   59             font-family: sans-serif;
   60             font-size: 10pt;
   61             line-height: 1.3;
   62 
   63             color: #333333;
   64             background-color: #ffffff;
   65         }
   66 
   67         div {
   68             margin: 0px;
   69             padding: 0px;
   70         }
   71 
   72         p {
   73             margin: 0px 0px 5px 0px;
   74             padding: 0px;
   75         }
   76 
   77         table {
   78             font-family: sans-serif;
   79             font-size: 10pt;
   80             line-height: 1.3;
   81 
   82             margin: 0px;
   83             border-collapse: collapse;
   84 
   85             color: #333333;
   86             background-color: transparent;
   87         }
   88 
   89         td {
   90             text-align: left;
   91             vertical-align: top;
   92         }
   93 
   94         th {
   95             text-align: left;
   96             vertical-align: top;
   97 
   98             font-weight: bold;
   99             color: #000000;
  100         }
  101 
  102 
  103 
  104         /* headings */
  105         h1, h2, h3 {
  106             margin: 0px;
  107             padding: 0px;
  108             line-height: 1;
  109             font-weight: bold;
  110             color: #000000;
  111         }
  112 
  113         h1 {
  114             margin-bottom: 20px;
  115             font-size: 16pt;
  116         }
  117 
  118         h2 {
  119             margin-bottom: 5px;
  120             font-size: 14pt;
  121         }
  122 
  123         h3 {
  124             font-size: 10pt;
  125         }
  126 
  127 
  128 
  129         /* content */
  130         a {
  131             color: #3333cc;
  132             text-decoration: none;
  133         }
  134 
  135         a:hover {
  136             text-decoration: underline;
  137         }
  138 
  139         img {
  140             margin: 0px;
  141             padding: 0px;
  142             border: none;
  143         }
  144 
  145         strong {
  146             color: #000000;
  147         }
  148 
  149 
  150 
  151         /* the content area */
  152         #content {
  153             margin-right: 220px;
  154         }
  155 
  156 
  157 
  158         /* the sidebar */
  159         #sidebar {
  160             width: 200px;
  161             float: right;
  162         }
  163 
  164         #sidebar h2 {
  165             margin: 20px 0px 10px 0px;
  166             padding: 0px 0px 5px 0px;
  167             border-bottom: 1px dashed #3366cc;
  168             text-transform: lowercase;
  169         }
  170 
  171         #sidebar h2 img.icon {
  172             width: 24px;
  173             height: 24px;
  174             margin-right: 5px;
  175             vertical-align: middle;
  176         }
  177 
  178         #sidebar h3 {
  179             margin-bottom: 2px;
  180             text-transform: lowercase;
  181         }
  182 
  183         #sidebar p {
  184             margin: 0px 5px 10px 15px;
  185         }
  186 
  187         #sidebar ul {
  188             list-style: none;
  189             padding: 0px;
  190             margin: 0px 0px 10px 0px;
  191         }
  192 
  193         #sidebar ul ul {
  194             margin: 0px 0px 0px 15px;
  195         }
  196 
  197         #sidebar ul.accountlist {
  198             margin-left: 15px;
  199         }
  200 
  201 
  202 
  203         /* the entrylist */
  204         #entrylist {
  205             width: 99%;
  206             padding: 0px;
  207             margin: 0px;
  208         }
  209 
  210 
  211 
  212         /* the footer */
  213         #footer {
  214             margin: 50px 220px 10px 0px;
  215             font-size: 8pt;
  216             text-align: center;
  217             color: #aaaaaa;
  218         }
  219 
  220         #footer a {
  221             color: #8888ee;
  222         }
  223 
  224 
  225 
  226         /* folders */
  227         li.folder {
  228             width: 100%;
  229             list-style-type: none;
  230         }
  231 
  232         li.folder .folder-data {
  233             margin: 0px 0px 10px 0px;
  234             padding: 2px 5px 3px 5px;
  235 
  236             border: 1px solid #3366cc;
  237             background-color: #e5ecf9;
  238         }
  239 
  240         li.folder .folder-data h2 {
  241             margin: 0px;
  242         }
  243 
  244         li.folder .folder-data p {
  245             margin: 0px;
  246         }
  247 
  248 
  249 
  250         /* accounts  */
  251         li.account {
  252             list-style-type: none;
  253             width: 350px;
  254             margin: 0px 0px 10px 0px;
  255             border: 1px solid #3366cc;
  256         }
  257 
  258         li.account .heading {
  259             padding: 2px 5px;
  260             background-color: #e5ecf9;
  261             border-bottom: 1px solid #3366cc;
  262         }
  263 
  264         li.account .heading h2 {
  265             margin: 0px 0px 1px 0px;
  266         }
  267 
  268         li.account .heading img {
  269             float: right;
  270             width: 24px;
  271             height: 24px;
  272         }
  273 
  274         li.account .heading .description {
  275             margin: 0px;
  276         }
  277 
  278         li.account .heading .type {
  279             color: #000000;
  280             font-weight: bold;
  281         }
  282 
  283         li.account .data {
  284             padding: 5px;
  285         }
  286 
  287         li.account .data .fields {
  288             margin: 0px 0px 3px 0px;
  289         }
  290 
  291         li.account .data .fields td {
  292             padding: 1px 0px;
  293         }
  294 
  295         li.account .data .fields th {
  296             padding: 1px 5px 1px 0px;
  297         }
  298 
  299         li.account .updated {
  300             font-size: 8pt;
  301             text-align: right;
  302             margin: 0px;
  303         }
  304 """
  305 
  306         return css
  307 
  308 
  309     def __generate_entry(self, entrystore, iter, depth = 0):
  310         "Generates xhtml for an entry"
  311 
  312         tabs = "\t" * (depth + 2)
  313         e = entrystore.get_entry(iter)
  314 
  315         if e is not None:
  316             e.path = self.__get_entryid(entrystore, iter)
  317 
  318 
  319         xhtml = ""
  320 
  321         if e is None:
  322 
  323             xhtml += "<div id=\"content\">\n"
  324             xhtml += "  <ul id=\"entrylist\">\n"
  325 
  326             for i in range(entrystore.iter_n_children(iter)):
  327                 child = entrystore.iter_nth_child(iter, i)
  328                 xhtml += self.__generate_entry(entrystore, child, depth)
  329 
  330             xhtml += "  </ul>\n"
  331             xhtml += "</div>\n"
  332 
  333 
  334         elif type(e) == entry.FolderEntry:
  335             xhtml += tabs + "<li class=\"folder\" id=\"%s\">\n" % e.path
  336             xhtml += tabs + "   <div class=\"folder-data\">\n"
  337             xhtml += tabs + "       <h2>%s</h2>\n" % e.name
  338 
  339             if e.description != "":
  340                 xhtml += tabs + "       <p class=\"description\">%s</p>\n" % e.description
  341 
  342             xhtml += tabs + "   </div>\n"
  343             xhtml += tabs + "\n"
  344             xhtml += tabs + "   <ul>\n"
  345 
  346             for i in range(entrystore.iter_n_children(iter)):
  347                 child = entrystore.iter_nth_child(iter, i)
  348                 xhtml += self.__generate_entry(entrystore, child, depth + 2)
  349 
  350             xhtml += tabs + "   </ul>\n"
  351             xhtml += tabs + "</li>\n"
  352             xhtml += tabs + "\n"
  353 
  354 
  355         else:
  356 
  357             xhtml += tabs + "<li class=\"account\" id=\"%s\">\n" % e.path
  358             xhtml += tabs + "   <div class=\"heading\">\n"
  359             xhtml += tabs + "       <img src=\"%s/entry/%s.png\" alt=\"%s\" />\n" % ( IMAGEPATH, e.id, e.typename )
  360             xhtml += tabs + "       <h2>%s</h2>\n" % e.name
  361             xhtml += tabs + "       <p class=\"description\"><span class=\"type\">%s</span>%s</p>\n" % ( e.typename + (e.description != "" and "; " or ""), e.description )
  362             xhtml += tabs + "   </div>\n"
  363             xhtml += tabs + "\n"
  364 
  365             xhtml += tabs + "   <div class=\"data\">\n"
  366 
  367             fields = []
  368             for field in e.fields:
  369                 if field.value != "":
  370                     fields.append(field)
  371 
  372             if len(fields) > 0:
  373                 xhtml += tabs + "       <table class=\"fields\">\n"
  374 
  375                 for field in fields:
  376                     xhtml += tabs + "           <tr>\n"
  377                     xhtml += tabs + "               <th>" + field.name + ":</th>\n"
  378                     xhtml += tabs + "               <td>" + field.value + "</td>\n"
  379                     xhtml += tabs + "           </tr>\n"
  380 
  381                 xhtml += tabs + "       </table>\n"
  382 
  383             xhtml += tabs + "       <p class=\"updated\">Updated " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(e.updated)) + "</p>\n"
  384             xhtml += tabs + "   </div>\n"
  385             xhtml += tabs + "</li>\n"
  386             xhtml += tabs + "\n"
  387 
  388         return xhtml
  389 
  390 
  391     def __generate_footer(self):
  392         "Generates an xhtml footer"
  393 
  394         xhtml = ""
  395         xhtml += "<div id=\"footer\">\n"
  396         xhtml += "  Generated by <a href=\"%s\">%s %s</a>" % ( config.URL, config.APPNAME, config.VERSION )
  397         xhtml += "</div>\n"
  398         xhtml += "</body>\n"
  399         xhtml += "</html>\n"
  400 
  401         return xhtml
  402 
  403 
  404     def __generate_header(self):
  405         "Generates an xhtml header"
  406 
  407         xhtml = ""
  408         xhtml += "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
  409         xhtml += "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
  410         xhtml += "<head>\n"
  411         xhtml += "  <title>Revelation account list</title>\n"
  412         xhtml += "  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\" />\n"
  413         xhtml += "\n"
  414         xhtml += "  <style type=\"text/css\">\n"
  415         xhtml += self.__generate_css()
  416         xhtml += "  </style>\n"
  417         xhtml += "</head>\n"
  418         xhtml += "\n"
  419         xhtml += "<body>\n"
  420         xhtml += "<h1>" + _('Revelation account list') + "</h1>\n"
  421         xhtml += "\n"
  422 
  423         return xhtml
  424 
  425 
  426     def __generate_sidebar(self, entrystore):
  427         "Generates a sidebar"
  428 
  429         xhtml = ""
  430         xhtml += "<div id=\"sidebar\">\n"
  431         xhtml += self.__generate_sidebar_fileinfo()
  432         xhtml += self.__generate_sidebar_foldertree(entrystore)
  433         xhtml += self.__generate_sidebar_accountlist(entrystore)
  434         xhtml += "</div>\n"
  435 
  436         return xhtml
  437 
  438 
  439     def __generate_sidebar_accountlist(self, entrystore):
  440         "Generates an account list"
  441 
  442         # find the entries
  443         entries = {}
  444         iter = entrystore.iter_nth_child(None, 0)
  445 
  446         while iter is not None:
  447             e = entrystore.get_entry(iter)
  448             e.path = self.__get_entryid(entrystore, iter)
  449 
  450             if type(e) != entry.FolderEntry:
  451                 if type(e) not in entries:
  452                     entries[type(e)] = []
  453 
  454                 entries[type(e)].append(e)
  455 
  456             iter = entrystore.iter_traverse_next(iter)
  457 
  458 
  459         # generate the xhtml
  460         xhtml = ""
  461         xhtml += (" <h2><img src=\"%s/sidebar/accountlist.png\" class=\"icon\" alt=\"Account list\" />" + _('Account list') + "</h2>\n") % IMAGEPATH
  462         xhtml += "\n"
  463 
  464         for entrytype in entry.ENTRYLIST:
  465             if entrytype not in entries:
  466                 continue
  467 
  468             xhtml += "  <h3>%s:</h3>\n" % entrytype().typename
  469             xhtml += "\n"
  470             xhtml += "  <ul class=\"accountlist\">\n"
  471 
  472             entrylist = entries[entrytype]
  473 
  474             for e in entrylist:
  475                 xhtml += "      <li><a href=\"#%s\">%s</a></li>\n" % ( str(e.path), e.name )
  476 
  477             xhtml += "  </ul>\n"
  478             xhtml += "\n"
  479 
  480         return xhtml
  481 
  482 
  483     def __generate_sidebar_fileinfo(self):
  484         "Generates file info for the sidebar"
  485 
  486         xhtml = ""
  487         xhtml += "  <h2 style=\"margin-top: 0px;\"><img src=\"%s/sidebar/file.png\" class=\"icon\" alt=\"File info\" />File info</h2>\n" % IMAGEPATH
  488         xhtml += "\n"
  489         xhtml += "  <h3>" + _('Created:') + "</h3>\n"
  490         xhtml += "  <p>%s</p>\n" % time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
  491         xhtml += "\n"
  492         xhtml += "  <h3>" + _('Revelation version:') + "</h3>\n"
  493         xhtml += "  <p>%s</p>\n" % config.VERSION
  494         xhtml += "\n"
  495 
  496         return xhtml
  497 
  498 
  499     def __generate_sidebar_foldertree(self, entrystore, parent = None, depth = 0):
  500         "Generates a folder tree for the sidebar"
  501 
  502         tabs = "\t" * ((depth * 2) - 2)
  503         xhtml = ""
  504 
  505         if parent is None:
  506             xhtml += "  <h2><img src=\"%s/sidebar/foldertree.png\" class=\"icon\" alt=\"Folder tree\" />Folder tree</h2>\n" % IMAGEPATH
  507             xhtml += "\n"
  508 
  509         # fetch folder list
  510         folders = []
  511         for i in range(entrystore.iter_n_children(parent)):
  512             iter = entrystore.iter_nth_child(parent, i)
  513             e = entrystore.get_entry(iter)
  514             e.path = self.__get_entryid(entrystore, iter)
  515             e.iter = iter
  516 
  517             if type(e) == entry.FolderEntry:
  518                 folders.append(e)
  519 
  520 
  521         # generate xhtml
  522         if len(folders) > 0:
  523             xhtml += tabs + "<ul>\n"
  524 
  525             for e in folders:
  526                 childxhtml = self.__generate_sidebar_foldertree(entrystore, e.iter, depth + 1)
  527 
  528                 if childxhtml != "":
  529                     xhtml += tabs + "   <li>\n"
  530                     xhtml += tabs + "       <a href=\"#%s\">%s</a>\n" % ( str(e.path), e.name )
  531                     xhtml += childxhtml
  532                     xhtml += tabs + "   </li>\n"
  533 
  534                 else:
  535                     xhtml += tabs + "   <li><a href=\"#%s\">%s</a></li>\n" % ( str(e.path), e.name )
  536 
  537             xhtml += tabs + "</ul>\n"
  538 
  539 
  540         return xhtml
  541 
  542 
  543     def __get_entryid(self, entrystore, iter):
  544         "Returns an entry id for an iter"
  545 
  546         path = "entry-"
  547 
  548         for i in entrystore.get_path(iter):
  549             path += str(i) + "-"
  550 
  551         path = path[:-1]
  552 
  553         return path
  554 
  555 
  556     def export_data(self, entrystore, password = None):
  557         "Exports data from an entrystore into a XHTML document"
  558 
  559         xhtml = ""
  560         xhtml += self.__generate_header()
  561         xhtml += self.__generate_sidebar(entrystore)
  562         xhtml += self.__generate_entry(entrystore, None)
  563         xhtml += self.__generate_footer()
  564 
  565         return xhtml
  566