Fix ViewMode related bugs:
- The user will no longer lost their 'ViewMode' option after being updated in the settings.
- The console will not output errors due tot he scroll function when Mosaic mode is on.
Former-commit-id: 97aa6abdc8b864dc7a55dbf03a2e58895ea7613f [formerly ff9e6ff0898f32bd106b644b2e9002b5de45281c] [formerly 556cc12bd5ff1d91776c81f48dd1dceb8bb627b4 [formerly 51104c5ee7
]]
Former-commit-id: dd63b2b818a7bd4960a7243866d6b2829f4c03a8 [formerly 45855d70eaa9a2b060d3a89cb70388040ea8e6d9]
Former-commit-id: 6e0ebf10d7fe3e2c234abc9c0ffd447cfbdd7455
pull/726/head
parent
c716d126eb
commit
59a0daa293
|
@ -1,231 +1,231 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div id="breadcrumbs">
|
<div id="breadcrumbs">
|
||||||
<router-link to="/files/" :aria-label="$t('files.home')" :title="$t('files.home')">
|
<router-link to="/files/" :aria-label="$t('files.home')" :title="$t('files.home')">
|
||||||
<i class="material-icons">home</i>
|
<i class="material-icons">home</i>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<span v-for="link in breadcrumbs" :key="link.name">
|
<span v-for="link in breadcrumbs" :key="link.name">
|
||||||
<span class="chevron"><i class="material-icons">keyboard_arrow_right</i></span>
|
<span class="chevron"><i class="material-icons">keyboard_arrow_right</i></span>
|
||||||
<router-link :to="link.url">{{ link.name }}</router-link>
|
<router-link :to="link.url">{{ link.name }}</router-link>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="error">
|
<div v-if="error">
|
||||||
<not-found v-if="error.message === '404'"></not-found>
|
<not-found v-if="error.message === '404'"></not-found>
|
||||||
<forbidden v-else-if="error.message === '403'"></forbidden>
|
<forbidden v-else-if="error.message === '403'"></forbidden>
|
||||||
<internal-error v-else></internal-error>
|
<internal-error v-else></internal-error>
|
||||||
</div>
|
</div>
|
||||||
<editor v-else-if="isEditor"></editor>
|
<editor v-else-if="isEditor"></editor>
|
||||||
<listing :class="{ multiple }" v-else-if="isListing"></listing>
|
<listing :class="{ multiple }" v-else-if="isListing"></listing>
|
||||||
<preview v-else-if="isPreview"></preview>
|
<preview v-else-if="isPreview"></preview>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<h2 class="message">
|
<h2 class="message">
|
||||||
<span>{{ $t('files.loading') }}</span>
|
<span>{{ $t('files.loading') }}</span>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Forbidden from './errors/403'
|
import Forbidden from './errors/403'
|
||||||
import NotFound from './errors/404'
|
import NotFound from './errors/404'
|
||||||
import InternalError from './errors/500'
|
import InternalError from './errors/500'
|
||||||
import Preview from '@/components/files/Preview'
|
import Preview from '@/components/files/Preview'
|
||||||
import Listing from '@/components/files/Listing'
|
import Listing from '@/components/files/Listing'
|
||||||
import Editor from '@/components/files/Editor'
|
import Editor from '@/components/files/Editor'
|
||||||
import * as api from '@/utils/api'
|
import * as api from '@/utils/api'
|
||||||
import { mapGetters, mapState, mapMutations } from 'vuex'
|
import { mapGetters, mapState, mapMutations } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'files',
|
name: 'files',
|
||||||
components: {
|
components: {
|
||||||
Forbidden,
|
Forbidden,
|
||||||
NotFound,
|
NotFound,
|
||||||
InternalError,
|
InternalError,
|
||||||
Preview,
|
Preview,
|
||||||
Listing,
|
Listing,
|
||||||
Editor
|
Editor
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
'selectedCount'
|
'selectedCount'
|
||||||
]),
|
]),
|
||||||
...mapState([
|
...mapState([
|
||||||
'req',
|
'req',
|
||||||
'user',
|
'user',
|
||||||
'reload',
|
'reload',
|
||||||
'multiple',
|
'multiple',
|
||||||
'loading'
|
'loading'
|
||||||
]),
|
]),
|
||||||
isListing () {
|
isListing () {
|
||||||
return this.req.kind === 'listing' && !this.loading
|
return this.req.kind === 'listing' && !this.loading
|
||||||
},
|
},
|
||||||
isPreview () {
|
isPreview () {
|
||||||
return this.req.kind === 'preview' && !this.loading
|
return this.req.kind === 'preview' && !this.loading
|
||||||
},
|
},
|
||||||
isEditor () {
|
isEditor () {
|
||||||
return this.req.kind === 'editor' && !this.loading
|
return this.req.kind === 'editor' && !this.loading
|
||||||
},
|
},
|
||||||
breadcrumbs () {
|
breadcrumbs () {
|
||||||
let parts = this.$route.path.split('/')
|
let parts = this.$route.path.split('/')
|
||||||
|
|
||||||
if (parts[0] === '') {
|
if (parts[0] === '') {
|
||||||
parts.shift()
|
parts.shift()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parts[parts.length - 1] === '') {
|
if (parts[parts.length - 1] === '') {
|
||||||
parts.pop()
|
parts.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
let breadcrumbs = []
|
let breadcrumbs = []
|
||||||
|
|
||||||
for (let i = 0; i < parts.length; i++) {
|
for (let i = 0; i < parts.length; i++) {
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
breadcrumbs.push({ name: decodeURIComponent(parts[i]), url: '/' + parts[i] + '/' })
|
breadcrumbs.push({ name: decodeURIComponent(parts[i]), url: '/' + parts[i] + '/' })
|
||||||
} else {
|
} else {
|
||||||
breadcrumbs.push({ name: decodeURIComponent(parts[i]), url: breadcrumbs[i - 1].url + parts[i] + '/' })
|
breadcrumbs.push({ name: decodeURIComponent(parts[i]), url: breadcrumbs[i - 1].url + parts[i] + '/' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
breadcrumbs.shift()
|
breadcrumbs.shift()
|
||||||
|
|
||||||
if (breadcrumbs.length > 3) {
|
if (breadcrumbs.length > 3) {
|
||||||
while (breadcrumbs.length !== 4) {
|
while (breadcrumbs.length !== 4) {
|
||||||
breadcrumbs.shift()
|
breadcrumbs.shift()
|
||||||
}
|
}
|
||||||
|
|
||||||
breadcrumbs[0].name = '...'
|
breadcrumbs[0].name = '...'
|
||||||
}
|
}
|
||||||
|
|
||||||
return breadcrumbs
|
return breadcrumbs
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
error: null
|
error: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route': 'fetchData',
|
'$route': 'fetchData',
|
||||||
'reload': function () {
|
'reload': function () {
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
window.addEventListener('keydown', this.keyEvent)
|
window.addEventListener('keydown', this.keyEvent)
|
||||||
window.addEventListener('scroll', this.scroll)
|
window.addEventListener('scroll', this.scroll)
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
window.removeEventListener('keydown', this.keyEvent)
|
window.removeEventListener('keydown', this.keyEvent)
|
||||||
window.removeEventListener('scroll', this.scroll)
|
window.removeEventListener('scroll', this.scroll)
|
||||||
},
|
},
|
||||||
destroyed () {
|
destroyed () {
|
||||||
this.$store.commit('updateRequest', {})
|
this.$store.commit('updateRequest', {})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations([ 'setLoading' ]),
|
...mapMutations([ 'setLoading' ]),
|
||||||
fetchData () {
|
fetchData () {
|
||||||
// Reset view information.
|
// Reset view information.
|
||||||
this.$store.commit('setReload', false)
|
this.$store.commit('setReload', false)
|
||||||
this.$store.commit('resetSelected')
|
this.$store.commit('resetSelected')
|
||||||
this.$store.commit('multiple', false)
|
this.$store.commit('multiple', false)
|
||||||
this.$store.commit('closeHovers')
|
this.$store.commit('closeHovers')
|
||||||
|
|
||||||
// Set loading to true and reset the error.
|
// Set loading to true and reset the error.
|
||||||
this.setLoading(true)
|
this.setLoading(true)
|
||||||
this.error = null
|
this.error = null
|
||||||
|
|
||||||
let url = this.$route.path
|
let url = this.$route.path
|
||||||
if (url === '') url = '/'
|
if (url === '') url = '/'
|
||||||
if (url[0] !== '/') url = '/' + url
|
if (url[0] !== '/') url = '/' + url
|
||||||
|
|
||||||
api.fetch(url)
|
api.fetch(url)
|
||||||
.then((req) => {
|
.then((req) => {
|
||||||
if (!url.endsWith('/') && req.url.endsWith('/')) {
|
if (!url.endsWith('/') && req.url.endsWith('/')) {
|
||||||
window.history.replaceState(window.history.state, document.title, window.location.pathname + '/')
|
window.history.replaceState(window.history.state, document.title, window.location.pathname + '/')
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$store.commit('updateRequest', req)
|
this.$store.commit('updateRequest', req)
|
||||||
document.title = req.name
|
document.title = req.name
|
||||||
this.setLoading(false)
|
this.setLoading(false)
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
this.setLoading(false)
|
this.setLoading(false)
|
||||||
this.error = error
|
this.error = error
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
keyEvent (event) {
|
keyEvent (event) {
|
||||||
// Esc!
|
// Esc!
|
||||||
if (event.keyCode === 27) {
|
if (event.keyCode === 27) {
|
||||||
this.$store.commit('closeHovers')
|
this.$store.commit('closeHovers')
|
||||||
|
|
||||||
// If we're on a listing, unselect all
|
// If we're on a listing, unselect all
|
||||||
// files and folders.
|
// files and folders.
|
||||||
if (this.req.kind === 'listing') {
|
if (this.req.kind === 'listing') {
|
||||||
this.$store.commit('resetSelected')
|
this.$store.commit('resetSelected')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Del!
|
// Del!
|
||||||
if (event.keyCode === 46) {
|
if (event.keyCode === 46) {
|
||||||
if (this.req.kind === 'editor' ||
|
if (this.req.kind === 'editor' ||
|
||||||
this.$route.name !== 'Files' ||
|
this.$route.name !== 'Files' ||
|
||||||
this.loading ||
|
this.loading ||
|
||||||
!this.user.allowEdit ||
|
!this.user.allowEdit ||
|
||||||
(this.req.kind === 'listing' && this.selectedCount === 0)) return
|
(this.req.kind === 'listing' && this.selectedCount === 0)) return
|
||||||
|
|
||||||
this.$store.commit('showHover', 'delete')
|
this.$store.commit('showHover', 'delete')
|
||||||
}
|
}
|
||||||
|
|
||||||
// F1!
|
// F1!
|
||||||
if (event.keyCode === 112) {
|
if (event.keyCode === 112) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
this.$store.commit('showHover', 'help')
|
this.$store.commit('showHover', 'help')
|
||||||
}
|
}
|
||||||
|
|
||||||
// F2!
|
// F2!
|
||||||
if (event.keyCode === 113) {
|
if (event.keyCode === 113) {
|
||||||
if (this.req.kind === 'editor' ||
|
if (this.req.kind === 'editor' ||
|
||||||
this.$route.name !== 'Files' ||
|
this.$route.name !== 'Files' ||
|
||||||
this.loading ||
|
this.loading ||
|
||||||
!this.user.allowEdit ||
|
!this.user.allowEdit ||
|
||||||
(this.req.kind === 'listing' && this.selectedCount === 0) ||
|
(this.req.kind === 'listing' && this.selectedCount === 0) ||
|
||||||
(this.req.kind === 'listing' && this.selectedCount > 1)) return
|
(this.req.kind === 'listing' && this.selectedCount > 1)) return
|
||||||
|
|
||||||
this.$store.commit('showHover', 'rename')
|
this.$store.commit('showHover', 'rename')
|
||||||
}
|
}
|
||||||
|
|
||||||
// CTRL + S
|
// CTRL + S
|
||||||
if (event.ctrlKey || event.metaKey) {
|
if (event.ctrlKey || event.metaKey) {
|
||||||
if (String.fromCharCode(event.which).toLowerCase() === 's') {
|
if (String.fromCharCode(event.which).toLowerCase() === 's') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
if (this.req.kind !== 'editor') {
|
if (this.req.kind !== 'editor') {
|
||||||
document.getElementById('download-button').click()
|
document.getElementById('download-button').click()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scroll (event) {
|
scroll (event) {
|
||||||
if (this.req.kind !== 'listing' || this.$store.state.req.display === 'mosaic') return
|
if (this.req.kind !== 'listing' || this.$store.state.user.viewMode === 'mosaic') return
|
||||||
|
|
||||||
let top = 112 - window.scrollY
|
let top = 112 - window.scrollY
|
||||||
|
|
||||||
if (top < 64) {
|
if (top < 64) {
|
||||||
top = 64
|
top = 64
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelector('#listing.list .item.header').style.top = top + 'px'
|
document.querySelector('#listing.list .item.header').style.top = top + 'px'
|
||||||
},
|
},
|
||||||
openSidebar () {
|
openSidebar () {
|
||||||
this.$store.commit('showHover', 'sidebar')
|
this.$store.commit('showHover', 'sidebar')
|
||||||
},
|
},
|
||||||
openSearch () {
|
openSearch () {
|
||||||
this.$store.commit('showHover', 'search')
|
this.$store.commit('showHover', 'search')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -7,10 +7,21 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
|
<p>
|
||||||
|
<label for="username">{{ $t('settings.username') }}</label>
|
||||||
|
<input type="text" v-model="username" id="username">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<label for="password">{{ $t('settings.password') }}</label>
|
||||||
|
<input type="password" :placeholder="passwordPlaceholder" v-model="password" id="password">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<label for="scope">{{ $t('settings.scope') }}</label>
|
||||||
|
<input type="text" v-model="filesystem" id="scope">
|
||||||
|
</p>
|
||||||
|
|
||||||
<p><label for="username">{{ $t('settings.username') }}</label><input type="text" v-model="username" id="username"></p>
|
|
||||||
<p><label for="password">{{ $t('settings.password') }}</label><input type="password" :placeholder="passwordPlaceholder" v-model="password" id="password"></p>
|
|
||||||
<p><label for="scope">{{ $t('settings.scope') }}</label><input type="text" v-model="filesystem" id="scope"></p>
|
|
||||||
<p>
|
<p>
|
||||||
<label for="locale">{{ $t('settings.language') }}</label>
|
<label for="locale">{{ $t('settings.language') }}</label>
|
||||||
<languages id="locale" :selected.sync="locale"></languages>
|
<languages id="locale" :selected.sync="locale"></languages>
|
||||||
|
@ -91,6 +102,7 @@ export default {
|
||||||
components: { Languages },
|
components: { Languages },
|
||||||
data: () => {
|
data: () => {
|
||||||
return {
|
return {
|
||||||
|
originalUser: null,
|
||||||
id: 0,
|
id: 0,
|
||||||
admin: false,
|
admin: false,
|
||||||
allowNew: false,
|
allowNew: false,
|
||||||
|
@ -141,6 +153,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
getUser(user).then(user => {
|
getUser(user).then(user => {
|
||||||
|
this.originalUser = user
|
||||||
this.id = user.ID
|
this.id = user.ID
|
||||||
this.admin = user.admin
|
this.admin = user.admin
|
||||||
this.allowCommands = user.allowCommands
|
this.allowCommands = user.allowCommands
|
||||||
|
@ -242,23 +255,21 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
parseForm () {
|
parseForm () {
|
||||||
let user = {
|
let user = this.originalUser
|
||||||
ID: this.id,
|
user.username = this.username
|
||||||
username: this.username,
|
user.password = this.password
|
||||||
password: this.password,
|
user.lockPassword = this.lockPassword
|
||||||
lockPassword: this.lockPassword,
|
user.filesystem = this.filesystem
|
||||||
filesystem: this.filesystem,
|
user.admin = this.admin
|
||||||
admin: this.admin,
|
user.allowCommands = this.allowCommands
|
||||||
allowCommands: this.allowCommands,
|
user.allowNew = this.allowNew
|
||||||
allowNew: this.allowNew,
|
user.allowEdit = this.allowEdit
|
||||||
allowEdit: this.allowEdit,
|
user.allowPublish = this.allowPublish
|
||||||
allowPublish: this.allowPublish,
|
user.permissions = this.permissions
|
||||||
permissions: this.permissions,
|
user.css = this.css
|
||||||
css: this.css,
|
user.locale = this.locale
|
||||||
locale: this.locale,
|
user.commands = this.commands.split(' ')
|
||||||
commands: this.commands.split(' '),
|
user.rules = []
|
||||||
rules: []
|
|
||||||
}
|
|
||||||
|
|
||||||
let rules = this.rules.split('\n')
|
let rules = this.rules.split('\n')
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ var (
|
||||||
ErrEmptyScope = errors.New("scope is empty")
|
ErrEmptyScope = errors.New("scope is empty")
|
||||||
ErrWrongDataType = errors.New("wrong data type")
|
ErrWrongDataType = errors.New("wrong data type")
|
||||||
ErrInvalidUpdateField = errors.New("invalid field to update")
|
ErrInvalidUpdateField = errors.New("invalid field to update")
|
||||||
ErrInvalidOption = errors.New("Invalid option")
|
ErrInvalidOption = errors.New("invalid option")
|
||||||
)
|
)
|
||||||
|
|
||||||
// FileManager is a file manager instance. It should be creating using the
|
// FileManager is a file manager instance. It should be creating using the
|
||||||
|
|
17
http/auth.go
17
http/auth.go
|
@ -1,7 +1,6 @@
|
||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -14,22 +13,23 @@ import (
|
||||||
fm "github.com/hacdias/filemanager"
|
fm "github.com/hacdias/filemanager"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const reCaptchaAPI = "https://www.google.com/recaptcha/api/siteverify"
|
||||||
|
|
||||||
type cred struct {
|
type cred struct {
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Recaptcha string `json:"recaptcha"`
|
ReCaptcha string `json:"recaptcha"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// recaptcha checks the recaptcha code.
|
// reCaptcha checks the reCaptcha code.
|
||||||
func recaptcha(secret string, response string) (bool, error) {
|
func reCaptcha(secret string, response string) (bool, error) {
|
||||||
api := "https://www.google.com/recaptcha/api/siteverify"
|
|
||||||
|
|
||||||
body := url.Values{}
|
body := url.Values{}
|
||||||
body.Set("secret", secret)
|
body.Set("secret", secret)
|
||||||
body.Add("response", response)
|
body.Add("response", response)
|
||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
resp, err := client.Post(api, "application/x-www-form-urlencoded", bytes.NewBufferString(body.Encode()))
|
|
||||||
|
resp, err := client.Post(reCaptchaAPI, "application/x-www-form-urlencoded", strings.NewReader(body.Encode()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ func authHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, er
|
||||||
|
|
||||||
// If ReCaptcha is enabled, check the code.
|
// If ReCaptcha is enabled, check the code.
|
||||||
if len(c.ReCaptchaSecret) > 0 {
|
if len(c.ReCaptchaSecret) > 0 {
|
||||||
ok, err := recaptcha(c.ReCaptchaSecret, cred.Recaptcha)
|
ok, err := reCaptcha(c.ReCaptchaSecret, cred.ReCaptcha)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return http.StatusForbidden, err
|
return http.StatusForbidden, err
|
||||||
|
@ -179,6 +179,7 @@ func validateAuth(c *fm.Context, r *http.Request) (bool, *fm.User) {
|
||||||
keyFunc := func(token *jwt.Token) (interface{}, error) {
|
keyFunc := func(token *jwt.Token) (interface{}, error) {
|
||||||
return c.Key, nil
|
return c.Key, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var claims claims
|
var claims claims
|
||||||
token, err := request.ParseFromRequestWithClaims(r,
|
token, err := request.ParseFromRequestWithClaims(r,
|
||||||
extractor{},
|
extractor{},
|
||||||
|
|
|
@ -17,21 +17,13 @@ import (
|
||||||
// downloadHandler creates an archive in one of the supported formats (zip, tar,
|
// downloadHandler creates an archive in one of the supported formats (zip, tar,
|
||||||
// tar.gz or tar.bz2) and sends it to be downloaded.
|
// tar.gz or tar.bz2) and sends it to be downloaded.
|
||||||
func downloadHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
func downloadHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
query := r.URL.Query().Get("format")
|
|
||||||
|
|
||||||
// If the file isn't a directory, serve it using http.ServeFile. We display it
|
// If the file isn't a directory, serve it using http.ServeFile. We display it
|
||||||
// inline if it is requested.
|
// inline if it is requested.
|
||||||
if !c.File.IsDir {
|
if !c.File.IsDir {
|
||||||
if r.URL.Query().Get("inline") == "true" {
|
return downloadFileHandler(c, w, r)
|
||||||
w.Header().Set("Content-Disposition", "inline")
|
|
||||||
} else {
|
|
||||||
w.Header().Set("Content-Disposition", "attachment; filename=\""+c.File.Name+"\"")
|
|
||||||
}
|
|
||||||
|
|
||||||
http.ServeFile(w, r, c.File.Path)
|
|
||||||
return 0, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query := r.URL.Query().Get("format")
|
||||||
files := []string{}
|
files := []string{}
|
||||||
names := strings.Split(r.URL.Query().Get("files"), ",")
|
names := strings.Split(r.URL.Query().Get("files"), ",")
|
||||||
|
|
||||||
|
@ -111,3 +103,14 @@ func downloadHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
||||||
_, err = io.Copy(w, file)
|
_, err = io.Copy(w, file)
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func downloadFileHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
|
if r.URL.Query().Get("inline") == "true" {
|
||||||
|
w.Header().Set("Content-Disposition", "inline")
|
||||||
|
} else {
|
||||||
|
w.Header().Set("Content-Disposition", "attachment; filename=\""+c.File.Name+"\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
http.ServeFile(w, r, c.File.Path)
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
|
@ -160,6 +160,11 @@ func usersPostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
|
||||||
u.Rules = []*fm.Rule{}
|
u.Rules = []*fm.Rule{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the view mode is empty, initialize with the default one.
|
||||||
|
if u.ViewMode == "" {
|
||||||
|
u.ViewMode = c.DefaultUser.ViewMode
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize commands if not initialized.
|
// Initialize commands if not initialized.
|
||||||
if u.Commands == nil {
|
if u.Commands == nil {
|
||||||
u.Commands = []string{}
|
u.Commands = []string{}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
9536ea589ebfb34b4ccbf549776ff8b4c70d6dd6
|
|
Loading…
Reference in New Issue