[Python-modules-commits] r366 - in /packages/forgethtml: ./ branches/ branches/upstream/ branches/upstream/current/ branches/upstream/current/lib/ branches/upstream/current/lib/forgetHTML.py branches/upstream/current/lib/session.py branches/upstream/current/setup.py tags/

werner at users.alioth.debian.org werner at users.alioth.debian.org
Mon May 1 10:35:35 UTC 2006


Author: werner
Date: Mon May  1 10:35:28 2006
New Revision: 366

URL: http://svn.debian.org/wsvn/python-modules/?sc=1&rev=366
Log:
[svn-inject] Installing original source of forgethtml

Added:
    packages/forgethtml/
    packages/forgethtml/branches/
    packages/forgethtml/branches/upstream/
    packages/forgethtml/branches/upstream/current/
    packages/forgethtml/branches/upstream/current/lib/
    packages/forgethtml/branches/upstream/current/lib/forgetHTML.py
    packages/forgethtml/branches/upstream/current/lib/session.py
    packages/forgethtml/branches/upstream/current/setup.py
    packages/forgethtml/tags/

Added: packages/forgethtml/branches/upstream/current/lib/forgetHTML.py
URL: http://svn.debian.org/wsvn/python-modules/packages/forgethtml/branches/upstream/current/lib/forgetHTML.py?rev=366&op=file
==============================================================================
--- packages/forgethtml/branches/upstream/current/lib/forgetHTML.py (added)
+++ packages/forgethtml/branches/upstream/current/lib/forgetHTML.py Mon May  1 10:35:28 2006
@@ -1,0 +1,731 @@
+"""A totally object-oriented way of writing HTML. Each
+element is a object which may contain other HTML
+elements (ie. objects). Only those elements allowed
+in HTML to contain each other are allowed to be
+inserted.
+
+Print or str() or .output() the top (root) object
+to get the final HTML."""
+
+# $Id: forgetHTML.py,v 1.4 2003/10/08 15:03:58 stain Exp $
+#
+# (c) Stian Soiland <stain at nvg.org> 2001-2003
+# Licence: LGPL
+#
+# Last changes:
+# $Log: forgetHTML.py,v $
+# Revision 1.4  2003/10/08 15:03:58  stain
+# Dirty hack0rz.. allowing existing class for rows
+#
+# Revision 1.3  2003/09/11 22:37:51  stain
+# a new compare-function, let things be sorted
+#
+# A NonIndentMixin to prevent indention on certain
+# elements
+#
+# SimpleTable.add now supports TableCells, even with their own
+# colspan - this is done in a very dirty way, but prevents
+# expansion in these cases:
+#
+# t = SimpleTable()
+# t.add("Col1", "Col2")
+# t.add(html.TableCell("Both columns", colspan=2))
+#
+# Strong, Emphasis, Small, Big, Break added.
+#
+#
+# Textarea and Pre now don't indent by using NonIndentMixin.
+#
+# Revision 1.2  2003/06/25 11:45:37  stain
+# Added SimpleTable - a nice way to create a
+# description-list-type table (ie. with first row
+# or column as headers)
+#
+# TODO? Both row and column!
+#
+# Revision 1.1  2003/06/23 08:16:07  stain
+# now getitem (ie element['blapp']) would refer to attributes on item,
+# not retrieve subelements.
+#
+# Revision 1.1  2003/01/18 05:29:15  stain
+# First import from aapningstider.no
+#
+# Revision 1.5  2002/10/16 11:22:22  stain
+# wohoo
+#
+# Revision 1.4  2002/08/13 00:00:54  stain
+# Now without those stupid bugs.
+#
+# Revision 1.3  2002/08/11 22:22:36  stain
+#
+# Jay. Added two classes, QuickForm and SimpleDocument.
+# QuickForm is a nifty way of creating SIMPLE forms.
+#
+# SimpleDocument is a way of getting started with a document,
+# creating <head>, <body>, <title>, <h1> and optionnally a
+# stylesheet reference.
+#
+# Jah, and Label was added.
+#
+# Revision 1.2  2002/08/11 22:21:56  stain
+# Jay. Added two classes, QuickForm and SimpleDocument.
+#
+# QuickForm is a nifty way of creating SIMPLE forms.
+#
+# SimpleDocument is a way of getting started with a document,
+# creating <head>, <body>, <title>, <h1> and optionnally a
+# stylesheet reference.
+#
+# Revision 1.1  2002/07/18 23:12:02  stain
+# Akkai
+#
+# Revision 1.13  2001/11/07 01:49:47  stain
+# Støtte for å slå opp (rekursivt) id-tagger med element.get("id")
+# eller element["id"].
+#
+# Ie.
+#
+#   body = html.Body()
+#   div = html.Division(id="overskrift")
+#   body.append(div)
+#   body["overskrift"] == div
+#
+#   body["overskrift"].append(html.Header("Hei", id="blapp"))
+#
+#   body["blapp"].attributes["style"] = "align: right;"
+#
+# Blapp - bør gjerne skrives om til å bruke bredde-først-søk
+# istedet for dybde-først for effektivitetens skyld
+# (hvis man søker i et element man tror key-en ligger direkte
+# under), på den andre siden er dybde-først tilsvarende en
+# topp-til-bunn-søk i en flat HTML-fil.
+#
+# Revision 1.12  2001/04/07 10:39:32  stain
+# Header did not set level correct
+#
+# Revision 1.11  2001/04/06 19:37:20  stain
+# Formfields. Support for some stuff. stylesheet. Wraps attribute lists.
+#
+# Revision 1.10  2001/04/02 19:22:24  stain
+# Støtte for ruler <hr> og tittel <title>
+#
+# Revision 1.9  2001/03/20 23:22:26  stain
+# Small errors in indentation fixed.
+#
+# Protected methods should NOT be used for __define_*, as these
+# are called by superclass methods! Now uses _define_*.
+#
+# Use self._content instead of self.content to indicate this
+# is a 'privat' (but not protected) variable.
+#
+# Revision 1.8  2001/03/15 00:34:53  stain
+# Don't use __method__ anymore for private
+# methods, this was nasty. Using __method now.
+#
+# As well: raising ElementNotAllowed with
+# element.__class__.__name__ makes a much
+# nicer output.
+#
+# (Previous code printed out the HTML
+# of the object not allowed!)
+#
+# Revision 1.7  2001/03/13 23:01:29  stain
+# Added some nice meta information on top
+#
+# 
+
+# Note:
+#  + Only a few elements are supported at this time.
+#  + Currently all possible attributes are allowed
+#   (modify element.attributes or simply include them
+#    as keywords in constructor call)
+
+# Todo:
+# + Form elements!
+
+import exceptions, types
+
+indention = ' ' * 2  # Use two spaces for indention in HTML output
+
+class HTMLError(exceptions.Exception):
+  """General HTML error"""
+  def __str__(self):
+    args = exceptions.Exception.__str__(self) # Get our arguments
+    return self.__doc__ + ': ' + args
+
+class ElementNotAllowedError(HTMLError):
+  """Element not allowed"""
+  pass
+
+class AbstractClassError(HTMLError):
+  """Abstract class"""
+  pass
+
+class HeaderLevelOutOfRangeError(HTMLError):
+  """Header level out of range (1-6)"""
+  pass
+
+class Element:
+  tag = None # this would be 'p' for <p>, etc.
+  def __init__(self, *add, **attributes):
+    self._content = []
+    self.attributes = attributes # might be {} :=)
+    self.allowed_content = self._define_allowed()
+    self.default_child = self._define_default()
+    self.extend(add)
+
+    # _class means the class attribute. We need to 
+    # 'escape' this to avoid the Python keyword class
+    if(self.attributes.has_key('_class')):
+      # Rename it!
+      self['class'] = self['_class']
+      del self.attributes['_class']
+  def __cmp__(self, other):
+    # Sort (recursive) by content
+    if isinstance(other, Element):
+        return cmp(self._content, other._content)
+    else: 
+        return cmp(self._content, other)
+  def _define_allowed(self):
+    """Override this method to specify allowed content"""
+    return [Flow]     # list of classes of elements 
+    # The reason for using a seperate function for this
+    # is to make it possible to allow classes that have
+    # not yet been declared at the point of parsing
+  def _define_default(self):
+    """Override this method to specify an element
+    class wrapper to be tried if not matched by isallowed""" 
+    return None
+  def _check_abstract(self):   
+    """Checks if our class is capable of producing HTML"""
+    # If self.tag is not set, this is not a real
+    # HTML-element for use by append or __str__
+    if(self.tag == None): # we allow '' as a tag (used by Text)
+      raise AbstractClassError, self.__class__.__name__    
+  def __str__(self):
+    return self.output()
+  def output(self, indent=0):
+    # returns the HTML-formatted output, nicely indented
+    self._check_abstract()
+    result = indention * indent + '<' + self.tag
+    # Each attribute in the form key="value"
+    count = -1
+    for (attribute,value) in self.attributes.items():
+      count += 1
+      if(not count % 2 and count): # Not the first time!
+        result = result + '\n' + indention * indent + ' ' * (len(self.tag) + 1)
+      result = result + ' %s="%s"' % (attribute,value)
+    if(not self._content):
+      result = result + ' />\n' # No content!
+    else:
+      result = result + '>\n'
+      for element in self._content:
+        result = result + element.output(indent+1) # increased indent level
+        # end tag
+      result = result + indention * indent + '</' + self.tag + '>\n'
+    return result
+
+  def get(self, key):
+    """Finds a sub-element by it's id. Fun part: recursive! """
+    if(key == self.attributes.get('id')):
+      return self # simplest case
+    for item in self._content:
+      match = item.get(key)
+      if(match):
+        return match
+    return None # No match
+ 
+  def __getitem__(self, key):
+    return self.attributes.__getitem__(key)
+  def __setitem__(self, key, value):
+    self.attributes.__setitem__(key, value)
+    
+  def isallowed(self,element):
+    """Checks if the given given element is allowed within ourself"""
+    for allowed in self.allowed_content:
+      if(isinstance(element,allowed)):
+        return 1
+    return 0 # None of those allowed matched
+
+  def extend(self, list):
+    """Appends each element in the given list"""
+    for element in list:
+      self.append(element)
+    
+  def append(self, element):    
+    """Appends the given element within this element"""
+    self._check_abstract()
+    if(type(element) in (types.StringType, types.LongType, types.IntType, types.FloatType)):
+       # For easy adding of text and numbers, we make a text
+       #  element
+       element = Text(element)
+    if(not self.isallowed(element)):
+      if(type(self.default_child) == types.ClassType):
+        element = self.default_child(element) # No further checks
+      else:
+        raise ElementNotAllowedError, repr(element)
+    self._content.append(element)
+  
+  def set(self, element):
+    """Replaces the content with this new element, if it's allowed"""
+    old = self._content
+    self._content = []
+    try:
+      self.append(element)
+    except Exception, e:
+      self_content = old # Restore!
+      raise e
+
+class Document(Element):
+  tag = 'html'
+  def _define_allowed(self):
+    return [Head, Body]
+  def output(self, indent=0):
+    result = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+"""
+    return result + Element.output(self, indent)
+
+
+class Head(Element):
+  tag = 'head'
+  def _define_allowed(self):
+    return [HeadStuff]
+
+class HeadStuff(Element):
+  pass
+
+class Meta(HeadStuff):
+  tag = 'meta'
+  def _define_allowed(self):
+    return []
+
+class Link(HeadStuff):
+  tag = 'link'
+  def _define_allowed(self):
+    return []
+
+class NonIndentMixin:
+  def output(self, indent=0):
+    indent = -999
+    return Element.output(self, indent)
+
+# <link href="/stylesheet.css" rel="stylesheet" type="text/css" />
+
+class Stylesheet(Link):
+  def __init__(self, href, media=None):
+    if(media):
+      Link.__init__(self,
+              rel='stylesheet',
+              type='text/css',
+              href=href,
+              media=media)
+    else:
+      Link.__init__(self,
+              rel='stylesheet',
+              type='text/css',
+              href=href)
+
+class Title(HeadStuff):
+  tag = 'title'
+  def _define_allowed(self):
+    return [Text]
+
+class Body(Element):
+  tag = 'body'
+
+class Flow(Element):
+  pass
+
+class Block(Flow):
+  pass
+
+class Inline(Flow):
+  def _define_allowed(self):
+    return [Inline]
+
+class Text(Inline):
+  """Special class for plain text"""
+  tag = ''
+  def _define_allowed(self):
+    return []
+  def isallowed(self,element):
+    # Only strings and numbers are allowed. Unicode not supported (yet)
+    if(type(element) in (types.StringType, types.LongType, types.IntType, types.FloatType)):
+      return 1
+    else:
+      return 0
+  def get(self, key):
+    """Finds a sub-element by it's id. Fun part: recursive! """
+    if(key == self.attributes.get('id')):
+      return self # simplest case
+    else:
+      return None
+    # We don't want to search our _content
+  def append(self, element):
+    # Overriding this method is very important,
+    # otherwise Text('blapp') would loop forever :)
+    if(not self.isallowed(element)):
+      raise ElementNotAllowedError, element
+    self._content.append(element)
+  def output(self, indent=0):
+    result = ''
+    for line in self._content:
+      result = result + indention * indent + str(line) + '\n'
+      # Question: What would be the right thing to do here?
+      # Is it acceptable to allow several entries in self._content?
+      # Shoult they be seperated by ' ', '\n' or '' in output? 
+    return result
+
+class List(Block):
+  def _define_allowed(self):
+    return [ListItem]
+  def _define_default(self):
+    return ListItem
+  
+class UnorderedList(List):
+  tag = 'ul'
+
+class OrderedList(List):
+  tag = 'ol'
+
+class ListItem(Element):
+  tag = 'li'
+
+class Table(Block):
+  tag = 'table'
+  def _define_allowed(self):
+    return [TableRow]
+  def _define_default(self):
+    return TableRow
+  def extend2(self, lists):
+    """Inserts each array in lists as a row in the table"""
+    for list in lists:
+      row = TableRow()
+      row.extend(list)
+      self.append(row)
+
+class TableRow(Element):
+  tag = 'tr'
+  def _define_allowed(self):
+    return [TableCell]
+  def _define_default(self):
+    return TableCell
+
+class TableCell(Element):
+  tag = 'td'
+
+class TableHeader(TableCell):
+ tag = 'th'
+
+class SimpleTable(Table):
+    def __init__(self, header="column", *args, **kwargs):
+        """header -- "column" or "row"
+        if column, the first column will be indexed (TableHeader), 
+        if "row", the first row will be indexed.
+        if "both", both the first row and column will be indexed.
+        Anything else (like None) - no index"""
+        Table.__init__(self, *args, **kwargs)
+        self._items = []
+        self._width=0
+        self.header = header
+    def add(self, *args, **kwargs):
+        self._content = [] # reset html version because we changed..!
+        row = (kwargs,) + args
+        self._width = max(self._width, self._rowWidth(row))
+        rowWidth = self._rowWidth(row)
+        self._items.append(row)
+    def _getColSpan(self, cell):
+        # Eh.. we need to substract colspans.. 
+        if isinstance(cell, TableCell):
+            try:
+                # *cough* *cough*
+                colspan = cell['colspan']
+                colspan = int(colspan)
+                return colspan
+            except KeyError:
+                return 1
+            except ValueError:
+                return 1
+        return 1           
+    def _rowWidth(self, row):
+        rowWidth = 0
+        for cell in row[1:]:
+            rowWidth += self._getColSpan(cell)
+        return rowWidth    
+    def _extendRow(self, row):
+        """Extends a row if needed, but skip the kwargs in pos 0"""
+        rowWidth = self._rowWidth(row)
+        extendWidth = self._width - rowWidth
+        # skip first element, and extend
+        return list(row[1:]) + [''] * extendWidth
+        
+    def _generateContent(self):    
+        if not self._items:
+            pass
+        items = self._items
+        if self.header in ("row", "both"):
+            row=items.pop(0)
+            kwargs = row[0]
+            row = self._extendRow(row)
+            tablerow = TableRow(**kwargs)
+            self.append(tablerow)
+            pos = 0
+            for column in row:
+                cssClass = "col%s" % pos
+                if not isinstance(column, TableCell):
+                    column = TableHeader(column)
+                try:
+                    column['class'] = column['class'] + ' ' + cssClass
+                except KeyError:
+                    column['class'] = cssClass
+                tablerow.append(column)
+                pos += self._getColSpan(column)
+        even = True         
+        for row in items:
+            even = not even #ooo, flipz colorstylz
+
+            kwargs = row[0]
+            row = self._extendRow(row)
+            tablerow = TableRow(**kwargs)
+            try:
+                _class = tablerow['class'] + " "
+            except KeyError:
+                _class = ""
+            tablerow['class'] = _class + (even and 'even' or 'odd')
+            self.append(tablerow)
+            pos = 0
+            cssClass = "col%s" % pos
+            column = row[0]
+            if not isinstance(column, TableCell):
+                if self.header in ("column", "both"):
+                    column = TableHeader(column)
+                else:
+                    column = TableCell(column)
+            try:
+                column['class'] = column['class'] + ' ' + cssClass
+            except KeyError:   
+                column['class'] = cssClass
+            tablerow.append(column)    
+            pos += self._getColSpan(column)
+            for column in row[1:]:
+                cssClass = "col%s" % pos
+                if not isinstance(column, TableCell):
+                    column = TableCell(column)
+                try:
+                    column['class'] = column['class'] + ' ' + cssClass
+                except KeyError:   
+                    column['class'] = cssClass
+                tablerow.append(column)
+                pos += self._getColSpan(column)
+    def output(self, *args, **kwargs):
+        if not self._content:
+            self._generateContent()
+        return Table.output(self, *args, **kwargs)
+ 
+class Division(Block):
+  tag = 'div'
+
+class Span(Inline):
+  tag = 'span'
+
+class Strong(Inline):
+  tag = 'strong'
+
+class Emphasis(Inline):
+  tag = 'em'
+
+class Small(Inline):
+  tag = 'small'
+
+class Big(Inline):
+  tag = 'big'
+
+
+class Header(Block):
+  def _define_allowed(self):
+    return [Inline] 
+  def __init__(self, add=None, level=1, **kargs):
+    self.set_level(level)
+    if(add):
+      Block.__init__(self, add, **kargs)
+    else:
+      Block.__init__(self, **kargs)
+
+  def set_level(self, level):
+    if((level >= 1) and (level <= 6)):
+      self.level = level
+      self.tag = 'h' + str(self.level)
+    else:
+      raise HeaderLevelOutOfRangeError, level
+
+class Paragraph(Block): 
+  tag = 'p'
+  def _define_allowed(self):
+    return [Inline]
+
+class Pre(NonIndentMixin, Block): 
+  tag = 'pre'
+  def _define_allowed(self):
+    return [Inline]
+
+class Break(Inline):
+  tag = 'br'
+  def _define_allowed(self):
+    return []
+
+class Image(Inline):
+  tag = 'img'
+  def _define_allowed(self):
+    return []
+
+class Anchor(Inline):
+  tag = 'a'
+  def _define_allowed(self):
+    return [Inline]
+    
+
+class Ruler(Block):
+  tag = 'hr'
+  def _define_allowed(self):
+    return []
+
+class Form(Block):
+  tag = 'form'
+  def _define_allowed(self):
+    return [Flow]
+
+class Input(Inline):
+  tag = 'input'
+  def _define_allowed(self):
+    return []
+
+class Select(Inline):
+  tag = 'select'
+  def _define_allowed(self):
+    return [OptGroup, Option]
+
+class OptGroup(Element):
+  tag = 'optgroup'
+  def _define_allowed(self):
+    return [Option]
+
+class Option(Element):
+  tag = 'option'
+  def _define_allowed(self):
+    return [Text]
+
+class Submit(Input):
+  def __init__(self, value=None, *args, **kargs):
+    if(value <> None):
+      Input.__init__(self, type='submit', value=value, *args, **kargs)
+    else:
+      Input.__init__(self, type='submit', *args, **kargs)
+
+class Checkbox(Input):
+  def __init__(self, *args, **kargs):
+    Input.__init__(self, type='checkbox',  *args, **kargs)
+
+class Radiobutton(Input):
+  def __init__(self, *args, **kargs):
+    Input.__init__(self, type='radiobutton',  *args, **kargs)
+
+class Textfield(Input):
+  def __init__(self, *args, **kargs):
+    Input.__init__(self, type='text',  *args, **kargs)
+
+class Hidden(Input):
+  def __init__(self, *args, **kargs):
+    Input.__init__(self, type='hidden',  *args, **kargs)
+
+class Textarea(Inline, NonIndentMixin):
+  tag = 'textarea'
+
+class Label(Inline):
+  tag = 'label'
+  def _define_allowed(self):
+    return [Inline]
+
+class SimpleDocument(Document):
+  """A handy default document with a title and
+  optionally a specified external stylesheet. You
+  may change the title or stylesheet later on using
+  the methods setTitle() and setStylesheet()."""
+  def __init__(self, title=None, stylesheet=None):
+    Document.__init__(self)
+    self.head = Head()
+    self.body = Body()
+    self.append(self.head)
+    self.append(self.body)
+    self.title = None
+    self.header = None
+    self.stylesheet = None
+    if(title):
+      self.setTitle(title)
+    if(stylesheet):
+      self.setStylesheet(stylesheet)
+
+  def setTitle(self, title):   
+    if not self.title:
+      self.title = Title()
+      self.head.append(self.title)
+    if not self.header:
+      self.header = Header()
+      self.body.append(self.header)
+    self.title.set(title)
+    self.header.set(title)
+
+  def setStylesheet(self, url):
+    if not self.stylesheet:
+      self.stylesheet = Stylesheet(url)
+      self.head.append(self.stylesheet)
+    self.stylesheet['href'] = url  
+
+class SimpleForm(Form):
+  """A simple way to create an easy form. 
+
+  form = SimpleForm()
+  form.addText('firstname', 'First name', 'John')
+  form.addText('lastname', 'Last name')
+  choices = [
+    ('red', 'Red color'),
+    ('blue', 'Blue color'),
+    ('green', 'Greenish color')
+  ]
+  form.addChoices('color', choices, 'Select a color',
+                  'red')
+  """
+  
+  def __init__(self, **kwargs):
+    Form.__init__(self, **kwargs)
+  def addText(self, id, description=None, value=None):
+    """Adds a textfield, optionallly with a label."""
+    div = Division()
+    self.append(div)
+    if(description):
+      label = Label(description)
+      label['for'] = id
+      div.append(label)
+    if(value):
+      div.append(Textfield(id=id, name=id, value=value))
+    else:  
+      div.append(Textfield(id=id, name=id))
+  def addChoices(self, id, choices, description=None, 
+                 default=None):
+    """Adds a selection box for the given choices.
+    Note that the choices parameter must be a sequence of 
+    bi-tupples (key, description).
+    """
+    div = Division()
+    self.append(div)
+    label = Label(description)
+    label['for'] = id
+    select = Select(id=id, name=id)
+    for (key, desc) in choices:
+      option = Option(desc, id=key, value=key)
+      if(key == default):
+        option['selected'] = 'selected'
+      select.append(option)
+    div.append(label)
+    div.append(select)
+

