prelimiary changes for automated documentation
parent
ecef425e8b
commit
52c47e7529
|
@ -0,0 +1,125 @@
|
||||||
|
"""
|
||||||
|
This is a small script that creates the endpoint doc page. It should be
|
||||||
|
evoked from the command line each time changes are made. It writes
|
||||||
|
to ./documentation/docs/api_overview.md
|
||||||
|
|
||||||
|
The code used in this script is the absolute minimum required to
|
||||||
|
get the job done; it can be considered a crude hack at best. I am
|
||||||
|
more interested in writing good documentation than making sure that
|
||||||
|
the script that shits it out is politcally correct ;)
|
||||||
|
"""
|
||||||
|
|
||||||
|
from server import API
|
||||||
|
import pydoc
|
||||||
|
|
||||||
|
body = """
|
||||||
|
# How to BBJ?
|
||||||
|
|
||||||
|
## Input
|
||||||
|
|
||||||
|
BBJ is interacted with entirely through POST requests, whose bodies are
|
||||||
|
json objects.
|
||||||
|
|
||||||
|
The endpoints, all listed below, can be contacted at the path /api/ relative
|
||||||
|
to the root of where BBJ is hosted. If bbj is hosted on a server on port 80
|
||||||
|
at the root:
|
||||||
|
|
||||||
|
`http://server.com/api/endpoint_here`
|
||||||
|
|
||||||
|
The body of your request contains all of it's argument fields, instead of
|
||||||
|
using URL parameters. As a demonstration, to call `thread_create`,
|
||||||
|
it requires two arguments: `title`, and `body`. We put those argument
|
||||||
|
names at the root of the json object, and their values are the info
|
||||||
|
passed into the API for that spot. Your input will look like this:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"title": "Hello world!!",
|
||||||
|
"body": "Hi! I am exploring this cool board thing!!"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And you will POST this body to `http://server.com:PORT/api/thread_create`.
|
||||||
|
|
||||||
|
A few endpoints do not require any arguments. These can still be POSTed to,
|
||||||
|
but the body may be completely empty or an empty json object. You can even
|
||||||
|
GET these if you so choose.
|
||||||
|
|
||||||
|
For all endpoints, argument keys that are not consumed by the endpoint are
|
||||||
|
ignored. Posting an object with a key/value pair of `"sandwich": True` will
|
||||||
|
not clog up any pipes :) In the same vein, endpoints who dont take arguments
|
||||||
|
don't care if you supply them anyway.
|
||||||
|
|
||||||
|
## Output
|
||||||
|
|
||||||
|
BBJ returns data in a consistently formatted json object. The base object
|
||||||
|
has three keys: `data`, `usermap`, and `error`. Visualizied:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
"error": false, // boolean false or error object
|
||||||
|
"data": null, // null or the requested data from endpoint.
|
||||||
|
"usermap": {} // potentially empty object, maps user_ids to user objects
|
||||||
|
}
|
||||||
|
|
||||||
|
// If "error" is true, it looks like this:
|
||||||
|
|
||||||
|
{
|
||||||
|
"error": {
|
||||||
|
"code": // an integer from 0 to 5,
|
||||||
|
"description": // a string describing the error in detail.
|
||||||
|
}
|
||||||
|
"data": null // ALWAYS null if error is not false
|
||||||
|
"usermap": {} // ALWAYS empty if error is not false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### data
|
||||||
|
|
||||||
|
`data` is what the endpoint actually returns. The type of contents vary
|
||||||
|
by endpoint and are documented below. If an endpoint says it returns a
|
||||||
|
boolean, it will look like `"data": True`. If it says it returns an array,
|
||||||
|
it will look like `"data": ["stuff", "goes", "here"]`
|
||||||
|
|
||||||
|
### usermap
|
||||||
|
|
||||||
|
The usermap is a json object mapping user_ids within `data` to full user
|
||||||
|
objects. BBJ handles users entirely by an ID system, meaning any references
|
||||||
|
to them inside of response data will not include vital information like their
|
||||||
|
username, or their profile information. Instead, we fetch those values from
|
||||||
|
this usermap object. All of it's root keys are user_id's and their values
|
||||||
|
are user objects. It should be noted that the anonymous user has it's own
|
||||||
|
ID and profile object as well.
|
||||||
|
|
||||||
|
### error
|
||||||
|
|
||||||
|
`error` is typically `false`. If it is __not__ false, then the request failed
|
||||||
|
and the json object that `error` contains should be inspected. (see the above
|
||||||
|
visualation) Errors follow a strict code system, making it easy for your client
|
||||||
|
to map these responses to native exception types or signals in your language of
|
||||||
|
choice. See [the full error page](errors.md) for details.
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
endpoints = [
|
||||||
|
ref for name, ref in API.__dict__.items()
|
||||||
|
if hasattr(ref, "exposed")
|
||||||
|
]
|
||||||
|
|
||||||
|
types = {
|
||||||
|
function.doctype: list() for function in endpoints
|
||||||
|
}
|
||||||
|
|
||||||
|
for function in endpoints:
|
||||||
|
types[function.doctype].append(function)
|
||||||
|
|
||||||
|
for doctype in sorted(types.keys()):
|
||||||
|
body += "# %s\n\n" % doctype
|
||||||
|
funcs = sorted(types[doctype], key=lambda _: _.__name__)
|
||||||
|
for f in funcs:
|
||||||
|
body += "## %s\n\n%s\n\n" % (f.__name__, pydoc.getdoc(f))
|
||||||
|
body += "\n\n--------\n\n"
|
||||||
|
|
||||||
|
with open("documentation/docs/api_overview.md", "w") as output:
|
||||||
|
output.write(body)
|
|
@ -0,0 +1,315 @@
|
||||||
|
|
||||||
|
# How to BBJ?
|
||||||
|
|
||||||
|
## Input
|
||||||
|
|
||||||
|
BBJ is interacted with entirely through POST requests, whose bodies are
|
||||||
|
json objects.
|
||||||
|
|
||||||
|
The endpoints, all listed below, can be contacted at the path /api/ relative
|
||||||
|
to the root of where BBJ is hosted. If bbj is hosted on a server on port 80
|
||||||
|
at the root:
|
||||||
|
|
||||||
|
`http://server.com/api/endpoint_here`
|
||||||
|
|
||||||
|
The body of your request contains all of it's argument fields, instead of
|
||||||
|
using URL parameters. As a demonstration, lets call `thread_create`.
|
||||||
|
It requires two arguments: `title`, and `body`. We put those argument
|
||||||
|
names at the root of the json object, and their values are the info
|
||||||
|
passed into the API for that spot. Your input will look like this:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"title": "Hello world!!",
|
||||||
|
"body": "Hi! I am exploring this cool board thing!!"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And you will POST this body to `http://server.com:PORT/api/thread_create`.
|
||||||
|
|
||||||
|
A few endpoints do not require any arguments. These can still be POSTed to,
|
||||||
|
but the body may be completely empty or an empty json object. You can even
|
||||||
|
GET these if you so choose.
|
||||||
|
|
||||||
|
For all endpoints, argument keys that are not consumed by the endpoint are
|
||||||
|
ignored. Posting an object with a key/value pair of `"sandwich": True` will
|
||||||
|
not clog up any pipes :) In the same vein, endpoints who dont take arguments
|
||||||
|
don't care if you supply them anyway.
|
||||||
|
|
||||||
|
## Output
|
||||||
|
|
||||||
|
BBJ returns data in a consistently formatted json object. The base object
|
||||||
|
has three keys: `data`, `usermap`, and `error`. Visualizied:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
"error": false, // boolean false or error object
|
||||||
|
"data": null, // null or the requested data from endpoint.
|
||||||
|
"usermap": {} // a potentially empty object mapping user_ids to their objects
|
||||||
|
}
|
||||||
|
|
||||||
|
// If "error" is true, it looks like this:
|
||||||
|
|
||||||
|
{
|
||||||
|
"error": {
|
||||||
|
"code": // an integer from 0 to 5,
|
||||||
|
"description": // a string describing the error in detail.
|
||||||
|
}
|
||||||
|
"data": null // ALWAYS null if error is not false
|
||||||
|
"usermap": {} // ALWAYS empty if error is not false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### data
|
||||||
|
|
||||||
|
`data` is what the endpoint actually returns. The type of contents vary
|
||||||
|
by endpoint and are documented below. If an endpoint says it returns a
|
||||||
|
boolean, it will look like `"data": True`. If it says it returns an array,
|
||||||
|
it will look like `"data": ["stuff", "goes", "here"]`
|
||||||
|
|
||||||
|
### usermap
|
||||||
|
|
||||||
|
The usermap is a json object mapping user_ids within `data` to full user
|
||||||
|
objects. BBJ handles users entirely by an ID system, meaning any references
|
||||||
|
to them inside of response data will not include vital information like their
|
||||||
|
username, or their profile information. Instead, we fetch those values from
|
||||||
|
this usermap object. All of it's root keys are user_id's and their values
|
||||||
|
are user objects. It should be noted that the anonymous user has it's own
|
||||||
|
ID and profile object as well.
|
||||||
|
|
||||||
|
### error
|
||||||
|
|
||||||
|
`error` is typically `null`. If it is __not__ null, then the request failed
|
||||||
|
and the json object that `error` contains should be inspected. (see the above
|
||||||
|
visualation) Errors follow a strict code system, making it easy for your client
|
||||||
|
to map these responses to native exception types or signals in your language of
|
||||||
|
choice. See [the full error page](errors.md) for details.
|
||||||
|
|
||||||
|
|
||||||
|
# Authorization
|
||||||
|
|
||||||
|
## check_auth
|
||||||
|
|
||||||
|
Takes the arguments `target_user` and `target_hash`, and
|
||||||
|
returns boolean true or false whether the hash is valid.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------
|
||||||
|
|
||||||
|
# Threads & Messages
|
||||||
|
|
||||||
|
## delete_post
|
||||||
|
|
||||||
|
Requires the arguments `thread_id` and `post_id`.
|
||||||
|
|
||||||
|
Delete a message from a thread. The same rules apply
|
||||||
|
here as `edit_post` and `edit_query`: the logged in user
|
||||||
|
must either be the one who posted the message within 24hrs,
|
||||||
|
or have admin rights. The same error descriptions and code
|
||||||
|
are returned on falilure. Boolean true is returned on
|
||||||
|
success.
|
||||||
|
|
||||||
|
If the post_id is 0, the whole thread is deleted.
|
||||||
|
|
||||||
|
## edit_post
|
||||||
|
|
||||||
|
Replace a post with a new body. Requires the arguments
|
||||||
|
`thread_id`, `post_id`, and `body`. This method verifies
|
||||||
|
that the user can edit a post before commiting the change,
|
||||||
|
otherwise an error object is returned whose description
|
||||||
|
should be shown to the user.
|
||||||
|
|
||||||
|
To perform sanity checks and retrieve the unformatted body
|
||||||
|
of a post without actually attempting to replace it, use
|
||||||
|
`edit_query` first.
|
||||||
|
|
||||||
|
Optionally you may also include the argument `send_raw` to
|
||||||
|
set the message's formatting flag. However, if this is the
|
||||||
|
only change you would like to make, you should use the
|
||||||
|
endpoint `set_post_raw` instead.
|
||||||
|
|
||||||
|
Returns the new message object.
|
||||||
|
|
||||||
|
## edit_query
|
||||||
|
|
||||||
|
Queries the database to ensure the user can edit a given
|
||||||
|
message. Requires the arguments `thread_id` and `post_id`
|
||||||
|
(does not require a new body)
|
||||||
|
|
||||||
|
Returns the original message object without any formatting
|
||||||
|
on success. Returns a descriptive code 4 otherwise.
|
||||||
|
|
||||||
|
## message_feed
|
||||||
|
|
||||||
|
Returns a special object representing all activity on the board since
|
||||||
|
the argument `time`, a unix/epoch timestamp.
|
||||||
|
|
||||||
|
{
|
||||||
|
"threads": {
|
||||||
|
"thread_id": {
|
||||||
|
...thread object
|
||||||
|
},
|
||||||
|
...more thread_id/object pairs
|
||||||
|
},
|
||||||
|
"messages": [...standard message object array sorted by date]
|
||||||
|
}
|
||||||
|
|
||||||
|
The message objects in "messages" are the same objects returned
|
||||||
|
in threads normally. They each have a thread_id parameter, and
|
||||||
|
you can access metadata for these threads by the "threads" object
|
||||||
|
which is also provided.
|
||||||
|
|
||||||
|
The "messages" array is already sorted by submission time, newest
|
||||||
|
first. The order in the threads object is undefined and you should
|
||||||
|
instead use their `last_mod` attribute if you intend to list them
|
||||||
|
out visually.
|
||||||
|
|
||||||
|
You may optionally provide a `format` argument: this is treated
|
||||||
|
the same way as the `thread_load` endpoint and you should refer
|
||||||
|
to its documentation for more info.
|
||||||
|
|
||||||
|
## set_post_raw
|
||||||
|
|
||||||
|
Requires the boolean argument of `value`, string argument
|
||||||
|
`thread_id`, and integer argument `post_id`. `value`, when false,
|
||||||
|
means that the message will be passed through message formatters
|
||||||
|
before being sent to clients. When `value` is true, this means
|
||||||
|
it will never go through formatters, all of its whitespace is
|
||||||
|
sent to clients verbatim and expressions are not processed.
|
||||||
|
|
||||||
|
The same rules for editing messages (see `edit_query`) apply here
|
||||||
|
and the same error objects are returned for violations.
|
||||||
|
|
||||||
|
You may optionally set this value as well when using `edit_post`,
|
||||||
|
but if this is the only change you want to make to the message,
|
||||||
|
using this endpoint instead is preferable.
|
||||||
|
|
||||||
|
## set_thread_pin
|
||||||
|
|
||||||
|
Requires the arguments `thread_id` and `value`. `value`
|
||||||
|
must be a boolean of what the pinned status should be.
|
||||||
|
This method requires that the caller is logged in and
|
||||||
|
has admin status on their account.
|
||||||
|
|
||||||
|
Returns the same boolean you supply as `value`
|
||||||
|
|
||||||
|
## thread_create
|
||||||
|
|
||||||
|
Creates a new thread and returns it. Requires the non-empty
|
||||||
|
string arguments `body` and `title`.
|
||||||
|
|
||||||
|
If the argument `send_raw` is specified and has a non-nil
|
||||||
|
value, the OP message will never recieve special formatting.
|
||||||
|
|
||||||
|
## thread_index
|
||||||
|
|
||||||
|
Return an array with all the threads, ordered by most recent activity.
|
||||||
|
Requires no arguments.
|
||||||
|
|
||||||
|
Optionally, you may supply the argument `include_op`, which, when
|
||||||
|
non-nil, will include a "messages" key with the object, whose sole
|
||||||
|
content is the original message (post_id 0).
|
||||||
|
|
||||||
|
## thread_load
|
||||||
|
|
||||||
|
Returns the thread object with all of its messages loaded.
|
||||||
|
Requires the argument `thread_id`. `format` may also be
|
||||||
|
specified as a formatter to run the messages through.
|
||||||
|
Currently only "sequential" is supported.
|
||||||
|
|
||||||
|
You may also supply the parameter `op_only`. When it's value
|
||||||
|
is non-nil, the messages array will only include post_id 0 (the first)
|
||||||
|
|
||||||
|
## thread_reply
|
||||||
|
|
||||||
|
Creates a new reply for the given thread and returns it.
|
||||||
|
Requires the string arguments `thread_id` and `body`
|
||||||
|
|
||||||
|
If the argument `send_raw` is specified and has a non-nil
|
||||||
|
value, the message will never recieve special formatting.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------
|
||||||
|
|
||||||
|
# Tools
|
||||||
|
|
||||||
|
## db_validate
|
||||||
|
|
||||||
|
Requires the arguments `key` and `value`. Returns an object
|
||||||
|
with information about the database sanity criteria for
|
||||||
|
key. This can be used to validate user input in the client
|
||||||
|
before trying to send it to the server.
|
||||||
|
|
||||||
|
If the argument `error` is supplied with a non-nil value,
|
||||||
|
the server will return a standard error object on failure
|
||||||
|
instead of the special object described below.
|
||||||
|
|
||||||
|
The returned object has two keys:
|
||||||
|
|
||||||
|
{
|
||||||
|
"bool": true/false,
|
||||||
|
"description": null/"why this value is bad"
|
||||||
|
}
|
||||||
|
|
||||||
|
If bool == false, description is a string describing the
|
||||||
|
problem. If bool == true, description is null and the
|
||||||
|
provided value is safe to use.
|
||||||
|
|
||||||
|
## format_message
|
||||||
|
|
||||||
|
Requires the arguments `body` and `format`. Applies
|
||||||
|
`format` to `body` and returns the new object. See
|
||||||
|
`thread_load` for supported specifications for `format`.
|
||||||
|
|
||||||
|
## user_map
|
||||||
|
|
||||||
|
Returns an array with all registered user_ids, with the usermap
|
||||||
|
object populated by their full objects.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------
|
||||||
|
|
||||||
|
# Users
|
||||||
|
|
||||||
|
## get_me
|
||||||
|
|
||||||
|
Requires no arguments. Returns your internal user object,
|
||||||
|
including your authorization hash.
|
||||||
|
|
||||||
|
## is_admin
|
||||||
|
|
||||||
|
Requires the argument `target_user`. Returns a boolean
|
||||||
|
of whether that user is an admin.
|
||||||
|
|
||||||
|
## user_get
|
||||||
|
|
||||||
|
Retreive an external user object for the given `user`.
|
||||||
|
Can be a user_id or user_name.
|
||||||
|
|
||||||
|
## user_is_registered
|
||||||
|
|
||||||
|
Takes the argument `target_user` and returns true or false
|
||||||
|
whether they are in the system or not.
|
||||||
|
|
||||||
|
## user_register
|
||||||
|
|
||||||
|
Register a new user into the system and return the new object.
|
||||||
|
Requires the string arguments `user_name` and `auth_hash`.
|
||||||
|
Do not send User/Auth headers with this method.
|
||||||
|
|
||||||
|
## user_update
|
||||||
|
|
||||||
|
Receives new parameters and assigns them to the user_object
|
||||||
|
in the database. The following new parameters can be supplied:
|
||||||
|
`user_name`, `auth_hash`, `quip`, `bio`, and `color`. Any number
|
||||||
|
of them may be supplied.
|
||||||
|
|
||||||
|
The newly updated user object is returned on success.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
# Welcome to MkDocs
|
# Bulletin Butter & Jelly
|
||||||
|
## A simple community textboard
|
||||||
|
### BBJ is trivial collection of python scripts and database queries that miraculously shit out a fully functional client-server textboard.
|
||||||
|
|
||||||
For full documentation visit [mkdocs.org](http://mkdocs.org).
|
See also: the [GitHub repository](https://github.com/desvox/bbj).
|
||||||
|
|
||||||
## Commands
|
BBJ is heavily inspired by image boards like 4chan, but it offers a simple
|
||||||
|
account system to allow users to identify themselves and set profile
|
||||||
|
attributes like a more traditional forum. Registration is optional and there
|
||||||
|
are only minimal restrictions on anonymous participation.
|
||||||
|
|
||||||
* `mkdocs new [dir-name]` - Create a new project.
|
![screenshot](https://tilde.town/~desvox/bbj/screenshot.png)
|
||||||
* `mkdocs serve` - Start the live-reloading docs server.
|
|
||||||
* `mkdocs build` - Build the documentation site.
|
|
||||||
* `mkdocs help` - Print this help message.
|
|
||||||
|
|
||||||
## Project layout
|
Being a command-line-oriented text board, BBJ has no avatars or file sharing
|
||||||
|
capabilties, so its easier to administrate and can't be used to distribute illegal
|
||||||
|
content like imageboards. It has very few dependancies and is easy to set up.
|
||||||
|
|
||||||
mkdocs.yml # The configuration file.
|
The API is simple and doesn't use require complex authorization schemes or session management.
|
||||||
docs/
|
It is fully documented on this site.
|
||||||
index.md # The documentation homepage.
|
|
||||||
... # Other markdown pages, images and other files.
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
site_name: My Docs
|
site_name: BBJ API Documentation
|
||||||
|
|
45
server.py
45
server.py
|
@ -20,6 +20,7 @@ app_config = {
|
||||||
"debug": False
|
"debug": False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open("config.json") as _conf:
|
with open("config.json") as _conf:
|
||||||
app_config.update(json.load(_conf))
|
app_config.update(json.load(_conf))
|
||||||
|
@ -191,6 +192,11 @@ class API(object):
|
||||||
validate(args, ["user_name", "auth_hash"])
|
validate(args, ["user_name", "auth_hash"])
|
||||||
return db.user_register(
|
return db.user_register(
|
||||||
database, args["user_name"], args["auth_hash"])
|
database, args["user_name"], args["auth_hash"])
|
||||||
|
user_register.doctype = "Users"
|
||||||
|
user_register.args = [
|
||||||
|
("user_name", "string: the desired display name"),
|
||||||
|
("auth_hash", "string: a sha256 hash of a password")
|
||||||
|
]
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def user_update(self, args, database, user, **kwargs):
|
def user_update(self, args, database, user, **kwargs):
|
||||||
|
@ -205,6 +211,15 @@ class API(object):
|
||||||
no_anon_hook(user, "Anons cannot modify their account.")
|
no_anon_hook(user, "Anons cannot modify their account.")
|
||||||
validate(args, []) # just make sure its not empty
|
validate(args, []) # just make sure its not empty
|
||||||
return db.user_update(database, user, args)
|
return db.user_update(database, user, args)
|
||||||
|
user_update.doctype = "Users"
|
||||||
|
user_update.args = [
|
||||||
|
("Any of the following may be submitted:", ""),
|
||||||
|
("user_name", "string: a desired display name"),
|
||||||
|
("auth_hash", "string: sha256 hash for a new password"),
|
||||||
|
("quip", "string: a short string that can be used as a signature"),
|
||||||
|
("bio", "string: a user biography for their profile"),
|
||||||
|
("color", "integer: 0-6, a display color for the user")
|
||||||
|
]
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def get_me(self, args, database, user, **kwargs):
|
def get_me(self, args, database, user, **kwargs):
|
||||||
|
@ -213,6 +228,8 @@ class API(object):
|
||||||
including your authorization hash.
|
including your authorization hash.
|
||||||
"""
|
"""
|
||||||
return user
|
return user
|
||||||
|
get_me.doctype = "Users"
|
||||||
|
get_me.args = [("", "")]
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def user_map(self, args, database, user, **kwargs):
|
def user_map(self, args, database, user, **kwargs):
|
||||||
|
@ -232,16 +249,22 @@ class API(object):
|
||||||
for user in users
|
for user in users
|
||||||
}
|
}
|
||||||
return list(users)
|
return list(users)
|
||||||
|
user_map.doctype = "Tools"
|
||||||
|
user_map.args = [("", "")]
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def user_get(self, args, database, user, **kwargs):
|
def user_get(self, args, database, user, **kwargs):
|
||||||
"""
|
"""
|
||||||
Retreive an external user object for the given `user`.
|
Retreive an external user object for the given `target_user`.
|
||||||
Can be a user_id or user_name.
|
Can be a user_id or user_name.
|
||||||
"""
|
"""
|
||||||
validate(args, ["user"])
|
validate(args, ["target_user"])
|
||||||
return db.user_resolve(
|
return db.user_resolve(
|
||||||
database, args["user"], return_false=False, externalize=True)
|
database, args["target_user"], return_false=False, externalize=True)
|
||||||
|
user_get.doctype = "Users"
|
||||||
|
user_get.args = [
|
||||||
|
("user", "string: either a user_name or a user_id")
|
||||||
|
]
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def user_is_registered(self, args, database, user, **kwargs):
|
def user_is_registered(self, args, database, user, **kwargs):
|
||||||
|
@ -251,6 +274,8 @@ class API(object):
|
||||||
"""
|
"""
|
||||||
validate(args, ["target_user"])
|
validate(args, ["target_user"])
|
||||||
return bool(db.user_resolve(database, args["target_user"]))
|
return bool(db.user_resolve(database, args["target_user"]))
|
||||||
|
user_is_registered.doctype = "Users"
|
||||||
|
# user_is_registered.args =
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def check_auth(self, args, database, user, **kwargs):
|
def check_auth(self, args, database, user, **kwargs):
|
||||||
|
@ -262,6 +287,7 @@ class API(object):
|
||||||
user = db.user_resolve(
|
user = db.user_resolve(
|
||||||
database, args["target_user"], return_false=False)
|
database, args["target_user"], return_false=False)
|
||||||
return args["target_hash"].lower() == user["auth_hash"].lower()
|
return args["target_hash"].lower() == user["auth_hash"].lower()
|
||||||
|
check_auth.doctype = "Authorization"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def thread_index(self, args, database, user, **kwargs):
|
def thread_index(self, args, database, user, **kwargs):
|
||||||
|
@ -277,6 +303,7 @@ class API(object):
|
||||||
threads = db.thread_index(database, include_op=op)
|
threads = db.thread_index(database, include_op=op)
|
||||||
cherrypy.thread_data.usermap = create_usermap(database, threads, True)
|
cherrypy.thread_data.usermap = create_usermap(database, threads, True)
|
||||||
return threads
|
return threads
|
||||||
|
thread_index.doctype = "Threads & Messages"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def message_feed(self, args, database, user, **kwargs):
|
def message_feed(self, args, database, user, **kwargs):
|
||||||
|
@ -317,6 +344,7 @@ class API(object):
|
||||||
|
|
||||||
do_formatting(args.get("format"), feed["messages"])
|
do_formatting(args.get("format"), feed["messages"])
|
||||||
return feed
|
return feed
|
||||||
|
message_feed.doctype = "Threads & Messages"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def thread_create(self, args, database, user, **kwargs):
|
def thread_create(self, args, database, user, **kwargs):
|
||||||
|
@ -335,6 +363,7 @@ class API(object):
|
||||||
cherrypy.thread_data.usermap = \
|
cherrypy.thread_data.usermap = \
|
||||||
create_usermap(database, thread["messages"])
|
create_usermap(database, thread["messages"])
|
||||||
return thread
|
return thread
|
||||||
|
thread_create.doctype = "Threads & Messages"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def thread_reply(self, args, database, user, **kwargs):
|
def thread_reply(self, args, database, user, **kwargs):
|
||||||
|
@ -350,6 +379,7 @@ class API(object):
|
||||||
return db.thread_reply(
|
return db.thread_reply(
|
||||||
database, user["user_id"], args["thread_id"],
|
database, user["user_id"], args["thread_id"],
|
||||||
args["body"], args.get("send_raw"))
|
args["body"], args.get("send_raw"))
|
||||||
|
thread_reply.doctype = "Threads & Messages"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def thread_load(self, args, database, user, **kwargs):
|
def thread_load(self, args, database, user, **kwargs):
|
||||||
|
@ -369,6 +399,7 @@ class API(object):
|
||||||
create_usermap(database, thread["messages"])
|
create_usermap(database, thread["messages"])
|
||||||
do_formatting(args.get("format"), thread["messages"])
|
do_formatting(args.get("format"), thread["messages"])
|
||||||
return thread
|
return thread
|
||||||
|
thread_load.doctype = "Threads & Messages"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def edit_post(self, args, database, user, **kwargs):
|
def edit_post(self, args, database, user, **kwargs):
|
||||||
|
@ -395,6 +426,7 @@ class API(object):
|
||||||
return db.message_edit_commit(
|
return db.message_edit_commit(
|
||||||
database, user["user_id"], args["thread_id"],
|
database, user["user_id"], args["thread_id"],
|
||||||
args["post_id"], args["body"], args.get("send_raw"))
|
args["post_id"], args["body"], args.get("send_raw"))
|
||||||
|
edit_post.doctype = "Threads & Messages"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def delete_post(self, args, database, user, **kwargs):
|
def delete_post(self, args, database, user, **kwargs):
|
||||||
|
@ -414,6 +446,7 @@ class API(object):
|
||||||
validate(args, ["thread_id", "post_id"])
|
validate(args, ["thread_id", "post_id"])
|
||||||
return db.message_delete(
|
return db.message_delete(
|
||||||
database, user["user_id"], args["thread_id"], args["post_id"])
|
database, user["user_id"], args["thread_id"], args["post_id"])
|
||||||
|
delete_post.doctype = "Threads & Messages"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def set_post_raw(self, args, database, user, **kwargs):
|
def set_post_raw(self, args, database, user, **kwargs):
|
||||||
|
@ -438,6 +471,7 @@ class API(object):
|
||||||
database, user["user_id"],
|
database, user["user_id"],
|
||||||
args["thread_id"], args["post_id"],
|
args["thread_id"], args["post_id"],
|
||||||
None, args["value"], None)
|
None, args["value"], None)
|
||||||
|
set_post_raw.doctype = "Threads & Messages"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def is_admin(self, args, database, user, **kwargs):
|
def is_admin(self, args, database, user, **kwargs):
|
||||||
|
@ -449,6 +483,7 @@ class API(object):
|
||||||
user = db.user_resolve(
|
user = db.user_resolve(
|
||||||
database, args["target_user"], return_false=False)
|
database, args["target_user"], return_false=False)
|
||||||
return user["is_admin"]
|
return user["is_admin"]
|
||||||
|
is_admin.doctype = "Users"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def edit_query(self, args, database, user, **kwargs):
|
def edit_query(self, args, database, user, **kwargs):
|
||||||
|
@ -464,6 +499,7 @@ class API(object):
|
||||||
validate(args, ["thread_id", "post_id"])
|
validate(args, ["thread_id", "post_id"])
|
||||||
return db.message_edit_query(
|
return db.message_edit_query(
|
||||||
database, user["user_id"], args["thread_id"], args["post_id"])
|
database, user["user_id"], args["thread_id"], args["post_id"])
|
||||||
|
edit_query.doctype = "Threads & Messages"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def format_message(self, args, database, user, **kwargs):
|
def format_message(self, args, database, user, **kwargs):
|
||||||
|
@ -476,6 +512,7 @@ class API(object):
|
||||||
message = [{"body": args["body"]}]
|
message = [{"body": args["body"]}]
|
||||||
do_formatting(args["format"], message)
|
do_formatting(args["format"], message)
|
||||||
return message[0]["body"]
|
return message[0]["body"]
|
||||||
|
format_message.doctype = "Tools"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def set_thread_pin(self, args, database, user, **kwargs):
|
def set_thread_pin(self, args, database, user, **kwargs):
|
||||||
|
@ -491,6 +528,7 @@ class API(object):
|
||||||
if not user["is_admin"]:
|
if not user["is_admin"]:
|
||||||
raise BBJUserError("Only admins can set thread pins")
|
raise BBJUserError("Only admins can set thread pins")
|
||||||
return db.set_thread_pin(database, args["thread_id"], args["value"])
|
return db.set_thread_pin(database, args["thread_id"], args["value"])
|
||||||
|
set_thread_pin.doctype = "Threads & Messages"
|
||||||
|
|
||||||
@api_method
|
@api_method
|
||||||
def db_validate(self, args, database, user, **kwargs):
|
def db_validate(self, args, database, user, **kwargs):
|
||||||
|
@ -527,6 +565,7 @@ class API(object):
|
||||||
response["bool"] = False
|
response["bool"] = False
|
||||||
response["description"] = e.description
|
response["description"] = e.description
|
||||||
return response
|
return response
|
||||||
|
db_validate.doctype = "Tools"
|
||||||
|
|
||||||
|
|
||||||
def api_http_error(status, message, traceback, version):
|
def api_http_error(status, message, traceback, version):
|
||||||
|
|
Loading…
Reference in New Issue