packages = ["pandas", "pillow"]
[[fetch]]
from = "/scripts/python/"
files = ["custom_fetch.py", "config.py"]
# Imports
import asyncio
# import quopri
import os
import subprocess
import sys
#image handler
from pyodide.http import open_url
from pyodide.ffi import create_proxy, to_js
from js import document, console, alert, Object, FileReader, encodeURIComponent, processHTML
import base64
from pathlib import Path
#custom scripts
from config import set_config, get_config
from custom_fetch import get_fetch
# Global Constants & Variables
TEMP_FILE = []
CONFIG = get_config()
fileTypes = [
'text/html',
'message/rfc822'
]
uploadInput = document.getElementById('upload')
processButton = document.getElementById('process')
downloadButton = document.getElementById('download')
contentEl = document.getElementById('content')
outputEl = document.getElementById('output')
outputCodeEl = document.getElementById('output-code')
#Testing set config
#set_config("test", "test")
# Functions
def read_complete(e):
loadedFile = uploadInput.files.item(0)
codeStr = e.target.result.encode().decode()
outputEl.srcdoc = outputCodeEl.innerText = codeStr
TEMP_FILE.append({
'name': loadedFile.name.rsplit('.', 1)[0],
'type': loadedFile.type,
'data': codeStr
})
processButton.disabled = False
downloadButton.disabled = True
contentEl.classList.remove('hidden')
if len(contentEl.classList) == 0:
contentEl.removeAttribute('class')
async def read_file(e):
fileList = uploadInput.files
for f in fileList:
if fileTypes.count(f.type) > 0:
reader = FileReader.new()
onLoadEvent = create_proxy(read_complete)
reader.onload = onLoadEvent
reader.readAsText(f)
return
async def process_file(e):
if len(TEMP_FILE) > 0:
latestFile = TEMP_FILE[len(TEMP_FILE) - 1]
viewModeEl = contentEl.querySelector('#view-mode')
viewMode = viewModeEl.dataset.viewMode
if latestFile['type'] == 'text/html':
updatedHTML = await processHTML(
latestFile['data'],
to_js(get_config())
)
latestFile['data'] = outputEl.srcdoc = outputCodeEl.innerText = updatedHTML.data
uploadInput.value = ''
processButton.disabled = True
if updatedHTML.status == 'error' and viewMode == 'code':
viewMode = 'design'
viewModeEl.innerHTML = 'View Code'
outputEl.classList.remove('hidden')
outputCodeEl.classList.add('hidden')
if len(outputEl.classList) == 0:
outputEl.removeAttribute('class')
else:
downloadButton.disabled = False
return
return alert(f'Please upload one of the following file types: {", ".join(fileTypes)}')
def download_file(e):
if len(TEMP_FILE) > 0:
outputFile = TEMP_FILE[len(TEMP_FILE) - 1]
uri = f'data:{outputFile["type"]};charset=utf-8,{encodeURIComponent(outputFile["data"])}'
tag = document.createElement('a')
tag.href = uri
tag.download = f'{outputFile["name"]} copy'
tag.style.display = 'none'
document.body.appendChild(tag)
tag.click()
document.body.removeChild(tag)
def clear_file(e):
e.preventDefault()
if len(TEMP_FILE) > 0:
TEMP_FILE.clear()
uploadInput.value = outputEl.srcdoc = ''
processButton.disabled = downloadButton.disabled = True
contentEl.classList.add('hidden')
def change_view(e):
e.preventDefault()
elData = e.target.dataset
fileData = TEMP_FILE[len(TEMP_FILE) - 1]['data']
if elData.viewMode == 'design':
elData.viewMode = 'code'
e.target.innerHTML = 'View Design'
outputCodeEl.classList.remove('hidden')
outputEl.classList.add('hidden')
if len(outputCodeEl.classList) == 0:
outputCodeEl.removeAttribute('class')
else:
elData.viewMode = 'design'
e.target.innerHTML = 'View Code'
outputEl.classList.remove('hidden')
outputCodeEl.classList.add('hidden')
if len(outputEl.classList) == 0:
outputEl.removeAttribute('class')
console.log(e.target.dataset.viewMode)
#calls get_fetch(url, type)
async def fetch_req(url):
response = await get_fetch(url)
return response
async def main():
#task = await fetch_req("https://dummyjson.com/products/1")
fileEvent = create_proxy(read_file)
processEvent = create_proxy(process_file)
downloadEvent = create_proxy(download_file)
clearEvent = create_proxy(clear_file)
viewEvent = create_proxy(change_view)
uploadInput.accept = ','.join(fileTypes)
# Event Listeners
uploadInput.addEventListener('change', fileEvent)
processButton.addEventListener('click', processEvent)
downloadButton.addEventListener('click', downloadEvent)
contentEl.querySelector('.close').addEventListener('click', clearEvent)
contentEl.querySelector('#view-mode').addEventListener('click', viewEvent)
# Output & Misc + Guard rails to run when file is invoked directly
if __name__ == '__main__':
# Can't use run as an async queue already exists so we create another task
main_task = asyncio.create_task(main())