Backup-bdg's picture
Upload 964 files
51ff9e5 verified
raw
history blame
5.56 kB
"""
Utility module for generating file viewer HTML content.
"""
import base64
import mimetypes
import os
def generate_file_viewer_html(file_path: str) -> str:
"""
Generate HTML content for viewing different file types.
Args:
file_path: The absolute path to the file
Returns:
str: HTML content for viewing the file
Raises:
ValueError: If the file extension is not supported
"""
file_extension = os.path.splitext(file_path)[1].lower()
file_name = os.path.basename(file_path)
# Define supported file extensions
supported_extensions = [
'.pdf',
'.png',
'.jpg',
'.jpeg',
'.gif',
]
# Check if the file extension is supported
if file_extension not in supported_extensions:
raise ValueError(
f'Unsupported file extension: {file_extension}. '
f'Supported extensions are: {", ".join(supported_extensions)}'
)
# Check if the file exists
if not os.path.exists(file_path):
raise ValueError(
f'File not found locally: {file_path}. Please download the file to the local machine and try again.'
)
# Read file content directly
file_content = None
mime_type = mimetypes.guess_type(file_path)[0] or 'application/octet-stream'
# For binary files (images, PDFs), encode as base64
if file_extension in ['.pdf', '.png', '.jpg', '.jpeg', '.gif', '.bmp']:
with open(file_path, 'rb') as file:
file_content = base64.b64encode(file.read()).decode('utf-8')
# For text files, read as text
else:
with open(file_path, 'r', encoding='utf-8') as file:
file_content = file.read()
return f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Viewer - {file_name}</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
<style>
body, html {{ margin: 0; padding: 0; height: 100%; overflow: hidden; font-family: Arial, sans-serif; }}
#viewer-container {{ width: 100%; height: 100vh; overflow: auto; }}
.page {{ margin: 10px auto; box-shadow: 0 0 10px rgba(0,0,0,0.3); }}
.text-content {{ margin: 20px; white-space: pre-wrap; font-family: monospace; line-height: 1.5; }}
.error {{ color: red; margin: 20px; }}
img {{ max-width: 100%; margin: 20px auto; display: block; }}
</style>
</head>
<body>
<div id="viewer-container"></div>
<script>
const filePath = "{file_path}";
const fileExtension = "{file_extension}";
const fileContent = `{file_content if file_extension not in ['.pdf', '.png', '.jpg', '.jpeg', '.gif', '.bmp'] else ''}`;
const fileBase64 = "{file_content if file_extension in ['.pdf', '.png', '.jpg', '.jpeg', '.gif', '.bmp'] else ''}";
const mimeType = "{mime_type}";
const container = document.getElementById('viewer-container');
async function loadContent() {{
try {{
if (fileExtension === '.pdf') {{
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';
const binaryString = atob(fileBase64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {{
bytes[i] = binaryString.charCodeAt(i);
}}
const loadingTask = pdfjsLib.getDocument({{data: bytes.buffer}});
const pdf = await loadingTask.promise;
// Get total number of pages
const numPages = pdf.numPages;
// Render each page
for (let pageNum = 1; pageNum <= numPages; pageNum++) {{
const page = await pdf.getPage(pageNum);
// Set scale for rendering
const viewport = page.getViewport({{ scale: 1.5 }});
// Create canvas for rendering
const canvas = document.createElement('canvas');
canvas.className = 'page';
canvas.width = viewport.width;
canvas.height = viewport.height;
container.appendChild(canvas);
// Render PDF page into canvas context
const context = canvas.getContext('2d');
const renderContext = {{
canvasContext: context,
viewport: viewport
}};
await page.render(renderContext).promise;
}}
}} else if (['.png', '.jpg', '.jpeg', '.gif', '.bmp'].includes(fileExtension)) {{
const img = document.createElement('img');
img.src = `data:${{mimeType}};base64,${{fileBase64}}`;
img.alt = filePath.split('/').pop();
container.appendChild(img);
}} else {{
const pre = document.createElement('pre');
pre.className = 'text-content';
pre.textContent = fileContent;
container.appendChild(pre);
}}
}} catch (error) {{
console.error('Error:', error);
container.innerHTML = `<div class="error"><h2>Error loading file</h2><p>${{error.message}}</p></div>`;
}}
}}
window.onload = loadContent;
</script>
</body>
</html>"""