Beispiel #1
1
// GetPage returns pagination attributes from query
func GetPage(c *echo.Context) (pn int, ps int) {
	var err error
	pns := c.Query("pn")
	pss := c.Query("ps")

	pn, err = strconv.Atoi(pns)
	if err != nil || pn < 0 {
		if pns != "" {
			log.Println("Bad argument of ?pn query param: ", pns)
		} else {
			log.Println("Empty ?pn argument")
		}
		pn = 1
	}

	ps, err = strconv.Atoi(pss)
	if err != nil || ps < 0 {
		if pss != "" {
			log.Println("Bad argument of ?ps query param: ", pss)
		} else {
			log.Println("Empty ?ps argument")
		}
		ps = 10
	}

	return
}
Beispiel #2
0
// putPlace изменяет определение уже существующего места.
func putPlace(c *echo.Context) error {
	groupID := c.Get("GroupID").(string)
	placeID := c.Query("place-id")
	if !bson.IsObjectIdHex(placeID) {
		return echo.NewHTTPError(http.StatusNotFound)
	}
	var place places.Place // описание места
	err := c.Bind(&place)  // разбираем описание места из запроса
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	if place.Circle == nil && place.Polygon == nil {
		return echo.NewHTTPError(http.StatusBadRequest)
	}
	place.ID = bson.ObjectIdHex(placeID)
	place.GroupID = groupID
	_, err = placesDB.Save(place)
	if err == mgo.ErrNotFound {
		return echo.NewHTTPError(http.StatusNotFound)
	}
	if err != nil {
		llog.Error("placesDB error: %v", err)
		return err
	}
	return c.NoContent(http.StatusOK)
}
Beispiel #3
0
/**
 * @api {get} /topics Get a list of topics
 * @apiName GetTopics
 * @apiGroup Topics
 *
 * @apiParam {Number} [limit=10] The maximum number of items to return
 * @apiParam {Number} [offset=0] The offset relative to the number of items (not page number)
 */
