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.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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 = (
  26. db.session.query(DatasetAutoDisableLog).filter(DatasetAutoDisableLog.notified == False).all()
  27. )
  28. # group by tenant_id
  29. dataset_auto_disable_logs_map: dict[str, list[DatasetAutoDisableLog]] = defaultdict(list)
  30. for dataset_auto_disable_log in dataset_auto_disable_logs:
  31. if dataset_auto_disable_log.tenant_id not in dataset_auto_disable_logs_map:
  32. dataset_auto_disable_logs_map[dataset_auto_disable_log.tenant_id] = []
  33. dataset_auto_disable_logs_map[dataset_auto_disable_log.tenant_id].append(dataset_auto_disable_log)
  34. url = f"{dify_config.CONSOLE_WEB_URL}/datasets"
  35. for tenant_id, tenant_dataset_auto_disable_logs in dataset_auto_disable_logs_map.items():
  36. features = FeatureService.get_features(tenant_id)
  37. plan = features.billing.subscription.plan
  38. if plan != "sandbox":
  39. knowledge_details = []
  40. # check tenant
  41. tenant = db.session.query(Tenant).filter(Tenant.id == tenant_id).first()
  42. if not tenant:
  43. continue
  44. # check current owner
  45. current_owner_join = (
  46. db.session.query(TenantAccountJoin).filter_by(tenant_id=tenant.id, role="owner").first()
  47. )
  48. if not current_owner_join:
  49. continue
  50. account = db.session.query(Account).filter(Account.id == current_owner_join.account_id).first()
  51. if not account:
  52. continue
  53. dataset_auto_dataset_map = {} # type: ignore
  54. for dataset_auto_disable_log in tenant_dataset_auto_disable_logs:
  55. if dataset_auto_disable_log.dataset_id not in dataset_auto_dataset_map:
  56. dataset_auto_dataset_map[dataset_auto_disable_log.dataset_id] = []
  57. dataset_auto_dataset_map[dataset_auto_disable_log.dataset_id].append(
  58. dataset_auto_disable_log.document_id
  59. )
  60. for dataset_id, document_ids in dataset_auto_dataset_map.items():
  61. dataset = db.session.query(Dataset).filter(Dataset.id == dataset_id).first()
  62. if dataset:
  63. document_count = len(document_ids)
  64. knowledge_details.append(rf"Knowledge base {dataset.name}: {document_count} documents")
  65. if knowledge_details:
  66. html_content = render_template(
  67. "clean_document_job_mail_template-US.html",
  68. userName=account.email,
  69. knowledge_details=knowledge_details,
  70. url=url,
  71. )
  72. mail.send(
  73. to=account.email, subject="Dify Knowledge base auto disable notification", html=html_content
  74. )
  75. # update notified to True
  76. for dataset_auto_disable_log in tenant_dataset_auto_disable_logs:
  77. dataset_auto_disable_log.notified = True
  78. db.session.commit()
  79. end_at = time.perf_counter()
  80. logging.info(
  81. click.style("Send document clean notify mail succeeded: latency: {}".format(end_at - start_at), fg="green")
  82. )
  83. except Exception:
  84. logging.exception("Send document clean notify mail failed")