diff --git a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/api/DocumentController.kt b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/api/DocumentController.kt index 10aa3f6..60fbab5 100644 --- a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/api/DocumentController.kt +++ b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/api/DocumentController.kt @@ -58,12 +58,13 @@ class DocumentController { @RequestParam renderer: String?, @RequestParam editor: String?, @RequestParam tags: List?, - @RequestParam mimeType: String? + @RequestParam mimeType: String?, + @RequestParam fileExtension: String?, ): String { if (mimeType == null && file == null) throw ResponseStatusException(HttpStatus.BAD_REQUEST) val uuid = if (file != null) - documentService!!.createDocument(title, renderer, editor, mimeType ?: file.contentType, tags, file.inputStream) - else documentService!!.createDocument(title, renderer, editor, mimeType!!, tags, null) + documentService!!.createDocument(title, renderer, editor, mimeType ?: file.contentType, tags, fileExtension, file.inputStream) + else documentService!!.createDocument(title, renderer, editor, mimeType!!, tags, fileExtension, null) return uuid.toString() } diff --git a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/database/dao/DocumentDao.kt b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/database/dao/DocumentDao.kt index 787621c..7b38b5e 100644 --- a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/database/dao/DocumentDao.kt +++ b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/database/dao/DocumentDao.kt @@ -15,7 +15,8 @@ interface DocumentDao { renderer: String, editor: String, mimeType: String, - tags: List + tags: List, + fileExtension: String?, ) fun deleteDocument(id: UUID) diff --git a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/database/dao/DocumentRepository.kt b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/database/dao/DocumentRepository.kt index 1e9e6f4..886e67b 100644 --- a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/database/dao/DocumentRepository.kt +++ b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/database/dao/DocumentRepository.kt @@ -85,16 +85,18 @@ class DocumentRepository : DocumentDao { renderer: String, editor: String, mimeType: String, - tags: List + tags: List, + fileExtension: String?, ) { if (jdbcTemplate!!.update( - "insert into Document (id, title, renderer, editor, mimeType) values (?,?,?,?,?)", + "insert into Document (id, title, renderer, editor, mimeType, fileExtension) values (?,?,?,?,?,?)", uuid.toString(), title, renderer, editor, - mimeType + mimeType, + fileExtension ) != 1 ) throw RuntimeException("document creation did not work / didn't affect one row") diff --git a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/renderer/Renderer.kt b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/renderer/Renderer.kt index 5893d42..8aa173d 100644 --- a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/renderer/Renderer.kt +++ b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/renderer/Renderer.kt @@ -20,9 +20,9 @@ class Renderer { companion object { private val plainRenderer = Renderer().output { RenderedDocument( - FileInputStream(it.fsService.getFileFromID(it.document.id)), + FileInputStream(it.fsService.getFileFromID(it.document.id, it.document.fileExtension)), it.document.mimeType, - it.fsService.getFileAttributesFromID(it.document.id).size(), + it.fsService.getFileAttributesFromID(it.document.id, it.document.fileExtension).size(), it.document.id.toString() + if (it.document.fileExtension != "") "." + it.document.fileExtension else "" ) } diff --git a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/services/DocumentMeta.kt b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/services/DocumentMeta.kt index e29722e..ef71fb0 100644 --- a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/services/DocumentMeta.kt +++ b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/services/DocumentMeta.kt @@ -13,6 +13,7 @@ data class DocumentMeta( val modified: Timestamp, val accessed: Timestamp, val tags: List, + val fileExtension: String?, ) { constructor( doc: Document, @@ -20,5 +21,5 @@ data class DocumentMeta( modified: Timestamp, accessed: Timestamp, tags: List - ) : this(doc.id, doc.title, doc.added, doc.editor, created, modified, accessed, tags) + ) : this(doc.id, doc.title, doc.added, doc.editor, created, modified, accessed, tags, doc.fileExtension) } diff --git a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/services/DocumentService.kt b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/services/DocumentService.kt index 49536e2..d8111db 100644 --- a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/services/DocumentService.kt +++ b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/services/DocumentService.kt @@ -29,7 +29,7 @@ class DocumentService { } private fun documentToMeta(document: Document): DocumentMeta { - val attributes = fsService!!.getFileAttributesFromID(document.id) + val attributes = fsService!!.getFileAttributesFromID(document.id, document.fileExtension) return DocumentMeta( document, Timestamp(attributes.creationTime().toMillis()), @@ -64,6 +64,7 @@ class DocumentService { editor: String?, mimeType: String, tags: List?, + fileExtension: String?, content: InputStream?, ): UUID { val uuid = uuidGenerator.generate() @@ -75,11 +76,12 @@ class DocumentService { editor ?: "text", mimeType, tags ?: listOf(), + fileExtension, ) - fsService!!.createDocument(uuid) + fsService!!.createDocument(uuid, fileExtension) if (content != null) { - fsService!!.writeToDocument(uuid, content) + fsService!!.writeToDocument(uuid, fileExtension, content) content.close() } diff --git a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/services/FileSystemService.kt b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/services/FileSystemService.kt index 0dc3cea..82dac2a 100644 --- a/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/services/FileSystemService.kt +++ b/backend/app/src/main/kotlin/me/kruemmelspalter/file_spider/backend/services/FileSystemService.kt @@ -40,25 +40,25 @@ class FileSystemService { if (!Files.isWritable(tmpDirectory)) throw Exception("Temporary Directory isn't writable") } - fun getDocumentPathFromID(id: UUID): Path { - return Paths.get(getDirectoryPathFromID(id).toString(), id.toString()) + fun getDocumentPathFromID(id: UUID, fileExtension: String?): Path { + return Paths.get(getDirectoryPathFromID(id).toString(), id.toString() + if (fileExtension != null) ".$fileExtension" else "") } fun getDirectoryPathFromID(id: UUID): Path { return Paths.get(documentDirectory.toString(), id.toString()).toAbsolutePath() } - fun getFileFromID(id: UUID): File { - return getDocumentPathFromID(id).toFile() + fun getFileFromID(id: UUID, fileExtension: String?): File { + return getDocumentPathFromID(id, fileExtension).toFile() } - fun getInputStreamFromID(id: UUID): InputStream { - return FileInputStream(getFileFromID(id)) + fun getInputStreamFromID(id: UUID, fileExtension: String?): InputStream { + return FileInputStream(getFileFromID(id, fileExtension)) } - fun getContentFromID(id: UUID): String { + fun getContentFromID(id: UUID, fileExtension: String?): String { val resultBuilder = StringBuilder() - val br = BufferedReader(FileReader(getFileFromID(id))) + val br = BufferedReader(FileReader(getFileFromID(id, fileExtension))) br.use { var line = br.readLine() while (line != null) { @@ -69,8 +69,8 @@ class FileSystemService { return resultBuilder.toString() } - fun getFileAttributesFromID(id: UUID): BasicFileAttributes { - return Files.readAttributes(getDocumentPathFromID(id), BasicFileAttributes::class.java) + fun getFileAttributesFromID(id: UUID, fileExtension: String?): BasicFileAttributes { + return Files.readAttributes(getDocumentPathFromID(id, fileExtension), BasicFileAttributes::class.java) } fun getTemporaryDirectory(): Path { @@ -87,15 +87,15 @@ class FileSystemService { else FileInputStream(file) } - fun createDocument(id: UUID) { + fun createDocument(id: UUID, fileExtension: String?) { val directory = getDirectoryPathFromID(id).toFile() if (!directory.mkdir()) throw Error("could not create document directory") - val file = getFileFromID(id) + val file = getFileFromID(id, fileExtension) if (!file.createNewFile()) throw Error("could not create document file") } - fun writeToDocument(id: UUID, stream: InputStream) { - val outStream = FileOutputStream(getFileFromID(id)) + fun writeToDocument(id: UUID, fileExtension: String?, stream: InputStream) { + val outStream = FileOutputStream(getFileFromID(id, fileExtension)) stream.transferTo(outStream) outStream.close() } diff --git a/backend/app/src/main/resources/sql/init.sql b/backend/app/src/main/resources/sql/init.sql index 0226dca..0b30b98 100644 --- a/backend/app/src/main/resources/sql/init.sql +++ b/backend/app/src/main/resources/sql/init.sql @@ -5,7 +5,7 @@ create table Document ( renderer varchar(16) default 'mimeSpecific', editor varchar(32) default 'mimeSpecific', mimeType varchar(64) not null, - fileExtension varchar(10) default '', + fileExtension varchar(10), primary key (id) ); diff --git a/client/.gitignore b/client/.gitignore index 3c3629e..37d7e73 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -1 +1,2 @@ node_modules +.env diff --git a/client/index.js b/client/index.js index d913658..8345c7f 100644 --- a/client/index.js +++ b/client/index.js @@ -2,15 +2,15 @@ const express = require('express') const proxy = require('express-http-proxy') const { execSync, spawn } = require("child_process") const axios = require('axios') +require('dotenv').config() -const API_HOST = 'http://172.31.69.5' -const MOUNT_PATH = process.env.HOME + '/.filespider' -const PORT = 8080 - +const API_HOST = process.env.API_HOST || 'http://172.31.69.4' +const MOUNT_PATH = process.env.MOUNT_PATH || (process.env.HOME + '/.filespider') +const PORT = process.env.PORT || 8080 const app = express() const editors = { - mimeSpecific: path => ({explorer: true, command: 'xdg-open', args: [path]}), + mime: path => ({explorer: true, command: 'xdg-open', args: [path]}), plain: path => ({explorer: true, command: 'kate', args: [path]}), xournalpp: path => ({explorer: true, command: 'xournalpp', args: [path]}), } @@ -34,13 +34,14 @@ app.post('/document/:docId/edit', async (req, res) => { res.status(500).send({path: `${API_HOST}/document/${req.params.docId}`, error: e}) return } - const path = `${MOUNT_PATH}/${req.params.docId}/${req.params.docId}` - const editor = editors[meta.data.editor](path) - if(editor === undefined) { + const path = `${MOUNT_PATH}/${req.params.docId}/${req.params.docId}` + (meta.data.fileExtension !== undefined ? "." + meta.data.fileExtension : "") + const editorProvider = editors[meta.data.editor] + if(editorProvider === undefined) { res.status(400).send(`Wrong editor ${meta.data.editor}`) console.log(`Wrong editor ${meta.data.editor}`) return } + const editor = editorProvider(path) if(editor.explorer) spawn('dolphin', [`${path}/..`]) spawn(editor.command, editor.args) res.send() diff --git a/client/package.json b/client/package.json index 9a0f967..5daca9c 100644 --- a/client/package.json +++ b/client/package.json @@ -5,6 +5,7 @@ "license": "MIT", "dependencies": { "axios": "^1.2.1", + "dotenv": "^16.0.3", "express": "^4.18.2", "express-http-proxy": "^1.6.3" }, diff --git a/client/yarn.lock b/client/yarn.lock index 13ade0d..8ba5d70 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -176,6 +176,11 @@ destroy@1.2.0: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== +dotenv@^16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" + integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" diff --git a/frontend/components/DocumentCreationDialog.vue b/frontend/components/DocumentCreationDialog.vue index 6f52b28..b136f4f 100644 --- a/frontend/components/DocumentCreationDialog.vue +++ b/frontend/components/DocumentCreationDialog.vue @@ -33,6 +33,7 @@ /> + Submit @@ -67,6 +68,7 @@ export default { renderer: null, editor: null, file: null, + fileExtension: null, }, } }, @@ -92,7 +94,14 @@ export default { formData.append('editor', this.creationMeta.editor || 'mime') if (this.creationMeta.file !== null) { formData.append('file', this.creationMeta.file) + if (this.creationMeta.fileExtension === null) { + formData.append('fileExtension', this.creationMeta.file.name.split('.').at(-1)) + } } + if (this.creationMeta.fileExtension !== null) { + formData.append('fileExtension', this.creationMeta.fileExtension) + } + this.$axios.$post(`${this.apiSource}/document/`, formData, { headers: { 'Content-Type': 'multipart/form-data' }, }) @@ -106,7 +115,8 @@ export default { show () { this.visible = true }, - }, + } + , }