Added: packages/forgethtml/branches/upstream/current/lib/session.py
URL: http://svn.debian.org/wsvn/python-modules/packages/forgethtml/branches/upstream/current/lib/session.py?rev=366&op=file
==============================================================================
--- packages/forgethtml/branches/upstream/current/lib/session.py (added)
+++ packages/forgethtml/branches/upstream/current/lib/session.py Mon May  1 10:35:28 2006
@@ -1,0 +1,138 @@
+"""A server-side module for «sessions» in HTTP/HTTPS by
+giving/getting a magic cookie from the browser, which
+is simply a reference to a local data storage."""
+
+# $Id: session.py,v 1.1 2003/01/18 05:29:16 stain Exp $
+#
+# Strongly inspired by PHP4's sessions.
+# (c) Stian Soiland <stain at nvg.org> 2001
+# Licence: LGPL
+#
+# Last changes:
+# $Log: session.py,v $
+# Revision 1.1  2003/01/18 05:29:16  stain
+# First import from aapningstider.no
+#
+# Revision 1.1  2002/07/18 23:12:02  stain
+# Akkai
+#
+# Revision 1.6  2002/04/08 01:58:54  stain
+# I couldn't sleep and for some reason decided to change this module's
+# ID-generation method. It's a bit easier then just lying in the dark
+# thinking about girl problems.
+#
+#
+# New method:
+#
+# Chooses 20 random characters from the readable part of the 7-bit ascii,
+# ie, from chr(32) till chr(126) inclusive.
+#
+# This yields approximately 2**128 variations.  Actually it yields 95**20
+# == 3584859224085422343574104404449462890625 ~= 2**131 variations.
+#
+# This of course is based on a 'perfect' random generator, which we don't
+# have. Note that the basic idea is to have a ID that is hard to guess. If
+# you have a system with 2**64 different sessions registered (unthinkable!
+# Calculate the number!) - an attacker would need to do 2**64
+#
+# (??? Shouldn't this number be calculated in a bit trickier way?)
+#
+# connection attempts in order to retrieve an usable ID
+# - and then he still wouldn't have any way to decide which ID to
+#   retrieve.
+#
+#
+# Other suggestions: (involves uglier programming)
+#
+# Calculate a number 2L**128 large by selecting four integers at random,
+# putting them together by bitshifting 32, 64 and 96 bits and thereafter
+# adding/and-ing them together.
+#
+# Then - use as a string. (you would probably need to do C-stuff to do
+# this, bitshifting and adding letters with chr() would be STUPID), and
+# THEN again, convert to base64.
+#
+# This method would use more processing power, look stupider and uglier,
+# but would only use 4 random calls instead of 20. This could
+#
+#   a) Reduce total processing time if the randomizer is very CPU and/or
+#      hardware intensive
+#
+#   b) Reduce possible patterns caused by imperfect random generators, and
+#      thereby making the result 'more random'
+#
+# Revision 1.5  2001/04/10 00:11:08  stain
+# Support for expiration (ie. sessions stored between browser
+# instances)
+#
+# Revision 1.4  2001/04/06 19:36:38  stain
+# Noe er endret.
+#
+# Revision 1.3  2001/03/13 23:45:07  stain
+# Nå virker den.
+#
+# 
+
+# Todo:
+#   + Maybe check that the session does not exist already
+
+
+import Cookie,os,random,UserDict,pickle,time
+
+class Session(UserDict.UserDict):
+  def __init__(self, identifier=None, valid=None):
+    """Initializes a new session or restores the old one.
+    Identifier is used as the cookie name, and any integer
+    in 'valid' is the number of seconds the cookie should
+    be valid"""
+    UserDict.UserDict.__init__(self)
+
+    if(identifier):
+      self.identifier = identifier
+    else:
+      try:
+        self.identifier = os.environ['HTTP_HOST']
+      except:
+        self.identifier = "localhost"
+
+    self.cookie = Cookie.SimpleCookie()
+    try:
+      self.cookie.load(os.environ['HTTP_COOKIE'])
+      self.id = self.cookie[self.identifier].value
+      self.data = pickle.load(open('/tmp/py_session_' +
+                     self.identifier + '_' + self.id))
+    except: # Any kind of error forces a new session!
+      self.new_id()
+      self.new_session()
+    if(valid):
+      self.cookie[self.identifier]['expires'] = valid
+    print self.cookie.output()    
+
+  def __del__(self):
+    pickle.dump(self.data,
+          open('/tmp/py_session_' + self.identifier +
+             '_' + self.id, 'w'))
+
+  def new_id(self):
+    """Forces a new session id"""
+    choices = range(32,127) # the normal 7-bits ascii letters
+    key = ''
+    for char in range(20): # 20 chars, aprox 2**128 bits resolution
+      key = key + chr(random.choice(choices))
+   
+    self.id = key
+    self.cookie[self.identifier] = self.id
+
+  def new_session(self):
+    """Forces a blank session (reuse ID)"""
+    self.data = {}
+    
+
+
+
+
+
+
+
+
+

Added: packages/forgethtml/branches/upstream/current/setup.py
URL: http://svn.debian.org/wsvn/python-modules/packages/forgethtml/branches/upstream/current/setup.py?rev=366&op=file
==============================================================================
--- packages/forgethtml/branches/upstream/current/setup.py (added)
+++ packages/forgethtml/branches/upstream/current/setup.py Mon May  1 10:35:28 2006
@@ -1,0 +1,17 @@
+#!/usr/bin/env python
+
+from distutils.core import setup
+setup(name="forgetHTML",
+      version="0.8",
+      author="Stian Soiland",
+      author_email="stian at soiland.no",
+      url="http://forgethtml.sourceforge.net/",
+      license="LGPL",
+      description=
+"""forgetHTML is a Python module for writing HTML by building a tree from
+different classes, one pr. HTML element. This makes it possible to
+modify and create elements in a different order than they will end up in
+the final HTML output. """,
+      py_modules=['forgetHTML'],
+      package_dir = {'': 'lib'}
+     )




More information about the Python-modules-commits mailing list