We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Directory hashes are not expired when directories are added/removed
if you add or remove a directory it should expire hashes on all parents and related - ie /projects/x directories

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pootle/apps/pootle_revision/receivers.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) Pootle contributors.
4 #
5 # This file is a part of the Pootle project. It is distributed under the GPL3
6 # or later license. See the LICENSE file for a copy of the license and the
7 # AUTHORS file for copyright and authorship information.
8 
9 from django.db.models.signals import post_save
10 from django.dispatch import receiver
11 
12 from pootle.core.delegate import revision_updater
13 from pootle_data.models import StoreData
14 from pootle_store.models import Store
15 
16 
17 @receiver(post_save, sender=StoreData)
18 def handle_storedata_save(**kwargs):
19     revision_updater.get(Store)(
20         context=kwargs["instance"].store).update(keys=["stats", "checks"])
21
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pootle/apps/pootle_revision/receivers.py b/pootle/apps/pootle_revision/receivers.py
--- a/pootle/apps/pootle_revision/receivers.py
+++ b/pootle/apps/pootle_revision/receivers.py
@@ -6,10 +6,11 @@
 # or later license. See the LICENSE file for a copy of the license and the
 # AUTHORS file for copyright and authorship information.
 
-from django.db.models.signals import post_save
+from django.db.models.signals import post_save, pre_delete
 from django.dispatch import receiver
 
 from pootle.core.delegate import revision_updater
+from pootle_app.models import Directory
 from pootle_data.models import StoreData
 from pootle_store.models import Store
 
@@ -18,3 +19,17 @@
 def handle_storedata_save(**kwargs):
     revision_updater.get(Store)(
         context=kwargs["instance"].store).update(keys=["stats", "checks"])
+
+
+@receiver(post_save, sender=Directory)
+def handle_directory_save(**kwargs):
+    if kwargs.get("created"):
+        return
+    revision_updater.get(Directory)(
+        context=kwargs["instance"]).update(keys=["stats", "checks"])
+
+
+@receiver(pre_delete, sender=Directory)
+def handle_directory_delete(**kwargs):
+    revision_updater.get(Directory)(
+        context=kwargs["instance"].parent).update(keys=["stats", "checks"])

{"golden_diff": "diff --git a/pootle/apps/pootle_revision/receivers.py b/pootle/apps/pootle_revision/receivers.py\n--- a/pootle/apps/pootle_revision/receivers.py\n+++ b/pootle/apps/pootle_revision/receivers.py\n@@ -6,10 +6,11 @@\n # or later license. See the LICENSE file for a copy of the license and the\n # AUTHORS file for copyright and authorship information.\n \n-from django.db.models.signals import post_save\n+from django.db.models.signals import post_save, pre_delete\n from django.dispatch import receiver\n \n from pootle.core.delegate import revision_updater\n+from pootle_app.models import Directory\n from pootle_data.models import StoreData\n from pootle_store.models import Store\n \n@@ -18,3 +19,17 @@\n def handle_storedata_save(**kwargs):\n     revision_updater.get(Store)(\n         context=kwargs[\"instance\"].store).update(keys=[\"stats\", \"checks\"])\n+\n+\n+@receiver(post_save, sender=Directory)\n+def handle_directory_save(**kwargs):\n+    if kwargs.get(\"created\"):\n+        return\n+    revision_updater.get(Directory)(\n+        context=kwargs[\"instance\"]).update(keys=[\"stats\", \"checks\"])\n+\n+\n+@receiver(pre_delete, sender=Directory)\n+def handle_directory_delete(**kwargs):\n+    revision_updater.get(Directory)(\n+        context=kwargs[\"instance\"].parent).update(keys=[\"stats\", \"checks\"])\n", "issue": "Directory hashes are not expired when directories are added/removed\nif you add or remove a directory it should expire hashes on all parents and related - ie /projects/x directories\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n#\n# Copyright (C) Pootle contributors.\n#\n# This file is a part of the Pootle project. It is distributed under the GPL3\n# or later license. See the LICENSE file for a copy of the license and the\n# AUTHORS file for copyright and authorship information.\n\nfrom django.db.models.signals import post_save\nfrom django.dispatch import receiver\n\nfrom pootle.core.delegate import revision_updater\nfrom pootle_data.models import StoreData\nfrom pootle_store.models import Store\n\n\n@receiver(post_save, sender=StoreData)\ndef handle_storedata_save(**kwargs):\n    revision_updater.get(Store)(\n        context=kwargs[\"instance\"].store).update(keys=[\"stats\", \"checks\"])\n", "path": "pootle/apps/pootle_revision/receivers.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n#\n# Copyright (C) Pootle contributors.\n#\n# This file is a part of the Pootle project. It is distributed under the GPL3\n# or later license. See the LICENSE file for a copy of the license and the\n# AUTHORS file for copyright and authorship information.\n\nfrom django.db.models.signals import post_save, pre_delete\nfrom django.dispatch import receiver\n\nfrom pootle.core.delegate import revision_updater\nfrom pootle_app.models import Directory\nfrom pootle_data.models import StoreData\nfrom pootle_store.models import Store\n\n\n@receiver(post_save, sender=StoreData)\ndef handle_storedata_save(**kwargs):\n    revision_updater.get(Store)(\n        context=kwargs[\"instance\"].store).update(keys=[\"stats\", \"checks\"])\n\n\n@receiver(post_save, sender=Directory)\ndef handle_directory_save(**kwargs):\n    if kwargs.get(\"created\"):\n        return\n    revision_updater.get(Directory)(\n        context=kwargs[\"instance\"]).update(keys=[\"stats\", \"checks\"])\n\n\n@receiver(pre_delete, sender=Directory)\ndef handle_directory_delete(**kwargs):\n    revision_updater.get(Directory)(\n        context=kwargs[\"instance\"].parent).update(keys=[\"stats\", \"checks\"])\n", "path": "pootle/apps/pootle_revision/receivers.py"}]}