o
    UQ{im/                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZ	d dl
Z
d dlZd dlZd dlmZmZmZ ejejd edZdZdZdedefd	d
Zdedeeef fddZ	d4dedededee deeef f
ddZedkrid dlZd dlZejddZej dedd ej dedd ej dedd ej deddd  ej d!ed"d e! Z"e"j#Z$e"j%Z&e"j'Z(e"j)Z*e"j+r"z?e j,-e"j+re.e"j+d#Z/e0e/Z1W d   n1 sw   Y  ne2e"j+Z1e13dZ$e13d$Z&e13d%Z(e13d&Z*W n e4y! Z5 ze6d'e5  e7d( W Y dZ5[5ndZ5[5ww e$r+e&r+e(s7e6d) d*Z$d+Z&d,Z(dZ*e6d- e6d.e$  e6d/e(  e*rSe6d0e*  ee$e&e(e*Z8e6d1 e6ej9e8d2d3 dS dS )5    N)DictAnyOptional)levelresponse_iq_analysisz#http://localhost:11434/api/generatezllama3.1:8bvoice_inputreturnc              
   C   s\  z| sW dS |  ds|  dr`tj| dd}|  d}d| dd	 v r4d| dd	 dd	  }tjd
|d}|jddD ]}|| qB|j	W  d   W S 1 sXw   Y  W dS d| v rk| dd } t
| }tjd
dd}|| |j	W  d   W S 1 sw   Y  W dS  ty } ztd|  W Y d}~dS d}~ww )zEHandles both URL and Base64 audio inputs, saving to a temporary file. zhttp://zhttps://T)streamz.mpeg./F)deletesuffixi    )
chunk_sizeN,   z.wavzFailed to process audio input: )
startswithrequestsgetraise_for_statussplittempfileNamedTemporaryFileiter_contentwritenamebase64	b64decode	Exceptionloggererror)r   responser   tmp_filechunk
audio_datae r'   D/var/www/eduai.edurigo.com/response_iq_kunal/response_iq_analysis.pydownload_or_save_audio   s4   (

(r)   	file_pathc              
   C   sZ  zt j| dd\}}t j||d\}}||t|k }t|dkr(t|nd}t|dkr5t|nd}t jj	||d}t j
j||d}	t|	dkrQ|	d nd}
t jj|dd }t|}t|}t jj||dd }t|}t jj|dd }t|}t jj|dd }t|}t jj||dd}tj|d	d
}g }|
dkr|d n|
dk r|d n|d |dkr|d n	|dk r|d ||d  dkr|d n|d |dkr|d d|t|t|t|
t|t|t|t|t|ddW S  ty, } ztd|  di dW  Y d}~S d}~ww )zX
    Extracts advanced acoustic features using librosa for improved tonal analysis.
    N)sr)yr+   r   )onset_enveloper+   )r,      )r,   r+   n_mfccr   )axis   z,Fast speaking pace (high energy or nervous).P   z,Slow speaking pace (measured or low energy).zNormal/Moderate speaking pace.<   z*High pitch variation (expressive/excited).   z'Low pitch variation (monotone/robotic).gư>g      ?zKSignificant energy fluctuations (might indicate hesitation or shaky voice).z,Stable vocal energy (suggesting confidence).g?zBreathy or noisy vocal texture. )avg_pitch_hz	pitch_std	tempo_bpm
avg_energyenergy_fluctuationavg_centroidavg_flatnessavg_zcr)summarystatszAudio analysis failed: z"Technical audio extraction failed.)librosaloadpiptracknpmedianlenmeanstdonsetonset_strengthbeattempofeaturermsspectral_centroidspectral_flatnesszero_crossing_ratemfccappendjoinfloatr   r    r!   )r*   r,   r+   pitches
magnitudespitches_masked	avg_pitchr7   	onset_envrK   	avg_temporM   r9   
energy_stdrN   r;   flatnessr<   zcrr=   rQ   
mfcc_meansdescriptionr&   r'   r'   r(   analyze_audio_features:   sZ   






r`   questionpredefined_answeruser_answeruser_voice_urlc              
   C   s  d}d }d }|r(t d t|}|r(t d t|}zt| W n   Y d}d}|r>d|d  dt|d  d	}d
