Skip to content

Commit

Permalink
Merge branch 'plonezope4' of git://github.com/zopefoundation/Zope int…
Browse files Browse the repository at this point in the history
…o plonezope4
  • Loading branch information
MrTango committed Feb 5, 2017
2 parents e195ce0 + 2978d65 commit 27ff940
Show file tree
Hide file tree
Showing 8 changed files with 317 additions and 5 deletions.
8 changes: 6 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ Bugs Fixed
- Removed meta type column from manage_main, because of also removed icons
[MrTango]

- Be more verbose when reraising exceptions.
[pbauer]

Features Added
++++++++++++++

Expand Down Expand Up @@ -85,6 +88,9 @@ Features Added
Restructuring
+++++++++++++

- Removed xml-export.
[maurits, pbauer]

- Add back ZCacheable support.

- Update to zope.testbrowser 5.0 and its WebTest based implementation.
Expand Down Expand Up @@ -172,8 +178,6 @@ Restructuring

- Drop `OFS.History` functionality.

- Removed ZMI export/import feature.

- Drop ZopeUndo dependency and move undo management to the control panel.

- Simplify ZMI control panel and globally available management screens.
Expand Down
88 changes: 87 additions & 1 deletion src/OFS/ObjectManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""

from cgi import escape
from cStringIO import StringIO
from logging import getLogger
import copy
import fnmatch
Expand All @@ -31,6 +32,7 @@
from AccessControl.Permissions import access_contents_information
from AccessControl.Permissions import delete_objects
from AccessControl.Permissions import ftp_access
from AccessControl.Permissions import import_export_objects
from AccessControl import getSecurityManager
from AccessControl.ZopeSecurityPolicy import getRoles
from Acquisition import aq_base, aq_acquire, aq_parent
Expand Down Expand Up @@ -59,6 +61,7 @@
from OFS.event import ObjectWillBeRemovedEvent
from OFS.Lockable import LockableItem
from OFS.subscribers import compatibilityCall

import collections

if bbb.HAS_ZSERVER:
Expand All @@ -82,7 +85,6 @@

bad_id = re.compile(r'[^a-zA-Z0-9-_~,.$\(\)# @]').search


def checkValidId(self, id, allow_dup=0):
# If allow_dup is false, an error will be raised if an object
# with the given id already exists. If allow_dup is true,
Expand Down Expand Up @@ -569,6 +571,90 @@ def tpValues(self):
r.append(o)
return r

security.declareProtected(import_export_objects, 'manage_exportObject')
def manage_exportObject(self, id='', download=None,
RESPONSE=None,REQUEST=None):
"""Exports an object to a file and returns that file."""
if not id:
# can't use getId() here (breaks on "old" exported objects)
id=self.id
if hasattr(id, 'im_func'): id=id()
ob=self
else: ob=self._getOb(id)

suffix = 'zexp'

if download:
f=StringIO()
ob._p_jar.exportFile(ob._p_oid, f)
if RESPONSE is not None:
RESPONSE.setHeader('Content-type','application/data')
RESPONSE.setHeader('Content-Disposition',
'inline;filename=%s.%s' % (id, suffix))
return f.getvalue()

cfg = getConfiguration()
f = os.path.join(cfg.clienthome, '%s.%s' % (id, suffix))
ob._p_jar.exportFile(ob._p_oid, f)

if REQUEST is not None:
return self.manage_main(self, REQUEST,
manage_tabs_message=
'"%s" successfully exported to "%s"' % (id,f),
title = 'Object exported')


security.declareProtected(import_export_objects, 'manage_importExportForm')
manage_importExportForm=DTMLFile('dtml/importExport',globals())

security.declareProtected(import_export_objects, 'manage_importObject')
def manage_importObject(self, file, REQUEST=None, set_owner=1):
"""Import an object from a file"""
dirname, file=os.path.split(file)
if dirname:
raise BadRequest, 'Invalid file name %s' % escape(file)

for impath in self._getImportPaths():
filepath = os.path.join(impath, 'import', file)
if os.path.exists(filepath):
break
else:
raise BadRequest, 'File does not exist: %s' % escape(file)

imported = self._importObjectFromFile(
filepath, verify=bool(REQUEST), set_owner=set_owner)
id = imported.id
if hasattr(id, '__func__'):
id = id()

if REQUEST is not None:
return self.manage_main(
self, REQUEST,
manage_tabs_message='"%s" successfully imported' % id,
title='Object imported',
update_menu=1)

def _importObjectFromFile(self, filepath, verify=1, set_owner=1):
# locate a valid connection
connection=self._p_jar
obj=self

while connection is None:
obj=obj.aq_parent
connection=obj._p_jar
ob=connection.importFile(filepath)
if verify: self._verifyObjectPaste(ob, validate_src=0)
id = ob.id
if hasattr(id, '__func__'):
id = id()
self._setObject(id, ob, set_owner=set_owner)

