Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Useful daily business packages

Tommy Mühle
September 03, 2020

Useful daily business packages

Slides of my talk at the Gophers Dresden Meetup about, in my opinion, useful packages to solve daily business challenges.

Tommy Mühle

September 03, 2020
Tweet

More Decks by Tommy Mühle

Other Decks in Programming

Transcript

  1. Tommy Mühle | tommy-muehle.io Why did I selected these packages?

    3 Speaker notes:
 * To give you some context
  2. Tommy Mühle | tommy-muehle.io 6 Speaker notes:
 * In most

    cases we’ve to deal with user generated data
  3. Tommy Mühle | tommy-muehle.io Disclaimer 7 Speaker notes:
 * I

    didn’t used every library personally * But starred it on Github for the case I came in the situation
  4. Tommy Mühle | tommy-muehle.io 10 package main import ( "time"

    "github.com/jinzhu/now" ) func main() { time.Now() // 2020-08-31 22:04:25.54499 +0200 CEST m=+0.000405346 now.BeginningOfYear() // 2020-01-01 00:00:00 +0100 CET now.EndOfWeek() // 2020-09-05 23:59:59.999999999 +0200 CEST } Speaker notes:
 * Many pre-defined functions like EndOfWeek, StartOfWeek * Based on current time
  5. Tommy Mühle | tommy-muehle.io 11 package main import ( "time"

    "github.com/jinzhu/now" ) func main() { location, _ := time.LoadLocation("Europe/Berlin") c := &now.Config{ WeekStartDay: time.Monday, TimeLocation: location, TimeFormats: []string{"2006-01-02 15:04:05"}, } t := time.Date(2013, 11, 18, 17, 51, 49, 123456789, location) _ = c.With(t).BeginningOfWeek() // 2013-11-18 00:00:00 +0100 CET } Speaker notes:
 * But it’s also possible with configured time
  6. Tommy Mühle | tommy-muehle.io 13 package main import ( "time"

    “github.com/rickar/cal/v2" "github.com/rickar/cal/v2/us" ) func main() { c := cal.NewBusinessCalendar() c.AddHoliday( us.NewYear, us.ChristmasDay, ) c.SetWorkday(time.Saturday, true) c.SetWorkHours(8*time.Hour, 18*time.Hour+30*time.Minute) } Speaker notes:
 * Create your own custom business calendar
  7. Tommy Mühle | tommy-muehle.io 14 package main import ( "time"

    "github.com/rickar/cal/v2" ) func main() { // ... t := time.Now() if c.IsWorkday(t) { // ... } if c.WorkdaysRemain(t) == 0 { // ... } } Speaker notes:
 * Interact with them * For example check if its the last workday so that you send out receipts, emails etc * Or is it holiday
  8. Tommy Mühle | tommy-muehle.io go-playground/validator 16 Speaker notes:
 * What

    is the first thing what you do with customer data? * Validate
  9. Tommy Mühle | tommy-muehle.io 17 package main type User struct

    { FirstName string `validate:"required"` LastName string `validate:"required"` Age uint8 `validate:"gte=0,lte=130"` Email string `validate:"required,email"` IsAwesome string `validate:"is-awesome"` // custom } // ... func isAwesome(value string) bool { return value == "is-awesome" } Speaker notes:
 * Use pre-defined validators like required, email etc
  10. Tommy Mühle | tommy-muehle.io 18 package main import ( "github.com/go-playground/validator"

    ) var validate *validator.Validate func main() { validate = validator.New() validate.RegisterValidation("is-awesome", isAwesome) user := &User{ FirstName: "John", Email: "invalid-email", } err := validate.Struct(user) if err != nil { // ... } } Speaker notes:
 * Or add easily own ones
  11. Tommy Mühle | tommy-muehle.io 20 package main import ( "github.com/nyaruka/phonenumbers"

    ) func main() { num, err := phonenumbers.Parse("03518757545", "DE") if err != nil { // ... } // save only parsable phone numbers phonenumbers.Format(num, phonenumbers.NATIONAL) // 0351 8757545 phonenumbers.Format(num, phonenumbers.INTERNATIONAL) // +49 351 8757545 } Speaker notes:
 * It’s a Go port of the Google Java library
  12. Tommy Mühle | tommy-muehle.io 22 package main import ( "github.com/montanaflynn/stats"

    ) func main() { // Age of our users ages := stats.LoadRawData([]int{30, 35, 18, 25, 23, 27}) median, err := stats.Median(ages) if err != nil { // ... } _ = median // 26 } Speaker notes:
 * Sometimes you’ve to do statistic calculations * Almost all possible functions available
  13. Tommy Mühle | tommy-muehle.io 23 package main import ( "github.com/montanaflynn/stats"

    ) func main() { // Size of our users (in mm) sizes := stats.LoadRawData([]int{150, 170, 180, 201, 190, 165, 178}) mean, err := stats.Mean(sizes) if err != nil { // ... } deviation, err := stats.StandardDeviation(sizes) if err != nil { // ... } _ = mean // 176.28571428571428 _ = deviation // 15.46160484845593 }
  14. Tommy Mühle | tommy-muehle.io 25 package main import ( cregex

    "github.com/mingrammer/commonregex" ) func main() { text := `John, please get that article on www.linkedin.com or www.xing.com.` _ = cregex.Links(text) // [www.linkedin.com www.xing.com] _ = cregex.Phones(`You can reach me at (519)-236-2723`) // [(519)-236-2723] } Speaker notes:
 * Sometimes you want to extract some parts out of a text * To filter spam or not allowed content
  15. Tommy Mühle | tommy-muehle.io 28 package main import ( "github.com/disintegration/imaging"

    ) func main() { image, err := imaging.Open("source.jpg") if err != nil { // ... } // Resize the image newImage := imaging.Resize(image, 256, 256, imaging.Lanczos) // Add a blur effect _ = imaging.Blur(newImage, 0.5) } Speaker notes:
 * Basic image processing * We can use it for example to create profile pictures
  16. Tommy Mühle | tommy-muehle.io graymeta/stow 29 Speaker notes:
 * File

    abstraction layer
 * For example to store your user or product images
  17. Tommy Mühle | tommy-muehle.io 30 package main import ( "github.com/graymeta/stow"

    "github.com/graymeta/stow/s3" ) func main() { config := stow.ConfigMap{ s3.ConfigAccessKeyID: "246810", s3.ConfigSecretKey: "abc123", s3.ConfigRegion: "eu-west-1", } location, err := stow.Dial("s3", config) if err != nil { // ... } defer location.Close() // ... } Speaker notes:
 * Concept is Location (for example S3) -> Container (group of items) -> Item (single file) * First of all you need a location
  18. Tommy Mühle | tommy-muehle.io 31 package main func main() {

    // ... c, err := location.CreateContainer("profile_pictures") if err != nil { // ... } // "i" created via os.Open and "s" via image.Stat().Size() _, err = c.Put("avatar.jpg", i, s, map[string]interface{}{}) if err != nil { // ... } } Speaker notes:
 * Create a container and add files to it * Later you can walk over containers, collect items and process them
  19. Tommy Mühle | tommy-muehle.io 33 package main import ( "image/jpeg"

    "os" "github.com/corona10/goimagehash" ) func main() { file1, _ := os.Open("Poolbild.jpg") file2, _ := os.Open("Poolbild.jpg") defer file1.Close() defer file2.Close() img1, _ := jpeg.Decode(file1) img2, _ := jpeg.Decode(file2) hash1, _ := goimagehash.AverageHash(img1) hash2, _ := goimagehash.AverageHash(img2) distance, _ := hash1.Distance(hash2) // 0 } Speaker notes:
 * Use it if you want to know which users uses the same profile picture * You can calculate the hash for every image and later find duplicates easily
 * There are more hashing algorithms available
  20. Tommy Mühle | tommy-muehle.io 36 package main import ( "github.com/sethvargo/go-password/password"

    ) func main() { // Generate a password that is 32 characters long with 10 digits, 2 symbols, allowing upper and 
 lower case letters, disallowing repeat characters pass, err := password.Generate(32, 10, 2, false, false) if err != nil { // ... } _ = pass // 73g6QcNDj2BqH:FZiMeW`09ItV51EO84 } Speaker notes:
 * Based on requirements as described by AgileBits 1Password
  21. Tommy Mühle | tommy-muehle.io 39 package main import ( "github.com/ory/dockertest/v3"

    ) func main() { pool, _ := dockertest.NewPool("") // pulls an image, creates a container based on it and 
 runs it resource, _ := pool.Run("mysql", "5.7", []string{"MYSQL_ROOT_PASSWORD=secret"}) } Speaker notes:
 * If you want not only to mock dependencies * Easily interact with Docker in integration tests
  22. Tommy Mühle | tommy-muehle.io 40 package main import ( "database/sql"

    "log" ) func main() { // ... var err error var db *sql.DB if err = pool.Retry(func() error { db, _ = sql.Open("mysql", "...") return db.Ping() }); err != nil { ... } // Your code _ = pool.Purge(resource) } Speaker notes:
 * The retry is needed because you need to wait until the container is ready
 * Purge the container at the end
  23. Tommy Mühle | tommy-muehle.io Summary 41 Speaker notes:
 * I

    hope you found at least one interesting package that you can use for your daily work