[ANN] zshell: The Zope Shell
Hi there, I'm pleased to announce you the Zope Shell version 0.001. The Zope shell is a GPLed Python Script which makes some of the most commonly used unix shell commands available from within Zope, to manage the ZODB contents. You'll find this 155 lines script attached to this message. As for the 0.001 version which is attached to this message, the following commands are recognized: cd, cp, mv, rm, ls there are some restrictions however, and it doesn't seem to work with absolute paths, read the source for details and the future commands. zshell accepts an unlimited number of commands to launch in a single Zope transaction, so feel free to combine these five commands to do some very complicated stuff. Despite its current limitations it works fine here on Zope 2.3.2+Hotfix0501. Please feel free to send me any comment about this software. Such similar functionnality included in Zope's core would make me VERY happy. hoping this helps. Jerome Alet - alet@unice.fr ## Script (Python) "zshell" ##bind container=container ##bind context=context ##bind namespace= ##bind script=script ##bind subpath=traverse_subpath ##parameters= ##title=The Zope Shell ## # zshell - (c) 2001 Jerome Alet # # You're welcome to redistribute this software under the # terms of the GNU General Public Licence version 2.0 # or, at your option, any higher version. # # You can read the complete GNU GPL in the file COPYING # which should come along with this software, or visit # the Free Software Foundation's WEB site http://www.fsf.org # # author: Jerome Alet - <alet@unice.fr> # # # This is the Zope shell, an attempt at making the most common # Unix shell commands available from within Zope. # # As of May 3rd 2001, version 0.001, the following commands # are recognized: # # cd, rm, mv, cp, ls # # * cd accepts a single path as an argument # * rm accepts many path arguments # * mv and cp last argument is the destination folder, every previous # argument is an object id in the current folder # * ls accepts many meta types as its arguments # # The future: # # in the future I'd be interested in adding more functionnalities # as well as making it a complete Zope product, splitting it # in one method per command, and making the accepted syntax much more # match Unix shell's one. # adding support for a find command is also high on my priority list # # Feel free to send me any feedback about this software at: alet@unice.fr # import string def toObject(curdir, path) : import string path = string.strip(path) if path[0] == '/' : path = path[1:] while hasattr(curdir, 'aq_parent') and (curdir.aq_parent is not None): curdir = curdir.aq_parent components = filter(None, string.split(path, '/')) for component in components : if component == '.' : continue elif component == '..' : if hasattr(curdir, 'aq_parent') and (curdir.aq_parent is not None): curdir = curdir.aq_parent elif hasattr(curdir, component) : curdir = curdir[component] else : return None # Error return curdir print context.standard_html_header.document_src() if context.REQUEST.has_key("commands") : commands = filter(None, context.REQUEST["commands"]) else : commands = [] print '<p><form action="zshell" method="POST">' print 'Enter your commands below:<br>' print '<textarea rows="10" cols="50" wrap="physical" name="commands:lines">%s</textarea>' % string.join(commands, '\n') print '<br><input type="submit" name="run" value="Run !" />' print '</form></p>' if commands : print '<hr noshade="noshade" width="33%" /><p>Results:' current = context for command in commands : cmd = command[:2] print '<br><b>%s:</b> ' % cmd if cmd == 'cd' : path = command[3:] newdir = toObject(current, path) if (newdir is not None) and hasattr(newdir, 'meta_type') and (newdir.meta_type == 'Folder') : current = newdir print 'New folder is <em><b>/%s</b></em>' % newdir.absolute_url(relative=1) else : print 'Incorrect path <em><b>%s</b></em>' % path print '[%s]' % repr(newdir) elif (cmd == 'mv') or (cmd == 'cp') : args = string.split(command[3:]) if len(args) < 2 : print 'Incorrect number of arguments' else : dst = args[-1] srcs = args[:-1] objids = [] for src in srcs : if '/' in src : print 'Paths in source objects are not allowed at this time: <em><b>%s</b></em>' % src else : objids.append(src) dsto = toObject(current, dst) if dsto is None : print 'Incorrect destination argument <em><b>%s</b></em>' % dst continue if dsto.meta_type != 'Folder' : print 'Destination <em><b>%s</b></em> is not a folderish object' % dst continue if cmd == 'cp' : clipboard = current.manage_copyObjects(ids = objids) action = 'copied' else : clipboard = current.manage_cutObjects(ids = objids) action = 'moved' dsto.manage_pasteObjects(cb_copy_data = clipboard) for oid in objids : print '<br>%s %s' % (oid, action) elif cmd == 'rm' : objpaths = filter(None, string.split(string.strip(command[3:]))) for objpath in objpaths : object = toObject(current, objpath) if object is None : print 'Incorrect path <em><b>%s</b></em>' % objpath else : if hasattr(object, 'aq_parent') : object.aq_parent.manage_delObjects(ids = [object.getId()]) print "<br>/%s removed" % object.absolute_url(relative=1) elif cmd == 'ls' : metatypes = filter(None, string.split(string.strip(command[3:]))) if metatypes : objects = current.objectValues(metatypes) else : objects = current.objectValues() if objects : print '<table border="1"><tr><th>Id</th><th>Title</th><th>MetaType</th></tr>' for object in objects : title = object.title or ' ' print '<tr><td>%s</td><td>%s</td><td>%s</td></tr>' % (object.getId(), title, object.meta_type) print '</table>' else : print 'Unknown command <em><b>%s</b></em>' % command print '</p>' print context.standard_html_footer.document_src() return printed
I'm pleased to announce you the Zope Shell version 0.001.
Jerome That is beautiful!! Using 'ls' in Zope makes one thing about what it is in new ways.. its an interesting paradigm mapping. It would be nice to show depth and complexity via 'ls' Similar to ls -la etc.. How many folder-like containers lie within? How many objects are in them? Who owns them How big Piping would be cool.. 'grep' would be lovely too ls -l | grep '^d' Perhaps ZopeShell grep is what is needed to manage permissions ? oh my you have started something VirtualShellMonster:-) Dreams_Department I was just looking again at lightening fast, tiny RDBMS called Kdb from Kx Systems and wondering about how it might work with Zope. http://www.kx.com download and play around.. Now playing with your new shell really makes me wonder serisouly about Zope interpreter. One can use python to but not at the same time as Zope is running. So I gguess the reick woudl be to harness the two ideas. Youtrs is cool becuae the semantic is well understood [up to a point] In zope it takes a long time to gather a familiar consistent vocabulary, and it still lacks the concise simplicity of shellscripts. I wonder if there if there's some meaningful way to integrate your 'jaxml' code into all this. So that one can create xml on the fly inside of the environemnt it is describing. I have played with jaml a little as a means to create Zopescripts and then tested with various XML parsing tools in Zope. I was exploring was how to quickly 'sketch' an outline zope site. If you don't liek throw it away adn satrt again. If it is good then flesh it out.. It is very boring to click on all those 'OK' buttons and watch the HTML screen keep redrawing. Sitting with potential clients for Zopesites really brings this home, I notice that what one really wants to do is take a few lines of compact code and immediately generate the named folders with simple properties, and dummy dethods/documents etc. Saves lots of Time add and very useful templating and Zope design asset. in other words jaxml meets mkdir [folder] touch [method|document] meets ParsedXML ./Jason ___________________________________________________________ Jason CUNLIFFE = NOMADICS['Interactive Art and Technology']
On Thu, 3 May 2001, Jason Cunliffe wrote:
I'm pleased to announce you the Zope Shell version 0.001.
That is beautiful!!
Thanks a lot ! I've desesperatly searched for something like that on zope.org this morning but without luck, so I've written my own :-) I was surprised to not find anything similar.
Using 'ls' in Zope makes one thing about what it is in new ways.. its an interesting paradigm mapping. It would be nice to show depth and complexity via 'ls'
Similar to ls -la etc..
it was just a first shot. expect it to be more complex/powerful soon.
Piping would be cool..
YES it would !
'grep' would be lovely too
yes but without re it will be either difficult or not powerful. I suppose I'll recode all in a Python Zope product, which wouls solve the problem.
Now playing with your new shell really makes me wonder serisouly about Zope interpreter. One can use python to but not at the same time as Zope is running. So I gguess the reick woudl be to harness the two ideas. Youtrs is cool becuae the semantic is well understood [up to a point] In zope it takes a long time to gather a familiar consistent vocabulary, and it still lacks the concise simplicity of shellscripts.
I wonder if there if there's some meaningful way to integrate your 'jaxml' code into all this. So that one can create xml on the fly inside of the environemnt it is describing. I have played with jaml a little as a means to create Zopescripts and then tested with various XML parsing tools in Zope.
Not done that yet, but was thinking to do something like an AutoXMLDocument with jaxml (http://cortex.unice.fr/~jerome/jaxml/), a document which creates its own tags on demand.
It is very boring to click on all those 'OK' buttons and watch the HTML
YES it is, that's why I've made the previous feature request yesterday, and coded ZopeShell today.
screen keep redrawing. Sitting with potential clients for Zopesites really brings this home, I notice that what one really wants to do is take a few lines of compact code and immediately generate the named folders with simple properties, and dummy dethods/documents etc. Saves lots of Time add and very useful templating and Zope design asset.
I think we need some basic zshell commands: the five following commands already work: ls to list objects cp to copy objects mv to move objects (which should work to rename things too but doesn't yet) rm to delete objects cd (should a cd to a non ObjectManager object be allowed ? probably yes if we want to use grep on its contents ;-) it would be very nice to have: grep to search in objects contents cut (not the Unix cut command, think about cut&paste) copy paste id (return the id of the current object) title (return the title of the current object) prop return some or all properties for the current object (id and title are just shortcuts) chmod to change permissions takeown to take ownership, since changing it is impossible AFAIK view to view the object edit to edit it tab to access a specific tab for the object (view and edit are just shortcuts) find to search for objects Some things to also have: piping wildcards the use of '.' or preferably '->' (no confusion with some ids) to access objects' attributes e.g.: grep foo *->someproperty would search for string 'foo' in all objects's property named someproperty. And somewhere in the future: if and for !!! Any comments or more commands needed ? Feel free to send them. I'm curently reorganising zshell's source, expect something more complete soon. bye, and thanks for the feedback. Jerome Alet
At Thu, 3 May 2001 14:42:11 +0200 (MET DST), Jerome Alet wrote:
On Thu, 3 May 2001, Jason Cunliffe wrote:
I'm pleased to announce you the Zope Shell version 0.001.
That is beautiful!!
Thanks a lot !
I've desesperatly searched for something like that on zope.org this morning but without luck, so I've written my own :-)
Hiya Jérome, there is already a Zope shell tool : <http://www.zope.org/Members/sf/zopeshell/> -- Serge Stinckwich -< ) http://multiagent.com/ CNRS UMR 6072>GREYC>I3>SMILE /~\ http://squeak.org/ Université de Caen>IUT de Caen>Campus 3>Dept Info (/ | http://zope.org/ http://www.iutc3.unicaen.fr/~stincs/ _|_/ http://debian.org/
Now playing with your new shell really makes me wonder serisouly about Zope interpreter. One can use python to but not at the same time as Zope is running.
Actually, this isn't true. [chrism@serenade chrism]$ cd sandboxes/CMFTest/ [chrism@serenade CMFTest]$ ls CVS ZServer lib utilities wo_pcgi.py zpasswd.py Extensions doc pcgi var wo_pcgi.pyc zpasswd.pyc LICENSE.txt import start w_pcgi.py z2.py README.txt inst stop w_pcgi.pyc z2.pyc [chrism@serenade CMFTest]$ cd lib/python/ [chrism@serenade python]$ python Python 1.5.2 (#1, Feb 1 2000, 16:32:16) [GCC egcs-2.91.66 19990314/Linux (egcs - on linux-i386 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
import Zope app = Zope.app() app.objectIds() ['acl_users', 'Control_Panel', 'standard_html_header', 'standard_html_footer', ' standard_error_message', 'QuickStart', 'index_html', 'ChrisPortal', 'fudgely', ' fleeber']
--On Donnerstag, 3. Mai 2001 08:18 -0400 Jason Cunliffe <jasonic@nomadicsltd.com> wrote: Hi, ...
Now playing with your new shell really makes me wonder serisouly about Zope interpreter. One can use python to but not at the same time as Zope is running. So I gguess the reick woudl be to harness the two ideas.
Not? You mean not with the ZODB, if its in use by the current zope. Sure. But for this we have ZEO. ... snip ...
It is very boring to click on all those 'OK' buttons and watch the HTML screen keep redrawing. Sitting with potential clients for Zopesites really brings this home, I notice that what one really wants to do is take a few lines of compact code and immediately generate the named folders with simple properties, and dummy dethods/documents etc. Saves lots of Time add and very useful templating and Zope design asset.
The problem is, zope is currently very web-centric. We badly need an abstraction layer for all the things products and the management interface in general want to interact with the user. Then this interface can be mapped to HTTP/HTML HTTP/WML or even stand-alone GUIs (wxWindows as example) All could talk to the very same application. This counts also for the XML-Stuff. Regards Tino
Where on can find Zope Shell version 0.001 ? at http://www.zope.org/Members/sf/zopeshell there's only... Release Version Date ---------------------------------------------------------------------- Zopeshell 0.4 0.4 (Stable) 2000/12/19 zopeshell-0.3.0 0.3.0 (Development) 2000/08/05 zopeshell-0.2.0 0.2.0 (Development) 2000/06/06 zopeshell 0.1.1 0.1.1 (Development) 2000/05/07 zopeshell vers 0.1 0.1 (Development) 2000/05/06 Jerome Alet wrote:
Hi there,
I'm pleased to announce you the Zope Shell version 0.001.
The Zope shell is a GPLed Python Script which makes some of the most commonly used unix shell commands available from within Zope, to manage the ZODB contents. You'll find this 155 lines script attached to this message.
As for the 0.001 version which is attached to this message, the following commands are recognized: cd, cp, mv, rm, ls
there are some restrictions however, and it doesn't seem to work with absolute paths, read the source for details and the future commands.
zshell accepts an unlimited number of commands to launch in a single Zope transaction, so feel free to combine these five commands to do some very complicated stuff. Despite its current limitations it works fine here on Zope 2.3.2+Hotfix0501.
Please feel free to send me any comment about this software.
Such similar functionnality included in Zope's core would make me VERY happy.
hoping this helps.
Jerome Alet - alet@unice.fr
------------------------------------------------------------------------ ## Script (Python) "zshell" ##bind container=container ##bind context=context ##bind namespace= ##bind script=script ##bind subpath=traverse_subpath ##parameters= ##title=The Zope Shell ## # zshell - (c) 2001 Jerome Alet # # You're welcome to redistribute this software under the # terms of the GNU General Public Licence version 2.0 # or, at your option, any higher version. # # You can read the complete GNU GPL in the file COPYING # which should come along with this software, or visit # the Free Software Foundation's WEB site http://www.fsf.org # # author: Jerome Alet - <alet@unice.fr> # # # This is the Zope shell, an attempt at making the most common # Unix shell commands available from within Zope. # # As of May 3rd 2001, version 0.001, the following commands # are recognized: # # cd, rm, mv, cp, ls # # * cd accepts a single path as an argument # * rm accepts many path arguments # * mv and cp last argument is the destination folder, every previous # argument is an object id in the current folder # * ls accepts many meta types as its arguments # # The future: # # in the future I'd be interested in adding more functionnalities # as well as making it a complete Zope product, splitting it # in one method per command, and making the accepted syntax much more # match Unix shell's one. # adding support for a find command is also high on my priority list # # Feel free to send me any feedback about this software at: alet@unice.fr #
import string
def toObject(curdir, path) : import string path = string.strip(path) if path[0] == '/' : path = path[1:] while hasattr(curdir, 'aq_parent') and (curdir.aq_parent is not None): curdir = curdir.aq_parent
components = filter(None, string.split(path, '/')) for component in components : if component == '.' : continue elif component == '..' : if hasattr(curdir, 'aq_parent') and (curdir.aq_parent is not None): curdir = curdir.aq_parent elif hasattr(curdir, component) : curdir = curdir[component] else : return None # Error return curdir
print context.standard_html_header.document_src()
if context.REQUEST.has_key("commands") : commands = filter(None, context.REQUEST["commands"]) else : commands = []
print '<p><form action="zshell" method="POST">' print 'Enter your commands below:<br>' print '<textarea rows="10" cols="50" wrap="physical" name="commands:lines">%s</textarea>' % string.join(commands, '\n') print '<br><input type="submit" name="run" value="Run !" />' print '</form></p>'
if commands : print '<hr noshade="noshade" width="33%" /><p>Results:' current = context for command in commands : cmd = command[:2] print '<br><b>%s:</b> ' % cmd if cmd == 'cd' : path = command[3:] newdir = toObject(current, path) if (newdir is not None) and hasattr(newdir, 'meta_type') and (newdir.meta_type == 'Folder') : current = newdir print 'New folder is <em><b>/%s</b></em>' % newdir.absolute_url(relative=1) else : print 'Incorrect path <em><b>%s</b></em>' % path print '[%s]' % repr(newdir) elif (cmd == 'mv') or (cmd == 'cp') : args = string.split(command[3:]) if len(args) < 2 : print 'Incorrect number of arguments' else : dst = args[-1] srcs = args[:-1] objids = [] for src in srcs : if '/' in src : print 'Paths in source objects are not allowed at this time: <em><b>%s</b></em>' % src else : objids.append(src) dsto = toObject(current, dst) if dsto is None : print 'Incorrect destination argument <em><b>%s</b></em>' % dst continue if dsto.meta_type != 'Folder' : print 'Destination <em><b>%s</b></em> is not a folderish object' % dst continue if cmd == 'cp' : clipboard = current.manage_copyObjects(ids = objids) action = 'copied' else : clipboard = current.manage_cutObjects(ids = objids) action = 'moved' dsto.manage_pasteObjects(cb_copy_data = clipboard) for oid in objids : print '<br>%s %s' % (oid, action) elif cmd == 'rm' : objpaths = filter(None, string.split(string.strip(command[3:]))) for objpath in objpaths : object = toObject(current, objpath) if object is None : print 'Incorrect path <em><b>%s</b></em>' % objpath else : if hasattr(object, 'aq_parent') : object.aq_parent.manage_delObjects(ids = [object.getId()]) print "<br>/%s removed" % object.absolute_url(relative=1) elif cmd == 'ls' : metatypes = filter(None, string.split(string.strip(command[3:]))) if metatypes : objects = current.objectValues(metatypes) else : objects = current.objectValues() if objects : print '<table border="1"><tr><th>Id</th><th>Title</th><th>MetaType</th></tr>' for object in objects : title = object.title or ' ' print '<tr><td>%s</td><td>%s</td><td>%s</td></tr>' % (object.getId(), title, object.meta_type) print '</table>' else : print 'Unknown command <em><b>%s</b></em>' % command print '</p>'
print context.standard_html_footer.document_src() return printed
On Fri, 4 May 2001, Jose Soares wrote:
Where on can find Zope Shell version 0.001 ? at http://www.zope.org/Members/sf/zopeshell there's only...
Sorry, it's not the same product. zshell 0.001 is just the script below, but expect a much much more powerful version in minutes. I'll announce it there. bye, Jerome
------------------------------------------------------------------------ ## Script (Python) "zshell" ##bind container=container ##bind context=context ##bind namespace= ##bind script=script ##bind subpath=traverse_subpath ##parameters= ##title=The Zope Shell ## # zshell - (c) 2001 Jerome Alet # # You're welcome to redistribute this software under the # terms of the GNU General Public Licence version 2.0 # or, at your option, any higher version. # # You can read the complete GNU GPL in the file COPYING # which should come along with this software, or visit # the Free Software Foundation's WEB site http://www.fsf.org # # author: Jerome Alet - <alet@unice.fr> # # # This is the Zope shell, an attempt at making the most common # Unix shell commands available from within Zope. # # As of May 3rd 2001, version 0.001, the following commands # are recognized: # # cd, rm, mv, cp, ls # # * cd accepts a single path as an argument # * rm accepts many path arguments # * mv and cp last argument is the destination folder, every previous # argument is an object id in the current folder # * ls accepts many meta types as its arguments # # The future: # # in the future I'd be interested in adding more functionnalities # as well as making it a complete Zope product, splitting it # in one method per command, and making the accepted syntax much more # match Unix shell's one. # adding support for a find command is also high on my priority list # # Feel free to send me any feedback about this software at: alet@unice.fr #
import string
def toObject(curdir, path) : import string path = string.strip(path) if path[0] == '/' : path = path[1:] while hasattr(curdir, 'aq_parent') and (curdir.aq_parent is not None): curdir = curdir.aq_parent
components = filter(None, string.split(path, '/')) for component in components : if component == '.' : continue elif component == '..' : if hasattr(curdir, 'aq_parent') and (curdir.aq_parent is not None): curdir = curdir.aq_parent elif hasattr(curdir, component) : curdir = curdir[component] else : return None # Error return curdir
print context.standard_html_header.document_src()
if context.REQUEST.has_key("commands") : commands = filter(None, context.REQUEST["commands"]) else : commands = []
print '<p><form action="zshell" method="POST">' print 'Enter your commands below:<br>' print '<textarea rows="10" cols="50" wrap="physical" name="commands:lines">%s</textarea>' % string.join(commands, '\n') print '<br><input type="submit" name="run" value="Run !" />' print '</form></p>'
if commands : print '<hr noshade="noshade" width="33%" /><p>Results:' current = context for command in commands : cmd = command[:2] print '<br><b>%s:</b> ' % cmd if cmd == 'cd' : path = command[3:] newdir = toObject(current, path) if (newdir is not None) and hasattr(newdir, 'meta_type') and (newdir.meta_type == 'Folder') : current = newdir print 'New folder is <em><b>/%s</b></em>' % newdir.absolute_url(relative=1) else : print 'Incorrect path <em><b>%s</b></em>' % path print '[%s]' % repr(newdir) elif (cmd == 'mv') or (cmd == 'cp') : args = string.split(command[3:]) if len(args) < 2 : print 'Incorrect number of arguments' else : dst = args[-1] srcs = args[:-1] objids = [] for src in srcs : if '/' in src : print 'Paths in source objects are not allowed at this time: <em><b>%s</b></em>' % src else : objids.append(src) dsto = toObject(current, dst) if dsto is None : print 'Incorrect destination argument <em><b>%s</b></em>' % dst continue if dsto.meta_type != 'Folder' : print 'Destination <em><b>%s</b></em> is not a folderish object' % dst continue if cmd == 'cp' : clipboard = current.manage_copyObjects(ids = objids) action = 'copied' else : clipboard = current.manage_cutObjects(ids = objids) action = 'moved' dsto.manage_pasteObjects(cb_copy_data = clipboard) for oid in objids : print '<br>%s %s' % (oid, action) elif cmd == 'rm' : objpaths = filter(None, string.split(string.strip(command[3:]))) for objpath in objpaths : object = toObject(current, objpath) if object is None : print 'Incorrect path <em><b>%s</b></em>' % objpath else : if hasattr(object, 'aq_parent') : object.aq_parent.manage_delObjects(ids = [object.getId()]) print "<br>/%s removed" % object.absolute_url(relative=1) elif cmd == 'ls' : metatypes = filter(None, string.split(string.strip(command[3:]))) if metatypes : objects = current.objectValues(metatypes) else : objects = current.objectValues() if objects : print '<table border="1"><tr><th>Id</th><th>Title</th><th>MetaType</th></tr>' for object in objects : title = object.title or ' ' print '<tr><td>%s</td><td>%s</td><td>%s</td></tr>' % (object.getId(), title, object.meta_type) print '</table>' else : print 'Unknown command <em><b>%s</b></em>' % command print '</p>'
print context.standard_html_footer.document_src() return printed
participants (6)
-
Chris McDonough -
Jason Cunliffe -
Jerome Alet -
Jose Soares -
Serge Stinckwich -
Tino Wildenhain