diff --git a/joint_teapot/__main__.py b/joint_teapot/__main__.py
index fcfa629..98cd5b6 100644
--- a/joint_teapot/__main__.py
+++ b/joint_teapot/__main__.py
@@ -113,8 +113,8 @@ def get_repos_status(
     "prepare-assignment-dir",
     help='prepare assignment dir from extracted canvas "Download Submissions" zip',
 )
-def prepare_assignment_dir(dir: Path) -> None:
-    tea.pot.canvas.prepare_assignment_dir(str(dir))
+def prepare_assignment_dir(dir_or_zip_file: Path) -> None:
+    tea.pot.canvas.prepare_assignment_dir(str(dir_or_zip_file))
 
 
 @app.command(
diff --git a/joint_teapot/workers/canvas.py b/joint_teapot/workers/canvas.py
index b147df9..b9743bc 100644
--- a/joint_teapot/workers/canvas.py
+++ b/joint_teapot/workers/canvas.py
@@ -36,7 +36,14 @@ class Canvas:
         self.score_filename = score_filename
         logger.debug("Canvas initialized")
 
-    def prepare_assignment_dir(self, dir: str, create_score_file: bool = True) -> None:
+    def prepare_assignment_dir(
+        self, dir_or_zip_file: str, create_score_file: bool = True
+    ) -> None:
+        if os.path.isdir(dir_or_zip_file):
+            dir = dir_or_zip_file
+        else:
+            dir = os.path.splitext(dir_or_zip_file)[0]
+            extract_archive(dir_or_zip_file, outdir=dir, verbosity=-1)
         login_ids = {stu.id: stu.login_id for stu in self.students}
         for v in login_ids.values():
             new_path = os.path.join(dir, v)
@@ -47,12 +54,14 @@ class Canvas:
             if "_" not in file_name:
                 continue
             segments = file_name.split("_")
+            is_late = False
             if segments[1] == "late":
                 file_id = int(segments[2])
                 student = first(
                     self.students, lambda x: x.login_id == login_ids[file_id]
                 )
                 logger.info(f"{student} submits late")
+                is_late = True
             else:
                 file_id = int(segments[1])
             target_dir = os.path.join(dir, login_ids[file_id])
@@ -61,6 +70,8 @@ class Canvas:
                 os.remove(path)
             except PatoolError:
                 os.rename(path, os.path.join(target_dir, file_name))
+            if is_late:
+                open(os.path.join(target_dir, "SUBMIT_LATE"), mode="w")
             if create_score_file:
                 open(os.path.join(target_dir, self.score_filename), mode="w")