updaeted a lot`

This commit is contained in:
Graham Steffaniak 2023-07-12 21:23:29 -05:00
parent 54328654a2
commit 5806060775
7 changed files with 162 additions and 122 deletions

2
.gitignore vendored
View File

@ -6,7 +6,7 @@ rice-box.go
/filebrowser
/filebrowser.exe
/dist
/src/backend/vendor/*
/src/backend/vendor
.DS_Store
node_modules

View File

@ -1,7 +1,8 @@
FROM node:14.21-slim as nbuild
FROM node:slim as nbuild
WORKDIR /app
COPY ./src/frontend ./
COPY ./src/frontend/package*.json ./
RUN npm i
COPY ./src/frontend/ ./
RUN npm run build
FROM golang:alpine as base

View File

@ -8,12 +8,17 @@ import (
var searchHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
response := []map[string]interface{}{}
query := r.URL.Query().Get("query")
files, dirs := search.SearchAllIndexes(query, r.URL.Path)
for _,v := range(files){
response = append(response, map[string]interface{}{
files, dirs, fileTypes := search.SearchAllIndexes(query, r.URL.Path)
for _,path := range(files){
f := fileTypes[path]
responseObj := map[string]interface{}{
"dir" : false,
"path": v,
})
"path" : path,
}
for _,filterType := range(search.FilterableTypes) {
if f[filterType] { responseObj[filterType] = f[filterType] }
}
response = append(response,responseObj)
}
for _,v := range(dirs){
response = append(response, map[string]interface{}{

View File

@ -11,6 +11,8 @@ var documentTypes = []string{
".word",
".pdf",
".txt",
".doc",
".docx",
}
var compressedFile = []string{
@ -45,7 +47,6 @@ func ParseSearch(value string) *searchOptions {
if len(filterType) == 1 {
continue
}
switch filterType[1] {
case "image":
opts.Conditions["image"] = true
@ -55,8 +56,8 @@ func ParseSearch(value string) *searchOptions {
opts.Conditions["video"] = true
case "doc":
opts.Conditions["doc"] = true
case "zip":
opts.Conditions["zip"] = true
case "archive":
opts.Conditions["archive"] = true
}
}

View File

@ -13,7 +13,8 @@ import (
var (
rootPath string = "/srv"
indexes map[string][]string
indexes = map[string][]string{}
FilterableTypes = []string{"audio","image","video","doc","archive"}
mutex sync.RWMutex
lastIndexed time.Time
)
@ -21,6 +22,8 @@ var (
func InitializeIndex(intervalMinutes uint32) {
// Initialize the indexes map
indexes = make(map[string][]string)
indexes["dirs"] = []string{}
indexes["files"] = []string{}
var numFiles, numDirs int
log.Println("Indexing files...")
lastIndexedStart := time.Now()
@ -79,78 +82,80 @@ func indexFiles(path string, numFiles *int, numDirs *int) (int, int, error) {
for _, file := range files {
if file.IsDir() {
*numDirs++
indexFiles(path+"/"+file.Name(), numFiles, numDirs)
}
addToIndex(path, file.Name(), true)
indexFiles(path+"/"+file.Name(), numFiles, numDirs) // recursive
} else {
*numFiles++
addToIndex(path, file.Name())
addToIndex(path, file.Name(), false)
}
}
return *numFiles, *numDirs, nil
}
func addToIndex(path string, fileName string) {
func addToIndex(path string, fileName string, isDir bool) {
mutex.Lock()
defer mutex.Unlock()
path = strings.TrimPrefix(path, rootPath+"/")
path = strings.TrimSuffix(path, "/")
adjustedPath := path + "/" + fileName
if path == rootPath {
path = "/"
adjustedPath = fileName
}
info, exists := indexes[path]
if !exists {
info = []string{}
if isDir {
indexes["dirs"] = append(indexes["dirs"], adjustedPath)
}else{
indexes["files"] = append(indexes["files"], adjustedPath)
}
info = append(info, fileName)
indexes[path] = info
}
func SearchAllIndexes(search string, scope string) ([]string, []string) {
func SearchAllIndexes(search string, scope string) ([]string, []string, map[string]map[string]bool) {
searchOptions := ParseSearch(search)
mutex.RLock()
defer mutex.RUnlock()
fileListTypes := make(map[string]map[string]bool)
var matchingFiles []string
var matchingDirs []string
maximum := 100
count := 0
maximum := 125
for _, searchTerm := range searchOptions.Terms {
if searchTerm == "" {
continue
}
count := 0
// Iterate over the indexes
for dirName, v := range indexes {
for _, dirName := range indexes["dirs"] {
if count > maximum {
break
}
searchItems := v
// Iterate over the path names
for _, pathName := range searchItems {
if count > maximum {
break
}
if dirName != "/" {
pathName = dirName + "/" + pathName
}
// Check if the path name contains the search term
if !containsSearchTerm(pathName, searchTerm, searchOptions.Conditions) {
continue
}
pathName = scopedPathNameFilter(pathName, scope)
if pathName == "" {
continue
}
count++
matchingFiles = append(matchingFiles, pathName)
}
// Check if the path name contains the search term
if !containsSearchTerm(dirName, searchTerm, searchOptions.Conditions) {
continue
}
pathName := scopedPathNameFilter(dirName, scope)
if pathName == "" {
continue
}
matches, _ := containsSearchTerm(pathName, searchTerm, searchOptions.Conditions)
if !matches {
continue
}
count++
matchingDirs = append(matchingDirs, pathName)
}
count = 0
for _, fileName := range indexes["files"] {
if count > maximum {
break
}
pathName := scopedPathNameFilter(fileName, scope)
if pathName == "" {
continue
}
// Check if the path name contains the search term
matches, fileType := containsSearchTerm(pathName, searchTerm, searchOptions.Conditions)
if !matches {
continue
}
matchingFiles = append(matchingFiles, pathName)
fileListTypes[pathName] = fileType
count++
}
}
// Sort the strings based on the number of elements after splitting by "/"
sort.Slice(matchingFiles, func(i, j int) bool {
@ -164,7 +169,7 @@ func SearchAllIndexes(search string, scope string) ([]string, []string) {
parts2 := strings.Split(matchingDirs[j], "/")
return len(parts1) < len(parts2)
})
return matchingFiles, matchingDirs
return matchingFiles, matchingDirs, fileListTypes
}
func scopedPathNameFilter(pathName string, scope string) string {
@ -177,51 +182,51 @@ func scopedPathNameFilter(pathName string, scope string) string {
return pathName
}
func containsSearchTerm(pathName string, searchTerm string, conditions map[string]bool) bool {
func containsSearchTerm(pathName string, searchTerm string, conditions map[string]bool) (bool, map[string]bool) {
path := getLastPathComponent(pathName)
fileTypes := map[string]bool{}
matchesCondition := false
extension := filepath.Ext(strings.ToLower(path))
mimetype := mime.TypeByExtension(extension)
filterTypes := FilterableTypes
fileTypes["audio"] = strings.HasPrefix(mimetype, "audio")
fileTypes["image"] = strings.HasPrefix(mimetype, "image")
fileTypes["video"] = strings.HasPrefix(mimetype, "video")
fileTypes["doc"] = isDoc(extension)
fileTypes["archive"] = isArchive(extension)
anyFilter := false
for _,t := range(filterTypes){
if conditions[t] {
anyFilter = true
matchesCondition = fileTypes[t]
}
}
if !anyFilter {
matchesCondition = true
}
if !conditions["exact"] {
path = strings.ToLower(path)
searchTerm = strings.ToLower(searchTerm)
}
matchesCondition := true
if conditions["audio"] {
extension := filepath.Ext(path)
mimetype := mime.TypeByExtension(extension)
matchesCondition = strings.HasPrefix(mimetype, "audio")
return strings.Contains(path, searchTerm) && matchesCondition, fileTypes
}
if conditions["video"] {
extension := filepath.Ext(path)
mimetype := mime.TypeByExtension(extension)
matchesCondition = strings.HasPrefix(mimetype, "video")
}
if conditions["image"] {
extension := filepath.Ext(path)
mimetype := mime.TypeByExtension(extension)
matchesCondition = strings.HasPrefix(mimetype, "image")
}
if conditions["doc"] {
extension := filepath.Ext(path)
func isDoc(extension string) bool {
for _, typefile := range documentTypes {
if extension == typefile {
matchesCondition = true
continue
} else {
matchesCondition = false
return true
}
}
return false
}
if conditions["zip"] {
extension := filepath.Ext(path)
func isArchive(extension string) bool {
for _, typefile := range compressedFile {
if extension == typefile {
matchesCondition = true
continue
} else {
matchesCondition = false
return true
}
}
}
return strings.Contains(path, searchTerm) && matchesCondition
return false
}
func getLastPathComponent(path string) string {

View File

@ -24,7 +24,9 @@
</div>
<div id="result" ref="result">
<div>
<div id="result-list">
<br>
<br>
<template v-if="isEmpty">
<p>{{ text }}</p>
@ -48,11 +50,16 @@
</template>
</template>
<ul v-show="filteredResults.length > 0">
<li v-for="(s, k) in filteredResults" :key="k">
<router-link @click.native="close" :to="s.url">
<i v-if="s.dir" class="material-icons">folder</i>
<i v-else class="material-icons">insert_drive_file</i>
<span>./{{ s.path }}</span>
<div>Searching Scope : {{ path }}</div>
<li v-for="(s, k) in filteredResults" :key="k" @click="navigate(s.url,$event)" style="cursor: pointer;">
<router-link :to="s.url">
<i v-if="s.dir" class="material-icons folder-icons"> folder </i>
<i v-else-if="s.audio" class="material-icons audio-icons"> volume_up </i>
<i v-else-if="s.image" class="material-icons image-icons"> photo </i>
<i v-else-if="s.video" class="material-icons video-icons"> movie </i>
<i v-else-if="s.archive" class="material-icons archive-icons"> archive </i>
<i v-else class="material-icons file-icons"> insert_drive_file </i>
{{ s.path }}
</router-link>
</li>
</ul>
@ -92,7 +99,6 @@ export default {
watch: {
show(val, old) {
this.active = val === "search";
if (old === "search" && !this.active) {
if (this.reload) {
this.setReload(true);
@ -155,8 +161,13 @@ export default {
close(event) {
event.stopPropagation();
event.preventDefault();
console.log("closing")
this.closeHovers();
},
navigate(url, event) {
this.close(event); // pass the event object to the close method
this.$router.push(url);
},
keyup(event) {
if (event.keyCode === 27) {
this.close(event);

View File

@ -82,7 +82,7 @@ header .menu-button {
}
#search #input {
background-color: #f5f5f5;
background-color: rgba(100, 100, 100, 0.2);
display: flex;
height: 100%;
padding: 0em 0.75em;
@ -93,9 +93,9 @@ header .menu-button {
}
#search.active #input {
border-bottom: 1px solid rgba(0, 0, 0, 0.075);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
background-color: #fff;
border-bottom: 3px solid rgba(0, 0, 0, 0.075);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(6px);
height: 4em;
}
@ -103,11 +103,6 @@ header .menu-button {
border-radius: 0 !important;
}
#search.active i,
#search.active input {
color: #212121;
}
#search #input>.action,
#search #input>i {
margin-right: 0.3em;
@ -121,20 +116,35 @@ header .menu-button {
padding: 0;
}
#result-list {
width: 60em;
max-width: 100%;
padding: 0.5em;
overflow-x: hidden;
overflow-y: auto;
}
#search #result {
visibility: visible;
max-height: none;
background-color: #f8f8f8;
overflow: hidden;
background: white;
display: flex;
top: -4em;
flex-direction: column;
align-items: center;
text-align: left;
padding: 0;
color: rgba(0, 0, 0, 0.6);
height: 0;
transition: .1s ease height, .1s ease padding;
overflow-x: hidden;
overflow-y: auto;
transition: .2s ease height, .2s ease padding;
z-index: 1;
}
@media screen and (min-width: 800px) {
#search #result {
background: linear-gradient(to right, white 15%,lightgray 25%,lightgray 75%,white 85%);
}
}
body.rtl #search #result {
direction: ltr;
}
@ -156,12 +166,12 @@ body.rtl #search #result ul>* {
#search.active #result {
padding: .5em;
height: calc(100% - 4em);
height: 100%
}
#search ul {
margin-top: 1em;
padding: 0;
margin: 0;
list-style: none;
}
@ -169,11 +179,6 @@ body.rtl #search #result ul>* {
margin-bottom: .5em;
}
#search #result>div {
max-width: 45em;
margin: 0 auto;
}
#search #result #renew {
width: 100%;
text-align: center;
@ -186,8 +191,20 @@ body.rtl #search #result ul>* {
display: block;
}
#search.active #result i {
color: #ccc;
.folder-icons {
color: var(--icon-blue);
}
.video-icons {
color: lightskyblue;
}
.image-icons {
color: lightcoral;
}
.archive-icons {
color: tan;
}
.audio-icons {
color: plum;
}
#search.active #result>p>i {