wip interface, err fixes, reorganization, config added, test ready
This commit is contained in:
parent
7c6f7dab03
commit
aeab084ecb
128
app.moon
128
app.moon
@ -1,115 +1,33 @@
|
|||||||
import Application from require "lapis"
|
import Application from require "lapis"
|
||||||
import json_params, capture_errors_json, yield_error, assert_error from require "lapis.application"
|
|
||||||
import assert_valid from require "lapis.validate"
|
|
||||||
|
|
||||||
import Keys, Tasks from require "models"
|
import Keys, Tasks from require "models"
|
||||||
import locate from require "locator"
|
import autoload, locate, registry from require "locator"
|
||||||
import random from locate "calc"
|
import settings from autoload "utility"
|
||||||
import escape_similar_to from locate "db"
|
|
||||||
|
|
||||||
get_key = =>
|
|
||||||
yield_error "api_key not specified." unless @params.api_key and @params.api_key\len! > 0
|
|
||||||
if key = Keys\find uuid: @params.api_key
|
|
||||||
return key
|
|
||||||
else
|
|
||||||
yield_error "Invalid api_key."
|
|
||||||
|
|
||||||
get_task = =>
|
|
||||||
assert_valid @params, {
|
|
||||||
{"api_key", exists: true, "api_key not specified."}
|
|
||||||
{"id", exists: true, "Task id not specified."}
|
|
||||||
{"id", is_integer: true, "Task id is invalid."}
|
|
||||||
}
|
|
||||||
|
|
||||||
key = Keys\find uuid: @params.api_key
|
|
||||||
yield_error "Invalid api_key." unless key
|
|
||||||
|
|
||||||
task = Tasks\find id: @params.id
|
|
||||||
yield_error "Invalid task id." unless task
|
|
||||||
|
|
||||||
unless task.user_id == key.user_id
|
|
||||||
yield_error "Invalid task id."
|
|
||||||
|
|
||||||
return task
|
|
||||||
|
|
||||||
class extends Application
|
class extends Application
|
||||||
-- api_key AND text
|
@before_filter =>
|
||||||
[new: "/new"]: capture_errors_json =>
|
settings.load!
|
||||||
json_params =>
|
registry.before_filter(@)
|
||||||
key = get_key(@)
|
|
||||||
yield_error "Task text not specified." unless @params.text and @params.text\len! > 0
|
|
||||||
|
|
||||||
task = assert_error Tasks\create {
|
-- layout: "layout"
|
||||||
user_id: key.user_id
|
@include locate "users"
|
||||||
text: @params.text
|
@include locate "api"
|
||||||
}
|
|
||||||
|
|
||||||
return json: { success: true, :task }
|
[index: "/"]: =>
|
||||||
|
if @user
|
||||||
|
@keys = Keys\find user_id: @user.id
|
||||||
|
@tasks = Tasks\find user_id: @user.id -- TODO convert to paginated
|
||||||
|
|
||||||
-- api_key AND id
|
unless #@keys > 0
|
||||||
[do: "/do"]: capture_errors_json =>
|
table.insert @keys, Keys\create user_id: @user.id
|
||||||
json_params =>
|
|
||||||
task = get_task(@)
|
|
||||||
task = assert_error task\update { done: true }
|
|
||||||
return json: { success: true, :task }
|
|
||||||
|
|
||||||
-- api_key AND id
|
return render: "index.logged_in"
|
||||||
[undo: "/undo"]: capture_errors_json =>
|
|
||||||
json_params =>
|
|
||||||
task = get_task(@)
|
|
||||||
task = assert_error task\update { done: false }
|
|
||||||
return json: { success: true, :task }
|
|
||||||
|
|
||||||
-- api_key AND (id OR (done true/false/nil AND/OR page))
|
else
|
||||||
[fetch: "/fetch"]: capture_errors_json =>
|
return redirect_to: @url_for "user_login"
|
||||||
json_params =>
|
-- TODO
|
||||||
if @params.id
|
-- return render: "index.logged_out"
|
||||||
task = get_task(@)
|
|
||||||
return json: { success: true, :task }
|
|
||||||
else
|
|
||||||
key = get_key(@)
|
|
||||||
page = tonumber(@params.page) or 1
|
|
||||||
|
|
||||||
local paginator
|
-- [generate_api_key: "/generate_api_key"]: =>
|
||||||
if @params.done != nil
|
-- if @user
|
||||||
paginator = Tasks\paginated "WHERE user_id = ? AND done = ? ORDER BY id ASC", key.user_id, @params.done, per_page: 50
|
-- if key = Keys\create user_id: @user.id
|
||||||
else
|
-- return json: { success: true, :key }
|
||||||
paginator = Tasks\paginated "WHERE user_id = ? ORDER BY id ASC", key.user_id, per_page: 50
|
|
||||||
|
|
||||||
tasks = paginator\get_page page
|
|
||||||
return json: { success: true, :tasks }
|
|
||||||
|
|
||||||
-- api_key AND done true/false/nil
|
|
||||||
[random: "/fetch/random"]: capture_errors_json =>
|
|
||||||
json_params =>
|
|
||||||
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
|
|
||||||
return status: 500, json: { errors: "No task matches query." }
|
|
||||||
|
|
||||||
-- api_key AND done true/false/nil AND/OR case true
|
|
||||||
[search: "/search"]: capture_errors_json =>
|
|
||||||
json_params =>
|
|
||||||
key = get_key(@)
|
|
||||||
like = @params.case and "ILIKE" or "LIKE"
|
|
||||||
|
|
||||||
local tasks
|
|
||||||
if @params.done
|
|
||||||
tasks = Tasks\select "WHERE user_id = ? AND done = ? AND text #{like} ? ORDER BY id ASC", key.user_id, @params.done, escape_similar_to @params.text
|
|
||||||
else
|
|
||||||
tasks = Tasks\select "WHERE user_id = ? AND text #{like} ? ORDER BY id ASC", key.user_id, escape_similar_to @params.text
|
|
||||||
|
|
||||||
if tasks and #tasks == 1
|
|
||||||
return json: { success: true, task: tasks[1] }
|
|
||||||
else
|
|
||||||
return status: 500, json: { errors: "No task matches query." }
|
|
||||||
|
121
applications/api.moon
Normal file
121
applications/api.moon
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
import Application from require "lapis"
|
||||||
|
import json_params, capture_errors_json, yield_error, assert_error from require "lapis.application"
|
||||||
|
import assert_valid from require "lapis.validate"
|
||||||
|
|
||||||
|
import Keys, Tasks from require "models"
|
||||||
|
import locate from require "locator"
|
||||||
|
import random from locate "calc"
|
||||||
|
import escape_similar_to from locate "db"
|
||||||
|
|
||||||
|
standard_err = ->
|
||||||
|
return status: 500, json: { errors: {"No task matches query."} }
|
||||||
|
|
||||||
|
get_key = =>
|
||||||
|
yield_error "api_key not specified." unless @params.api_key and @params.api_key\len! > 0
|
||||||
|
if key = Keys\find uuid: @params.api_key
|
||||||
|
return key
|
||||||
|
else
|
||||||
|
yield_error "Invalid api_key."
|
||||||
|
|
||||||
|
get_task = =>
|
||||||
|
assert_valid @params, {
|
||||||
|
{"id", exists: true, "Task id not specified."}
|
||||||
|
{"id", is_integer: true, "Task id is invalid."}
|
||||||
|
}
|
||||||
|
|
||||||
|
key = get_key(@)
|
||||||
|
task = Tasks\find id: @params.id
|
||||||
|
yield_error "Invalid task id." unless task
|
||||||
|
|
||||||
|
unless task.user_id == key.user_id
|
||||||
|
yield_error "Invalid task id."
|
||||||
|
|
||||||
|
return task
|
||||||
|
|
||||||
|
class extends Application
|
||||||
|
-- api_key AND text
|
||||||
|
[new: "/new"]: capture_errors_json =>
|
||||||
|
json_params =>
|
||||||
|
key = get_key(@)
|
||||||
|
yield_error "Task text not specified." unless @params.text and @params.text\len! > 0
|
||||||
|
|
||||||
|
task = assert_error Tasks\create {
|
||||||
|
user_id: key.user_id
|
||||||
|
text: @params.text
|
||||||
|
}
|
||||||
|
|
||||||
|
return json: { success: true, :task }
|
||||||
|
|
||||||
|
-- api_key AND id
|
||||||
|
[do: "/do"]: capture_errors_json =>
|
||||||
|
json_params =>
|
||||||
|
if task = get_task(@)
|
||||||
|
task = assert_error task\update { done: true }
|
||||||
|
return json: { success: true, :task }
|
||||||
|
else
|
||||||
|
return standard_err!
|
||||||
|
|
||||||
|
-- api_key AND id
|
||||||
|
[undo: "/undo"]: capture_errors_json =>
|
||||||
|
json_params =>
|
||||||
|
if task = get_task(@)
|
||||||
|
task = assert_error task\update { done: false }
|
||||||
|
return json: { success: true, :task }
|
||||||
|
else
|
||||||
|
return standard_err!
|
||||||
|
|
||||||
|
-- api_key AND (id OR (done true/false/nil AND/OR page))
|
||||||
|
[fetch: "/fetch"]: capture_errors_json =>
|
||||||
|
json_params =>
|
||||||
|
if @params.id
|
||||||
|
if task = get_task(@)
|
||||||
|
return json: { success: true, :task }
|
||||||
|
else
|
||||||
|
return standard_err!
|
||||||
|
else
|
||||||
|
key = get_key(@)
|
||||||
|
page = tonumber(@params.page) or 1
|
||||||
|
|
||||||
|
local paginator
|
||||||
|
if @params.done != nil
|
||||||
|
paginator = Tasks\paginated "WHERE user_id = ? AND done = ? ORDER BY id ASC", key.user_id, @params.done, per_page: 50
|
||||||
|
else
|
||||||
|
paginator = Tasks\paginated "WHERE user_id = ? ORDER BY id ASC", key.user_id, per_page: 50
|
||||||
|
|
||||||
|
tasks = paginator\get_page page
|
||||||
|
return json: { success: true, :tasks }
|
||||||
|
|
||||||
|
-- api_key AND done true/false/nil
|
||||||
|
[random: "/fetch/random"]: capture_errors_json =>
|
||||||
|
json_params =>
|
||||||
|
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
|
||||||
|
return standard_err!
|
||||||
|
|
||||||
|
-- api_key AND done true/false/nil AND/OR case true
|
||||||
|
[search: "/search"]: capture_errors_json =>
|
||||||
|
json_params =>
|
||||||
|
key = get_key(@)
|
||||||
|
like = @params.case and "ILIKE" or "LIKE"
|
||||||
|
|
||||||
|
local tasks
|
||||||
|
if @params.done
|
||||||
|
tasks = Tasks\select "WHERE user_id = ? AND done = ? AND text #{like} ? ORDER BY id ASC", key.user_id, @params.done, escape_similar_to @params.text
|
||||||
|
else
|
||||||
|
tasks = Tasks\select "WHERE user_id = ? AND text #{like} ? ORDER BY id ASC", key.user_id, escape_similar_to @params.text
|
||||||
|
|
||||||
|
if tasks and #tasks >= 1
|
||||||
|
return json: { success: true, :tasks }
|
||||||
|
else
|
||||||
|
return standard_err!
|
25
config.moon
Normal file
25
config.moon
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
config = require "lapis.config"
|
||||||
|
import autoload from require "locator"
|
||||||
|
import sql_password, session_secret from autoload "secret"
|
||||||
|
|
||||||
|
config {"production", "development"}, ->
|
||||||
|
session_name "simplex"
|
||||||
|
secret session_secret
|
||||||
|
postgres ->
|
||||||
|
host "127.0.0.1"
|
||||||
|
user "postgres"
|
||||||
|
password sql_password
|
||||||
|
|
||||||
|
config "production", ->
|
||||||
|
postgres ->
|
||||||
|
database "simplex"
|
||||||
|
num_workers 4
|
||||||
|
code_cache "on"
|
||||||
|
port 8251
|
||||||
|
|
||||||
|
config "development", ->
|
||||||
|
postgres ->
|
||||||
|
database "dev.simplex"
|
||||||
|
num_workers 2
|
||||||
|
code_cache "off"
|
||||||
|
port 8250
|
@ -6,6 +6,9 @@
|
|||||||
fetch: "https://github.com/lazuscripts/users"
|
fetch: "https://github.com/lazuscripts/users"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
path: "applications"
|
||||||
|
}
|
||||||
{
|
{
|
||||||
path: "utility"
|
path: "utility"
|
||||||
remote: {
|
remote: {
|
||||||
|
@ -20,4 +20,10 @@ make_migrations {
|
|||||||
{"created_at", types.time}
|
{"created_at", types.time}
|
||||||
{"updated_at", types.time}
|
{"updated_at", types.time}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create_index "keys", "user_id"
|
||||||
|
create_index "keys", "uuid"
|
||||||
|
create_index "tasks", "id"
|
||||||
|
create_index "tasks", "user_id"
|
||||||
|
create_index "tasks", "user_id", "done"
|
||||||
}
|
}
|
||||||
|
44
static/index.js
Normal file
44
static/index.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
function request(url) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", url, true);
|
||||||
|
xhr.setRequestHeader("Content-Type", "application/json");
|
||||||
|
return xhr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check(id) {
|
||||||
|
var checkbox = document.getElementById("task-"+id);
|
||||||
|
if (checkbox.checked) {
|
||||||
|
var xhr = request("/do");
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
// TODO handle success / errors
|
||||||
|
console.log(xhr.responseText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhr.send(JSON.stringify({api_key: API_KEY, id: id}));
|
||||||
|
} else {
|
||||||
|
var xhr = request("/undo");
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
// TODO handle success / errors
|
||||||
|
console.log(xhr.responseText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhr.send(JSON.stringify({api_key: API_KEY, id: id}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function new() {
|
||||||
|
var text = document.getElementById("new-task");
|
||||||
|
console.log(text); // TEMPORARY
|
||||||
|
var xhr = request("/new");
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
// TODO handle success / errors
|
||||||
|
console.log(xhr.responseText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhr.send(JSON.stringify({api_key: API_KEY, text: text.value}));
|
||||||
|
|
||||||
|
return false; // prevent form submission
|
||||||
|
}
|
25
views/index/logged_in.moon
Normal file
25
views/index/logged_in.moon
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import Widget from require "lapis.html"
|
||||||
|
|
||||||
|
class extends Widget
|
||||||
|
content: =>
|
||||||
|
script -> raw "var API_KEY = '#{@keys[1].uuid}';"
|
||||||
|
script src: "/static/index.js"
|
||||||
|
p "API Keys:"
|
||||||
|
ul ->
|
||||||
|
for key in *@keys
|
||||||
|
li key.uuid
|
||||||
|
-- li ->
|
||||||
|
-- a onclick: "new_key()"
|
||||||
|
|
||||||
|
p "Tasks:"
|
||||||
|
ul ->
|
||||||
|
for task in *@tasks
|
||||||
|
li ->
|
||||||
|
input type: "checkbox", id: "task-#{task.id}", onchange: "check(#{task.id})" checked: task.done
|
||||||
|
text " #{task.text}"
|
||||||
|
li ->
|
||||||
|
form {
|
||||||
|
onsubmit: "new()"
|
||||||
|
}, ->
|
||||||
|
input type: "text", id: "new-task", placeholder: "new task"
|
||||||
|
input type: "submit", value: "add task"
|
Loading…
Reference in New Issue
Block a user