Skip to content

Commit

Permalink
Merge pull request #1 from Sciroccogti/dev
Browse files Browse the repository at this point in the history
v1.0
  • Loading branch information
Sciroccogti authored May 5, 2020
2 parents 1513a58 + 7f7fbef commit c37de9c
Show file tree
Hide file tree
Showing 12 changed files with 551 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*.dll
*.so
*.dylib
foldest-linux*

# Test binary, built with `go test -c`
*.test
Expand All @@ -13,3 +14,5 @@

# Dependency directories (remove the comment below to include it)
# vendor/

*.code-workspace
39 changes: 39 additions & 0 deletions README.md
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
9 changes: 9 additions & 0 deletions conf.yml
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
29 changes: 29 additions & 0 deletions foldest.go
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()
}
5 changes: 5 additions & 0 deletions go.mod
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
3 changes: 3 additions & 0 deletions go.sum
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=
20 changes: 20 additions & 0 deletions rules.yml
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
113 changes: 113 additions & 0 deletions utils/classify.go
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)
}
}
}
}
}
100 changes: 100 additions & 0 deletions utils/conf.go
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)
}
Loading

0 comments on commit c37de9c

Please sign in to comment.