diff options
Diffstat (limited to 'src/guff/api/methods.cr')
-rw-r--r-- | src/guff/api/methods.cr | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/src/guff/api/methods.cr b/src/guff/api/methods.cr new file mode 100644 index 0000000..758cca9 --- /dev/null +++ b/src/guff/api/methods.cr @@ -0,0 +1,366 @@ +require "json" + +module Guff + module API + module Methods + METHODS = { + "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, + type: :json, + required: false, + default: "", + }, + + "sort": { + text: "Sort order of results", + type: :sort, + required: false, + default: "date,desc", + }, + + "cols": { + text: "Column list", + type: :text, + required: false, + }, + }, + }, + + "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, + type: :json, + required: false, + default: "", + }, + }, + }, + + "update_post": { + text: "Update existing post.", + args: { + "name": { + text: "Post title.", + type: :text, + required: false, + }, + + "slug": { + text: "Post slug.", + type: :slug, + required: false, + }, + + "body": { + text: "Post body.", + type: :text, + required: false, + }, + + "tags": { + text: "Post tags.", + type: :json, + required: false, + }, + + "posted": { + text: "Is this post posted?", + type: :bool, + required: false, + }, + }, + }, + + "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, + type: :json, + 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, + type: :json, + required: false, + default: "", + }, + }, + }, + }, + + "site": { + "add_site": { + text: "Create a new site", + + args: { + "name": { + text: "Name of this site", + type: :text, + required: true, + }, + + "default": { + text: "Is this the default site?", + type: :bool, + required: false, + default: "f", + }, + + "domains": { + text: "Array of domain matches.", + type: :domain_list, + required: true, + }, + }, + }, + + "remove_sites": { + text: "Remove one or more existing sites", + + args: { + "site_ids": { + text: "IDs of sites to remove", + type: :int_list, + required: true, + }, + }, + }, + + "set_default": { + text: "Set new default site", + + args: { + "site_id": { + text: "ID of new default site", + type: :int, + required: true, + }, + }, + }, + + "set_domains": { + text: "Set domains for given site", + + args: { + "site_id": { + text: "ID of site", + type: :int, + required: true, + }, + + "domains": { + text: "Domains for this site.", + type: :domain_list, + required: true, + }, + }, + }, + }, + + "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+)*$/, + sort: /^[a-z0-9_]+,(?:asc|desc)$/, + + # FIXME: lock these down more + json: /.*/, + path: /^[^\/].*[^\/]$/, + } + + private def get_method_args( + params : HTTP::Params, + namespace : String, + method : String + ) + return {} of String => String unless ( + METHODS[namespace]? && + METHODS[namespace][method] && + METHODS[namespace][method][:args]? + ) + + # get method args + args = METHODS[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) + # elsif arg_data.has_key?(:default) + elsif arg_data[:default]? + params.fetch(arg_name, arg_data[:default] as String) + else + nil + end + + if val + # 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 + end + + # return result + r + end + end + end + end +end |