work in progress: BSCW interface
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2592 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
		
							parent
							
								
									d1f8a17e63
								
							
						
					
					
						commit
						a932deff3e
					
				
					 5 changed files with 170 additions and 27 deletions
				
			
		|  | @ -22,7 +22,7 @@ Let's do some basic set up | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Accessing Objects in the Filesystem | Accessing Objects in the Filesystem | ||||||
| ======================================= | =================================== | ||||||
| 
 | 
 | ||||||
|   >>> top = component.getUtility(IContainerFactory, name='filesystem')(testDir) |   >>> top = component.getUtility(IContainerFactory, name='filesystem')(testDir) | ||||||
|   >>> sorted(top) |   >>> sorted(top) | ||||||
|  |  | ||||||
|  | @ -35,12 +35,28 @@ from cybertools.integrator.base import ReadContainer, File, Image | ||||||
| from cybertools.text import mimetypes | from cybertools.text import mimetypes | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | baseAttributes = ['__class__', 'name', 'id', 'descr', 'notes', | ||||||
|  |     'bound_sub_artifacts', 'creator', 'owner', 'owners', | ||||||
|  |     'ctime', 'mtime', 'atime', 'lastEvent', 'createEvent', | ||||||
|  |     'lastChange', 'lastMove', 'containers', 'access'] | ||||||
|  | 
 | ||||||
|  | standardAttributes = ['__class__', 'name', 'id', 'descr', 'mtime'] | ||||||
|  | 
 | ||||||
|  | additionalAttributes = ['banner', 'moderated', 'ratings'] | ||||||
|  | 
 | ||||||
|  | documentAttributes = ['vid', 'vstore', 'file_extensions', 'size', 'encoding', 'type'] | ||||||
|  | 
 | ||||||
|  | urlAttributes = ['url_link', 'last_verified', 'last_error', 'content_length', | ||||||
|  |     'content_type', 'content_encoding', 'last_modified'] | ||||||
|  | 
 | ||||||
|  | classes = ['cl_core.Folder', 'cl_core.Document', 'cl_core.URL', ] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| # proxy classes | # proxy classes | ||||||
| 
 | 
 | ||||||
| class ReadContainer(ReadContainer): | class ReadContainer(ReadContainer): | ||||||
| 
 | 
 | ||||||
|     factoryName = 'bscw' |     factoryName = 'bscw' | ||||||
|     data = None |  | ||||||
| 
 | 
 | ||||||
|     @Lazy |     @Lazy | ||||||
|     def data(self): |     def data(self): | ||||||
|  | @ -64,12 +80,13 @@ class ReadContainer(ReadContainer): | ||||||
|             return default |             return default | ||||||
|         item = self.data[key] |         item = self.data[key] | ||||||
|         if 'Folder' in item['__class__']: |         if 'Folder' in item['__class__']: | ||||||
|             return self.containerFactory(item['id'], server=self.server) |             return self.containerFactory(item['id'], server=self.server, | ||||||
|  |                                          name=item['name']) | ||||||
|         elif 'Document' in item['__class__']: |         elif 'Document' in item['__class__']: | ||||||
|             return self.fileFactory(item['id'], server=self.server, |             return self.fileFactory(item['id'], item['type'], server=self.server, | ||||||
|                                     type=item['type']) |                                     name=item['name']) | ||||||
|         else: |         else: | ||||||
|             return OtherObject(item['id'], server=self.server) |             return OtherObject(item['id'], None, server=self.server, name=item['name']) | ||||||
| 
 | 
 | ||||||
|     def values(self): |     def values(self): | ||||||
|         return [self.get(k) for k in self] |         return [self.get(k) for k in self] | ||||||
|  | @ -93,15 +110,7 @@ class File(File): | ||||||
|     data = property(getData) |     data = property(getData) | ||||||
| 
 | 
 | ||||||
|     def getSize(self): |     def getSize(self): | ||||||
|         return os.stat(self.address)[stat.ST_SIZE] |         return 0 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class Image(File): |  | ||||||
| 
 |  | ||||||
|     width = height = 0 |  | ||||||
| 
 |  | ||||||
|     def getImageSize(self): |  | ||||||
|         return self.width, self.height |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class OtherObject(File): | class OtherObject(File): | ||||||
|  | @ -116,20 +125,16 @@ class ContainerFactory(ContainerFactory): | ||||||
|     proxyClass = ReadContainer |     proxyClass = ReadContainer | ||||||
| 
 | 
 | ||||||
