/cmd/rapina/cmdutils.go

https://github.com/dude333/rapina · Go · 118 lines · 84 code · 17 blank · 17 comment · 15 complexity · 42cf0487b1598f709485086cf67f9e92 MD5 · raw file

  1. package main
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. "strings"
  8. "github.com/manifoldco/promptui"
  9. "github.com/pkg/errors"
  10. )
  11. // Directory where the DB and downloaded files are stored
  12. const dataDir = ".data"
  13. const yamlFile = "./setores.yml"
  14. // Parms holds the input parameters
  15. type Parms struct {
  16. // Company name to be processed
  17. Company string
  18. // OutputDir: path of the output xlsx
  19. OutputDir string
  20. // YamlFile: file with the companies' sectors
  21. YamlFile string
  22. // Reports is a map with the reports and reports items to be printed
  23. Reports map[string]bool
  24. }
  25. //
  26. // openDatabase to be used by parsers and reporting
  27. //
  28. func openDatabase() (db *sql.DB, err error) {
  29. if err := os.MkdirAll(dataDir, os.ModePerm); err != nil {
  30. return nil, err
  31. }
  32. connStr := "file:" + dataDir + "/rapina.db?cache=shared&mode=rwc&_journal_mode=WAL&_busy_timeout=5000"
  33. db, err = sql.Open("sqlite3", connStr)
  34. if err != nil {
  35. return db, errors.Wrap(err, "database open failed")
  36. }
  37. db.SetMaxOpenConns(1)
  38. return
  39. }
  40. //
  41. // promptUser presents a navigable list to be selected on CLI
  42. //
  43. func promptUser(list []string) (result string) {
  44. templates := &promptui.SelectTemplates{
  45. Help: `{{ "Use estas teclas para navegar:" | faint }} {{ .NextKey | faint }} ` +
  46. `{{ .PrevKey | faint }} {{ .PageDownKey | faint }} {{ .PageUpKey | faint }} ` +
  47. `{{ if .Search }} {{ "and" | faint }} {{ .SearchKey | faint }} {{ "toggles search" | faint }}{{ end }}`,
  48. }
  49. prompt := promptui.Select{
  50. Label: "Selecione a Empresa",
  51. Items: list,
  52. Templates: templates,
  53. }
  54. _, result, err := prompt.Run()
  55. if err != nil {
  56. fmt.Printf("Prompt failed %v\n", err)
  57. return
  58. }
  59. return
  60. }
  61. //
  62. // filename cleans up the filename and returns the path/filename
  63. func filename(path, name string) (fpath string, err error) {
  64. clean := func(r rune) rune {
  65. switch r {
  66. case ' ', ',', '/', '\\':
  67. return '_'
  68. }
  69. return r
  70. }
  71. path = strings.TrimSuffix(path, "/")
  72. name = strings.TrimSuffix(name, ".")
  73. name = strings.Map(clean, name)
  74. fpath = filepath.FromSlash(path + "/" + name + ".xlsx")
  75. const max = 50
  76. var x int
  77. for x = 1; x <= max; x++ {
  78. _, err = os.Stat(fpath)
  79. if err == nil {
  80. // File exists, try again with another name
  81. fpath = fmt.Sprintf("%s/%s(%d).xlsx", path, name, x)
  82. } else if os.IsNotExist(err) {
  83. err = nil // reset error
  84. break
  85. } else {
  86. err = fmt.Errorf("file %s stat error: %v", fpath, err)
  87. return
  88. }
  89. }
  90. if x > max {
  91. err = fmt.Errorf("remova o arquivo %s/%s.xlsx antes de continuar", path, name)
  92. return
  93. }
  94. // Create directory
  95. _ = os.Mkdir(path, os.ModePerm)
  96. // Check if the directory was created
  97. if _, err := os.Stat(path); os.IsNotExist(err) {
  98. return "", errors.Wrap(err, "diretório não pode ser criado")
  99. }
  100. return
  101. }