<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"html/template"
	"koding/artifact"
	"koding/db/models"
	"koding/db/mongodb/modelhelper"
	"koding/go-webserver/templates"
	"koding/tools/config"
	"net/http"
	"runtime"
	"time"

	"github.com/koding/logging"
)

var (
	Name        = "gowebserver"
	flagConfig  = flag.String("c", "", "Configuration profile from file")
	log         = logging.NewLogger(Name)
	kodingGroup *models.Group
	conf        *config.Config
)

type HomeContent struct {
	Version string
	Runtime config.RuntimeOptions
	User    LoggedInUser
}

type LoggedInUser struct {
	Account    *models.Account
	Machines   []*modelhelper.MachineContainer
	Workspaces []*models.Workspace
	Group      *models.Group
	Username   string
	SessionId  string
}

func initialize() {
	runtime.GOMAXPROCS(runtime.NumCPU() - 1)

	flag.Parse()
	if *flagConfig == "" {
		log.Critical("Please define config file with -c")
	}

	conf = config.MustConfig(*flagConfig)
	modelhelper.Initialize(conf.Mongo)

	var err error
	kodingGroup, err = modelhelper.GetGroup("koding")
	if err != nil {
		log.Critical("Couldn't fetching `koding` group: %v", err)
		panic(err)
	}
}

func main() {
	initialize()

	url := fmt.Sprintf(":%d", conf.Gowebserver.Port)

	log.Info("Starting gowebserver on %v", url)

	http.HandleFunc("/", HomeHandler)
	http.HandleFunc("/version", artifact.VersionHandler())
	http.HandleFunc("/healthCheck", artifact.HealthCheckHandler(Name))
	http.ListenAndServe(url, nil)
}

func HomeHandler(w http.ResponseWriter, r *http.Request) {
	start := time.Now()

	cookie, err := r.Cookie("clientId")
	if err != nil {
		if err != http.ErrNoCookie {
			log.Error("Couldn't fetch the cookie: %s", err)
		}
		log.Info("loggedout page took: %s", time.Since(start))
		renderLoggedOutHome(w)

		return
	}

	if cookie.Value == "" {
		log.Info("loggedout page took: %s", time.Since(start))
		renderLoggedOutHome(w)

		return
	}

	clientId := cookie.Value

	session, err := modelhelper.GetSession(clientId)
	if err != nil {
		log.Error("Couldn't fetch session with clientId %s: %s", clientId, err)
		log.Info("loggedout page took: %s", time.Since(start))

		renderLoggedOutHome(w) // TODO: clean up session

		return
	}

	username := session.Username
	if username == "" {
		log.Error("Username is empty for session with clientId: %s", clientId)
		log.Info("loggedout page took: %s", time.Since(start))

		renderLoggedOutHome(w)

		return
	}

	//----------------------------------------------------------
	// Account
	//----------------------------------------------------------

	account, err := modelhelper.GetAccount(username)
	if err != nil {
		log.Error("Couldn't fetch account with username %s: %s", username, err)
		log.Info("loggedout page took: %s", time.Since(start))

		renderLoggedOutHome(w)

		return
	}

	if account.Type != "registered" {
		log.Info("loggedout page took: %s", time.Since(start))
		renderLoggedOutHome(w)

		return
	}

	//----------------------------------------------------------
	// Machines
	//----------------------------------------------------------

	user, err := modelhelper.GetUser(username)
	if err != nil {
		log.Error("Couldn't get user of %s: %s", username, err)
		log.Info("loggedout page took: %s", time.Since(start))

		renderLoggedOutHome(w)
	}

	machines, err := modelhelper.GetMachines(user.ObjectId)
	if err != nil {
		log.Error("Couldn't fetch machines: %s", err)
		machines = []*modelhelper.MachineContainer{}
	}

	//----------------------------------------------------------
	// Workspaces
	//----------------------------------------------------------

	workspaces, err := modelhelper.GetWorkspaces(account.Id)
	if err != nil {
		log.Error("Couldn't fetch workspaces: %s", err)
		workspaces = []*models.Workspace{}
	}

	loggedInUser := LoggedInUser{
		SessionId:  clientId,
		Group:      kodingGroup,
		Workspaces: workspaces,
		Machines:   machines,
		Account:    account,
		Username:   username,
	}

	renderLoggedInHome(w, loggedInUser)

	log.Info("loggedin page took: %s", time.Since(start))
}

func renderLoggedInHome(w http.ResponseWriter, u LoggedInUser) {
	homeTmpl := template.Must(template.New("home").Parse(templates.LoggedInHome))
	hc := HomeContent{Version: conf.Version, Runtime: conf.Client.RuntimeOptions, User: u}

	var buf bytes.Buffer
	if err := homeTmpl.Execute(&buf, hc); err != nil {
		log.Error("Failed to render loggedin page: %s", err)
		renderLoggedOutHome(w)

		return
	}

	fmt.Fprintf(w, buf.String())
}

func renderLoggedOutHome(w http.ResponseWriter) {
	homeTmpl := template.Must(template.New("home").Parse(templates.LoggedOutHome))
	hc := HomeContent{Version: conf.Version}

	var buf bytes.Buffer
	if err := homeTmpl.Execute(&buf, hc); err != nil {
		log.Error("Failed to render loggedout page: %s", err)
	}

	fmt.Fprintf(w, buf.String())
}
<commit_msg>seo: add title, description fields to homecontent<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"html/template"
	"koding/artifact"
	"koding/db/models"
	"koding/db/mongodb/modelhelper"
	"koding/go-webserver/templates"
	"koding/tools/config"
	"net/http"
	"runtime"
	"time"

	"github.com/koding/logging"
)

