-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Sciroccogti/dev
v1.0
- Loading branch information
Showing
12 changed files
with
551 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Foldest-go | ||
|
||
Automatically manage your folder. | ||
|
||
## How to use | ||
|
||
1. Download binary file in release page | ||
2. Download `conf.yml` and place it in the same folder with binary file | ||
3. Configure settings in `conf.yml`: | ||
```yml | ||
verbose: # verbose output, false as default | ||
targetdir: # the folder you want to manage, you can set it within the program. Last setted folder will be remembered. | ||
tmpbin: | ||
enable: # whether to use tmpbin, false as default | ||
name: tmpbin/ # name of tmpbin, "tmpbin/" as default | ||
treshday: 30 # files not modified for more than this long will be moved into tmpbin, 30 days as default | ||
deleteday: 30 # files in tmpbin for more than this long will be deleted, 30 days as default | ||
``` | ||
4. Set your rules in `rules.yml`: (Currently support 10 rules utmost) | ||
```yml | ||
rule1: | ||
enable: true | ||
name: document | ||
regex: | ||
- ".*?.doc" | ||
- ".*?.docx" | ||
- ".*?.pdf" | ||
threshday: 7 | ||
maxsize: # MB | ||
minsize: # MB | ||
rule2: | ||
... | ||
``` | ||
|
||
## Development progress | ||
|
||
- [ ] Automatic | ||
- [x] Temp trash bin | ||
- [x] Customize rules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
verbose: true | ||
targetdir: D:/Download/ | ||
tmpbin: | ||
enable: true | ||
name: tmpbin/ | ||
treshday: 30 | ||
deleteday: 30 | ||
ignore: | ||
- .accelerate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"foldest-go/utils" | ||
) | ||
|
||
func main() { | ||
conf := utils.ReadConf() | ||
fmt.Println("Press enter to start...") | ||
fmt.Scanln() | ||
|
||
rules := utils.ReadRules() | ||
if rules == nil { | ||
fmt.Println("Skipping classify...") | ||
} else { | ||
utils.DoClassify(rules, conf.Targetdir, conf.Verbose) | ||
} | ||
|
||
if conf.Tmpbin.Enable { | ||
fmt.Println("Performing tmpbin...") | ||
utils.Manage(conf) | ||
} else { | ||
fmt.Println("tmpbin is disabled, skipping...") | ||
} | ||
|
||
fmt.Println("Press enter to exit...") | ||
fmt.Scanln() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module foldest-go | ||
|
||
go 1.13 | ||
|
||
require gopkg.in/yaml.v2 v2.2.8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= | ||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
rule1: | ||
enable: true | ||
name: document | ||
regex: | ||
- ".*?.doc" | ||
- ".*?.docx" | ||
- ".*?.pdf" | ||
threshday: 7 | ||
maxsize: | ||
minsize: | ||
rule2: | ||
enable: true | ||
name: films | ||
regex: | ||
- ".*?.mp4" | ||
- ".*?.avi" | ||
- ".*?.flv" | ||
threshday: 7 | ||
maxsize: | ||
minsize: 300 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package utils | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"reflect" | ||
"regexp" | ||
"strings" | ||
"time" | ||
|
||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
// ReadRules : Read rules.yml | ||
func ReadRules() (rules *Rules) { | ||
fmt.Println("Reading conf.yml ...") | ||
rules = new(Rules) | ||
|
||
if _, err := os.Stat("rules.yml"); os.IsNotExist(err) { | ||
fmt.Println("rules.yml not found, skipping ...") | ||
return nil | ||
} | ||
|
||
yamlFile, err := ioutil.ReadFile("rules.yml") | ||
if err != nil { | ||
fmt.Printf("Error while reading rules.yml :\n") | ||
fmt.Printf("\t%c[0;31m%s%c[0m\n", 0x1B, err, 0x1B) | ||
} | ||
err = yaml.Unmarshal(yamlFile, rules) | ||
if err != nil { | ||
fmt.Printf("Error while reading rules.yml :\n") | ||
fmt.Printf("\t%c[0;31m%s%c[0m\n", 0x1B, err, 0x1B) | ||
} | ||
|
||
return rules | ||
} | ||
|
||
// DoClassify : | ||
func DoClassify(rules *Rules, path string, isVerbose bool) { | ||
rType := reflect.TypeOf(rules) | ||
rVal := reflect.ValueOf(rules) | ||
if rType.Kind() == reflect.Ptr { | ||
// 传入的rules是指针,需要.Elem()取得指针指向的value | ||
rType = rType.Elem() | ||
rVal = rVal.Elem() | ||
} else { | ||
panic("rules must be ptr to struct") | ||
} | ||
for i := 0; i < rType.NumField(); i++ { | ||
rule := rVal.Field(i).Interface().(Rule) | ||
if rule.Enable { | ||
doRule(&rule, path, isVerbose) | ||
} | ||
} | ||
} | ||
|
||
// doRule : | ||
func doRule(rule *Rule, path string, isVerbose bool) { | ||
fmt.Printf("Performing rule %c[0;33m%s%c[0m ...\n", 0x1B, rule.Name, 0x1B) | ||
if !strings.HasSuffix(rule.Name, "/") { | ||
rule.Name = rule.Name + "/" | ||
} | ||
_, err := os.Stat(path + rule.Name) | ||
if err != nil { | ||
fmt.Printf("Making folder %c[0;33m%s%c[0m ...\n", 0x1B, rule.Name, 0x1B) | ||
err := os.Mkdir(path+rule.Name, 0777) | ||
if err != nil { | ||
fmt.Printf("Error while making folder %c[0;33m%s%c[0m ...\n", 0x1B, rule.Name, 0x1B) | ||
fmt.Printf("\t%c[0;31m%s%c[0m\n", 0x1B, err, 0x1B) | ||
} | ||
} | ||
|
||
dir := OpenDir(path) | ||
if dir == nil { | ||
return | ||
} | ||
|
||
// Moving files to rule dir | ||
for _, file := range dir { | ||
// jump rule dir | ||
if file.Name() == rule.Name || file.IsDir() { | ||
continue | ||
} | ||
|
||
for _, pattern := range rule.Regex { | ||
re := regexp.MustCompile(pattern) | ||
match := re.MatchString(file.Name()) | ||
if match { | ||
modTime, strerr := GetFileModTime(path + file.Name()) | ||
if strerr == "" { | ||
if isVerbose { | ||
fmt.Printf("%c[0;34m%s%c[0m %c[0;32m%s%c[0m %d\n", 0x1B, file.Name(), 0x1B, 0x1B, modTime, 0x1B, file.Size()) | ||
} | ||
// If file reaches deleteday | ||
if time.Now().Unix()-modTime.Unix() >= int64(rule.Thresh*86400) { | ||
if (rule.Maxsize <= 0 || file.Size() < (int64)(rule.Maxsize)*1024*1024) && file.Size() > (int64)(rule.Minsize)*1024*1024 { | ||
if isVerbose { | ||
fmt.Printf("%c[0;34m%s%c[0m matches %c[0;33m%s%c[0m\n", 0x1B, file.Name(), 0x1B, 0x1B, rule.Name, 0x1B) | ||
} | ||
src := path + file.Name() | ||
des := path + rule.Name + file.Name() | ||
MoveAll(file, src, des) | ||
} | ||
} | ||
} else { | ||
fmt.Printf("Error while scanning %c[0;34m%s%c[0m :", 0x1B, file.Name(), 0x1B) | ||
fmt.Printf("\t%c[0;31m%s%c[0m\n", 0x1B, err, 0x1B) | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package utils | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"strings" | ||
|
||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
// ReadConf : Read conf.yml | ||
func ReadConf() (conf *Conf) { | ||
fmt.Println("Reading conf.yml ...") | ||
conf = new(Conf) | ||
if _, err := os.Stat("conf.yml"); os.IsNotExist(err) { | ||
fmt.Println("conf.yml not found, starting with default value ...") | ||
} else { | ||
yamlFile, err := ioutil.ReadFile("conf.yml") | ||
if err != nil { | ||
fmt.Printf("Error while reading conf.yml :\n") | ||
fmt.Printf("\t%c[0;31m%s%c[0m\n", 0x1B, err, 0x1B) | ||
} | ||
err = yaml.Unmarshal(yamlFile, conf) | ||
if err != nil { | ||
fmt.Printf("Error while reading conf.yml :\n") | ||
fmt.Printf("\t%c[0;31m%s%c[0m\n", 0x1B, err, 0x1B) | ||
} | ||
} | ||
|
||
// Set path | ||
var isChanged bool | ||
isChanged = SetPath(&conf.Targetdir) | ||
|
||
// Set default values | ||
SetDefault(conf) | ||
|
||
if isChanged { | ||
SaveConf(conf) | ||
} | ||
|
||
return conf | ||
} | ||
|
||
// SetPath : Set target dir | ||
func SetPath(path *string) (isChanged bool) { | ||
isChanged = false | ||
|
||
for { | ||
if *path == "" { | ||
fmt.Println("Please input path of the target folder:") | ||
fmt.Scanln(path) | ||
isChanged = true | ||
} | ||
|
||
if !strings.HasSuffix(*path, "/") { | ||
*path = *path + "/" | ||
isChanged = true | ||
} | ||
|
||
if CheckDir(*path) { | ||
break | ||
} | ||
} | ||
|
||
return isChanged | ||
} | ||
|
||
// SetDefault : Set default value of the conf | ||
func SetDefault(conf *Conf) { | ||
if conf.Tmpbin.Name == "" { | ||
conf.Tmpbin.Name = "tmpbin/" | ||
} | ||
if !strings.HasSuffix(conf.Tmpbin.Name, "/") { | ||
conf.Tmpbin.Name = conf.Tmpbin.Name + "/" | ||
} | ||
|
||
if conf.Tmpbin.Thresh == 0 { | ||
conf.Tmpbin.Thresh = 30 | ||
} | ||
|
||
if conf.Tmpbin.Delete == 0 { | ||
conf.Tmpbin.Delete = 30 | ||
} | ||
|
||
if len(conf.Tmpbin.Ignore) == 0 { | ||
conf.Tmpbin.Ignore = append(conf.Tmpbin.Ignore, ".accelerate") | ||
} | ||
} | ||
|
||
// SaveConf : Save the conf.yml | ||
func SaveConf(conf *Conf) { | ||
fmt.Println("Saving conf.yml ...") | ||
yamlChanged, err := yaml.Marshal(conf) | ||
if err != nil { | ||
fmt.Printf("Error while saving conf.yml :\n") | ||
fmt.Printf("\t%c[0;31m%s%c[0m\n", 0x1B, err, 0x1B) | ||
} | ||
err = ioutil.WriteFile("conf.yml", yamlChanged, 0644) | ||
} |
Oops, something went wrong.