github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/net/http/upload/huprep/huprep.go (about) 1 // hugoprep is a utility to customize a hugo-config.toml, 2 // to statify, to replace strings, to zip-compress, 3 // to upload. 4 package main 5 6 import ( 7 "bytes" 8 "encoding/json" 9 "fmt" 10 "io/ioutil" 11 "log" 12 "net/url" 13 "os" 14 "path/filepath" 15 "runtime" 16 "strings" 17 "text/template" 18 "time" 19 20 "github.com/codegangsta/cli" 21 "github.com/pbberlin/tools/os/osutilpb" 22 ) 23 24 const dirStat = "cnt_statified" 25 const dirStatPref = "./cnt_statified" 26 27 func main() { 28 29 app := cli.NewApp() 30 app.Name = "hugoprep" 31 app.Usage = "Prepare a core hugo installation for multiple sites, with distinct config and directories." 32 app.Version = "0.1" 33 34 app.Flags = []cli.Flag{ 35 cli.StringFlag{ 36 Name: "name, n", 37 Value: "tec-news", 38 Usage: "The site name with all its JSON settings", 39 EnvVar: "ENV_VAR_HUGOPREP_NAME_1,ENV_VAR_HUGOPREP_NAME_2", 40 }, 41 cli.StringFlag{ 42 Name: "arg2, a2", 43 Value: "arg2default", 44 Usage: "some second unused arg", 45 }, 46 } 47 48 app.Action = func(c *cli.Context) { 49 50 args := c.Args() 51 if len(args) > 0 { 52 fmt.Printf(" %v args given:\n", len(args)) 53 for k, v := range args { 54 fmt.Printf("%4v %-v\n", k, v) 55 } 56 } else { 57 fmt.Printf(" no args given\n") 58 } 59 60 name := c.String("name") 61 if name == "" { 62 fmt.Printf(" need the name of a site config\n") 63 os.Exit(1) 64 } else { 65 // fmt.Printf(" preparing config... %v\n", name) 66 } 67 68 prepareConfigToml(name, "arg2") 69 70 } 71 72 app.Run(os.Args) 73 } 74 75 func prepareConfigToml(name, arg2 string) { 76 77 log.SetFlags(log.Lshortfile) 78 79 configTpl := template.Must(template.ParseFiles("config.tmpl")) 80 81 bts, err := ioutil.ReadFile(name + ".json") 82 if err != nil || len(bts) < 10 { 83 log.Printf("did not find or too tiny file %v - %v\n", name+".json", err) 84 os.Exit(1) 85 } 86 var data1 map[string]interface{} 87 err = json.Unmarshal(bts, &data1) 88 if err != nil { 89 log.Printf("unmarshalling failed %v - %v\n", name+".json", err) 90 os.Exit(1) 91 } 92 93 // lg(stringspb.IndentedDumpBytes(data1)) 94 if len(data1) < 2 { 95 log.Printf("unmarshalling yielded too fee settings for %v - %v\n", name+".json") 96 os.Exit(1) 97 } 98 99 log.Printf("config data successfully unmarshalled") 100 101 // sweep previous 102 err = os.Remove("config.toml") 103 if err != nil { 104 if os.IsNotExist(err) { 105 log.Printf("no previous file config.toml to delete") 106 } else { 107 log.Printf("deletion failed %v\n", err) 108 os.Exit(1) 109 } 110 } else { 111 log.Printf("removed previous %q\n", "config.toml") 112 } 113 114 f, err := os.Create("config.toml") 115 if err != nil { 116 log.Printf("could not open file config.toml: %v\n", err) 117 os.Exit(1) 118 } 119 defer f.Close() 120 121 err = configTpl.Execute(f, data1) 122 if err != nil { 123 log.Printf("tmpl execution failed: %v\n", err) 124 os.Exit(1) 125 } 126 127 log.Printf("=========fine-new-config.toml=======\n") 128 129 // if ok := osutilpb.ExecCmdWithExitCode("cp", "config.toml", "../statify.toml"); !ok { 130 // return 131 // } 132 // log.Printf("copied to statify.toml...\n") 133 134 // os.Chdir("./..") 135 // curdir, _ := os.Getwd() 136 // log.Printf("curdir now %v\n", curdir) 137 138 if ok := osutilpb.ExecCmdWithExitCode("rm", "-rf", dirStatPref+"/*"); !ok { 139 return 140 } 141 log.Printf("cnt_statify cleaned up...\n") 142 143 // hugo --destination="cnt_statified" --config="statify.toml" --disableRSS=true --disableSitemap=true 144 if ok := osutilpb.ExecCmdWithExitCode("hugo", 145 `--destination=`+dirStat, 146 `--config=config.toml`, 147 `--disableRSS=true`, 148 `--disableSitemap=true`); !ok { 149 return 150 } 151 log.Printf("statified...\n") 152 153 paths1 := []string{} 154 155 // 156 // 157 // now the search and replace 158 type WalkFunc func(path string, info os.FileInfo, err error) error 159 fc := func(path string, info os.FileInfo, err error) error { 160 161 if !info.IsDir() || true { 162 paths1 = append(paths1, path) 163 } 164 165 if ext := filepath.Ext(path); ext == ".html" { 166 167 bts, err := ioutil.ReadFile(path) 168 if err != nil { 169 log.Printf("could not read file: %v\n", path, err) 170 return err 171 } 172 bef := len(bts) 173 bts = bytes.Replace(bts, []byte("http://localhost:1313"), []byte("/"), -1) 174 // bts = bytes.Replace(bts, []byte("©2015 Peter Buchmann"), []byte("©2015"), -1) 175 aft := len(bts) 176 err = ioutil.WriteFile(path, bts, 0777) 177 if err != nil { 178 log.Printf("could not write file: %v\n", path, err) 179 return err 180 } 181 182 // 183 // 184 log.Printf("\t %-55v %5v %5v\n", path, bef, aft) 185 } 186 return nil 187 } 188 189 filepath.Walk(dirStatPref, fc) 190 log.Printf("replacements finished...\n") 191 192 log.Printf("=========fine-new-statification=======\n") 193 194 // 195 err = os.Chdir(dirStatPref) 196 if err != nil { 197 log.Printf("could not change dir: %v\n", err) 198 return 199 } 200 curdir, _ := os.Getwd() 201 log.Printf("curdir now %v\n", curdir) 202 203 paths2 := make([]string, 0, len(paths1)) 204 for _, path := range paths1 { 205 206 if path == dirStatPref { 207 continue 208 } 209 210 ext := filepath.Ext(path) 211 ext = strings.ToLower(ext) 212 if ext != "" && // directory 213 ext != ".html" && ext != ".css" && ext != ".js" && 214 ext != ".jpg" && ext != ".gif" && ext != ".png" && ext != ".ico" { 215 log.Printf("\t skipping %v", path) 216 continue 217 } 218 219 pathAfter := strings.TrimPrefix(path, dirStat) 220 if strings.HasPrefix(pathAfter, "/") || strings.HasPrefix(pathAfter, "\\") { 221 pathAfter = pathAfter[1:] 222 } 223 paths2 = append(paths2, pathAfter) 224 // log.Printf("%-54v %-54v", path, pathAfter) 225 } 226 227 osutilpb.CreateZipFile(paths2, dirStat+".zip") 228 log.Printf("=========zip-file-created=============\n") 229 230 if tgs, ok := data1["targets"]; ok { 231 log.Printf("\t found targets ...") 232 if tgs1, ok := tgs.(map[string]interface{}); ok { 233 log.Printf("\t ... %v urls - map[string]interface{} \n", len(tgs1)) 234 235 for _, v := range tgs1 { 236 v1 := v.(string) 237 // curl --verbose -F mountname=mnt02 -F filefield=@cnt_statified.zip subdm.appspot.com/filesys/post-upload-receive 238 // -F, --form CONTENT Specify HTTP multipart POST data 239 240 // We could also use 241 // req, err := upload.CreateFilePostRequest(effUpUrl, "filefield", filePath, extraParams) 242 // and client.Do(req) 243 244 log.Printf("\t trying upload %v\n", v1) 245 if ok := osutilpb.ExecCmdWithExitCode("curl", "--verbose", 246 "-F", "mountname=mnt02", 247 "-F", "filefield=@"+dirStat+".zip", 248 v1); !ok { 249 return 250 } 251 252 // Prepend a protocol for url.Parse to behave as desired 253 if !strings.HasPrefix(v1, "http://") && !strings.HasPrefix(v1, "https://") { 254 v1 = "https://" + v1 255 } 256 url2, err := url.Parse(v1) 257 if err != nil { 258 log.Printf("could not parse url: %q - %v\n", v1, err) 259 return 260 } 261 262 url2.Path = "/reset-memfs" 263 log.Printf("\t trying reset memfs %v\n", url2.Host+url2.Path) 264 if ok := osutilpb.ExecCmdWithExitCode("curl", "--verbose", url2.Host+url2.Path); !ok { 265 return 266 } 267 268 url2.Path = "/tpl/reset" 269 log.Printf("\t trying reset templates %v\n", url2.Host+url2.Path) 270 if ok := osutilpb.ExecCmdWithExitCode("curl", "--verbose", url2.Host+url2.Path); !ok { 271 return 272 } 273 274 } 275 276 } 277 278 } 279 log.Printf("====== upload completed ==============\n") 280 log.Printf("CTRC+C to exit\n") 281 282 for i := 0; i < 300; i++ { 283 time.Sleep(100 * time.Millisecond) 284 runtime.Gosched() 285 } 286 287 }