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("&copy;2015 Peter Buchmann"), []byte("&copy;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  }