You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mail_clean_document_notify_task.py 4.1KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import logging
  2. import time
  3. from collections import defaultdict
  4. import click
  5. from flask import render_template # type: ignore
  6. import app
  7. from configs import dify_config
  8. from extensions.ext_database import db
  9. from extensions.ext_mail import mail
  10. from models.account import Account, Tenant, TenantAccountJoin
  11. from models.dataset import Dataset, DatasetAutoDisableLog
  12. from services.feature_service import FeatureService
  13. @app.celery.task(queue="dataset")
  14. def mail_clean_document_notify_task():
  15. """
  16. Async Send document clean notify mail
  17. Usage: mail_clean_document_notify_task.delay()
  18. """
  19. if not mail.is_inited():
  20. return
  21. logging.info(click.style("Start send document clean notify mail", fg="green"))
  22. start_at = time.perf_counter()
  23. # send document clean notify mail
  24. try:
  25. dataset_auto_disable_logs = DatasetAutoDisableLog.query.filter(DatasetAutoDisableLog.notified == False).all()
  26. # group by tenant_id
  27. dataset_auto_disable_logs_map: dict[str, list[DatasetAutoDisableLog]] = defaultdict(list)
  28. for dataset_auto_disable_log in dataset_auto_disable_logs:
  29. if dataset_auto_disable_log.tenant_id not in dataset_auto_disable_logs_map:
  30. dataset_auto_disable_logs_map[dataset_auto_disable_log.tenant_id] = []
  31. dataset_auto_disable_logs_map[dataset_auto_disable_log.tenant_id].append(dataset_auto_disable_log)
  32. url = f"{dify_config.CONSOLE_WEB_URL}/datasets"
  33. for tenant_id, tenant_dataset_auto_disable_logs in dataset_auto_disable_logs_map.items():
  34. features = FeatureService.get_features(tenant_id)
  35. plan = features.billing.subscription.plan
  36. if plan != "sandbox":
  37. knowledge_details = []
  38. # check tenant
  39. tenant = Tenant.query.filter(Tenant.id == tenant_id).first()
  40. if not tenant:
  41. continue
  42. # check current owner
  43. current_owner_join = (
  44. db.session.query(TenantAccountJoin).filter_by(tenant_id=tenant.id, role="owner").first()
  45. )
  46. if not current_owner_join:
  47. continue
  48. account = Account.query.filter(Account.id == current_owner_join.account_id).first()
  49. if not account:
  50. continue
  51. dataset_auto_dataset_map = {} # type: ignore
  52. for dataset_auto_disable_log in tenant_dataset_auto_disable_logs:
  53. if dataset_auto_disable_log.dataset_id not in dataset_auto_dataset_map:
  54. dataset_auto_dataset_map[dataset_auto_disable_log.dataset_id] = []
  55. dataset_auto_dataset_map[dataset_auto_disable_log.dataset_id].append(
  56. dataset_auto_disable_log.document_id
  57. )
  58. for dataset_id, document_ids in dataset_auto_dataset_map.items():
  59. dataset = Dataset.query.filter(Dataset.id == dataset_id).first()
  60. if dataset:
  61. document_count = len(document_ids)
  62. knowledge_details.append(rf"Knowledge base {dataset.name}: {document_count} documents")
  63. if knowledge_details:
  64. html_content = render_template(
  65. "clean_document_job_mail_template-US.html",
  66. userName=account.email,
  67. knowledge_details=knowledge_details,
  68. url=url,
  69. )
  70. mail.send(
  71. to=account.email, subject="Dify Knowledge base auto disable notification", html=html_content
  72. )
  73. # update notified to True
  74. for dataset_auto_disable_log in tenant_dataset_auto_disable_logs:
  75. dataset_auto_disable_log.notified = True
  76. db.session.commit()
  77. end_at = time.perf_counter()
  78. logging.info(
  79. click.style("Send document clean notify mail succeeded: latency: {}".format(end_at - start_at), fg="green")
  80. )
  81. except Exception:
  82. logging.exception("Send document clean notify mail failed")