Commit 14cbd55e authored by Jim Fulton's avatar Jim Fulton

new folderish control panel and product management

parent f400850a
#!/bin/env python
##############################################################################
#
# Copyright
#
# Copyright 1998 Digital Creations, Inc., 910 Princess Anne
# Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All
# rights reserved.
#
##############################################################################
__doc__='''Standard routines for handling Principia Extensions
Principia extensions currently include external methods and pluggable brains.
$Id: Extensions.py,v 1.1 1998/08/03 13:43:26 jim Exp $'''
__version__='$Revision: 1.1 $'[11:-2]
from string import find
import os, zlib, rotor
path_split=os.path.split
exists=os.path.exists
class FuncCode:
def __init__(self, f, im=0):
self.co_varnames=f.func_code.co_varnames[im:]
self.co_argcount=f.func_code.co_argcount-im
def __cmp__(self,other):
return cmp((self.co_argcount, self.co_varnames),
(other.co_argcount, other.co_varnames))
def getObject(module, name, reload=0, modules={}):
if modules.has_key(module):
old=modules[module]
if old.has_key(name) and not reload: return old[name]
else:
old=None
d,n = path_split(module)
if d: raise ValueError, (
'The file name, %s, should be a simple file name' % module)
m={}
d=find(n,'.')
if d > 0:
d,n=n[:d],n[d+1:]
n=("%s/lib/python/Products/%s/Extensions/%s.pyp"
% (SOFTWARE_HOME,d,n))
__traceback_info__=n, module
if exists(n):
data=zlib.decompress(
rotor.newrotor(d+' shshsh').decrypt(open(n).read())
)
exec compile(data,module,'exec') in m
else:
exec open("%s/Extensions/%s.py" %
(SOFTWARE_HOME, module)) in m
else:
exec open("%s/Extensions/%s.py" % (SOFTWARE_HOME, module)) in m
r=m[name]
if old:
for k, v in m.items(): old[k]=v
else: modules[module]=m
return r
class NoBrains: pass
def getBrain(module, class_name, reload=0):
'Check/load a class'
if not module and not class_name: return NoBrains
try: c=getObject(module, class_name, reload)
except KeyError, v:
if v == class_name: raise ValueError, (
'The class, %s, is not defined in file, %s' % (class_name, module))
if not hasattr(c,'__bases__'): raise ValueError, (
'%s, is not a class' % class_name)
return c
##############################################################################
#
# $Log: Extensions.py,v $
# Revision 1.1 1998/08/03 13:43:26 jim
# new folderish control panel and product management
#
#
#!/bin/env python
##############################################################################
#
# Copyright
#
# Copyright 1998 Digital Creations, Inc., 910 Princess Anne
# Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All
# rights reserved.
#
##############################################################################
__doc__='''Principia Factories
$Id: Factory.py,v 1.1 1998/08/03 13:43:27 jim Exp $'''
__version__='$Revision: 1.1 $'[11:-2]
import OFS.SimpleItem, Acquisition, Globals
class Factory(OFS.SimpleItem.Item, Acquisition.Implicit):
"Model factory meta-data"
meta_type='Principia Factory'
icon='p_/Factory_icon'
manage_options=(
{'label':'Edit', 'action':'manage_main'},
{'label':'Security', 'action':'manage_access'},
)
def __init__(self, id, title, object_type, initial, product):
self.id=id
self.title=title
self.object_type=object_type
self.initial=initial
self.__of__(product)._register()
def _notifyOfCopyTo(self, container):
if container.__class__ is not Product:
raise TypeError, (
'Factories can only be copied to <b>products</b>.')
def _postCopy(self, container):
self._register()
def _register(self):
# Register with the product folder
product=self.aq_parent
product.aq_acquire('_manage_add_product_meta_type')(
product, self.id, self.object_type)
def _unregister(self):
# Unregister with the product folder
product=self.aq_parent
product.aq_acquire('_manage_remove_product_meta_type')(
product, self.id, self.object_type)
manage_main=Globals.HTMLFile('editFactory',globals())
def index_html(self, REQUEST):
" "
return getattr(self, self.initial)(self.aq_parent, REQUEST)
##############################################################################
#
# $Log: Factory.py,v $
# Revision 1.1 1998/08/03 13:43:27 jim
# new folderish control panel and product management
#
#
# Implement the manage_addProduct method of object managers
import Acquisition
from string import rfind
class ProductDispatcher(Acquisition.Implicit):
" "
def __bobo_traverse__(self, REQUEST, name):
product=self.aq_acquire('_getProducts')()._product(name)
dispatcher=FactoryDispatcher(product, self.aq_parent, REQUEST)
return dispatcher.__of__(self)
class FactoryDispatcher(Acquisition.Implicit):
" "
def __init__(self, product, dest, REQUEST):
self._product=product.__dict__
self._d=dest
v=REQUEST['URL']
v=v[:rfind(v,'/')]
self._u=v[:rfind(v,'/')]
def Destination(self):
"Return the destination for factory output"
return self._d
Destination__roles__=None
def DestinationURL(self):
"Return the URL for the destination for factory output"
return self._u
DestinationURL__roles__=None
def __getattr__(self, name):
d=self._product
if d.has_key(name): return d[name].__of__(self)
raise AttributeError, name
"""Principia Product Objects
"""
# The new Product model:
#
# Products may be defined with Principia or by placing directories in
# lib/python/Products.
#
# Products in lib/python/Products may have up to three sources of information:
#
# - Static information defined via Python. This information is
# described and made available via __init__.py.
#
# - Dynamic object data that gets copied into the Bobobase.
# This is contained in product.dat (which is obfuscated).
#
# - Static extensions supporting the dynamic data. These too
# are obfuscated.
#
# Products may be copied and pasted only within the products folder.
#
# If a product is deleted (or cut), it is automatically recreated
# on restart if there is still a product directory.
import Globals, OFS.Folder, OFS.SimpleItem, os, string, Acquisition
from OFS.Folder import Folder
import regex, zlib, Globals, cPickle, marshal, Main, rotor
from string import rfind, atoi, find, strip, join
from Factory import Factory
class ProductFolder(Folder):
"Manage a collection of Products"
id ='Products'
name=title='Product Management'
meta_type ='Product Management'
icon='p_/ProductFolder_icon'
all_meta_types={'name': 'Product', 'action': 'manage_addProductForm'},
meta_types=all_meta_types
def _product(self, name): return getattr(self, name)
manage_addProductForm=Globals.HTMLFile('addProduct',globals())
def manage_addProduct(self, id, title, REQUEST=None):
' '
i=Product(id, title)
self._setObject(id,i)
if REQUEST is not None:
return self.manage_main(self,REQUEST,update_menu=1)
def _delObject(self,id):
for factory in getattr(self, id)._factories(): factory._unregister()
ProductFolder.inheritedAttribute('_delObject')(self, id)
class Product(Folder):
"""Model a product that can be created through the web.
"""
meta_type='Product'
icon='p_/Product_icon'
version=''
configurable_objects_=()
def new_version(self,
_intending=regex.compile("[.]?[0-9]+$").search,
):
# Return a new version number based on the existing version.
v=str(self.version)
if not v: return '1.0'
if _intending(v) < 0: return v
l=rfind(v,'.')
return v[:l+1]+str(1+atoi(v[l+1:]))
meta_types=(
{
'name': 'Principia Factory',
'action': 'manage_addPrincipiaFactoryForm'
},
)
manage_options=Folder.manage_options+(
{'label':'Distribution', 'action':'manage_distributionView'},
)
manage_distributionView=Globals.HTMLFile('distributionView',globals())
_properties=Folder._properties+(
{'id':'version', 'type': 'string'},
)
manage_addPrincipiaFactoryForm=Globals.HTMLFile('addFactory',globals())
def manage_addPrincipiaFactory(
self, id, title, object_type, initial, REQUEST=None):
' '
i=Factory(id, title, object_type, initial, self)
self._setObject(id,i)
if REQUEST is not None:
return self.manage_main(self,REQUEST,update_menu=1)
def _delObject(self,id):
o=getattr(self, id)
if o.meta_type==Factory.meta_type: o._unregister()
Product.inheritedAttribute('_delObject')(self, id)
def __init__(self, id, title):
self.id=id
self.title=title
def _notifyOfCopyTo(self, container):
if container.__class__ is not ProductFolder:
raise TypeError, (
'Products can only be copied to <b>product folders</b>.')
def _postCopy(self, container):
for factory in self._factories():
factory._register()
def _factories(self):
r=[]
append=r.append
for o in self.__dict__.values():
if hasattr(o,'meta_type') and o.meta_type==Factory.meta_type:
append(o.__of__(self))
return r
def Destination(self):
"Return the destination for factory output"
return self
Destination__roles__=None
def DestinationURL(self):
"Return the URL for the destination for factory output"
return self.REQUEST['BASE4']
DestinationURL__roles__=None
def manage_distribute(self, version, RESPONSE, configurable_objects=[]):
"Set the product up to create a distribution and give a link"
if self.__dict__.has_key('manage_options'):
raise TypeError, 'This product is <b>not</b> redistributable.'
self.version=version=strip(version)
self.configurable_objects_=configurable_objects
RESPONSE.redirect('Distributions/%s-%s.tar.gz' % (self.id, version))
def _distribution(self):
# Return a distribution
if self.__dict__.has_key('manage_options'):
raise TypeError, 'This product is <b>not</b> redistributable.'
id=self.id
import tar
rot=rotor.newrotor(id+' shshsh')
ar=tar.tgzarchive("%s-%s" % (id, self.version))
prefix="lib/python/Products/%s/" % self.id
# __init__.py
ar.add(prefix+"__init__.py",
'''"Product %s"
''' % id
)
# Extensions
pp=id+'.'
lpp=len(pp)
ed=os.path.join(SOFTWARE_HOME,'Extensions')
for name in os.listdir(ed):
suffix=''
if name[:lpp]==pp:
path=os.path.join(ed, name)
try:
f=open(path)
data=f.read()
f.close()
if name[-3:]=='.py':
data=rot.encrypt(zlib.compress(data))
suffix='p'
except: data=None
if data:
ar.add("%sExtensions/%s%s" %
(prefix,name[lpp:],suffix),
data)
# version.txt
ar.add(prefix+'version.txt', self.version)
# product.dat
f=CompressedOutputFile(rot)
meta={
'_objects': tuple(filter(
lambda o, obs=self.configurable_objects_:
o['id'] in obs,
self._objects))
}
f.write(cPickle.dumps(meta,1))
self._p_jar.db.exportoid(self._p_oid, f)
ar.add(prefix+'product.dat', f.getdata())
ar.finish()
return str(ar)
class Distributions(Acquisition.Explicit):
"Product Distributions"
def __bobo_traverse__(self, REQUEST, name):
if name[-7:] != '.tar.gz': raise 'Invalid Name', name
l=find(name,'-')
id, version = name[:l], name[l+1:-7]
product=self.aq_parent
if product.id==id and product.version==version:
return Distribution(product)
raise 'Invalid version or product id', name
Distributions=Distributions()
class CompressedOutputFile:
def __init__(self, rot):
self._c=zlib.compressobj()
self._r=[]
self._rot=rot
rot.encrypt('')
def write(self, s):
self._r.append(self._rot.encryptmore(self._c.compress(s)))
def getdata(self):
self._r.append(self._rot.encryptmore(self._c.flush()))
return join(self._r,'')
class CompressedInputFile:
_done=0
def __init__(self, f, rot):
self._c=zlib.decompressobj()
self._b=''
if type(rot) is type(''): rot=rotor.newrotor(rot)
self._rot=rot
rot.decrypt('')
self._f=f
def _next(self):
if self._done: return
l=self._f.read(8196)
if not l:
l=self._c.flush()
self._done=1
else:
l=self._c.decompress(self._rot.decryptmore(l))
self._b=self._b+l
def read(self, l=None):
if l is None:
while not self._done: self._next()
l=len(self._b)
else:
while l > len(self._b) and not self._done: self._next()
r=self._b[:l]
self._b=self._b[l:]
return r
def readline(self):
l=find(self._b, '\n')
while l < 0 and not self._done:
self._next()
l=find(self._b, '\n')
if l < 0: l=len(self._b)
else: l=l+1
r=self._b[:l]
self._b=self._b[l:]
return r
class Distribution:
"A distribution builder"
def __init__(self, product):
self._product=product
def index_html(self, RESPONSE):
"Return distribution data"
r=self._product._distribution()
RESPONSE['content-type']='application/x-gzip'
return r
def initializeProduct(name, home, app):
# Initialize a levered product
products=app.Control_Panel.Products
try: fver=strip(open(home+'/version.txt').read())
except: fver='under development'
old=None
try:
if ihasattr(products,name):
old=getattr(products, name)
if ihasattr(old,'version') and old.version==fver:
return
except: pass
try:
f=CompressedInputFile(open(home+'/product.dat'),name+' shshsh')
meta=cPickle.Unpickler(f).load()
product=Globals.Bobobase._jar.import_file(f)
product._objects=meta['_objects']
except:
product=Product(name, 'Installed product %s (%s)' % (name,fver))
if old is not None: products._delObject(name)
products._setObject(name, product)
product.__of__(products)._postCopy(products)
product.manage_options=OFS.Folder.Folder.manage_options
product.icon='p_/InstalledProduct_icon'
product.version=fver
product._distribution=None
product.manage_distribution=None
product.thisIsAnInstalledProduct=1
def ihasattr(o, name):
return hasattr(o, name) and o.__dict__.has_key(name)
# Product registry and new product factory model. There will be a new
# mechanism for defining actions for meta types. If an action is of
# the form:
#
# manage_addProduct-name-factoryid
#
# Then the machinery that invokes an add-product form
# will return:
# ....what?
from OFS.Folder import Folder
class ProductRegistry:
# This class implements a protocol for registering products that
# are defined through the web. It also provides methods for
# getting hold of the Product Registry, Control_Panel.Products.
# This class is a mix-in class for the top-level application object.
def _getProducts(self): return self.Control_Panel.Products
_product_meta_types=()
def _manage_remove_product_meta_type(self, product, id, meta_type):
self._product_meta_types=filter(lambda mt, nmt=meta_type:
mt['name']!=nmt,
self._product_meta_types)
def _manage_add_product_meta_type(self, product, id, meta_type):
if filter(lambda mt, nmt=meta_type:
mt['name']==nmt,
self.all_meta_types()):
raise 'Type Exists', (
'The type <em>%s</em> is already defined.')
self._product_meta_types=self._product_meta_types+({
'name': meta_type,
'action': ('manage_addProduct/%s/%s' % (product.id, id)),
},)
<html><head><title>Create a factory</title></head>
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555" alink="#77003B">
<h2>Create an object factory</h2>
<!--#if objectIds-->
<form action="manage_addPrincipiaFactory" method="POST">
<table cellspacing="2">
<tr>
<th align="LEFT" valign="TOP">Id</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="id"
size="40"></td>
</tr>
<tr>
<th align="LEFT" valign="TOP">Title</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="title"
size="40"></td>
</tr>
<tr>
<th align="LEFT" valign="TOP">Add list name</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="object_type"
size="40"></td>
</tr>
<tr><th ALIGN="LEFT">Method</th>
<td ALIGN="LEFT"><select name="initial">
<!--#in objectItems-->
<!--#if "meta_type != 'Principia Factory'"-->
<option><!--#var sequence-key--></option>
<!--#/if-->
<!--#/in-->
</select></td></tr>
<tr><td></td><td><br><input type="SUBMIT" value="Generate"></td></tr>
</table></form>
The <strong>Method</strong> is the method that will be invoked when a
user adds a new object. This must be one of the objects in the
product, typically a Document.
<!--#else-->
Before you can define a factory, you have to define one or more "methods",
such as Document or other objects that do the factory's work.
<!--#/if-->
</body></html>
<html><head><title>Create a product</title></head>
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555" alink="#77003B">
<h2>Create a Product</h2>
<form action="manage_addProduct" method="POST">
<table cellspacing="2">
<tr>
<th align="LEFT" valign="TOP">Id</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="id"
size="40"></td>
</tr>
<tr>
<th align="LEFT" valign="TOP">Title</th>
<td align="LEFT" valign="TOP">
<input type="TEXT" name="title" size="40">
</td>
</tr>
<tr><td></td><td><br><input type="submit" value="Generate"></td></tr>
</table></form>
</body></html>
<HTML>
<HEAD>
<TITLE>Cache</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#000099" VLINK="#555555">
<!--#var manage_tabs-->
<h2>Manual Cache Garbage Collection</h2><P>
<table>
<tr><td>
<strong>Full Sweep</strong><br>
Make a single pass through the cache, removing any objects that are no
longer referenced, and deactivating objects that have not been
accessed in the number of seconds given in the input box to the right
of this text.
</td><td>
<form action="<!--#var URL1-->/manage_full_sweep" method=GET>
<input type="text" name="value:int" value="<!--#var cache_age-->" size=6><br>
<input type="submit" value="Full Sweep">
</form></td></tr>
<tr><td>
<strong>Minimize</strong><br>
Make multiple passes through the cache, removing any objects that are no
longer referenced, and deactivating objects that have not been
accessed in the number of seconds given in the input box to the right
of this text.
</td><td>
<form action="<!--#var URL1-->/manage_minimize" method=GET>
<input type="text" name="value:int" value="<!--#var cache_age-->" size=6><br>
<input type="submit" value="Minimize">
</form></td></tr>
</table
<h3>Cache Statistics</h3>
<table>
<tr><th align=right>Total number of objects in the database:</th>
<td><!--#var database_size--></td></tr>
<tr><th align=right>Number of objects in the cache:</th>
<td><!--#var cache_length--></td></tr>
<tr><th align=right>Mean time since last access:</th>
<td><!--#var cache_mean_age--></td></tr>
<tr><th align=right>Deactivation rate (objects/second):</th>
<td><!--#var cache_mean_deac--></td></tr>
<tr><th align=right>Deallocation rate (objects/second):</th>
<td><!--#var cache_mean_deal--></td></tr>
<tr><th align=right>Time of last cache garbage collection:</th>
<td><!--#var cache_last_gc_time--></td></tr>
</table>
<!--#if show_cache_detail-->
<h4>Cache Details</h4><P>
<table border><tr><th>Object Class</th><th>Count</th></tr>
<!--#in cache_detail-->
<tr><td><!--#var sequence-key--></td><td><!--#var sequence-item--></td></tr>
<!--#/in-->
</table>
<!--#/if-->
<!--#if show_cache_extreme_detail-->
<h4>Objects in the cache</h4><P>
<table border><tr><th>Object ID</th>
<th>Object Class</th>
<th>Reference Count</th>
<th>References</th>
</tr>
<!--#in cache_extreme_detail mapping-->
<tr><td><!--#var oid--></td>
<td><!--#var klass--></td>
<td><!--#var rc--></td>
<td><!--#var references--></td>
</tr>
<!--#/in-->
</table>
<!--#/if-->
</BODY></HTML>
<HTML>
<HEAD>
<TITLE>Cache</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#000099" VLINK="#555555">
<!--#var manage_tabs-->
<h2>Cache Parameters and Statistics</h2>
<table>
<tr><th align=right>Total number of objects in the database:</th>
<td><!--#var database_size--></td></tr>
<tr><th align=right>Number of objects in the cache:</th>
<td><!--#var cache_length--></td></tr>
<tr><th valign=top align=right>Target size:</th><td>
<form action="<!--#var URL1-->/manage_cache_size" method=GET>
<input type="text" name="value:int" value="<!--#var cache_size-->" size=6>
<input type="submit" value="Change">
</form></td></tr>
<tr><th align=right>Mean time since last access:</th>
<td><!--#var cache_mean_age--></td></tr>
<tr><th valign=top align=right>Target maximum time between accesses:</th><td>
<form action="<!--#var URL1-->/manage_cache_age" method=GET>
<input type="text" name="value:int" value="<!--#var cache_age-->" size=6>
<input type="submit" value="Change">
</form></td></tr>
<tr><th align=right>Deactivation rate (objects/second):</th>
<td><!--#var cache_mean_deac--></td></tr>
<tr><th align=right>Deallocation rate (objects/second):</th>
<td><!--#var cache_mean_deal--></td></tr>
<tr><th align=right>Time of last cache garbage collection:</th>
<td><!--#var cache_last_gc_time--></td></tr>
</table>
<!--#if show_cache_detail-->
<h4>Cache Details</h4><P>
<table border><tr><th>Object Class</th><th>Count</th></tr>
<!--#in cache_detail-->
<tr><td><!--#var sequence-key--></td><td><!--#var sequence-item--></td></tr>
<!--#/in-->
</table>
<!--#/if-->
<!--#if show_cache_extreme_detail-->
<h4>Objects in the cache</h4><P>
<table border><tr><th>Object ID</th>
<th>Object Class</th>
<th>Reference Count</th>
<th>References</th>
</tr>
<!--#in cache_extreme_detail mapping-->
<tr><td><!--#var oid--></td>
<td><!--#var klass--></td>
<td><!--#var rc--></td>
<td><!--#var references--></td>
</tr>
<!--#/in-->
</table>
<!--#/if-->
</BODY></HTML>
<HTML>
<HEAD>
<TITLE>Contents</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#000099" VLINK="#555555">
<!--#var manage_tabs-->
<FORM ACTION="manage_shutdown" METHOD="POST" TARGET="_top">
The Control Panel provides access to system management functions,
such as database and product management. The system has been running
(with a process ID of <!--#var process_id-->) for <!--#var
process_time-->. Click &quot;Shutdown&quot; to shutdown the Principia
process. It will be restarted on the next web request.
<BR><INPUT TYPE="SUBMIT" VALUE="Shutdown">
</FORM>
<!--#if Principia-Session-->
<EM>You are currently working in session <!--#var Principia-Session--></EM>
<!--#/if Principia-Session-->
<P>
<TABLE>
<!--#in objectItems-->
<TR>
<td> </td>
<TD ALIGN="LEFT" VALIGN="TOP">
<A HREF="<!--#var sequence-key-->/manage_main">
<IMG SRC="<!--#var SCRIPT_NAME-->/<!--#var icon-->"
ALT="Click to open this item" BORDER="0"></A>
</TD>
<TD ALIGN="LEFT" VALIGN="TOP">
<A HREF="<!--#var sequence-key-->/manage_main">
<!--#var title-->
</A>
<!--#if locked_in_session-->
<!--#if modified_in_session-->
<IMG SRC="<!--#var SCRIPT_NAME-->/p_/locked"
ALT="This item has been modified in this session">
<!--#else-->
<IMG SRC="<!--#var SCRIPT_NAME-->/p_/lockedo"
ALT="This item has been modified in another session">
<!--#/if-->
<!--#/if-->
</TD>
</TR>
<!--#/in objectValues-->
</TABLE>
</BODY>
</HTML>
<HTML>
<HEAD>
<TITLE><!--#var title--></TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#000099" VLINK="#555555">
<!--#var manage_tabs-->
<P>
The Database Manager allows you to view database status information.
It also allows you to perform maintenance tasks such as
database packing, cache management,
and &quot;undoing&quot; previous changes to your site.
<P>
<TABLE CELLPADDING="4" BORDER="1">
<TR>
<TD ALIGN="LEFT" VALIGN="TOP">
<STRONG>Database Size</STRONG>
</TD>
<TD ALIGN="LEFT" VALIGN="TOP">
<!--#var db_size-->
</TD>
</TR>
<TR>
<TD ALIGN="LEFT" VALIGN="TOP">
<STRONG>Database Location</STRONG>
</TD>
<TD ALIGN="LEFT" VALIGN="TOP">
<font size="-1"><!--#var db_name--></font>
</TD>
</TR>
</TABLE>
<TABLE CELLPADDING="4">
<TR>
<FORM ACTION="manage_pack" METHOD="POST" TARGET="manage_main">
<TD ALIGN="LEFT" VALIGN="TOP">
<BR>Click &quot;Pack&quot; to pack the Principia database, removing
previous revisions of objects that are older than
<INPUT TYPE="TEXT" VALUE="0" NAME="days:float" SIZE="3"> days.
</TD>
<TD ALIGN="LEFT" VALIGN="TOP">
<BR><INPUT TYPE="SUBMIT" VALUE=" Pack ">
</TD>
</FORM>
</TR>
</TABLE>
</BODY>
</HTML>
<html><head>
<title>Create a Distribution Archive</title>
</head><body>
<!--#var manage_tabs-->
<H2>Create a Distribution Archive</H2>
<form action="manage_distribute"><table>
<tr><th align="LEFT" valign="TOP">Version</th>
<td align="LEFT" valign="TOP">
<input type=text name="version" value="<!--#var new_version-->">
</td>
</tr>
<tr><th align="LEFT" valign="TOP">Configurable objects</th>
<td align="LEFT" valign="TOP">
<select name="configurable_objects:list" size=10 multiple>
<!--#in objectItems-->
<option value="<!--#var sequence-key-->" <!--#
if "_['sequence-key'] in configurable_objects_"
-->SELECTED<!--#/if-->><!--#
var title_and_id--></option>
<!--#/in-->
</select>
</td>
</tr>
<tr><th></th>
<td align="LEFT" valign="TOP">
<input type=submit value="Create a distribution archive"
</td>
</tr>
</table></form>
</body></html>
<html><head><title>Change a factory</title></head>
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555" alink="#77003B">
<!--#var manage_tabs-->
<form action="manage_edit" method="POST">
<table cellspacing="2">
<tr>
<th align="LEFT" valign="TOP">Id</th>
<td align="LEFT" valign="TOP"><!--#var id--></td>
</tr>
<tr>
<th align="LEFT" valign="TOP">Title</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="title"
size="40" value="<!--#var title-->"></td>
</tr>
<tr>
<th align="LEFT" valign="TOP">
Name of new object type, which is the name that will appear in
the folder "add" list
</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="object_type"
size="40" value="<!--#var object_type-->"></td>
</tr>
<tr><th ALIGN="LEFT">
Select a method to begin the process of adding
new objects. This is the method that will be invoked when a
user adds a new object.
</th>
<td ALIGN="LEFT"><select name="initial">
<!--#in objectIds-->
<option
<!--#if expr="_['sequence-item']==initial"-->SELECTED<!--#/if-->
><!--#var sequence-item--></option>
<!--#/in-->
</select></td></tr>
<tr><td></td><td><br><input type="SUBMIT" value="Change"></td></tr>
</table></form>
</body></html>
#!/bin/env python
##############################################################################
#
# Copyright
#
# Copyright 1996 Digital Creations, L.C., 910 Princess Anne
# Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All
# rights reserved.
#
##############################################################################
__doc__='''Simple module for writing tar files
$Id: tar.py,v 1.1 1998/08/03 13:43:28 jim Exp $'''
__version__='$Revision: 1.1 $'[11:-2]
import sys, time, zlib
try:
from newstruct import pack
except:
from struct import pack
from string import find, join
def oct8(i):
i=oct(i)
return '0'*(6-len(i))+i+' \0'
def oct12(i):
i=oct(i)
return '0'*(11-len(i))+i+' '
def pad(s,l):
ls=len(s)
if ls >= l: raise ValueError, 'value, %s, too wide for field (%d)' % (s,l)
return s+'\0'*(l-ls)
class TarEntry:
def __init__(self, path, data,
mode=0644, uid=0, gid=0, mtime=None, typeflag='0',
linkname='', uname='jim', gname='system', prefix=''):
"Initialize a Tar archive entry"
self.data=data
if mtime is None: mtime=int(time.time())
header=join([
pad(path, 100),
oct8(mode),
oct8(uid),
oct8(gid),
oct12(len(data)),
oct12(mtime),
' ' * 8,
typeflag,
pad(linkname, 100),
'ustar\0',
'00',
pad(uname, 32),
pad(gname, 32),
'000000 \0',
'000000 \0',
pad(prefix, 155),
'\0'*12,
], '')
if len(header) != 512: raise 'Bad Header Length', len(header)
header=(header[:148]+
oct8(reduce(lambda a,b: a+b, map(ord,header)))+
header[156:])
self.header=header
def __str__(self):
data=self.data
l=len(data)
if l%512: data=data+'\0'*(512-l%512)
return self.header+data
def tar(entries):
r=[]
ra=r.append
for name, data in entries:
ra(str(TarEntry(name,data)))
ra('\0'*1024)
return join(r,'')
def tgz(entries):
c=zlib.compressobj()
compress=c.compress
r=[]
ra=r.append
for name, data in entries:
ra(compress(str(TarEntry(name,data))))
ra(compress('\0'*1024))
ra(c.flush())
return join(r,'')
class tgzarchive:
def __init__(self, name, time=None):
self._f=gzFile('%s.tar' % name, time)
def add(self, name, data):
self._f.write(str(TarEntry(name,data)))
def finish(self):
self._f.write('\0'*1024)
def __str__(self):
return self._f.getdata()
class gzFile:
_l=0
_crc=zlib.crc32("")
def __init__(self, name, t=None):
self._c=zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS,
zlib.DEF_MEM_LEVEL, 0)
if t is None: t=time.time()
self._r=['\037\213\010\010',
pack("<i", int(t)),
'\2\377',
name,
'\0'
]
def write(self, s):
self._crc=zlib.crc32(s, self._crc)
self._r.append(self._c.compress(s))
self._l=self._l+len(s)
def getdata(self):
r=self._r
append=r.append
append(self._c.flush())
append(pack("<i", self._crc))
append(pack("<i", self._l))
return join(r,'')
##############################################################################
#
# $Log: tar.py,v $
# Revision 1.1 1998/08/03 13:43:28 jim
# new folderish control panel and product management
#
#
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment