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) |
---|