diff --git a/docs/setup/administrators/cron-jobs.md b/docs/setup/administrators/cron-jobs.md new file mode 100644 index 0000000000..e4a2ff9fef --- /dev/null +++ b/docs/setup/administrators/cron-jobs.md @@ -0,0 +1,29 @@ +# Possible Cron Commands + +Hypha comes stock with management commands that can be utilized in tandem with a job scheduler to automate specific tasks + +## Account Cleanup + +Accounts that haven't been logged into in 5 months can be marked as inactive with the following command: + +```shell +python3 manage.py accounts_cleanup +``` + +## Drafts Cleanup + +Drafts that haven't been modified in a specified time (in days) can be deleted with the following command: + +```shell +python3 manage.py drafts_cleanup [days] + +# Or, to run without a confirmation prompt + +python3 manage.py drafts_cleanup [days] --noinput +``` + +Example: to delete all drafts that haven't been modified in a year without a confirmation prompt: + +```shell +python3 manage.py drafts_cleanup 365 --noinput +``` \ No newline at end of file diff --git a/hypha/apply/funds/management/commands/drafts_cleanup.py b/hypha/apply/funds/management/commands/drafts_cleanup.py index 26d4229933..cc4a6b072d 100644 --- a/hypha/apply/funds/management/commands/drafts_cleanup.py +++ b/hypha/apply/funds/management/commands/drafts_cleanup.py @@ -9,10 +9,17 @@ from hypha.apply.funds.workflow import DRAFT_STATE -def check_not_negative(value): +def check_not_negative(value) -> int: """Used to validate `older_than_days` argument - Needs to be a non-negative int + Args: + value: Argument to be validated + + Returns: + int: Valid non-negative value + + Raises: + argparse.ArgumentTypeError: if not non-negative integer """ try: ivalue = int(value) @@ -27,14 +34,14 @@ def check_not_negative(value): class Command(BaseCommand): - help = "Delete all drafts that are older than 2 years" + help = "Delete all drafts that are older than the specified time in days" def add_arguments(self, parser): parser.add_argument( "older_than_days", action="store", type=check_not_negative, - help="Clear all applications older than the days specified here", + help="Time in days to delete drafts older than", ) parser.add_argument( "--noinput", @@ -60,13 +67,13 @@ def handle(self, *args, **options): if not (draft_count := old_drafts.count()): self.stdout.write( - f"No drafts older than {older_than} day{"s" if older_than > 1 else ""} exist." + f"No drafts older than {older_than} day{'s' if older_than > 1 else ''} exist." ) return if interactive: confirm = input( - f"This action will permanently delete {draft_count} draft{"s" if draft_count != 1 else ""}.\nAre you sure you want to do this?\n\nType 'yes' to continue, or 'no' to cancel: " + f"This action will permanently delete {draft_count} draft{'s' if draft_count != 1 else ''}.\nAre you sure you want to do this?\n\nType 'yes' to continue, or 'no' to cancel: " ) else: confirm = "yes" @@ -74,7 +81,7 @@ def handle(self, *args, **options): if confirm == "yes": old_drafts.delete() self.stdout.write( - f"{draft_count} draft{"s" if draft_count != 1 else ""} deleted." + f"{draft_count} draft{'s' if draft_count != 1 else ''} deleted." ) else: self.stdout.write("Deletion cancelled.")