var (
	Name        = "gowebserver"
	flagConfig  = flag.String("c", "", "Configuration profile from file")
	log         = logging.NewLogger(Name)
	kodingGroup *models.Group
	conf        *config.Config
)

type HomeContent struct {
	Version     string
	Runtime     config.RuntimeOptions
	User        LoggedInUser
	Title       string
	Description string
	ShareUrl    string
}

type LoggedInUser struct {
	Account    *models.Account
	Machines   []*modelhelper.MachineContainer
	Workspaces []*models.Workspace
	Group      *models.Group
	Username   string
	SessionId  string
}

func initialize() {
	runtime.GOMAXPROCS(runtime.NumCPU() - 1)

	flag.Parse()
	if *flagConfig == "" {
		log.Critical("Please define config file with -c")
	}

	conf = config.MustConfig(*flagConfig)
	modelhelper.Initialize(conf.Mongo)

	var err error
	kodingGroup, err = modelhelper.GetGroup("koding")
	if err != nil {
		log.Critical("Couldn't fetching `koding` group: %v", err)
		panic(err)
	}
}

func main() {
	initialize()

	url := fmt.Sprintf(":%d", conf.Gowebserver.Port)

	log.Info("Starting gowebserver on %v", url)

	http.HandleFunc("/", HomeHandler)
	http.HandleFunc("/version", artifact.VersionHandler())
	http.HandleFunc("/healthCheck", artifact.HealthCheckHandler(Name))
	http.ListenAndServe(url, nil)
}

func HomeHandler(w http.ResponseWriter, r *http.Request) {
	start := time.Now()

	cookie, err := r.Cookie("clientId")
	if err != nil {
		if err != http.ErrNoCookie {
			log.Error("Couldn't fetch the cookie: %s", err)
		}
		log.Info("loggedout page took: %s", time.Since(start))
		renderLoggedOutHome(w)

		return
	}

	if cookie.Value == "" {
		log.Info("loggedout page took: %s", time.Since(start))
		renderLoggedOutHome(w)

		return
	}

	clientId := cookie.Value

	session, err := modelhelper.GetSession(clientId)
	if err != nil {
		log.Error("Couldn't fetch session with clientId %s: %s", clientId, err)
		log.Info("loggedout page took: %s", time.Since(start))

		renderLoggedOutHome(w) // TODO: clean up session

		return
	}

	username := session.Username
	if username == "" {
		log.Error("Username is empty for session with clientId: %s", clientId)
		log.Info("loggedout page took: %s", time.Since(start))

		renderLoggedOutHome(w)

		return
	}

	//----------------------------------------------------------
	// Account
	//----------------------------------------------------------

	account, err := modelhelper.GetAccount(username)
	if err != nil {
		log.Error("Couldn't fetch account with username %s: %s", username, err)
		log.Info("loggedout page took: %s", time.Since(start))

		renderLoggedOutHome(w)

		return
	}

	if account.Type != "registered" {
		log.Info("loggedout page took: %s", time.Since(start))
		renderLoggedOutHome(w)

		return
	}

	//----------------------------------------------------------
	// Machines
	//----------------------------------------------------------

	user, err := modelhelper.GetUser(username)
	if err != nil {
		log.Error("Couldn't get user of %s: %s", username, err)
		log.Info("loggedout page took: %s", time.Since(start))

		renderLoggedOutHome(w)
	}

	machines, err := modelhelper.GetMachines(user.ObjectId)
	if err != nil {
		log.Error("Couldn't fetch machines: %s", err)
		machines = []*modelhelper.MachineContainer{}
	}

	//----------------------------------------------------------
	// Workspaces
	//----------------------------------------------------------

	workspaces, err := modelhelper.GetWorkspaces(account.Id)
	if err != nil {
		log.Error("Couldn't fetch workspaces: %s", err)
		workspaces = []*models.Workspace{}
	}

	loggedInUser := LoggedInUser{
		SessionId:  clientId,
		Group:      kodingGroup,
		Workspaces: workspaces,
		Machines:   machines,
		Account:    account,
		Username:   username,
	}

	renderLoggedInHome(w, loggedInUser)

	log.Info("loggedin page took: %s", time.Since(start))
}

func renderLoggedInHome(w http.ResponseWriter, u LoggedInUser) {
	homeTmpl := template.Must(template.New("home").Parse(templates.LoggedInHome))
	hc := HomeContent{Version: conf.Version, Runtime: conf.Client.RuntimeOptions, User: u}

	var buf bytes.Buffer
	if err := homeTmpl.Execute(&buf, hc); err != nil {
		log.Error("Failed to render loggedin page: %s", err)
		renderLoggedOutHome(w)

		return
	}

	fmt.Fprintf(w, buf.String())
}

func renderLoggedOutHome(w http.ResponseWriter) {
	homeTmpl := template.Must(template.New("home").Parse(templates.LoggedOutHome))
	hc := HomeContent{Version: conf.Version}

	var buf bytes.Buffer
	if err := homeTmpl.Execute(&buf, hc); err != nil {
		log.Error("Failed to render loggedout page: %s", err)
	}

	fmt.Fprintf(w, buf.String())
}

{'fraction_non_alphanumeric': 0.20508092603974595, 'fraction_numerical': 0.0002048760499897562, 'mean_word_length': 2.94146144529673, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3213795', 'n_tokens_mistral': 3420, 'n_tokens_neox': 3191, 'n_words': 720}