Added folder for german translation

This commit is contained in:
digitalcraftsman
2015-06-23 20:04:41 +02:00
parent bdd5423884
commit e47666b0ab
270 changed files with 16240 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
package main
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
)
func checkError(err error) {
if err != nil {
panic(err)
}
}
func postFile(filename string, targetUrl string) {
bodyBuf := &bytes.Buffer{}
bodyWriter := multipart.NewWriter(bodyBuf)
fileWriter, err := bodyWriter.CreateFormFile("uploadfile", filename)
checkError(err)
fh, err := os.Open(filename)
checkError(err)
_, err = io.Copy(fileWriter, fh)
checkError(err)
contentType := bodyWriter.FormDataContentType()
bodyWriter.Close()
resp, err := http.Post(targetUrl, contentType, bodyBuf)
checkError(err)
defer resp.Body.Close()
resp_body, err := ioutil.ReadAll(resp.Body)
checkError(err)
fmt.Println(resp.Status)
fmt.Println(string(resp_body))
}
func main() {
target_url := "http://localhost:9090/upload"
filename := "../file.txt"
postFile(filename, target_url)
}

View File

@@ -0,0 +1,15 @@
{{define "index"}}
<!doctype html>
<html>
<head>
<title>Upload file</title>
</head>
<body>
<form enctype="multipart/form-data" action="http://127.0.0.1:9090/upload" method="post">
<input type="file" name="uploadfile" />
<input type="hidden" name="token" value="{{.}}"/>
<input type="submit" value="upload" />
</form>
</body>
</html>
{{end}}

View File

@@ -0,0 +1,64 @@
// Example code for Chapter 4.5
// Purpose is to create a server to handle uploading files.
package main
import (
"apps/ch.4.4/nonce"
"apps/ch.4.4/validator"
"fmt"
"html/template"
"io"
"mime/multipart"
"net/http"
"os"
)
const MiB_UNIT = 1 << 20
var t *template.Template
var submissions nonce.Nonces = nonce.New()
func checkError(err error) {
if err != nil {
panic(err)
}
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
err := t.ExecuteTemplate(w, "index", submissions.NewToken())
checkError(err)
}
func uploadHandler(w http.ResponseWriter, r *http.Request) {
var errs validator.Errors
r.ParseMultipartForm(32 * MiB_UNIT)
token := r.Form.Get("token")
if err := submissions.CheckThenMarkToken(token); err != nil {
errs = validator.Errors{[]error{err}}
} else {
file, handler, err := r.FormFile("uploadfile")
checkError(err)
saveUpload(file, handler)
}
err := t.ExecuteTemplate(w, "upload", errs)
checkError(err)
}
func saveUpload(file multipart.File, handler *multipart.FileHeader) {
defer file.Close()
fmt.Printf("Uploaded file info: %#v", handler.Header)
localFilename := fmt.Sprintf("./uploads/%v.%v", handler.Filename, submissions.NewToken())
f, err := os.OpenFile(localFilename, os.O_WRONLY|os.O_CREATE, 0666)
checkError(err)
defer f.Close()
_, err = io.Copy(f, file)
checkError(err)
}
func init() {
var err error
t, err = template.ParseFiles("index.gtpl", "upload.gtpl")
checkError(err)
}
func main() {
http.HandleFunc("/", indexHandler)
http.HandleFunc("/upload", uploadHandler)
err := http.ListenAndServe(":9090", nil)
checkError(err)
}

View File

@@ -0,0 +1,70 @@
// A nonce is a number or string used only once.
// This is useful for generating a unique token for login pages to prevent duplicate submissions.
package nonce
import (
"crypto/md5"
"errors"
"fmt"
"io"
"math/rand"
"strconv"
"time"
)
// Contains a unique token
type Nonce struct {
Token string
}
// Keeps track of marked/used tokens
type Nonces struct {
hashs map[string]bool
}
func New() Nonces {
return Nonces{make(map[string]bool)}
}
func (n *Nonces) NewNonce() Nonce {
return Nonce{n.NewToken()}
}
// Returns a new unique token
func (n *Nonces) NewToken() string {
t := createToken()
for n.HasToken(t) {
t = createToken()
}
return t
}
// Checks if token has been marked.
func (n *Nonces) HasToken(token string) bool {
return n.hashs[token] == true
}
func (n *Nonces) MarkToken(token string) {
n.hashs[token] = true
}
func (n *Nonces) CheckToken(token string) error {
if token == "" {
return errors.New("No token supplied")
}
if n.HasToken(token) {
return errors.New("Duplicate submission.")
}
return nil
}
func (n *Nonces) CheckThenMarkToken(token string) error {
defer n.MarkToken(token)
if err := n.CheckToken(token); err != nil {
return err
}
return nil
}
func createToken() string {
h := md5.New()
now := time.Now().Unix()
io.WriteString(h, strconv.FormatInt(now, 10))
io.WriteString(h, strconv.FormatInt(rand.Int63(), 10))
return fmt.Sprintf("%x", h.Sum(nil))
}

