We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
updateChannelMetadata fails on upgrade
### Observed behavior
Can't see any content when I install latest.

### Expected behavior

Content should still be available

### User-facing consequences

Thinking that all content was deleted

### Errors and logs

```
Traceback (most recent call last):
  File "/home/david/.virtualenvs/kolibri/bin/kolibri", line 9, in <module>
    load_entry_point('kolibri', 'console_scripts', 'kolibri')()
  File "/home/david/Work/kolibri/kolibri/utils/cli.py", line 655, in main
    start(port, daemon=daemon)
  File "/home/david/Work/kolibri/kolibri/utils/cli.py", line 311, in start
    update()
  File "/home/david/Work/kolibri/kolibri/utils/cli.py", line 295, in update
    update_channel_metadata()
  File "/home/david/Work/kolibri/kolibri/content/utils/annotation.py", line 35, in update_channel_metadata
    set_availability()
TypeError: set_availability() takes at least 1 argument (0 given)
```


### Steps to reproduce

try and run latest `release-v0.7.x` with existing content

### Context

* Kolibri version:  0.7
* Operating system: Linux
* Browser: Chromium


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kolibri/content/utils/annotation.py`
Content:
```
1 import logging as logger
2 import datetime
3 import os
4 
5 from django.conf import settings
6 from kolibri.content.apps import KolibriContentConfig
7 from kolibri.content.models import ChannelMetadata, ContentNode, File, LocalFile
8 from le_utils.constants import content_kinds
9 from sqlalchemy import and_, exists, func, select
10 
11 from .channels import get_channel_ids_for_content_database_dir
12 from .paths import get_content_file_name, get_content_storage_file_path
13 from .sqlalchemybridge import Bridge
14 
15 logging = logger.getLogger(__name__)
16 
17 CONTENT_APP_NAME = KolibriContentConfig.label
18 
19 CHUNKSIZE = 10000
20 
21 def update_channel_metadata():
22     """
23     If we are potentially moving from a version of Kolibri that did not import its content data,
24     scan through the settings.CONTENT_DATABASE_DIR folder for all channel content databases,
25     and pull the data from each database if we have not already imported it.
26     """
27     from .channel_import import import_channel_from_local_db
28     channel_ids = get_channel_ids_for_content_database_dir(settings.CONTENT_DATABASE_DIR)
29     imported = False
30     for channel_id in channel_ids:
31         if not ChannelMetadata.objects.filter(id=channel_id).exists():
32             import_channel_from_local_db(channel_id)
33             imported = True
34     if imported:
35         set_availability()
36 
37 
38 def set_leaf_node_availability_from_local_file_availability():
39     bridge = Bridge(app_name=CONTENT_APP_NAME)
40 
41     ContentNodeTable = bridge.get_table(ContentNode)
42     FileTable = bridge.get_table(File)
43     LocalFileTable = bridge.get_table(LocalFile)
44 
45     connection = bridge.get_connection()
46 
47     file_statement = select([LocalFileTable.c.available]).where(
48         FileTable.c.local_file_id == LocalFileTable.c.id,
49     ).limit(1)
50 
51     logging.info('Setting availability of File objects based on LocalFile availability')
52 
53     connection.execute(FileTable.update().values(available=file_statement).execution_options(autocommit=True))
54 
55     contentnode_statement = select([FileTable.c.contentnode_id]).where(
56         and_(
57             FileTable.c.available == True,  # noqa
58             FileTable.c.supplementary == False
59         )
60     ).where(ContentNodeTable.c.id == FileTable.c.contentnode_id)
61 
62     logging.info('Setting availability of non-topic ContentNode objects based on File availability')
63 
64     connection.execute(ContentNodeTable.update().where(
65         ContentNodeTable.c.kind != content_kinds.TOPIC).values(available=exists(contentnode_statement)).execution_options(autocommit=True))
66 
67     bridge.end()
68 
69 def mark_local_files_as_available(checksums):
70     """
71     Shortcut method to update database if we are sure that the files are available.
72     Can be used after successful downloads to flag availability without having to do expensive disk reads.
73     """
74     bridge = Bridge(app_name=CONTENT_APP_NAME)
75 
76     LocalFileClass = bridge.get_class(LocalFile)
77 
78     logging.info('Setting availability of {number} LocalFile objects based on passed in checksums'.format(number=len(checksums)))
79 
80     for i in range(0, len(checksums), CHUNKSIZE):
81         bridge.session.bulk_update_mappings(LocalFileClass, ({
82             'id': checksum,
83             'available': True
84         } for checksum in checksums[i:i+CHUNKSIZE]))
85         bridge.session.flush()
86 
87     bridge.session.commit()
88 
89     bridge.end()
90 
91 def set_local_file_availability_from_disk(checksums=None):
92     bridge = Bridge(app_name=CONTENT_APP_NAME)
93 
94     LocalFileClass = bridge.get_class(LocalFile)
95 
96     if checksums is None:
97         logging.info('Setting availability of LocalFile objects based on disk availability')
98         files = bridge.session.query(LocalFileClass).all()
99     elif type(checksums) == list:
100         logging.info('Setting availability of {number} LocalFile objects based on disk availability'.format(number=len(checksums)))
101         files = bridge.session.query(LocalFileClass).filter(LocalFileClass.id.in_(checksums)).all()
102     else:
103         logging.info('Setting availability of LocalFile object with checksum {checksum} based on disk availability'.format(checksum=checksums))
104         files = [bridge.session.query(LocalFileClass).get(checksums)]
105 
106     checksums_to_update = [
107         file.id for file in files if os.path.exists(get_content_storage_file_path(get_content_file_name(file)))
108     ]
109 
110     bridge.end()
111 
112     mark_local_files_as_available(checksums_to_update)
113 
114 def recurse_availability_up_tree(channel_id):
115     bridge = Bridge(app_name=CONTENT_APP_NAME)
116 
117     ContentNodeClass = bridge.get_class(ContentNode)
118 
119     ContentNodeTable = bridge.get_table(ContentNode)
120 
121     connection = bridge.get_connection()
122 
123     node_depth = bridge.session.query(func.max(ContentNodeClass.level)).scalar()
124 
125     logging.info('Setting availability of ContentNode objects with children for {levels} levels'.format(levels=node_depth))
126 
127     child = ContentNodeTable.alias()
128 
129     # start a transaction
130 
131     trans = connection.begin()
132     # Go from the deepest level to the shallowest
133     start = datetime.datetime.now()
134     for level in range(node_depth, 0, -1):
135 
136         available_nodes = select([child.c.available]).where(
137             and_(
138                 child.c.available == True,  # noqa
139                 child.c.level == level,
140                 child.c.channel_id == channel_id,
141             )
142         ).where(ContentNodeTable.c.id == child.c.parent_id)
143 
144         logging.info('Setting availability of ContentNode objects with children for level {level}'.format(level=level))
145         # Only modify topic availability here
146         connection.execute(ContentNodeTable.update().where(
147             and_(
148                 ContentNodeTable.c.level == level - 1,
149                 ContentNodeTable.c.channel_id == channel_id,
150                 ContentNodeTable.c.kind == content_kinds.TOPIC)).values(available=exists(available_nodes)))
151 
152     # commit the transaction
153     trans.commit()
154 
155     elapsed = (datetime.datetime.now() - start)
156     logging.debug("Availability annotation took {} seconds".format(elapsed.seconds))
157 
158     bridge.end()
159 
160 def set_availability(channel_id, checksums=None):
161     if checksums is None:
162         set_local_file_availability_from_disk()
163     else:
164         mark_local_files_as_available(checksums)
165 
166     set_leaf_node_availability_from_local_file_availability()
167     recurse_availability_up_tree(channel_id)
168
```
--- 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/kolibri/content/utils/annotation.py b/kolibri/content/utils/annotation.py
--- a/kolibri/content/utils/annotation.py
+++ b/kolibri/content/utils/annotation.py
@@ -1,5 +1,5 @@
-import logging as logger
 import datetime
+import logging as logger
 import os
 
 from django.conf import settings
@@ -26,13 +26,10 @@
     """
     from .channel_import import import_channel_from_local_db
     channel_ids = get_channel_ids_for_content_database_dir(settings.CONTENT_DATABASE_DIR)
-    imported = False
     for channel_id in channel_ids:
         if not ChannelMetadata.objects.filter(id=channel_id).exists():
             import_channel_from_local_db(channel_id)
-            imported = True
-    if imported:
-        set_availability()
+            set_availability(channel_id)
 
 
 def set_leaf_node_availability_from_local_file_availability():

{"golden_diff": "diff --git a/kolibri/content/utils/annotation.py b/kolibri/content/utils/annotation.py\n--- a/kolibri/content/utils/annotation.py\n+++ b/kolibri/content/utils/annotation.py\n@@ -1,5 +1,5 @@\n-import logging as logger\n import datetime\n+import logging as logger\n import os\n \n from django.conf import settings\n@@ -26,13 +26,10 @@\n     \"\"\"\n     from .channel_import import import_channel_from_local_db\n     channel_ids = get_channel_ids_for_content_database_dir(settings.CONTENT_DATABASE_DIR)\n-    imported = False\n     for channel_id in channel_ids:\n         if not ChannelMetadata.objects.filter(id=channel_id).exists():\n             import_channel_from_local_db(channel_id)\n-            imported = True\n-    if imported:\n-        set_availability()\n+            set_availability(channel_id)\n \n \n def set_leaf_node_availability_from_local_file_availability():\n", "issue": "updateChannelMetadata fails on upgrade\n### Observed behavior\r\nCan't see any content when I install latest.\r\n\r\n### Expected behavior\r\n\r\nContent should still be available\r\n\r\n### User-facing consequences\r\n\r\nThinking that all content was deleted\r\n\r\n### Errors and logs\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"/home/david/.virtualenvs/kolibri/bin/kolibri\", line 9, in <module>\r\n    load_entry_point('kolibri', 'console_scripts', 'kolibri')()\r\n  File \"/home/david/Work/kolibri/kolibri/utils/cli.py\", line 655, in main\r\n    start(port, daemon=daemon)\r\n  File \"/home/david/Work/kolibri/kolibri/utils/cli.py\", line 311, in start\r\n    update()\r\n  File \"/home/david/Work/kolibri/kolibri/utils/cli.py\", line 295, in update\r\n    update_channel_metadata()\r\n  File \"/home/david/Work/kolibri/kolibri/content/utils/annotation.py\", line 35, in update_channel_metadata\r\n    set_availability()\r\nTypeError: set_availability() takes at least 1 argument (0 given)\r\n```\r\n\r\n\r\n### Steps to reproduce\r\n\r\ntry and run latest `release-v0.7.x` with existing content\r\n\r\n### Context\r\n\r\n* Kolibri version:  0.7\r\n* Operating system: Linux\r\n* Browser: Chromium\r\n\n", "before_files": [{"content": "import logging as logger\nimport datetime\nimport os\n\nfrom django.conf import settings\nfrom kolibri.content.apps import KolibriContentConfig\nfrom kolibri.content.models import ChannelMetadata, ContentNode, File, LocalFile\nfrom le_utils.constants import content_kinds\nfrom sqlalchemy import and_, exists, func, select\n\nfrom .channels import get_channel_ids_for_content_database_dir\nfrom .paths import get_content_file_name, get_content_storage_file_path\nfrom .sqlalchemybridge import Bridge\n\nlogging = logger.getLogger(__name__)\n\nCONTENT_APP_NAME = KolibriContentConfig.label\n\nCHUNKSIZE = 10000\n\ndef update_channel_metadata():\n    \"\"\"\n    If we are potentially moving from a version of Kolibri that did not import its content data,\n    scan through the settings.CONTENT_DATABASE_DIR folder for all channel content databases,\n    and pull the data from each database if we have not already imported it.\n    \"\"\"\n    from .channel_import import import_channel_from_local_db\n    channel_ids = get_channel_ids_for_content_database_dir(settings.CONTENT_DATABASE_DIR)\n    imported = False\n    for channel_id in channel_ids:\n        if not ChannelMetadata.objects.filter(id=channel_id).exists():\n            import_channel_from_local_db(channel_id)\n            imported = True\n    if imported:\n        set_availability()\n\n\ndef set_leaf_node_availability_from_local_file_availability():\n    bridge = Bridge(app_name=CONTENT_APP_NAME)\n\n    ContentNodeTable = bridge.get_table(ContentNode)\n    FileTable = bridge.get_table(File)\n    LocalFileTable = bridge.get_table(LocalFile)\n\n    connection = bridge.get_connection()\n\n    file_statement = select([LocalFileTable.c.available]).where(\n        FileTable.c.local_file_id == LocalFileTable.c.id,\n    ).limit(1)\n\n    logging.info('Setting availability of File objects based on LocalFile availability')\n\n    connection.execute(FileTable.update().values(available=file_statement).execution_options(autocommit=True))\n\n    contentnode_statement = select([FileTable.c.contentnode_id]).where(\n        and_(\n            FileTable.c.available == True,  # noqa\n            FileTable.c.supplementary == False\n        )\n    ).where(ContentNodeTable.c.id == FileTable.c.contentnode_id)\n\n    logging.info('Setting availability of non-topic ContentNode objects based on File availability')\n\n    connection.execute(ContentNodeTable.update().where(\n        ContentNodeTable.c.kind != content_kinds.TOPIC).values(available=exists(contentnode_statement)).execution_options(autocommit=True))\n\n    bridge.end()\n\ndef mark_local_files_as_available(checksums):\n    \"\"\"\n    Shortcut method to update database if we are sure that the files are available.\n    Can be used after successful downloads to flag availability without having to do expensive disk reads.\n    \"\"\"\n    bridge = Bridge(app_name=CONTENT_APP_NAME)\n\n    LocalFileClass = bridge.get_class(LocalFile)\n\n    logging.info('Setting availability of {number} LocalFile objects based on passed in checksums'.format(number=len(checksums)))\n\n    for i in range(0, len(checksums), CHUNKSIZE):\n        bridge.session.bulk_update_mappings(LocalFileClass, ({\n            'id': checksum,\n            'available': True\n        } for checksum in checksums[i:i+CHUNKSIZE]))\n        bridge.session.flush()\n\n    bridge.session.commit()\n\n    bridge.end()\n\ndef set_local_file_availability_from_disk(checksums=None):\n    bridge = Bridge(app_name=CONTENT_APP_NAME)\n\n    LocalFileClass = bridge.get_class(LocalFile)\n\n    if checksums is None:\n        logging.info('Setting availability of LocalFile objects based on disk availability')\n        files = bridge.session.query(LocalFileClass).all()\n    elif type(checksums) == list:\n        logging.info('Setting availability of {number} LocalFile objects based on disk availability'.format(number=len(checksums)))\n        files = bridge.session.query(LocalFileClass).filter(LocalFileClass.id.in_(checksums)).all()\n    else:\n        logging.info('Setting availability of LocalFile object with checksum {checksum} based on disk availability'.format(checksum=checksums))\n        files = [bridge.session.query(LocalFileClass).get(checksums)]\n\n    checksums_to_update = [\n        file.id for file in files if os.path.exists(get_content_storage_file_path(get_content_file_name(file)))\n    ]\n\n    bridge.end()\n\n    mark_local_files_as_available(checksums_to_update)\n\ndef recurse_availability_up_tree(channel_id):\n    bridge = Bridge(app_name=CONTENT_APP_NAME)\n\n    ContentNodeClass = bridge.get_class(ContentNode)\n\n    ContentNodeTable = bridge.get_table(ContentNode)\n\n    connection = bridge.get_connection()\n\n    node_depth = bridge.session.query(func.max(ContentNodeClass.level)).scalar()\n\n    logging.info('Setting availability of ContentNode objects with children for {levels} levels'.format(levels=node_depth))\n\n    child = ContentNodeTable.alias()\n\n    # start a transaction\n\n    trans = connection.begin()\n    # Go from the deepest level to the shallowest\n    start = datetime.datetime.now()\n    for level in range(node_depth, 0, -1):\n\n        available_nodes = select([child.c.available]).where(\n            and_(\n                child.c.available == True,  # noqa\n                child.c.level == level,\n                child.c.channel_id == channel_id,\n            )\n        ).where(ContentNodeTable.c.id == child.c.parent_id)\n\n        logging.info('Setting availability of ContentNode objects with children for level {level}'.format(level=level))\n        # Only modify topic availability here\n        connection.execute(ContentNodeTable.update().where(\n            and_(\n                ContentNodeTable.c.level == level - 1,\n                ContentNodeTable.c.channel_id == channel_id,\n                ContentNodeTable.c.kind == content_kinds.TOPIC)).values(available=exists(available_nodes)))\n\n    # commit the transaction\n    trans.commit()\n\n    elapsed = (datetime.datetime.now() - start)\n    logging.debug(\"Availability annotation took {} seconds\".format(elapsed.seconds))\n\n    bridge.end()\n\ndef set_availability(channel_id, checksums=None):\n    if checksums is None:\n        set_local_file_availability_from_disk()\n    else:\n        mark_local_files_as_available(checksums)\n\n    set_leaf_node_availability_from_local_file_availability()\n    recurse_availability_up_tree(channel_id)\n", "path": "kolibri/content/utils/annotation.py"}], "after_files": [{"content": "import datetime\nimport logging as logger\nimport os\n\nfrom django.conf import settings\nfrom kolibri.content.apps import KolibriContentConfig\nfrom kolibri.content.models import ChannelMetadata, ContentNode, File, LocalFile\nfrom le_utils.constants import content_kinds\nfrom sqlalchemy import and_, exists, func, select\n\nfrom .channels import get_channel_ids_for_content_database_dir\nfrom .paths import get_content_file_name, get_content_storage_file_path\nfrom .sqlalchemybridge import Bridge\n\nlogging = logger.getLogger(__name__)\n\nCONTENT_APP_NAME = KolibriContentConfig.label\n\nCHUNKSIZE = 10000\n\ndef update_channel_metadata():\n    \"\"\"\n    If we are potentially moving from a version of Kolibri that did not import its content data,\n    scan through the settings.CONTENT_DATABASE_DIR folder for all channel content databases,\n    and pull the data from each database if we have not already imported it.\n    \"\"\"\n    from .channel_import import import_channel_from_local_db\n    channel_ids = get_channel_ids_for_content_database_dir(settings.CONTENT_DATABASE_DIR)\n    for channel_id in channel_ids:\n        if not ChannelMetadata.objects.filter(id=channel_id).exists():\n            import_channel_from_local_db(channel_id)\n            set_availability(channel_id)\n\n\ndef set_leaf_node_availability_from_local_file_availability():\n    bridge = Bridge(app_name=CONTENT_APP_NAME)\n\n    ContentNodeTable = bridge.get_table(ContentNode)\n    FileTable = bridge.get_table(File)\n    LocalFileTable = bridge.get_table(LocalFile)\n\n    connection = bridge.get_connection()\n\n    file_statement = select([LocalFileTable.c.available]).where(\n        FileTable.c.local_file_id == LocalFileTable.c.id,\n    ).limit(1)\n\n    logging.info('Setting availability of File objects based on LocalFile availability')\n\n    connection.execute(FileTable.update().values(available=file_statement).execution_options(autocommit=True))\n\n    contentnode_statement = select([FileTable.c.contentnode_id]).where(\n        and_(\n            FileTable.c.available == True,  # noqa\n            FileTable.c.supplementary == False\n        )\n    ).where(ContentNodeTable.c.id == FileTable.c.contentnode_id)\n\n    logging.info('Setting availability of non-topic ContentNode objects based on File availability')\n\n    connection.execute(ContentNodeTable.update().where(\n        ContentNodeTable.c.kind != content_kinds.TOPIC).values(available=exists(contentnode_statement)).execution_options(autocommit=True))\n\n    bridge.end()\n\ndef mark_local_files_as_available(checksums):\n    \"\"\"\n    Shortcut method to update database if we are sure that the files are available.\n    Can be used after successful downloads to flag availability without having to do expensive disk reads.\n    \"\"\"\n    bridge = Bridge(app_name=CONTENT_APP_NAME)\n\n    LocalFileClass = bridge.get_class(LocalFile)\n\n    logging.info('Setting availability of {number} LocalFile objects based on passed in checksums'.format(number=len(checksums)))\n\n    for i in range(0, len(checksums), CHUNKSIZE):\n        bridge.session.bulk_update_mappings(LocalFileClass, ({\n            'id': checksum,\n            'available': True\n        } for checksum in checksums[i:i+CHUNKSIZE]))\n        bridge.session.flush()\n\n    bridge.session.commit()\n\n    bridge.end()\n\ndef set_local_file_availability_from_disk(checksums=None):\n    bridge = Bridge(app_name=CONTENT_APP_NAME)\n\n    LocalFileClass = bridge.get_class(LocalFile)\n\n    if checksums is None:\n        logging.info('Setting availability of LocalFile objects based on disk availability')\n        files = bridge.session.query(LocalFileClass).all()\n    elif type(checksums) == list:\n        logging.info('Setting availability of {number} LocalFile objects based on disk availability'.format(number=len(checksums)))\n        files = bridge.session.query(LocalFileClass).filter(LocalFileClass.id.in_(checksums)).all()\n    else:\n        logging.info('Setting availability of LocalFile object with checksum {checksum} based on disk availability'.format(checksum=checksums))\n        files = [bridge.session.query(LocalFileClass).get(checksums)]\n\n    checksums_to_update = [\n        file.id for file in files if os.path.exists(get_content_storage_file_path(get_content_file_name(file)))\n    ]\n\n    bridge.end()\n\n    mark_local_files_as_available(checksums_to_update)\n\ndef recurse_availability_up_tree(channel_id):\n    bridge = Bridge(app_name=CONTENT_APP_NAME)\n\n    ContentNodeClass = bridge.get_class(ContentNode)\n\n    ContentNodeTable = bridge.get_table(ContentNode)\n\n    connection = bridge.get_connection()\n\n    node_depth = bridge.session.query(func.max(ContentNodeClass.level)).scalar()\n\n    logging.info('Setting availability of ContentNode objects with children for {levels} levels'.format(levels=node_depth))\n\n    child = ContentNodeTable.alias()\n\n    # start a transaction\n\n    trans = connection.begin()\n    # Go from the deepest level to the shallowest\n    start = datetime.datetime.now()\n    for level in range(node_depth, 0, -1):\n\n        available_nodes = select([child.c.available]).where(\n            and_(\n                child.c.available == True,  # noqa\n                child.c.level == level,\n                child.c.channel_id == channel_id,\n            )\n        ).where(ContentNodeTable.c.id == child.c.parent_id)\n\n        logging.info('Setting availability of ContentNode objects with children for level {level}'.format(level=level))\n        # Only modify topic availability here\n        connection.execute(ContentNodeTable.update().where(\n            and_(\n                ContentNodeTable.c.level == level - 1,\n                ContentNodeTable.c.channel_id == channel_id,\n                ContentNodeTable.c.kind == content_kinds.TOPIC)).values(available=exists(available_nodes)))\n\n    # commit the transaction\n    trans.commit()\n\n    elapsed = (datetime.datetime.now() - start)\n    logging.debug(\"Availability annotation took {} seconds\".format(elapsed.seconds))\n\n    bridge.end()\n\ndef set_availability(channel_id, checksums=None):\n    if checksums is None:\n        set_local_file_availability_from_disk()\n    else:\n        mark_local_files_as_available(checksums)\n\n    set_leaf_node_availability_from_local_file_availability()\n    recurse_availability_up_tree(channel_id)\n", "path": "kolibri/content/utils/annotation.py"}]}