source: trunk/ToolboxSearchTool.py @ 53

Revision 53, 6.1 KB checked in by meelis, 14 years ago (diff)

renaming activities to stories

  • Property svn:eol-style set to LF
Line 
1from OFS.SimpleItem import SimpleItem
2from OFS.SimpleItem import Item
3from OFS.PropertyManager import PropertyManager
4from Products.CMFCore.utils import UniqueObject
5from Globals import InitializeClass
6from AccessControl import ClassSecurityInfo
7from Products.CMFCore.utils import getToolByName
8from ZODB.PersistentMapping import PersistentMapping
9import xmlrpclib
10from Acquisition import aq_base
11from config import MANAGE_PORTAL
12
13class ToolboxSearchTool(PropertyManager, SimpleItem, UniqueObject):
14    """ toolbox search. Performs standard plone search and xml-rpc search to query distant toolboxes """
15
16    id = 'toolbox_search'
17    meta_type = 'ToolboxSearch'
18    security = ClassSecurityInfo()
19    plone_tool = 1
20    __allow_access_to_unprotected_subobjects__ = 1
21
22    def manage_afterAdd(self, item, container):
23        self._setProperty('enable_remotesearch', True, 'boolean')
24        self.remote_toolboxes = {}
25
26    def toolbox_search(self, REQUEST, **kw):
27    """ toolbox search method. performs local and remote searches """
28        class myremotebrain:
29            """ my brain """
30            __allow_access_to_unprotected_subobjects__=1
31            def __init__(self, ob, data):
32                self.__ob = ob
33                self.data = data
34               
35            def __get__(self, key):
36                try:
37                    return self.data[key]
38                except:
39                    print "ERROR: ", key
40
41            def __getattr__(self, key, default=''):
42                if self.data.has_key(key):
43                    return self.data[key]
44                return getattr(self.__ob, key)
45
46        results = []
47        local = self.local_search(REQUEST, **kw)
48        remote = []
49        if self.enable_remotesearch:
50            remote = self.remote_search(REQUEST, **kw)
51        for x in local:
52            results.append(x)
53        for y in remote:
54            rbrain = myremotebrain(aq_base(self).__of__(self),y)
55            results.append(rbrain)
56    return results
57
58    security.declarePrivate('local_search')
59    def local_search(self, REQUEST, **kw):
60        """ do a local search """
61    portal_catalog = getToolByName( self, 'portal_catalog' )
62    results = portal_catalog.searchResults(REQUEST, **kw)
63        return results
64
65    security.declarePrivate('remote_search')
66    def remote_search(self, REQUEST, **kw):
67        """ do remote search.
68            connects to distant toolbox via xml-rpc and invokes incoming_query method.
69        """
70        # get remote toolbox address from somewhere
71        tb_locations = self.get_urls_of_remote_toolboxes()
72        result = []
73        if tb_locations is None:
74            return result
75        for tb in tb_locations:
76            ping = self.ping(tb)
77            if not ping:
78                print "Toolbox @ %s is alive!" % tb
79                # connect now!
80                r = xmlrpclib.Server(tb+'/'+self.getId(), allow_none=1)
81                query_str = REQUEST.get('QUERY_STRING')
82                query = {}
83                q_tmp = query_str.split('&')
84                params = []
85                for pair in q_tmp:
86                    key_tmp, value = pair.split('=')
87                    key = key_tmp.split('%')[0]
88                    if key not in params:
89                        params.append(key)
90                for p in params:
91                    query[p] = REQUEST.get(p)
92                #XXX: this is evil. need to find out if unix timestamps are ok here.
93                query['created'] = str(query['created'])
94                result += r.incoming_search(query)
95                #XXX: when passing **kw
96                #XXX: TypeError: __call__() got an unexpected keyword argument 'use_types_blacklist'
97            else:
98                print "Toolbox @ %s is dead!" % tb
99        return result
100
101    security.declarePublic('incoming_search')
102    def incoming_search(self, query):
103        """ search request coming from remote toolbox uses this method """
104        from DateTime import DateTime
105        #XXX: this is evil. need to find out if unix timestamps are ok here.
106        # mybrains object doesn't want to travel over xml-rpc...
107        query['created'] = eval(query['created'])
108        query_results = self.local_search(query)
109        results = []
110        for x in query_results:
111            # XXX: should use schema values here?
112            results.append({'Title':x.Title,
113                    'Description':x.Description,
114                    'pretty_title_or_id':x.pretty_title_or_id(),
115                    'Creator':x.Creator,
116                    'ModificationDate':x.ModificationDate,
117                    'getURL':x.getURL(),
118                    'portal_type':x.portal_type,
119                    'review_state':x.review_state,
120                    'data_record_normalized_score_':x.data_record_normalized_score_,
121                    })
122        return results
123
124    def get_urls_of_remote_toolboxes(self):
125        """ get remote toolbox locations. ie. ('http://localhost:9090/SecondToolBox',) """
126        result = []
127        for x in self.remote_toolboxes.values():
128            print x
129            result.append(x['URL'])
130        return result
131
132    def get_remote_toolboxes(self):
133        return self.remote_toolboxes
134
135    def ping(self, address):
136        """ ping remote toolbox, see if it's alive """
137        address = address +'/'+ self.getId()
138        r = xmlrpclib.Server(address)
139        remote = r.pong('ping')
140        if remote != 'pong':
141            return 1
142        return 0
143
144    def pong(self, ping):
145        """ respond to ping """
146        if ping != 'ping':
147            return 1
148        return "pong"
149
150    security.declareProtected(MANAGE_PORTAL, 'manage_changeLocations')
151    def setNewLocation(self, location):
152        """ set remote search location and protocol """
153        import time
154        timestamp = time.time()
155        while self.remote_toolboxes.has_key(str(int(timestamp))):
156            timestamp = time.time()
157        timestamp = str(int(timestamp))
158        self.remote_toolboxes[timestamp] = {'URL': location, 'protocol': 'xmlrpc'}
159        self._p_changed = True
160        return 0
161
162    def setEnableRemoteSearch(self, enable):
163        self.enable_remotesearch = enable
164
165InitializeClass(ToolboxSearchTool)
Note: See TracBrowser for help on using the repository browser.