View File

@@ -0,0 +1,17 @@
{{define "upload"}}<!DOCTYPE html>
<html>
<body>
{{if .Errors}}
<h2>Errors:</h2>
<ol>
{{range .Errors}}
<li>{{.}}</li>
{{end}}
</ol>
{{else}}
File uploaded successfully.<br/>
Note: Refreshing the page will produce a duplicate entry.
{{end}}
</body>
</html>
{{end}}

View File

@@ -0,0 +1,175 @@
// This file contains all the validators to validate the profile page.
package validator
import (
"errors"
"fmt"
"net/url"
"regexp"
"strconv"
"strings"
"time"
)
type ProfilePage struct {
Form *url.Values
}
type Errors struct {
Errors []error
}
// Goes through the form object and validates each element.
// Attachs an error to the output if validation fails.
func (p *ProfilePage) GetErrors() Errors {
errs := make([]error, 0, 10)
if *p.Form == nil || len(*p.Form) < 1 {
errs = append(errs, errors.New("No data was received. Please submit from the profile page."))
}
for name, val := range *p.Form {
if fn, ok := stringValidator[name]; ok {
if err := fn(strings.Join(val, "")); err != nil {
errs = append(errs, err)
}
} else {
if fn, ok := stringsValidator[name]; ok {
if err := fn(val); err != nil {
errs = append(errs, err)
}
}
}
}
return Errors{errs}
}
const (
// Used for parsing the time
mmddyyyyForm = "01/02/2006" // we want the date sent in this format
yyyymmddForm = "2006-01-02" // However, HTML5 pages send the date in this format
)
var stringValidator map[string]func(string) error = map[string]func(string) error{
// parameter name : validator reference
"age": checkAge,
"birthday": checkDate,
"chineseName": checkChineseName,
"email": checkEmail,
"gender": checkGender,
"shirtsize": checkShirtSize,
"username": checkUsername,
}
var stringsValidator map[string]func([]string) error = map[string]func([]string) error{
// parameter name : validator reference
"sibling": checkSibling,
}
// Returns true if slices have a common element
func doSlicesIntersect(s1, s2 []string) bool {
if s1 == nil || s2 == nil {
return false
}
for _, str := range s1 {
if isElementInSlice(str, s2) {
return true
}
}
return false
}
func isElementInSlice(str string, sl []string) bool {
if sl == nil || str == "" {
return false
}
for _, v := range sl {
if v == str {
return true
}
}
return false
}
// Checks if all the characters are chinese characters. Won't check if empty.'
func checkChineseName(str string) error {
if str != "" {
if m, _ := regexp.MatchString("^[\\x{4e00}-\\x{9fa5}]+$", strings.Trim(str, " ")); !m {
return errors.New("Please make sure that the chinese name only contains chinese characters.")
}
}
return nil
}
// Checks if a user name exist.
func checkUsername(str string) error {
if strings.Trim(str, " ") == "" {
return errors.New("Please enter a username.")
}
return nil
}
// Check if age is a number and between 13 and 130
func checkAge(str string) error {
age, err := strconv.Atoi(str)
if str == "" || err != nil {
return errors.New("Please enter a valid age.")
}
if age < 13 {
return errors.New("You must be at least 13 years of age to submit.")
}
if age > 130 {
return errors.New("You're too old to register, grandpa.")
}
return nil
}
func checkEmail(str string) error {
if m, err := regexp.MatchString(`^[^@]+@[^@]+$`, str); !m {
fmt.Println("err = ", err)
return errors.New("Please enter a valid email address.")
}
return nil
}
// Checks if a valid date was passed.
func checkDate(str string) error {
_, err := time.Parse(mmddyyyyForm, str)
if err != nil {
_, err = time.Parse(yyyymmddForm, str)
}
if str == "" || err != nil {
return errors.New("Please enter a valid Date.")
}
return nil
}
// Checks if the passed input is a known gender option
func checkGender(str string) error {
if str == "" {
return nil
}
siblings := []string{"m", "f", "na"}
if !isElementInSlice(str, siblings) {
return errors.New("Please select a valid gender.")
}
return nil
}
// Check if all the values are known options.
func checkSibling(strs []string) error {
if strs == nil || len(strs) < 1 {
return nil
}
siblings := []string{"m", "f"}
if siblings != nil && !doSlicesIntersect(siblings, strs) {
return errors.New("Please select a valid sibling")
}
return nil
}
// Checks if the shirt size is a known option.
func checkShirtSize(str string) error {
if str == "" {
return nil
}
shirts := []string{"s", "m", "l", "xl", "xxl"}
if !isElementInSlice(str, shirts) {
return errors.New("Please select a valid shirt size")
}
return nil
}