|
142 | 142 |
|
143 | 143 | from libreforms_fastapi.utils.custom_tinydb import CustomEncoder
|
144 | 144 |
|
| 145 | +# This import is used for caching with selective invalidation |
| 146 | +from libreforms_fastapi.utils.parameterized_caching import parameterized_lru_cache |
| 147 | + |
145 | 148 | # Import to render more powerful email content
|
146 | 149 | from libreforms_fastapi.utils.jinja_emails import (
|
147 | 150 | render_email_message_from_jinja,
|
|
155 | 158 | _env = os.environ.get('ENVIRONMENT', 'development')
|
156 | 159 |
|
157 | 160 |
|
| 161 | + |
| 162 | +# The following functions will be used to cache form stage data, |
| 163 | +# see https://github.com/signebedi/libreforms-fastapi/issues/62 |
| 164 | +@parameterized_lru_cache(maxsize=128) |
| 165 | +def cache_form_stage_data( |
| 166 | + form_name: str, |
| 167 | + form_stages: dict, |
| 168 | + doc_db: ManageDocumentDB, |
| 169 | +): |
| 170 | + """ |
| 171 | + This function wraps ManageDocumentDB.get_all_documents_by_stage() so we can cache values |
| 172 | + outside the class scope, since we are using it largely as a dependency injection... |
| 173 | + """ |
| 174 | + |
| 175 | + # We begin be instantiating an empty container to store document_id values for each stage |
| 176 | + stage_dict = {} |
| 177 | + |
| 178 | + # Then we iterate through each stage and collect each of the items |
| 179 | + for stage_name, _stage_conf in form_stages.items(): # _stage_conf is not important in this function |
| 180 | + |
| 181 | + document_ids = [] # Reset this variable... perhaps redundant |
| 182 | + document_ids = doc.db.get_all_documents_by_stage(form_name, stage_name) # Get all values with the current stage |
| 183 | + |
| 184 | + # Add these values to stage_dict |
| 185 | + stage_dict[stage_name] = document_ids |
| 186 | + |
| 187 | + return stage_dict |
| 188 | + |
| 189 | +# @parameterized_lru_cache(maxsize=128) |
| 190 | +@lru_cache() # Opt for a standard cache because we probably need to rebuild this entire cache when there are changes |
| 191 | +def cache_form_stage_data_for_specified_user( |
| 192 | + form_name: str, |
| 193 | + form_stages: dict, |
| 194 | + current_user, # This is a sqlalchemy row |
| 195 | + doc_db: ManageDocumentDB, |
| 196 | +): |
| 197 | + """ |
| 198 | + This function wraps extends cache_form_stage_data to get a list of documents that a given |
| 199 | + user is eligible to approve. |
| 200 | + """ |
| 201 | + |
| 202 | + # Get the list of documents in each stage from cached data |
| 203 | + all_stage_data = cache_form_stage_data(form_name, form_stages, doc_db) |
| 204 | + |
| 205 | + user_specific_data = [] |
| 206 | + |
| 207 | + # Iterate through each form stage in form_stages |
| 208 | + for stage_name, stage_conf in form_stages.items(): |
| 209 | + |
| 210 | + stage_specific_data = all_stage_data[stage_name] |
| 211 | + |
| 212 | + # Start with the static form approval method |
| 213 | + if stage_conf.method == "static": |
| 214 | + # If this user is the specified approver, then append all the stage- |
| 215 | + # specific data to the user's list of documents needing their action |
| 216 | + if user.email == stage_conf.target: |
| 217 | + user_specific_data.extend(stage_specific_data) |
| 218 | + |
| 219 | + # Then do group based approval |
| 220 | + if stage_conf.method == "group": |
| 221 | + # If the user is a member of the approving group, then add all the stage- |
| 222 | + # specific data to the user's list of docs needing their action |
| 223 | + if stage_conf.target in user.groups: |
| 224 | + user_specific_data.extend(stage_specific_data) |
| 225 | + |
| 226 | + # Relationship-based approval is... complex, to say the least. This will remain unimplemented |
| 227 | + # for now, see https://github.com/signebedi/libreforms-fastapi/issues/332 |
| 228 | + |
| 229 | + return user_specific_data |
| 230 | + |
| 231 | + |
| 232 | + |
158 | 233 | class ConfigFileChangeHandler(FileSystemEventHandler):
|
159 | 234 | """
|
160 | 235 | I am adding this class to help manage caching for the application configuration,
|
|
0 commit comments