Spaces:
Running
Running
<script lang="ts"> | |
import { createEventDispatcher, tick, getContext } from "svelte"; | |
import { upload_files, upload, FileData } from "@gradio/client"; | |
import LoadingSpinner from "./loading_spinner.svelte"; | |
let uploaded_files; | |
const dispatch = createEventDispatcher(); | |
const upload_fn = getContext<typeof upload_files>("upload_files"); | |
export let root: string; | |
async function handle_upload(file_data: FileData): Promise<void> { | |
await tick(); | |
const upload_id = Math.random().toString(36).substring(2, 15); | |
uploaded_files = await upload([file_data], root, upload_id, upload_fn); | |
dispatch("load", uploaded_files[0]); | |
} | |
let loading = false; | |
async function fetchFromDB(identifier, database): Promise<void> { | |
let dbs = { | |
pdb_assym: { | |
url: "https://files.rcsb.org/view/", | |
ext: ".pdb", | |
}, | |
pdb_bioass: { | |
url: "https://files.rcsb.org/view/", | |
ext: ".pdb1", | |
}, | |
af: { | |
url: "https://alphafold.ebi.ac.uk/files/AF-", | |
ext: "-F1-model_v4.pdb", | |
}, | |
esm: { | |
url: "https://api.esmatlas.com/fetchPredictedStructure/", | |
ext: ".pdb", | |
}, | |
// pubchem: "pubchem", | |
// text: "text", | |
}; | |
let url = dbs[database]["url"]; | |
let ext = dbs[database]["ext"]; | |
// load the file and save blob | |
// emulate file upload by fetching from the db and triggering upload | |
// check if response status is 200, then return blob | |
loading = true; | |
let file = null; | |
try { | |
file = await fetch(url + identifier + ext) | |
.then((r) => { | |
loading = false; | |
if (r.status == 200) { | |
return r.blob(); | |
} else { | |
dispatch("notfound"); | |
} | |
}) | |
.then((blob) => { | |
return new File([blob], identifier + ".pdb", { type: "text/plain" }); | |
}); | |
} catch (error) { | |
loading = false; | |
dispatch("notfound"); | |
} | |
let file_data = new FileData({ | |
path: identifier + ".pdb", | |
orig_name: identifier + ".pdb", | |
blob: file, | |
size: file.size, | |
mime_type: file.type, | |
is_stream: false, | |
}); | |
await handle_upload(file_data); | |
} | |
let selectedValue = "pdb_assym"; | |
let placeholder = ""; | |
let textInput = ""; | |
function handleSelect(event) { | |
selectedValue = event.target.value; | |
} | |
let placeholders = { | |
pdb_assym: "Enter PDB identifier", | |
pdb_bioass: "Enter PDB identifier", | |
af: "Enter UniProt identifier", | |
esm: "Enter MGnify protein identifier", | |
// pubchem: "Enter PubChem identifier", | |
// text: "Enter molecule in PDB or mol2 format", | |
}; | |
$: placeholder = placeholders[selectedValue]; | |
function isEnterPressed(event) { | |
if (event.key === "Enter") { | |
fetchFromDB(textInput, selectedValue); | |
} | |
} | |
</script> | |
<div class="flex mt-2"> | |
<div class="flex input wfull"> | |
<input | |
type="text" | |
{placeholder} | |
class="wfull inp" | |
bind:value={textInput} | |
on:keydown={isEnterPressed} | |
/> | |
<select name="" id="" class="select" on:change={handleSelect}> | |
<option value="pdb_assym">PDB Assym. Unit</option> | |
<option value="pdb_bioass">PDB BioAssembly</option> | |
<option value="af">AlphaFold DB</option> | |
<option value="esm">ESMFold DB</option> | |
<!-- <option value="pubchem">Pubchem</option> | |
<option value="text">Text input</option> --> | |
</select> | |
</div> | |
<button | |
class="btn text-center" | |
on:click={() => fetchFromDB(textInput, selectedValue)} | |
> | |
{#if loading} | |
<LoadingSpinner /> | |
{:else} | |
<span>Fetch</span> | |
{/if} | |
</button> | |
</div> | |
<span class="or py">- or -</span> | |
<style> | |
.py { | |
padding: 10px 0; | |
} | |
.btn { | |
margin: 0 5px; | |
padding: 3px 15px; | |
border: var(--button-border-width) solid | |
var(--button-secondary-border-color); | |
background: var(--button-secondary-background-fill); | |
color: var(--button-secondary-text-color); | |
border-radius: var(--button-large-radius); | |
padding: var(--button-large-padding); | |
font-weight: var(--button-large-text-weight); | |
font-size: var(--button-large-text-size); | |
cursor: pointer; | |
} | |
.btn:hover { | |
border-color: var(--button-secondary-border-color-hover); | |
background: var(--button-secondary-background-fill-hover); | |
color: var(--button-secondary-text-color-hover); | |
box-shadow: var(--button-shadow-hover); | |
} | |
.or { | |
color: var(--body-text-color-subdued); | |
text-align: center; | |
display: block; | |
} | |
.wfull { | |
width: 100%; | |
} | |
.mt-2 { | |
margin-top: 2rem; | |
} | |
.input { | |
box-shadow: var(--input-shadow); | |
background: var(--input-background-fill); | |
border: var(--input-border-width) solid var(--input-border-color); | |
border-radius: var(--input-radius); | |
margin: 0 5px; | |
} | |
.select { | |
outline: none; | |
border: none; | |
} | |
.flex { | |
display: flex; | |
justify-content: space-between; | |
} | |
.inp { | |
width: 100%; | |
border: 0 #fff ; | |
outline: none ; | |
} | |
.inp:focus, | |
.inp:hover { | |
border: 0 ; | |
outline: none ; | |
} | |
.text-center { | |
text-align: center; | |
} | |
</style> | |