Source code for djpro.commands.project

# This file is part of djpro.
#
# Copyright (c) 2024, Franco Gidaszewski <gidaszewskifranco@gmail.com>
#
# For the full copyright and license information, please view
# the LICENSE.txt file that was distributed with this source code.

from pathlib import Path

from ..utils.logging import logging, log_with_color, Fore
from ..utils.messages import run_dev, run_prod
from ..utils.django_utils import generate_secret_key
from ..utils.write_and_config import (
    create_dirs,
    create_files,
    write_to_file,
    configure_requirements,
    configure_settings_base,
)
from ..utils.files_content import (
    settings_content,
    settings_dev_content,
    settings_prod_content,
    wsgi_content,
    asgi_content,
    urls_content,
    env_dev_content,
    requirements_content,
    gitignore_content,
    views_auth_content,
    urls_auth_content,
    manage_content,
    dockerfile_content,
    dockercompose_content,
    env_prod_content,
    env_prod_db_content,
    urls_api_content,
)


[docs]def create_project( base_dir: Path, project_name: str, api: bool = False, docker: bool = False, unfold: bool = False, ): """Function to create directories and files""" base_dir_path = Path(base_dir) if base_dir_path.exists(): raise FileExistsError( log_with_color( logging.INFO, "\nError: a project already exists in the current path.", Fore.YELLOW, ) ) # Directories directories = [ base_dir_path / "bin", base_dir_path / "config", base_dir_path / "static", base_dir_path / "modules", base_dir_path / "modules" / "authentication", base_dir_path / "modules" / "authentication" / "models", base_dir_path / "modules" / "authentication" / "views", base_dir_path / "modules" / "authentication" / "serializers", base_dir_path / "utils", base_dir_path / "tests", base_dir_path / "templates", ] # Files project_files = [ base_dir_path / "bin" / "__init__.py", base_dir_path / "bin" / "manage.py", base_dir_path / "config" / "__init__.py", base_dir_path / "config" / "settings.py", base_dir_path / "config" / "settings_base.py", base_dir_path / "config" / "settings_prod.py", base_dir_path / "config" / "settings_dev.py", base_dir_path / "config" / "asgi.py", base_dir_path / "config" / "wsgi.py", base_dir_path / "config" / "urls.py", base_dir_path / "config" / ".env.conf", base_dir_path / "modules" / "__init__.py", base_dir_path / "modules" / "authentication" / "__init__.py", base_dir_path / "modules" / "authentication" / "serializers" / "__init__.py", base_dir_path / "modules" / "authentication" / "serializers" / "login_serializer.py", base_dir_path / "modules" / "authentication" / "models" / "__init__.py", base_dir_path / "modules" / "authentication" / "models" / "auth_model.py", base_dir_path / "modules" / "authentication" / "views" / "__init__.py", base_dir_path / "modules" / "authentication" / "views" / "login.py", base_dir_path / "modules" / "authentication" / "urls.py", base_dir_path / "utils" / "__init__.py", base_dir_path / "tests" / "__init__.py", ] root_files = [ Path(".env.dev"), Path(".gitignore"), Path("requirements.txt"), ] if docker: log_with_color( logging.INFO, "\nConfiguring Docker...", Fore.WHITE, delay=2, ) docker_files = [ Path(".env.prod"), Path(".env.prod.db"), Path("Dockerfile"), Path("docker-compose.yml"), ] for file in docker_files: root_files.append(file) if api: log_with_color( logging.INFO, "\nConfiguring Django Rest Framework...", Fore.WHITE, delay=1, ) api_dir = [ base_dir_path / "modules" / "api", base_dir_path / "modules" / "api" / "models", base_dir_path / "modules" / "api" / "views", base_dir_path / "modules" / "api" / "serializers", ] for dir in api_dir: directories.append(dir) # Include API dirs api_files = [ base_dir_path / "modules" / "api" / "__init__.py", base_dir_path / "modules" / "api" / "serializers" / "__init__.py", base_dir_path / "modules" / "api" / "serializers" / "get_product.py", base_dir_path / "modules" / "api" / "models" / "__init__.py", base_dir_path / "modules" / "api" / "models" / "product_model.py", base_dir_path / "modules" / "api" / "views" / "__init__.py", base_dir_path / "modules" / "api" / "views" / "get_product.py", base_dir_path / "modules" / "api" / "urls.py", ] for file in api_files: project_files.append(file) log_with_color(logging.INFO, "Creating directories...", Fore.BLUE) create_dirs(directories) # Create dirs log_with_color(logging.INFO, "Almost ready...", Fore.YELLOW, delay=3) create_files(project_files + root_files) # Create files write(base_dir, project_name, api, docker, unfold) # Write files
[docs]def write( base_dir: Path, project_name: str, api: bool = False, docker: bool = False, unfold: bool = False, ): """Function to write the content in each file of the project.""" log_with_color(logging.INFO, "Configuring files...", Fore.YELLOW, delay=3) base_dir_path = Path(base_dir) config_dir = base_dir_path / "config" bin_dir = base_dir_path / "bin" auth_module_dir = base_dir_path / "modules" / "authentication" files_to_write = [ ( config_dir / ".env.conf", "DJANGO_ENV=dev", ), # Development environment by default ( config_dir / "settings.py", settings_content.format(project_name=project_name), ), (config_dir / "settings_dev.py", settings_dev_content), (config_dir / "settings_prod.py", settings_prod_content), (config_dir / "wsgi.py", wsgi_content.format(project_name=project_name)), (config_dir / "asgi.py", asgi_content.format(project_name=project_name)), (config_dir / "urls.py", urls_content.format(project_name=project_name)), (bin_dir / "manage.py", manage_content), (auth_module_dir / "views" / "login.py", views_auth_content), (auth_module_dir / "urls.py", urls_auth_content), (Path("requirements.txt"), requirements_content), (Path(".gitignore"), gitignore_content), (Path(".env.dev"), env_dev_content.format(secret_key=generate_secret_key())), ] if api: files_to_write[6] = ( config_dir / "urls.py", urls_api_content.format(project_name=project_name), ) if docker: # Set production environment files_to_write[0] = ( config_dir / ".env.conf", "DJANGO_ENV=prod", ) docker_files = [ ( Path(".env.prod"), env_prod_content.format(secret_key=generate_secret_key()), ), (Path(".env.prod.db"), env_prod_db_content), (Path("Dockerfile"), dockerfile_content), (Path("docker-compose.yml"), dockercompose_content), ] for file in docker_files: files_to_write.append(file) for file_path, content in files_to_write: write_to_file(file_path, content) # settings_base.py settings_base_content = configure_settings_base(api, unfold) write_to_file(config_dir / "settings_base.py", settings_base_content) # sub-commands requirements.txt additional_requirements = configure_requirements(api, unfold) if additional_requirements: write_to_file(Path("requirements.txt"), additional_requirements, mode="a")
[docs]def run(args): """Entry point for command 'project'.""" try: create_project( base_dir=args.base_dir, project_name=args.project_name, api=args.api, docker=args.docker, unfold=args.unfold, ) log_with_color(logging.INFO, "---- Project created successfully.", Fore.GREEN) log_with_color( logging.INFO, "\nIMPORTANT:\n", Fore.YELLOW, ) # Messages if args.docker: run_prod.run_prod_messages() else: run_dev.run_dev_messages() except Exception as e: error_message = "\nError while creating project" if f"{e}" != "None": error_message += f": {e}" log_with_color( logging.INFO, error_message, Fore.RED, )