feat: Distinguish symlinks (#3)
parent
847d870782
commit
a4b607d5a0
|
@ -34,6 +34,8 @@ type FileInfo struct {
|
|||
ModTime time.Time `json:"modified"`
|
||||
Mode os.FileMode `json:"mode"`
|
||||
IsDir bool `json:"isDir"`
|
||||
IsSymlink bool `json:"isSymlink"`
|
||||
Link string `json:"link"`
|
||||
Type string `json:"type"`
|
||||
Subtitles []string `json:"subtitles,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
|
@ -254,13 +256,23 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
|||
continue
|
||||
}
|
||||
|
||||
if IsSymlink(f.Mode()) {
|
||||
isSymlink := IsSymlink(f.Mode())
|
||||
symLink := ""
|
||||
if isSymlink {
|
||||
// It's a symbolic link. We try to follow it. If it doesn't work,
|
||||
// we stay with the link information instead of the target's.
|
||||
info, err := i.Fs.Stat(fPath)
|
||||
if err == nil {
|
||||
f = info
|
||||
}
|
||||
|
||||
// Try to read the link's target
|
||||
if lsf, ok := i.Fs.(afero.LinkReader); ok {
|
||||
link, err := lsf.ReadlinkIfPossible(fPath)
|
||||
if err == nil {
|
||||
symLink = link
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file := &FileInfo{
|
||||
|
@ -270,6 +282,8 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
|||
ModTime: f.ModTime(),
|
||||
Mode: f.Mode(),
|
||||
IsDir: f.IsDir(),
|
||||
IsSymlink: isSymlink,
|
||||
Link: symLink,
|
||||
Extension: filepath.Ext(name),
|
||||
Path: fPath,
|
||||
}
|
||||
|
|
|
@ -104,6 +104,9 @@ nav > div {
|
|||
#listing.list .item.header {
|
||||
background: var(--background);
|
||||
}
|
||||
#listing .item .symlink-icon {
|
||||
color: var(--surfacePrimary);
|
||||
}
|
||||
|
||||
.message {
|
||||
color: var(--textPrimary);
|
||||
|
|
|
@ -17,11 +17,23 @@
|
|||
v-if="readOnly == undefined && type === 'image' && isThumbsEnabled"
|
||||
v-lazy="thumbnailUrl"
|
||||
/>
|
||||
<i v-else class="material-icons">{{ icon }}</i>
|
||||
<template v-else>
|
||||
<i class="material-icons">{{ icon }}</i>
|
||||
<i
|
||||
v-if="isSymlink"
|
||||
class="material-icons symlink-icon"
|
||||
:class="{ dir: isDir, file: !isDir }"
|
||||
>
|
||||
link
|
||||
</i>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="name">{{ name }}</p>
|
||||
<p v-if="isSymlink && link !== ''" class="name">
|
||||
{{ name }} → {{ link }}
|
||||
</p>
|
||||
<p v-else class="name">{{ name }}</p>
|
||||
|
||||
<p v-if="isDir" class="size" data-order="-1">—</p>
|
||||
<p v-else class="size" :data-order="humanSize()">{{ humanSize() }}</p>
|
||||
|
@ -50,6 +62,8 @@ export default {
|
|||
},
|
||||
props: [
|
||||
"name",
|
||||
"link",
|
||||
"isSymlink",
|
||||
"isDir",
|
||||
"url",
|
||||
"type",
|
||||
|
|
|
@ -76,14 +76,14 @@ export default {
|
|||
uri = uri.replace("//", "/");
|
||||
|
||||
try {
|
||||
this.loading = true
|
||||
this.loading = true;
|
||||
await api.archive(uri, this.name, format, ...items);
|
||||
|
||||
this.$store.commit("setReload", true);
|
||||
} catch (e) {
|
||||
this.$showError(e);
|
||||
} finally {
|
||||
this.loading = false
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
this.$store.commit("closeHovers");
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
|
||||
#listing.mosaic .item div:first-of-type {
|
||||
width: 5em;
|
||||
position: inherit;
|
||||
}
|
||||
|
||||
#listing.mosaic .item div:last-of-type {
|
||||
|
@ -240,3 +241,32 @@
|
|||
#listing #multiple-selection i {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#listing .item .symlink-icon {
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#listing.mosaic .item .symlink-icon.dir {
|
||||
font-size: 1.5em;
|
||||
left: .45em;
|
||||
bottom: .45em;
|
||||
}
|
||||
|
||||
#listing.mosaic .item .symlink-icon.file {
|
||||
font-size: 1.5em;
|
||||
left: .65em;
|
||||
bottom: .2em;
|
||||
}
|
||||
|
||||
#listing.list .item .symlink-icon.dir {
|
||||
font-size: 1.2em;
|
||||
left: 1em;
|
||||
bottom: 1em;
|
||||
}
|
||||
|
||||
#listing.list .item .symlink-icon.file {
|
||||
font-size: 1.2em;
|
||||
left: 1.14em;
|
||||
bottom: .85em;
|
||||
}
|
|
@ -213,6 +213,8 @@
|
|||
:key="base64(item.name)"
|
||||
v-bind:index="item.index"
|
||||
v-bind:name="item.name"
|
||||
v-bind:isSymlink="item.isSymlink"
|
||||
v-bind:link="item.link"
|
||||
v-bind:isDir="item.isDir"
|
||||
v-bind:url="item.url"
|
||||
v-bind:modified="item.modified"
|
||||
|
@ -229,6 +231,8 @@
|
|||
:key="base64(item.name)"
|
||||
v-bind:index="item.index"
|
||||
v-bind:name="item.name"
|
||||
v-bind:isSymlink="item.isSymlink"
|
||||
v-bind:link="item.link"
|
||||
v-bind:isDir="item.isDir"
|
||||
v-bind:url="item.url"
|
||||
v-bind:modified="item.modified"
|
||||
|
|
2
go.mod
2
go.mod
|
@ -21,7 +21,7 @@ require (
|
|||
github.com/nwaples/rardecode v1.0.0 // indirect
|
||||
github.com/pelletier/go-toml v1.6.0
|
||||
github.com/pierrec/lz4 v0.0.0-20190131084431-473cd7ce01a1 // indirect
|
||||
github.com/spf13/afero v1.2.2
|
||||
github.com/spf13/afero v1.3.0
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5
|
||||
|
|
7
go.sum
7
go.sum
|
@ -114,6 +114,7 @@ github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
|
|||
github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
|
@ -159,7 +160,9 @@ github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t
|
|||
github.com/pierrec/lz4 v0.0.0-20190131084431-473cd7ce01a1 h1:0utzB5Mn6QyMzIeOn+oD7pjKQLjJwfM9bz6TkPPdxcw=
|
||||
github.com/pierrec/lz4 v0.0.0-20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
|
@ -184,6 +187,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO
|
|||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/afero v1.3.0 h1:Ysnmjh1Di8EaWaBv40CYR4IdaIsBc5996Gh1oZzCBKk=
|
||||
github.com/spf13/afero v1.3.0/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||
|
@ -201,6 +206,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
|
@ -229,6 +235,7 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf
|
|||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||
|
|
Loading…
Reference in New Issue