utils.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package transfer
  3. import (
  4. "crypto/rand"
  5. "encoding/hex"
  6. "fmt"
  7. "os"
  8. "path/filepath"
  9. "strings"
  10. "kitty/tools/crypto"
  11. "kitty/tools/utils"
  12. "kitty/tools/utils/humanize"
  13. )
  14. var _ = fmt.Print
  15. var global_cwd, global_home string
  16. func cwd_path() string {
  17. if global_cwd == "" {
  18. ans, _ := os.Getwd()
  19. return ans
  20. }
  21. return global_cwd
  22. }
  23. func home_path() string {
  24. if global_home == "" {
  25. return utils.Expanduser("~")
  26. }
  27. return global_home
  28. }
  29. func encode_bypass(request_id string, bypass string) (string, error) {
  30. q := request_id + ";" + bypass
  31. if pkey_encoded := os.Getenv("KITTY_PUBLIC_KEY"); pkey_encoded != "" {
  32. encryption_protocol, pubkey, err := crypto.DecodePublicKey(pkey_encoded)
  33. if err != nil {
  34. return "", err
  35. }
  36. encrypted, err := crypto.Encrypt_data(utils.UnsafeStringToBytes(q), pubkey, encryption_protocol)
  37. if err != nil {
  38. return "", err
  39. }
  40. return fmt.Sprintf("kitty-1:%s", utils.UnsafeBytesToString(encrypted)), nil
  41. }
  42. return "", fmt.Errorf("KITTY_PUBLIC_KEY env var not set, cannot transmit password securely")
  43. }
  44. func abspath(path string, use_home ...bool) string {
  45. if filepath.IsAbs(path) {
  46. return path
  47. }
  48. var base string
  49. if len(use_home) > 0 && use_home[0] {
  50. base = home_path()
  51. } else {
  52. base = cwd_path()
  53. }
  54. return filepath.Join(base, path)
  55. }
  56. func expand_home(path string) string {
  57. if strings.HasPrefix(path, "~"+string(os.PathSeparator)) {
  58. path = strings.TrimLeft(path[2:], string(os.PathSeparator))
  59. path = filepath.Join(home_path(), path)
  60. } else if path == "~" {
  61. path = home_path()
  62. }
  63. return path
  64. }
  65. func random_id() string {
  66. bytes := []byte{0, 0}
  67. rand.Read(bytes)
  68. return fmt.Sprintf("%x%s", os.Getpid(), hex.EncodeToString(bytes))
  69. }
  70. func run_with_paths(cwd, home string, f func()) {
  71. global_cwd, global_home = cwd, home
  72. defer func() { global_cwd, global_home = "", "" }()
  73. f()
  74. }
  75. func should_be_compressed(path, strategy string) bool {
  76. if strategy == "always" {
  77. return true
  78. }
  79. if strategy == "never" {
  80. return false
  81. }
  82. ext := strings.ToLower(filepath.Ext(path))
  83. if ext != "" {
  84. switch ext[1:] {
  85. case "zip", "odt", "odp", "pptx", "docx", "gz", "bz2", "xz", "svgz":
  86. return false
  87. }
  88. }
  89. mt := utils.GuessMimeType(path)
  90. if strings.HasSuffix(mt, "+zip") || (strings.HasPrefix(mt, "image/") && mt != "image/svg+xml") || strings.HasPrefix(mt, "video/") {
  91. return false
  92. }
  93. return true
  94. }
  95. func print_rsync_stats(total_bytes, delta_bytes, signature_bytes int64) {
  96. fmt.Println("Rsync stats:")
  97. fmt.Printf(" Delta size: %s Signature size: %s\n", humanize.Size(delta_bytes), humanize.Size(signature_bytes))
  98. frac := float64(delta_bytes+signature_bytes) / float64(utils.Max(1, total_bytes))
  99. fmt.Printf(" Transmitted: %s of a total of %s (%.1f%%)\n", humanize.Size(delta_bytes+signature_bytes), humanize.Size(total_bytes), frac*100)
  100. }