utils.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. package utils
  2. import (
  3. "bytes"
  4. "crypto/md5"
  5. "encoding/gob"
  6. "encoding/hex"
  7. "fmt"
  8. "log"
  9. "net"
  10. "os"
  11. "os/exec"
  12. "os/user"
  13. "path/filepath"
  14. "runtime"
  15. "strings"
  16. "sync"
  17. "time"
  18. "github.com/eiannone/keyboard"
  19. "github.com/teris-io/shortid"
  20. "github.com/go-ini/ini"
  21. )
  22. func LocalIP() string {
  23. ip := ""
  24. if addrs, err := net.InterfaceAddrs(); err == nil {
  25. for _, addr := range addrs {
  26. if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && !ipnet.IP.IsMulticast() && !ipnet.IP.IsLinkLocalUnicast() && !ipnet.IP.IsLinkLocalMulticast() && ipnet.IP.To4() != nil {
  27. ip = ipnet.IP.String()
  28. }
  29. }
  30. }
  31. return ip
  32. }
  33. func MD5(str string) string {
  34. encoder := md5.New()
  35. encoder.Write([]byte(str))
  36. return hex.EncodeToString(encoder.Sum(nil))
  37. }
  38. func CWD() string {
  39. path, err := os.Executable()
  40. if err != nil {
  41. return ""
  42. }
  43. return filepath.Dir(path)
  44. }
  45. var workInDirLock sync.Mutex
  46. func WorkInDir(f func(), dir string) {
  47. wd, _ := os.Getwd()
  48. workInDirLock.Lock()
  49. defer workInDirLock.Unlock()
  50. os.Chdir(dir)
  51. defer os.Chdir(wd)
  52. f()
  53. }
  54. func EXEName() string {
  55. path, err := os.Executable()
  56. if err != nil {
  57. return ""
  58. }
  59. return strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))
  60. }
  61. func HomeDir() string {
  62. u, err := user.Current()
  63. if err != nil {
  64. return ""
  65. }
  66. return u.HomeDir
  67. }
  68. func LogDir() string {
  69. dir := filepath.Join(CWD(), "logs")
  70. EnsureDir(dir)
  71. return dir
  72. }
  73. func ErrorLogFilename() string {
  74. return filepath.Join(LogDir(), fmt.Sprintf("%s-error.log", strings.ToLower(EXEName())))
  75. }
  76. func DataDir() string {
  77. dir := CWD()
  78. _dir := Conf().Section("").Key("data_dir").Value()
  79. if _dir != "" {
  80. dir = _dir
  81. }
  82. dir = ExpandHomeDir(dir)
  83. EnsureDir(dir)
  84. return dir
  85. }
  86. var FlagVarConfFile string
  87. func ConfFile() string {
  88. if FlagVarConfFile != "" {
  89. return FlagVarConfFile
  90. }
  91. if Exist(ConfFileDev()) {
  92. return ConfFileDev()
  93. }
  94. return filepath.Join(CWD(), strings.ToLower(EXEName())+".ini")
  95. }
  96. func ConfFileDev() string {
  97. return filepath.Join(CWD(), strings.ToLower(EXEName())+".dev.ini")
  98. }
  99. var FlagVarDBFile string
  100. func DBFile() string {
  101. if FlagVarDBFile != "" {
  102. return FlagVarDBFile
  103. }
  104. if Exist(DBFileDev()) {
  105. return DBFileDev()
  106. }
  107. return filepath.Join(CWD(), strings.ToLower(EXEName()+".db"))
  108. }
  109. func DBFileDev() string {
  110. return filepath.Join(CWD(), strings.ToLower(EXEName())+".dev.db")
  111. }
  112. var conf *ini.File
  113. func Conf() *ini.File {
  114. if conf != nil {
  115. return conf
  116. }
  117. if _conf, err := ini.InsensitiveLoad(ConfFile()); err != nil {
  118. _conf, _ = ini.LoadSources(ini.LoadOptions{Insensitive: true}, []byte(""))
  119. conf = _conf
  120. } else {
  121. conf = _conf
  122. }
  123. return conf
  124. }
  125. func ReloadConf() *ini.File {
  126. if _conf, err := ini.InsensitiveLoad(ConfFile()); err != nil {
  127. _conf, _ = ini.LoadSources(ini.LoadOptions{Insensitive: true}, []byte(""))
  128. conf = _conf
  129. } else {
  130. conf = _conf
  131. }
  132. return conf
  133. }
  134. func SaveToConf(section string, kvmap map[string]string) error {
  135. var _conf *ini.File
  136. var err error
  137. if _conf, err = ini.InsensitiveLoad(ConfFile()); err != nil {
  138. if _conf, err = ini.LoadSources(ini.LoadOptions{Insensitive: true}, []byte("")); err != nil {
  139. return err
  140. }
  141. }
  142. sec := _conf.Section(section)
  143. for k, v := range kvmap {
  144. sec.Key(k).SetValue(v)
  145. }
  146. _conf.SaveTo(ConfFile())
  147. conf = _conf
  148. return nil
  149. }
  150. func ExpandHomeDir(path string) string {
  151. if len(path) == 0 {
  152. return path
  153. }
  154. if path[0] != '~' {
  155. return path
  156. }
  157. if len(path) > 1 && path[1] != '/' && path[1] != '\\' {
  158. return path
  159. }
  160. return filepath.Join(HomeDir(), path[1:])
  161. }
  162. func EnsureDir(dir string) (err error) {
  163. if _, err = os.Stat(dir); os.IsNotExist(err) {
  164. err = os.MkdirAll(dir, 0755)
  165. if err != nil {
  166. return
  167. }
  168. }
  169. return
  170. }
  171. func Exist(path string) bool {
  172. if _, err := os.Stat(path); os.IsNotExist(err) {
  173. return false
  174. }
  175. return true
  176. }
  177. func DeepCopy(dst, src interface{}) error {
  178. var buf bytes.Buffer
  179. if err := gob.NewEncoder(&buf).Encode(src); err != nil {
  180. return err
  181. }
  182. return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
  183. }
  184. func Open(url string) error {
  185. var cmd string
  186. var args []string
  187. switch runtime.GOOS {
  188. case "windows":
  189. cmd = "cmd"
  190. args = []string{"/c", "start"}
  191. case "darwin":
  192. cmd = "open"
  193. default: // "linux", "freebsd", "openbsd", "netbsd"
  194. cmd = "xdg-open"
  195. }
  196. args = append(args, url)
  197. return exec.Command(cmd, args...).Start()
  198. }
  199. func ShortID() string {
  200. return shortid.MustGenerate()
  201. }
  202. func PauseExit() {
  203. log.Println("Press any to exit")
  204. keyboard.GetSingleKey()
  205. os.Exit(0)
  206. }
  207. func PauseGo(msg ...interface{}) {
  208. log.Println(msg...)
  209. keyboard.GetSingleKey()
  210. }
  211. func IsPortInUse(port int) bool {
  212. if conn, err := net.DialTimeout("tcp", net.JoinHostPort("", fmt.Sprintf("%d", port)), 3*time.Second); err == nil {
  213. conn.Close()
  214. return true
  215. }
  216. return false
  217. }
  218. func init() {
  219. gob.Register(map[string]interface{}{})
  220. gob.Register(StringArray(""))
  221. ini.PrettyFormat = false
  222. }