File size: 9,150 Bytes
9f2d44c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
import gradio as gr
import requests
import os
from dotenv import load_dotenv
import tempfile

# Load environment variables
load_dotenv()

def get_sample_cv():
    """
    Return the sample CV markdown content for reference
    """
    try:
        with open('Sample.md', 'r', encoding='utf-8') as f:
            return f.read()
    except FileNotFoundError:
        return "Sample.md file not found in the current directory."
    except Exception as e:
        return f"Error reading Sample.md: {str(e)}"

def get_cv_formatting_instructions():
    """
    Return detailed CV formatting instructions from external markdown file
    """
    try:
        with open('Instructions.md', 'r', encoding='utf-8') as f:
            return f.read()
    except FileNotFoundError:
        return "Instructions.md file not found in the current directory."
    except Exception as e:
        return f"Error reading Instructions.md: {str(e)}"

def convert_markdown_to_pdf(markdown_text):
    """
    Convert markdown text to PDF and HTML using the external API endpoints
    
    Args:
        markdown_text (str): The markdown text to convert
        
    Returns:
        tuple: (pdf_path, html_content, status_message)
    """
    if not markdown_text.strip():
        return None, "", "Please enter some markdown text."
    
    # Get bearer token from environment
    bearer_token = os.getenv('BEARER_TOKEN')
    if not bearer_token or bearer_token == 'your_bearer_token_here':
        return None, "", "❌ Bearer token not configured. Please set BEARER_TOKEN in .env file."
    
    try:
        headers = {
            'Authorization': f'Bearer {bearer_token}',
            'Content-Type': 'text/markdown'
        }
        
        # Get base URL from environment
        base_url = os.getenv('API_BASE_URL', 'https://nirav-madhani-resume-server.hf.space')
        
        # Get PDF directly from API
        pdf_url = f"{base_url}/convert/pdf"
        print(f"📡 Making request to {pdf_url}")
        pdf_response = requests.post(pdf_url, data=markdown_text, headers=headers, timeout=30)
        
        if pdf_response.status_code != 200:
            return None, "", f"❌ PDF API request failed with status {pdf_response.status_code}: {pdf_response.text}"
        
        # Save PDF to temporary file
        with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf', mode='w+b') as temp_pdf:
            temp_pdf.write(pdf_response.content)
            pdf_path = temp_pdf.name
        
        # Get HTML for preview
        html_url = f"{base_url}/convert/html"
        print(f"📡 Making request to {html_url}")
        html_response = requests.post(html_url, data=markdown_text, headers=headers, timeout=30)
        
        if html_response.status_code != 200:
            # PDF worked but HTML failed - still return PDF
            return pdf_path, "", f"✅ PDF generated successfully! (HTML preview failed: {html_response.status_code})"
        
        html_content = html_response.text
        return pdf_path, html_content, "✅ PDF and HTML generated successfully via API!"
            
    except requests.exceptions.RequestException as e:
        return None, "", f"❌ Network error: {str(e)}"
    except Exception as e:
        return None, "", f"❌ Error generating PDF: {str(e)}"

def process_conversion(markdown_text):
    """
    Process the markdown conversion and return results for Gradio interface
    
    Args:
        markdown_text (str): The markdown text to convert
        
    Returns:
        tuple: (pdf_file_path, html_content, status_message)
    """
    pdf_path, html_content, message = convert_markdown_to_pdf(markdown_text)
    return pdf_path, html_content, message

# MCP Tool Functions (callable by AI assistants)
def mcp_get_sample_cv():
    """MCP tool: Get sample CV markdown
    
    Returns:
        str: The sample CV markdown content
    """
    return get_sample_cv()

def mcp_get_cv_instructions():
    """MCP tool: Get CV formatting instructions
    
    Returns:
        str: The CV formatting instructions
    """
    return get_cv_formatting_instructions()

def mcp_convert_cv(markdown_text: str):
    """MCP tool: Convert CV markdown to PDF
    
    Args:
        markdown_text (str): The markdown text to convert to PDF
        
    Returns:
        str: The conversion result message
    """
    pdf_path, html_content, message = process_conversion(markdown_text)
    return f"Conversion result: {message}"

