mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 17:38:04 +08:00
Merge branch 'main' into feat/plugin-readme
This commit is contained in:
@ -425,7 +425,7 @@ class AccountService:
|
||||
cls,
|
||||
account: Optional[Account] = None,
|
||||
email: Optional[str] = None,
|
||||
language: Optional[str] = "en-US",
|
||||
language: str = "en-US",
|
||||
):
|
||||
account_email = account.email if account else email
|
||||
if account_email is None:
|
||||
@ -452,12 +452,14 @@ class AccountService:
|
||||
account: Optional[Account] = None,
|
||||
email: Optional[str] = None,
|
||||
old_email: Optional[str] = None,
|
||||
language: Optional[str] = "en-US",
|
||||
language: str = "en-US",
|
||||
phase: Optional[str] = None,
|
||||
):
|
||||
account_email = account.email if account else email
|
||||
if account_email is None:
|
||||
raise ValueError("Email must be provided.")
|
||||
if not phase:
|
||||
raise ValueError("phase must be provided.")
|
||||
|
||||
if cls.change_email_rate_limiter.is_rate_limited(account_email):
|
||||
from controllers.console.auth.error import EmailChangeRateLimitExceededError
|
||||
@ -480,7 +482,7 @@ class AccountService:
|
||||
cls,
|
||||
account: Optional[Account] = None,
|
||||
email: Optional[str] = None,
|
||||
language: Optional[str] = "en-US",
|
||||
language: str = "en-US",
|
||||
):
|
||||
account_email = account.email if account else email
|
||||
if account_email is None:
|
||||
@ -496,7 +498,7 @@ class AccountService:
|
||||
cls,
|
||||
account: Optional[Account] = None,
|
||||
email: Optional[str] = None,
|
||||
language: Optional[str] = "en-US",
|
||||
language: str = "en-US",
|
||||
workspace_name: Optional[str] = "",
|
||||
):
|
||||
account_email = account.email if account else email
|
||||
@ -509,6 +511,7 @@ class AccountService:
|
||||
raise OwnerTransferRateLimitExceededError()
|
||||
|
||||
code, token = cls.generate_owner_transfer_token(account_email, account)
|
||||
workspace_name = workspace_name or ""
|
||||
|
||||
send_owner_transfer_confirm_task.delay(
|
||||
language=language,
|
||||
@ -524,13 +527,14 @@ class AccountService:
|
||||
cls,
|
||||
account: Optional[Account] = None,
|
||||
email: Optional[str] = None,
|
||||
language: Optional[str] = "en-US",
|
||||
language: str = "en-US",
|
||||
workspace_name: Optional[str] = "",
|
||||
new_owner_email: Optional[str] = "",
|
||||
new_owner_email: str = "",
|
||||
):
|
||||
account_email = account.email if account else email
|
||||
if account_email is None:
|
||||
raise ValueError("Email must be provided.")
|
||||
workspace_name = workspace_name or ""
|
||||
|
||||
send_old_owner_transfer_notify_email_task.delay(
|
||||
language=language,
|
||||
@ -544,12 +548,13 @@ class AccountService:
|
||||
cls,
|
||||
account: Optional[Account] = None,
|
||||
email: Optional[str] = None,
|
||||
language: Optional[str] = "en-US",
|
||||
language: str = "en-US",
|
||||
workspace_name: Optional[str] = "",
|
||||
):
|
||||
account_email = account.email if account else email
|
||||
if account_email is None:
|
||||
raise ValueError("Email must be provided.")
|
||||
workspace_name = workspace_name or ""
|
||||
|
||||
send_new_owner_transfer_notify_email_task.delay(
|
||||
language=language,
|
||||
@ -633,7 +638,10 @@ class AccountService:
|
||||
|
||||
@classmethod
|
||||
def send_email_code_login_email(
|
||||
cls, account: Optional[Account] = None, email: Optional[str] = None, language: Optional[str] = "en-US"
|
||||
cls,
|
||||
account: Optional[Account] = None,
|
||||
email: Optional[str] = None,
|
||||
language: str = "en-US",
|
||||
):
|
||||
email = account.email if account else email
|
||||
if email is None:
|
||||
@ -1260,10 +1268,11 @@ class RegisterService:
|
||||
raise AccountAlreadyInTenantError("Account already in tenant.")
|
||||
|
||||
token = cls.generate_invite_token(tenant, account)
|
||||
language = account.interface_language or "en-US"
|
||||
|
||||
# send email
|
||||
send_invite_member_mail_task.delay(
|
||||
language=account.interface_language,
|
||||
language=language,
|
||||
to=email,
|
||||
token=token,
|
||||
inviter_name=inviter.name if inviter else "Dify",
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import datetime
|
||||
import uuid
|
||||
from typing import cast
|
||||
|
||||
@ -10,6 +9,7 @@ from werkzeug.exceptions import NotFound
|
||||
|
||||
from extensions.ext_database import db
|
||||
from extensions.ext_redis import redis_client
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from models.model import App, AppAnnotationHitHistory, AppAnnotationSetting, Message, MessageAnnotation
|
||||
from services.feature_service import FeatureService
|
||||
from tasks.annotation.add_annotation_to_index_task import add_annotation_to_index_task
|
||||
@ -473,7 +473,7 @@ class AppAnnotationService:
|
||||
raise NotFound("App annotation not found")
|
||||
annotation_setting.score_threshold = args["score_threshold"]
|
||||
annotation_setting.updated_user_id = current_user.id
|
||||
annotation_setting.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
annotation_setting.updated_at = naive_utc_now()
|
||||
db.session.add(annotation_setting)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import contextlib
|
||||
import logging
|
||||
from collections.abc import Callable, Sequence
|
||||
from typing import Any, Optional, Union
|
||||
|
||||
@ -23,6 +24,9 @@ from services.errors.conversation import (
|
||||
LastConversationNotExistsError,
|
||||
)
|
||||
from services.errors.message import MessageNotExistsError
|
||||
from tasks.delete_conversation_task import delete_conversation_related_data
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ConversationService:
|
||||
@ -175,11 +179,21 @@ class ConversationService:
|
||||
|
||||
@classmethod
|
||||
def delete(cls, app_model: App, conversation_id: str, user: Optional[Union[Account, EndUser]]):
|
||||
conversation = cls.get_conversation(app_model, conversation_id, user)
|
||||
try:
|
||||
logger.info(
|
||||
"Initiating conversation deletion for app_name %s, conversation_id: %s",
|
||||
app_model.name,
|
||||
conversation_id,
|
||||
)
|
||||
|
||||
conversation.is_deleted = True
|
||||
conversation.updated_at = naive_utc_now()
|
||||
db.session.commit()
|
||||
db.session.query(Conversation).where(Conversation.id == conversation_id).delete(synchronize_session=False)
|
||||
db.session.commit()
|
||||
|
||||
delete_conversation_related_data.delay(conversation_id)
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
raise e
|
||||
|
||||
@classmethod
|
||||
def get_conversational_variable(
|
||||
|
||||
@ -1234,7 +1234,7 @@ class DocumentService:
|
||||
)
|
||||
if document:
|
||||
document.dataset_process_rule_id = dataset_process_rule.id # type: ignore
|
||||
document.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
document.updated_at = naive_utc_now()
|
||||
document.created_from = created_from
|
||||
document.doc_form = knowledge_config.doc_form
|
||||
document.doc_language = knowledge_config.doc_language
|
||||
@ -1552,7 +1552,7 @@ class DocumentService:
|
||||
document.parsing_completed_at = None
|
||||
document.cleaning_completed_at = None
|
||||
document.splitting_completed_at = None
|
||||
document.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
document.updated_at = naive_utc_now()
|
||||
document.created_from = created_from
|
||||
document.doc_form = document_data.doc_form
|
||||
db.session.add(document)
|
||||
@ -1912,7 +1912,7 @@ class DocumentService:
|
||||
Returns:
|
||||
dict: Update information or None if no update needed
|
||||
"""
|
||||
now = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
now = naive_utc_now()
|
||||
|
||||
if action == "enable":
|
||||
return DocumentService._prepare_enable_update(document, now)
|
||||
@ -2040,8 +2040,8 @@ class SegmentService:
|
||||
word_count=len(content),
|
||||
tokens=tokens,
|
||||
status="completed",
|
||||
indexing_at=datetime.datetime.now(datetime.UTC).replace(tzinfo=None),
|
||||
completed_at=datetime.datetime.now(datetime.UTC).replace(tzinfo=None),
|
||||
indexing_at=naive_utc_now(),
|
||||
completed_at=naive_utc_now(),
|
||||
created_by=current_user.id,
|
||||
)
|
||||
if document.doc_form == "qa_model":
|
||||
@ -2061,7 +2061,7 @@ class SegmentService:
|
||||
except Exception as e:
|
||||
logging.exception("create segment index failed")
|
||||
segment_document.enabled = False
|
||||
segment_document.disabled_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
segment_document.disabled_at = naive_utc_now()
|
||||
segment_document.status = "error"
|
||||
segment_document.error = str(e)
|
||||
db.session.commit()
|
||||
@ -2117,8 +2117,8 @@ class SegmentService:
|
||||
tokens=tokens,
|
||||
keywords=segment_item.get("keywords", []),
|
||||
status="completed",
|
||||
indexing_at=datetime.datetime.now(datetime.UTC).replace(tzinfo=None),
|
||||
completed_at=datetime.datetime.now(datetime.UTC).replace(tzinfo=None),
|
||||
indexing_at=naive_utc_now(),
|
||||
completed_at=naive_utc_now(),
|
||||
created_by=current_user.id,
|
||||
)
|
||||
if document.doc_form == "qa_model":
|
||||
@ -2145,7 +2145,7 @@ class SegmentService:
|
||||
logging.exception("create segment index failed")
|
||||
for segment_document in segment_data_list:
|
||||
segment_document.enabled = False
|
||||
segment_document.disabled_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
segment_document.disabled_at = naive_utc_now()
|
||||
segment_document.status = "error"
|
||||
segment_document.error = str(e)
|
||||
db.session.commit()
|
||||
@ -2162,7 +2162,7 @@ class SegmentService:
|
||||
if segment.enabled != action:
|
||||
if not action:
|
||||
segment.enabled = action
|
||||
segment.disabled_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
segment.disabled_at = naive_utc_now()
|
||||
segment.disabled_by = current_user.id
|
||||
db.session.add(segment)
|
||||
db.session.commit()
|
||||
@ -2260,10 +2260,10 @@ class SegmentService:
|
||||
segment.word_count = len(content)
|
||||
segment.tokens = tokens
|
||||
segment.status = "completed"
|
||||
segment.indexing_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
segment.completed_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
segment.indexing_at = naive_utc_now()
|
||||
segment.completed_at = naive_utc_now()
|
||||
segment.updated_by = current_user.id
|
||||
segment.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
segment.updated_at = naive_utc_now()
|
||||
segment.enabled = True
|
||||
segment.disabled_at = None
|
||||
segment.disabled_by = None
|
||||
@ -2316,7 +2316,7 @@ class SegmentService:
|
||||
except Exception as e:
|
||||
logging.exception("update segment index failed")
|
||||
segment.enabled = False
|
||||
segment.disabled_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
segment.disabled_at = naive_utc_now()
|
||||
segment.status = "error"
|
||||
segment.error = str(e)
|
||||
db.session.commit()
|
||||
@ -2344,13 +2344,9 @@ class SegmentService:
|
||||
|
||||
@classmethod
|
||||
def delete_segments(cls, segment_ids: list, document: Document, dataset: Dataset):
|
||||
# Check if segment_ids is not empty to avoid WHERE false condition
|
||||
if not segment_ids or len(segment_ids) == 0:
|
||||
return
|
||||
index_node_ids = (
|
||||
db.session.query(DocumentSegment)
|
||||
.with_entities(DocumentSegment.index_node_id)
|
||||
.where(
|
||||
segments = (
|
||||
db.session.query(DocumentSegment.index_node_id, DocumentSegment.word_count)
|
||||
.filter(
|
||||
DocumentSegment.id.in_(segment_ids),
|
||||
DocumentSegment.dataset_id == dataset.id,
|
||||
DocumentSegment.document_id == document.id,
|
||||
@ -2358,7 +2354,15 @@ class SegmentService:
|
||||
)
|
||||
.all()
|
||||
)
|
||||
index_node_ids = [index_node_id[0] for index_node_id in index_node_ids]
|
||||
|
||||
if not segments:
|
||||
return
|
||||
|
||||
index_node_ids = [seg.index_node_id for seg in segments]
|
||||
total_words = sum(seg.word_count for seg in segments)
|
||||
|
||||
document.word_count -= total_words
|
||||
db.session.add(document)
|
||||
|
||||
delete_segment_from_index_task.delay(index_node_ids, dataset.id, document.id)
|
||||
db.session.query(DocumentSegment).where(DocumentSegment.id.in_(segment_ids)).delete()
|
||||
@ -2418,7 +2422,7 @@ class SegmentService:
|
||||
if cache_result is not None:
|
||||
continue
|
||||
segment.enabled = False
|
||||
segment.disabled_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
segment.disabled_at = naive_utc_now()
|
||||
segment.disabled_by = current_user.id
|
||||
db.session.add(segment)
|
||||
real_deal_segment_ids.append(segment.id)
|
||||
@ -2508,7 +2512,7 @@ class SegmentService:
|
||||
child_chunk.content = child_chunk_update_args.content
|
||||
child_chunk.word_count = len(child_chunk.content)
|
||||
child_chunk.updated_by = current_user.id
|
||||
child_chunk.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
child_chunk.updated_at = naive_utc_now()
|
||||
child_chunk.type = "customized"
|
||||
update_child_chunks.append(child_chunk)
|
||||
else:
|
||||
@ -2565,7 +2569,7 @@ class SegmentService:
|
||||
child_chunk.content = content
|
||||
child_chunk.word_count = len(content)
|
||||
child_chunk.updated_by = current_user.id
|
||||
child_chunk.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
child_chunk.updated_at = naive_utc_now()
|
||||
child_chunk.type = "customized"
|
||||
db.session.add(child_chunk)
|
||||
VectorService.update_child_chunk_vector([], [child_chunk], [], dataset)
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import datetime
|
||||
import hashlib
|
||||
import os
|
||||
import uuid
|
||||
@ -18,6 +17,7 @@ from core.file import helpers as file_helpers
|
||||
from core.rag.extractor.extract_processor import ExtractProcessor
|
||||
from extensions.ext_database import db
|
||||
from extensions.ext_storage import storage
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from libs.helper import extract_tenant_id
|
||||
from models.account import Account
|
||||
from models.enums import CreatorUserRole
|
||||
@ -80,7 +80,7 @@ class FileService:
|
||||
mime_type=mimetype,
|
||||
created_by_role=(CreatorUserRole.ACCOUNT if isinstance(user, Account) else CreatorUserRole.END_USER),
|
||||
created_by=user.id,
|
||||
created_at=datetime.datetime.now(datetime.UTC).replace(tzinfo=None),
|
||||
created_at=naive_utc_now(),
|
||||
used=False,
|
||||
hash=hashlib.sha3_256(content).hexdigest(),
|
||||
source_url=source_url,
|
||||
@ -131,10 +131,10 @@ class FileService:
|
||||
mime_type="text/plain",
|
||||
created_by=current_user.id,
|
||||
created_by_role=CreatorUserRole.ACCOUNT,
|
||||
created_at=datetime.datetime.now(datetime.UTC).replace(tzinfo=None),
|
||||
created_at=naive_utc_now(),
|
||||
used=True,
|
||||
used_by=current_user.id,
|
||||
used_at=datetime.datetime.now(datetime.UTC).replace(tzinfo=None),
|
||||
used_at=naive_utc_now(),
|
||||
)
|
||||
|
||||
db.session.add(upload_file)
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import copy
|
||||
import datetime
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
@ -8,6 +7,7 @@ from flask_login import current_user
|
||||
from core.rag.index_processor.constant.built_in_field import BuiltInField, MetadataDataSource
|
||||
from extensions.ext_database import db
|
||||
from extensions.ext_redis import redis_client
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from models.dataset import Dataset, DatasetMetadata, DatasetMetadataBinding
|
||||
from services.dataset_service import DocumentService
|
||||
from services.entities.knowledge_entities.knowledge_entities import (
|
||||
@ -69,7 +69,7 @@ class MetadataService:
|
||||
old_name = metadata.name
|
||||
metadata.name = name
|
||||
metadata.updated_by = current_user.id
|
||||
metadata.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
metadata.updated_at = naive_utc_now()
|
||||
|
||||
# update related documents
|
||||
dataset_metadata_bindings = (
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import datetime
|
||||
import json
|
||||
import logging
|
||||
from json import JSONDecodeError
|
||||
@ -17,6 +16,7 @@ from core.model_runtime.entities.provider_entities import (
|
||||
from core.model_runtime.model_providers.model_provider_factory import ModelProviderFactory
|
||||
from core.provider_manager import ProviderManager
|
||||
from extensions.ext_database import db
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from models.provider import LoadBalancingModelConfig
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -371,7 +371,7 @@ class ModelLoadBalancingService:
|
||||
|
||||
load_balancing_config.name = name
|
||||
load_balancing_config.enabled = enabled
|
||||
load_balancing_config.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
load_balancing_config.updated_at = naive_utc_now()
|
||||
db.session.commit()
|
||||
|
||||
self._clear_credentials_cache(tenant_id, config_id)
|
||||
|
||||
@ -63,7 +63,7 @@ class WebAppAuthService:
|
||||
|
||||
@classmethod
|
||||
def send_email_code_login_email(
|
||||
cls, account: Optional[Account] = None, email: Optional[str] = None, language: Optional[str] = "en-US"
|
||||
cls, account: Optional[Account] = None, email: Optional[str] = None, language: str = "en-US"
|
||||
):
|
||||
email = account.email if account else email
|
||||
if email is None:
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import dataclasses
|
||||
import datetime
|
||||
import logging
|
||||
from collections.abc import Mapping, Sequence
|
||||
from enum import StrEnum
|
||||
@ -23,6 +22,7 @@ from core.workflow.nodes.variable_assigner.common.helpers import get_updated_var
|
||||
from core.workflow.variable_loader import VariableLoader
|
||||
from factories.file_factory import StorageKeyLoader
|
||||
from factories.variable_factory import build_segment, segment_to_variable
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from models import App, Conversation
|
||||
from models.enums import DraftVariableType
|
||||
from models.workflow import Workflow, WorkflowDraftVariable, is_system_variable_editable
|
||||
@ -231,7 +231,7 @@ class WorkflowDraftVariableService:
|
||||
variable.set_name(name)
|
||||
if value is not None:
|
||||
variable.set_value(value)
|
||||
variable.last_edited_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||
variable.last_edited_at = naive_utc_now()
|
||||
self._session.flush()
|
||||
return variable
|
||||
|
||||
|
||||
Reference in New Issue
Block a user