func (tc *TopicsController) Index(c *echo.Context) error {
	resp := response.New(c)
	defer resp.Render()

	// Defaults
	var limit int64 = 10
	var offset int64 = 0

	// Getting limit
	limitInt, err := strconv.ParseInt(c.Query("limit"), 10, 64)
	if err == nil {
		limit = limitInt
	}

	// Getting offset
	offsetInt, err := strconv.ParseInt(c.Query("offset"), 10, 64)
	if err == nil {
		offset = offsetInt
	}

	// Fetching models
	res, err := models.AllTopics(limit, offset)
	if err != nil {
		resp.SetResponse(http.StatusInternalServerError, nil)
		return nil
	}

	resp.SetResponse(http.StatusOK, res)
	return nil
}
Beispiel #4
0
func GetDownloadToken(c *echo.Context) error {
	filename := c.Query("filename")
	if len(filename) == 0 {
		return c.JSON(
			http.StatusBadRequest,
			hash{
				"error": "filename not specified",
			},
		)
	}

	accessToken, fail := oauth2.GetAccessToken(c.Request())
	if fail != nil {
		return oauthError(c, fail)
	}

	user := c.Get("user").(*users.User)
	token, err := createDownloadToken(user, accessToken, filename)
	if err != nil {
		return err
	}
	return c.JSON(
		http.StatusOK,
		hash{
			"token": token,
		},
	)
}
Beispiel #5
0
// fillBlogContext dumps into a blog context default query values.
func fillBlogContext(c *echo.Context, bc *blogContext) error {
	var err error

	// Query the categories
	err = database.Current.Select(&bc.Categories, database.Queries.Categories)
	if err != nil {
		return err
	}

	// Query the archive
	err = database.Current.Select(&bc.Archives, database.Queries.Archives)
	if err != nil {
		return err
	}

	bc.Info = config.BlogInfo

	errparam := c.Query("error")
	if errparam != "" {
		bc.HasError = true
		bc.ErrorText = errparam
	}

	msgparam := c.Query("msg")
	if msgparam != "" {
		bc.HasMsg = true
		bc.MsgText = msgparam
	}
	return nil
}
Beispiel #6
0
// Lists all the keys in the bucket starting from "offset" key up to "limit" number of keys.
// This returns all the keys joined by "\n" so a simple split will give back an array.
func (app *App) List(c *echo.Context) error {
	// Check that we can parse limit, ignore errors
	limit, err := strconv.ParseInt(c.Query("limit"), 10, 64)
	if err != nil {
		limit = LIMIT
	}
	// Get all keys up to limit
	data := app.Store[c.Param("user")].All("store", c.Query("offset"), int(limit))
	// Join the array with new lines
	return c.String(http.StatusOK, strings.Join(data, "\n"))
}
Beispiel #7
0
func (h *handler) OauthCallbackHandler(c *echo.Context) error {
	code := c.Query("code")
	token, err := oauthConf.Exchange(oauth2.NoContext, code)
	if err != nil {
		log.Println(err.Error(), "Can't exchange token")
		return c.Redirect(http.StatusTemporaryRedirect, "/")
	}

	oauthClient := oauthConf.Client(oauth2.NoContext, token)
	client := github.NewClient(oauthClient)
	user, _, err := client.Users.Get("")
	if err != nil {
		log.Println(err.Error(), "Can't get user")
		return c.Redirect(http.StatusTemporaryRedirect, "/")
	}

	userLogin := *user.Login
	userToken := token.AccessToken

	u := &model.UserRow{
		Login:     userLogin,
		Token:     userToken,
		AvatarURL: *user.AvatarURL,
	}
	ci, err := h.back.Model.User.CreateOrUpdate(u)
	if err != nil {
		log.Println(err.Error(), "Can't create user")
		return c.Redirect(http.StatusTemporaryRedirect, "/")
	}

	s := session.Default(c)
	if ci.Updated == 0 {
		s.Set("just_signup", true)
	} else {
		u, err = h.back.Model.User.GetByLogin(userLogin)
		if err != nil {
			return c.Redirect(http.StatusTemporaryRedirect, "/")
		}
	}

	var buf bytes.Buffer
	enc := json.NewEncoder(&buf)
	enc.Encode(*u)

	s.Set("username", userLogin)
	s.Set("user", buf.String())
	// hack to display username in header
	http.SetCookie(c.Response(), &http.Cookie{Name: "username", Value: userLogin, Path: "/"})
	http.SetCookie(c.Response(), &http.Cookie{Name: "useravatar", Value: *user.AvatarURL, Path: "/"})
	s.Set("token", userToken)
	s.Save()

	return c.Redirect(http.StatusFound, "/dashboard")
}
Beispiel #8
0
func (s *yovpnServer) createEndpoint(c *echo.Context) error {
	region := c.Query("region")
	if len(region) == 0 {
		return echo.NewHTTPError(http.StatusBadRequest, "You need to provide a region!")
	}

	endpoint := s.provisioner.CreateEndpoint(region)
	c.Response().Header().Set(echo.Location, c.Echo().URI(s.getEndpoint, endpoint.ID))
	c.JSON(http.StatusAccepted, endpoint)
	return nil
}
Beispiel #9
0
/**
 *  快递用户取件查询接口GET
 */