|     def __call__(self, address, **kw): |     def __call__(self, address, **kw): | ||||||
|         server = ServerProxy(address) |         server = kw.pop('server') | ||||||
|         name = kw.pop('name', '') |         if isinstance(server, basestring):  # just a URL, resolve for XML-RPC | ||||||
|         return self.proxyClass(name, server=server, **kw) |             server = ServerProxy(server) | ||||||
|  |         return self.proxyClass(address, server=server, **kw) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class FileFactory(FileFactory): | class FileFactory(FileFactory): | ||||||
| 
 | 
 | ||||||
|     def __call__(self, address, **kw): |     def __call__(self, address, **kw): | ||||||
|         contentType = kw.pop('type', None) |         contentType = kw.pop('type', 'application/octet-stream') | ||||||
|         width = height = 0 |  | ||||||
|         obj = File(address, contentType, **kw) |         obj = File(address, contentType, **kw) | ||||||
|         if contentType.startswith('image/'): |  | ||||||
|             return Image(address, contentType=contentType, |  | ||||||
|                          width=width, height=height, **kw) |  | ||||||
|         else: |  | ||||||
|         obj.contentType = contentType |         obj.contentType = contentType | ||||||
|         return obj |         return obj | ||||||
|  |  | ||||||
							
								
								
									
										34
									
								
								integrator/bscw.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								integrator/bscw.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | ||||||
|  | ========================================= | ||||||
|  | Integrating objects from external systems | ||||||
|  | ========================================= | ||||||
|  | 
 | ||||||
|  | Integration of external sources. | ||||||
|  | 
 | ||||||
|  |   ($Id$) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Accessing Objects on a Remote BSCW Repository | ||||||
|  | ============================================= | ||||||
|  | 
 | ||||||
|  | In fact we do not access a remote repository but just a dummy (fake) | ||||||
|  | repository for testing purposes. | ||||||
|  | 
 | ||||||
|  |   >>> from cybertools.integrator.testing.bscw import BSCWServer, sampleObjects | ||||||
|  |   >>> from cybertools.integrator.bscw import standardAttributes | ||||||
|  |   >>> server = BSCWServer(sampleObjects) | ||||||
|  | 
 | ||||||
|  |   >>> server.get_attributes('4', standardAttributes + ['containers'], 1, True) | ||||||
|  |   [{...'name': 'public'...}, [{...'name': 'Introduction'...}]] | ||||||
|  | 
 | ||||||
|  | Access via read container and file proxies | ||||||
|  | ------------------------------------------ | ||||||
|  | 
 | ||||||
|  |   >>> from zope import component | ||||||
|  |   >>> from cybertools.integrator.bscw import ContainerFactory | ||||||
|  |   >>> component.provideUtility(ContainerFactory(), name='bscw') | ||||||
|  | 
 | ||||||
|  |   >>> from cybertools.integrator.interfaces import IContainerFactory | ||||||
|  |   >>> root = component.getUtility(IContainerFactory, name='bscw')('4', server=server) | ||||||
|  | 
 | ||||||
|  |   >>> sorted(root) | ||||||
|  |   ['bs_5'] | ||||||
							
								
								
									
										102
									
								
								integrator/testing/bscw.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								integrator/testing/bscw.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,102 @@ | ||||||
|  | # | ||||||
|  | #  Copyright (c) 2008 Helmut Merz helmutm@cy55.de | ||||||
|  | # | ||||||
|  | #  This program is free software; you can redistribute it and/or modify | ||||||
|  | #  it under the terms of the GNU General Public License as published by | ||||||
|  | #  the Free Software Foundation; either version 2 of the License, or | ||||||
|  | #  (at your option) any later version. | ||||||
|  | # | ||||||
|  | #  This program is distributed in the hope that it will be useful, | ||||||
|  | #  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | #  GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | #  You should have received a copy of the GNU General Public License | ||||||
|  | #  along with this program; if not, write to the Free Software | ||||||
|  | #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | """ | ||||||
|  | Fake BSCW repository for testing purposes. | ||||||
|  | 
 | ||||||
|  | $Id$ | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | from xmlrpclib import Fault | ||||||
|  | 
 | ||||||
|  | from cybertools.integrator import bscw | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Artifact(dict): | ||||||
|  | 
 | ||||||
|  |     attributes = bscw.baseAttributes | ||||||
|  |     repository = None | ||||||
|  | 
 | ||||||
