Skip to content
Permalink
Browse files

add -no-robots, -red-logo flags

These are useful for running a second, staging instance of the website:

• no robots is used because the staging instance shouldn't be indexed
• red logo makes it possible to tell the staging instance apart

Update testdata to match.
  • Loading branch information...
dmitshur committed Sep 4, 2019
1 parent 05a34a9 commit a8cced5af713f2f38b9fcd519d68a9e8c58b43dd
@@ -14,7 +14,9 @@ import (
"strings"
"time"

"github.com/gopherjs/gopherjs/js"
"github.com/shurcooL/frontend/reactionsmenu"
homecomponent "github.com/shurcooL/home/component"
homehttp "github.com/shurcooL/home/http"
"github.com/shurcooL/home/internal/page/resume"
"github.com/shurcooL/notificationsapp/httpclient"
@@ -50,6 +52,8 @@ func setup(ctx context.Context) {
query, _ := url.ParseQuery(strings.TrimPrefix(dom.GetWindow().Location().Search, "?"))
prerender, _ := strconv.ParseBool(query.Get("prerender"))
if !prerender {
homecomponent.RedLogo = js.Global.Get("RedLogo").Bool()

httpClient := httpClient()

notificationsService := httpclient.NewNotifications(httpClient, "", "")
@@ -17,6 +17,10 @@ type Header struct {
ReturnURL string
}

// RedLogo controls whether the logo is displayed in red,
// rather than its normal color.
var RedLogo bool

// Render implements htmlg.Component.
func (h Header) Render() []*html.Node {
// TODO: Make this much nicer.
@@ -87,6 +91,15 @@ header.header .user {
float: right;
padding-top: 8px;
}`))
if RedLogo {
style.AppendChild(htmlg.Text(`
header.header a.Logo {
color: red;
}
header.header a.Logo:hover {
color: darkred;
}`))
}

header := &html.Node{
Type: html.ElementNode, Data: atom.Header.String(),
@@ -208,6 +221,7 @@ func (Logo) Render() []*html.Node {
Attr: []html.Attribute{
{Key: atom.Href.String(), Val: "/"},
{Key: atom.Style.String(), Val: "display: inline-block;"},
{Key: atom.Class.String(), Val: "Logo"},
},
}
svg := &html.Node{
@@ -32,7 +32,7 @@
header.header .user {
float: right;
padding-top: 8px;
}</style><header class="header"><a href="/" style="display: inline-block;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="32" height="32" style="fill: currentColor;
}</style><header class="header"><a href="/" style="display: inline-block;" class="Logo"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="32" height="32" style="fill: currentColor;
stroke: currentColor;
vertical-align: middle;"><circle cx="100" cy="100" r="90" stroke-width="20" fill="none"></circle><circle cx="100" cy="100" r="60"></circle></svg></a><ul class="nav"><li class="nav"><a href="/packages">Packages</a></li><li class="nav"><a href="/blog">Blog</a></li><li class="nav smaller"><a href="/idiomatic-go">Idiomatic Go</a></li><li class="nav"><a href="/talks">Talks</a></li><li class="nav"><a href="/projects">Projects</a></li><li class="nav"><a href="/resume">Resume</a></li><li class="nav"><a href="/about">About</a></li></ul><span class="user"><span style="margin-right: 10px;"><a href="/notifications" style="display: inline-block;
vertical-align: top;
@@ -32,7 +32,7 @@
header.header .user {
float: right;
padding-top: 8px;
}</style><header class="header"><a href="/" style="display: inline-block;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="32" height="32" style="fill: currentColor;
}</style><header class="header"><a href="/" style="display: inline-block;" class="Logo"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="32" height="32" style="fill: currentColor;
stroke: currentColor;
vertical-align: middle;"><circle cx="100" cy="100" r="90" stroke-width="20" fill="none"></circle><circle cx="100" cy="100" r="60"></circle></svg></a><ul class="nav"><li class="nav"><a href="/packages">Packages</a></li><li class="nav"><a href="/blog">Blog</a></li><li class="nav smaller"><a href="/idiomatic-go">Idiomatic Go</a></li><li class="nav"><a href="/talks">Talks</a></li><li class="nav"><a href="/projects">Projects</a></li><li class="nav"><a href="/resume">Resume</a></li><li class="nav"><a href="/about">About</a></li></ul><span class="user"><span style="margin-right: 10px;"><a href="/notifications" style="display: inline-block;
vertical-align: top;
25 main.go
@@ -6,6 +6,7 @@ import (
"flag"
"fmt"
"html/template"
"io"
"io/ioutil"
"log"
"mime"
@@ -17,6 +18,7 @@ import (
"time"

"github.com/shurcooL/home/assets"
"github.com/shurcooL/home/component"
"github.com/shurcooL/home/httphandler"
"github.com/shurcooL/home/httputil"
codepkg "github.com/shurcooL/home/internal/code"
@@ -34,6 +36,8 @@ var (
storeDirFlag = flag.String("store-dir", filepath.Join(os.TempDir(), "home-store"), "Directory of home store (required).")
stateFileFlag = flag.String("state-file", "", "Optional path to file to save/load state (file is deleted after loading).")
analyticsFileFlag = flag.String("analytics-file", "", "Optional path to file containing analytics HTML to insert at the beginning of <head>.")
noRobotsFlag = flag.Bool("no-robots", false, "Disallow all robots on all pages.")
redLogoFlag = flag.Bool("red-logo", false, "Display the logo in red.")
)

var (
@@ -48,13 +52,13 @@ func main() {
ctx, cancel := context.WithCancel(context.Background())
go func() { <-int; cancel() }()

err := run(ctx, cancel, *storeDirFlag, *stateFileFlag, *analyticsFileFlag)
err := run(ctx, cancel, *storeDirFlag, *stateFileFlag, *analyticsFileFlag, *noRobotsFlag, *redLogoFlag)
if err != nil {
log.Fatalln(err)
}
}

func run(ctx context.Context, cancel context.CancelFunc, storeDir, stateFile, analyticsFile string) error {
func run(ctx context.Context, cancel context.CancelFunc, storeDir, stateFile, analyticsFile string, noRobots, redLogo bool) error {
if err := mime.AddExtensionType(".md", "text/markdown"); err != nil {
return err
}
@@ -69,6 +73,23 @@ func run(ctx context.Context, cancel context.CancelFunc, storeDir, stateFile, an
}
analyticsHTML = template.HTML(b)
}
if noRobots {
http.HandleFunc("/robots.txt", func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
io.WriteString(w, "User-agent: *\nDisallow: /\n")
})
}
if redLogo {
component.RedLogo = true
http.HandleFunc("/icon.png", func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "image/png")
w.Header()["Content-Encoding"] = nil // Disable automatic gzip compression, png is already compressed.
err := serveFile(w, req, filepath.Join(os.Getenv("HOME"), "Dropbox", "Public", "dmitri", "icon-red.png"))
if err != nil {
log.Println(`serveFile("icon-red.png"):`, err)
}
})
}

initStores := func(storeDir string) error {
// Make sure storeDir exists and is a directory.
@@ -23,6 +23,7 @@ var resumeHTML = template.Must(template.New("").Funcs(template.FuncMap{"noescape
<meta name="viewport" content="width=device-width">
<link href="/assets/fonts/fonts.css" rel="stylesheet" type="text/css">
<link href="/assets/resume/style.css" rel="stylesheet" type="text/css">
<script>var RedLogo = {{.RedLogo}};</script>
{{noescape "<!-- Unminified source is at https://github.com/shurcooL/resume. -->"}}
<script async src="/assets/resume/resume.js"></script>
@@ -36,7 +37,10 @@ func initResume(reactions reactions.Service, notifications notifications.Service
}

w.Header().Set("Content-Type", "text/html; charset=utf-8")
data := struct{ AnalyticsHTML template.HTML }{analyticsHTML}
data := struct {
AnalyticsHTML template.HTML
RedLogo bool
}{analyticsHTML, *redLogoFlag}
err := resumeHTML.Execute(w, data)
if err != nil {
return err
18 util.go
@@ -3,6 +3,9 @@ package main
import (
"net/http"
"net/url"
"os"

"github.com/shurcooL/httpgzip"
)

// copyRequestAndURL returns a copy of req and its URL field.
@@ -27,3 +30,18 @@ func stripPrefix(r *http.Request, prefixLen int) *http.Request {
}
return r2
}

// serveFile opens the file at path and serves it using httpgzip.ServeContent.
func serveFile(w http.ResponseWriter, req *http.Request, path string) error {
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
fi, err := f.Stat()
if err != nil {
return err
}
httpgzip.ServeContent(w, req, fi.Name(), fi.ModTime(), f)
return nil
}

0 comments on commit a8cced5

Please sign in to comment.
You can’t perform that action at this time.