Repository: learningequality/kolibri

Issue:
Crash when trying to run importcontent in command line.
### Observed behavior
A crash happens when running this management command in the Command Line/Terminal: 
* `kolibri manage importcontent network 1ceff53605e55bef987d88e0908658c5`

This sample content is for the Khan Academy (English).  Here's the user guide for reference: [Import Content from Internet](https://kolibri.readthedocs.io/en/latest/manage/command_line.html#import-content-channels-from-internet).

Here's the output:


```bash
user@ubuntu:~$ kolibri manage importcontent network 1ceff53605e55bef987d88e0908658c5
INFO     Running Kolibri with the following settings: kolibri.deployment.default.settings.base
INFO     Invoking command importcontent network 1ceff53605e55bef987d88e0908658c5
Traceback (most recent call last):
  File "/usr/bin/kolibri", line 11, in <module>
    load_entry_point('kolibri==0.13.2b1', 'console_scripts', 'kolibri')()
  File "/usr/lib/python3/dist-packages/kolibri/dist/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/kolibri/dist/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3/dist-packages/kolibri/dist/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python3/dist-packages/kolibri/utils/cli.py", line 243, in invoke
    return super(KolibriDjangoCommand, self).invoke(ctx)
  File "/usr/lib/python3/dist-packages/kolibri/dist/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3/dist-packages/kolibri/dist/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/kolibri/dist/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/usr/lib/python3/dist-packages/kolibri/utils/cli.py", line 641, in manage
    execute_from_command_line(["kolibri manage"] + ctx.args)
  File "/usr/lib/python3/dist-packages/kolibri/dist/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/usr/lib/python3/dist-packages/kolibri/dist/django/core/management/__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/lib/python3/dist-packages/kolibri/dist/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/lib/python3/dist-packages/kolibri/dist/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "/usr/lib/python3/dist-packages/kolibri/core/tasks/management/commands/base.py", line 102, in handle
    return self.handle_async(*args, **options)
  File "/usr/lib/python3/dist-packages/kolibri/core/content/management/commands/importcontent.py", line 439, in handle_async
    renderable_only=options["renderable_only"],
  File "/usr/lib/python3/dist-packages/kolibri/core/content/management/commands/importcontent.py", line 159, in download_content
    renderable_only=renderable_only,
  File "/usr/lib/python3/dist-packages/kolibri/core/content/management/commands/importcontent.py", line 257, in _transfer
    total=total_bytes_to_transfer + dummy_bytes_for_annotation
  File "/usr/lib/python3/dist-packages/kolibri/core/tasks/management/commands/base.py", line 115, in start_progress
    total=total, level=level, update_callback=self._update_all_progress
  File "/usr/lib/python3/dist-packages/kolibri/core/tasks/management/commands/base.py", line 38, in __init__
    self.progressbar = click.progressbar(length=total, width=0)
  File "/usr/lib/python3/dist-packages/kolibri/dist/click/termui.py", line 351, in progressbar
    width=width, color=color)
  File "/usr/lib/python3/dist-packages/kolibri/dist/click/_termui_impl.py", line 81, in __init__
    iterable = range_type(length)
TypeError: 'float' object cannot be interpreted as an integer
user@ubuntu:~$
```


### Expected behavior
No crash should happen and that the Channel content is imported successfully.


### Errors and logs

* [daemon.txt](https://github.com/learningequality/kolibri/files/4410316/daemon.txt)
* [kolibri.txt](https://github.com/learningequality/kolibri/files/4410317/kolibri.txt)


### Steps to reproduce
1. Install [Kolibri v0.13.2-beta1](https://github.com/learningequality/kolibri/releases/tag/v0.13.2-beta1) in Ubuntu 16.04.6 VM
1. Launch Terminal, then run `kolibri manage importchannel network 1ceff53605e55bef987d88e0908658c5` - ignore the warning
1. Run `kolibri manage importcontent network 1ceff53605e55bef987d88e0908658c5` - notice the crash.


### Context
 
* Kolibri version: [Kolibri v0.13.2-beta1](https://github.com/learningequality/kolibri/releases/tag/v0.13.2-beta1)
* Operating system: Ubuntu 16.04.6 VM (2GB RAM, 2CPUs, 64GB disk)
* Browser: Firefox v74.0


### Related Issue/s

* https://github.com/learningequality/kolibri/issues/6715#issuecomment-606696997



Discussion:
This is a regression introduced by a bug fix in the 0.13.2 milestone, so we should fix this before release.

Resolving patch:
diff --git a/kolibri/core/content/utils/annotation.py b/kolibri/core/content/utils/annotation.py
--- a/kolibri/core/content/utils/annotation.py
+++ b/kolibri/core/content/utils/annotation.py
@@ -631,7 +631,7 @@ def calculate_dummy_progress_for_annotation(node_ids, exclude_node_ids, total_pr
     annotation_proportion = min(10, max(1, int(num_annotation_constraints / 500)))
 
     # Create some progress proportional to annotation task
-    return annotation_proportion * total_progress / (100 - annotation_proportion)
+    return int(annotation_proportion * total_progress / (100 - annotation_proportion))
 
 
 def propagate_forced_localfile_removal(localfiles):
diff --git a/kolibri/core/tasks/management/commands/base.py b/kolibri/core/tasks/management/commands/base.py
--- a/kolibri/core/tasks/management/commands/base.py
+++ b/kolibri/core/tasks/management/commands/base.py
@@ -1,13 +1,16 @@
 import abc
+import logging
+import sys
 from collections import namedtuple
 
 import click
-import sys
 from django.core.management.base import BaseCommand
 
 from kolibri.core.tasks.exceptions import UserCancelledError
 from kolibri.core.tasks.utils import get_current_job
 
+logger = logging.getLogger(__name__)
+
 Progress = namedtuple(
     "Progress", ["progress_fraction", "message", "extra_data", "level"]
 )
@@ -35,12 +38,17 @@ def __init__(self, total=100, level=0, update_callback=None):
             # as we only want to display progress bars from the command line.
             try:
                 click.get_current_context()
-                self.progressbar = click.progressbar(length=total, width=0)
+                # Coerce to an integer for safety, as click uses Python `range` on this
+                # value, which requires an integer argument
+                # N.B. because we are only doing this in Python3, safe to just use int,
+                # as long is Py2 only
+                self.progressbar = click.progressbar(length=int(total), width=0)
             except RuntimeError:
                 self.progressbar = None
 
     def update_progress(self, increment=1, message="", extra_data=None):
         if self.progressbar:
+            # Click only enforces integers on the total (because it is implemented assuming a length)
             self.progressbar.update(increment)
         self.progress += increment
         self.message = message


Test patch: