<commit_before>// package main is a robust modern todolist service
package main

import (
	"database/sql"
	"encoding/json"
	"html"
	"html/template"
	"log"
	"net/http"
	"os"

	// uniuri for random string generation
	"github.com/dchest/uniuri"
	// mysql driver
	_ "github.com/go-sql-driver/mysql"
	// mux routing
	"github.com/gorilla/mux"
	// securecookie for cookie handling
	"github.com/gorilla/securecookie"
	// bcrypt for password hashing
	"golang.org/x/crypto/bcrypt"
)

type Configuration struct {
	// PORT for golang to listen on
	Port string
	// LENGTH todo name length
	Length int
	// USERNAME database username
	Username string
	// PASS database password
	Password string
	// NAME database name
	Name string
}

var configuration Configuration

// DATABASE connection String
var DATABASE string

var templates = template.Must(template.ParseFiles("static/index.html", "static/login.html", "static/register.html", "static/todo.html", "static/task.html"))

// generate new random cookie keys
var cookieHandler = securecookie.New(
	securecookie.GenerateRandomKey(64),
	securecookie.GenerateRandomKey(32),
)

// User struct
type User struct {
	ID       int
	Email    string
	Password string
}

// Tasks todo tasks struct
type Tasks struct {
	Name      string `json:"name"`
	Title     string `json:"title"`
	Task      string `json:"task"`
	Created   string `json:"created"`
	DueDate   string `json:"duedate"`
	Email     string `json:"email"`
	Completed bool   `json:"completed"`
	Public    bool   `json:"public"`
	Allday    bool   `json:"allday"`
}

// Page []Tasks struct
type Page struct {
	Tasks []Tasks `json:"tasks"`
}

// Cal fullcalendar struct
type Cal struct {
	Title       string `json:"title"`
	Description string `json:"description"`
	Start       string `json:"start"`
	End         string `json:"end"`
	Allday      bool   `json:"allDay"`
	URL         string `json:"url"`
}

// checkErr logger
func checkErr(err error) {
	if err != nil {
		log.Println(err)
	}
}

// genName Random name geneation function
func genName() string {
	// use uniuri to generate random string
	name := uniuri.NewLen(configuration.Length)

	// open db connection
	db, err := sql.Open("mysql", DATABASE)
	checkErr(err)

	_, err = db.Query("select name from tasks where name=?", name)
	db.Close()
	// if name exists in db call genName again
	if err != sql.ErrNoRows {
		genName()
	}
	checkErr(err)
	// return random string
	return name
}

// loggedIn returns true if cookie exists
func loggedIn(r *http.Request) bool {
	cookie, err := r.Cookie("session")
	cookieValue := make(map[string]string)
	if err != nil {
		return false
	}
	err = cookieHandler.Decode("session", cookie.Value, &cookieValue)
	if err != nil {
		return false
	}
	return true

}

// getEmail returns the users email address from cookie
func getEmail(r *http.Request) (string, error) {
	cookie, err := r.Cookie("session")
	cookieValue := make(map[string]string)
	if err != nil {
		return "", err
	}
	err = cookieHandler.Decode("session", cookie.Value, &cookieValue)
	if err != nil {
		return "", err
	}
	return cookieValue["email"], nil

}

// rootHandler root page handler
func rootHandler(w http.ResponseWriter, r *http.Request) {
	// check if user is logged in, if not redirect to login page
	if loggedIn(r) != true {
		http.Redirect(w, r, "/login", 302)
	}

	err := templates.ExecuteTemplate(w, "index.html", "")
	checkErr(err)
}

