Commit fd1f1eb3 authored by Boris Mühmer's avatar Boris Mühmer
Browse files

1st version without dummies

parent 897fac7f
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
package filediscovery

import (
	"fmt"
)

// Program information.
const (
	Author  = "Boris Mühmer"
	Title   = "File Discovery"
	Version = "*not specified*"
)

// Banner displays some information.
func Banner() string {
	res := fmt.Sprintf("%s (%s) by %s", Title, Version, Author)
	return res
}
+12 −0
Original line number Diff line number Diff line
package filediscovery

import "testing"

func TestBanner(t *testing.T) {
	exp := Title + " (" + Version + ") by " + Author
	res := Banner()

	if res != exp {
		t.Errorf("Banner() = %s, expected %s", res, exp)
	}
}
+117 −0
Original line number Diff line number Diff line
package filediscovery

import (
	"crypto/sha512"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
)

var (
	errorNotImplemented error
)

func init() {
	errorNotImplemented = errors.New("function is not implemented")
}

// FileData holds more information about a file.
type FileData struct {
	Path string
	Info os.FileInfo
}

// FileDatas is an array of FileData.
type FileDatas []FileData

// HashArray contains
type HashArray [sha512.Size]byte

// Status holds information about the found files.
type Status struct {
	NumberOfErrors      int64
	NumberOfDirectories int64
	NumberOfFiles       int64
	Contents            map[HashArray]FileDatas
}

// FindFiles searches for files at the specific path.
func FindFiles(path string) (*Status, error) {

	var status Status

	status.Contents = make(map[HashArray]FileDatas, 0)

	err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			status.NumberOfErrors++
			return err
		}

		// only count directories
		if info.IsDir() {
			log.Printf("Working on: %s", path)
			status.NumberOfDirectories++
			return nil
		}

		status.NumberOfFiles++
		hash, err := hashFile(path)
		if err != nil {
			status.NumberOfErrors++
			return err
		}

		entry := FileData{
			Path: path,
			Info: info,
		}

		entries := status.Contents[hash]
		if entries == nil {
			entries = make(FileDatas, 0)
		}
		entries = append(entries, entry)
		status.Contents[hash] = entries

		return nil
	})

	return &status, err
}

func walkFunc(path string, info os.FileInfo, err error) error {
	return errors.New("function not implemented")
}

// hashFile calculates a sha512 of a given file.
func hashFile(filename string) (HashArray, error) {
	var ha HashArray

	f, err := os.Open(filename)
	if err != nil {
		return ha, err
	}
	defer f.Close()

	h := sha512.New()
	if _, err := io.Copy(h, f); err != nil {
		return ha, err
	}

	t := h.Sum(nil)

	if len(t) != len(ha) {
		msg := fmt.Sprintf("hash rank mismatch: %d, expected %d", len(t), len(ha))
		return ha, errors.New(msg)
	}

	for i := range t {
		ha[i] = t[i]
	}

	return ha, nil
}
+10 −0
Original line number Diff line number Diff line
package filediscovery

import "testing"

func TestFindFiles(t *testing.T) {
	_, err := FindFiles("")
	if err != errorNotImplemented {
		t.Error(err)
	}
}

main.go

0 → 100644
+36 −0
Original line number Diff line number Diff line
package main

import (
	"fmt"
	"log"
	"os"

	"repositories.muehmer.net/bsmrgo/filediscovery/internal/pkg/filediscovery"
)

func main() {
	fmt.Printf("%s\n", filediscovery.Banner())

	path := os.Args[1]

	fmt.Printf("Working on %s...\n", path)

	res, err := filediscovery.FindFiles(path)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Errors: %d, Directories: %d, Files: %d\n", res.NumberOfErrors, res.NumberOfDirectories, res.NumberOfFiles)
	for _, v := range res.Contents {
		l := len(v)
		if l < 2 {
			//fmt.Printf("Skipping: %s\n", v[0].Path)
			continue
		}

		fmt.Printf("- %d entries\n", l)
		for i, s := range v {
			fmt.Printf("%d: %d - %s - %s\n", i, s.Info.Size(), s.Info.Name(), s.Path)
		}
	}
}