104 lines
3.1 KiB
Go
104 lines
3.1 KiB
Go
package scanner
|
|
|
|
import (
|
|
"git.entr0py.de/garionion/murphy/store"
|
|
"github.com/karrick/godirwalk"
|
|
"github.com/mehdioa/nlog"
|
|
"github.com/oriser/regroup"
|
|
"io/ioutil"
|
|
"os"
|
|
"path"
|
|
"time"
|
|
)
|
|
|
|
func scan(p *store.Project) {
|
|
log := p.Logger
|
|
log.Infof("Scanning %s", p.ProjectName)
|
|
lastModified := time.Time{}
|
|
err := godirwalk.Walk(p.TargetPath, &godirwalk.Options{
|
|
Callback: func(osPathname string, de *godirwalk.Dirent) error {
|
|
fi, err := os.Stat(osPathname)
|
|
if err != nil {
|
|
log.Errorf("Error while getting Stats on %s: %v", osPathname, err)
|
|
return err
|
|
}
|
|
modtime := fi.ModTime()
|
|
if modtime.After(lastModified) {
|
|
lastModified = modtime
|
|
}
|
|
return nil
|
|
},
|
|
Unsorted: true, // (optional) set true for faster yet non-deterministic enumeration (see godoc)
|
|
})
|
|
if err != nil {
|
|
log.Errorf("Error scanning %s: %v", p.ProjectName, err)
|
|
}
|
|
log.Infof("Found last modification time %v", lastModified)
|
|
p.LastChange = lastModified
|
|
}
|
|
|
|
func NewProject(target, projectName string, createdAt time.Time, logger *nlog.Logger) *store.Project {
|
|
projectLogger := logger.New("Project", nlog.Data{"Project": projectName})
|
|
project := &store.Project{TargetPath: target, Created: createdAt, ProjectName: projectName, Logger: projectLogger}
|
|
go scan(project)
|
|
return project
|
|
}
|
|
|
|
func InitScanner(s *store.Store, sourcePath string) {
|
|
s.Logger.Infof("Initializing scanner")
|
|
projects := s.GetProjects()
|
|
rootScanner(sourcePath, projects, s.Logger)
|
|
s.Logger.Infof("Found %d projects", len(projects))
|
|
}
|
|
|
|
func rootScanner(rootPath string, projects map[string]*store.Project, logger *nlog.Logger) {
|
|
resorts, err := ioutil.ReadDir(rootPath)
|
|
if err != nil {
|
|
logger.Errorf("Error reading directory %s: %v", rootPath, err)
|
|
return
|
|
}
|
|
re := regroup.MustCompile(`(?P<date>\d{4}-\d{2}-\d{2})_(?P<name>.*$)`)
|
|
for _, r := range resorts {
|
|
if r.IsDir() && r.Name()[0] != '.' {
|
|
resort := path.Join(rootPath, r.Name())
|
|
logger.Debugf("Found directory: %s", resort)
|
|
projectsDir, err := ioutil.ReadDir(resort)
|
|
if err != nil {
|
|
logger.Errorf("Error reading directory %s: %v", projects, err)
|
|
return
|
|
}
|
|
for _, p := range projectsDir {
|
|
if p.IsDir() {
|
|
_, mapContainsProject := projects[p.Name()]
|
|
if mapContainsProject {
|
|
continue
|
|
}
|
|
projectPath := path.Join(resort, p.Name())
|
|
matches, err := re.Groups(p.Name())
|
|
if err != nil {
|
|
logger.Debugf("Failed to Match %s: %v", p.Name(), err)
|
|
continue
|
|
}
|
|
logger.Debugf("Matches: %+v", matches)
|
|
if len(matches) != 0 {
|
|
createdAtString := matches["date"]
|
|
projectName := matches["name"]
|
|
logger.Infof("Found project: %s", projectName)
|
|
|
|
createdAt, err := time.Parse("2006-01-02", createdAtString)
|
|
if err != nil {
|
|
logger.Errorf("Failed to parse date %s: %v, Using Null-Time for %s", createdAtString, err, p.Name())
|
|
createdAt = time.Time{}
|
|
}
|
|
scanner := NewProject(projectPath, projectName, createdAt, logger)
|
|
projects[p.Name()] = scanner
|
|
} else {
|
|
logger.Debugf("Ignoring Directory %s", projectPath)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|