~ubuntu-branches/ubuntu/saucy/boa-constructor/saucy

« back to all changes in this revision

Viewing changes to .pc/stdlib.patch/ZopeLib/ZopeExplorer.py

  • Committer: Bazaar Package Importer
  • Author(s): Charlie Smotherman
  • Date: 2011-02-15 17:48:34 UTC
  • mfrom: (7.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110215174834-0mm22h9ffz05jaub
Tags: 0.6.1-11
* debian/source:
  - switched to using source format 3.0 (quilt).
* debian/control:
  - increase min python version to (>=2.6.6-11~).
  - after a discussion with Luca Falavigna I am taking over maintenance of 
    the package.  Added my info to Maintainers: field
  - bumped Standards-Version to 3.9.1, no changes needed.
  - removed dependency on quilt.
  - removed dependency on python-support.
  - use X-P-V instead of XS-P-V, increase version to 2.6
* debian/rules:
  - removed "--with quilt", added "--with python2".
  - changed override to "dh_python2" and corrected syntax.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#-----------------------------------------------------------------------------
 
2
# Name:        ZopeExplorer.py
 
3
# Purpose:
 
4
#
 
5
# Author:      Riaan Booysen & Robert Boulanger
 
6
#
 
7
# Created:     2001/02/04
 
8
# RCS-ID:      $Id: ZopeExplorer.py,v 1.17 2007/07/02 15:01:17 riaan Exp $
 
9
# Copyright:   (c) 2001 - 2007
 
10
# Licence:     GPL
 
11
#-----------------------------------------------------------------------------
 
12
print 'importing ZopeLib.ZopeExplorer'
 
13
 
 
14
import os, urllib, urlparse, time, socket
 
15
from thread import start_new_thread
 
16
 
 
17
import wx
 
18
 
 
19
from Explorers import ExplorerNodes
 
20
from Models import EditorHelper, Controllers
 
21
from ExternalLib import xmlrpclib, BasicAuthTransport
 
22
from Preferences import IS
 
23
import Utils, Preferences
 
24
import Views, Views.SourceViews, Views.PySourceView
 
25
import PaletteStore
 
26
 
 
27
import ZopeEditorModels, ZopeViews, Client, ExtMethDlg
 
28
from ZopeCompanions import ZopeConnection, ZopeCompanion, FolderZC
 
29
 
 
30
# XXX Add owner property
 
31
 
 
32
# XXX root attribute is no longer really necessary
 
33
# XXX Improve '/' management ;)
 
34
 
 
35
class ZopeEClip(ExplorerNodes.ExplorerClipboard):
 
36
    def __init__(self, globClip, props):
 
37
        ExplorerNodes.ExplorerClipboard.__init__(self, globClip)
 
38
        self.clipRef = ''
 
39
 
 
40
        self.props = props
 
41
        self.zc = ZopeConnection()
 
42
        self.zc.connect(props['host'], props['httpport'],
 
43
                        props['username'], props['passwd'])
 
44
    def callAndSetRef(self, objpath, method, nodes):
 
45
        names = [n.name for n in nodes]
 
46
        mime, res = self.zc.call(objpath, method, ids = names)
 
47
        self.clipRef = mime.get('Set-Cookie').split('"')[1]
 
48
    def clipCut(self, node, nodes):
 
49
        ExplorerNodes.ExplorerClipboard.clipCut(self, node, nodes)
 
50
        self.callAndSetRef(node.resourcepath, 'manage_cutObjects', nodes)
 
51
    def clipCopy(self, node, nodes):
 
52
        ExplorerNodes.ExplorerClipboard.clipCopy(self, node, nodes)
 
53
        self.callAndSetRef(node.resourcepath, 'manage_copyObjects', nodes)
 
54
#    def clipPaste(self, node):
 
55
#        ExplorerNodes.ExplorerClipboard.clipPaste(self, node)
 
56
 
 
57
    def clipPaste_ZopeEClip(self, node, nodes, mode):
 
58
        mime, res = self.zc.call(node.resourcepath,
 
59
              'manage_pasteObjects', cb_copy_data = self.clipRef)
 
60
 
 
61
    def clipPaste_FileSysExpClipboard(self, node, nodes, mode):
 
62
        for file in nodes:
 
63
            if file.isDir():
 
64
                node.newFolder(file.name)
 
65
                folderNode = node.createChildNode('Folder', file.name)
 
66
                self.clipPaste_FileSysExpClipboard(folderNode,
 
67
                                                   file.openList(), mode)
 
68
            else:
 
69
                node.uploadFromFS(file)
 
70
 
 
71
class ZopeCatNode(ExplorerNodes.CategoryNode):
 
72
    protocol = 'config.zope'
 
73
    itemProtocol = 'zope'
 
74
 
 
75
    defName = 'Zope'
 
76
    defaultStruct = {'host': 'localhost',
 
77
                     'httpport': 8080,
 
78
                     'localpath': '',
 
79
                     'passwd': '',
 
80
                     'path': '/',
 
81
                     'username': '',
 
82
                     'servicename': '',
 
83
                     'startuptimeout': 30}
 
84
    def __init__(self, globClip, config, parent, bookmarks):
 
85
        ExplorerNodes.CategoryNode.__init__(self, 'Zope', ('explorer', 'zope'),
 
86
              None, config, None)
 
87
        self.globClip = globClip
 
88
        self.bookmarks = bookmarks
 
89
 
 
90
    def createChildNode(self, name, props):
 
91
        # Zope clipboards should be global but unique on site / user
 
92
        clipboard = ZopeEClip(self.globClip, props)
 
93
        zin = ZopeItemNode('', props['path'], clipboard,
 
94
            EditorHelper.imgZopeConnection, self, None, None, props, 'Folder')
 
95
        zin.category = name
 
96
        zin.treename = name
 
97
        zin.bookmarks = self.bookmarks
 
98
        return zin
 
99
 
 
100
    def createCatCompanion(self, catNode):
 
101
        comp = ExplorerNodes.CategoryDictCompanion(catNode.treename, self)
 
102
        return comp
 
103
 
 
104
class ZopeItemNode(ExplorerNodes.ExplorerNode):
 
105
    protocol = 'zope'
 
106
    Model = ZopeEditorModels.ZopeBlankEditorModel
 
107
    defaultViews = ()
 
108
    additionalViews = (ZopeViews.ZopeSecurityView,
 
109
                       ZopeViews.ZopeUndoView)
 
110
    itemsSubPath = ''
 
111
    connection = False
 
112
    def __init__(self, name, resourcepath, clipboard, imgIdx, parent, xmlrpcsvr,
 
113
          root, properties, metatype):
 
114
        ExplorerNodes.ExplorerNode.__init__(self, name, resourcepath, clipboard,
 
115
              imgIdx, None, properties)
 
116
        self.metatype = metatype
 
117
        self.image = imgIdx
 
118
        self.root = None
 
119
        self.cache = {}
 
120
        self.server = xmlrpcsvr
 
121
        self.entries = None
 
122
        self.entryIds = None
 
123
        self.typ = None
 
124
 
 
125
    def getURI(self):
 
126
        return '%s://%s/<%s>%s'%(self.protocol, self.category, self.metatype, self.getTitle())
 
127
 
 
128
    def buildUrl(self):
 
129
        path = urllib.quote(self.resourcepath)
 
130
        if path:
 
131
            if path == '/':
 
132
                path = '//'
 
133
            if path[0] != '/':
 
134
                path = '/'+path
 
135
        else:
 
136
            path = '//'
 
137
        return '%(host)s:%(httpport)d' % self.properties + path
 
138
 
 
139
    def destroy(self):
 
140
        self.cache = {}
 
141
        self.root = None
 
142
        self.parent = None
 
143
 
 
144
    def canAdd(self, paletteName):
 
145
        return paletteName == 'Zope'
 
146
 
 
147
    def createChildNode(self, metatype, id, respath=None):
 
148
        if respath is None:
 
149
            respath = self.resourcepath
 
150
 
 
151
        if respath == '/':
 
152
            tmppath = respath + self.itemsSubPath + id
 
153
        else:
 
154
            tmppath = respath + self.itemsSubPath + '/' + id
 
155
 
 
156
        itm = self.checkentry(id, metatype, tmppath)
 
157
        if itm.imgIdx == -1:
 
158
            itm.imgIdx = ZopeEditorModels.ZOAIcons.get(metatype,
 
159
                         ZopeEditorModels.ZOAIcons['unknown'])
 
160
        itm.category = self.category
 
161
        itm.bookmarks = self.bookmarks
 
162
        return itm
 
163
 
 
164
    def checkentry(self, name, metatype, path):
 
165
        ZopeNodeClass = zopeClassMap.get(metatype, ZopeItemNode)
 
166
        return ZopeNodeClass(*(name, path, self.clipboard, -1, self,
 
167
            self.server, self.root, self.properties, metatype))
 
168
 
 
169
    def whole_name(self):
 
170
        return self.resourcepath
 
171
 
 
172
    def getResource(self, url=''):
 
173
        if not url:
 
174
            url = self.buildUrl()
 
175
        return getServer(url, self.properties['username'],
 
176
               self.properties['passwd'])
 
177
 
 
178
    def getParentResource(self):
 
179
        path, name = os.path.split(self.name)
 
180
        return self.getResource(os.path.dirname(self.buildUrl())), name
 
181
 
 
182
    def openList(self, root = None):
 
183
        url = self.buildUrl()+self.itemsSubPath
 
184
        if url[-1] == '/':
 
185
            url = url[:-1]
 
186
        self.server = self.getResource(url)
 
187
        try:
 
188
            self.entries, self.entryIds = self.server.zoa.items()
 
189
        except xmlrpclib.Fault, error:
 
190
            #print str(error)
 
191
            # see if zoa object is installed
 
192
            try:
 
193
                Client.call('http://%s/zoa'%self.buildUrl(),
 
194
                      self.properties['username'], self.properties['passwd'],
 
195
                      function='version')
 
196
            except Client.NotFound:
 
197
                if wx.MessageBox(
 
198
                  'The zoa object not found in the root of your Zope tree.\n\n'
 
199
                  'Do you want to install it?', 'Install zoa',
 
200
                  wx.YES_NO | wx.ICON_QUESTION) == wx.YES:
 
201
 
 
202
                    import ZoaClient
 
203
                    conninfo = ('http://%s'%self.buildUrl(),
 
204
                         self.properties['username'], self.properties['passwd'])
 
205
                    ZoaClient.installFromFS(conninfo,
 
206
                          os.path.join(Preferences.pyPath, 'ZopeLib', 'zoa', ))
 
207
 
 
208
                    # try again, if this fails the real error should break thru
 
209
                    self.entries, self.entryIds = self.server.zoa.items()
 
210
 
 
211
            else:
 
212
                err = error.faultString
 
213
                raise zopeHtmlErr2Strs(err)
 
214
 
 
215
        self.cache = {}
 
216
        result = []
 
217
        if self.entryIds:
 
218
            for i in range(len(self.entries)):
 
219
                z = self.createChildNode(self.entries[i], self.entryIds[i] )
 
220
                if z:
 
221
                    result.append(z)
 
222
                    self.cache[self.entryIds[i]] = z
 
223
        return result
 
224
 
 
225
    def isFolderish(self):
 
226
        return True
 
227
 
 
228
    def getTitle(self):
 
229
        return self.resourcepath
 
230
 
 
231
    def open(self, editor):
 
232
        return editor.openOrGotoZopeDocument(self)
 
233
 
 
234
    def deleteItems(self, names):
 
235
        mime, res = self.clipboard.zc.call(self.resourcepath,
 
236
              'manage_delObjects', ids = names)
 
237
 
 
238
    def renameItem(self, name, newName):
 
239
        mime, res = self.clipboard.zc.call(self.resourcepath,
 
240
              'manage_renameObject', id = name, new_id = newName)
 
241
 
 
242
    def exportObj(self):
 
243
        mime, res = self.clipboard.zc.call(os.path.dirname(self.resourcepath),
 
244
              'manage_exportObject', download = 1, id = self.name)
 
245
        return res
 
246
 
 
247
    def uploadObj(self, content):
 
248
        mime, res = self.clipboard.zc.call(self.resourcepath,
 
249
              'manage_upload', file = content)
 
250
        return res
 
251
 
 
252
    def listImportFiles(self):
 
253
        if self.properties.has_key('localpath') and self.properties['localpath']:
 
254
            from Explorers import Explorer
 
255
            return Explorer.listdirEx(self.properties['localpath']+'/import', '.zexp')
 
256
        else:
 
257
            return []
 
258
 
 
259
    def importObj(self, name):
 
260
        try:
 
261
            mime, res = self.clipboard.zc.call(self.resourcepath, 'manage_importObject', file = name)
 
262
        except Exception, message:
 
263
            wx.MessageBox(`message.args`, 'Error on import')
 
264
            #raise
 
265
 
 
266
    def newItem(self, name, Compn, getNewValidName = True):
 
267
        props = self.properties
 
268
        if getNewValidName:
 
269
            name = Utils.getValidName(self.cache.keys(), name)
 
270
        cmp = Compn(name, self.resourcepath, props.get('localpath', ''))
 
271
        cmp.connect(props['host'], props['httpport'],
 
272
                    props['username'], props['passwd'])
 
273
        cmp.create()
 
274
 
 
275
        return cmp.name
 
276
 
 
277
    def getUndoableTransactions(self):
 
278
        from ZopeLib.DateTime import DateTime
 
279
        svr, name = self.getParentResource()
 
280
        return eval(svr.zoa.undo(name), {})
 
281
 
 
282
    def undoTransaction(self, transactionIds):
 
283
        self.getResource().manage_undo_transactions(transactionIds)
 
284
 
 
285
    def getPermissions(self):
 
286
        return self.getResource().permission_settings()#ZOA('permissions')
 
287
 
 
288
    def getRoles(self):
 
289
        return self.getResource().valid_roles()
 
290
 
 
291
    def load(self, mode='rb'):
 
292
        return ''#return self.getResource().document_src()
 
293
 
 
294
 
 
295
    def save(self, filename, data, mode='wb'):
 
296
        """ Saves contents of data to Zope """
 
297
        pass#self.getResource().manage_upload(data)
 
298
 
 
299
    def newFolder(self, name):
 
300
        self.getResource().manage_addFolder(name)
 
301
 
 
302
    def newBlankDocument(self, name=''):
 
303
        try:
 
304
            self.getResource().manage_addDTMLDocument(name)
 
305
        except xmlrpclib.ProtocolError, error:
 
306
            if error.errcode != 302:
 
307
                raise
 
308
 
 
309
    def uploadFromFS(self, filenode):
 
310
        props = self.properties
 
311
        from ExternalLib.WebDAV.client import Resource
 
312
        r = Resource(('http://%(host)s:%(httpport)s/'+self.resourcepath+'/'+\
 
313
            filenode.name) % props, props['username'], props['passwd'])
 
314
        r.put(filenode.load())
 
315
 
 
316
    def downloadToFS(self, filename):
 
317
        open(filename, 'wb').write(self.getResource().manage_FTPget())
 
318
 
 
319
    def getNodeFromPath(self, respath, metatype):
 
320
        return self.createChildNode(metatype, os.path.basename(respath),
 
321
              os.path.dirname(respath))
 
322
 
 
323
    def findItems(self, obj_ids=(), obj_metatypes=None, obj_searchterm=None,
 
324
          search_sub=1):
 
325
        # silly xml-rpc restrictions
 
326
        if obj_metatypes is None: obj_metatypes=0
 
327
        if obj_searchterm is None: obj_searchterm=0
 
328
        if not search_sub: search_sub=''
 
329
 
 
330
        return self.getResource().zoa.find(obj_ids, obj_metatypes, obj_searchterm)
 
331
 
 
332
 
 
333
(wxID_ZOPEEXPORT, wxID_ZOPEIMPORT, wxID_ZOPEINSPECT, wxID_ZOPEOPENINEDITOR,
 
334
 wxID_ZOPEUPLOAD, wxID_ZOPESECURITY, wxID_ZOPEUNDO, wxID_ZOPEVIEWBROWSER,
 
335
 wxID_ZCCSTART, wxID_ZCCRESTART, wxID_ZCCSHUTDOWN, wxID_ZCCTEST, wxID_ZCCOPENLOG,
 
336
 wxID_ZACONFZ2, wxID_ZOPEMANAGEBROWSER, wxID_ZOPEFIND,
 
337
 wxID_ZCOPENZ2, wxID_ZCBREAKINTO,
 
338
) = Utils.wxNewIds(18)
 
339
 
 
340
class ZopeCatController(ExplorerNodes.CategoryController):
 
341
    protocol = 'config.zope'
 
342
    zopeStatupTimeout = 60 # default when not read from property
 
343
    zopeRunning = 'The server is available'
 
344
    err_zopeNotRunning = 'The server is not running'
 
345
    err_localpathBlank = 'The "localpath" property must be defined'
 
346
    def __init__(self, editor, list, inspector, controllers, menuDefs = []):
 
347
        zccMenuDef = [ (-1, '-', None, '-'),
 
348
                       (wxID_ZCCSTART, 'Start', self.OnStart, '-'),
 
349
                       (wxID_ZCCRESTART, 'Restart', self.OnRestart, '-'),
 
350
                       (wxID_ZCCSHUTDOWN, 'Shutdown', self.OnShutdown, '-'),
 
351
                       (wxID_ZCCTEST, 'Test', self.OnTest, '-'),
 
352
                       (-1, '-', None, '-'),
 
353
                       (wxID_ZCCOPENLOG, 'Open Zope log', self.OnOpenZopeLog, '-'),
 
354
#                       (wxID_ZACONFZ2, 'Configure z2.py', self.OnConfigureZ2py, '-'),
 
355
                       (-1, '-', None, '-'),
 
356
                       (wxID_ZCOPENZ2, 'Open z2.py', self.OnOpenZ2, '-'),
 
357
                       (wxID_ZCBREAKINTO, 'Break into', self.OnBreakInto, '-'),
 
358
                     ]
 
359
        ExplorerNodes.CategoryController.__init__(self, editor, list, inspector,
 
360
              controllers, menuDefs = menuDefs + zccMenuDef)
 
361
 
 
362
    def checkAvailability(self, props, timeout=10, showDlg=True):
 
363
        retry = True
 
364
        dlg = None
 
365
        while retry:
 
366
            retry = False
 
367
            if showDlg and not dlg:
 
368
                dlg = wx.ProgressDialog('Testing %s'% props['host'],
 
369
                               'Checking availability...', 100, self.editor,
 
370
                               wx.PD_CAN_ABORT | wx.PD_APP_MODAL | wx.PD_AUTO_HIDE)
 
371
            try:
 
372
                now = time.time()
 
373
                res = ''
 
374
                while not timeout or time.time() < now + timeout:
 
375
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
376
                    try:
 
377
                        s.connect( (props['host'], props['httpport']) )
 
378
                    except socket.error, err:
 
379
                        if err[0] == 10061:
 
380
                            # not running
 
381
                            res = self.err_zopeNotRunning
 
382
                            if time.time() > now + timeout and \
 
383
                                  wx.MessageBox('Keep checking for Zope to become available',
 
384
                                  'Retry?', style=wx.YES_NO | wx.ICON_QUESTION) == wx.YES:
 
385
                                retry = True
 
386
                        else:
 
387
                            res = 'Socket error: '+err[1]
 
388
                    else:
 
389
                        res = self.zopeRunning
 
390
 
 
391
                    if not timeout:
 
392
                        break
 
393
            finally:
 
394
                if showDlg:
 
395
                    dlg.Destroy()
 
396
 
 
397
        return res
 
398
 
 
399
    def getControlPanel(self, props):
 
400
        return getServer('%(host)s:%(httpport)d/Control_Panel' % props,
 
401
            props['username'], props['passwd'])
 
402
 
 
403
    def callControlPanelMethod(self, props, meth):
 
404
        zc = ZopeConnection()
 
405
        zc.connect(props['host'], props['httpport'],
 
406
                   props['username'], props['passwd'])
 
407
        zc.call('/Control_Panel', meth)
 
408
 
 
409
    def OnStart(self, event):
 
410
        for node in self.getNodesForSelection(self.list.getMultiSelection()):
 
411
            props = node.properties
 
412
            try: zopeStatupTimeout = props['startuptimeout']
 
413
            except KeyError: zopeStatupTimeout = self.zopeStatupTimeout
 
414
 
 
415
            if props['servicename']:
 
416
                os.system('net start "%s"'%props['servicename'])
 
417
                self.checkAvailability(node.properties, zopeStatupTimeout)
 
418
            elif props['localpath']:
 
419
                if props['localpath'].find(' ') != -1:
 
420
                    wx.LogError('Localpath property may not contain spaces (use SHORT~1 version if necessary)')
 
421
                else:
 
422
                    os.system('start %s\\start.bat'%props['localpath'])
 
423
                    self.checkAvailability(node.properties, zopeStatupTimeout)
 
424
            else:
 
425
                wx.LogError('Unable to start '+node.treename)
 
426
 
 
427
    def OnRestart(self, event):
 
428
        for node in self.getNodesForSelection(self.list.getMultiSelection()):
 
429
            props = node.properties
 
430
            try: zopeStatupTimeout = props['startuptimeout']
 
431
            except KeyError: zopeStatupTimeout = self.zopeStatupTimeout
 
432
            try:
 
433
                self.callControlPanelMethod(node.properties, 'manage_restart')
 
434
                resp = self.checkAvailability(node.properties, zopeStatupTimeout)
 
435
                if resp == 'The server is available':
 
436
                    self.editor.setStatus(resp)
 
437
                else:
 
438
                    self.editor.setStatus(resp, 'Warning')
 
439
            except Exception, error:
 
440
                wx.LogError('Restart not supported for '+node.treename+'\n'+str(error))
 
441
 
 
442
    def OnShutdown(self, event):
 
443
        for node in self.getNodesForSelection(self.list.getMultiSelection()):
 
444
            self.callControlPanelMethod(node.properties, 'manage_shutdown')
 
445
 
 
446
    def OnTest(self, event):
 
447
        for node in self.getNodesForSelection(self.list.getMultiSelection()):
 
448
            wx.LogMessage( '%s : %s' % (node.treename,
 
449
                self.checkAvailability(node.properties, 0)))
 
450
 
 
451
    def OnOpenZopeLog(self, event):
 
452
        for node in self.getNodesForSelection(self.list.getMultiSelection()):
 
453
            props = node.properties
 
454
            if props['localpath']:
 
455
                self.editor.openOrGotoModule(os.path.join(props['localpath'],
 
456
                      'var', 'Z2.log'))
 
457
            else:
 
458
                wx.LogError(self.err_localpathBlank)
 
459
 
 
460
    def OnConfigureZ2py(self, event):
 
461
        # XXX Disabled for now until only useful values are displayed
 
462
        # XXX Or until someone complains :)
 
463
        node = self.getNodesForSelection(self.list.getMultiSelection())
 
464
        if len(node):
 
465
            node = node[0]
 
466
        else:
 
467
            print 'Nothing selected'
 
468
 
 
469
        props = node.properties
 
470
        if props['localpath']:
 
471
            cfgZ2SrcNode = ZopeZ2pySourceBasedPrefColNode('Z2.py',
 
472
                  ('*',), props['localpath']+'/z2.py', -1, node)
 
473
            cfgZ2SrcNode.open(self.editor)
 
474
        else:
 
475
            wx.LogError(self.err_localpathBlank)
 
476
 
 
477
    def OnOpenZ2(self, event):
 
478
        for node in self.getNodesForSelection(self.list.getMultiSelection()):
 
479
            localpath = node.properties['localpath']
 
480
            if localpath:
 
481
                self.editor.openOrGotoModule(localpath+'/z2.py')
 
482
            else:
 
483
                wx.LogError(self.err_localpathBlank)
 
484
 
 
485
    def breakpointInBackground(self, zc):
 
486
        zc.call('zoa', 'breakpoint')
 
487
 
 
488
    def OnBreakInto(self, event):
 
489
        for node in self.getNodesForSelection(self.list.getMultiSelection()):
 
490
            props = node.properties
 
491
            zc = ZopeConnection()
 
492
            zc.connect(props['host'], props['httpport'],
 
493
                       props['username'], props['passwd'])
 
494
            start_new_thread(self.breakpointInBackground, (zc,))
 
495
 
 
496
 
 
497
# XXX Better field validation and hints as to when path props shound end in / or not !!
 
498
 
 
499
class ZopeController(ExplorerNodes.Controller, ExplorerNodes.ClipboardControllerMix):
 
500
    inspectBmp = 'Images/Shared/Inspector.png'
 
501
    importBmp = 'Images/Shared/ZopeImport.png'
 
502
    exportBmp = 'Images/Shared/ZopeExport.png'
 
503
    uploadBmp = 'Images/ZOA/upload_doc.png'
 
504
    viewInBrowserBmp = 'Images/ZOA/ViewInBrowser.png'
 
505
    findBmp = 'Images/Shared/Find.png'
 
506
    def __init__(self, editor, list, inspector, controllers):
 
507
        ExplorerNodes.ClipboardControllerMix.__init__(self)
 
508
        ExplorerNodes.Controller.__init__(self, editor)
 
509
 
 
510
        self.list = list
 
511
        self.menu = wx.Menu()
 
512
        self.inspector = inspector
 
513
 
 
514
        self.zopeMenuDef = [
 
515
            (wxID_ZOPEINSPECT, 'Inspect', self.OnInspectItem, self.inspectBmp),
 
516
            (-1, '-', None, '') ] +\
 
517
            self.clipMenuDef +\
 
518
          [ (-1, '-', None, ''),
 
519
            (wxID_ZOPEFIND, 'Find', self.OnFindZopeItems, self.findBmp),
 
520
            (-1, '-', None, ''),
 
521
            (wxID_ZOPEUPLOAD, 'Upload', self.OnUploadZopeItem, self.uploadBmp),
 
522
            (wxID_ZOPEEXPORT, 'Export', self.OnExportZopeItem, self.exportBmp),
 
523
            (wxID_ZOPEIMPORT, 'Import', self.OnImportZopeItem, self.importBmp),
 
524
            (-1, '-', None, '-'),
 
525
            (wxID_ZOPEOPENINEDITOR, 'Open in Editor', self.OnOpenInEditorZopeItem, '-'),
 
526
            (wxID_ZOPESECURITY, 'Security', self.OnSecurityZopeItem, '-'),
 
527
            (wxID_ZOPEUNDO,     'Undo',     self.OnUndoZopeItem, '-'),
 
528
            (-1, '-', None, ''),
 
529
            (wxID_ZOPEVIEWBROWSER,'View in browser', self.OnViewInBrowser, self.viewInBrowserBmp),
 
530
            (wxID_ZOPEMANAGEBROWSER,'Manage in browser', self.OnManageInBrowser, '-'),
 
531
        ]
 
532
 
 
533
        self.setupMenu(self.menu, self.list, self.zopeMenuDef)
 
534
        self.toolbarMenus = [self.zopeMenuDef]
 
535
 
 
536
    def destroy(self):
 
537
        ExplorerNodes.ClipboardControllerMix.destroy(self)
 
538
        self.zopeMenuDef = ()
 
539
        self.toolbarMenus = ()
 
540
        self.menu.Destroy()
 
541
 
 
542
    def OnExportZopeItem(self, event):
 
543
        if self.list.node:
 
544
            idxs = self.list.getMultiSelection()
 
545
            currPath = '.'
 
546
            for idx in idxs:
 
547
                item = self.list.items[idx]
 
548
                if item:
 
549
                    zexp = item.exportObj()
 
550
 
 
551
                    from FileDlg import wxFileDialog
 
552
                    dlg = wxFileDialog(self.list, 'Save as...', currPath,
 
553
                          item.name+'.zexp', '', wx.SAVE | wx.OVERWRITE_PROMPT)
 
554
                    try:
 
555
                        if dlg.ShowModal() == wx.ID_OK:
 
556
                            zexpFile = dlg.GetFilePath()
 
557
                            open(zexpFile, 'wb').write(zexp)
 
558
                            currPath = os.path.dirname(zexpFile)
 
559
                    finally:
 
560
                        dlg.Destroy()
 
561
 
 
562
    def OnImportZopeItem(self, event):
 
563
        fls = self.list.node.listImportFiles()
 
564
 
 
565
        if fls:
 
566
            dlg = wx.SingleChoiceDialog(self.list, 'Choose the file to import', 'Import object', fls)
 
567
            try:
 
568
                if dlg.ShowModal() == wx.ID_OK:
 
569
                    zexp = dlg.GetStringSelection()
 
570
                else:
 
571
                    return
 
572
            finally:
 
573
                dlg.Destroy()
 
574
        else:
 
575
            dlg = wx.TextEntryDialog(self.list, 'Enter file to import', 'Import object', '.zexp')
 
576
            try:
 
577
                if dlg.ShowModal() == wx.ID_OK:
 
578
                    zexp = dlg.GetValue()
 
579
                else:
 
580
                    return
 
581
            finally:
 
582
                dlg.Destroy()
 
583
 
 
584
        self.list.node.importObj(zexp)
 
585
        self.list.refreshCurrent()
 
586
 
 
587
    def doInspectZopeItem(self, zopeItem):
 
588
        props = zopeItem.properties
 
589
        try:
 
590
            ZComp = PaletteStore.compInfo[zopeItem.metatype][1]
 
591
        except KeyError:
 
592
            ZComp = ZopeCompanion
 
593
 
 
594
        zc = ZComp(zopeItem.name, zopeItem.resourcepath)
 
595
        zc.connect(props['host'], props['httpport'],
 
596
                   props['username'], props['passwd'])
 
597
        zc.updateZopeProps()
 
598
 
 
599
        self.inspector.selectObject(zc, False, focusPage=1)
 
600
 
 
601
    def OnInspectItem(self, event):
 
602
        if self.list.node:
 
603
            # Create new companion for selection
 
604
            zopeItem = self.list.getSelection()
 
605
            if not zopeItem: zopeItem = self.list.node
 
606
            self.doInspectZopeItem(zopeItem)
 
607
 
 
608
    def OnUploadZopeItem(self, event):
 
609
        if self.list.node:
 
610
            idxs = self.list.getMultiSelection()
 
611
            currPath = '.'
 
612
            for idx in idxs:
 
613
                item = self.list.items[idx]
 
614
                if item:
 
615
                    from FileDlg import wxFileDialog
 
616
                    dlg = wxFileDialog(self.list, 'Upload '+item.name, currPath,
 
617
                          item.name, '', wx.OPEN)
 
618
                    try:
 
619
                        if dlg.ShowModal() == wx.ID_OK:
 
620
                            try:
 
621
                                # XXX Update to handle all transports
 
622
                                item.uploadObj(open(dlg.GetFilePath(), 'rb'))#.read())
 
623
                            except Client.NotFound:
 
624
                                wx.MessageBox('Object does not support uploading', 'Error on upload')
 
625
                            currPath = dlg.GetDirectory()
 
626
                    finally:
 
627
                        dlg.Destroy()
 
628
 
 
629
    def OnSecurityZopeItem(self, event):
 
630
        if self.list.node:
 
631
            zopeItem = self.list.getSelection()
 
632
            if zopeItem:
 
633
                model, cntrlr = self.editor.openOrGotoZopeDocument(zopeItem)
 
634
                viewName = ZopeViews.ZopeSecurityView.viewName
 
635
                if not model.views.has_key(viewName):
 
636
                    resultView = self.editor.addNewView(viewName,
 
637
                          ZopeViews.ZopeSecurityView)
 
638
                else:
 
639
                    resultView = model.views[viewName]
 
640
                resultView.refresh()
 
641
                resultView.focus()
 
642
 
 
643
    def OnUndoZopeItem(self, event):
 
644
        if self.list.node:
 
645
            zopeItem = self.list.getSelection()
 
646
            if zopeItem and ZopeViews.ZopeUndoView in zopeItem.additionalViews:
 
647
                model, cntrlr = self.editor.openOrGotoZopeDocument(zopeItem)
 
648
                viewName = ZopeViews.ZopeUndoView.viewName
 
649
                if not model.views.has_key(viewName):
 
650
                    resultView = self.editor.addNewView(viewName,
 
651
                          ZopeViews.ZopeUndoView)
 
652
                else:
 
653
                    resultView = model.views[viewName]
 
654
                resultView.refresh()
 
655
                resultView.focus()
 
656
 
 
657
    def openSelItemInBrowser(self, addToUrl='', zopeItem=None):
 
658
        if self.list.node:
 
659
            if not zopeItem:
 
660
                zopeItem = self.list.getSelection()
 
661
 
 
662
            if not zopeItem:
 
663
                raise Exception, 'No item selected'
 
664
            try:
 
665
                import webbrowser
 
666
                webbrowser.open('http://%s%s'%(zopeItem.buildUrl(), addToUrl))
 
667
            except ImportError:
 
668
                raise Exception, 'Python 2.0 or higher required'
 
669
 
 
670
    def OnViewInBrowser(self, event):
 
671
        self.openSelItemInBrowser()
 
672
 
 
673
    def OnManageInBrowser(self, event):
 
674
        self.openSelItemInBrowser('/manage')
 
675
 
 
676
    def OnOpenInEditorZopeItem(self, event):
 
677
        if self.list.node:
 
678
            zopeItem = self.list.getSelection()
 
679
            if zopeItem:
 
680
                model, cntrlr = self.editor.openOrGotoZopeDocument(zopeItem)
 
681
 
 
682
    def OnFindZopeItems(self, event):
 
683
        node = self.list.node
 
684
        if node:
 
685
            from ZopeFindDlg import ZopeFindDlg
 
686
            dlg = ZopeFindDlg(self.editor)
 
687
            try:
 
688
                if dlg.ShowModal() == wx.ID_OK:
 
689
                    res = dlg.objIds.GetValue().split(',') or ()
 
690
                    obj_ids = []
 
691
                    for zid in res:
 
692
                        zid = zid.strip()
 
693
                        if zid:
 
694
                            obj_ids.append(zid)
 
695
                    meta_type = 0
 
696
                    search_text = dlg.searchText.GetValue() or 0
 
697
                    search_sub = dlg.recurse.GetValue()
 
698
 
 
699
                    wx.BeginBusyCursor()
 
700
                    try:
 
701
                        results = node.findItems(obj_ids, meta_type,
 
702
                                                 search_text, search_sub)
 
703
                    finally:
 
704
                        wx.EndBusyCursor()
 
705
 
 
706
                    bookmarks, category = node.bookmarks, node.category
 
707
                    self.list.node = node = ZopeResultsFolderNode(
 
708
                          'Zope Find Results', node.resourcepath,
 
709
                          node.clipboard, -1, node, node.server, node.root,
 
710
                          node.properties, 'Zope Find Results')
 
711
                    node.bookmarks = bookmarks
 
712
                    node.category = category
 
713
 
 
714
                    node.results = results
 
715
                    #node.lastSearch = dlg.GetValue()
 
716
 
 
717
                    # Collapse possible current contents in tree
 
718
                    tree = self.editor.explorer.tree
 
719
                    item = tree.GetSelection()
 
720
                    tree.CollapseAndReset(item)
 
721
 
 
722
                    self.list.refreshCurrent()
 
723
 
 
724
            finally:
 
725
                dlg.Destroy()
 
726
 
 
727
 
 
728
def getServer(url, user, password):
 
729
    return xmlrpclib.Server('http://' + url,
 
730
              BasicAuthTransport.BasicAuthTransport(user, password) )
 
731
 
 
732
class ZopeNode(ZopeItemNode):
 
733
    def load(self, mode='rb'):
 
734
        return self.getResource().document_src()
 
735
 
 
736
    def save(self, filename, data, mode='wb'):
 
737
        """ Saves contents of data to Zope """
 
738
        self.getResource().manage_upload(data)
 
739
 
 
740
    def isFolderish(self):
 
741
        return False
 
742
 
 
743
class ZopeImageNode(ZopeNode):
 
744
    pass
 
745
 
 
746
class DirNode(ZopeItemNode): pass
 
747
 
 
748
class UserFolderNode(ZopeItemNode):
 
749
    def deleteItems(self, names):
 
750
        print 'User Folder delete: %s'%names
 
751
#        mime, res = self.clipboard.zc.call(self.resourcepath,
 
752
#              'manage_delObjects', ids = names)
 
753
 
 
754
class ZopeUserNode(ZopeNode):
 
755
    def isFolderish(self):
 
756
        return False
 
757
    def open(self, editor):
 
758
        print 'Should inspect'
 
759
        #editor.openOrGotoZopeDocument(self)
 
760
 
 
761
class ControlNode(DirNode):
 
762
    def checkentry(self, id, entry, path):
 
763
        if entry == 'Product Management':
 
764
            childnode = PMNode(id, path, self.clipboard, -1, self,
 
765
                self.server, self.root, self.properties, entry)
 
766
        else:
 
767
            childnode = DirNode.checkentry(self, id, entry, path)
 
768
        return childnode
 
769
 
 
770
class PMNode(ControlNode):
 
771
    def checkentry(self,id,entry,path):
 
772
        if entry == 'Product' :
 
773
            childnode = ProductNode(id, path, self.clipboard, -1, self,
 
774
            self.server, self.root, self.properties, entry)
 
775
        else:
 
776
            childnode = ControlNode.checkentry(self, id, entry, path)
 
777
        return childnode
 
778
 
 
779
class ProductNode(DirNode):
 
780
    def checkentry(self, id, entry, path):
 
781
        if entry == 'Z Class' :
 
782
            childnode = ZClassNode(id, path, self.clipboard, -1, self,
 
783
                self.server, self.root, self.properties, entry)
 
784
        else:
 
785
            childnode = DirNode.checkentry(self, id, entry, path)
 
786
        return childnode
 
787
 
 
788
class ZClassNode(DirNode):
 
789
    itemsSubPath = '/propertysheets/methods'
 
790
##    def __init__(self, name, resourcepath, clipboard, imgIdx, parent, xmlrpcsvr, root, properties, metatype):
 
791
##        resourcepath = resourcepath + '/propertysheets/methods'
 
792
##        DirNode.__init__(self, name, resourcepath, clipboard, imgIdx, parent,
 
793
##              xmlrpcsvr, root, properties, metatype)
 
794
 
 
795
# Thanks to M. Adam Kendall (akendall) for fixing save
 
796
class ZSQLNode(ZopeNode):
 
797
    Model = ZopeEditorModels.ZopeSQLMethodModel
 
798
    defaultViews = (ZopeViews.ZopeHTMLSourceView,)
 
799
    additionalViews = (ZopeViews.ZopeSecurityView, ZopeViews.ZopeUndoView)
 
800
    def getParams(self, data):
 
801
        return data.split('<params>')[1].split('</params>')[0]
 
802
    def getBody(self, data):
 
803
        return data.split('</params>')[1].lstrip()
 
804
    def save(self, filename, data, mode='wb'):
 
805
        """ Saves contents of data to Zope """
 
806
        props = self.getResource().zoa.props.SQLMethod()
 
807
        try:
 
808
            title = props['title']
 
809
            connection_id = props['connection_id']
 
810
            arguments = self.getParams(data)
 
811
            template = self.getBody(data)
 
812
            self.getResource().manage_edit(title, connection_id, arguments, template)
 
813
        except xmlrpclib.ProtocolError, error:
 
814
            # Getting a zero content warning is not an error
 
815
            if error.errcode != 204:
 
816
                raise ExplorerNodes.TransportSaveError(error, filename)
 
817
        except Exception, error:
 
818
            raise ExplorerNodes.TransportSaveError(error, filename)
 
819
 
 
820
class PythonNode(ZopeNode):
 
821
    Model = ZopeEditorModels.ZopePythonScriptModel
 
822
    defaultViews = (Views.PySourceView.PythonSourceView,)
 
823
    additionalViews = (ZopeViews.ZopeSecurityView, Views.EditorViews.ToDoView,
 
824
                       ZopeViews.ZopeUndoView)
 
825
 
 
826
    def getParams(self, data):
 
827
        return data[data.find('(')+1 : data.find('):')]
 
828
 
 
829
    def getBody(self, data):
 
830
        tmp = data[data.find(':')+2:].split('\n')
 
831
        tmp2 = []
 
832
        for l in tmp:
 
833
            # Handle comments which may be indented less
 
834
            if l[:4].strip():
 
835
                l = l.lstrip()
 
836
            else:
 
837
                l = l[4:]
 
838
            tmp2.append(l)
 
839
        return '\n'.join(tmp2)
 
840
 
 
841
    def save(self, filename, data, mode='wb'):
 
842
        self.getResource().manage_edit(self.name, self.getParams(data),
 
843
              self.getBody(data))
 
844
 
 
845
class PythonScriptNode(PythonNode):
 
846
    additionalViews = (ZopeViews.ZopeSecurityView,
 
847
          ZopeViews.ZopeUndoView, Views.EditorViews.ToDoView)
 
848
 
 
849
    def preparedata(self, data):
 
850
        tmp=data.split('\n')
 
851
        tmp2=[]
 
852
        h=1
 
853
        for l in tmp:
 
854
            if l[:2] <> '##' :
 
855
                h=0
 
856
            if l[:12] == '##parameters':
 
857
                params = l[l.find('=')+1:]
 
858
            if h:
 
859
                pass # perhaps we need this anytime
 
860
            else:
 
861
                tmp2.append('    ' + l)
 
862
        return 'def %s(%s):\n%s' % (self.name, params, '\n'.join(tmp2))
 
863
 
 
864
    def load(self, mode='rb'):
 
865
        data = PythonNode.load(self, mode)
 
866
        return self.preparedata(data)
 
867
 
 
868
    def save(self, filename, data, mode='wb'):
 
869
        self.getResource().ZPythonScriptHTML_editAction('fake',
 
870
              self.name, self.getParams(data), self.getBody(data))
 
871
 
 
872
class ExtPythonNode(PythonNode):
 
873
    Model = ZopeEditorModels.ZopeExternalMethodModel
 
874
    defaultViews = (Views.PySourceView.PythonSourceView,
 
875
                    Views.EditorViews.ExploreView)
 
876
    additionalViews = (Views.EditorViews.HierarchyView,
 
877
                       Views.EditorViews.ModuleDocView,
 
878
                       ZopeViews.ZopeSecurityView, Views.EditorViews.ToDoView,
 
879
                       ZopeViews.ZopeUndoView)
 
880
 
 
881
 
 
882
    def openTransportFromProperties(self):
 
883
        zopePath = self.properties['localpath']
 
884
 
 
885
        svr, name = self.getParentResource()
 
886
        res = svr.zoa.props.ExternalMethod(name)
 
887
 
 
888
        module = res['module']
 
889
 
 
890
        emf = ExtMethDlg.ExternalMethodFinder(zopePath)
 
891
        extPath = emf.getExtPath(module)
 
892
 
 
893
        from Explorers import Explorer
 
894
        return Explorer.openEx(extPath)
 
895
 
 
896
    def load(self, mode='rb'):
 
897
        return self.openTransportFromProperties().load(mode=mode)
 
898
 
 
899
    def save(self, filename, data, mode='wb'):
 
900
        transp = self.openTransportFromProperties()
 
901
        transp.save(transp.currentFilename(), data, mode)
 
902
 
 
903
class DTMLDocNode(ZopeNode):
 
904
    Model = ZopeEditorModels.ZopeDTMLDocumentModel
 
905
    defaultViews = (ZopeViews.ZopeHTMLSourceView,)
 
906
    additionalViews = (ZopeViews.ZopeUndoView,
 
907
          ZopeViews.ZopeSecurityView, ZopeViews.ZopeHTMLView,)
 
908
 
 
909
class DTMLMethodNode(ZopeNode):
 
910
    Model = ZopeEditorModels.ZopeDTMLMethodModel
 
911
    defaultViews = (ZopeViews.ZopeHTMLSourceView,)
 
912
    additionalViews = (ZopeViews.ZopeUndoView,
 
913
          ZopeViews.ZopeSecurityView, ZopeViews.ZopeHTMLView)
 
914
 
 
915
class SiteErrorLogNode(ZopeItemNode):
 
916
    Model = ZopeEditorModels.ZopeSiteErrorLogModel
 
917
    defaultViews = (ZopeViews.ZopeSiteErrorLogView,)
 
918
    additionalViews = (ZopeViews.ZopeUndoView,
 
919
                       ZopeViews.ZopeSecurityView)
 
920
    def isFolderish(self):
 
921
        return False
 
922
 
 
923
class HelpTopicNode(ZopeItemNode):
 
924
    Model = ZopeEditorModels.ZopeHelpTopicModel
 
925
    defaultViews = (ZopeViews.ZopeHTMLView,)
 
926
    additionalViews = ()
 
927
    def isFolderish(self):
 
928
        return False
 
929
 
 
930
from Explorers.PrefsExplorer import SourceBasedPrefColNode
 
931
class ZopeZ2pySourceBasedPrefColNode(SourceBasedPrefColNode):
 
932
    pass
 
933
 
 
934
class ZopeResultsFolderNode(ZopeItemNode):
 
935
    results = []
 
936
 
 
937
    def createChildNode(self, metatype, id, respath, label):
 
938
        item = ZopeItemNode.createChildNode(self, metatype, id, respath)
 
939
        item.name = item.treename = label
 
940
        return item
 
941
 
 
942
    def openList(self):
 
943
        self.parentOpensChildren = True
 
944
        entries = []
 
945
 
 
946
        for zmeta, zid in self.results:
 
947
            zpath = os.path.dirname(self.resourcepath+'/'+zid)
 
948
            name = os.path.basename(zid)
 
949
            node = self.createChildNode(zmeta, name, zpath, '%s (%s)'%(name, zpath))
 
950
            if node:# and not node.isFolderish():
 
951
                entries.append(node)
 
952
 
 
953
        self.entries = entries
 
954
        return self.entries
 
955
 
 
956
    def openParent(self, editor):
 
957
        editor.explorer.tree.SelectItem(editor.explorer.tree.GetSelection())
 
958
        return True
 
959
 
 
960
    def open(self, node, editor):
 
961
        # recreate with proper name
 
962
        node = node.getNodeFromPath(node.resourcepath, node.metatype)
 
963
        return node.open(editor)
 
964
 
 
965
    def getTitle(self):
 
966
        return 'Zope Find Results'
 
967
 
 
968
def findBetween(strg, startMarker, endMarker):
 
969
    strL = strg.lower()
 
970
    found = ''
 
971
    idx = strL.find(startMarker)
 
972
    idx2 = -1
 
973
    if idx != -1:
 
974
        idx2 = strL.find(endMarker, idx)
 
975
        if idx2 != -1:
 
976
            found = strg[idx + len(startMarker)+1: idx2]
 
977
    return idx, idx2, found
 
978
 
 
979
class ZopeError(Exception):
 
980
    def __init__(self, htmlFaultStr):
 
981
        self.htmlFault = htmlFaultStr
 
982
 
 
983
        # find possible traceback
 
984
        idx, idx2, tracebk = findBetween(htmlFaultStr, '<pre>', '</pre>')
 
985
        if tracebk:
 
986
            tracebk = 'Traceback:\n'+tracebk
 
987
        self.traceback = tracebk
 
988
 
 
989
        txt = Utils.html2txt(htmlFaultStr)
 
990
        self.textFault = '%s\n%s\n' % (txt, tracebk)
 
991
 
 
992
        idx, idx1, self.ErrorType = findBetween(txt, 'Error Type:', '\n')
 
993
        idx, idx1, self.ErrorValue = findBetween(txt, 'Error Value:', '\n')
 
994
 
 
995
    def __str__(self):
 
996
        return self.ErrorType and ('%s:%s' % (self.ErrorType, self.ErrorValue)) or self.textFault
 
997
 
 
998
 
 
999
def zopeHtmlErr2Strs(faultStr):
 
1000
    sFaultStr = str(faultStr)
 
1001
    fs = sFaultStr.lower()
 
1002
    idx = fs.find('<pre>')
 
1003
    traceBk = ''
 
1004
    if idx != -1:
 
1005
        idx2 = fs.find('</pre>', idx)
 
1006
        if idx2 != -1:
 
1007
            traceBk = '\nTraceback:\n'+sFaultStr[idx + 5: idx2]
 
1008
    txt = Utils.html2txt(sFaultStr)
 
1009
    return txt+traceBk
 
1010
 
 
1011
def uriSplitZope(filename, filepath):
 
1012
    # zope://[category]/<[meta type]>/[path] format
 
1013
    segs = filepath.split('/')
 
1014
    if len(segs) < 2:
 
1015
        raise ExplorerNodes.TransportCategoryError(
 
1016
              'Category not found', filepath)
 
1017
    category = segs[0]+'|'+segs[1][1:-1]
 
1018
    return 'zope', category, '/'.join(segs[2:]), filename
 
1019
 
 
1020
def uriSplitZopeDebug(filename, filepath):
 
1021
    # zopedebug://[host[:port]]/[path]/[meta type]
 
1022
    # magically maps zopedebug urls to Boa zope uris
 
1023
    segs = filepath.split('/')
 
1024
    if len(segs) < 3:
 
1025
        raise ExplorerNodes.TransportCategoryError(
 
1026
              'Zope debug path invalid', filepath)
 
1027
    host, filepaths, meta = segs[0], segs[1:-1], segs[-1]
 
1028
    try:               host, port = host.split(':')
 
1029
    except ValueError: port = 80
 
1030
    else:              port = int(port)
 
1031
    # try to find category that can open this url
 
1032
    for cat in ExplorerNodes.all_transports.entries:
 
1033
        if cat.itemProtocol == 'zope':
 
1034
            itms = cat.openList()
 
1035
            for itm in itms:
 
1036
                props = itm.properties
 
1037
                # @@@ Gogo.
 
1038
                if socket.gethostbyname(props['host']) == socket.gethostbyname(host) and \
 
1039
                       props['httpport'] == port:
 
1040
                # @@@ original code follows:
 
1041
                # if props['host'].lower() == host.lower() and \
 
1042
                #       props['httpport'] == port:
 
1043
                    path = '/'.join(filepaths)
 
1044
                    name = itm.name or itm.treename
 
1045
                    return 'zope', '%s|%s' %(name, meta), path, \
 
1046
                           'zope://%s/<%s>/%s'%(name, meta, path)
 
1047
 
 
1048
    raise ExplorerNodes.TransportCategoryError(\
 
1049
          'Could not map Zope debug path to defined Zope Category item',
 
1050
          filepath)
 
1051
 
 
1052
def findZopeExplorerNode(catandmeta, respath, transports):
 
1053
    category, metatype = catandmeta.split('|')
 
1054
    for cat in transports.entries:
 
1055
        if hasattr(cat, 'itemProtocol') and cat.itemProtocol == 'zope':
 
1056
            itms = cat.openList()
 
1057
            for itm in itms:
 
1058
                if itm.name == category or itm.treename == category:
 
1059
                    return itm.getNodeFromPath('/'+respath, metatype)
 
1060
    raise ExplorerNodes.TransportError(
 
1061
          'Zope transport could not be found: %s || %s'%(category, respath))
 
1062
 
 
1063
#-------------------------------------------------------------------------------
 
1064
# maps meta types to ExplorerNodes
 
1065
zopeClassMap = { 'Folder': DirNode,
 
1066
        'Product Help': DirNode,
 
1067
        'Z Class': ZClassNode,
 
1068
        'User Folder': UserFolderNode,
 
1069
        'Control Panel': ControlNode,
 
1070
        'Z SQL Method': ZSQLNode,
 
1071
        'DTML Document': DTMLDocNode,
 
1072
        'DTML Method': DTMLMethodNode,
 
1073
        'Python Method': PythonNode,
 
1074
        'External Method': ExtPythonNode,
 
1075
        'Script (Python)': PythonScriptNode,
 
1076
        'Image': ZopeImageNode,
 
1077
        'File': ZopeNode,
 
1078
        'User': ZopeUserNode,
 
1079
        'Site Error Log': SiteErrorLogNode,
 
1080
        'Help Topic': HelpTopicNode,
 
1081
       }
 
1082
 
 
1083
ExplorerNodes.register(ZopeCatNode, controller=ZopeCatController)
 
1084
ExplorerNodes.register(ZopeItemNode, clipboard='global',
 
1085
  confdef=('explorer', 'zope'), controller=ZopeController, category=ZopeCatNode)
 
1086
ExplorerNodes.uriSplitReg[('zope', 2)] = uriSplitZope
 
1087
ExplorerNodes.uriSplitReg[('zopedebug', 2)] = uriSplitZopeDebug
 
1088
ExplorerNodes.transportFindReg['zope'] = findZopeExplorerNode