latest
This commit is contained in:
@@ -9,6 +9,7 @@ import modules.database.schemas.nodes.workers.workers as worker_nodes
|
||||
import modules.database.init.init_calendar as init_calendar
|
||||
import modules.database.schemas.relationships.entity_relationships as entity_relationships
|
||||
import modules.database.tools.neontology_tools as neon
|
||||
import modules.database.tools.supabase_storage_tools as storage_tools
|
||||
from modules.logger_tool import initialise_logger
|
||||
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
|
||||
|
||||
@@ -21,11 +22,27 @@ def create_and_check_db(db_name):
|
||||
return database_status
|
||||
|
||||
class UserCreator(ABC):
|
||||
def __init__(self, user_id, cc_users_db_name, user_type, worker_type, user_email, worker_email, cc_username, user_name, worker_name, calendar_start_date, calendar_end_date):
|
||||
cc_schools_db_name = "cc.institutes" # Fix the TODO
|
||||
def __init__(
|
||||
self,
|
||||
user_id,
|
||||
cc_users_db_name,
|
||||
user_type,
|
||||
worker_type,
|
||||
user_email,
|
||||
worker_email,
|
||||
cc_username,
|
||||
user_name,
|
||||
worker_name,
|
||||
calendar_start_date,
|
||||
calendar_end_date,
|
||||
storage_tools=None,
|
||||
user_db_name: Optional[str] = None,
|
||||
worker_db_name: Optional[str] = None,
|
||||
cc_schools_db_name: str = "cc.institutes",
|
||||
):
|
||||
self.cc_users_db_name = cc_users_db_name
|
||||
self.user_db_name = f"{cc_users_db_name}.{user_type}.{cc_username}"
|
||||
self.worker_db_name = f"{cc_schools_db_name}.{user_type}.{cc_username}"
|
||||
self.user_db_name = user_db_name or f"{cc_users_db_name}.{user_type}.{cc_username}"
|
||||
self.worker_db_name = worker_db_name or f"{cc_schools_db_name}.{worker_type}.{cc_username}"
|
||||
self.user_type = user_type
|
||||
self.worker_type = worker_type
|
||||
self.cc_username = cc_username
|
||||
@@ -34,6 +51,7 @@ class UserCreator(ABC):
|
||||
self.user_name = user_name
|
||||
self.worker_name = worker_name
|
||||
self.user_id = user_id
|
||||
self.storage_tools = storage_tools # Store the storage tools instance
|
||||
self.user_nodes: Dict[str, Optional[Any]] = {
|
||||
'default_user_node': None,
|
||||
'private_user_node': None,
|
||||
@@ -48,6 +66,25 @@ class UserCreator(ABC):
|
||||
self.calendar_start_date = datetime.now().date()
|
||||
self.calendar_end_date = (datetime.now() + timedelta(days=5)).date()
|
||||
|
||||
def _derive_user_storage_path(self) -> str:
|
||||
return os.path.join(
|
||||
"users",
|
||||
self.user_id,
|
||||
"databases",
|
||||
self.user_db_name,
|
||||
self.user_id,
|
||||
).replace('\\', '/')
|
||||
|
||||
def _derive_internal_worker_path(self, worker_kind: str) -> str:
|
||||
return os.path.join(
|
||||
"users",
|
||||
self.user_id,
|
||||
"databases",
|
||||
self.user_db_name,
|
||||
worker_kind,
|
||||
self.user_id,
|
||||
).replace('\\', '/')
|
||||
|
||||
@abstractmethod
|
||||
def create_user(self):
|
||||
pass
|
||||
@@ -66,9 +103,17 @@ class UserCreator(ABC):
|
||||
# Ensure Neontology is initialized
|
||||
neon.init_neontology_connection()
|
||||
|
||||
# Generate storage path for user node using Supabase Storage
|
||||
if self.storage_tools:
|
||||
user_dir_created, node_storage_path = self.storage_tools.create_user_storage_path(self.user_id)
|
||||
self.user_path = node_storage_path # Store for later use
|
||||
else:
|
||||
node_storage_path = self._derive_user_storage_path()
|
||||
self.user_path = None
|
||||
|
||||
user_node = user_nodes.UserNode(
|
||||
unique_id=f"{self.user_id}",
|
||||
tldraw_snapshot="",
|
||||
uuid_string=f"{self.user_id}",
|
||||
node_storage_path=node_storage_path,
|
||||
cc_username=f"{self.cc_username}",
|
||||
user_email=f"{self.user_email}",
|
||||
user_name=f"{self.user_name}",
|
||||
@@ -76,81 +121,79 @@ class UserCreator(ABC):
|
||||
user_type=f"{self.user_type}",
|
||||
)
|
||||
logger.debug(f"User node template created: {user_node.to_dict()}. Writing to database {db_name}")
|
||||
neon.create_or_merge_neontology_node(node=user_node, database=db_name, operation='merge')
|
||||
logger.info(f"User node created: {user_node.to_dict()}")
|
||||
logger.debug(f"About to call create_or_merge_neontology_node with node class: {user_node.__class__.__name__}")
|
||||
logger.debug(f"Node primary label: {user_node.__primarylabel__}")
|
||||
logger.debug(f"Node primary property: {user_node.__primaryproperty__}")
|
||||
|
||||
try:
|
||||
neon.create_or_merge_neontology_node(node=user_node, database=db_name, operation='merge')
|
||||
logger.info(f"User node created successfully: {user_node.to_dict()}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to create user node: {e}")
|
||||
raise
|
||||
return user_node
|
||||
|
||||
def create_storage_bucket(self, bucket_id: str, bucket_name: str, access_token: Optional[str] = None) -> bool:
|
||||
"""Create public and private storage buckets for the user using their access token or service role during initialization"""
|
||||
logger.info(f"Creating storage buckets for user {self.cc_username}")
|
||||
|
||||
try:
|
||||
from modules.database.supabase.utils.client import SupabaseServiceRoleClient, SupabaseAnonClient, CreateBucketOptions
|
||||
|
||||
# During initialization (no access token provided), use service role
|
||||
if not access_token:
|
||||
logger.info("Using service role client for bucket creation during initialization")
|
||||
supabase = SupabaseServiceRoleClient()
|
||||
else:
|
||||
# For regular operations, use the user's access token
|
||||
logger.info("Using user token for bucket creation")
|
||||
supabase = SupabaseAnonClient.for_user(access_token)
|
||||
|
||||
# Create both public and private buckets
|
||||
buckets = [
|
||||
{
|
||||
"id": f"{bucket_id}.public",
|
||||
"options": CreateBucketOptions(
|
||||
name=f"{bucket_name} - Public Files",
|
||||
public=True,
|
||||
file_size_limit=50 * 1024 * 1024, # 50MB
|
||||
allowed_mime_types=[
|
||||
'image/*', 'video/*', 'application/pdf',
|
||||
'application/msword', 'application/vnd.openxmlformats-officedocument.*',
|
||||
'text/plain', 'text/csv', 'application/json'
|
||||
]
|
||||
)
|
||||
},
|
||||
{
|
||||
"id": f"{bucket_id}.private",
|
||||
"options": CreateBucketOptions(
|
||||
name=f"{bucket_name} - Private Files",
|
||||
public=False,
|
||||
file_size_limit=50 * 1024 * 1024, # 50MB
|
||||
allowed_mime_types=[
|
||||
'image/*', 'video/*', 'application/pdf',
|
||||
'application/msword', 'application/vnd.openxmlformats-officedocument.*',
|
||||
'text/plain', 'text/csv', 'application/json'
|
||||
]
|
||||
)
|
||||
}
|
||||
]
|
||||
|
||||
success = True
|
||||
for bucket in buckets:
|
||||
try:
|
||||
result = supabase.create_bucket(bucket["id"], bucket["options"])
|
||||
if not result:
|
||||
logger.error(f"Failed to create bucket {bucket['id']}")
|
||||
success = False
|
||||
else:
|
||||
logger.info(f"Successfully created bucket {bucket['id']}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating bucket {bucket['id']}: {str(e)}")
|
||||
success = False
|
||||
|
||||
return success
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating storage buckets: {str(e)}")
|
||||
return False
|
||||
"""Create storage buckets for the user - DEPRECATED: Use centralized bucket initialization instead"""
|
||||
logger.warning(f"Individual user bucket creation is deprecated. Use centralized bucket initialization instead.")
|
||||
logger.info(f"User {self.cc_username} will use centralized storage buckets.")
|
||||
return True # Return success to avoid breaking existing code
|
||||
|
||||
class SchoolUserCreator(UserCreator):
|
||||
def __init__(self, user_id, cc_users_db_name, user_type, worker_type, user_email, worker_email, cc_username, user_name, worker_name, calendar_start_date, calendar_end_date, school_node, worker_node=None):
|
||||
super().__init__(user_id, cc_users_db_name, user_type, worker_type, user_email, worker_email, cc_username, user_name, worker_name, calendar_start_date, calendar_end_date)
|
||||
def __init__(
|
||||
self,
|
||||
user_id,
|
||||
cc_users_db_name,
|
||||
user_type,
|
||||
worker_type,
|
||||
user_email,
|
||||
worker_email,
|
||||
cc_username,
|
||||
user_name,
|
||||
worker_name,
|
||||
calendar_start_date,
|
||||
calendar_end_date,
|
||||
school_node,
|
||||
worker_node=None,
|
||||
storage_tools=None,
|
||||
user_db_name: Optional[str] = None,
|
||||
worker_db_name: Optional[str] = None,
|
||||
):
|
||||
super().__init__(
|
||||
user_id,
|
||||
cc_users_db_name,
|
||||
user_type,
|
||||
worker_type,
|
||||
user_email,
|
||||
worker_email,
|
||||
cc_username,
|
||||
user_name,
|
||||
worker_name,
|
||||
calendar_start_date,
|
||||
calendar_end_date,
|
||||
storage_tools,
|
||||
user_db_name=user_db_name,
|
||||
worker_db_name=worker_db_name or (school_node.private_database_name if hasattr(school_node, "private_database_name") else None),
|
||||
cc_schools_db_name="cc.institutes",
|
||||
)
|
||||
self.school_node = school_node
|
||||
self.worker_node = worker_node
|
||||
|
||||
|
||||
def _derive_school_worker_path(self, worker_kind: str) -> str:
|
||||
school_identifier = getattr(self.school_node, 'uuid_string', None) if self.school_node else None
|
||||
if not school_identifier and self.worker_db_name:
|
||||
school_identifier = self.worker_db_name.split('.')[-1]
|
||||
school_identifier = school_identifier or self.user_id
|
||||
db_name_segment = self.worker_db_name or f"cc.institutes.{school_identifier}"
|
||||
return os.path.join(
|
||||
"schools",
|
||||
school_identifier,
|
||||
"databases",
|
||||
db_name_segment,
|
||||
worker_kind,
|
||||
self.user_id,
|
||||
).replace('\\', '/')
|
||||
|
||||
def create_user(self):
|
||||
# Ensure Neontology is initialized
|
||||
logger.debug(f"Initializing Neontology connection. Closing any existing connection")
|
||||
@@ -167,7 +210,7 @@ class SchoolUserCreator(UserCreator):
|
||||
|
||||
self.user_nodes[f'worker_node'] = worker_node
|
||||
|
||||
user_node = self.create_user_node(self.cc_users_db_name)
|
||||
user_node = self.create_user_node(self.user_db_name)
|
||||
|
||||
logger.info(f"User node created: {user_node}")
|
||||
|
||||
@@ -190,16 +233,25 @@ class SchoolUserCreator(UserCreator):
|
||||
raise ValueError(f"Error creating teacher node: {e}") from e
|
||||
|
||||
def _create_teacher_node(self):
|
||||
# Generate storage path for teacher node using Supabase Storage
|
||||
if self.storage_tools:
|
||||
teacher_dir_created, node_storage_path = self.storage_tools.create_teacher_storage_path(self.user_id)
|
||||
else:
|
||||
node_storage_path = self._derive_school_worker_path(self.worker_type)
|
||||
|
||||
teacher_node = worker_nodes.TeacherNode(
|
||||
unique_id=f"{self.user_id}",
|
||||
tldraw_snapshot="",
|
||||
uuid_string=f"{self.user_id}",
|
||||
node_storage_path=node_storage_path,
|
||||
worker_name=self.worker_name,
|
||||
worker_email=self.worker_email,
|
||||
worker_db_name=self.worker_db_name,
|
||||
worker_type=self.worker_type
|
||||
)
|
||||
# Use the school's private database name if available
|
||||
school_db = self.school_node.private_database_name if hasattr(self.school_node, 'private_database_name') else f"cc.institutes.{self.school_node.school_type}.{self.school_node.id}"
|
||||
school_db = self.worker_db_name or (
|
||||
self.school_node.private_database_name if hasattr(self.school_node, 'private_database_name')
|
||||
else f"cc.institutes.{self.school_node.school_type}.{getattr(self.school_node, 'id', self.school_node.uuid_string)}"
|
||||
)
|
||||
logger.info(f"Teacher node template created: {teacher_node}... setting school db to {school_db}")
|
||||
|
||||
neon.create_or_merge_neontology_node(node=teacher_node, database=school_db, operation='merge')
|
||||
@@ -208,16 +260,25 @@ class SchoolUserCreator(UserCreator):
|
||||
return teacher_node
|
||||
|
||||
def create_student_node(self):
|
||||
# Generate storage path for student node using Supabase Storage
|
||||
if self.storage_tools:
|
||||
student_dir_created, node_storage_path = self.storage_tools.create_student_storage_path(f"Student_{self.user_id}")
|
||||
else:
|
||||
node_storage_path = self._derive_school_worker_path(self.worker_type)
|
||||
|
||||
student_node = worker_nodes.StudentNode(
|
||||
unique_id=f"Student_{self.user_id}",
|
||||
uuid_string=f"Student_{self.user_id}",
|
||||
worker_name=self.worker_name,
|
||||
worker_email=self.worker_email,
|
||||
worker_db_name=self.worker_db_name,
|
||||
worker_type=self.worker_type,
|
||||
tldraw_snapshot=""
|
||||
node_storage_path=node_storage_path
|
||||
)
|
||||
# Use the school's private database name if available
|
||||
school_db = self.school_node.private_database_name if hasattr(self.school_node, 'private_database_name') else f"cc.institutes.{self.school_node.school_type}.{self.school_node.id}"
|
||||
school_db = self.worker_db_name or (
|
||||
self.school_node.private_database_name if hasattr(self.school_node, 'private_database_name')
|
||||
else f"cc.institutes.{self.school_node.school_type}.{getattr(self.school_node, 'id', self.school_node.uuid_string)}"
|
||||
)
|
||||
logger.info(f"Student node template created: {student_node}... setting school db to {school_db}")
|
||||
|
||||
neon.create_or_merge_neontology_node(node=student_node, database=school_db, operation='merge')
|
||||
@@ -228,20 +289,58 @@ class SchoolUserCreator(UserCreator):
|
||||
def create_user_worker_relationship(self, user_node, worker_node):
|
||||
user_role_rel = entity_relationships.UserIsSchoolWorker(source=user_node, target=worker_node)
|
||||
# Use the school's private database name if available
|
||||
school_db = self.school_node.private_database_name if hasattr(self.school_node, 'private_database_name') else f"cc.institutes.{self.school_node.school_type}.{self.school_node.id}"
|
||||
school_db = self.worker_db_name or (
|
||||
self.school_node.private_database_name if hasattr(self.school_node, 'private_database_name')
|
||||
else f"cc.institutes.{self.school_node.school_type}.{getattr(self.school_node, 'id', self.school_node.uuid_string)}"
|
||||
)
|
||||
neon.create_or_merge_neontology_relationship(user_role_rel, database=school_db, operation='merge')
|
||||
logger.info(f"Relationship created between user and worker in database {school_db}")
|
||||
|
||||
def create_worker_school_relationship(self, worker_node, school_node):
|
||||
worker_school_rel = entity_relationships.EntityBelongsToSchool(source=worker_node, target=school_node)
|
||||
# Use the school's private database name if available
|
||||
school_db = school_node.private_database_name if hasattr(school_node, 'private_database_name') else f"cc.institutes.{school_node.school_type}.{school_node.id}"
|
||||
school_db = self.worker_db_name or (
|
||||
school_node.private_database_name if hasattr(school_node, 'private_database_name')
|
||||
else f"cc.institutes.{school_node.school_type}.{getattr(school_node, 'id', school_node.uuid_string)}"
|
||||
)
|
||||
neon.create_or_merge_neontology_relationship(worker_school_rel, database=school_db, operation='merge')
|
||||
logger.info(f"Relationship created between worker and school in database {school_db}")
|
||||
|
||||
class NonSchoolUserCreator(UserCreator):
|
||||
def __init__(self, user_id, cc_users_db_name, user_type, worker_type, user_email, worker_email, cc_username, user_name, worker_name, calendar_start_date, calendar_end_date, developer_role: str = "developer"):
|
||||
super().__init__(user_id, cc_users_db_name, user_type, worker_type, user_email, worker_email, cc_username, user_name, worker_name, calendar_start_date, calendar_end_date)
|
||||
def __init__(
|
||||
self,
|
||||
user_id,
|
||||
cc_users_db_name,
|
||||
user_type,
|
||||
worker_type,
|
||||
user_email,
|
||||
worker_email,
|
||||
cc_username,
|
||||
user_name,
|
||||
worker_name,
|
||||
calendar_start_date,
|
||||
calendar_end_date,
|
||||
developer_role: str = "developer",
|
||||
storage_tools=None,
|
||||
user_db_name: Optional[str] = None,
|
||||
worker_db_name: Optional[str] = None,
|
||||
):
|
||||
super().__init__(
|
||||
user_id,
|
||||
cc_users_db_name,
|
||||
user_type,
|
||||
worker_type,
|
||||
user_email,
|
||||
worker_email,
|
||||
cc_username,
|
||||
user_name,
|
||||
worker_name,
|
||||
calendar_start_date,
|
||||
calendar_end_date,
|
||||
storage_tools,
|
||||
user_db_name=user_db_name,
|
||||
worker_db_name=worker_db_name,
|
||||
)
|
||||
self.developer_role = developer_role
|
||||
|
||||
def create_user(self, access_token: Optional[str] = None):
|
||||
@@ -273,7 +372,8 @@ class NonSchoolUserCreator(UserCreator):
|
||||
logger.debug(f"Creating developer db for {self.user_type} user {self.cc_username} in database {self.user_db_name}")
|
||||
self.create_developer_db()
|
||||
else:
|
||||
raise ValueError(f"User type {self.user_type} not supported")
|
||||
logger.warning(f"User type {self.user_type} not explicitly supported; defaulting to developer workspace")
|
||||
self.create_developer_db()
|
||||
|
||||
logger.debug(f"User nodes after creation: {self.user_nodes}")
|
||||
return self.user_nodes
|
||||
@@ -290,10 +390,16 @@ class NonSchoolUserCreator(UserCreator):
|
||||
logger.debug(f"Creating super admin user node for {self.user_type} user {self.cc_username} in database {self.user_db_name}")
|
||||
private_user_node = self.create_user_node(self.user_db_name)
|
||||
|
||||
# Generate storage path for super admin node using Supabase Storage
|
||||
if self.storage_tools:
|
||||
admin_dir_created, node_storage_path = self.storage_tools.create_super_admin_storage_path(self.user_id)
|
||||
else:
|
||||
node_storage_path = self._derive_internal_worker_path(self.worker_type)
|
||||
|
||||
super_admin_node = worker_nodes.SuperAdminNode(
|
||||
unique_id=f"SuperAdmin_{self.user_id}",
|
||||
uuid_string=self.user_id,
|
||||
worker_email=self.worker_email,
|
||||
tldraw_snapshot="",
|
||||
node_storage_path=node_storage_path,
|
||||
worker_name=self.worker_name,
|
||||
worker_db_name=self.worker_db_name,
|
||||
worker_type=self.worker_type
|
||||
@@ -329,11 +435,17 @@ class NonSchoolUserCreator(UserCreator):
|
||||
# Create the user node again for the user db
|
||||
private_user_node = self.create_user_node(self.user_db_name)
|
||||
|
||||
# Generate storage path for developer node using Supabase Storage
|
||||
if self.storage_tools:
|
||||
dev_dir_created, node_storage_path = self.storage_tools.create_developer_storage_path(self.user_id)
|
||||
else:
|
||||
node_storage_path = self._derive_internal_worker_path(self.worker_type)
|
||||
|
||||
developer_node = worker_nodes.DeveloperNode(
|
||||
unique_id=f"Developer_{self.user_id}",
|
||||
uuid_string=self.user_id,
|
||||
worker_name=self.worker_name,
|
||||
worker_email=self.worker_email,
|
||||
tldraw_snapshot="",
|
||||
node_storage_path=node_storage_path,
|
||||
worker_db_name=self.worker_db_name,
|
||||
worker_type=self.worker_type,
|
||||
developer_role=self.developer_role
|
||||
@@ -372,8 +484,101 @@ class NonSchoolUserCreator(UserCreator):
|
||||
neon.create_or_merge_neontology_relationship(specific_user_rel, database=self.user_db_name, operation='merge')
|
||||
logger.info("Relationship created between user and specific node")
|
||||
|
||||
def create_calendar(self, user_node: user_nodes.UserNode):
|
||||
calendar_nodes = init_calendar.create_calendar(self.user_db_name, self.calendar_start_date, self.calendar_end_date, attach_to_calendar_node=True, owner_node=user_node)
|
||||
def create_calendar(self, user_node: user_nodes.UserNode):
|
||||
calendar_nodes = init_calendar.create_calendar(self.user_db_name, self.calendar_start_date, self.calendar_end_date, attach_to_calendar_node=True, owner_node=user_node, filesystem=self.filesystem)
|
||||
|
||||
logger.info(f"Calendar nodes created.")
|
||||
return calendar_nodes
|
||||
|
||||
|
||||
def _default_date_range():
|
||||
today = datetime.now().date()
|
||||
return today, (datetime.now() + timedelta(days=365)).date()
|
||||
|
||||
|
||||
def create_user(
|
||||
*,
|
||||
user_id: str,
|
||||
user_type: str,
|
||||
username: str,
|
||||
user_email: str,
|
||||
user_name: Optional[str] = None,
|
||||
worker_name: Optional[str] = None,
|
||||
worker_type: Optional[str] = None,
|
||||
worker_email: Optional[str] = None,
|
||||
cc_users_db_name: str = "cc.users",
|
||||
user_db_name: Optional[str] = None,
|
||||
worker_db_name: Optional[str] = None,
|
||||
calendar_start_date: Optional[datetime.date] = None,
|
||||
calendar_end_date: Optional[datetime.date] = None,
|
||||
school_node: Optional[Any] = None,
|
||||
storage_tools=None,
|
||||
) -> Dict[str, Optional[Any]]:
|
||||
"""Create a user graph structure in Neo4j.
|
||||
|
||||
Args:
|
||||
user_id: Identifier used as UUID for graph nodes.
|
||||
user_type: Application-level user type (e.g. email_teacher, developer).
|
||||
username: Canonical username/slug.
|
||||
user_email: Contact email for the user node.
|
||||
user_name: Friendly display name (defaults to username).
|
||||
worker_name: Friendly name for worker node (defaults to user_name).
|
||||
worker_type: Worker role (teacher, student, developer, etc.).
|
||||
worker_email: Email for worker node (defaults to user_email).
|
||||
cc_users_db_name: Root namespace for user databases (defaults to cc.users).
|
||||
user_db_name: Fully-qualified target database for the user graph.
|
||||
worker_db_name: Database for worker entities (usually school private DB).
|
||||
calendar_start_date/calendar_end_date: Date range for initial calendar seeding.
|
||||
school_node: Optional school context; if provided a SchoolUserCreator is used.
|
||||
storage_tools: Optional Supabase storage tools for generating storage paths.
|
||||
|
||||
Returns:
|
||||
Dict describing created nodes keyed by semantic role.
|
||||
"""
|
||||
|
||||
start_date, end_date = calendar_start_date, calendar_end_date
|
||||
if not start_date or not end_date:
|
||||
start_date, end_date = _default_date_range()
|
||||
|
||||
worker_email = worker_email or user_email
|
||||
user_name = user_name or username
|
||||
worker_name = worker_name or user_name
|
||||
|
||||
if school_node is not None:
|
||||
creator = SchoolUserCreator(
|
||||
user_id=user_id,
|
||||
cc_users_db_name=cc_users_db_name,
|
||||
user_type=user_type,
|
||||
worker_type=worker_type or "teacher",
|
||||
user_email=user_email,
|
||||
worker_email=worker_email,
|
||||
cc_username=username,
|
||||
user_name=user_name,
|
||||
worker_name=worker_name,
|
||||
calendar_start_date=start_date,
|
||||
calendar_end_date=end_date,
|
||||
school_node=school_node,
|
||||
worker_node=None,
|
||||
storage_tools=storage_tools,
|
||||
user_db_name=user_db_name,
|
||||
worker_db_name=worker_db_name,
|
||||
)
|
||||
else:
|
||||
creator = NonSchoolUserCreator(
|
||||
user_id=user_id,
|
||||
cc_users_db_name=cc_users_db_name,
|
||||
user_type=user_type,
|
||||
worker_type=worker_type or user_type,
|
||||
user_email=user_email,
|
||||
worker_email=worker_email,
|
||||
cc_username=username,
|
||||
user_name=user_name,
|
||||
worker_name=worker_name,
|
||||
calendar_start_date=start_date,
|
||||
calendar_end_date=end_date,
|
||||
storage_tools=storage_tools,
|
||||
user_db_name=user_db_name,
|
||||
worker_db_name=worker_db_name,
|
||||
)
|
||||
|
||||
return creator.create_user()
|
||||
|
||||
Reference in New Issue
Block a user