mirror of
https://framagit.org/les/gancio.git
synced 2025-01-31 16:42:22 +01:00
fix #10 choose upload path in config.js
This commit is contained in:
parent
a557348b21
commit
5778c64108
16 changed files with 99 additions and 95 deletions
|
@ -1,14 +1,15 @@
|
|||
const path = require('path')
|
||||
|
||||
/**
|
||||
* -[ GANCIO CONFIGURATION ]-
|
||||
*
|
||||
* search and replace 'CHANGE ME'
|
||||
*
|
||||
* -[ Database configuration ]-
|
||||
* `development` configuration is enabled running `yarn dev`
|
||||
* while `production` with `yarn start`
|
||||
* ref: http://docs.sequelizejs.com/class/lib/sequelize.js~Sequelize.html#instance-constructor-constructor
|
||||
*
|
||||
*/
|
||||
const path = require('path')
|
||||
|
||||
const DB_CONF = {
|
||||
development: {
|
||||
|
@ -16,8 +17,8 @@ const DB_CONF = {
|
|||
dialect: 'sqlite'
|
||||
},
|
||||
production: {
|
||||
username: '',
|
||||
password: '',
|
||||
username: 'CHANGE ME',
|
||||
password: 'CHANGE ME',
|
||||
database: 'gancio',
|
||||
host: 'localhost',
|
||||
dialect: 'postgres',
|
||||
|
@ -26,7 +27,7 @@ const DB_CONF = {
|
|||
}
|
||||
|
||||
const env = process.env.NODE_ENV || 'development'
|
||||
|
||||
const isDev = env === 'development'
|
||||
/**
|
||||
* -[ Main configuration ]-
|
||||
*
|
||||
|
@ -34,30 +35,34 @@ const env = process.env.NODE_ENV || 'development'
|
|||
const config = {
|
||||
server: {
|
||||
port: '3000',
|
||||
host: '0',
|
||||
host: 'localhost', // use 0.0.0.0 to bind to all interface
|
||||
|
||||
// uncomment to use unix socket to serve gancio
|
||||
// path: '/tmp/gancio_socket',
|
||||
},
|
||||
|
||||
locale: 'it',
|
||||
title: 'GANCIO',
|
||||
description: 'A shared agenda for radical communities',
|
||||
baseurl: '' || 'http://localhost:3000',
|
||||
title: isDev ? 'GANCIO' : 'CHANGE ME',
|
||||
description: isDev ? 'A shared agenda for radical communities' : 'CHANGE ME',
|
||||
baseurl: isDev ? 'http://localhost:3000' : 'https://CHANGE_ME',
|
||||
|
||||
upload_path: isDev ? '/tmp/gancio_upload' : '/var/gancio/upload/',
|
||||
|
||||
// where events/users confirmation email are sent
|
||||
admin: '',
|
||||
admin: 'CHANGE ME',
|
||||
|
||||
// jwt salt secret, generate it randomly with
|
||||
// < /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32};echo;
|
||||
secret: '',
|
||||
secret: isDev ? 'notreallyrandom' : 'CHANGE ME',
|
||||
|
||||
// smtp account to send email
|
||||
smtp: {
|
||||
host: process.env.SMTP_HOST || 'mail.example.com',
|
||||
secure: true,
|
||||
host: 'CHANGE ME', // mail.example.com
|
||||
auth: {
|
||||
user: process.env.SMTP_USER || 'gancio@example.com',
|
||||
pass: process.env.SMTP_PASS || ''
|
||||
}
|
||||
user: 'CHANGE ME',
|
||||
pass: 'CHANGE ME'
|
||||
},
|
||||
secure: true
|
||||
},
|
||||
db: DB_CONF[env]
|
||||
}
|
||||
|
|
|
@ -122,21 +122,21 @@ const it = {
|
|||
},
|
||||
|
||||
settings: {
|
||||
change_password: 'Cambia password'
|
||||
change_password: 'Cambia password',
|
||||
password_updated: 'Password modificata'
|
||||
},
|
||||
|
||||
err: {
|
||||
register_error: 'Errore nella registrazione'
|
||||
}
|
||||
|
||||
|
||||
|
||||
// firstrun: {
|
||||
// basic: `Inserisci titolo e descrizione della tua istanza di gancio.`,
|
||||
// database: `Gancio ha bisogno di un database postgresql!`,
|
||||
// smtp: `Inserisci un account SMTP relativo a questa istanza di gancio.`
|
||||
// },
|
||||
// email: {
|
||||
// registration: `Abbiamo ricevuto la richiesta di registrazione. La confermeremo quanto prima.\n Ciao`
|
||||
// }
|
||||
}
|
||||
|
||||
export default it
|
||||
|
|
|
@ -223,6 +223,8 @@ export default {
|
|||
const place = this.places.find( p => p.name === this.event.place.name )
|
||||
if (place && place.address) {
|
||||
this.event.place.address = place.address
|
||||
} else {
|
||||
this.event.place.address = ''
|
||||
}
|
||||
this.$refs.address.focus()
|
||||
},
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
import { mapState } from 'vuex'
|
||||
import List from '../../components/List'
|
||||
import moment from 'dayjs'
|
||||
import get from 'lodash/get'
|
||||
|
||||
export default {
|
||||
layout: 'iframe',
|
||||
components: { List },
|
||||
computed: mapState(['config']),
|
||||
async asyncData ({ $axios, req, res }) {
|
||||
const title = req && req.query && req.query.title || this.config.title
|
||||
const title = get(req, 'query.title')
|
||||
const tags = req && req.query && req.query.tags
|
||||
const places = req && req.query && req.query.places
|
||||
const now = new Date()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<template lang="pug">
|
||||
el-card#eventDetail
|
||||
|
||||
el-card#eventDetail(v-loading='!loaded')
|
||||
//- close button
|
||||
nuxt-link.float-right(to='/')
|
||||
el-button(circle icon='el-icon-close' type='danger' size='small' plain)
|
||||
|
@ -18,7 +17,7 @@
|
|||
el-button(icon='el-icon-arrow-right' round type='success')
|
||||
|
||||
//- image
|
||||
img(:src='imgPath' v-if='event.image_path')
|
||||
img(:src='imgPath' v-if='event.image_path' @load='image_loaded')
|
||||
|
||||
.info
|
||||
div {{event|event_when}}
|
||||
|
@ -56,6 +55,11 @@ import { mapState, mapActions, mapGetters } from 'vuex'
|
|||
|
||||
export default {
|
||||
name: 'Event',
|
||||
data () {
|
||||
return {
|
||||
loaded: false,
|
||||
}
|
||||
},
|
||||
// transition: null,
|
||||
// Watch for $route.query.page to call Component methods (asyncData, fetch, validate, layout, etc.)
|
||||
// watchQuery: ['id'],
|
||||
|
@ -84,7 +88,8 @@ export default {
|
|||
},
|
||||
async asyncData ( { $axios, params }) {
|
||||
const event = await $axios.$get(`/event/${params.id}`)
|
||||
return { event, id: params.id}
|
||||
const loaded = !event.image_path
|
||||
return { event, id: params.id, loaded }
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['filteredEvents']),
|
||||
|
@ -112,6 +117,9 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
image_loaded (e, b) {
|
||||
this.loaded = true
|
||||
},
|
||||
...mapActions(['delEvent']),
|
||||
comment_filter (value) {
|
||||
return value.replace(/<a.*href="([^">]+).*>(?:.(?!\<\/a\>))*.<\/a>/, (orig, url) => {
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
//- el-tag.ml-1(size='mini' v-for='place in filters.places' :key='place.id') {{place}}
|
||||
el-tabs.mt-2(v-model='type')
|
||||
|
||||
el-tab-pane.pt-1(label='email' name='email')
|
||||
p(v-html='$t(`export.email_description`)')
|
||||
el-form(@submit.native.prevent)
|
||||
//- el-switch(v-model='notification.notify_on_add' :active-text="$t('notify_on_insert')")
|
||||
//- br
|
||||
//- el-switch.mt-2(v-model='notification.send_notification' :active-text="$t('send_notification')")
|
||||
el-input.mt-2(v-model='notification.email' :placeholder="$t('export.insert_your_address')" ref='email')
|
||||
el-button.mt-2.float-right(native-type= 'submit' type='success' @click='add_notification') {{$t('common.send')}}
|
||||
//- el-tab-pane.pt-1(label='email' name='email')
|
||||
//- p(v-html='$t(`export.email_description`)')
|
||||
//- el-form(@submit.native.prevent)
|
||||
//- //- el-switch(v-model='notification.notify_on_add' :active-text="$t('notify_on_insert')")
|
||||
//- //- br
|
||||
//- //- el-switch.mt-2(v-model='notification.send_notification' :active-text="$t('send_notification')")
|
||||
//- el-input.mt-2(v-model='notification.email' :placeholder="$t('export.insert_your_address')" ref='email')
|
||||
//- el-button.mt-2.float-right(native-type= 'submit' type='success' @click='add_notification') {{$t('common.send')}}
|
||||
|
||||
el-tab-pane.pt-1(label='feed rss' name='feed')
|
||||
span(v-html='$t(`export.feed_description`)')
|
||||
|
@ -104,10 +104,14 @@ export default {
|
|||
params.push(`title=${this.list.title}`)
|
||||
}
|
||||
|
||||
if (this.filters.places) {
|
||||
if (this.filters.places.length) {
|
||||
params.push(`places=${this.filters.places}`)
|
||||
}
|
||||
|
||||
if (this.filters.tags.length) {
|
||||
params.push(`tags=${this.filters.tags}`)
|
||||
}
|
||||
|
||||
return `<iframe src="${process.env.baseurl}/embed/list?${params.join('&')}"></iframe>`
|
||||
},
|
||||
link () {
|
||||
|
|
|
@ -5,21 +5,21 @@
|
|||
v-icon(name='times' color='red')
|
||||
h5 {{$t('common.settings')}}
|
||||
|
||||
//- el-form
|
||||
//- el-form-item {{$t('settings.change_password')}}
|
||||
el-divider {{$t('settings.change_password')}}
|
||||
el-input(v-model='password' type='password')
|
||||
el-button(slot='append' @click='change' type='success') {{$t('common.send')}}
|
||||
el-form(action='/api/user' method='PUT' @submit.native.prevent='change')
|
||||
el-form-item {{$t('settings.change_password')}}
|
||||
el-input(v-model='password' type='password')
|
||||
el-button(type='success' native-type='submit') {{$t('common.send')}}
|
||||
</template>
|
||||
<script>
|
||||
import { mapState, mapActions } from 'vuex'
|
||||
import { Message } from 'element-ui'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
password: '',
|
||||
}
|
||||
},
|
||||
// computed: mapState(['user']),
|
||||
// async asyncData ({ $axios, params }) {
|
||||
// const user = await $axios.$get('/auth/user')
|
||||
// user.mastodon_auth = ''
|
||||
|
@ -31,6 +31,8 @@ export default {
|
|||
const user_data = { id : this.$auth.user.id, password: this.password }
|
||||
try {
|
||||
const user = await this.$axios.$put('/user', user_data)
|
||||
Message({ message: this.$t('settings.password_updated'), type: 'success' })
|
||||
this.$router.replace('/')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
import Vue from 'vue'
|
||||
import { Button, Select, Tag, Option, Table, FormItem, Card, Row, Col, Upload, Checkbox,
|
||||
Form, Tabs, TabPane, Switch, Input, Loading, TimeSelect, Badge, ButtonGroup, Divider, Step, Steps,
|
||||
TableColumn, ColorPicker, Pagination, Popover, Tooltip, Dialog,
|
||||
Container, Footer , Timeline, TimelineItem, Menu, MenuItem } from 'element-ui'
|
||||
import localeEn from 'element-ui/lib/locale/lang/en'
|
||||
import localeIt from 'element-ui/lib/locale/lang/it'
|
||||
TableColumn, ColorPicker, Pagination, Popover, Tooltip, Dialog, Image,
|
||||
Container, Footer, Timeline, TimelineItem, Menu, MenuItem } from 'element-ui'
|
||||
import locale from 'element-ui/lib/locale'
|
||||
locale.use(localeIt)
|
||||
|
||||
const locales = {
|
||||
it: require('element-ui/lib/locale/lang/it'),
|
||||
en: require('element-ui/lib/locale/lang/en')
|
||||
}
|
||||
locale.use(locales[process.env.locale])
|
||||
|
||||
export default () => {
|
||||
Vue.use(Button)
|
||||
Vue.use(Divider)
|
||||
Vue.use(Image)
|
||||
Vue.use(Step)
|
||||
Vue.use(Steps)
|
||||
Vue.use(Checkbox)
|
||||
|
|
|
@ -48,7 +48,7 @@ ${event.description.length > 200 ? event.description.substr(0, 200) + '...' : ev
|
|||
|
||||
let media
|
||||
if (event.image_path) {
|
||||
const file = path.join(__dirname, '..', '..', '..', 'uploads', event.image_path)
|
||||
const file = path.join(config.upload_path, event.image_path)
|
||||
if (fs.statSync(file)) {
|
||||
media = await bot.post('media', { file: fs.createReadStream(file) })
|
||||
}
|
||||
|
|
|
@ -53,8 +53,8 @@ const userController = {
|
|||
// check if event is mine (or user is admin)
|
||||
if (event && (req.user.is_admin || req.user.id === event.userId)) {
|
||||
if (event.image_path) {
|
||||
const old_path = path.resolve(__dirname, '..', '..', 'uploads', event.image_path)
|
||||
const old_thumb_path = path.resolve(__dirname, '..', '..', 'uploads', 'thumb', event.image_path)
|
||||
const old_path = path.join(config.upload_path, event.image_path)
|
||||
const old_thumb_path = path.join(config.upload_path, 'thumb', event.image_path)
|
||||
try {
|
||||
await fs.unlink(old_path)
|
||||
await fs.unlink(old_thumb_path)
|
||||
|
@ -126,8 +126,8 @@ const userController = {
|
|||
|
||||
if (req.file) {
|
||||
if (event.image_path) {
|
||||
const old_path = path.resolve(__dirname, '..', '..', 'uploads', event.image_path)
|
||||
const old_thumb_path = path.resolve(__dirname, '..', '..', 'uploads', 'thumb', event.image_path)
|
||||
const old_path = path.resolve(config.upload_path, event.image_path)
|
||||
const old_thumb_path = path.resolve(config.upload_path, 'thumb', event.image_path)
|
||||
await fs.unlink(old_path, e => console.error(e))
|
||||
await fs.unlink(old_thumb_path, e => console.error(e))
|
||||
}
|
||||
|
|
|
@ -11,9 +11,7 @@ const exportController = require('./controller/export')
|
|||
const userController = require('./controller/user')
|
||||
const settingsController = require('./controller/settings')
|
||||
|
||||
const storage = require('./storage')({
|
||||
destination: 'uploads/'
|
||||
})
|
||||
const storage = require('./storage')
|
||||
|
||||
const upload = multer({ storage })
|
||||
const api = express.Router()
|
||||
|
|
|
@ -1,62 +1,43 @@
|
|||
const fs = require('fs')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const crypto = require('crypto')
|
||||
const mkdirp = require('mkdirp')
|
||||
const sharp = require('sharp')
|
||||
const consola = require('consola')
|
||||
const config = require('../config')
|
||||
|
||||
function getDestination(req, file, cb) {
|
||||
cb(null, os.tmpdir())
|
||||
}
|
||||
|
||||
function DiskStorage(opts) {
|
||||
if (typeof opts.destination === 'string') {
|
||||
mkdirp.sync(opts.destination)
|
||||
this.getDestination = function ($0, $1, cb) { cb(null, opts.destination) }
|
||||
} else {
|
||||
this.getDestination = (opts.destination || getDestination)
|
||||
}
|
||||
}
|
||||
|
||||
DiskStorage.prototype._handleFile = function _handleFile(req, file, cb) {
|
||||
const that = this
|
||||
that.getDestination(req, file, function (err, destination) {
|
||||
if (err) return cb(err)
|
||||
mkdirp.sync(config.upload_path + '/thumb')
|
||||
|
||||
const DiskStorage = {
|
||||
_handleFile(req, file, cb) {
|
||||
const filename = crypto.randomBytes(16).toString('hex') + '.jpg'
|
||||
const finalPath = path.join(destination, filename)
|
||||
const thumbPath = path.join(destination, 'thumb', filename)
|
||||
const finalPath = path.resolve(config.upload_path, filename)
|
||||
const thumbPath = path.resolve(config.upload_path, 'thumb', filename)
|
||||
const outStream = fs.createWriteStream(finalPath)
|
||||
const thumbStream = fs.createWriteStream(thumbPath)
|
||||
const resizer = sharp().resize(800).jpeg({ quality: 90 })
|
||||
const thumbnailer = sharp().resize(400).jpeg({ quality: 90 })
|
||||
|
||||
file.stream.pipe(thumbnailer).pipe(thumbStream)
|
||||
thumbStream.on('error', e => console.log('thumbStream error ', e))
|
||||
thumbStream.on('error', e => consola.error('thumbStream error ', e))
|
||||
|
||||
file.stream.pipe(resizer).pipe(outStream)
|
||||
outStream.on('error', cb)
|
||||
outStream.on('finish', function () {
|
||||
cb(null, {
|
||||
destination,
|
||||
destination: config.upload_path,
|
||||
filename,
|
||||
path: finalPath,
|
||||
size: outStream.bytesWritten
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
_removeFile(req, file, cb) {
|
||||
delete file.destination
|
||||
delete file.filename
|
||||
delete file.path
|
||||
fs.unlink(path, cb)
|
||||
}
|
||||
}
|
||||
|
||||
DiskStorage.prototype._removeFile = function _removeFile(req, file, cb) {
|
||||
let path = file.path
|
||||
|
||||
delete file.destination
|
||||
delete file.filename
|
||||
delete file.path
|
||||
|
||||
fs.unlink(path, cb)
|
||||
}
|
||||
|
||||
module.exports = function (opts) {
|
||||
return new DiskStorage(opts)
|
||||
}
|
||||
module.exports = DiskStorage
|
||||
|
|
|
@ -3,7 +3,7 @@ p Dove: #{event.place.name} - #{event.place.address}
|
|||
p Quando: #{datetime(event.start_datetime)}
|
||||
br
|
||||
if event.image_path
|
||||
<img style="width: 100%" src="#{config.apiurl}/uploads/#{event.image_path}" />
|
||||
<img style="width: 100%" src="#{config.apiurl}/media/#{event.image_path}" />
|
||||
p #{event.description}
|
||||
|
||||
each tag in event.tags
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
p= t('mail.recover')
|
||||
p= t('email.recover')
|
||||
|
||||
<a href="#{config.baseurl}/recover/#{user.recover_code}">#{t('press here')}</a>
|
||||
<a href="#{config.baseurl}/recover/#{user.recover_code}">#{t('email.press_here')}</a>
|
|
@ -26,7 +26,7 @@ async function start() {
|
|||
|
||||
// Give nuxt middleware to express
|
||||
app.use(morgan('dev'))
|
||||
app.use('/media/', express.static(path.join(__dirname, '..', 'uploads')))
|
||||
app.use('/media/', express.static(config.upload_path))
|
||||
app.use(nuxt.render)
|
||||
|
||||
// Listen the server
|
||||
|
|
|
@ -16,7 +16,7 @@ rss(version='2.0')
|
|||
| <h4>#{event.title}</h4>
|
||||
| <strong>#{event.place.name} - #{event.place.address}</strong>
|
||||
| #{moment(event.start_datetime).format("dddd, D MMMM HH:mm")}<br/>
|
||||
| <img src="#{config.apiurl}/../uploads/#{event.image_path}"/>
|
||||
| <img src="#{config.apiurl}/media/#{event.image_path}"/>
|
||||
| <pre>!{event.description}</pre>
|
||||
| ]]>
|
||||
pubDate= new Date(event.createdAt).toUTCString()
|
||||
|
|
Loading…
Reference in a new issue