simplex/applications/api.moon

160 lines
5.7 KiB
Plaintext
Raw Normal View History

2018-04-23 12:00:42 +00:00
import Application from require "lapis"
2018-04-23 13:15:44 +00:00
import assert_valid from require "lapis.validate"
import APIKeys, Users, Tasks from require "models"
2018-04-25 00:32:08 +00:00
import locate from require "locator"
2018-04-25 00:55:38 +00:00
import api_request, abort from locate "helpers.api"
2018-04-23 12:00:42 +00:00
-- import random from locate "calc"
-- import escape_similar_to from locate "db"
get_task = =>
if @params.id
assert_valid @params, {
{"id", exists: true, min_length: 1, "Attempted to select by task id, but no id specified."}
{"id", is_integer: true, "Task id is not an integer."}
}
@task = Tasks\find id: @params.id, user_id: @user.id
elseif @params.content
assert_valid @params, {
{"content", exists: true, min_length: 1, "Attempted to select by task content, but no content specified."}
}
@task = Tasks\find content: @params.content, user_id: @user.id
else
abort "Task id or content not specified."
abort 404, "Invalid task specified." unless @task
2018-04-23 12:00:42 +00:00
class API extends Application
@path: "/v1"
@name: "api_"
2018-04-25 00:37:52 +00:00
@before_filter( api_request =>
return if @user
if auth = @req.headers["authorization"]
if auth\len! > 0
@params.api_key = auth
abort "Auth: api_key not specified." unless @params.api_key
2018-04-23 12:00:42 +00:00
@api_key = APIKeys\find key: @params.api_key
abort "Auth: Invalid api_key." unless @api_key
@user = Users\find id: @api_key.user_id
abort "Auth: Invalid api_key." unless @user -- NOTE this should also delete the api_key and error (this should never happen!)
2018-04-23 12:00:42 +00:00
)
2018-04-25 00:28:23 +00:00
[new: "/new"]: api_request =>
2018-04-23 12:00:42 +00:00
assert_valid @params, {
{"content", exists: true, min_length: 1, "Task content not specified."}
}
task, err = Tasks\create {
user_id: @user.id
2018-04-23 12:00:42 +00:00
content: @params.content
}
2018-04-25 00:55:38 +00:00
abort 500, err unless task
2018-04-23 12:00:42 +00:00
return json: { success: true, :task }
2018-04-25 01:33:18 +00:00
[get: "/get"]: api_request =>
get_task(@)
-- return json: { success: true, :task }
2018-04-25 01:33:18 +00:00
abort 501, "Not implemented."
2018-04-25 00:37:52 +00:00
[do: "/do"]: api_request =>
get_task(@)
@task, err = @task\update done: true
abort 500, err unless @task
return json: { success: true, :task }
2018-04-25 00:37:52 +00:00
[undo: "/undo"]: api_request =>
get_task(@)
@task, err = @task\update done: false
abort 500, err unless @task
return json: { success: true, :task }
2018-04-25 02:44:46 +00:00
[delete: "/delete"]: api_request =>
get_task(@)
if @task\delete!
return json: { success: true }
else
abort 500, "Error deleting task."
2018-04-25 00:37:52 +00:00
[random: "/random"]: api_request =>
assert_valid @params, {
{"count", exists: true, is_integer: true, optional: true, "Count is not an integer."}
{"done", exists: true, one_of: {true, false}, optional: true, "Done is not a boolean."}
}
@params.count or= 1
@params.done = false if @params.done == nil
2018-04-25 00:55:38 +00:00
abort 501, "Not implemented."
2018-04-25 00:37:52 +00:00
-- possibly need to store how many items each user has and use a different strategy for users with low amounts vs high amounts
-- key = get_key(@)
--
-- local tasks
-- if @params.done
-- offset = random Tasks\count "user_id = ? AND done = ? ORDER BY id ASC", key.user_id, @params.done
-- tasks = Tasks\select "WHERE user_id = ? AND done = ? ORDER BY id ASC OFFSET ? LIMIT 1", key.user_id, @params.done, offset
-- else
-- offset = random Tasks\count "user_id = ? ORDER BY id ASC", key.user_id
-- tasks = Tasks\select "WHERE user_id = ? ORDER BY id ASC OFFSET ? LIMIT 1", key.user_id, offset
--
-- if tasks and #tasks == 1
-- return json: { success: true, task: tasks[1] }
-- else
2018-04-25 00:55:38 +00:00
-- abort!
2018-04-25 00:37:52 +00:00
[list: "/list"]: api_request =>
assert_valid @params, {
{"count", exists: true, is_integer: true, optional: true, "Count is not an integer."}
{"done", exists: true, one_of: {true, false}, optional: true, "Done is not a boolean."}
{"page", exists: true, is_integer: true, optional: true, "Page is not an integer."}
{"order", exists: true, one_of: {"asc", "desc"}, optional: true, "Invalid order. (Must be 'asc' or 'desc'.)"}
}
@params.count or= 50
@params.page or= 1
2018-04-24 17:02:51 +00:00
@params.order or= "asc"
2018-04-25 00:55:38 +00:00
abort "Invalid page. (Must be a positive integer.)" if @params.page < 1
local Paginator
if @params.done == nil
Paginator = Tasks\paginated "WHERE user_id = ? ORDER BY created_at ?", @user.id, @params.order, per_page: @params.count
else
Paginator = Tasks\paginated "WHERE user_id = ? AND done = ? ORDER BY created_at ?", @user.id, @params.done, @params.order, per_page: @params.count
num_pages = Paginator\num_pages!
if num_pages < @params.page
@params.page = num_pages
tasks = Paginator\get_page(@params.page)
-- returns page in case it returned a different page than you asked for! (in the case you ask for a page beyond the end)
return json: { success: true, page: @params.page, :tasks }
2018-04-25 00:37:52 +00:00
[new_key: "/key/new"]: api_request =>
2018-04-25 01:33:18 +00:00
api_key, err = APIKeys\create(@user)
abort 500, err unless api_key
return json: { success: true, :api_key }
2018-04-25 00:37:52 +00:00
[delete_key: "/key/delete"]: api_request =>
if @params.id
assert_valid @params, {
{"id", exists: true, min_length: 1, "Attempted to select by API key id, but no id specified."}
{"id", is_integer: true, "API key id is not an integer."}
}
@key_to_delete = APIKeys\find id: @params.id, user_id: @user.id
elseif @params.key
assert_valid @params, {
{"key", exists: true, min_length: 32, max_length: 32, "Invalid api_key specified."}
}
@key_to_delete = APIKeys\find key: @params.key, user_id: @user.id
else
abort 400, "No api_key specified."
abort 404, "Invalid api_key specified." unless @key_to_delete
if @key_to_delete\delete!
return json: { success: true }
else
abort 500, "Error deleting api_key."