import tempfile from io import BytesIO from datetime import datetime import pandas as pd from django.core.files.base import ContentFile from django.core.files.base import File as DjangoFile from centralisedFileSystem.models import File, ScreenPlay, Script from centralisedFileSystem.serializers import (FileSerializer, ScreenPlayScriptSerializer, ScriptSerializer, ScreenPlaySerializer) from rest_framework.serializers import ReturnDict, ValidationError # from scriptpage.serializers import ScriptRelatedDataSerializer from utils import utilities def new_version(screenplay_name : str, user, file, file_type : str, language : str, raise_exception : bool = False) -> ReturnDict: """ Use this function for creatinng a new version. This creates a script in the existing Screenplay object. Args: screenplay_name (str): name of the screenplay you want to add another script user : user file : File object file_type (str): Type of file you want to upload language (str): language of the script you are uploading Returns: ReturnDict: the Serialised dictionary of the ner script. """ screenplay = ScreenPlay.objects.get(name=screenplay_name, user=user) data = { "screenplay": screenplay.id, "file": { "file": file, "type": file_type, }, "language": language, "user" : user } serializer = ScriptSerializer(data=data) # serializer.context["request"].user = user if serializer.is_valid(raise_exception): serializer.save() return serializer.data return serializer.errors def new_screenplay(user, author : str, name : str, file, file_type : str, language : str, raise_exception : bool = False) -> ReturnDict: """ This function creates a new screenplay and a script inside it with a file. Args: user : user author (str): name of the author of screenplay name (str): name of the screenplay file : file object file_type (str): Type of file you are uploading language (str): language of the script you are uploading raise_exception (bool): default = False To raise exception on invalid data or to return error dictionary. Returns: ReturnDict: A serialised dicionary of the new screenplay, script and the file created. """ print("test00", user) data = { "author": author, "name": name, "script": { "file": { "file": file, "type": file_type, }, "language": language, }, } serializer = ScreenPlayScriptSerializer(data=data) serializer.user = user # raise_exception has been removed here if serializer.is_valid(raise_exception=True): serializer.save(user=user) return serializer.data return serializer.errors def update_file(script_id : str, file_type : str, file) -> ReturnDict: """ This function is used for updating the existing file_type. Args: script_id (str): Id of Script file_type (str): Type of file you want to update file : The file object which will be replacing the existing file object. Returns: ReturnDict: Serialised dectionary. """ req_file = File.objects.get(script=script_id, type=file_type) req_file.file = file req_file.save() return FileSerializer(req_file).data def get_file(script_id : str, file_type : str, *args, **kwargs): """ Returns the file object of the given file type in the Script. Args: script_id (str): Id of the Script file_type (str): Type of File you want Returns: file object: The file object which `open` returns. """ file = File.objects.get( script__id = script_id, type = file_type, ).file return file def get_file_path(script_id : str, file_type : str) -> str: """ Retuens the absolute path of the file path from script_id anf file_type. Args: script_id (str): Id of Script file_type (str): The type of file of which you want the path Returns: str: Path of the desired file. """ return get_file(script_id, file_type).path def create_script_docx(script_id : str, *args, **kwargs): """ Creates the docx file from the audited script-csv and saves it in the CFS Args: script_id (str): Id of the Script Returns: file object: The file object which `open` returns. """ print("apple 102.1 creating docx") df = pd.read_csv( get_file(script_id, "script-csv") ) docx = utilities.csv_to_docx(df) temp_file_stream = BytesIO() docx.save(temp_file_stream) temp_file_stream.seek(0) docx_file = ContentFile( temp_file_stream.getvalue(), "from_audited_csv_to_document.docx", ) new_file, _ = File.objects.update_or_create( script = Script.objects.get(id=script_id), type = "script-docx", defaults = { "file" : docx_file, } ) temp_file_stream.close() print("apple 102.2 docx created") return new_file.file def create_script_pdf(script_id : str, *args, **kwargs): """ Creates the pdf file from the audited script-csv and saves it in the CFS Args: script_id (str): Id of the Script Returns: file object: The file object which `open` returns. """ try: docx_file = get_file(script_id, "script-docx") except File.DoesNotExist: docx_file = create_script_docx(script_id) temp_dir = tempfile.TemporaryDirectory() pdf_file_path = utilities.docx_to_pdf(docx_file.path, temp_dir.name) with open(pdf_file_path, "rb") as temp_pdf: pdf_file = DjangoFile( temp_pdf, pdf_file_path.rsplit('/',1)[1], ) new_file, _ = File.objects.update_or_create( script = Script.objects.get(id=script_id), type = "script-pdf", defaults = { "file" : pdf_file, } ) return new_file.file VALID_SCRIPT_TYPES = ("script-docx", "script-csv", "script-pdf") def get_script(script_id : str, script_type : str, create : bool = False, *args, **kwargs): """ This function is for getting scripts with the script id. If a script_type is not present, create flag can be set to true so that the file is created and then returned. Args: script_id (str): Id of the script script_type (str): script type (valid types : docx, csv, pdf) create (bool): Default is Flag, This flag indicates weather to create a file in case of absence. """ if script_type not in VALID_SCRIPT_TYPES: raise ValueError(f"{script_type} is not a valid type. Valid types : {VALID_SCRIPT_TYPES}.") try: print("apple trying") return get_file(script_id, script_type, *args, **kwargs) # except File.DoesNotExist as exp: except Exception as exp: print("apple exception") if not create: raise File.DoesNotExist(f"{script_type} does not exist. If you want to create and then return one, make sure create flag is set True. If you are looking for the audited script, why not use script-csv?") from exp elif script_type == "script-docx": print("apple 101") return create_script_docx(script_id, *args, **kwargs) elif script_type == "script-pdf": return create_script_pdf(script_id, *args, **kwargs) def get_script_data(script_id : str) -> ReturnDict: """ Returns all the data of script and its related models. Args: script_id (str): Id of the Script Returns: ReturnDict: Dictionary of data. """ scriptqueryobject = Script.objects.get( id = script_id, ) screenplay = ScreenPlaySerializer(scriptqueryobject.screenplay) script_related = ScriptRelatedDataSerializer(scriptqueryobject) data = screenplay.data data["script"] = script_related.data return data def new_screenplay_without_audit_in_background(user, author : str, name : str, file, file_type : str, language : str, raise_exception : bool = False) -> ReturnDict: """ This function creates a new screenplay and a script inside it with a file. Args: user : user author (str): name of the author of screenplay name (str): name of the screenplay file : file object file_type (str): Type of file you are uploading language (str): language of the script you are uploading raise_exception (bool): default = False To raise exception on invalid data or to return error dictionary. Returns: ReturnDict: A serialised dicionary of the new screenplay, script and the file created. """ print("test00", user) print("heheh",file) data = { "author": author, "name": name, "script": { "file": { "file": file, "type": file_type, "skip_post_save" : True , }, "language": language, }, } print("DATA : ",data) serializer = ScreenPlayScriptSerializer(data=data) serializer.user = user # raise_exception has been removed here if serializer.is_valid(raise_exception=True): serializer.save(user=user) return serializer.data return serializer.errors