"Fossies" - the Fresh Open Source Software Archive

Member "roundup-2.0.0/roundup/backends/sessions_rdbms.py" (26 Aug 2019, 4521 Bytes) of package /linux/www/roundup-2.0.0.tar.gz:


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. See also the latest Fossies "Diffs" side-by-side code changes report for "sessions_rdbms.py": 1.6.1_vs_2.0.0.

    1 """This module defines a very basic store that's used by the CGI interface
    2 to store session and one-time-key information.
    3 
    4 Yes, it's called "sessions" - because originally it only defined a session
    5 class. It's now also used for One Time Key handling too.
    6 """
    7 __docformat__ = 'restructuredtext'
    8 import os, time, logging
    9 
   10 from roundup.anypy.html import html_escape as escape
   11 
   12 class BasicDatabase:
   13     ''' Provide a nice encapsulation of an RDBMS table.
   14 
   15         Keys are id strings, values are automatically marshalled data.
   16     '''
   17     name = None
   18     def __init__(self, db):
   19         self.db = db
   20         self.conn, self.cursor = self.db.sql_open_connection()
   21 
   22     def clear(self):
   23         self.cursor.execute('delete from %ss'%self.name)
   24 
   25     def exists(self, infoid):
   26         n = self.name
   27         self.cursor.execute('select count(*) from %ss where %s_key=%s'%(n,
   28             n, self.db.arg), (infoid,))
   29         return int(self.cursor.fetchone()[0])
   30 
   31     _marker = []
   32     def get(self, infoid, value, default=_marker):
   33         n = self.name
   34         self.cursor.execute('select %s_value from %ss where %s_key=%s'%(n,
   35             n, n, self.db.arg), (infoid,))
   36         res = self.cursor.fetchone()
   37         if not res:
   38             if default != self._marker:
   39                 return default
   40             raise KeyError('No such %s "%s"'%(self.name, escape(infoid)))
   41         values = eval(res[0])
   42         return values.get(value, None)
   43 
   44     def getall(self, infoid):
   45         n = self.name
   46         self.cursor.execute('select %s_value from %ss where %s_key=%s'%(n,
   47             n, n, self.db.arg), (infoid,))
   48         res = self.cursor.fetchone()
   49         if not res:
   50             raise KeyError('No such %s "%s"'%(self.name, escape (infoid)))
   51         return eval(res[0])
   52 
   53     def set(self, infoid, **newvalues):
   54         """ Store all newvalues under key infoid with a timestamp in database.
   55 
   56             If newvalues['__timestamp'] exists and is representable as a floating point number
   57             (i.e. could be generated by time.time()), that value is used for the <name>_time
   58             column in the database.
   59         """
   60         c = self.cursor
   61         n = self.name
   62         a = self.db.arg
   63         c.execute('select %s_value from %ss where %s_key=%s'%(n, n, n, a),
   64             (infoid,))
   65         res = c.fetchone()
   66         if res:
   67             values = eval(res[0])
   68         else:
   69             values = {}
   70         values.update(newvalues)
   71 
   72         if res:
   73             sql = 'update %ss set %s_value=%s where %s_key=%s'%(n, n,
   74                 a, n, a)
   75             args = (repr(values), infoid)
   76         else:
   77             if '__timestamp' in newvalues:
   78                 try:
   79                     # __timestamp must be represntable as a float. Check it.
   80                     timestamp = float(newvalues['__timestamp'])
   81                 except ValueError:
   82                     timestamp = time.time()
   83             else:
   84                 timestamp = time.time()
   85 
   86             sql = 'insert into %ss (%s_key, %s_time, %s_value) '\
   87                 'values (%s, %s, %s)'%(n, n, n, n, a, a, a)
   88             args = (infoid, timestamp, repr(values))
   89         c.execute(sql, args)
   90 
   91     def list(self):
   92         c = self.cursor
   93         n = self.name
   94         c.execute('select %s_key from %ss'%(n, n))
   95         return [res[0] for res in c.fetchall()]
   96 
   97     def destroy(self, infoid):
   98         self.cursor.execute('delete from %ss where %s_key=%s'%(self.name,
   99             self.name, self.db.arg), (infoid,))
  100 
  101     def updateTimestamp(self, infoid):
  102         """ don't update every hit - once a minute should be OK """
  103         now = time.time()
  104         self.cursor.execute('''update %ss set %s_time=%s where %s_key=%s
  105             and %s_time < %s'''%(self.name, self.name, self.db.arg,
  106             self.name, self.db.arg, self.name, self.db.arg),
  107             (now, infoid, now-60))
  108 
  109     def clean(self):
  110         ''' Remove session records that haven't been used for a week. '''
  111         now = time.time()
  112         week = 60*60*24*7
  113         old = now - week
  114         self.cursor.execute('delete from %ss where %s_time < %s'%(self.name,
  115             self.name, self.db.arg), (old, ))
  116 
  117     def commit(self):
  118         logger = logging.getLogger('roundup.hyperdb.backend')
  119         logger.info('commit %s' % self.name)
  120         self.conn.commit()
  121         self.cursor = self.conn.cursor()
  122 
  123     def close(self):
  124         self.conn.close()
  125 
  126 class Sessions(BasicDatabase):
  127     name = 'session'
  128 
  129 class OneTimeKeys(BasicDatabase):
  130     name = 'otk'
  131 
  132 # vim: set et sts=4 sw=4 :