make docker usable

This commit is contained in:
Michel Roux 2023-06-24 19:53:53 +02:00
parent 41250ea97d
commit 04350b4512
5 changed files with 105 additions and 264 deletions

7
.dockerignore Normal file
View File

@ -0,0 +1,7 @@
.idea
*.iml
/vendor/
/build/
node_modules/
/.php-cs-fixer.cache
js/

View File

@ -15,7 +15,7 @@ COPY --chown=www-data:www-data . apps/repod
RUN curl -sSLo /tmp/gpoddersync.tar.gz https://github.com/thrillfall/nextcloud-gpodder/releases/download/3.8.1/gpoddersync.tar.gz && \
tar xvzf /tmp/gpoddersync.tar.gz -C apps && \
rm /tmp/gpoddersync.tar.gz && \
cd apps/repod && make build && cd - \
cd apps/repod && make build && cd - && \
php occ app:enable gpoddersync repod
USER root

174
package-lock.json generated
View File

@ -10,7 +10,6 @@
"license": "agpl",
"dependencies": {
"@nextcloud/axios": "2.3.0",
"@nextcloud/dialogs": "4.0.1",
"@nextcloud/router": "2.1.2",
"@nextcloud/vue": "7.0.1",
"vue": "2.7.14"
@ -1985,6 +1984,19 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@floating-ui/core": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.3.1.tgz",
"integrity": "sha512-ensKY7Ub59u16qsVIFEo2hwTCqZ/r9oZZFh51ivcLGHfUwTn8l1Xzng8RJUe91H/UP8PeqeBronAGx0qmzwk2g=="
},
"node_modules/@floating-ui/dom": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.1.10.tgz",
"integrity": "sha512-4kAVoogvQm2N0XE0G6APQJuCNuErjOfPW8Ux7DFxh8+AfugWflwVJ5LDlHOwrwut7z/30NUvdtHzQ3zSip4EzQ==",
"dependencies": {
"@floating-ui/core": "^0.3.0"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
@ -2200,12 +2212,12 @@
}
},
"node_modules/@nextcloud/dialogs": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-4.0.1.tgz",
"integrity": "sha512-jgIJdxTpc3suHkuZBRge6/dU6krG7x9emMGTxKY5qRQqFwn9r4rCqjV7Cys7VMn1QLlHmEDdqHcYZFRtN/XVNA==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-3.2.0.tgz",
"integrity": "sha512-notaHF8LXPJINBbILCbRe+dgXnJPe7NQTIrN1vwfaGUSG9GUfEf+v367yyg2brCgV6ulE/HmNhYjTQwW5AqSJA==",
"dependencies": {
"@nextcloud/l10n": "^1.3.0",
"@nextcloud/typings": "^1.4.3",
"@nextcloud/typings": "^1.0.0",
"core-js": "^3.6.4",
"toastify-js": "^1.12.0"
},
@ -2420,21 +2432,6 @@
"npm": "^7.0.0 || ^8.0.0"
}
},
"node_modules/@nextcloud/vue/node_modules/@nextcloud/dialogs": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-3.2.0.tgz",
"integrity": "sha512-notaHF8LXPJINBbILCbRe+dgXnJPe7NQTIrN1vwfaGUSG9GUfEf+v367yyg2brCgV6ulE/HmNhYjTQwW5AqSJA==",
"dependencies": {
"@nextcloud/l10n": "^1.3.0",
"@nextcloud/typings": "^1.0.0",
"core-js": "^3.6.4",
"toastify-js": "^1.12.0"
},
"engines": {
"node": "^16.0.0",
"npm": "^7.0.0 || ^8.0.0"
}
},
"node_modules/@nextcloud/webpack-vue-config": {
"version": "5.5.1",
"resolved": "https://registry.npmjs.org/@nextcloud/webpack-vue-config/-/webpack-vue-config-5.5.1.tgz",
@ -2605,6 +2602,13 @@
"@types/send": "*"
}
},
"node_modules/@types/http-errors": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz",
"integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==",
"dev": true,
"peer": true
},
"node_modules/@types/http-proxy": {
"version": "1.17.11",
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz",
@ -2722,12 +2726,13 @@
}
},
"node_modules/@types/serve-static": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz",
"integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==",
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz",
"integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==",
"dev": true,
"peer": true,
"dependencies": {
"@types/http-errors": "*",
"@types/mime": "*",
"@types/node": "*"
}
@ -5182,9 +5187,9 @@
"peer": true
},
"node_modules/electron-to-chromium": {
"version": "1.4.439",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.439.tgz",
"integrity": "sha512-BHpErPSNhb9FB25+OwQP6mCAf3ZXfGbmuvc4LzBNVJwpCcXQJm++LerimocYRG9FRxUVRKZqaB7d0+pImSTPSg==",
"version": "1.4.440",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.440.tgz",
"integrity": "sha512-r6dCgNpRhPwiWlxbHzZQ/d9swfPaEJGi8ekqRBwQYaR3WmA5VkqQfBWSDDjuJU1ntO+W9tHx8OHV/96Q8e0dVw==",
"dev": true,
"peer": true
},
@ -5829,9 +5834,9 @@
}
},
"node_modules/eslint-plugin-vue": {
"version": "9.15.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.15.0.tgz",
"integrity": "sha512-XYzpK6e2REli100+6iCeBA69v6Sm0D/yK2FZP+fCeNt0yH/m82qZQq+ztseyV0JsKdhFysuSEzeE1yCmSC92BA==",
"version": "9.15.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.15.1.tgz",
"integrity": "sha512-CJE/oZOslvmAR9hf8SClTdQ9JLweghT6JCBQNrT2Iel1uVw0W0OLJxzvPd6CxmABKCvLrtyDnqGV37O7KQv6+A==",
"dev": true,
"peer": true,
"dependencies": {
@ -6563,19 +6568,6 @@
"vue": "^2.6.10"
}
},
"node_modules/floating-vue/node_modules/@floating-ui/core": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.3.1.tgz",
"integrity": "sha512-ensKY7Ub59u16qsVIFEo2hwTCqZ/r9oZZFh51ivcLGHfUwTn8l1Xzng8RJUe91H/UP8PeqeBronAGx0qmzwk2g=="
},
"node_modules/floating-vue/node_modules/@floating-ui/dom": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.1.10.tgz",
"integrity": "sha512-4kAVoogvQm2N0XE0G6APQJuCNuErjOfPW8Ux7DFxh8+AfugWflwVJ5LDlHOwrwut7z/30NUvdtHzQ3zSip4EzQ==",
"dependencies": {
"@floating-ui/core": "^0.3.0"
}
},
"node_modules/focus-trap": {
"version": "7.4.3",
"resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.4.3.tgz",
@ -6660,6 +6652,21 @@
"dev": true,
"peer": true
},
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"peer": true,
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@ -13912,6 +13919,19 @@
"dev": true,
"peer": true
},
"@floating-ui/core": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.3.1.tgz",
"integrity": "sha512-ensKY7Ub59u16qsVIFEo2hwTCqZ/r9oZZFh51ivcLGHfUwTn8l1Xzng8RJUe91H/UP8PeqeBronAGx0qmzwk2g=="
},
"@floating-ui/dom": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.1.10.tgz",
"integrity": "sha512-4kAVoogvQm2N0XE0G6APQJuCNuErjOfPW8Ux7DFxh8+AfugWflwVJ5LDlHOwrwut7z/30NUvdtHzQ3zSip4EzQ==",
"requires": {
"@floating-ui/core": "^0.3.0"
}
},
"@humanwhocodes/config-array": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
@ -14082,12 +14102,12 @@
}
},
"@nextcloud/dialogs": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-4.0.1.tgz",
"integrity": "sha512-jgIJdxTpc3suHkuZBRge6/dU6krG7x9emMGTxKY5qRQqFwn9r4rCqjV7Cys7VMn1QLlHmEDdqHcYZFRtN/XVNA==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-3.2.0.tgz",
"integrity": "sha512-notaHF8LXPJINBbILCbRe+dgXnJPe7NQTIrN1vwfaGUSG9GUfEf+v367yyg2brCgV6ulE/HmNhYjTQwW5AqSJA==",
"requires": {
"@nextcloud/l10n": "^1.3.0",
"@nextcloud/typings": "^1.4.3",
"@nextcloud/typings": "^1.0.0",
"core-js": "^3.6.4",
"toastify-js": "^1.12.0"
}
@ -14231,19 +14251,6 @@
"vue-material-design-icons": "^5.1.2",
"vue-multiselect": "^2.1.6",
"vue2-datepicker": "^3.11.0"
},
"dependencies": {
"@nextcloud/dialogs": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-3.2.0.tgz",
"integrity": "sha512-notaHF8LXPJINBbILCbRe+dgXnJPe7NQTIrN1vwfaGUSG9GUfEf+v367yyg2brCgV6ulE/HmNhYjTQwW5AqSJA==",
"requires": {
"@nextcloud/l10n": "^1.3.0",
"@nextcloud/typings": "^1.0.0",
"core-js": "^3.6.4",
"toastify-js": "^1.12.0"
}
}
}
},
"@nextcloud/webpack-vue-config": {
@ -14389,6 +14396,13 @@
"@types/send": "*"
}
},
"@types/http-errors": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz",
"integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==",
"dev": true,
"peer": true
},
"@types/http-proxy": {
"version": "1.17.11",
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz",
@ -14506,12 +14520,13 @@
}
},
"@types/serve-static": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz",
"integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==",
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz",
"integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==",
"dev": true,
"peer": true,
"requires": {
"@types/http-errors": "*",
"@types/mime": "*",
"@types/node": "*"
}
@ -16434,9 +16449,9 @@
"peer": true
},
"electron-to-chromium": {
"version": "1.4.439",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.439.tgz",
"integrity": "sha512-BHpErPSNhb9FB25+OwQP6mCAf3ZXfGbmuvc4LzBNVJwpCcXQJm++LerimocYRG9FRxUVRKZqaB7d0+pImSTPSg==",
"version": "1.4.440",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.440.tgz",
"integrity": "sha512-r6dCgNpRhPwiWlxbHzZQ/d9swfPaEJGi8ekqRBwQYaR3WmA5VkqQfBWSDDjuJU1ntO+W9tHx8OHV/96Q8e0dVw==",
"dev": true,
"peer": true
},
@ -17042,9 +17057,9 @@
"requires": {}
},
"eslint-plugin-vue": {
"version": "9.15.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.15.0.tgz",
"integrity": "sha512-XYzpK6e2REli100+6iCeBA69v6Sm0D/yK2FZP+fCeNt0yH/m82qZQq+ztseyV0JsKdhFysuSEzeE1yCmSC92BA==",
"version": "9.15.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.15.1.tgz",
"integrity": "sha512-CJE/oZOslvmAR9hf8SClTdQ9JLweghT6JCBQNrT2Iel1uVw0W0OLJxzvPd6CxmABKCvLrtyDnqGV37O7KQv6+A==",
"dev": true,
"peer": true,
"requires": {
@ -17504,21 +17519,6 @@
"requires": {
"@floating-ui/dom": "^0.1.10",
"vue-resize": "^1.0.0"
},
"dependencies": {
"@floating-ui/core": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.3.1.tgz",
"integrity": "sha512-ensKY7Ub59u16qsVIFEo2hwTCqZ/r9oZZFh51ivcLGHfUwTn8l1Xzng8RJUe91H/UP8PeqeBronAGx0qmzwk2g=="
},
"@floating-ui/dom": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.1.10.tgz",
"integrity": "sha512-4kAVoogvQm2N0XE0G6APQJuCNuErjOfPW8Ux7DFxh8+AfugWflwVJ5LDlHOwrwut7z/30NUvdtHzQ3zSip4EzQ==",
"requires": {
"@floating-ui/core": "^0.3.0"
}
}
}
},
"focus-trap": {
@ -17582,6 +17582,14 @@
"dev": true,
"peer": true
},
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"optional": true,
"peer": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",

