require "json" require "./handler" module Guff module APIMethods API = { "post": { "get_posts": { text: "Get posts matching query.", args: { "q": { text: "Search string.", type: :text, required: false, default: "", }, "page": { text: "Page number", type: :int, required: false, default: "1", }, "tags": { text: "Comma-separated list of tags (union)", type: :tag_list, required: false, default: "1", }, "sort": { text: "Sort order of results", type: :sort, required: false, default: "date,desc", }, }, }, "add_post": { text: "Create new post.", args: { "name": { text: "Post title.", type: :text, required: true, }, "slug": { text: "Post slug.", type: :slug, required: true, }, "body": { text: "Post body.", type: :text, required: true, }, "tags": { text: "Post tags.", type: :tag_list, required: false, default: "", }, }, }, "remove_posts": { text: "Remove existing posts.", args: { "post_ids": { text: "Post IDs.", type: :int_list, required: false, default: "", }, "tags": { text: "Post tags.", type: :tag_list, required: false, default: "", }, }, }, "set_tags": { text: "Set tags for posts.", args: { "post_ids": { text: "Post IDs.", type: :int_list, required: true, }, }, }, }, "dir": { "add": { text: "Create new directory", args: { "path": { text: "Path to new directory", type: :path, required: true, }, }, }, "remove": { text: "Remove directory", args: { "path": { text: "Path to existing directory", type: :path, required: true, }, }, }, }, "file": { "add": { text: "Upload new file", args: { "path": { text: "Destination file path", type: :path, required: true, }, }, }, "remove": { text: "Remove existing file", args: { "path": { text: "Destination file path", type: :path, required: true, }, }, }, }, "tag": { "get_tags": { text: "Get list of tags", }, "remove_tags": { text: "Remove set of tags", args: { "tags": { text: "Tags to remove.", type: :tag_list, required: false, default: "", }, }, }, }, "test": { "version": { text: "Get version", }, "get_posts": { text: "Test get posts", }, "error": { text: "Test error response", }, } } TYPE_CHECKS = { text: /.*/, slug: /^[a-z0-9\.-]+$/, int: /^\d+$/, int_list: /^\d+(?:,\d+)*$/, tag_list: /^[a-z0-9_\/ -]+(?:,[a-z0-9_\/ -]+)*$/, sort: /^[a-z0-9_]+,(?:asc|desc)$/, # FIXME: lock this down more path: /^[^\/].*[^\/]$/, } private def get_method_args( params : HTTP::Params, namespace : String, method : String ) return {} of String => String unless ( API[namespace]? && API[namespace][method] && API[namespace][method][:args]? ) # get method args args = API[namespace][method][:args] as \ Hash(String, Hash(Symbol, String | Symbol | Bool)) args.keys.reduce({} of String => String) do |r, arg_name| arg_data = args[arg_name] as Hash(Symbol, String|Symbol|Bool) # check for required parameter if arg_data[:required] && !params.has_key?(arg_name) raise "missing required parameter: %s" % [arg_name] end # get value val = if arg_data[:required] params.fetch(arg_name) else params.fetch(arg_name, arg_data[:default] as String) end # check value if !TYPE_CHECKS[arg_data[:type]].match(val) raise "invalid parameter format: %s" % [arg_name] end # add value to result r[arg_name] = val # return result r end end ################ # post methods # ################ private def do_post_get_posts( context : HTTP::Server::Context, args : Hash(String, String) ) # TODO [{foo: "bar"}, {foo: "asdf"}].to_json end private def do_post_add_post( context : HTTP::Server::Context, args : Hash(String, String) ) # TODO: return post id {ok: true}.to_json end private def do_post_remove_posts( context : HTTP::Server::Context, args : Hash(String, String) ) # TODO {ok: true}.to_json end private def do_post_set_tags( context : HTTP::Server::Context, args : Hash(String, String) ) # TODO {ok: true}.to_json end ############### # dir methods # ############### private def do_dir_add( context : HTTP::Server::Context, args : Hash(String, String) ) # TODO {ok: true}.to_json end private def do_dir_remove( context : HTTP::Server::Context, args : Hash(String, String) ) # TODO {ok: true}.to_json end ################ # file methods # ################ private def do_file_add( context : HTTP::Server::Context, args : Hash(String, String) ) # TODO {ok: true}.to_json end private def do_file_remove( context : HTTP::Server::Context, args : Hash(String, String) ) # TODO {ok: true}.to_json end ############### # tag methods # ############### private def do_tag_get_tags( context : HTTP::Server::Context, args : Hash(String, String) ) [{foo: "bar"}, {foo: "asdf"}].to_json end private def do_tag_remove_tags( context : HTTP::Server::Context, args : Hash(String, String) ) true.to_json end ################ # test methods # ################ private def do_test_version( context : HTTP::Server::Context, args : Hash(String, String) ) {version: Guff::VERSION}.to_json end private def do_test_get_posts( context : HTTP::Server::Context, args : Hash(String, String) ) [{foo: "bar"}, {foo: "asdf"}].to_json end private def do_test_error( context : HTTP::Server::Context, args : Hash(String, String) ) raise "some random error" end end end