[5ec3a0b] | 1 | from repoze.catalog.catalog import Catalog |
---|
| 2 | from repoze.catalog.document import DocumentMap |
---|
| 3 | |
---|
| 4 | from pyramid.traversal import find_resource, resource_path |
---|
| 5 | |
---|
| 6 | |
---|
| 7 | def update_indexes(catalog, indexes={}): |
---|
| 8 | """ |
---|
| 9 | Setup indexes in the catalog. |
---|
| 10 | |
---|
| 11 | Any index in indexes that does not exist in the catalog will be added to it |
---|
| 12 | Any index in the catalog that is not in indexes will be removed from it |
---|
| 13 | """ |
---|
| 14 | added = [] |
---|
| 15 | removed = [] |
---|
| 16 | # add indexes |
---|
| 17 | for name, index in indexes.items(): |
---|
| 18 | if name not in catalog: |
---|
| 19 | added.append(name) |
---|
| 20 | catalog[name] = index |
---|
| 21 | # remove indexes |
---|
| 22 | for name in list(catalog.keys()): |
---|
| 23 | if name not in indexes: |
---|
| 24 | removed.append(name) |
---|
| 25 | del catalog[name] |
---|
| 26 | return {'added': added, 'removed': removed} |
---|
| 27 | |
---|
| 28 | |
---|
| 29 | def install_catalog(obj): |
---|
| 30 | """ |
---|
| 31 | Install a catalog in an object. |
---|
| 32 | |
---|
| 33 | The indexes to be used are set up in a method called |
---|
| 34 | _get_catalog_indexes() in the object. |
---|
| 35 | """ |
---|
| 36 | obj.catalog = Catalog() |
---|
| 37 | obj.catalog.document_map = DocumentMap() |
---|
| 38 | indexes = obj._get_catalog_indexes() |
---|
| 39 | update_indexes(obj.catalog, indexes) |
---|
| 40 | |
---|
| 41 | |
---|
| 42 | def get_catalog(obj): |
---|
| 43 | """ |
---|
| 44 | Return the catalog for this object: |
---|
| 45 | |
---|
| 46 | - if the object is the root folder and has no catalog, create one |
---|
| 47 | and return that |
---|
| 48 | |
---|
| 49 | - if the object is the root folder and has a catalog, return that |
---|
| 50 | |
---|
| 51 | - if the object is not the root folder and has a catalog by itself, |
---|
| 52 | return that |
---|
| 53 | |
---|
| 54 | - if the object is not the root folder and has not a catalog by itself, |
---|
| 55 | find the root and operate as described in the previous first 2 cases |
---|
| 56 | """ |
---|
| 57 | # object has its own catalog |
---|
| 58 | catalog = getattr(obj, "catalog", None) |
---|
| 59 | if catalog is not None: |
---|
| 60 | # the object has a catalog |
---|
| 61 | return catalog |
---|
| 62 | |
---|
| 63 | # go backwards up to the root of the tree, if we find any parent with |
---|
| 64 | # a catalog, return that, otherwise keep on until the root object |
---|
| 65 | while obj.__parent__ is not None: |
---|
| 66 | obj = obj.__parent__ |
---|
| 67 | catalog = getattr(obj, "catalog", None) |
---|
| 68 | if catalog is not None: |
---|
| 69 | return catalog |
---|
| 70 | |
---|
| 71 | # this code is run when the object is the root folder and has not a |
---|
| 72 | # catalog already |
---|
| 73 | install_catalog(obj) |
---|
| 74 | catalog = obj.catalog |
---|
| 75 | return catalog |
---|
| 76 | |
---|
| 77 | |
---|
| 78 | def address_docid(catalog, obj): |
---|
| 79 | """ |
---|
| 80 | Get the address and docid of an obj in the catalog |
---|
| 81 | (return None for the docid if it doesn't exist yet). |
---|
| 82 | """ |
---|
| 83 | address = resource_path(obj) |
---|
| 84 | docid = catalog.document_map.docid_for_address(address) |
---|
| 85 | return address, docid |
---|
| 86 | |
---|
| 87 | |
---|
| 88 | def reindex_object(catalog, obj): |
---|
| 89 | """ |
---|
| 90 | Index or reindex an object. |
---|
| 91 | """ |
---|
| 92 | address, docid = address_docid(catalog, obj) |
---|
| 93 | if docid is not None: |
---|
| 94 | # reindex an existing catalog entry |
---|
| 95 | catalog.reindex_doc(docid, obj) |
---|
| 96 | else: |
---|
| 97 | # new in the catalog |
---|
| 98 | docid = catalog.document_map.add(address) |
---|
| 99 | catalog.index_doc(docid, obj) |
---|
| 100 | |
---|
| 101 | |
---|
| 102 | def remove_from_catalog(catalog, obj): |
---|
| 103 | """ |
---|
| 104 | Handle removing of the address mapping and unindexing an object. |
---|
| 105 | """ |
---|
| 106 | address, docid = address_docid(catalog, obj) |
---|
| 107 | if docid is not None: |
---|
| 108 | catalog.unindex_doc(docid) |
---|
| 109 | catalog.document_map.remove_docid(docid) |
---|
| 110 | |
---|
| 111 | |
---|
| 112 | def resources_from_query_results(catalog, results, context): |
---|
| 113 | """ |
---|
| 114 | Return an iterator to get to the objects from a query result |
---|
| 115 | (which returns "addresses", i.e. resource paths). |
---|
| 116 | results - the ressult from the query |
---|
| 117 | context - an object (root folder usually) |
---|
| 118 | """ |
---|
| 119 | dm = catalog.document_map |
---|
| 120 | for docid in results: |
---|
| 121 | address = dm.address_for_docid(docid) |
---|
| 122 | yield find_resource(context, address) |
---|