func expressTakeUser(c *echo.Context) error {
	userID := c.Query("userID")
	if userID == "" {
		return c.JSON(http.StatusOK, errorMsg{errorNo: expressUserIDEmpty, errorMsg: "expressUserIDEmpty"})
	}
	var express []model.TcExpressMail
	err := engine.Where("express_to_user_id = ?", userID).Cols("*").Find(&express)
	if err != nil {
		return c.JSON(http.StatusOK, errorMsg{errorNo: expressTakeUserFaield, errorMsg: "expressTakeUserFaield"})
	}
	return c.JSON(http.StatusOK, express)
}
Beispiel #10
0
func NowPlaying(c *echo.Context) error {
	recent, err := radioparadise.RecentSongs()
	if err != nil {
		return err
	}

	return c.JSONP(http.StatusOK, c.Query("callback"), &struct {
		Songs []*radioparadise.Song `json:"songs"`
	}{
		recent,
	})
}
Beispiel #11
0
// deletePlace удаляет определение места.
func deletePlace(c *echo.Context) error {
	groupID := c.Get("GroupID").(string)
	placeID := c.Query("place-id")
	if !bson.IsObjectIdHex(placeID) {
		return echo.NewHTTPError(http.StatusNotFound)
	}
	err := placesDB.Delete(groupID, bson.ObjectIdHex(placeID))
	if err == mgo.ErrNotFound {
		return echo.NewHTTPError(http.StatusNotFound)
	}
	if err != nil {
		llog.Error("placesDB error: %v", err)
		return err
	}
	return c.NoContent(http.StatusOK)
}
func GetProducts(c *echo.Context) error {
	i := kendoui.Input(c.Request())
	logger.Json(i)

	callback := c.Query("callback")
	if len(callback) == 0 {
		callback = "test"
	}

	products, err := ps.GetAll()
	if err == nil {
		err = c.JSONP(http.StatusOK, callback, products)
	}

	return err
}
Beispiel #13
0
func (h *handler) SearchbackHandler(c *echo.Context) error {
	searchq := strings.ToLower(c.Query("search"))
	packages, err := h.back.Model.Package.GetItems(searchq)
	if err != nil {
		log.Error(err)
		return c.Redirect(http.StatusTemporaryRedirect, "/")
	}
	if len(searchq) > 50 && len(searchq) < 4 {
		return c.Redirect(http.StatusBadRequest, "/")
	}
	data := struct {
		Packages []model.PackageRow
	}{
		packages,
	}
	return c.Render(http.StatusOK, "search.html", data)
}
Beispiel #14
0
func Get(c *echo.Context) error {
	user := c.Get("user").(*users.User)
	if c.Query("me") == "true" {
		return utils.JSON(c, http.StatusOK, user)
	}

	if !user.IsAdmin {
		return apiErrors.AdminLevelRequired
	}

	users, err := users.FindUsers()
	if err != nil {
		log.Error(err)
		return apiErrors.InternalError.Detail("Unable to retreive the user list")
	}

	return utils.JSON(c, http.StatusOK, users)
}
func processPhotosHandler(c *echo.Context) error {
	ctx := appengine.NewContext(c.Request())

	var from time.Time
	var to time.Time
	var err error

	processorName := c.Param("processor")
	fromStr := c.Query("from")
	toStr := c.Query("to")
	now := time.Now().UTC()

	// default to previous day but allow any
	if toStr == "" {
		to = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC)
	} else {
		to, err = time.Parse(dateFormat, toStr)
		if err != nil {
			log.Errorf(ctx, "to error %s", err.Error())
			return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
		}
	}

	if fromStr == "" {
		from = to.Add(time.Duration(-24) * time.Hour)
	} else {
		from, err = time.Parse(dateFormat, fromStr)
		if err != nil {
			log.Errorf(ctx, "from error %s", err.Error())
			return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
		}
	}

	r := &photoProcessorRange{
		From: from,
		To:   to,
	}
	processorFn := photoProcessors[processorName]
	processor := processorFn(r)
	log.Debugf(c, "%#v", processor)
	processPhotosFunc.Call(ctx, processor)

	return c.NoContent(http.StatusOK)
}
Beispiel #16
0
// getSensors отдает список изменений сенсоров устройства.
func getSensors(c *echo.Context) error {
	groupID := c.Get("GroupID").(string)
	deviceID := c.Param("device-id")
	limit, err := strconv.ParseUint(c.Query("limit"), 10, 16)
	if err != nil || limit < 1 {
		limit = listLimit
	}
	lastID := c.Query("last")
	// запрашиваем список устройств постранично
	sensors, err := sensorsDB.Get(groupID, deviceID, int(limit), lastID)
	if err == mgo.ErrNotFound {
		return echo.NewHTTPError(http.StatusNotFound)
	}
	if err != nil {
		llog.Error("tracksDB error: %v", err)
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.JSON(http.StatusOK, sensors)
}
Beispiel #17
0
// createBot получает от веб-клиента данные и передает сформированную структуру менеджеру ботов
// для создания нового бота
func createBot(c *echo.Context) error {
	infbot := make(map[string]string)
	infbot["name"] = c.Query("name")
	infbot["server"] = c.Query("server")
	infbot["login"] = c.Query("login")
	infbot["password"] = c.Query("password")
	id, err := MB.AddBot(infbot)
	if err != nil {
		fmt.Println(err)
	}
	return c.String(http.StatusOK, id)
}
Beispiel #18
0
func (app *App) postValues(ctx *echo.Context) (err error) {
	key := ctx.Param("key")
	lockID := ctx.Param("lock_id")

	release, err := strconv.ParseBool(ctx.Query("release"))
	if err != nil {
		return err
	}

	value, err := readBody(ctx.Request())
	if err != nil {
		return err
	}

	app.Lock()
	entry, ok := app.store[key]
	app.Unlock()

	if !ok {
		ctx.NoContent(http.StatusNotFound)
		return
	}

	entry.Lock()
	defer entry.Unlock()

	if entry.lockID != lockID {
		ctx.NoContent(http.StatusUnauthorized)
		return
	}

	entry.value = value

	if release {
		entry.lockID = ""
	}

	ctx.NoContent(http.StatusNoContent)

	return
}
// path /update/account/:DeviceID/:ID?field1=value1&&field2=value2
// example /update/account/device10/12?Weight=17.3&&Height=20.69&&BodyFat=100.44
func setAccount(c *echo.Context, isInsert bool) error {
	deviceid := c.Param("DeviceID")
	id, err := strconv.ParseUint(c.Param("ID"), 10, 64)
	if err != nil {
		return jsonResp(c, err.Error())
	}

	acc := Account{DeviceID: deviceid, ID: id}
	has, err := g_engine.Get(&acc)
	if err != nil {
		return jsonResp(c, err.Error())
	}
	if isInsert && has {
		return jsonResp(c, "exists")
	}

	if !isInsert && !has {
		return jsonResp(c, "not exists")
	}

	for _, field := range []string{"Weight", "Height", "BodyFat"} {
		switch field {
		case "Weight":
			tmp, err := strconv.ParseFloat(c.Query(field), 32)
			acc.Weight = JSONFloat64(tmp)
			if err != nil {
				return jsonResp(c, err.Error())
			}
		case "Height":
			tmp, err := strconv.ParseFloat(c.Query(field), 32)
			acc.Height = JSONFloat64(tmp)
			if err != nil {
				return jsonResp(c, err.Error())
			}
		case "BodyFat":
			tmp, err := strconv.ParseFloat(c.Query(field), 32)
			acc.BodyFat = JSONFloat64(tmp)
			if err != nil {
				return jsonResp(c, err.Error())
			}
		}
	}

	if isInsert {
		_, err = g_engine.Insert(&acc)
	} else {
		_, err = g_engine.Update(&acc)
	}

	if err != nil {
		return jsonResp(c, err.Error())
	}

	if err = updateOrInsert(&SyncTime{DeviceID: deviceid}); err != nil {
		return jsonResp(c, err.Error())
	}

	return jsonResp(c, "success")
}
Beispiel #20
0
// sendActionToBot отправить команду боту
func sendActionToBot(c *echo.Context) error {
	param := make(map[string]interface{})
	id := c.Param("id")         // распарсить и получить id
	action := c.Param("action") // и команду

	switch action {
	case "update":
		ProcessID, _ := strconv.Atoi(c.Query("ProcessID"))
		param["ProcessID"] = ProcessID
	case "connect":
		infbot := make(map[string]string)
		infbot["name"] = "bot1"
		id, _ = MB.AddBot(infbot)
	case "disconnect":
		//		TODO отключить бота от игрового клиента
	}

	err := MB.SendActionToBot(id, action, param) // отправить команду боту
	if err != nil {
		fmt.Println(err)
	}

	return c.String(http.StatusOK, "ok\n")
}
Beispiel #21
0
func (h *avatarHandler) Get(ctx *echo.Context) error {
	name := ctx.Param("name")
	size := ctx.Query("size")
	if size == "" {
		size = "120"
	}
	//FIXME: auto size
	sz, err := strconv.Atoi(size)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}

	data, err := h.avatar.DrawToBytes(name, sz)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}

	ctx.Response().Header().Set("Content-Type", "image/png")
	ctx.Response().Header().Set("Cache-Control", "max-age=600")
	ctx.Response().WriteHeader(http.StatusOK)
	ctx.Response().Write(data)

	return nil
}
Beispiel #22
0
func (api *API) segmentation(c *echo.Context) error {
	event := c.Query("event")
	property := c.Query("property")
	sFrom := c.Query("from")
	sTo := c.Query("to")

	iFrom, err := strconv.ParseInt(sFrom, 10, 64)
	if err != nil {
		return err
	}

	iTo, err := strconv.ParseInt(sTo, 10, 64)
	if err != nil {
		return err
	}

	segments, err := api.serviceSegmentation.GetSegments(event, property, iFrom, iTo)
	if err != nil {
		return err
	}

	return c.JSON(http.StatusOK, segments)
}
Beispiel #23
0
func Get(c *echo.Context) error {
	w := c.Response()
	r := c.Request()

	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Cashe-Control", "no-store")
	w.Header().Set("Expires", "Sat, 01 Jan 2000 00:00:00 GMT")
	w.Header().Set("Pragma", "no-cache")

	path := c.Query("path")

	filename := c.Query("filename")
	if len(filename) == 0 {
		return c.JSON(
			http.StatusBadRequest,
			hash{
				"error": "Invalid Path",
			},
		)
	}

	var user *users.User
	var err error

	downloadToken := c.Query("token")
	if len(downloadToken) > 0 {
		user, err = checkDownloadToken(downloadToken, filename)
		if err != nil {
			return c.JSON(
				http.StatusBadRequest,
				hash{
					"error": "Invalid Download Token",
				},
			)
		}
	}

	if user == nil {
		u, fail := oauth2.GetUser(w, r)
		if u == nil {
			return errors.New("no authenticated user")
		}

		if fail != nil {
			return oauthError(c, fail)
		}

		user = u.(*users.User)
	}

	winUser, err := user.WindowsCredentials()
	if err != nil {
		return err
	}

	if filename[0] == '.' {
		path = filepath.Join(
			fmt.Sprintf(
				utils.Env("PLAZA_USER_DIR", "C:\\Users\\%s\\Desktop\\Nanocloud"),
				winUser.Sam,
			),
			filename,
		)
	} else {
		filename = strings.Replace(filename, "/", "\\", -1)
		path = filename
	}

	resp, err := http.Get("http://" + utils.Env("PLAZA_ADDRESS", "iaas-module") + ":" + utils.Env("PLAZA_PORT", "9090") + "/files?create=true&path=" + url.QueryEscape(path))
	if err != nil {
		log.Error(err)
		return apiErrors.WindowsNotOnline.Detail(err.Error())
	}

	if resp.StatusCode == http.StatusNotFound {
		jsonResponse(w, r, http.StatusNotFound, hash{
			"error": "File Not Found",
		})
		return nil
	}

	if resp.StatusCode != http.StatusOK {
		contents, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return errors.New("Unable to retrieve the file")
		}

		return apiErrors.NeedFirstConnection.Detail(string(contents))
	}

	var contentType string
	rContentType, exists := resp.Header["Content-Type"]
	if !exists || len(rContentType) == 0 || len(rContentType[0]) == 0 {
		contentType = "application/octet-stream"
	} else {
		contentType = rContentType[0]
	}

	var sent int64
	var lastBuffSize int64

	contentLength := resp.ContentLength

	var f string
	splt := strings.Split(path, "\\")
	if len(splt) > 0 {
		f = splt[len(splt)-1]
	} else {
		f = path
	}

	w.Header().Set("Content-Type", contentType)
	w.Header().Set("Content-Length", strconv.FormatInt(contentLength, 10))
	w.Header().Set("Content-Disposition", "attachment; filename=\""+f+"\"")

	var buff []byte

	for sent < contentLength {
		remaining := contentLength - sent
		if remaining > 4096 {
			remaining = 4096
		}

		if buff == nil || remaining != lastBuffSize {
			buff = make([]byte, remaining)
			lastBuffSize = remaining
		}

		nRead, readErr := resp.Body.Read(buff)

		if nRead > 0 {
			nWrite, writeErr := w.Write(buff[0:nRead])
			sent = sent + int64(nWrite)

			if writeErr != nil {
				log.Errorf("Write error: %s\n", writeErr.Error())
				break
			}
		}

		if readErr != nil && readErr.Error() != "EOF" {
			log.Errorf("Read error: %s\n", readErr.Error())
			break
		}
	}
	return nil
}
Beispiel #24
0
func Tickets(c *echo.Context) error {
	// cookie := checkCookie(c)
	// cookie := c.Param(model.SkCookie)
	cookie := c.Query(model.SkCookie)

	if cookie == "" {
		log.Println("Error!! Cookie is null")
		return c.JSON(model.CookieCheckFailed, model.OrderInfo{Timestamp: time.Now().UTC().Unix()})
	}

	phoneNum := c.Query("phone")
	if phoneNum == "" {
		log.Println("Error!! Phone is null")
		return c.JSON(model.UserPhoneNumNull, model.OrderInfo{Timestamp: time.Now().UTC().Unix(), UID: cookie})
	}

	eid := c.Query("id")
	if eid == "" {
		log.Println("Error!! Id is null")
		return c.JSON(model.UserPhoneNumNull, model.OrderInfo{Timestamp: time.Now().UTC().Unix(), UID: cookie})
	}

	model.CurrentEventId = eid

	// Get user info by cookie(UUID)
	// if cookie is not exit in redis return error
	// if status is null or status not 1 return StatusNotOne/StatusNull
	// if phone is null return UserPhoneNumNull
	// if event is null or event is not match current event return EventNull/EventNotMatch
	ckey := fmt.Sprintf(model.CookHashKey, cookie, eid)
	err := cache.CheckStatus(ckey)
	if err != nil {
		log.Printf("Error!! Status of %s is invalid", ckey)
		return c.JSON(model.InvalidStatus, model.OrderInfo{Timestamp: time.Now().UTC().Unix(), UID: cookie, EventId: eid})
	}

	// check phone number and event id make sure one phone number only have once chance in one activity
	repeat, err := cache.CheckPhoneNum(phoneNum)
	if err != nil {
		log.Println("check user phone number hs error: ", err)
	}

	order := &model.OrderInfo{
		Timestamp: time.Now().UTC().Unix(),
		UID:       cookie,
		EventId:   eid,
		Phone:     phoneNum,
	}

	if !repeat {
		return c.JSON(model.PhoneRepaet, order)
	}

	code := ProduceOrder(order)
	if code == 0 {
		go SaveOrder(order)
		return c.JSON(http.StatusOK, order)
	}

	return c.JSON(code, order)
}
Beispiel #25
0
func Get(c *echo.Context) error {
	filepath := c.Query("path")
	showHidden := c.Query("show_hidden") == "true"
	create := c.Query("create") == "true"

	if len(filepath) < 1 {
		return c.JSON(
			http.StatusBadRequest,
			hash{
				"error": "Path not specified",
			},
		)
	}

	s, err := os.Stat(filepath)
	if err != nil {
		log.Error(err.(*os.PathError).Err.Error())
		m := err.(*os.PathError).Err.Error()
		if m == "no such file or directory" || m == "The system cannot find the file specified." {
			if create {
				err := os.MkdirAll(filepath, 0777)
				if err != nil {
					return err
				}
				s, err = os.Stat(filepath)
				if err != nil {
					return err
				}
			} else {
				return c.JSON(
					http.StatusNotFound,
					hash{
						"error": "no such file or directory",
					},
				)
			}
		} else {
			return err
		}
	}

	if s.Mode().IsDir() {
		f, err := os.Open(filepath)
		if err != nil {
			return err
		}
		defer f.Close()

		files, err := f.Readdir(-1)
		if err != nil {
			return err
		}

		rt := make([]*file, 0)

		for _, fi := range files {
			name := fi.Name()
			if !showHidden && isFileHidden(fi) {
				continue
			}

			fullpath := path.Join(filepath, name)
			id, err := loadFileId(fullpath)
			if err != nil {
				log.Errorf("Cannot retrieve file id for file: %s: %s", fullpath, err.Error())
				continue
			}

			f := &file{
				Id:      id,
				ModTime: fi.ModTime().Unix(),
				Name:    name,
				Size:    fi.Size(),
			}
			if fi.IsDir() {
				f.Type = "directory"
			} else {
				f.Type = "regular file"
			}
			rt = append(rt, f)
		}
		/*
		 * The Content-Length is not set is the buffer length is more than 2048
		 */
		b, err := jsonapi.Marshal(rt)
		if err != nil {
			log.Error(err)
			return err
		}

		r := c.Response()
		r.Header().Set("Content-Length", strconv.Itoa(len(b)))
		r.Header().Set("Content-Type", "application/json; charset=utf-8")
		r.Write(b)
		return nil
	}

	return c.File(
		filepath,
		s.Name(),
		true,
	)
}
// path /update/lifthistory/:DeviceID/:ID?field1=value1&&field2=value2
// example /update/lifthistory/device10/15?Lift=kkk&&BodyPart=leg&&Weight=30.44&&Reps=300&&Date=2015-04-04&&Active=false
func setLiftHistory(c *echo.Context, isInsert bool) error {
	deviceid := c.Param("DeviceID")
	id, err := strconv.ParseUint(c.Param("ID"), 10, 64)
	if err != nil {
		return jsonResp(c, err.Error())
	}

	lift := LiftHistory{DeviceID: deviceid, ID: id}
	has, err := g_engine.Get(&lift)
	if err != nil {
		return jsonResp(c, err.Error())
	}
	if isInsert && has {
		return jsonResp(c, "exists")
	}

	if !isInsert && !has {
		return jsonResp(c, "not exists")
	}

	for _, field := range []string{"Lift", "BodyPart", "Weight", "Reps", "Date", "Active"} {
		switch field {
		case "Lift":
			lift.Lift = c.Query(field)
		case "BodyPart":
			lift.BodyPart = c.Query(field)
		case "Weight":
			tmp, err := strconv.ParseFloat(c.Query(field), 32)
			lift.Weight = JSONFloat64(tmp)
			if err != nil {
				return jsonResp(c, err.Error())
			}
		case "Reps":
			lift.Reps, err = strconv.ParseUint(c.Query(field), 10, 64)
			if err != nil {
				return jsonResp(c, err.Error())
			}
		case "InsertDate":
			date, err := time.Parse(TIME_LAYOUT, c.Query(field))
			lift.InsertDate = JSONTime(date)
			if err != nil {
				return jsonResp(c, err.Error())
			}
		case "LiftDate":
			date, err := time.Parse(TIME_LAYOUT, c.Query(field))
			lift.LiftDate = JSONTime(date)
			if err != nil {
				return jsonResp(c, err.Error())
			}
		case "Active":
			lift.Active, err = strconv.ParseBool(c.Query(field))
			if err != nil {
				return jsonResp(c, err.Error())
			}
		}
	}

	if isInsert {
		_, err = g_engine.Insert(&lift)
	} else {
		_, err = g_engine.Update(&lift)
	}

	if err != nil {
		return jsonResp(c, err.Error())
	}

	if err = updateOrInsert(&SyncTime{DeviceID: deviceid}); err != nil {
		return jsonResp(c, err.Error())
	}

	return jsonResp(c, "success")
}