Ejemplo n.º 1
0
func InitServer() *martini.ClassicMartini {
	envFileName := martini.Env + ".env"
	err := godotenv.Load(envFileName)
	if err != nil {
		log.Fatalf("Error loading: %s", envFileName)
	}

	m := martini.Classic()
	m.Map(db.Connect())

	m.Use(render.Renderer(render.Options{
		Layout: "layout",
	}))

	m.Get("/", func(r render.Render) {
		r.HTML(200, "home", "")
	})
	m.Get("/api/projects", controllers.ProjectIndex)
	m.Get("/api/projects/new", controllers.ProjectNew)
	m.Get("/api/projects/:id", controllers.ProjectGet)
	m.Post("/api/projects", binding.Bind(models.Project{}), controllers.ProjectCreate)
	m.Put("/api/projects/:id", binding.Bind(models.Project{}), controllers.ProjectUpdate)
	m.Delete("/api/projects/:id", controllers.ProjectDelete)

	return m
}
Ejemplo n.º 2
0
func Signin(m *martini.ClassicMartini) {
	m.Get("/signin", func(r render.Render) {
		r.HTML(200, "signin", nil)
	})
	m.Post("/signin", func(session sessions.Session) {
		fmt.Println("session set..")
		session.Set("hello", "world")
		//	return "OK"
	})
	m.Post("/signin", binding.Bind(UserSignin{}), func(usersingin UserSignin) string {
		// This function won't execute if there were errors
		if userpost, err := QueryUser(usersingin); err != false {
			//http.Redirect(w, r, "/profile", http.StatusFound)
			//return userpost.UName
			s := "<html>"
			s += userpost.UName
			s += `,恭喜你通过验证,请 <a href="/">回首页</a></html>`

			//sessions.Session.Set(userpost.UEmail, userpost.UName)
			//sessions.Session.("hello", "world")
			fmt.Println(s)
			//martini.Context.Next()
			return s
		} else {
			return "query DB failed"
		}
	})

}
Ejemplo n.º 3
0
func main() {
	//go ServeWebsocket()
	m := martini.Classic()
	m.Use(render.Renderer(render.Options{
		Layout: "layout",
	}))
	m.Use(martini.Static("assets"))

	m.Get("/", func(r render.Render) {
		r.HTML(200, "index", "index")
	})
	// api group
	m.Group("/api", func(r martini.Router) {
		r.Post("/log", binding.Bind(Log{}), NewLog)
		r.Get("/log/:appname", func(args martini.Params, r render.Render) {
			logs, err := GetLogForApp(args["appname"])
			if err != nil {
				r.JSON(200, map[string]interface{}{})
			}
			r.JSON(200, logs)
		})
	})

	//websocket
	m.Get("/sock/:appname", socketHandler)
	m.Run()
}
Ejemplo n.º 4
0
func main() {
	m := martini.Classic()
	dbMap := initDb()
	m.Map(dbMap)
	store := sessions.NewCookieStore([]byte("nonotestetstsst"))
	m.Use(sessions.Sessions("gogonki", store))
	m.Use(render.Renderer())
	m.Get("/", Index)

	m.Get("/coords", Coords)
	m.Get("/move/:x/:y", Move) // ToDo: make this post request
	m.Get("/state", GetState)
	m.Get("/profile", ShowProfile)
	m.Get("/login", LoginForm)
	m.Post("/login", Login)
	m.Get("/logout", Logout)
	m.Post("/create", binding.Bind(User{}), CreateUser)
	m.Get("/signup", SignupForm)
	m.Post("/signup", Signup)
	m.Post("/create-room", CreateRoom)
	m.Post("/list-rooms", ListRooms)

	//m.Use(Auth)
	m.Run()
}
Ejemplo n.º 5
0
func AccountHandlers(m *martini.ClassicMartini) {

	m.Use(BearerTokenValidation)
	m.Get("/account", func(r render.Render) {
		r.HTML(200, "account/login", nil)
	})
	// Authenticate user
	m.Post("/account", binding.Bind(LoginUserModel{}), func(user LoginUserModel, r *http.Request, render render.Render) {

		log.Println("user", user.Username)
		log.Println("pass", user.Password)

		if user.Username == ValidUser && user.Password == ValidPass {

			// Create JWT token
			token := jwt.New(jwt.GetSigningMethod("HS256"))
			token.Claims["username"] = user.Username
			// Expire in 5 mins
			token.Claims["exp"] = time.Now().Add(time.Minute * 5).Unix()
			tokenString, err := token.SignedString([]byte(SecretKey))

			if err == nil {
				data := map[string]string{"token": tokenString}
				render.JSON(201, data)
				return
			}

			r.Header.Add("Authorization", tokenString)

		}

		render.Redirect("/")
	})
}
Ejemplo n.º 6
0
func AdministationHandlers(m *martini.ClassicMartini) {
	log.Println("Initializing Administration pages.")

	m.Get("/admin", adminIndexHandler)

	// accounts.
	m.Post("/api/admin/account", binding.Bind(UserModel{}), adminNewAccount)
}
Ejemplo n.º 7
0
func main() {

	m := martini.Classic()

	m.Use(martini.Static("static"))
	m.Use(render.Renderer())

	m.Get("/", func(r render.Render) {
		r.HTML(201, "index", nil)
	})

	// Authenticate user
	m.Post("/auth", binding.Bind(User{}), func(user User, r render.Render) {

		if user.UserId == ValidUser && user.Password == ValidPass {

			// Create JWT token
			token := jwt.New(jwt.GetSigningMethod("HS256"))
			token.Claims["userid"] = user.UserId
			// Expire in 5 mins
			token.Claims["exp"] = time.Now().Add(time.Minute * 5).Unix()
			tokenString, err := token.SignedString([]byte(SecretKey))
			if err != nil {
				r.HTML(201, "error", nil)
				return
			}

			data := map[string]string{

				"token": tokenString,
			}

			r.HTML(201, "success", data)
		} else {
			r.HTML(201, "error", nil)
		}

	})

	// Check Key is ok
	m.Get("/debug/:token", func(params martini.Params, r render.Render) string {
		token, err := jwt.Parse(params["token"], func(token *jwt.Token) ([]byte, error) {
			return []byte(SecretKey), nil
		})
		if err == nil && token.Valid {
			return "User id: " + token.Claims["userid"].(string)
		} else {
			return "Invalid"
		}
	})

	// Only accesible if authenticated
	m.Post("/secret", func() {

	})

	m.Run()
}
Ejemplo n.º 8
0
//START_2 OMIT
func main() { // HLmartini

    m := martini.Classic() // HLmartini

    m.Use(render.Renderer(render.Options{
    m.Get("/", func(r render.Render) {
    m.Post("/", binding.Bind(Post{}), func(post Post, r render.Render) {
    m.Run() // HLmartini
}
Ejemplo n.º 9
0
func main() {

	log.Println("main start")

	m := martini.Classic()
	m.Use(render.Renderer())

	m.Get("/", func() string {
		return "Hello world!"
	})

	m.Get("/todo/", func(r render.Render) {
		r.HTML(200, "index", "")
	})

	m.Get("/todo/list.json", func(r render.Render) {
		r.JSON(200, list())
	})

	m.Get("/hello", func(r render.Render) {
		r.HTML(200, "hello", "you")
	})

	m.Post("/todo/create", binding.Bind(Content{}), func(r render.Render, todo Content) {
		insert(todo)
		r.JSON(200, list())
	})

	m.Post("/todo/update", binding.Bind(Todo{}), func(r render.Render, todo Todo) {
		update(todo)
		r.JSON(200, list())
	})

	m.Post("/todo/delete", binding.Bind(Todo{}), func(r render.Render, todo Todo) {
		delete(todo)
		r.JSON(200, list())
	})

	m.Run()

}
Ejemplo n.º 10
0
func main() {
	store := sessions.NewCookieStore([]byte("secret123"))
	dbmap = initDb()

	m := martini.Classic()
	m.Use(render.Renderer())
	m.Use(sessions.Sessions("my_session", store))
	m.Use(sessionauth.SessionUser(GenerateAnonymousUser))
	sessionauth.RedirectUrl = "/new-login"
	sessionauth.RedirectParam = "new-next"

	m.Get("/", func(r render.Render) {
		r.HTML(200, "index", nil)
	})

	m.Get("/new-login", func(r render.Render) {
		r.HTML(200, "login", nil)
	})

	m.Post("/new-login", binding.Bind(MyUserModel{}), func(session sessions.Session, postedUser MyUserModel, r render.Render, req *http.Request) {
		// You should verify credentials against a database or some other mechanism at this point.
		// Then you can authenticate this session.
		user := MyUserModel{}
		err := dbmap.SelectOne(&user, "SELECT * FROM users WHERE username = $1 and password = $2", postedUser.Username, postedUser.Password)
		if err != nil {
			r.Redirect(sessionauth.RedirectUrl)
			return
		} else {
			err := sessionauth.AuthenticateSession(session, &user)
			if err != nil {
				r.JSON(500, err)
			}

			params := req.URL.Query()
			redirect := params.Get(sessionauth.RedirectParam)
			r.Redirect(redirect)
			return
		}
	})

	m.Get("/private", sessionauth.LoginRequired, func(r render.Render, user sessionauth.User) {
		r.HTML(200, "private", user.(*MyUserModel))
	})

	m.Get("/logout", sessionauth.LoginRequired, func(session sessions.Session, user sessionauth.User, r render.Render) {
		sessionauth.Logout(session, user)
		r.Redirect("/")
	})

	m.Run()
}
Ejemplo n.º 11
0
func main() {
	fmt.Println("Attempting to authenticate to Salesforce....")
	forceApi, err := force.Create(
		"v32.0",
		os.Getenv("SFDC_CLIENT_ID"),
		os.Getenv("SFDC_CLIENT_SECRET"),
		os.Getenv("SFDC_USERNAME"),
		os.Getenv("SFDC_PASSWORD"),
		os.Getenv("SFDC_SECURITY_TOKEN"),
		os.Getenv("SFDC_ENVIRONMENT"),
	)
	if err != nil {
		panic(err)
	} else {
		fmt.Println("Bingo! Connected to Salesforce successfully!!")
	}

	m := martini.Classic()
	m.Use(render.Renderer())

	m.Get("/m/:handle", middleware, func(r render.Render, params martini.Params, res http.ResponseWriter) {
		member, status := fetchMemberByHandle(forceApi, params["handle"])
		r.JSON(status, member)
	})

	m.Post("/slack/whois", middleware, binding.Bind(SlackWhois{}), func(slack SlackWhois) string {
		if slack.Token != os.Getenv("SLACK_TOKEN") {
			return "Slack not authorized. Bad Slack token."
		} else {
			var status int
			var data interface{}
			if strings.Contains(slack.Text, "@") {
				data, status = fetchMemberByEmail(forceApi, slack.Text)
			} else {
				data, status = fetchMemberByHandle(forceApi, slack.Text)
			}
			if status == 200 {
				member := data.(map[string]interface{})
				return ("'" + member["handle"].(string) + "' is " + member["firstname"].(string) + " " + member["lastname"].(string) + " (" + member["email"].(string) + ") from " + member["country"].(string) + ". Current status is " + member["status"].(string) + " and their last login was " + member["lastLogin"].(string) + ".")
			} else if status == 404 {
				return "Requested member not found."
			} else {
				return "Bummer. Service returned an error."
			}
		}
	})

	m.Run()
}
Ejemplo n.º 12
0
func main() {
	fmt.Printf("Using config %s\n", conf.Path)
	fmt.Printf("Using models:\n")
	for _, m := range db.Models {
		t := reflect.TypeOf(m)
		fmt.Printf("    %s\n", fmt.Sprintf("%s", t)[1:])
	}

	// Establish session with mongodb
	db.Connect(conf.Config.DbHostString(), conf.Config.DbName)
	db.RegisterAllIndexes()

	m := martini.Classic()

	m.Use(martini.Static("static"))
	m.Use(DB(conf.Config.DbName))

	m.Use(render.Renderer(render.Options{
		Directory: "templates",
		Layout:    "layout", // Specify a layout template
		Charset:   "UTF-8",  // Sets encoding for json and html content-types. Default is "UTF-8".
		//IndentJSON: true, // Output human readable JSON
	}))

	m.NotFound(NotFoundHandler)
	m.Get("/", HomeHandler)
	m.Get("/events", event.EventListHandler)
	m.Get("/events/past", event.EventPastHandler)
	m.Get("/events/next", event.EventNextHandler)
	m.Get("/organise", event.OrganiseHandler)
	m.Get("/event/add", event.EventAddHandler)

	// Facebook related features
	// one-off link that allows event owner to grab group-specific events set with group-only perms
	m.Get("/facebook/login", FacebookLoginHandler)
	m.Get("/channel.html", FacebookChannelHandler)
	m.Get("/events/grab", event.EventGrabHandler)
	m.Post("/events/import", event.EventImportHandler)

	m.Post("/events/register", binding.Bind(event.Attendee{}), event.RegisterEventAttendeeHandler)

	m.Get("/event/:eid", event.ShowEventAttendees)

	m.Run()

}
Ejemplo n.º 13
0
func RunServer() {

	con := db.GetDbConn()
	defer con.Close()

	m := martini.Classic()
	m.Use(auth.Basic("kelly", "kelly"))
	m.Use(render.Renderer(render.Options{
		Directory: "templates",
		Layout:    "layout",
		Charset:   "UTF-8",
	}))

	m.Get("/", hello)
	m.Get("/create_user", createUserView)
	m.Post("/create_user", binding.Bind(NewUser{}), createUser)
	m.Run()
}
Ejemplo n.º 14
0
func init() {
	m := martini.Classic()
	m.Use(appEngine)
	m.Use(martini.Logger())
	m.Get("/", func(c context.Context, res http.ResponseWriter) {
		players, err := getAllPlayers(c, 200)
		if err != nil {
			log.Errorf(c, "Can't load players from DS: %v", err)
		}
		tmplt.Execute(res, players)
	})

	m.Get("/players.json", func(c context.Context, w http.ResponseWriter) {
		w.Header().Add("Access-Control-Allow-Origin", "*")
		if players, err := getAllPlayers(c, 20); err != nil {
			log.Errorf(c, "Can't load players from DS: %v", err)
		} else {
			if b, err := json.Marshal(players); err != nil {
				log.Errorf(c, "Can't convert players to json: %v", err)
			} else {
				w.Write(b)
				return
			}
		}
		w.WriteHeader(404)
	})
	m.Get("/results.json", func(c context.Context, w http.ResponseWriter) {
		w.Header().Add("Access-Control-Allow-Origin", "*")
		if players, err := getAllResults(c); err != nil {
			log.Errorf(c, "Can't load results from DS: %v", err)
		} else {
			if b, err := json.Marshal(players); err != nil {
				log.Errorf(c, "Can't convert results to json: %v", err)
			} else {
				w.Write(b)
				return
			}
		}
		w.WriteHeader(404)
	})
	m.Post("/", binding.Bind(PlayerInfo{}), handlePlayer)

	http.Handle("/", m)
}
Ejemplo n.º 15
0
func Signup(m *martini.ClassicMartini) {
	m.Get("/signup", func(r render.Render) {
		r.HTML(200, "signup", nil)
	})

	m.Post("/signup", binding.Bind(UserPost{}), func(userpost UserPost) string {
		// This function won't execute if there were errors
		if InsertUser(userpost) {
			//http.Redirect(w, r, "/profile", http.StatusFound)
			//return userpost.UName
			s := "<html>"
			s += userpost.UName
			s += `,恭喜你注册成功,请 <a href="/signin">登录</a></html>`
			return s
			//return `"<html>恭喜你", userpost.UName, "通过验证,请 <a href="/signin">登录</a></html>"`
		} else {
			return "insert DB failed"
		}
	})
}
Ejemplo n.º 16
0
func main() {
	//Change secret123 to something more secure and store session in backend instead of cookie
	store := sessions.NewCookieStore([]byte("secret123"))

	dbmap = initDb()

	defer dbmap.Db.Close()

	err := dbmap.TruncateTables()
	checkErr(err, "TruncateTables failed")

	u1 := newUser("*****@*****.**", "pass", "Bob", false)

	//insert rows
	err = dbmap.Insert(&u1)
	checkErr(err, "Insert failed")

	//create two posts, assign to user 1 above
	p1 := newPost("Post 1", "Lorem ipsum lorem ipsum", 1)
	p2 := newPost("Post 2", "This is my second post", 1)

	// insert rows
	err = dbmap.Insert(&p1, &p2)
	checkErr(err, "Insert failed")

	m := martini.Classic()

	m.Use(render.Renderer(render.Options{
		Directory: "templates",
		Layout:    "layout",
		Funcs: []template.FuncMap{
			{
				"formatTime": func(args ...interface{}) string {
					t1 := time.Unix(args[0].(int64), 0)
					return t1.Format(time.Stamp)
				},
			},
		},
	}))

	m.Use(sessions.Sessions("my_session", store))
	m.Use(sessionauth.SessionUser(GenerateAnonymousUser))

	sessionauth.RedirectUrl = "/login"
	sessionauth.RedirectParam = "next"

	//ROUTES

	m.Get("/register", func(r render.Render, user sessionauth.User) {

		//redirect to homepage if already authenticated
		if user.IsAuthenticated() {
			r.Redirect("/")
		} else {
			r.HTML(200, "register", nil)
		}

	})

	m.Get("/login", func(r render.Render, user sessionauth.User) {

		//redirect to homepage if already authenticated
		if user.IsAuthenticated() {
			r.Redirect("/")
		} else {
			r.HTML(200, "login", nil)
		}
	})

	m.Post("/login", binding.Form(User{}), func(session sessions.Session, postedUser User, r render.Render, ferr binding.Errors, req *http.Request) {

		log.Println(ferr)

		//Example of server side error validation for the client side form
		if ferr.Count() > 0 {
			newmap := map[string]interface{}{"metatitle": "Registration", "errormessage": "Error with Form Submission"}
			r.HTML(200, "login", newmap)
		} else {

			user := User{}

			//check login credentails with DataBase
			err := dbmap.SelectOne(&user, "SELECT * FROM users WHERE email = ? and password = ?", postedUser.Email, postedUser.Password)
			if err != nil {
				r.Redirect(sessionauth.RedirectUrl)
				return
			} else {
				err := sessionauth.AuthenticateSession(session, &user)
				if err != nil {
					r.JSON(500, err)
				}

				params := req.URL.Query()
				redirect := params.Get(sessionauth.RedirectParam)
				r.Redirect(redirect)
				return
			}

		}

	})

	m.Get("/logout", sessionauth.LoginRequired, func(session sessions.Session, user sessionauth.User, r render.Render) {
		sessionauth.Logout(session, user)
		r.Redirect("/")
	})

	m.Get("/", func(r render.Render, authuser sessionauth.User) {

		var posts []Post
		_, err = dbmap.Select(&posts, "select * from posts order by post_id")
		checkErr(err, "Select failed")

		newmap := map[string]interface{}{"metatitle": "HomePage", "authuser": authuser, "posts": posts}
		r.HTML(200, "posts", newmap)
	})

	m.Get("/users", func(r render.Render, authuser sessionauth.User) {

		var users []User

		_, err = dbmap.Select(&users, "select * from users order by id")
		checkErr(err, "Select failed")

		newmap := map[string]interface{}{"metatitle": "Users listing", "authuser": authuser, "users": users}
		r.HTML(200, "users", newmap)

	})

	m.Get("/users/:id", sessionauth.LoginRequired, func(args martini.Params, r render.Render, authuser sessionauth.User) {

		var user User

		err = dbmap.SelectOne(&user, "select * from users where id=?", args["id"])

		//simple error check
		if err != nil {
			newmap := map[string]interface{}{"metatitle": "404 Error", "message": "User not found"}
			r.HTML(404, "error", newmap)
		} else {

			var posts []Post
			_, err = dbmap.Select(&posts, "select * from posts where UserId=?", args["id"])
			checkErr(err, "Select failed")

			newmap := map[string]interface{}{"metatitle": user.Name + " profile page", "authuser": authuser, "user": user, "posts": posts}
			r.HTML(200, "user", newmap)
		}

	})

	m.Post("/users", binding.Form(User{}), func(session sessions.Session, user User, ferr binding.Errors, r render.Render) {

		//Example of server side error validation for the client side form
		if ferr.Count() > 0 {
			fmt.Println(ferr)
			newmap := map[string]interface{}{"metatitle": "Registration", "errormessage": "Error with Form Submission"}
			r.HTML(200, "register", newmap)
		} else {

			u := newUser(user.Email, user.Password, user.Name, user.authenticated)

			err = dbmap.Insert(&u)
			checkErr(err, "Insert failed")

			//create the session and redirect always to homepage
			err := sessionauth.AuthenticateSession(session, &u)
			if err != nil {
				r.JSON(500, err)
			}

			r.Redirect("/")
		}

	})

	m.Put("/users/:id", binding.Bind(User{}), func(args martini.Params, user User, r render.Render, authuser sessionauth.User) {

		//convert string to int64 so you can match the struct (passing userid via ajax does not work as it comes in as a string)
		f, _ := strconv.ParseInt(args["id"], 0, 64)

		//only allow the authenticated user to update his user attributes
		if authuser.UniqueId() == f {

			//specify the user id
			user.Id = f

			count, err := dbmap.Update(&user)
			checkErr(err, "Update failed")
			log.Println("Rows updated:", count)

			if count == 1 {
				newmap := map[string]interface{}{"responseText": "success"}
				r.JSON(200, newmap)
			} else {
				newmap := map[string]interface{}{"responseText": "error"}
				r.JSON(400, newmap)
			}

		} else {
			newmap := map[string]interface{}{"responseText": "You are not allowed to update this resource."}
			r.JSON(403, newmap)
		}

	})

	m.Delete("/users/:id", func(args martini.Params, r render.Render, authuser sessionauth.User) {

		//convert id from string to int64
		f, _ := strconv.ParseInt(args["id"], 0, 64)

		//only allow the authenticated user to delete him or her
		if authuser.UniqueId() == f {

			_, err = dbmap.Exec("delete from users where id=?", args["id"])
			checkErr(err, "Delete failed")

			if err == nil {
				newmap := map[string]interface{}{"responseText": "success"}
				r.JSON(200, newmap)
				//if you delete yourself, Ajax should redirec you
			} else {
				newmap := map[string]interface{}{"responseText": "error"}
				r.JSON(400, newmap)
			}

		} else {
			newmap := map[string]interface{}{"responseText": "You are not allowed to delete this resource."}
			r.JSON(403, newmap)
		}

	})

	m.Post("/posts", sessionauth.LoginRequired, binding.Bind(Post{}), func(post Post, r render.Render, authuser sessionauth.User) {

		//convert to int64
		f := authuser.UniqueId().(int64)
		p1 := newPost(post.Title, post.Body, f)

		err = dbmap.Insert(&p1)
		checkErr(err, "Insert failed")

		r.Redirect("/")
	})

	m.Get("/posts/:id", func(args martini.Params, r render.Render, authuser sessionauth.User) {

		var post Post

		err = dbmap.SelectOne(&post, "select * from posts where post_id=?", args["id"])

		//simple error check
		if err != nil {
			newmap := map[string]interface{}{"metatitle": "404 Error", "message": "This is not found"}
			r.HTML(404, "error", newmap)
		} else {
			newmap := map[string]interface{}{"metatitle": post.Title + " more custom", "authuser": authuser, "post": post}
			r.HTML(200, "post", newmap)
		}
	})

	m.Get("/p/:str", func(args martini.Params, r render.Render, authuser sessionauth.User) {

		var post Post

		err = dbmap.SelectOne(&post, "select * from posts where url=?", args["str"])

		//simple error check
		if err != nil {
			newmap := map[string]interface{}{"metatitle": "404 Error", "message": "This is not found"}
			r.HTML(404, "error", newmap)
		} else {
			newmap := map[string]interface{}{"metatitle": post.Title + " more custom", "authuser": authuser, "post": post}
			r.HTML(200, "post", newmap)
		}
	})

	m.Put("/posts/:id", binding.Bind(Post{}), func(args martini.Params, post Post, r render.Render, authuser sessionauth.User) {

		var newTitle = post.Title
		var newBody = post.Body

		err = dbmap.SelectOne(&post, "select * from posts where post_id=?", args["id"])

		//simple database error check
		if err != nil {
			newmap := map[string]interface{}{"message": "Something went wrong."}
			r.JSON(400, newmap)
		} else {

			//owner check
			if authuser.UniqueId() == post.UserId {

				post.Title = newTitle
				post.Body = newBody

				count, err := dbmap.Update(&post)
				checkErr(err, "Update failed")

				if count == 1 {
					newmap := map[string]interface{}{"responseText": "success"}
					r.JSON(200, newmap)
				} else {
					newmap := map[string]interface{}{"responseText": "error"}
					r.JSON(400, newmap)
				}

			} else {
				newmap := map[string]interface{}{"responseText": "You are not allowed to modify this resource."}
				r.JSON(403, newmap)
			}

		}

	})

	m.Delete("/posts/:id", func(args martini.Params, r render.Render, authuser sessionauth.User) {

		//retrieve the post to check the real owner
		var post Post
		err = dbmap.SelectOne(&post, "select * from posts where post_id=?", args["id"])

		//simple DB error check
		if err != nil {
			newmap := map[string]interface{}{"message": "Something went wrong."}
			r.JSON(400, newmap)
		} else {

			//owner check
			if authuser.UniqueId() == post.UserId {

				//delete it
				_, err := dbmap.Delete(&post)
				checkErr(err, "Delete failed")

				newmap := map[string]interface{}{"responseText": "success"}
				r.JSON(200, newmap)

			} else {
				newmap := map[string]interface{}{"responseText": "You are not allowed to delete this resource."}
				r.JSON(403, newmap)
			}

		}

	})

	m.Run()
}
Ejemplo n.º 17
0
func main() {
	// initialize the DbMap
	dbmap := initDb()
	defer dbmap.Db.Close()
	// setup some of the database
	// lets start martini and the real code
	m := martini.Classic()

	m.Use(render.Renderer(render.Options{
		Directory: "templates",
		//Layout:    "layout",
		Charset: "UTF-8",
		Funcs: []template.FuncMap{
			{
				"formatTime": func(args ...interface{}) string {
					t1 := time.Unix(args[0].(int64), 0)
					return t1.Format(time.Stamp)
				},
				"unescaped": func(args ...interface{}) template.HTML {
					return template.HTML(args[0].(string))
				},
			},
		},
	}))

	/**
	首页
	*/
	m.Get("/", func(r render.Render) {
		r.HTML(200, "main", "")
	})

	m.Get("/main/hotSpots", func(r render.Render) {
		//fetch all spots
		var viewSpotList []Ph_spot
		_, err := dbmap.Select(&viewSpotList, "select * from ph_view_spots")
		checkErr(err, "Select failed")
		newmap := map[string]interface{}{"metatitle": "this is my custom title", "posts": viewSpotList}
		r.HTML(200, "main_hot_spots", newmap)

	})

	m.Get("/main/hotCities", func(r render.Render) {
		var viewSpotList []Ph_spot
		_, err := dbmap.Select(&viewSpotList, "select * from ph_view_spots")
		checkErr(err, "Select failed")
		newmap := map[string]interface{}{"metatitle": "this is my custom title", "posts": viewSpotList}
		r.HTML(200, "main_hot_cities", newmap)
	})

	m.Get("/spot/:id", func(args martini.Params, r render.Render) {
		var viewSpotList []Ph_spot
		_, err := dbmap.Select(&viewSpotList, "select * from ph_view_spots where id=?", args["id"])
		checkErr(err, "Select failed")
		newmap := map[string]interface{}{"metatitle": "this is my custom title", "posts": viewSpotList}
		r.HTML(200, "spot_detail", newmap, render.HTMLOptions{
			Layout: "spot_layout",
		})
	})

	/**
	景点详情:测试
	*/
	m.Get("/spotDetail/:id", func(r render.Render) {
		r.HTML(200, "spot_detail_test", "", render.HTMLOptions{
			Layout: "spot_layout",
		})
	})

	/**
	套餐详情:测试
	*/
	m.Get("/packageDetail/:id", func(r render.Render) {

		r.HTML(200, "travel_package_detail_test", "", render.HTMLOptions{
			Layout: "package_layout",
		})
	})

	m.Get("/main/package/:id", func(args martini.Params, r render.Render) {
		/*
			第一步查出套餐ID
		*/
		var travelPackageIds []string
		_, err := dbmap.Select(&travelPackageIds, "SELECT TRAVEL_PACKAGES_ID FROM ph_travel_package_view_spots where VIEW_SPOT_ID=?", args["id"])
		checkErr(err, "Select failed")
		log.Println(travelPackageIds)

		/*
			第二部返回套餐详情
		*/

		var inSql = ""
		inSql = strings.Join(travelPackageIds, "','")
		inSql = "'" + inSql + "'"

		var travelpackageArr []ph_travel_packages
		log.Println("SELECT * FROM ph_travel_packages where ID in (" + inSql + ")")
		_, err = dbmap.Select(&travelpackageArr, "SELECT * FROM ph_travel_packages where ID in ("+inSql+")")
		checkErr(err, "Select failed")
		log.Println(travelpackageArr)

		newmap := map[string]interface{}{"metatitle": "this is my custom title", "posts": travelpackageArr}
		r.HTML(200, "package_detail", newmap)

	})
	/***********************************************管理端功能************************************************/
	/**
	景点列表显示
	*/
	m.Get("/admin/viewSpots", func(r render.Render) {
		//fetch all rows
		var viewSpotList []Ph_spot
		_, err := dbmap.Select(&viewSpotList, "select * from ph_view_spots")
		checkErr(err, "Select failed")
		newmap := map[string]interface{}{"metatitle": "this is my custom title", "posts": viewSpotList}
		r.HTML(200, "view_spot_list", newmap, render.HTMLOptions{
			Layout: "admin_layout",
		})
	})

	/**
	景点详情显示
	*/
	m.Get("/admin/viewSpots/:id", func(args martini.Params, r render.Render) {
		var spotDetail Ph_spot
		err := dbmap.SelectOne(&spotDetail, "select * from ph_view_spots where id=?", args["id"])

		if err != nil {
			newmap := map[string]interface{}{"metatitle": "404 Error", "message": "This is not found"}
			r.HTML(404, "error", newmap)
		} else {
			//var spotDetailImages Ph_spot_with_image
			//dbmap.Select(&spotDetailImages, "select * from ph_view_spot_iamges where view_spot_id=?", spotDetail.ID)
			//newImageMap := map[string]interface{}{"metatitle": spotDetail.NAME + " more custom", "spotImages": spotDetailImages}
			newmap := map[string]interface{}{"metatitle": spotDetail.NAME + " more custom", "post": spotDetail}
			r.HTML(200, "view_spot_update", newmap, render.HTMLOptions{
				Layout: "admin_layout",
			})
		}
	})

	/**
	景点修改内容获取
	*/
	m.Get("/admin/spots/:id/update", func(args martini.Params, r render.Render) {
		var spotDetail Ph_spot
		err := dbmap.SelectOne(&spotDetail, "select * from ph_view_spots where id=?", args["id"])
		//simple error check
		if err != nil {
			newmap := map[string]interface{}{"metatitle": "404 Error", "message": "This is not found"}
			r.HTML(404, "error", newmap)
		} else {
			newmap := map[string]interface{}{"metatitle": spotDetail.NAME + " more custom", "post": spotDetail}
			r.HTML(200, "view_spot_update", newmap, render.HTMLOptions{
				Layout: "admin_layout",
			})
		}
	})

	/**
	景点修改
	*/
	m.Post("/admin/spots/:id/update", func(args martini.Params, r render.Render) {

	})

	/**
	景点新增界面
	*/
	m.Get("/admin/spots/create/", func(r render.Render) {
		r.HTML(200, "view_spot_create", "", render.HTMLOptions{
			Layout: "admin_layout",
		})
	})

	/**
	景点新增
	*/
	m.Post("/admin/spots/create", binding.Bind(Ph_spot{}), func(spot Ph_spot, args martini.Params, w http.ResponseWriter, r *http.Request) (int, string) {
		err := r.ParseMultipartForm(100000)
		if err != nil {
			return http.StatusInternalServerError, err.Error()
		}

		files := r.MultipartForm.File["IMAGE"]
		//newSpotImages := []Ph_spot_with_image
		for i, _ := range files {
			file, err := files[i].Open()
			defer file.Close()
			if err != nil {
				return http.StatusInternalServerError, err.Error()
			}

			//获取扩展名
			sourceImageNameArr := strings.SplitAfter(files[i].Filename, ".")
			sourceImageNameExt := sourceImageNameArr[len(sourceImageNameArr)-1]
			u1 := uuid.NewV4().String()
			dstSource, err := os.Create("./public/uploads/source/" + u1 + "_s." + sourceImageNameExt)
			dstAlbum, err := os.Create("./public/uploads/album/" + u1 + "_a." + sourceImageNameExt)
			defer dstSource.Close()
			defer dstAlbum.Close()
			if err != nil {
				return http.StatusInternalServerError, err.Error()
			}

			if _, err := io.Copy(dstSource, file); err != nil {
				return http.StatusInternalServerError, err.Error()
			}
			if _, err := io.Copy(dstAlbum, file); err != nil {
				return http.StatusInternalServerError, err.Error()
			}

			p1 := newViewSpot(uuid.NewV4().String(), spot.COUNTRY, spot.PROVINCE, spot.CITY, spot.COUNTY, spot.NAME, spot.LEVEL, spot.LABEL, spot.PRICE, spot.STATUS, "uploads", u1, sourceImageNameExt)
			log.Println(p1)
			err = dbmap.Insert(&p1)
			checkErr(err, "Insert Spot failed")

			image1 := newSpotImage(uuid.NewV4().String(), u1, p1.ID, files[i].Filename, sourceImageNameExt, "uploads")
			log.Println(image1)
			//保存图片信息到图片数据库
			err = dbmap.Insert(&image1)
			checkErr(err, "Insert iamge failed")
		}

		return 200, "ok"

	})

	/**
	套餐管理首页
	*/
	m.Get("/admin/travelPackagelist/", func(r render.Render) {
		//fetch all packages....
		var travelpackagelist []ph_travel_packages
		_, err := dbmap.Select(&travelpackagelist, "SELECT * FROM ph_travel_packages")
		checkErr(err, "Select failed")
		newmap := map[string]interface{}{"metatitle": "this", "posts": travelpackagelist}
		r.HTML(200, "travel_package_list", newmap, render.HTMLOptions{
			Layout: "admin_layout",
		})

	})

	m.Get("/admin/travelPackagecreate/", func(r render.Render) {
		//fetch all packages....
		//		r.HTML(200, "travel_package_create", "", render.HTMLOptions{
		//			Layout: "admin_layout",
		//		})

		var viewSpotList []Ph_spot
		_, err := dbmap.Select(&viewSpotList, "SELECT * FROM ph_view_spots")
		checkErr(err, "Select failed")
		newmap := map[string]interface{}{"metatitle": "this", "posts": viewSpotList}
		r.HTML(200, "travel_package_create", newmap, render.HTMLOptions{
			Layout: "admin_layout",
		})

	})

	m.Post("/admin/travelPackagecreate/", binding.Bind(ph_travel_packages{}), func(travel ph_travel_packages, r render.Render) {

		P1 := travelpackage(uuid.NewV4().String(), travel.NAME, travel.DESCRIPTION, travel.FEE, travel.START_DATE, travel.END_DATE, travel.DAYS, travel.HOTELS, travel.TRANSPOT, travel.PERSON_NUM, travel.TAGS, travel.CONTENT, travel.ADVICE, travel.FEE_INCLUDE, travel.FEE_NOT_INCLUDE, travel.COLLECTION_ADDRESS, travel.HIGHLIGHTS, travel.VIEW_SPOT_ID)
		log.Println(P1)
		err := dbmap.Insert(&P1)
		checkErr(err, "Insert failed")
		//		return 200, "ok"

		//      保存标签
		iarray := strings.Split(P1.TAGS, ",")
		log.Println(iarray)

		for i := 0; i < len(iarray); i++ {

			p2 := travelpackagetags(uuid.NewV4().String(), P1.ID, iarray[i])
			log.Println(p2)
			err = dbmap.Insert(&p2)
			checkErr(err, "Insert iamge failed")

		}
		//      保存亮点
		highlights := strings.Split(P1.HIGHLIGHTS, ",")
		log.Println(highlights)

		for i := 0; i < len(highlights); i++ {

			p2 := travelpackagehighlights(uuid.NewV4().String(), P1.ID, highlights[i])
			log.Println(p2)
			err = dbmap.Insert(&p2)
			checkErr(err, "Insert iamge failed")

		}
		//      保存景点
		package_spot_id := strings.Split(P1.VIEW_SPOT_ID, ",")
		log.Println(package_spot_id)

		for i := 0; i < len(package_spot_id); i++ {
			if package_spot_id[i] != "" {
				p2 := travelpackageviewspot(uuid.NewV4().String(), P1.ID, package_spot_id[i], P1.DESCRIPTION, P1.DAYS, "")
				log.Println(p2)
				err = dbmap.Insert(&p2)
				checkErr(err, "Insert iamge failed")
			}

		}

		//		newmap := map[string]interface{}{"metatitle": "created post", "travel_package_create": p2}
		r.HTML(200, "main", "", render.HTMLOptions{
			Layout: "admin_layout",
		})
	})

	/**
	套餐详情显示
	*/
	m.Get("/admin/travelPackagecreate/:id", func(args martini.Params, r render.Render) {
		var travelpackagedetail ph_travel_packages
		err := dbmap.SelectOne(&travelpackagedetail, "select * from ph_travel_packages where id=?", args["id"])

		if err != nil {
			newmap := map[string]interface{}{"metatitle": "404 Error", "message": "This is not found"}
			r.HTML(404, "error", newmap)
		} else {
			//var spotDetailImages Ph_spot_with_image
			//dbmap.Select(&spotDetailImages, "select * from ph_view_spot_iamges where view_spot_id=?", spotDetail.ID)
			//newImageMap := map[string]interface{}{"metatitle": spotDetail.NAME + " more custom", "spotImages": spotDetailImages}
			newmap := map[string]interface{}{"metatitle": travelpackagedetail.NAME + " more custom", "post": travelpackagedetail}
			r.HTML(200, "travel_package_update", newmap, render.HTMLOptions{
				Layout: "admin_layout",
			})
		}
	})

	/**
	支付管理首页
	*/
	m.Get("/admin/payments", func(r render.Render) {
		//fetch all payment history....
		r.HTML(200, "payment_list", "", render.HTMLOptions{
			Layout: "admin_layout",
		})
	})

	/*******************************************管理功能结束************************************************/

	//jump to login page
	m.Get("/user/login/", func(r render.Render) {
		r.HTML(200, "login", "")
		//		r.HTML(200, "login","",render.HTMLOptions{
		//			Layout: "admin_layout",
		//
		//		})
	})

	m.Run()
}
Ejemplo n.º 18
0
func setupRoutes(r martini.Router) {
	// static
	r.Get("/", func(r render.Render) {
		r.HTML(http.StatusOK, "index", View{Title: "A browser-based Todo.txt application"})
	})
	r.NotFound(func(r render.Render) {
		r.HTML(http.StatusNotFound, "404", View{Title: "404 - Not Found"})
	})

	// api - for tasks
	r.Get("/api/tasks", func(tasks todo.TaskList, r render.Render) {
		r.JSON(http.StatusOK, tasks)
	})

	r.Get("/api/task/:id", func(tasks todo.TaskList, params martini.Params, r render.Render) {
		id, err := strconv.Atoi(params["id"])
		if err != nil {
			r.Error(http.StatusInternalServerError)
			return
		}

		task, err := tasks.GetTask(id)
		if err != nil {
			r.Error(http.StatusNotFound)
			return
		}
		r.JSON(http.StatusOK, task)
	})

	r.Post("/api/task", binding.Bind(todo.Task{}), func(newTask todo.Task, tasks todo.TaskList, config *Config, params martini.Params, r render.Render) {
		newTask.CreatedDate = time.Now()
		tasks.AddTask(&newTask)

		if err := tasks.WriteToFilename(config.TodoTxtFilename); err != nil {
			r.Error(http.StatusInternalServerError)
			return
		}
		r.JSON(http.StatusCreated, newTask)
	})

	r.Put("/api/task/:id", binding.Bind(todo.Task{}), func(updatedTask todo.Task, tasks todo.TaskList, config *Config, params martini.Params, r render.Render) {
		id, err := strconv.Atoi(params["id"])
		if err != nil {
			r.Error(http.StatusInternalServerError)
			return
		}

		currentTask, err := tasks.GetTask(id)
		if err != nil {
			r.Error(http.StatusNotFound)
			return
		}

		*currentTask = updatedTask
		if err := tasks.WriteToFilename(config.TodoTxtFilename); err != nil {
			r.Error(http.StatusInternalServerError)
			return
		}
		r.JSON(http.StatusOK, updatedTask)
	})

	r.Delete("/api/task/:id", func(tasks todo.TaskList, config *Config, params martini.Params, r render.Render) {
		id, err := strconv.Atoi(params["id"])
		if err != nil {
			r.Error(http.StatusInternalServerError)
			return
		}

		if err := tasks.RemoveTaskById(id); err != nil {
			r.Error(http.StatusNotFound)
			return
		}

		if err := tasks.WriteToFilename(config.TodoTxtFilename); err != nil {
			r.Error(http.StatusInternalServerError)
			return
		}
		r.JSON(http.StatusNoContent, `{}`)
	})

	r.Delete("/api/tasks", func(tasks todo.TaskList, config *Config, r render.Render) {
		openTasks := make(todo.TaskList, 0)
		for _, task := range tasks {
			if !task.Completed {
				openTasks.AddTask(&task)
			}
		}

		if err := openTasks.WriteToFilename(config.TodoTxtFilename); err != nil {
			r.Error(http.StatusInternalServerError)
			return
		}
		r.JSON(http.StatusOK, openTasks)
	})

	// api - for config file
	r.Get("/api/config", func(config *Config, r render.Render) {
		r.JSON(http.StatusOK, config)
	})

	r.Put("/api/config", binding.Bind(Config{}), func(bindConfig Config, r render.Render) {
		if err := bindConfig.writeConfigurationFile(configFile); err != nil {
			r.Error(http.StatusInternalServerError)
			return
		}
		r.JSON(http.StatusOK, bindConfig)
	})
}
func main() {
	var port int
	flag.IntVar(&port, "port", 3001, "server port")
	flag.Parse()
	fmt.Println("Port: ", port)

	// disable timestamps, since we're using journald
	log.SetFormatter(&log.TextFormatter{DisableTimestamp: true})

	var err error
	client, err = NewDokku()

	if err != nil {
		log.Fatal(err)
	}

	m := martini.Classic()
	m.Use(render.Renderer())
	m.Get("/list", func(r render.Render) {
		apps, err := client.List()
		if err == nil {
			r.JSON(http.StatusOK, apps)
		} else {
			log.Errorf("/list: %v", err.Error())
			r.JSON(http.StatusInternalServerError, err.Error())
		}
	})

	m.Post("/start", binding.Bind(DokkuApp{}), func(d DokkuApp, r render.Render) {
		err := client.start(d.Name)
		if err == nil {
			r.JSON(http.StatusOK, d)
		} else {
			log.Errorf("/start '%v': %v", d.Name, err.Error())
			r.JSON(http.StatusInternalServerError, err.Error())
		}
	})

	m.Post("/stop", binding.Bind(DokkuApp{}), func(d DokkuApp, r render.Render) {
		err := client.stop(d.Name)
		if err == nil {
			r.JSON(http.StatusOK, d)
		} else {
			log.Errorf("/stop '%v': %v", d.Name, err.Error())
			r.JSON(http.StatusInternalServerError, err.Error())
		}
	})

	m.Post("/restart", binding.Bind(DokkuApp{}), func(d DokkuApp, r render.Render) {
		err := client.restart(d.Name)
		if err == nil {
			r.JSON(http.StatusOK, d)
		} else {
			log.Errorf("/restart '%v': %v", d.Name, err.Error())
			r.JSON(http.StatusInternalServerError, err.Error())
		}
	})

	m.Post("/rebuild", binding.Bind(DokkuApp{}), func(d DokkuApp, r render.Render) {
		err := client.rebuild(d.Name)
		if err == nil {
			r.JSON(http.StatusOK, d)
		} else {
			log.Errorf("/rebuild '%v': %v", d.Name, err.Error())
			r.JSON(http.StatusInternalServerError, err.Error())
		}
	})

	m.Post("/destroy", binding.Bind(DokkuApp{}), func(d DokkuApp, r render.Render) {
		err := client.destroy(d.Name)
		if err == nil {
			r.JSON(http.StatusOK, d)
		} else {
			// ignore OverlayFS error
			overlayErrorString := "Driver overlay failed to remove root filesystem"
			if strings.Contains(err.Error(), overlayErrorString) {
				r.JSON(http.StatusOK, d)
			} else {
				log.Errorf("/destroy '%v': %v", d.Name, err.Error())
				r.JSON(http.StatusInternalServerError, err.Error())
			}
		}
	})

	m.Get("/urls/:name", func(args martini.Params, r render.Render) {
		name := args["name"]
		urls, err := client.urls(name)
		if err == nil {
			r.JSON(http.StatusOK, urls)
		} else {
			log.Errorf("/urls/%v: %v", name, err.Error())
			r.JSON(http.StatusInternalServerError, err.Error())
		}
	})

	m.Get("/logs/:name", func(args martini.Params, r render.Render) {
		name := args["name"]
		str, err := client.logs(name)
		if err == nil {
			r.JSON(http.StatusOK, struct {
				Message string `json:"msg"`
			}{
				str,
			})
		} else {
			log.Errorf("/logs/%v: %v", name, err.Error())
			r.JSON(http.StatusInternalServerError, err.Error())
		}
	})

	http.Handle("/", m)
	http.ListenAndServe(":"+strconv.Itoa(port), nil)
}
Ejemplo n.º 20
0
func init() {
	rand.Seed(time.Now().UTC().UnixNano())
	godotenv.Load("secrets.env")
	global.Tags = strings.Split(os.Getenv("TAGS"), ",")
	global.InstagramClientID = os.Getenv("INSTAGRAM_CLIENT_ID")
	global.TelegramKey = os.Getenv("TELEGRAM_KEY")

	m := martini.Classic()
	m.Use(appEngine)
	m.Use(render.Renderer())
	m.Use(martini.Logger())
	m.Get("/", func(r render.Render) {
		r.Redirect("https://telegram.me/QuestagBot", 302)
	})
	m.Post("/bothook", binding.Bind(telegram.Update{}), func(c context.Context, update telegram.Update, w http.ResponseWriter) {
		httpClient := urlfetch.Client(c)
		tele := telegram.NewTelegram(httpClient, global.TelegramKey)
		log.Infof(c, "%v", update)
		gamer, err := findOrCreateGamer(update, c)
		defer saveGamer(c, gamer)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			log.Errorf(c, "Can't find or create gamer: %v", err)
			return
		}
		log.Infof(c, "Gamer : %v", gamer.ChatID)

		if strings.Index(update.Message.Text, "/start") == 0 {
			log.Infof(c, "Start game with %v, %v", gamer.ChatID, update.Message.From.Username)
			gamer.handleStart()
			tele.SendPhoto(update.Message.Chat.ID, generateImage(gamer.GetCurrentQuestion(), httpClient), "", 0, gamer.GetKeyboard())
			return
		}
		if strings.Index(update.Message.Text, "/stop") == 0 {
			log.Infof(c, "Stop game with %v, %v", gamer.ChatID, update.Message.From.Username)
			gamer.handleStop()
			tele.SendMessage(update.Message.Chat.ID, "Game over", true, 0, nil)
			return
		}
		if strings.Index(update.Message.Text, "/status") == 0 {
			log.Infof(c, "Show game status for %v, %v", gamer.ChatID, update.Message.From.Username)
			tele.SendMessage(update.Message.Chat.ID, fmt.Sprintf("Your personal score:\nRight answers: %v\nWrong answers: %v\n%v accuracy", gamer.RightAnswers, gamer.WrongAnswers, gamer.GetAccuracy()*100), true, 0, nil)
			return
		}
		if strings.Index(update.Message.Text, "/top") == 0 {
			log.Infof(c, "Show top for %v, %v", gamer.ChatID, update.Message.From.Username)
			gamers, err := findBestGamer(c)
			count, _ := gamersCount(c)
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				log.Errorf(c, "Can't find all gamers: %v", err)
				return
			}
			top := fmt.Sprintf("Top 20 gamers. Total gamers - %v\n", count)
			for i, g := range gamers {
				top += fmt.Sprintf("%v - %v, Right answers: %v, Wrong answers: %v\n", i+1, g.Username, g.RightAnswers, g.WrongAnswers)
			}
			tele.SendMessage(update.Message.Chat.ID, top, true, 0, nil)
			return
		}
		if strings.Index(update.Message.Text, "/help") == 0 {
			log.Infof(c, "Show help for %v, %v", gamer.ChatID, update.Message.From.Username)
			tele.SendMessage(update.Message.Chat.ID, HelpText, true, 0, nil)
			return
		}
		if gamer.isPlaying() {
			log.Infof(c, "Get answer from %v, %v on question %v", gamer.ChatID, update.Message.From.Username, gamer.GetCurrentQuestion())
			if gamer.handleAnswer(update.Message.Text) {
				log.Infof(c, "Right answer, gamer: %v, %v", gamer.ChatID, update.Message.From.Username)
				tele.SendMessage(update.Message.Chat.ID, "👍 Right!", true, 0, nil)
			} else {
				log.Infof(c, "Wrong answer, gamer: %v, %v", gamer.ChatID, update.Message.From.Username)
				tele.SendMessage(update.Message.Chat.ID, "😕 Wrong, "+gamer.GetCurrentQuestion().Answer, true, 0, nil)
			}
			tele.SendPhoto(update.Message.Chat.ID, generateImage(gamer.NextQuestion(), httpClient), "", 0, gamer.GetKeyboard())
			return
		}
		log.Infof(c, "Show help for %v, %v", gamer.ChatID, update.Message.From.Username)
		tele.SendMessage(update.Message.Chat.ID, HelpText, true, 0, nil)
	})
	http.Handle("/", m)
}