Skip to content

Instantly share code, notes, and snippets.

@tenox7
Last active January 4, 2022 23:24
Show Gist options
  • Save tenox7/b9af5145987c298dd8f71ed39f8fd946 to your computer and use it in GitHub Desktop.
Save tenox7/b9af5145987c298dd8f71ed39f8fd946 to your computer and use it in GitHub Desktop.
// generate index file under gcs bucket prefix (non recursive, one level only)
package main
import (
"context"
"flag"
"fmt"
"html"
"log"
"path/filepath"
"strings"
"cloud.google.com/go/storage"
"github.com/dustin/go-humanize"
"google.golang.org/api/iterator"
)
var (
bucket = flag.String("bucket", "", "cloud storage bucket name")
prefix = flag.String("prefix", "", "prefix where to list/create index file")
dryRun = flag.Bool("dry_run", false, "do not write the index file")
)
func listFiles(ctx context.Context, b *storage.BucketHandle, pfx string) (string, error) {
var out strings.Builder
fmt.Fprintf(&out, "<html><body>\n")
o := b.Objects(ctx, &storage.Query{Prefix: pfx, Delimiter: "/"})
for {
oa, err := o.Next()
if err == iterator.Done {
break
}
if err != nil {
return "", err
}
if filepath.Base(oa.Name) == "index.html" || filepath.Base(oa.Name) == "." {
continue
}
fmt.Fprintf(&out, "<a href=\"%v\">%v</a> (%v)<br>\n",
html.EscapeString(filepath.Base(oa.Name)),
filepath.Base(oa.Name),
humanize.Bytes(uint64(oa.Size)),
)
}
fmt.Fprintf(&out, "</body></html>\n")
return out.String(), nil
}
func writeIndex(ctx context.Context, b *storage.BucketHandle, f, idx string) error {
bf := b.Object(f).NewWriter(ctx)
bf.ContentType = "text/html"
n, err := bf.Write([]byte(idx))
if err != nil {
return err
}
err = bf.Close()
if err != nil {
return err
}
if n != len(idx) {
return fmt.Errorf("len of index (%v) != bytes written (%v", len(idx), n)
}
return nil
}
func main() {
flag.Parse()
ctx := context.Background()
if *bucket == "" {
log.Fatalf("Bucket name not specified")
}
c, err := storage.NewClient(ctx)
if err != nil {
log.Fatalf("Opening storage client: %v", err)
}
b := c.Bucket(*bucket)
idx, err := listFiles(ctx, b, *prefix)
if err != nil {
log.Fatal(err)
}
if *dryRun {
fmt.Println(idx)
return
}
err = writeIndex(ctx, b, filepath.Clean(*prefix+"/index.html"), idx)
if err != nil {
log.Fatal(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment