Commit 398ecfa5 authored by 's avatar

Added copy/paste support, restricted unpickling, fixed DraftFolder bug

parent 0394d8b2
"""Copy interface"""
__version__='$Revision: 1.1 $'[11:-2]
import Globals, Moniker, rPickle
from cPickle import loads, dumps
from urllib import quote, unquote
from App.Dialogs import MessageDialog
rPickle.register('OFS.Moniker', 'Moniker', Moniker.Moniker)
class CopyContainer:
# Interface for containerish objects which allow
# objects to be copied into them.
def _getMoniker(self):
# Ask an object to return a moniker for itself.
return Moniker.Moniker(self)
pasteDialog=Globals.HTMLFile('OFS/pasteDialog')
def pasteFromClipboard(self,clip_id='',clip_data='',REQUEST=None):
""" """
if not clip_data: return eNoData
try: moniker=rPickle.loads(unquote(clip_data))
except: return eInvalid
if not clip_id:
return self.pasteDialog(self,REQUEST,bad=0,moniker=(moniker,))
try: self._checkId(clip_id)
except: return self.pasteDialog(self,REQUEST,bad=1,moniker=(moniker,))
try: obj=moniker.bind()
except: return eNotFound
# Acquire roles from new environment
try: del obj.__roles__
except: pass
obj=obj._getCopy(self)
obj._setId(clip_id)
self._setObject(clip_id, obj)
return self.manage_main(self, REQUEST)
class CopySource:
# Interface for objects which allow themselves to be copied.
def _getMoniker(self):
# Ask an object to return a moniker for itself.
return Moniker.Moniker(self)
def _getCopy(self, container):
# Ask an object for a new copy of itself.
return loads(dumps(self))
def _setId(self, id):
# Called to set the new id of a copied object.
self.id=id
def copyToClipboard(self, REQUEST):
""" """
# Set a cookie containing pickled moniker
try: moniker=self._getMoniker()
except: return eNotSupported
REQUEST['RESPONSE'].setCookie('clip_data',
quote(dumps(moniker)),
path='/',
expires='Friday, 31-Dec-99 23:59:59 GMT')
# Predefined errors
eNoData=Globals.MessageDialog(
title='No Data',
message='No clipboard data to be pasted',
action ='./manage_main',)
eInvalid=Globals.MessageDialog(
title='Clipboard Error',
message='Clipboard data could not be read ' \
'or is not supported in this installation',
action ='./manage_main',)
eNotFound=Globals.MessageDialog(
title='Clipboard Error',
message='The item referenced by the ' \
'clipboard data was not found',
action ='./manage_main',)
eNotSupported=Globals.MessageDialog(
title='Not Supported',
message='Operation not supported for the selected item',
action ='./manage_main',)
......@@ -14,8 +14,8 @@ Provide an area where people can work without others seeing their changes.
A Draft folder is a surrogate for a folder. It get\'s subobjects by
gettingthem from a session copy of a base folder.
$Id: DraftFolder.py,v 1.1 1997/11/11 21:05:44 jim Exp $'''
__version__='$Revision: 1.1 $'[11:-2]
$Id: DraftFolder.py,v 1.2 1997/11/11 21:25:28 brian Exp $'''
__version__='$Revision: 1.2 $'[11:-2]
import time, SimpleItem, AccessControl.Role, Persistence, Acquisition, Globals
import AccessControl.User, Session
......@@ -186,6 +186,11 @@ class DraftFolder(Persistence.Persistent,
def manage_supervisor(self): return self.__allow_groups__
def parentObject(self):
try: return (self.aq_parent,)
except: return ()
class Supervisor(AccessControl.User.UserFolder, Session.Session):
manage=manage_main=HTMLFile('OFS/DraftFolderSupervisor')
......@@ -198,6 +203,9 @@ class Supervisor(AccessControl.User.UserFolder, Session.Session):
##############################################################################
#
# $Log: DraftFolder.py,v $
# Revision 1.2 1997/11/11 21:25:28 brian
# Added copy/paste support, restricted unpickling, fixed DraftFolder bug
#
# Revision 1.1 1997/11/11 21:05:44 jim
# Draft Folders
#
......
"""Folder object
$Id: Folder.py,v 1.18 1997/11/11 18:52:20 jim Exp $"""
$Id: Folder.py,v 1.19 1997/11/11 21:25:28 brian Exp $"""
__version__='$Revision: 1.18 $'[11:-2]
__version__='$Revision: 1.19 $'[11:-2]
from Globals import HTMLFile
from ObjectManager import ObjectManager
from CopySupport import CopyContainer
from Image import ImageHandler
from Document import DocumentHandler
from AccessControl.User import UserFolderHandler
......@@ -17,6 +18,9 @@ from string import rfind, lower
from content_types import content_type, find_binary, text_type
import Image
class FolderHandler:
"""Folder object handler"""
......@@ -67,7 +71,7 @@ class FolderHandler:
class Folder(ObjectManager,RoleManager,DocumentHandler,
ImageHandler,FolderHandler,UserFolderHandler,
SimpleItem.Item):
SimpleItem.Item,CopyContainer):
"""Folder object"""
meta_type='Folder'
id ='folder'
......
"""
Object monikers
An object moniker is an intelligent reference to a
persistent object. A moniker can be turned back into
a real object that retains its correct session context
and aquisition relationships via a simple interface.
"""
__version__='$Revision: 1.1 $'[11:-2]
import Globals
class Moniker:
""" """
def __init__(self, obj=None, p=1):
if obj is None: return
self.id =absattr(obj.id)
self.title=absattr(obj.title)
self.mtype=absattr(obj.meta_type)
self.oid =obj._p_oid
self.jar =obj._p_jar.name
self.aqp =None
if p:
try: self.aqp=Moniker(obj.aq_parent, 0)
except: self.aqp=None
def bind(self):
if self.jar is None: jar=Globals.Bobobase._jar
else: jar=Globals.SessionBase[self.jar].jar
obj=jar[self.oid]
if self.aqp is not None:
obj=obj.__of__(self.aqp.bind())
return obj
def absattr(attr):
if callable(attr): return attr()
return attr
__doc__="""Object Manager
$Id: ObjectManager.py,v 1.18 1997/11/11 18:52:53 jim Exp $"""
$Id: ObjectManager.py,v 1.19 1997/11/11 21:25:29 brian Exp $"""
__version__='$Revision: 1.18 $'[11:-2]
__version__='$Revision: 1.19 $'[11:-2]
from SingleThreadedTransaction import Persistent
......@@ -78,6 +78,13 @@ class ObjectManager(Acquirer,Management,Persistent):
"""The id <em>%s<em> is invalid - it
is already in use.""" % id)
def _checkObject(self, object):
t=object.meta_type
if callable(t): t=t()
for d in self.all_meta_types():
if d['name']==t: return
raise 'Bad Request', 'Object type is not supported'
def parentObject(self):
try:
if self.aq_parent.isAnObjectManager:
......@@ -254,20 +261,41 @@ class ObjectManager(Acquirer,Management,Persistent):
aclEChecked='', aclAChecked=' CHECKED', aclPChecked='')
raise 'BadRequest', 'Unknown object type: %s' % type
def manage_delObjects(self,ids,REQUEST):
def manage_delObjects(self,ids=[],submit='',clip_id='',
clip_data='',REQUEST):
"""Delete a subordinate object"""
try: p=self._reserved_names
except: p=()
for n in ids:
if n in p:
return MessageDialog(title ='Not Deletable' % n,
message='<EM>%s</EM> cannot be deleted.' % n,
action ='./manage_main',)
while ids:
try: self._delObject(ids[-1])
except: raise 'BadRequest', ('%s does not exist' % ids[-1])
del ids[-1]
return self.manage_main(self, REQUEST)
if submit=='Copy':
c=len(ids)
if (c <= 0) or (c > 1):
return MessageDialog(
title='Invalid Selection',
message='Please select one and only one item to copy',
action ='./manage_main',)
obj=getattr(self, ids[0])
err=obj.copyToClipboard(REQUEST)
return err or self.manage_main(self, REQUEST)
if submit=='Paste':
return self.pasteFromClipboard(clip_id,clip_data,REQUEST)
if submit=='Delete':
if not ids:
return MessageDialog(title='No items specified',
message='No items were specified!',
action ='./manage_main',)
try: p=self._reserved_names
except: p=()
for n in ids:
if n in p:
return MessageDialog(title='Not Deletable',
message='<EM>%s</EM> cannot be deleted.' % n,
action ='./manage_main',)
while ids:
try: self._delObject(ids[-1])
except: raise 'BadRequest', ('%s does not exist' % ids[-1])
del ids[-1]
return self.manage_main(self, REQUEST)
def _setProperty(self,id,value,type='string'):
self._checkId(id)
......@@ -421,6 +449,9 @@ class ObjectManager(Acquirer,Management,Persistent):
##############################################################################
#
# $Log: ObjectManager.py,v $
# Revision 1.19 1997/11/11 21:25:29 brian
# Added copy/paste support, restricted unpickling, fixed DraftFolder bug
#
# Revision 1.18 1997/11/11 18:52:53 jim
# Fixed bug in modified_in_session.
#
......
......@@ -16,13 +16,15 @@ Aqueduct database adapters, etc.
This module can also be used as a simple template for implementing new
item types.
$Id: SimpleItem.py,v 1.5 1997/11/11 19:26:09 jim Exp $'''
__version__='$Revision: 1.5 $'[11:-2]
$Id: SimpleItem.py,v 1.6 1997/11/11 21:25:29 brian Exp $'''
__version__='$Revision: 1.6 $'[11:-2]
import Globals
from DateTime import DateTime
from CopySupport import CopySource
class Item:
class Item(CopySource):
# Name, relative to SOFTWARE_URL of icon used to display item
# in folder listings.
......@@ -100,9 +102,15 @@ class Item_w__name__(Item):
t=self.title
return t and ("%s (%s)" % (t,self.__name__)) or self.__name__
def _setId(self, id):
self.__name__=id
##############################################################################
#
# $Log: SimpleItem.py,v $
# Revision 1.6 1997/11/11 21:25:29 brian
# Added copy/paste support, restricted unpickling, fixed DraftFolder bug
#
# Revision 1.5 1997/11/11 19:26:09 jim
# Fixed bug in modified_in_session.
#
......
<HTML><HEAD><TITLE><!--#var title_or_id--></TITLE></HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#000099" VLINK="#555555">
<table border=0 width="100%" cellpadding=0 cellspacing=0>
<tr>
<td align=left width="90%">
<TABLE BORDER="0" WIDTH="100%" CELLSPACING="0" CELLPADDING="2">
<TR>
<TD ALIGN="LEFT" WIDTH="90%">
<H2><!--#var title_or_id--></H2>
<!--#if Principia-Session-->
<em>You are currently working in session
<!--#var Principia-Session--></em><br><br>
<!--#/if-->
</td>
<td align=right width="10%">
<EM>
You are currently working in session <!--#var Principia-Session-->
</EM>
<BR><BR>
<!--#/if Principia-Session-->
</TD>
<TD ALIGN="RIGHT">
<IMG SRC="<!--#var SOFTWARE_URL-->/OFS/Help_icon.gif" BORDER=0>
</td>
</tr>
</table>
</TD>
</TR>
</TABLE>
<!--#if objectValues-->
The following items have been defined. To <strong>manage</strong> the
item, click on the item's icon. To <strong>view</strong> the item,
click on the item's title and id.
<BR><BR>
<table border=0 cellspacing=0 cellpadding=2>
<tr>
<th align=center>
<font size="-1">Manage</font></th>
<th align=left><font size="-1">View</font></th>
</tr>
<!--#in objectValues sort=title_and_id-->
<tr>
<td align=center>
<FORM ACTION="manage_delObjects" METHOD="POST">
<TABLE BORDER="0" CELLSPACING="0" CELLPADDING=2>
<TR>
<TH ALIGN="CENTER">
<FONT SIZE="-1">Manage</FONT>
</TH>
<TH ALIGN="LEFT">
<FONT SIZE="-1">View</FONT>
</TH>
</TR>
<!--#in objectValues sort=title_and_id-->
<TR>
<TD ALIGN="LEFT" VALIGN="TOP">
<INPUT TYPE="CHECKBOX" NAME="ids:list" VALUE="<!--#var id-->">
<A HREF="<!--#var URL1-->/<!--#var id-->/manage"
<!--#if sequence-var-manage_options-->
TARGET="_top"
<!--#/if sequence-var-manage_options-->>
<IMG SRC="<!--#var SOFTWARE_URL-->/<!--#var icon-->"
ALT="manage" BORDER="0"></A></td>
<td>
<A HREF="<!--#var URL1-->/<!--#var id-->"><!--#var title_and_id--></A>
ALT="manage" BORDER="0"></A>
</TD>
<TD ALIGN="LEFT" VALIGN="TOP">
<A HREF="<!--#var URL1-->/<!--#var id-->">
<!--#var title_and_id--></A>
<!--#if modified_in_session-->
<img src="<!--#var SOFTWARE_URL-->/OFS/modified.gif">
<!--#/if-->
</td>
</tr>
<!--#/in objectValues-->
</table>
<IMG SRC="<!--#var SOFTWARE_URL-->/OFS/modified.gif">
<!--#/if modified_in_session-->
</TD>
</TR>
<!--#/in objectValues-->
<TR>
<TD></TD>
<TD>
<INPUT TYPE="SUBMIT" NAME="submit" VALUE="Copy">
<!--#if clip_data-->
<INPUT TYPE="SUBMIT" NAME="submit" VALUE="Paste">
<!--#/if clip_data-->
<INPUT TYPE="SUBMIT" NAME="submit" VALUE="Delete">
</TD>
</TR>
</TABLE>
</FORM>
<!--#else objectValues-->
<!--#if clip_data-->
<FORM ACTION="manage_delObjects" METHOD="POST">
<INPUT TYPE="SUBMIT" NAME="submit" VALUE="Paste">
</FORM>
<!--#/if clip_data-->
<!--#/if objectValues-->
<TABLE>
<TR>
<TD VALIGN="TOP">
To add a new item, select an item type and click &quot;Add&quot;.
</TD>
<TD VALIGN="TOP">
<FORM ACTION="manage_addObject" METHOD="GET">
<SELECT NAME="type">
......@@ -72,32 +89,7 @@ click on the item's title and id.
</FORM>
</TD>
</TR>
<!--#if objectValues_d-->
<TR>
<TD VALIGN="TOP">
To delete items, select one or more items and click &quot;Delete&quot;.
</TD>
<TD VALIGN="TOP">
<FORM ACTION="manage_delObjects" METHOD="GET">
<SELECT NAME="ids:list" MULTIPLE SIZE="4">
<!--#in objectValues_d-->
<OPTION VALUE="<!--#var id-->">
<!--#if title-->
<!--#var title size=25--> (<!--#var id-->)
<!--#else-->
<!--#var id-->
<!--#endif-->
<!--#/in objectValues_d-->
</SELECT><BR>
<INPUT TYPE="SUBMIT" VALUE="Delete">
</FORM>
</TD>
</TR>
<!--#/if objectValues_d-->
</TABLE>
</BODY>
</HTML>
<HTML>
<HEAD>
<TITLE>Paste Item</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#000099" VLINK="#555555">
<!--#if moniker-->
<!--#in moniker-->
<H2>Paste <!--#var sequence-var-mtype--></H2>
<!--#/in moniker-->
<!--#else moniker-->
<H2>Paste Item</H2>
<!--#/if moniker-->
<!--#if bad-->
<EM>An item with the specified id exists</EM>.
Please specify another id.
<!--#else bad-->
Please specify the id to use for this item.
<!--#/if bad-->
<FORM ACTION="pasteFromClipboard" METHOD="POST">
<TABLE CELLSPACING="2">
<TR>
<TD ALIGN="LEFT" VALIGN="TOP">
<STRONG>Id</STRONG>
</TD>
<TD ALIGN="LEFT" VALIGN="TOP">
<INPUT TYPE="TEXT" NAME="clip_id" SIZE="40"
<!--#if moniker-->
<!--#in moniker-->
VALUE="<!--#var sequence-var-id-->"
<!--#/in moniker-->
<!--#/if moniker-->>
</TD>
</TR>
<TR>
<TD></TD>
<TD>
<BR><INPUT TYPE="SUBMIT" VALUE=" OK ">
</TD>
</TR>
</TABLE>
</FORM>
</BODY>
</HTML>
"""Restricted unpickler"""
__version__='$Revision: 1.1 $'[11:-2]
import pickle
reg={}
class Unpickler(pickle.Unpickler):
def find_class(self, module, name):
try: return reg[(module,name)]
except: raise SystemError, 'Class not registered'
# Public interface
from cStringIO import StringIO
def loads(s):
"""Unpickle a string"""
return Unpickler(StringIO(s)).load()
def register(mod, cls, obj):
"""Register a class"""
reg[(mod,cls)]=obj
def unregister(mod, cls):
"""Unregister a class"""
del reg[(mod,cls)]
......@@ -14,8 +14,8 @@ Provide an area where people can work without others seeing their changes.
A Draft folder is a surrogate for a folder. It get\'s subobjects by
gettingthem from a session copy of a base folder.
$Id: DraftFolder.py,v 1.1 1997/11/11 21:05:44 jim Exp $'''
__version__='$Revision: 1.1 $'[11:-2]
$Id: DraftFolder.py,v 1.2 1997/11/11 21:25:28 brian Exp $'''
__version__='$Revision: 1.2 $'[11:-2]
import time, SimpleItem, AccessControl.Role, Persistence, Acquisition, Globals
import AccessControl.User, Session
......@@ -186,6 +186,11 @@ class DraftFolder(Persistence.Persistent,
def manage_supervisor(self): return self.__allow_groups__
def parentObject(self):
try: return (self.aq_parent,)
except: return ()
class Supervisor(AccessControl.User.UserFolder, Session.Session):
manage=manage_main=HTMLFile('OFS/DraftFolderSupervisor')
......@@ -198,6 +203,9 @@ class Supervisor(AccessControl.User.UserFolder, Session.Session):
##############################################################################
#
# $Log: DraftFolder.py,v $
# Revision 1.2 1997/11/11 21:25:28 brian
# Added copy/paste support, restricted unpickling, fixed DraftFolder bug
#
# Revision 1.1 1997/11/11 21:05:44 jim
# Draft Folders
#
......
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