|  d| d| d| d	}	t|	|ddddddd}
zft dt d t	j
t|
dd}|jdkrt dt d ddt dt d iW S |  | }|d!d}d"|v r|d"d# d$d%  }nd$|v r|d$d# d$d%  }t|}|W S  tjy   t d& d'|d( Y S  t	jy } zt d)|  dd*t| iW  Y d }~S d }~ww )+Nr	   zProcessing audio input...z%Extracting advanced audio features...a#  You are a world-class communication expert, behavioral psychologist, and tonal analyst. Your goal is to provide a deep, professional evaluation of a candidate's response. Analyze the text for semantic accuracy AND the voice for emotional nuance. Return the result ONLY in strict JSON format.z
        Voice Tonal Metadata: r>   z"
        Detailed Acoustic Stats: r?   z
        (Interpreting stats: Low pitch_std = monotone, High energy_fluctuation = shaky/hesitant, 
        High avg_flatness = breathy/unclear, Moderate tempo = confident/composed).
        zf
    Evaluate the following interview response with high precision.

    INPUT DATA:
    - Question: "z""
    - Ideal/Predefined Answer: "z"
    - User's Actual Answer: "z"
    a  
    
    REQUIRED ANALYSIS:
    1. Match Score (0-100): Quantify how well the user's answer covers the core concepts of the ideal answer. Be strict but fair.
    2. Comparison: A professional summary of why the score was given.
    3. Behavioral Analysis: Analyze the user's communication style. Are they assertive, analytical, empathetic, or vague? Check for logical flow and vocabulary choice.
    4. Tonal Analysis: 
       - If voice metadata is present: Provide a detailed breakdown of the user's delivery (confidence, pace, emotional stability). 
       - If voice metadata is NOT present: Base this on the 'tone' of the written text (formal, casual, apologetic).
    5. Visuals: Exactly 3 professional keywords summarizing the vibe (e.g., "Precise", "Authoritative", "Strategic").
    
    OUTPUT FORMAT (Strict JSON):
    {
        "matchScore": <int>,
        "comparison": "<str>",
        "behavioralAnalysis": "<str>",
        "tonalAnalysis": "<str>",
        "visuals": ["<kw1>", "<kw2>", "<kw3>"]
    }
    Fjsong?i   i   )temperaturenum_ctxnum_predict)modelpromptsystemr
   formatoptionsz&Sending request to Ollama using model z...   )re   timeouti  z
Model ID 'z' not found (404).r!   zModel 'z:' not found via Ollama. Please pull it using 'ollama pull 'r"   z```jsonr   z```r   zFailed to parse JSON from LLMzLLM returned invalid JSON)r!   raw_responsezOllama connection error: zCould not connect to LLM: )r    infor)   r`   osremovere   dumpsOLLAMA_MODELr   postOLLAMA_API_URLstatus_coder!   r   r   r   striploadsJSONDecodeErrorRequestExceptionstr)ra   rb   rc   rd   audio_analysis_textaudio_file_pathaudio_featuressystem_promptaudio_contextrj   payloadr"   resultllm_response_textparsed_jsonr&   r'   r'   r(   analyze_response   s   





r   __main__z&Run Response IQ Analysis from Terminal)r_   z
--questionzThe interview question)typehelpz--predefinedzThe correct/ideal answerz--userzThe user's answerz--voicezURL to user's voice recording)r   r   defaultz--json_inputzHJSON string with keys: question, predefinedAnswer, userAnswer, userVoicerpredefinedAnswer
userAnswer	userVoicezError parsing JSON input: r   z6No input provided. Running with DEFAULT DEMO values...zthis is the questionzthis is the predefined answerzthis is the user answerz
--- Starting Analysis ---z
Question: zUser Answer: zVoice URL: z
--- Analysis Result ---   )indent)N):rs   r   re   loggingr   r@   numpyrC   	soundfilesfr   ioretypingr   r   r   basicConfigINFO	getLoggerr    rx   rv   r~   r)   r`   r   __name__argparsesysArgumentParserparseradd_argument
parse_argsargsra   q
predefinedpauseruavoiceuv
json_inputpathisfileopenfrA   datar{   r   r   r&   printexitr   ru   r'   r'   r'   r(   <module>   s    
$N


y


