Skip to content

Commit 31c0418

Browse files
authored
Add command to purge recordings (#531)
1 parent 0f986c4 commit 31c0418

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
"""Management command to remove recordings from the system."""
2+
3+
from __future__ import annotations
4+
5+
import logging
6+
from pathlib import Path
7+
8+
import djclick as click
9+
10+
from bats_ai.core.models import Recording
11+
12+
logger = logging.getLogger(__name__)
13+
14+
exclude_help = "A newline-delimited list of recording IDs to keep"
15+
batch_size_help = "The number of recordings to delete at a time. Lower it for memory-limited"
16+
dry_run_help = "If true, report number of recordings that would be deleted,"
17+
" systems instead of deleting recordings."
18+
19+
20+
def delete_recordings(to_delete, batch_size: int, total_deleted_stats: dict):
21+
total_deleted_count = 0
22+
while True:
23+
batch_ids = list(to_delete[:batch_size].values_list("pk", flat=True))
24+
if not batch_ids:
25+
break
26+
total_deleted, deleted_stats = Recording.objects.filter(pk__in=batch_ids).delete()
27+
total_deleted_count += total_deleted
28+
for key in deleted_stats:
29+
if key in total_deleted_stats:
30+
total_deleted_stats[key] += deleted_stats[key]
31+
else:
32+
total_deleted_stats[key] = deleted_stats[key]
33+
return total_deleted_count
34+
35+
36+
@click.command()
37+
@click.option(
38+
"--exclude", type=click.Path(exists=True, dir_okay=False, path_type=Path), help=exclude_help
39+
)
40+
@click.option("--batch-size", type=click.INT, default=1000, help=batch_size_help)
41+
@click.option("--dry-run", type=click.BOOL, is_flag=True, help=dry_run_help)
42+
def purge_recordings(exclude: Path, batch_size: int, dry_run):
43+
to_skip = set()
44+
if exclude:
45+
with open(exclude) as f:
46+
lines = f.readlines()
47+
for recording_id in lines:
48+
stripped_id = recording_id.strip()
49+
if stripped_id:
50+
to_skip.add(int(stripped_id))
51+
if to_skip:
52+
logger.info("Purging all recordings. %d recordings will be skipped...", len(to_skip))
53+
else:
54+
logger.info("Purging all recordings...")
55+
56+
total_deleted_stats = {}
57+
total_deleted_count = 0
58+
to_delete = Recording.objects.exclude(pk__in=to_skip).order_by("pk")
59+
if dry_run:
60+
total_deleted_count = to_delete.count()
61+
else:
62+
total_deleted_count = delete_recordings(to_delete, batch_size, total_deleted_stats)
63+
64+
if dry_run:
65+
logger.info("Done. %d recordings would have been deleted.", total_deleted_count)
66+
else:
67+
logger.info("Done. Deleted %d objects.", total_deleted_count)
68+
for key, value in total_deleted_stats.items():
69+
logger.info("\t %d instances of %s deleted.", value, key)

0 commit comments

Comments
 (0)