# Create Gradio interface
with gr.Blocks(title="CV Markdown to PDF Converter", theme=gr.themes.Soft()) as demo:
    gr.Markdown("# 📄 CV Markdown to PDF Converter")
    gr.Markdown("Convert your CV markdown to professional PDF format. Use the Instructions & Sample tab to learn the proper formatting.")
    
    with gr.Tabs():
        with gr.TabItem("🚀 Convert CV"):
            with gr.Row():
                with gr.Column(scale=1):
                    gr.Markdown("## Input")
                    markdown_input = gr.Textbox(
                        label="CV Markdown Text",
                        placeholder="Enter your CV markdown here... (see Instructions & Sample tab for formatting guide)",
                        lines=20,
                        max_lines=30
                    )
                
                with gr.Column(scale=1):
                    gr.Markdown("## Output")
                    
                    with gr.Tabs():
                        with gr.TabItem("📄 PDF Download"):
                            pdf_output = gr.File(
                                label="Generated PDF",
                                file_types=[".pdf"]
                            )
                        
                        with gr.TabItem("🌐 HTML Preview"):
                            html_output = gr.HTML(
                                label="HTML Preview",
                                value="HTML preview will appear here after conversion..."
                            )
                    
                    status_message = gr.Textbox(
                        label="Status",
                        interactive=False,
                        lines=2
                    )
            
            with gr.Row():
                convert_btn = gr.Button("🚀 Convert to PDF", variant="primary", size="lg")
            
            # Event handler
            convert_btn.click(
                fn=process_conversion,
                inputs=[markdown_input],
                outputs=[pdf_output, html_output, status_message]
            )
        
        with gr.TabItem("📋 Instructions & Sample"):
            with gr.Tabs():
                with gr.TabItem("📖 Formatting Instructions"):
                    gr.Markdown(get_cv_formatting_instructions())
                
                with gr.TabItem("📄 Sample CV"):
                    gr.Markdown("## Sample CV Markdown")
                    gr.Markdown("Below is a complete sample CV showing all the formatting patterns:")
                    
                    sample_cv_display = gr.Code(
                        value=get_sample_cv(),
                        language="markdown",
                        label="Sample CV Markdown Code",
                        lines=30,
                        max_lines=50
                    )
                    
                    copy_sample_btn = gr.Button("📋 Copy Sample to Converter", variant="secondary")
                    
                    # Copy sample to main input
                    copy_sample_btn.click(
                        fn=get_sample_cv,
                        outputs=[markdown_input]
                    )
    
    # Example CV templates
    with gr.Row():
        gr.Examples(
            examples=[
                [get_sample_cv()],
                ["""---
name: John Doe
header:
  - text: |
      <span style="font-size: 1.2em; font-weight: bold;">Full Stack Developer</span>
  - text: <span class="iconify" data-icon="tabler:phone"></span> (555) 987-6543
    newLine: true
  - text: <span class="iconify" data-icon="tabler:mail"></span> john.doe@email.com
    link: mailto:john.doe@email.com
---

## Experience

[L2]Tech Startup Inc.[/L2] [L2R]San Francisco, CA[/L2R]

[L3]Full Stack Developer[/L3] [L3R]Jan 2022 - Present[/L3R]

- Designed and implemented scalable web applications serving 10K+ users
- Reduced page load times by 40% through optimization techniques
- Led migration from monolith to microservices architecture

## Education

[L2]University of California[/L2] GPA 3.8 [L2R]Berkeley, CA[/L2R]
[L3]B.S. in Computer Science[/L3] [L3R]2018 - 2022[/L3R]

## Skills

**Programming:** Python, JavaScript, TypeScript, Java
<br>
**Frameworks:** React, Node.js, Django, Spring Boot
<br>
**Databases:** PostgreSQL, MongoDB, Redis
"""],
            ],
            inputs=[markdown_input],
            label="📝 CV Templates"
        )
    
    # Register MCP tools
    gr.api(mcp_get_sample_cv)
    gr.api(mcp_get_cv_instructions)
    gr.api(mcp_convert_cv)

# Launch the app with MCP enabled
if __name__ == "__main__":
    demo.launch(
        mcp_server=True
    )