import.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package cmd
  2. import (
  3. "bufio"
  4. "bytes"
  5. "fmt"
  6. "gitote/gitote/pkg/setting"
  7. "os"
  8. "path/filepath"
  9. "time"
  10. "github.com/Unknwon/com"
  11. "github.com/urfave/cli"
  12. )
  13. var (
  14. Import = cli.Command{
  15. Name: "import",
  16. Usage: "Import portable data as local Gitote data",
  17. Description: `Allow user import data from other Gitote installations to local instance
  18. without manually hacking the data files`,
  19. Subcommands: []cli.Command{
  20. subcmdImportLocale,
  21. },
  22. }
  23. subcmdImportLocale = cli.Command{
  24. Name: "locale",
  25. Usage: "Import locale files to local repository",
  26. Action: runImportLocale,
  27. Flags: []cli.Flag{
  28. stringFlag("source", "", "Source directory that stores new locale files"),
  29. stringFlag("target", "", "Target directory that stores old locale files"),
  30. stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
  31. },
  32. }
  33. )
  34. func runImportLocale(c *cli.Context) error {
  35. if !c.IsSet("source") {
  36. return fmt.Errorf("Source directory is not specified")
  37. } else if !c.IsSet("target") {
  38. return fmt.Errorf("Target directory is not specified")
  39. }
  40. if !com.IsDir(c.String("source")) {
  41. return fmt.Errorf("Source directory does not exist or is not a directory")
  42. } else if !com.IsDir(c.String("target")) {
  43. return fmt.Errorf("Target directory does not exist or is not a directory")
  44. }
  45. if c.IsSet("config") {
  46. setting.CustomConf = c.String("config")
  47. }
  48. setting.NewContext()
  49. now := time.Now()
  50. line := make([]byte, 0, 100)
  51. badChars := []byte(`="`)
  52. escapedQuotes := []byte(`\"`)
  53. regularQuotes := []byte(`"`)
  54. // Cut out en-US.
  55. for _, lang := range setting.Langs[1:] {
  56. name := fmt.Sprintf("locale_%s.ini", lang)
  57. source := filepath.Join(c.String("source"), name)
  58. target := filepath.Join(c.String("target"), name)
  59. if !com.IsFile(source) {
  60. continue
  61. }
  62. // Crowdin surrounds double quotes for strings contain quotes inside,
  63. // this breaks INI parser, we need to fix that.
  64. sr, err := os.Open(source)
  65. if err != nil {
  66. return fmt.Errorf("Open: %v", err)
  67. }
  68. tw, err := os.Create(target)
  69. if err != nil {
  70. if err != nil {
  71. return fmt.Errorf("Open: %v", err)
  72. }
  73. }
  74. scanner := bufio.NewScanner(sr)
  75. for scanner.Scan() {
  76. line = scanner.Bytes()
  77. idx := bytes.Index(line, badChars)
  78. if idx > -1 && line[len(line)-1] == '"' {
  79. // We still want the "=" sign
  80. line = append(line[:idx+1], line[idx+2:len(line)-1]...)
  81. line = bytes.Replace(line, escapedQuotes, regularQuotes, -1)
  82. }
  83. tw.Write(line)
  84. tw.WriteString("\n")
  85. }
  86. sr.Close()
  87. tw.Close()
  88. // Modification time of files from Crowdin often ahead of current,
  89. // so we need to set back to current.
  90. os.Chtimes(target, now, now)
  91. }
  92. fmt.Println("Locale files has been successfully imported!")
  93. return nil
  94. }