| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  | import logging | 
					
						
							|  |  |  | import time | 
					
						
							| 
									
										
										
										
											2024-12-26 00:16:35 +08:00
										 |  |  | from collections import defaultdict | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import click | 
					
						
							| 
									
										
										
										
											2024-12-26 18:14:08 +08:00
										 |  |  | from flask import render_template  # type: ignore | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-26 18:14:08 +08:00
										 |  |  | import app | 
					
						
							|  |  |  | from configs import dify_config | 
					
						
							|  |  |  | from extensions.ext_database import db | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  | from extensions.ext_mail import mail | 
					
						
							|  |  |  | from models.account import Account, Tenant, TenantAccountJoin | 
					
						
							|  |  |  | from models.dataset import Dataset, DatasetAutoDisableLog | 
					
						
							| 
									
										
										
										
											2024-12-26 18:14:08 +08:00
										 |  |  | from services.feature_service import FeatureService | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-26 18:14:08 +08:00
										 |  |  | @app.celery.task(queue="dataset") | 
					
						
							| 
									
										
										
										
											2025-03-25 10:25:15 +08:00
										 |  |  | def mail_clean_document_notify_task(): | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     Async Send document clean notify mail | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-25 10:25:15 +08:00
										 |  |  |     Usage: mail_clean_document_notify_task.delay() | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     if not mail.is_inited(): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     logging.info(click.style("Start send document clean notify mail", fg="green")) | 
					
						
							|  |  |  |     start_at = time.perf_counter() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # send document clean notify mail | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         dataset_auto_disable_logs = DatasetAutoDisableLog.query.filter(DatasetAutoDisableLog.notified == False).all() | 
					
						
							|  |  |  |         # group by tenant_id | 
					
						
							| 
									
										
										
										
											2024-12-26 00:16:35 +08:00
										 |  |  |         dataset_auto_disable_logs_map: dict[str, list[DatasetAutoDisableLog]] = defaultdict(list) | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  |         for dataset_auto_disable_log in dataset_auto_disable_logs: | 
					
						
							| 
									
										
										
										
											2024-12-26 18:14:08 +08:00
										 |  |  |             if dataset_auto_disable_log.tenant_id not in dataset_auto_disable_logs_map: | 
					
						
							|  |  |  |                 dataset_auto_disable_logs_map[dataset_auto_disable_log.tenant_id] = [] | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  |             dataset_auto_disable_logs_map[dataset_auto_disable_log.tenant_id].append(dataset_auto_disable_log) | 
					
						
							| 
									
										
										
										
											2024-12-26 18:14:08 +08:00
										 |  |  |         url = f"{dify_config.CONSOLE_WEB_URL}/datasets" | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  |         for tenant_id, tenant_dataset_auto_disable_logs in dataset_auto_disable_logs_map.items(): | 
					
						
							| 
									
										
										
										
											2024-12-26 18:14:08 +08:00
										 |  |  |             features = FeatureService.get_features(tenant_id) | 
					
						
							|  |  |  |             plan = features.billing.subscription.plan | 
					
						
							|  |  |  |             if plan != "sandbox": | 
					
						
							|  |  |  |                 knowledge_details = [] | 
					
						
							|  |  |  |                 # check tenant | 
					
						
							|  |  |  |                 tenant = Tenant.query.filter(Tenant.id == tenant_id).first() | 
					
						
							|  |  |  |                 if not tenant: | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 # check current owner | 
					
						
							|  |  |  |                 current_owner_join = TenantAccountJoin.query.filter_by(tenant_id=tenant.id, role="owner").first() | 
					
						
							|  |  |  |                 if not current_owner_join: | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 account = Account.query.filter(Account.id == current_owner_join.account_id).first() | 
					
						
							|  |  |  |                 if not account: | 
					
						
							|  |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-26 18:14:08 +08:00
										 |  |  |                 dataset_auto_dataset_map = {}  # type: ignore | 
					
						
							|  |  |  |                 for dataset_auto_disable_log in tenant_dataset_auto_disable_logs: | 
					
						
							|  |  |  |                     if dataset_auto_disable_log.dataset_id not in dataset_auto_dataset_map: | 
					
						
							|  |  |  |                         dataset_auto_dataset_map[dataset_auto_disable_log.dataset_id] = [] | 
					
						
							|  |  |  |                     dataset_auto_dataset_map[dataset_auto_disable_log.dataset_id].append( | 
					
						
							|  |  |  |                         dataset_auto_disable_log.document_id | 
					
						
							|  |  |  |                     ) | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-26 18:14:08 +08:00
										 |  |  |                 for dataset_id, document_ids in dataset_auto_dataset_map.items(): | 
					
						
							|  |  |  |                     dataset = Dataset.query.filter(Dataset.id == dataset_id).first() | 
					
						
							|  |  |  |                     if dataset: | 
					
						
							|  |  |  |                         document_count = len(document_ids) | 
					
						
							|  |  |  |                         knowledge_details.append(rf"Knowledge base {dataset.name}: {document_count} documents") | 
					
						
							|  |  |  |                 if knowledge_details: | 
					
						
							|  |  |  |                     html_content = render_template( | 
					
						
							|  |  |  |                         "clean_document_job_mail_template-US.html", | 
					
						
							|  |  |  |                         userName=account.email, | 
					
						
							|  |  |  |                         knowledge_details=knowledge_details, | 
					
						
							|  |  |  |                         url=url, | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                     mail.send( | 
					
						
							|  |  |  |                         to=account.email, subject="Dify Knowledge base auto disable notification", html=html_content | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # update notified to True | 
					
						
							|  |  |  |             for dataset_auto_disable_log in tenant_dataset_auto_disable_logs: | 
					
						
							|  |  |  |                 dataset_auto_disable_log.notified = True | 
					
						
							|  |  |  |             db.session.commit() | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  |         end_at = time.perf_counter() | 
					
						
							|  |  |  |         logging.info( | 
					
						
							|  |  |  |             click.style("Send document clean notify mail succeeded: latency: {}".format(end_at - start_at), fg="green") | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     except Exception: | 
					
						
							| 
									
										
										
										
											2024-12-26 18:14:08 +08:00
										 |  |  |         logging.exception("Send document clean notify mail failed") |