// calHandler generates json string that is fullcalendar compatible
func calHandler(w http.ResponseWriter, r *http.Request) {
	// check if user is logged in, if not redirect to login page
	if loggedIn(r) != true {
		http.Redirect(w, r, "/login", 302)
	}
	db, err := sql.Open("mysql", DATABASE)
	checkErr(err)

	email, err := getEmail(r)
	checkErr(err)

	rows, err := db.Query("select title, task, created, duedate, allday, name from tasks where email=? order by duedate asc", email)
	checkErr(err)

	b := []Cal{}

	for rows.Next() {
		res := Cal{}
		rows.Scan(&res.Title, &res.Description, &res.Start, &res.End, &res.Allday, &res.URL)

		b = append(b, res)
	}
	db.Close()

	checkErr(err)
	w.Header().Set("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

}

// taskHandler
func taskHandler(w http.ResponseWriter, r *http.Request) {
	// check if user is logged in, if not redirect to login page
	if loggedIn(r) != true {
		http.Redirect(w, r, "/login", 302)
	}

	db, err := sql.Open("mysql", DATABASE)
	checkErr(err)

	email, err := getEmail(r)
	checkErr(err)

	rows, err := db.Query("select name, title, task, created, duedate from tasks where email=? order by duedate asc", email)
	checkErr(err)<commit_msg>Add more comments<commit_after>// package main is a robust modern todolist service
package main

import (
	"database/sql"
	"encoding/json"
	"html"
	"html/template"
	"log"
	"net/http"
	"os"

	// uniuri for random string generation
	"github.com/dchest/uniuri"
	// mysql driver
	_ "github.com/go-sql-driver/mysql"
	// mux routing
	"github.com/gorilla/mux"
	// securecookie for cookie handling
	"github.com/gorilla/securecookie"
	// bcrypt for password hashing
	"golang.org/x/crypto/bcrypt"
)

type Configuration struct {
	// PORT for golang to listen on
	Port string
	// LENGTH todo name length
	Length int
	// USERNAME database username
	Username string
	// PASS database password
	Password string
	// NAME database name
	Name string
}

var configuration Configuration

// DATABASE connection String
var DATABASE string

var templates = template.Must(template.ParseFiles("static/index.html", "static/login.html", "static/register.html", "static/todo.html", "static/task.html"))

// generate new random cookie keys
var cookieHandler = securecookie.New(
	securecookie.GenerateRandomKey(64),
	securecookie.GenerateRandomKey(32),
)

// User struct
type User struct {
	ID       int
	Email    string
	Password string
}

// Tasks todo tasks struct
type Tasks struct {
	Name      string `json:"name"`
	Title     string `json:"title"`
	Task      string `json:"task"`
	Created   string `json:"created"`
	DueDate   string `json:"duedate"`
	Email     string `json:"email"`
	Completed bool   `json:"completed"`
	Public    bool   `json:"public"`
	Allday    bool   `json:"allday"`
}

// Page []Tasks struct
type Page struct {
	Tasks []Tasks `json:"tasks"`
}

// Cal fullcalendar struct
type Cal struct {
	Title       string `json:"title"`
	Description string `json:"description"`
	Start       string `json:"start"`
	End         string `json:"end"`
	Allday      bool   `json:"allDay"`
	URL         string `json:"url"`
}

// checkErr logger
func checkErr(err error) {
	if err != nil {
		log.Println(err)
	}
}

// genName Random name geneation function
func genName() string {
	// use uniuri to generate random string
	name := uniuri.NewLen(configuration.Length)

	// open db connection
	db, err := sql.Open("mysql", DATABASE)
	checkErr(err)

	_, err = db.Query("select name from tasks where name=?", name)
	db.Close()
	// if name exists in db call genName again
	if err != sql.ErrNoRows {
		genName()
	}
	checkErr(err)
	// return random string
	return name
}

// loggedIn returns true if cookie exists
func loggedIn(r *http.Request) bool {
	cookie, err := r.Cookie("session")
	cookieValue := make(map[string]string)
	if err != nil {
		return false
	}
	err = cookieHandler.Decode("session", cookie.Value, &cookieValue)
	if err != nil {
		return false
	}
	return true

}

// getEmail returns the users email address from cookie
func getEmail(r *http.Request) (string, error) {
	cookie, err := r.Cookie("session")
	cookieValue := make(map[string]string)
	if err != nil {
		return "", err
	}
	err = cookieHandler.Decode("session", cookie.Value, &cookieValue)
	if err != nil {
		return "", err
	}
	return cookieValue["email"], nil

}

// rootHandler root page handler
func rootHandler(w http.ResponseWriter, r *http.Request) {
	// check if user is logged in, if not redirect to login page
	if loggedIn(r) != true {
		http.Redirect(w, r, "/login", 302)
	}

	err := templates.ExecuteTemplate(w, "index.html", "")
	checkErr(err)
}

// calHandler generates json string that is fullcalendar compatible
func calHandler(w http.ResponseWriter, r *http.Request) {
	// check if user is logged in, if not redirect to login page
	if loggedIn(r) != true {
		http.Redirect(w, r, "/login", 302)
	}
	db, err := sql.Open("mysql", DATABASE)
	checkErr(err)

	email, err := getEmail(r)
	checkErr(err)

	rows, err := db.Query("select title, task, created, duedate, allday, name from tasks where email=? order by duedate asc", email)
	checkErr(err)

	b := []Cal{}

	for rows.Next() {
		res := Cal{}
		// scan from db into Struct
		rows.Scan(&res.Title, &res.Description, &res.Start, &res.End, &res.Allday, &res.URL)

		// append Cal to array
		b = append(b, res)
	}
	db.Close()

	checkErr(err)
	w.Header().Set("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

}

// taskHandler
func taskHandler(w http.ResponseWriter, r *http.Request) {
	// check if user is logged in, if not redirect to login page
	if loggedIn(r) != true {
		http.Redirect(w, r, "/login", 302)
	}

	db, err := sql.Open("mysql", DATABASE)
	checkErr(err)

	// get the users email
	email, err := getEmail(r)
	checkErr(err)

	rows, err := db.Query("select name, title, task, created, duedate from tasks where email=? order by duedate asc", email)
	checkErr(err)
{'fraction_non_alphanumeric': 0.13261761919797915, 'fraction_numerical': 0.002736554046942427, 'mean_word_length': 3.7320717131474104, 'pattern_counts': {'":': 0, '<': 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': '7398550', 'n_tokens_mistral': 3255, 'n_tokens_neox': 3145, 'n_words': 964}