# try to make ownership implicit if possible in the context
# that the object was imported into.
ob=self._getOb(id)
ob.manage_changeOwnershipType(explicit=0)
return ob

def _getImportPaths(self):
cfg = getConfiguration()
paths = []
Expand Down
127 changes: 127 additions & 0 deletions src/OFS/dtml/importExport.dtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<dtml-var manage_page_header>
<dtml-var "manage_tabs(this(), _, )">

<p class="form-help">
You can export Zope objects to a file in order to transfer
them to a different Zope installation. You can either choose
to download the export file to your local machine, or save it
in the &quot;var&quot; directory of your Zope installation
on the server.
<br/>
<br/>
<b>Note:</b>
Zope can export/import objects in a binary format (called
ZEXP). The ZEXP format is the officially supported export/import
format for moving data between <u>identical</u> Zope installations (it is not a migration tool).
</p>

<form action="manage_exportObject" method="post">
<table cellspacing="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-label">
Export object id
</div>
</td>
<td align="left" valign="top">
<input type="text" name="id" size="25" value="<dtml-if ids><dtml-var "ids[0]" html_quote></dtml-if>" class="form-element"/>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Export to
</div>
</td>
<td align="left" valign="top">
<div class="form-text">
<label for="download_local">
<input type="radio" name="download:int" value="1" id="download_local" />
Download to local machine
</label>
<br />
<label for="download_server">
<input type="radio" name="download:int" value="0" id="download_server" checked />
Save to file on server
</label>
</div>
</td>
</tr>
<tr>
<td></td>
<td align="left" valign="top">
<div class="form-element">
<input class="form-element" type="submit" name="submit" value="Export" />
</div>
</td>
</tr>
</table>
</form>

<hr />

<p class="form-help">
You may import Zope objects which have been previously
exported to a file, by placing the file in the &quot;import&quot;
directory of your Zope installation on the server. You should create
the &quot;import&quot; directory in the root of your Zope installation
if it does not yet exist.
</p>

<p class="form-help">
Note that by default, you will become the owner of the objects
that you are importing. If you wish the imported objects to retain
their existing ownership information, select "retain existing
ownership information".
</p>

<form action="manage_importObject" method="post">
<table cellspacing="2" border="0">

<tr>
<td align="left" valign="top">
<div class="form-label">
Import file name
</div>
</td>
<td align="left" valign="top">
<select name="file">
<dtml-in "list_imports()">
<option value="<dtml-var sequence-item>"><dtml-var sequence-item></option>
</dtml-in>
</select>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Ownership
</div>
</td>
<td align="left" valign="top">
<div class="form-text">
<label for="owner_take">
<input type="radio" name="set_owner:int" value="1" id="owner_take" checked />
Take ownership of imported objects
</label>
<br />
<label for="owner_retain">
<input type="radio" name="set_owner:int" value="0" id="owner_retain" />
Retain existing ownership information
</label>
</div>
</td>
</tr>
<tr>
<td></td>
<td align="left" valign="top">
<div class="form-element">
<input class="form-element" type="submit" name="submit" value="Import" />
</div>
</td>
</tr>
</table>
</form>


<dtml-var manage_page_footer>
9 changes: 9 additions & 0 deletions src/OFS/dtml/main.dtml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@
<input class="form-element" type="submit" name="manage_delObjects:method"
value="Delete" />
</dtml-if>
<dtml-if "_.SecurityCheckPermission('Import/Export objects', this())">
<input class="form-element" type="submit"
name="manage_importExportForm:method"
value="Import/Export" />
</dtml-if>
</div>
</td>
</tr>
Expand All @@ -144,6 +149,10 @@ There are currently no items in <em>&dtml-title_or_id;</em>
</div>
</dtml-if>
</dtml-unless>
<dtml-if "_.SecurityCheckPermission('Import/Export objects', this())">
<input class="form-element" type="submit"
name="manage_importExportForm:method" value="Import/Export" />
</dtml-if>
</td>
</tr>
</table>
Expand Down
12 changes: 12 additions & 0 deletions src/OFS/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,7 @@ class IObjectManager(IZopeObject, ICopyContainer, INavigation, IManageable,
manage_main = Attribute(""" """)
manage_index_main = Attribute(""" """)
manage_addProduct = Attribute(""" """)
manage_importExportForm = Attribute(""" """)

def all_meta_types(interfaces=None):
"""
Expand Down Expand Up @@ -735,6 +736,17 @@ def tpValues():
"""Return a list of subobjects, used by tree tag.
"""

def manage_exportObject(id='', download=None,
RESPONSE=None, REQUEST=None):
"""Exports an object to a file and returns that file."""

def manage_importObject(file, REQUEST=None, set_owner=1):
"""Import an object from a file"""

def _importObjectFromFile(filepath, verify=1, set_owner=1):
"""
"""


class IFindSupport(Interface):
"""Find support for Zope Folders"""
Expand Down
Loading

0 comments on commit 27ff940

Please sign in to comment.