[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