Bombabillo is a non-web client for the terminal, supporting Gopher, Gemini and much more. https://bombadillo.colorfield.space
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
bombadillo/local/local.go

105 lines
2.5 KiB

/*
* Copyright (C) 2022 Brian Evans
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package local
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"
)
func Open(address string) (string, []string, error) {
links := make([]string, 0, 10)
if !pathExists(address) {
return "", links, fmt.Errorf("Invalid system path: %s", address)
}
file, err := os.Open(address)
if err != nil {
return "", links, err
}
defer file.Close()
if pathIsDir(address) {
offset := 1
fileList, err := file.Readdir(0)
if err != nil {
return "", links, err
}
var out strings.Builder
out.WriteString(fmt.Sprintf("Current directory: %s\n\n", address))
// Handle 'addres/..' display
offset = 2
upFp := filepath.Join(address, "..")
upOneLevel, _ := filepath.Abs(upFp)
info, err := os.Stat(upOneLevel)
if err == nil {
out.WriteString("[1] ")
out.WriteString(fmt.Sprintf("%-12s ", info.Mode().String()))
out.WriteString("../\n")
links = append(links, upOneLevel)
}
// Sort the directory contents alphabetically
sort.Slice(fileList, func(i, j int) bool {
return fileList[i].Name() < fileList[j].Name()
})
// Handle each item in the directory
for i, obj := range fileList {
linkNum := fmt.Sprintf("[%d]", i+offset)
out.WriteString(fmt.Sprintf("%-5s ", linkNum))
out.WriteString(fmt.Sprintf("%-12s ", obj.Mode().String()))
out.WriteString(obj.Name())
if obj.IsDir() {
out.WriteString("/")
}
out.WriteString("\n")
fp := filepath.Join(address, obj.Name())
links = append(links, fp)
}
return out.String(), links, nil
}
bytes, err := ioutil.ReadAll(file)
if err != nil {
return "", links, err
}
return string(bytes), links, nil
}
func pathExists(p string) bool {
exists := true
if _, err := os.Stat(p); os.IsNotExist(err) {
exists = false
}
return exists
}
func pathIsDir(p string) bool {
info, err := os.Stat(p)
if err != nil {
return false
}
return info.IsDir()
}