|  |     def __init__(self, id, **kw): | ||||||
|  |         if not id.startswith('bs_'): | ||||||
|  |             id = 'bs_' + id | ||||||
|  |         self.id = self['id'] = self['__id__'] = id | ||||||
|  |         self.children = kw.pop('children', []) | ||||||
|  |         self['__class__'] = kw.pop('__class__', 'cl_core.Folder') | ||||||
|  |         self.update(kw) | ||||||
|  | 
 | ||||||
|  |     def getData(self, attrs): | ||||||
|  |         return dict((key, self[key]) for key in attrs if key in self) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class BSCWRepository(dict): | ||||||
|  | 
 | ||||||
|  |     def __init__(self, *objs): | ||||||
|  |         for obj in objs: | ||||||
|  |             self[obj.id] = obj | ||||||
|  |             obj.repository = self | ||||||
|  |         self.updateContainersAttribute() | ||||||
|  | 
 | ||||||
|  |     def get(self, key, default=None): | ||||||
|  |         if not key.startswith('bs_'): | ||||||
|  |             key = 'bs_' + key | ||||||
|  |         return super(BSCWRepository, self).get(key, default) | ||||||
|  | 
 | ||||||
|  |     def updateContainersAttribute(self): | ||||||
|  |         for obj in self.values(): | ||||||
|  |             for c in obj.children: | ||||||
|  |                 child = self.get(c) | ||||||
|  |                 if child is not None: | ||||||
|  |                     containerInfo = dict(__id__=child.id, name=child['name']) | ||||||
|  |                     child.setdefault('containers', []).append(containerInfo) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | sampleObjects = BSCWRepository( | ||||||
|  |     Artifact('4', name='public', descr='Public Repository', children=['5'], | ||||||
|  |                   containers=[dict(__id__='4711', name='Community of Anonymous')]), | ||||||
|  |     Artifact('5', name='Introduction', descr='Introduction to BSCW'), | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class BSCWServer(object): | ||||||
|  | 
 | ||||||
|  |     def __init__(self, objects): | ||||||
|  |         self. objects = objects | ||||||
|  | 
 | ||||||
|  |     def get_attributes(self, id=None, attribute_names=['__id__', 'name'], depth=0, | ||||||
|  |                        nested=False, offset=0, number=0, sorted_by=None): | ||||||
|  |         obj = self.objects.get(id) | ||||||
|  |         if obj is None: | ||||||
|  |             raise Fault(10101, 'Bad object id: %s' % id) | ||||||
|  |         result = [obj.getData(attribute_names)] | ||||||
|  |         if nested: | ||||||
|  |             for level in range(depth): | ||||||
|  |                 for id in obj.children: | ||||||
|  |                     result.append(self.get_attributes(id, attribute_names, | ||||||
|  |                                   depth-1, nested, offset, number, sorted_by)) | ||||||
|  |         return result | ||||||
|  | 
 | ||||||
|  |     def get_attributenames(self, __class__): | ||||||
|  |         return baseAttributes | ||||||
|  | 
 | ||||||
|  |     def get_document(self, id, version_id): | ||||||
|  |         return '' | ||||||
|  | 
 | ||||||
|  |     def get_path(id): | ||||||
|  |         return self.get_attributes(id, ['containers'])[0].get('containers', []) | ||||||
|  | 
 | ||||||
|  | @ -9,6 +9,8 @@ from zope.interface.verify import verifyClass | ||||||
| baseDir = os.path.dirname(__file__) | baseDir = os.path.dirname(__file__) | ||||||
| testDir = os.path.join(baseDir, 'testing', 'data') | testDir = os.path.join(baseDir, 'testing', 'data') | ||||||
| 
 | 
 | ||||||
|  | flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class Test(unittest.TestCase): | class Test(unittest.TestCase): | ||||||
|     "Basic tests for the cybertools.integrator package." |     "Basic tests for the cybertools.integrator package." | ||||||
|  | @ -18,10 +20,10 @@ class Test(unittest.TestCase): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def test_suite(): | def test_suite(): | ||||||
|     flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS |  | ||||||
|     return unittest.TestSuite(( |     return unittest.TestSuite(( | ||||||
|                 unittest.makeSuite(Test), |                 unittest.makeSuite(Test), | ||||||
|                 DocFileSuite('README.txt', optionflags=flags), |                 DocFileSuite('README.txt', optionflags=flags), | ||||||
|  |                 DocFileSuite('bscw.txt', optionflags=flags), | ||||||
|             )) |             )) | ||||||
| 
 | 
 | ||||||
| if __name__ == '__main__': | if __name__ == '__main__': | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 helmutm
						helmutm