filer

package module
v0.0.0-...-e31cc93 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 23, 2019 License: MIT Imports: 8 Imported by: 0

README

Filer - Utils for dealing with file uploads and validation in Golang

Coverage StatusBuild Status


$ go get github.com/adelowo/filer

  • Validators : Validate files according to a set of rules

    • SizeValidator

    Validate a file by it's size

    max, _ := filer.LengthInBytes("2MB")
    min, _ := filer.LengthInBytes("200KB")
    
    val = NewSizeValidator(max, min)
    file, _ = os.Open("./path/to/file")
    
    isValid, err := val.Validate(file)
    
    • MimeTypeValidator

    Validate a file by it's mimetype.

    val = NewMimeTypeValidator([]string{"image/jpeg", "image/png"})
    file, _ = os.Open("./path/to/file")
    
    isValid, err := val.Validate(file)
    
    • ExtensionValidator

    Validate a file by it's extension.. Caveat, this is probably not what you need.

    val = NewExtensionValidator([]string{"go", "php", "md", "rb", "ts"})
    file, _ = os.Open("./path/to/file")
    
    isValid, err := val.Validate(file)
    

You can also make use of a chained validator to ease the pain of having to deal with multiple validators manually


validator := NewChainedValidator(
  NewExtensionValidator([]string{"go", "ts", "jpg"}),
  NewSizeValidator((1024*1024), (1024*6))) //1MB and 6 KB

file, _ := os.Open("./path/to/file.jpg")

isValid, err := validator.Validate(file)

  • File Name Generators:

    • MD5Generator :

    Get the ms5 hash sum of the file name

    gen := generator.NewMD5Generator()
    s := gen.Generate(file) //Assuming file is `os.Open("file")`
    
    • SlugGenerator :

    Generates a slugified version of the file name.

    gen := generator.NewSlugGenerator()
    s := gen.Generate(file)
    
    • RandomGenerator :

    This generates a random name for the file.. Discards the file name itself

    ran := generator.NewRandomGenerator(12) //random name with a length of 12
    generatedName := ran.Generate(file)
    
  • File Storage:

For storage, filer utilizes Afero. This is to allow making use of a single API while having multiple backends to choose from


fs = afero.NewMemMapFs() //Using an inmemory store here..
//Could be a local store,s3 store or anything.. As long as it implements `afero.Fs`
storeAdapter = storage.NewFilerStorage(fs, nil) //can also pass in a PathFunc instead of nil

A sample usage of this library would be :

package main

import (
	"io"
	"io/ioutil"
	"net/http"

	"github.com/adelowo/filer/storage"
	"github.com/adelowo/filer/validator"
	"github.com/spf13/afero"
)

func main() {
	http.HandleFunc("/upload", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "GET" {
			io.WriteString(w, "You came here")
			return
		}

		if r.Method == "POST" {
			file, header, err := r.FormFile("formNameInHTMLform")

			if err != nil {
				io.WriteString(w, err.Error())
				return
			}

			buf, err := ioutil.ReadAll(file)

			if err != nil {
				io.WriteString(w, err.Error())
				return
			}

			//Move to a temporary location
			//This is allow us be able to get details like it's size and others

			f, err := ioutil.TempFile("", header.Filename)

			if err != nil {
				panic("An error occurred while trying to create a temporary file")
			}

			val = validator.NewMimeTypeValidator([]string{"image/jpeg", "image/png"})
			val2 = validator.NewSizeValidator((1024 * 1024 * 2), (200 * 1024)) //2MB(maxSize) and 200KB(minSize)

			if _, err := val.Validate(f); err != nil {
				panic("Validation failed")
			}
			if _, err := val2.Validate(f); err != nil {
				panic("Validation failed")
			}


			//Upload to some place
			fs = afero.NewMemMapFs() //Using an inmemory store here..
			storeAdapter = storage.NewFilerStorage(fs, nil)

			if err := storeAdapter.Write("some/path", f); err != nil {
				panic("An error occurred while writing the file")
			}

			io.WriteString(w, "The upload was successful")
      return
		}
	})
}

License

MIT

Documentation

Index

Constants

View Source
const (
	BYTES     = 1
	KILOBYTES = 1024 * BYTES
	MEGABYTES = 1024 * KILOBYTES
	GIGABYTES = 1024 * MEGABYTES
)

Variables

This section is empty.

Functions

func Extension

func Extension(f File) string

Extension returns the known extension of a given file

func LengthInBytes

func LengthInBytes(format string) (int64, error)

LengthInBytes is a helper function that parses an human readable string and returns it's equivalent in bytes. Supported units are B,KB,MB and GB

func NormalizeExtension

func NormalizeExtension(s string) string

This is here so as to remove all non-aphabetic characters. The reasoning behind this is the fact that files are saved in the temp dir of the system and Go suffixes them with some weird integer hence path.Ext would return the integer alongside the original extension

Types

type File

type File interface {
	Name() string
	Stat() (os.FileInfo, error)
	io.Reader
}

File is a type that represents a file (can be in memory or a concrete file type) *os.File already implements this interface

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL