forked from open-webui/open-webui
		
	feat: stylised pdf
This commit is contained in:
		
							parent
							
								
									bfd066cc2f
								
							
						
					
					
						commit
						1f85354856
					
				
					 3 changed files with 78 additions and 4 deletions
				
			
		|  | @ -5,6 +5,8 @@ from starlette.responses import StreamingResponse, FileResponse | |||
| 
 | ||||
| from pydantic import BaseModel | ||||
| 
 | ||||
| 
 | ||||
| import markdown | ||||
| import requests | ||||
| import os | ||||
| import aiohttp | ||||
|  | @ -28,6 +30,17 @@ async def get_gravatar( | |||
|     return get_gravatar_url(email) | ||||
| 
 | ||||
| 
 | ||||
| class MarkdownForm(BaseModel): | ||||
|     md: str | ||||
| 
 | ||||
| 
 | ||||
| @router.post("/markdown") | ||||
| async def get_html_from_markdown( | ||||
|     form_data: MarkdownForm, | ||||
| ): | ||||
|     return {"html": markdown.markdown(form_data.md)} | ||||
| 
 | ||||
| 
 | ||||
| @router.get("/db/download") | ||||
| async def download_db(user=Depends(get_admin_user)): | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,6 +22,31 @@ export const getGravatarUrl = async (email: string) => { | |||
| 	return res; | ||||
| }; | ||||
| 
 | ||||
| export const getHTMLFromMarkdown = async (md: string) => { | ||||
| 	let error = null; | ||||
| 
 | ||||
| 	const res = await fetch(`${WEBUI_API_BASE_URL}/utils/markdown`, { | ||||
| 		method: 'POST', | ||||
| 		headers: { | ||||
| 			'Content-Type': 'application/json' | ||||
| 		}, | ||||
| 		body: JSON.stringify({ | ||||
| 			md: md | ||||
| 		}) | ||||
| 	}) | ||||
| 		.then(async (res) => { | ||||
| 			if (!res.ok) throw await res.json(); | ||||
| 			return res.json(); | ||||
| 		}) | ||||
| 		.catch((err) => { | ||||
| 			console.log(err); | ||||
| 			error = err; | ||||
| 			return null; | ||||
| 		}); | ||||
| 
 | ||||
| 	return res.html; | ||||
| }; | ||||
| 
 | ||||
| export const downloadDatabase = async (token: string) => { | ||||
| 	let error = null; | ||||
| 
 | ||||
|  |  | |||
|  | @ -46,11 +46,47 @@ | |||
| 
 | ||||
| 		const doc = new jsPDF(); | ||||
| 
 | ||||
| 		const chatText = _chat.messages.reduce((a, message, i, arr) => { | ||||
| 			return `${a}### ${message.role.toUpperCase()}\n${message.content}\n\n`; | ||||
| 		}, ''); | ||||
| 		// Initialize y-coordinate for text placement | ||||
| 		let yPos = 10; | ||||
| 		const pageHeight = doc.internal.pageSize.height; | ||||
| 
 | ||||
| 		// Function to check if new text exceeds the current page height | ||||
| 		function checkAndAddNewPage() { | ||||
| 			if (yPos > pageHeight - 10) { | ||||
| 				doc.addPage(); | ||||
| 				yPos = 10; // Reset yPos for the new page | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// Function to add text with specific style | ||||
| 		function addStyledText(text, isTitle = false) { | ||||
| 			// Set font style and size based on the parameters | ||||
| 			doc.setFont('helvetica', isTitle ? 'bold' : 'normal'); | ||||
| 			doc.setFontSize(isTitle ? 12 : 10); | ||||
| 
 | ||||
| 			const textMargin = 7; | ||||
| 
 | ||||
| 			// Split text into lines to ensure it fits within the page width | ||||
| 			const lines = doc.splitTextToSize(text, 180); // Adjust the width as needed | ||||
| 
 | ||||
| 			lines.forEach((line) => { | ||||
| 				checkAndAddNewPage(); // Check if we need a new page before adding more text | ||||
| 				doc.text(line, 10, yPos); | ||||
| 				yPos += textMargin; // Increment yPos for the next line | ||||
| 			}); | ||||
| 
 | ||||
| 			// Add extra space after a block of text | ||||
| 			yPos += 2; | ||||
| 		} | ||||
| 
 | ||||
| 		_chat.messages.forEach((message, i) => { | ||||
| 			// Add user text in bold | ||||
| 			doc.setFont('helvetica', 'normal', 'bold'); | ||||
| 
 | ||||
| 			addStyledText(message.role.toUpperCase(), { isTitle: true }); | ||||
| 			addStyledText(message.content); | ||||
| 		}); | ||||
| 
 | ||||
| 		doc.text(chatText, 10, 10); | ||||
| 		doc.save(`chat-${_chat.title}.pdf`); | ||||
| 	}; | ||||
| </script> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy J. Baek
						Timothy J. Baek