mirror of
https://github.com/rwinkhart/libmutton.git
synced 2026-09-01 22:57:25 -04:00
Implement synchronized renaming
This commit is contained in:
@@ -1,10 +1,5 @@
|
|||||||
package backend
|
package backend
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetOldEntryData decrypts and returns old entry data (with all required lines present)
|
// GetOldEntryData decrypts and returns old entry data (with all required lines present)
|
||||||
func GetOldEntryData(targetLocation string, field int) []string {
|
func GetOldEntryData(targetLocation string, field int) []string {
|
||||||
// ensure targetLocation exists
|
// ensure targetLocation exists
|
||||||
@@ -21,25 +16,6 @@ func GetOldEntryData(targetLocation string, field int) []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename renames oldLocation to newLocation
|
|
||||||
func Rename(oldLocation, newLocation string) {
|
|
||||||
// ensure newLocation does not exist
|
|
||||||
_, isAccessible := TargetIsFile(newLocation, false, 0)
|
|
||||||
if isAccessible {
|
|
||||||
fmt.Println(AnsiError + "\"" + newLocation + "\" already exists" + AnsiReset)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// rename oldLocation to newLocation
|
|
||||||
err := os.Rename(oldLocation, newLocation)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(AnsiError + "Failed to rename - does the target containing directory exists?" + AnsiReset)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO implement synced renaming
|
|
||||||
Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnsureSliceLength ensures slice is long enough to contain the specified index
|
// EnsureSliceLength ensures slice is long enough to contain the specified index
|
||||||
func EnsureSliceLength(slice []string, index int) []string {
|
func EnsureSliceLength(slice []string, index int) []string {
|
||||||
for len(slice) <= index {
|
for len(slice) <= index {
|
||||||
|
|||||||
+55
-12
@@ -3,12 +3,13 @@ package sync
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/rwinkhart/MUTN/src/backend"
|
"github.com/rwinkhart/MUTN/src/backend"
|
||||||
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// getModTimes returns a list of all entry modification times
|
||||||
func getModTimes(entryList []string) []int64 {
|
func getModTimes(entryList []string) []int64 {
|
||||||
// get a list of all entry modification times
|
|
||||||
var modList []int64
|
var modList []int64
|
||||||
for _, file := range entryList {
|
for _, file := range entryList {
|
||||||
modTime, _ := os.Stat(backend.TargetLocationFormat(file))
|
modTime, _ := os.Stat(backend.TargetLocationFormat(file))
|
||||||
@@ -18,6 +19,53 @@ func getModTimes(entryList []string) []int64 {
|
|||||||
return modList
|
return modList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// genDeviceIDList returns a pointer to a slice of all registered device IDs
|
||||||
|
func genDeviceIDList() *[]fs.DirEntry {
|
||||||
|
// create a slice of all registered devices
|
||||||
|
deviceIDList, err := os.ReadDir(backend.ConfigDir + backend.PathSeparator + "devices")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(backend.AnsiError + "Failed to read the devices directory: " + err.Error() + backend.AnsiReset)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return &deviceIDList
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rename renames oldLocation to newLocation
|
||||||
|
// if running on the client, also calls the server to rename the entry and add the old entry name to the deletions list
|
||||||
|
func Rename(oldLocationIncomplete, newLocationIncomplete string, onServer bool) {
|
||||||
|
// get full paths for both locations
|
||||||
|
oldLocation := backend.TargetLocationFormat(oldLocationIncomplete)
|
||||||
|
newLocation := backend.TargetLocationFormat(newLocationIncomplete)
|
||||||
|
|
||||||
|
// ensure oldLocation exists
|
||||||
|
backend.TargetIsFile(oldLocation, true, 0)
|
||||||
|
|
||||||
|
// ensure newLocation does not exist
|
||||||
|
_, isAccessible := backend.TargetIsFile(newLocation, false, 0)
|
||||||
|
if isAccessible {
|
||||||
|
fmt.Println(backend.AnsiError + "\"" + newLocation + "\" already exists" + backend.AnsiReset)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// rename oldLocation to newLocation
|
||||||
|
err := os.Rename(oldLocation, newLocation)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(backend.AnsiError + "Failed to rename - does the target containing directory exist?" + backend.AnsiReset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// call server to complete rename
|
||||||
|
if !onServer {
|
||||||
|
deviceIDList := genDeviceIDList()
|
||||||
|
if len(*deviceIDList) > 0 { // ensure a device ID exists (online mode)
|
||||||
|
GetSSHOutput("libmuttonserver rename",
|
||||||
|
(*deviceIDList)[0].Name()+"\n"+
|
||||||
|
strings.ReplaceAll(oldLocationIncomplete, backend.PathSeparator, "\x1d")+"\n"+
|
||||||
|
strings.ReplaceAll(newLocationIncomplete, backend.PathSeparator, "\x1d"), false)
|
||||||
|
}
|
||||||
|
backend.Exit(0) // do not exit program on server, as fallthrough is used to add the old entry name to the deletions list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ShearLocal removes the target file or directory from the local system
|
// ShearLocal removes the target file or directory from the local system
|
||||||
// returns: deviceID (on client), for use in ShearRemoteFromClient
|
// returns: deviceID (on client), for use in ShearRemoteFromClient
|
||||||
// if the local system is a server, it will also add the target to the deletions list for all clients (except the requesting client)
|
// if the local system is a server, it will also add the target to the deletions list for all clients (except the requesting client)
|
||||||
@@ -29,18 +77,13 @@ func ShearLocal(targetLocationIncomplete, clientDeviceID string) string {
|
|||||||
onServer = true
|
onServer = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a slice of all registered devices
|
deviceIDList := genDeviceIDList()
|
||||||
deviceIDList, err := os.ReadDir(backend.ConfigDir + backend.PathSeparator + "devices")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(backend.AnsiError + "Failed to read the devices directory: " + err.Error() + backend.AnsiReset)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the sheared target (incomplete, vanity) to the deletions list (if running on a server)
|
// add the sheared target (incomplete, vanity) to the deletions list (if running on a server)
|
||||||
if onServer {
|
if onServer {
|
||||||
for _, device := range deviceIDList {
|
for _, device := range *deviceIDList {
|
||||||
if device.Name() != clientDeviceID {
|
if device.Name() != clientDeviceID {
|
||||||
_, err = os.Create(backend.ConfigDir + backend.PathSeparator + "deletions" + backend.PathSeparator + device.Name() + "\x1e" + strings.ReplaceAll(targetLocationIncomplete, "/", "\x1d"))
|
_, err := os.Create(backend.ConfigDir + backend.PathSeparator + "deletions" + backend.PathSeparator + device.Name() + "\x1e" + strings.ReplaceAll(targetLocationIncomplete, "/", "\x1d"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// do not print error as there is currently no way of seeing server-side errors
|
// do not print error as there is currently no way of seeing server-side errors
|
||||||
// failure to add the target to the deletions list will exit the program and result in a client re-uploading the target (non-critical)
|
// failure to add the target to the deletions list will exit the program and result in a client re-uploading the target (non-critical)
|
||||||
@@ -55,14 +98,14 @@ func ShearLocal(targetLocationIncomplete, clientDeviceID string) string {
|
|||||||
if !onServer { // error if target does not exist on client, needed because os.RemoveAll does not return an error if target does not exist
|
if !onServer { // error if target does not exist on client, needed because os.RemoveAll does not return an error if target does not exist
|
||||||
backend.TargetIsFile(targetLocationComplete, true, 0)
|
backend.TargetIsFile(targetLocationComplete, true, 0)
|
||||||
}
|
}
|
||||||
err = os.RemoveAll(targetLocationComplete)
|
err := os.RemoveAll(targetLocationComplete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(backend.AnsiError + "Failed to remove local target: " + err.Error() + backend.AnsiReset)
|
fmt.Println(backend.AnsiError + "Failed to remove local target: " + err.Error() + backend.AnsiReset)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !onServer && len(deviceIDList) > 0 { // return the device ID if running on the client and a device ID exists (online mode)
|
if !onServer && len(*deviceIDList) > 0 { // return the device ID if running on the client and a device ID exists (online mode)
|
||||||
return deviceIDList[0].Name()
|
return (*deviceIDList)[0].Name()
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user