2022-09-14 21:45:47 +00:00
/*
* Vento , a CLI inventory for your files .
* Copyright ( C ) 2022 Lux Aliaga
*
* 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 , either version 3 of the License , or
* ( at your option ) any later version .
*
* 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/>.
*
* /
2022-09-14 22:45:28 +00:00
use super ::common ;
2022-09-19 03:23:54 +00:00
use anyhow ::{ bail , Context , Result } ;
2022-09-17 08:44:25 +00:00
use colored ::Colorize ;
2022-09-17 21:33:40 +00:00
use size_format ::SizeFormatterBinary ;
2022-09-17 08:44:25 +00:00
use std ::io ::{ self , Write } ;
use std ::path ::{ Path , PathBuf } ;
use std ::{ fs , process } ;
2022-09-19 03:23:54 +00:00
pub fn init ( ) -> Result < ( ) > {
2022-09-17 08:44:25 +00:00
// Initializes Vento
2022-10-17 21:11:38 +00:00
let ventodir = & common ::env_config ( ) ? . vento_dir ;
2022-09-14 12:36:34 +00:00
2022-09-17 08:44:25 +00:00
if ventodir . is_dir ( ) {
// Checks if Vento has already been initialized and prompts the user if they want to initialize it again
2022-09-14 12:36:34 +00:00
let mut answer = String ::new ( ) ;
2022-10-01 20:38:14 +00:00
print! ( " ⚠️ {} Vento has already been initialized. Reinitializing will delete all files on the directory for Vento. Do you wish to proceed? (y/N) " , " WARNING: " . bold ( ) . red ( ) ) ;
2022-09-14 12:36:34 +00:00
let _ = io ::stdout ( ) . flush ( ) ;
2022-10-17 22:56:23 +00:00
io ::stdin ( ) . read_line ( & mut answer ) ? ;
2022-09-14 12:36:34 +00:00
match answer . as_str ( ) . trim ( ) {
2022-09-19 03:23:54 +00:00
" y " | " Y " = > fs ::remove_dir_all ( & ventodir ) ? ,
_ = > process ::exit ( 0 ) ,
2022-09-14 12:36:34 +00:00
} ;
} ;
2022-09-17 08:44:25 +00:00
2022-09-19 03:23:54 +00:00
create_slots ( ) ? ;
Ok ( ( ) )
2022-09-14 12:36:34 +00:00
}
2022-09-19 03:23:54 +00:00
pub fn list ( slot : & str , dir : & str ) -> Result < ( ) > {
2022-09-17 08:44:25 +00:00
// Lists files in inventory
2022-10-17 21:11:38 +00:00
let ventodir = & common ::env_config ( ) ? . vento_dir ;
2022-09-26 19:54:39 +00:00
if ! ventodir . is_dir ( ) {
2022-09-27 23:05:08 +00:00
// Detects if Vento hasn't been initialized and bails if so
2022-09-26 19:54:39 +00:00
bail! (
2022-09-27 22:16:18 +00:00
" {} " ,
2022-09-26 19:54:39 +00:00
" Vento not initialized. Run \" vento -i \" to initialize Vento. " . red ( )
) ;
}
2022-09-27 23:05:08 +00:00
let mut slotdir : PathBuf = match slot {
2022-10-17 21:11:38 +00:00
" active " | " a " = > common ::env_config ( ) ? . active_dir . clone ( ) ,
" inactive " | " i " = > common ::env_config ( ) ? . inactive_dir . clone ( ) ,
2022-09-27 23:05:08 +00:00
_ = > PathBuf ::new ( ) ,
} ;
2022-10-01 20:38:14 +00:00
if ! dir . is_empty ( ) {
2022-09-27 23:05:08 +00:00
// Detects if the directory argument is not empty, and if so appends the path provided to the slot directory variable
2022-09-18 03:27:31 +00:00
slotdir = [ & slotdir , & Path ::new ( dir ) . to_path_buf ( ) ] . iter ( ) . collect ( ) ;
}
if dir . to_string ( ) . contains ( " .. " ) {
2022-09-27 23:05:08 +00:00
// Basically preventing from listing anything out of bounds. ls and dir exist for that
2022-09-27 22:16:18 +00:00
bail! ( " {} " , " Cannot access parent. " . red ( ) ) ;
2022-09-18 03:27:31 +00:00
}
2022-09-27 23:05:08 +00:00
if ! slotdir . is_dir ( ) {
// Detects if the consulted slot or directory exists
2022-09-27 22:16:18 +00:00
bail! (
" {} " ,
2022-09-17 08:44:25 +00:00
format! (
2022-09-18 03:27:31 +00:00
" No such slot or directory. Valid slots are {} and {}. " ,
2022-09-26 19:54:39 +00:00
" active " . green ( ) . bold ( ) ,
" inactive " . blue ( ) . bold ( )
2022-09-17 08:44:25 +00:00
)
. red ( )
) ;
2022-09-27 23:05:08 +00:00
} ;
if fs ::read_dir ( & slotdir ) . unwrap ( ) . count ( ) = = 0 {
// Detects if the slot or directory has any contents
println! (
" 🗃️ {} " ,
format! (
" No files in {}{}. " ,
match slot {
2022-10-01 20:38:14 +00:00
" active " = > slot . bold ( ) ,
_ = > slot . blue ( ) . bold ( ) ,
2022-09-27 23:05:08 +00:00
} ,
2022-10-01 20:38:14 +00:00
if ! dir . is_empty ( ) {
2022-09-27 23:05:08 +00:00
if cfg! ( windows ) {
2022-10-01 20:38:14 +00:00
format! ( " \\ {} " , dir )
2022-09-27 23:05:08 +00:00
} else {
2022-10-01 20:38:14 +00:00
format! ( " / {} " , dir )
2022-09-27 23:05:08 +00:00
}
} else {
" " . to_string ( )
}
)
. green ( )
) ;
} else {
println! (
" 🗃️ {} " ,
format! (
" Files in {}{} ({}): " ,
match slot {
2022-10-01 20:38:14 +00:00
" active " = > slot . bold ( ) ,
_ = > slot . blue ( ) . bold ( ) ,
2022-09-27 23:05:08 +00:00
} ,
2022-10-01 20:38:14 +00:00
if ! dir . is_empty ( ) {
2022-09-27 23:05:08 +00:00
if cfg! ( windows ) {
2022-10-01 20:38:14 +00:00
format! ( " \\ {} " , dir )
2022-09-27 23:05:08 +00:00
} else {
2022-10-01 20:38:14 +00:00
format! ( " / {} " , dir )
2022-09-27 23:05:08 +00:00
}
} else {
" inventory " . to_string ( )
} ,
format! ( " {} " , fs ::read_dir ( & slotdir ) . unwrap ( ) . count ( ) )
. white ( )
. bold ( )
)
. green ( )
) ;
for file in fs ::read_dir ( & slotdir ) . unwrap ( ) {
let file = file . unwrap ( ) . path ( ) ;
println! (
" - [{}] {}{} " ,
if file . clone ( ) . is_dir ( ) {
" D " . blue ( )
} else if file . clone ( ) . is_symlink ( ) {
" S " . yellow ( )
} else {
" F " . green ( )
} ,
file . clone ( )
. file_name ( )
. unwrap ( )
. to_os_string ( )
. into_string ( )
. unwrap ( ) ,
if file . clone ( ) . is_file ( ) {
format! (
" ({}B) " ,
SizeFormatterBinary ::new ( file . clone ( ) . metadata ( ) . unwrap ( ) . len ( ) )
)
} else {
2022-10-01 20:38:14 +00:00
String ::new ( )
2022-09-27 23:05:08 +00:00
}
) ;
}
2022-09-14 19:33:19 +00:00
}
2022-09-19 03:23:54 +00:00
Ok ( ( ) )
2022-09-14 12:36:34 +00:00
}
2022-09-19 03:23:54 +00:00
pub fn switch ( ) -> Result < ( ) > {
2022-09-17 08:44:25 +00:00
// Switches between inventory slots
2022-10-17 21:11:38 +00:00
let ventodir = & common ::env_config ( ) ? . vento_dir ;
let active = & common ::env_config ( ) ? . active_dir ;
let inactive = & common ::env_config ( ) ? . inactive_dir ;
2022-09-17 08:44:25 +00:00
let temp : PathBuf = [ ventodir . to_path_buf ( ) , Path ::new ( " temp " ) . to_path_buf ( ) ]
. iter ( )
. collect ( ) ;
2022-09-27 23:05:08 +00:00
let rename_error = " Vento was unable to switch slots. Try running \" vento -i \" and try again " ;
2022-09-14 12:36:34 +00:00
2022-09-26 19:54:39 +00:00
fs ::rename ( & active , & temp ) . context ( rename_error ) ? ;
fs ::rename ( & inactive , & active ) . context ( rename_error ) ? ;
fs ::rename ( & temp , & inactive ) . context ( rename_error ) ? ;
println! ( " 🎉 {} " , " Switched inventory slots! " . green ( ) ) ;
2022-09-19 03:23:54 +00:00
Ok ( ( ) )
2022-09-14 12:36:34 +00:00
}
2022-09-19 03:23:54 +00:00
fn create_slots ( ) -> Result < ( ) > {
2022-09-27 23:05:08 +00:00
// Used only on init. Creates all required directories
2022-10-17 21:11:38 +00:00
let active = & common ::env_config ( ) ? . active_dir ;
let inactive = & common ::env_config ( ) ? . inactive_dir ;
2022-09-14 12:36:34 +00:00
2022-10-17 22:56:23 +00:00
fs ::create_dir_all ( active ) ? ;
fs ::create_dir_all ( inactive ) ? ;
2022-09-14 12:36:34 +00:00
2022-09-26 19:54:39 +00:00
println! ( " 🎉 {} " , " Vento has been succesfully initialized! " . green ( ) ) ;
2022-09-19 03:23:54 +00:00
Ok ( ( ) )
2022-09-14 22:11:42 +00:00
}