View File

@ -19,7 +19,6 @@
},
"dependencies": {
"@nextcloud/axios": "2.3.0",
"@nextcloud/dialogs": "4.0.1",
"@nextcloud/router": "2.1.2",
"@nextcloud/vue": "7.0.1",
"vue": "2.7.14"

View File

@ -4,26 +4,12 @@
<NcAppNavigationNew :text="t('repod', 'Add a podcast')"
@click="discover" />
<ul>
<NcAppNavigationItem v-for="note in notes"
:key="note.id"
<NcAppNavigationItem v-for="podcast in podcasts"
:key="podcast.id"
:name="podcast.id"
:title="note.title ? note.title : t('repod', 'New note')"
:class="{active: currentNoteId === note.id}"
@click="openNote(note)">
<template slot="actions">
<NcActionButton v-if="note.id === -1"
icon="icon-close"
@click="cancelNewNote(note)">
{{
t('repod', 'Cancel note creation') }}
</NcActionButton>
<NcActionButton v-else
icon="icon-delete"
@click="deleteNote(note)">
{{
t('repod', 'Delete note') }}
</NcActionButton>
</template>
</NcAppNavigationItem>
@click="openNote(note)" />
</ul>
</NcAppNavigation>
<NcAppContent>
@ -32,17 +18,11 @@
</template>
<script>
import { NcActionButton, NcAppContent, NcContent, NcAppNavigation, NcAppNavigationItem, NcAppNavigationNew } from '@nextcloud/vue'
import '@nextcloud/dialogs/dist/index.css'
import { generateUrl } from '@nextcloud/router'
import { showError, showSuccess } from '@nextcloud/dialogs'
import axios from '@nextcloud/axios'
import { NcAppContent, NcContent, NcAppNavigation, NcAppNavigationItem, NcAppNavigationNew } from '@nextcloud/vue'
export default {
name: 'App',
components: {
NcActionButton,
NcAppContent,
NcAppNavigation,
NcAppNavigationItem,
@ -51,169 +31,16 @@ export default {
},
data() {
return {
notes: [],
currentNoteId: null,
updating: false,
loading: true,
podcasts: [],
}
},
computed: {
/**
* Return the currently selected note object
*
* @return {object | null}
*/
currentNote() {
if (this.currentNoteId === null) {
return null
}
return this.notes.find((note) => note.id === this.currentNoteId)
},
/**
* Returns true if a note is selected and its title is not empty
*
* @return {boolean}
*/
savePossible() {
return this.currentNote && this.currentNote.title !== ''
},
},
/**
* Fetch list of notes when the component is loaded
*/
async mounted() {
try {
const response = await axios.get(generateUrl('/apps/repod/notes'))
this.notes = response.data
} catch (e) {
console.error(e)
showError(t('notestutorial', 'Could not fetch notes'))
}
this.loading = false
},
methods: {
/**
* Create a new note and focus the note content field automatically
*
* @param {object} note Note object
*/
openNote(note) {
if (this.updating) {
return
}
this.currentNoteId = note.id
this.$nextTick(() => {
this.$refs.content.focus()
})
},
/**
* Action tiggered when clicking the save button
* create a new note or save
*/
saveNote() {
if (this.currentNoteId === -1) {
this.createNote(this.currentNote)
} else {
this.updateNote(this.currentNote)
}
},
/**
* Create a new note and focus the note content field automatically
* The note is not yet saved, therefore an id of -1 is used until it
* has been persisted in the backend
*/
newNote() {
if (this.currentNoteId !== -1) {
this.currentNoteId = -1
this.notes.push({
id: -1,
title: '',
content: '',
})
this.$nextTick(() => {
this.$refs.title.focus()
})
}
},
/**
* Abort creating a new note
*/
cancelNewNote() {
this.notes.splice(this.notes.findIndex((note) => note.id === -1), 1)
this.currentNoteId = null
},
/**
* Create a new note by sending the information to the server
*
* @param {object} note Note object
*/
async createNote(note) {
this.updating = true
try {
const response = await axios.post(generateUrl('/apps/repod/notes'), note)
const index = this.notes.findIndex((match) => match.id === this.currentNoteId)
this.$set(this.notes, index, response.data)
this.currentNoteId = response.data.id
} catch (e) {
console.error(e)
showError(t('notestutorial', 'Could not create the note'))
}
this.updating = false
},
/**
* Update an existing note on the server
*
* @param {object} note Note object
*/
async updateNote(note) {
this.updating = true
try {
await axios.put(generateUrl(`/apps/repod/notes/${note.id}`), note)
} catch (e) {
console.error(e)
showError(t('notestutorial', 'Could not update the note'))
}
this.updating = false
},
/**
* Delete a note, remove it from the frontend and show a hint
*
* @param {object} note Note object
*/
async deleteNote(note) {
try {
await axios.delete(generateUrl(`/apps/repod/notes/${note.id}`))
this.notes.splice(this.notes.indexOf(note), 1)
if (this.currentNoteId === note.id) {
this.currentNoteId = null
}
showSuccess(t('repod', 'Note deleted'))
} catch (e) {
console.error(e)
showError(t('repod', 'Could not delete the note'))
}
},
},
}
</script>
<style scoped>
#app-content > div {
width: 100%;
height: 100%;
padding: 20px;
display: flex;
flex-direction: column;
flex-grow: 1;
}
input[type='text'] {
width: 100%;
}
textarea {
flex-grow: 1;
width: 100%;
}
</style>