Skip to content

Commit 429eb88

Browse files
authored
zip-wheel-explorer
Created first version using a Claude 3.5 Haiku prompt similar to this: > web app with an input box to paste in a URL to a zip or .tar.gz or wheel file - it then uses fetch() to fetch that binary file and uses the necessary JavaScript libraries to unzip it and then shows a list of the files in that package, clicking each of those shows the content of that file But had to edit a lot - to use jsdelivr for example, and to remove the .tar.gz support which didn't work.
1 parent 7fbc86c commit 429eb88

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

zip-wheel-explorer.html

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Package File Browser</title>
5+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6+
<style>
7+
body {
8+
font-family: Helvetica, Arial, sans-serif;
9+
font-size: 16px;
10+
margin: 2rem;
11+
max-width: 800px;
12+
margin: 0 auto;
13+
}
14+
input, textarea {
15+
font-size: 16px;
16+
width: 100%;
17+
margin-bottom: 1rem;
18+
padding: 0.5rem;
19+
box-sizing: border-box;
20+
}
21+
#fileList, #fileContent {
22+
border: 1px solid #ddd;
23+
padding: 1rem;
24+
margin-top: 1rem;
25+
}
26+
pre {
27+
white-space: pre-wrap;
28+
word-wrap: break-word;
29+
background-color: #f4f4f4;
30+
padding: 1rem;
31+
max-height: 400px;
32+
overflow-y: auto;
33+
}
34+
</style>
35+
</head>
36+
<body>
37+
<h1>Package File Browser</h1>
38+
<input type="text" id="urlInput" placeholder="Paste URL to .zip, .tar.gz, or .whl file">
39+
<button onclick="fetchAndUnpackFile()">Unpack File</button>
40+
<p>Try a wheel from PyPI like: <code>https://files.pythonhosted.org/packages/ae/8f/e0661dd3077b7343419ddb5ff840f6bcf571e8d11d8acb031e1b167de79c/llm_mistral-0.8-py3-none-any.whl</code> (<a href="#" onclick="document.getElementById('urlInput').value='https://files.pythonhosted.org/packages/ae/8f/e0661dd3077b7343419ddb5ff840f6bcf571e8d11d8acb031e1b167de79c/llm_mistral-0.8-py3-none-any.whl'; fetchAndUnpackFile(); return false">try it</a>)</p>
41+
<div id="fileList" style="display: none"></div>
42+
<div id="fileContent" style="display: none"></div>
43+
44+
<script src="https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js"></script>
45+
<script>
46+
async function fetchAndUnpackFile() {
47+
const url = document.getElementById('urlInput').value;
48+
const fileListEl = document.getElementById('fileList');
49+
const fileContentEl = document.getElementById('fileContent');
50+
51+
fileListEl.innerHTML = 'Downloading file...';
52+
fileContentEl.innerHTML = '';
53+
54+
try {
55+
const response = await fetch(url);
56+
const arrayBuffer = await response.arrayBuffer();
57+
const files = await extractFiles(arrayBuffer, url);
58+
fileListEl.style.display = 'block';
59+
fileListEl.innerHTML = '<h3>Files in package:</h3>';
60+
files.forEach((file, index) => {
61+
const fileEl = document.createElement('div');
62+
fileEl.textContent = file.name;
63+
fileEl.style.cursor = 'pointer';
64+
fileEl.onclick = () => {
65+
fileContentEl.style.display = 'block';
66+
fileContentEl.innerHTML = `<h3>${file.name}</h3><pre>${file.content}</pre>`;
67+
};
68+
fileListEl.appendChild(fileEl);
69+
});
70+
} catch (error) {
71+
fileListEl.innerHTML = `Error: ${error.message}`;
72+
console.error(error);
73+
}
74+
}
75+
76+
async function extractFiles(arrayBuffer, url) {
77+
const files = [];
78+
79+
if (url.endsWith('.zip')) {
80+
const zip = await JSZip.loadAsync(arrayBuffer);
81+
for (const [name, file] of Object.entries(zip.files)) {
82+
const content = await file.async('text');
83+
files.push({ name, content });
84+
}
85+
} else if (url.endsWith('.tar.gz')) {
86+
alert('tar not supported yet');
87+
} else if (url.endsWith('.whl')) {
88+
// Wheel files are zip files with a specific structure
89+
const zip = await JSZip.loadAsync(arrayBuffer);
90+
for (const [name, file] of Object.entries(zip.files)) {
91+
const content = await file.async('text');
92+
files.push({ name, content });
93+
}
94+
} else {
95+
throw new Error('Unsupported file type');
96+
}
97+
98+
return files;
99+
}
100+
</script>
101+
</body>
102+
</html>

0 commit comments

Comments
 (0)