add file stuff

This commit is contained in:
HRG @ SCExC 2024-06-03 20:19:26 -04:00
parent c33a49e817
commit 7aac7aabdd
5 changed files with 195 additions and 26 deletions

View file

@ -311,6 +311,28 @@ function createDb(db, structId, name) {
return transaction(); return transaction();
} }
function getFilesForStruct(db, structureId) {
let test = db
.prepare("SELECT * FROM files WHERE structure_id = ? ORDER BY id DESC")
.all(structureId);
console.log(db.prepare("PRAGMA table_info(files)").all());
return test;
}
function getFile(db, fileId) {
return db.prepare("SELECT * FROM files WHERE id = ?").get(fileId);
}
function createFile(db, structure_id, name, filePath, mime_type, mime_subtype) {
return db
.prepare(
"INSERT INTO files (structure_id, name, path, mime_type, mime_subtype) VALUES (?, ?, ?, ?, ?)"
)
.run(structure_id, name, filePath, mime_type, mime_subtype).lastInsertRowid;
}
const { LRUCache } = require("lru-cache"); const { LRUCache } = require("lru-cache");
const templateCache = new LRUCache({ max: 100 }); const templateCache = new LRUCache({ max: 100 });
@ -586,8 +608,68 @@ app.get("/workshop/:structure_id/route/:id", (req, res) => {
); );
}); });
app.get("/workshop/tip", (req, res) => { // POST route to handle file upload
res.send("try entering something in the url field above"); app.post("/workshop/:structure_id/files", (req, res) => {
if (!req.files || Object.keys(req.files).length === 0) {
return res.status(400).send("failed to upload that file");
}
const { structure_id } = req.params;
const file = req.files.file;
const name = file.name;
const [mime_type, mime_subtype] = file.mimetype.split("/");
const uploadPath = path.join(__dirname, "public", structure_id);
const storedPath = path.join(structure_id, file.name);
fs.mkdirSync(uploadPath, { recursive: true });
file.mv(path.join(uploadPath, name), (err) => {
try {
if (err) {
return res.status(500).send(err);
}
let id = createFile(
db,
structure_id,
name,
storedPath,
mime_type,
mime_subtype
);
let file = getFile(db, id);
file.url = prefixUrlWithHost(req, file.path);
return res.send(eta.render("workshop/file_detail", { file: file }));
} catch (e) {
res.status(500);
return res.send(e);
}
});
});
function prefixUrlWithHost(req, path) {
return req.protocol + "://" + req.get("host") + "/" + path;
}
// POST route to handle file upload
app.get("/workshop/:structure_id/files", (req, res) => {
const { structure_id } = req.params;
const files = getFilesForStruct(db, structure_id);
files.map((it) => {
it.url = prefixUrlWithHost(req, it.path);
});
return res.send(
bootstrapTemplateWithHTMXetc(
eta.render("workshop/files", {
files,
...sidebarStuff(db, structure_id),
})
)
);
}); });
app.get("/workshop/:structure_id/new_template_modal", (req, res) => { app.get("/workshop/:structure_id/new_template_modal", (req, res) => {

View file

@ -37,8 +37,7 @@ CREATE TABLE templates (
engine TEXT NOT NULL DEFAULT "eta", engine TEXT NOT NULL DEFAULT "eta",
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY(structure_id) REFERENCES structures(id) FOREIGN KEY(structure_id) REFERENCES structures(id) UNIQUE(name, structure_id)
UNIQUE(name, structure_id)
); );
CREATE TABLE routes ( CREATE TABLE routes (
@ -57,47 +56,89 @@ CREATE TABLE structure_dbs (
db_id INTEGER, db_id INTEGER,
structure_id INTEGER, structure_id INTEGER,
alias TEXT NOT NULL, alias TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(db_id, structure_id), PRIMARY KEY(db_id, structure_id),
FOREIGN KEY(db_id) REFERENCES dbs(id), FOREIGN KEY(db_id) REFERENCES dbs(id),
FOREIGN KEY(structure_id) REFERENCES structures(id) FOREIGN KEY(structure_id) REFERENCES structures(id)
); );
CREATE TABLE files (
id INTEGER PRIMARY KEY,
structure_id INTEGER,
name TEXT,
path TEXT,
mime_type TEXT,
mime_subtype TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (structure_id) REFERENCES structures(id),
UNIQUE(path, structure_id)
);
-- =========================== -- ===========================
-- TRIGGERS -- TRIGGERS
-- =========================== -- ===========================
CREATE TRIGGER update_users_updated_at CREATE TRIGGER update_users_updated_at
AFTER UPDATE ON users AFTER
FOR EACH ROW UPDATE
BEGIN ON users FOR EACH ROW BEGIN
UPDATE users SET updated_at = CURRENT_TIMESTAMP WHERE id = OLD.id; UPDATE
users
SET
updated_at = CURRENT_TIMESTAMP
WHERE
id = OLD.id;
END; END;
CREATE TRIGGER update_structures_updated_at CREATE TRIGGER update_structures_updated_at
AFTER UPDATE ON structures AFTER
FOR EACH ROW UPDATE
BEGIN ON structures FOR EACH ROW BEGIN
UPDATE structures SET updated_at = CURRENT_TIMESTAMP WHERE id = OLD.id; UPDATE
structures
SET
updated_at = CURRENT_TIMESTAMP
WHERE
id = OLD.id;
END; END;
CREATE TRIGGER update_dbs_updated_at CREATE TRIGGER update_dbs_updated_at
AFTER UPDATE ON dbs AFTER
FOR EACH ROW UPDATE
BEGIN ON dbs FOR EACH ROW BEGIN
UPDATE dbs SET updated_at = CURRENT_TIMESTAMP WHERE id = OLD.id; UPDATE
dbs
SET
updated_at = CURRENT_TIMESTAMP
WHERE
id = OLD.id;
END; END;
CREATE TRIGGER update_templates_updated_at CREATE TRIGGER update_templates_updated_at
AFTER UPDATE ON templates AFTER
FOR EACH ROW UPDATE
BEGIN ON templates FOR EACH ROW BEGIN
UPDATE templates SET updated_at = CURRENT_TIMESTAMP WHERE id = OLD.id; UPDATE
templates
SET
updated_at = CURRENT_TIMESTAMP
WHERE
id = OLD.id;
END; END;
CREATE TRIGGER update_routes_updated_at CREATE TRIGGER update_routes_updated_at
AFTER UPDATE ON routes AFTER
FOR EACH ROW UPDATE
BEGIN ON routes FOR EACH ROW BEGIN
UPDATE routes SET updated_at = CURRENT_TIMESTAMP WHERE id = OLD.id; UPDATE
END; routes
SET
updated_at = CURRENT_TIMESTAMP
WHERE
id = OLD.id;
END;

View file

@ -0,0 +1 @@
<li><%= it.file.name %> &nbsp;&nbsp;&nbsp;<input value="<%= it.file.url %>"></input></li>

42
views/workshop/files.eta Normal file
View file

@ -0,0 +1,42 @@
<html>
<head>
<link rel="stylesheet" href="/css/xp.css">
<script src="/js/ace/ace.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div class="flex flex-col w-full h-full window">
<div class="title-bar">
<div class="title-bar-text">Workshop - <%~ include('/workshop/structure_name', {structure: it.structure}) %>
</div>
</div>
<div class="flex flex-row flex-grow window-body">
<div class="w-1/5 h-full">
<%~ include('/workshop/sidebar', it) %>
</div>
<div id="main-editor" class="flex flex-grow flex-col">
<h1>Files</h1>
<div>
<form hx-encoding='multipart/form-data' hx-post='/workshop/<%= it.structure.id %>/files' hx-target="#files-list" hx-swap="afterbegin" _='on htmx:xhr:progress(loaded, total) set #progress.value to (loaded/total)*100'>
<input type='file' name='file'>
<button type="submit">
Upload
</button>
<progress id='progress' value='0' max='100'></progress>
</form>
</div>
<div>
<ul id="files-list">
<% for (let file of it.files) { %>
<%~ include('/workshop/file_detail', { file }) %>
<% } %>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>

View file

@ -56,5 +56,8 @@
</ul> </ul>
</details> </details>
</li> </li>
<li>
<a href="/workshop/<%= it.structure.id %>/files">Files</a>
</li>
</ul> </ul>
<div id="modal-zone" style="z-index: 1000000;"></div> <div id="modal-zone" style="z-index: 1000000;"></div>