Skip to content

Commit

Permalink
Refinement of API and documentation
Browse files Browse the repository at this point in the history
Resolves #75
Closes #74
Closes #52
  • Loading branch information
TimDiekmann committed Jun 29, 2019
1 parent b5d845e commit ced0add
Show file tree
Hide file tree
Showing 15 changed files with 367 additions and 481 deletions.
88 changes: 12 additions & 76 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,45 +69,13 @@ def before_request():
return login_manager.unauthorized()


if not Room.query.get("test_room"):
meetup = Task(name="Meetup", num_users=2, layout=Layout.from_json_file("meetup_task"))
admin_token = Token(room_name='test_room',
id='00000000-0000-0000-0000-000000000000' if settings.debug else None,
task=meetup,
permissions=Permissions(
user_query=True,
user_log_query=True,
user_log_event=True,
user_permissions_query=True,
user_permissions_update=True,
user_room_query=True,
user_room_join=True,
user_room_leave=True,
message_text=True,
message_image=True,
message_command=True,
message_broadcast=True,
room_query=True,
room_log_query=True,
room_create=True,
room_update=True,
room_close=True,
room_delete=True,
layout_query=True,
layout_create=True,
layout_update=True,
task_create=True,
task_query=True,
task_update=True,
token_generate=True,
token_query=True,
token_invalidate=True,
token_update=True,
))
db.session.add(admin_token)
db.session.add(Token(room_name='test_room',
id='00000000-0000-0000-0000-000000000001' if settings.debug else None,
task=meetup,
if not Room.query.get("admin_room"):
db.session.add(Room(name="admin_room",
label="Admin Room",
layout=Layout.from_json_file("default"),
static=True))
db.session.add(Token(room_name='admin_room',
id='00000000-0000-0000-0000-000000000000' if settings.debug else None,
permissions=Permissions(
user_query=True,
user_log_query=True,
Expand All @@ -124,54 +92,22 @@ def before_request():
room_query=True,
room_log_query=True,
room_create=True,
room_update=True,
room_close=True,
task_create=True,
task_query=True,
task_update=True,
room_delete=True,
layout_query=True,
layout_create=True,
layout_update=True,
token_generate=True,
token_query=True,
token_invalidate=True,
token_update=True,
)))
db.session.add(Token(room_name='test_room',
id='00000000-0000-0000-0000-000000000002' if settings.debug else None,
permissions=Permissions(
user_query=True,
user_log_query=True,
user_log_event=True,
user_permissions_query=True,
user_permissions_update=True,
user_room_query=True,
user_room_join=True,
user_room_leave=True,
message_text=True,
message_image=True,
message_command=True,
message_broadcast=True,
room_query=True,
room_log_query=True,
room_create=True,
room_close=True,
layout_create=True,
layout_update=True,
task_create=True,
task_query=True,
task_update=True,
layout_query=True,
layout_create=True,
layout_update=True,
token_generate=True,
token_query=True,
token_invalidate=True,
token_update=True,
)))
db.session.add(Room(name="test_room",
label="Test Room",
static=True,
layout=Layout.from_json_file("test_room")))
db.session.commit()
getLogger("slurk").info("generating test room and admin token...")
getLogger("slurk").info("generating admin room and token...")
print("admin token:")
print(Token.query.order_by(Token.date_created).first().id)
sys.stdout.flush()
21 changes: 18 additions & 3 deletions app/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,9 @@ def get_users():
@api.route('/user/<int:id>', methods=['GET'])
@auth.login_required
def get_user(id):
user = User.query.get(id)
if id != g.current_user.id and not g.current_permissions.user_query:
return make_response(jsonify({'error': 'insufficient rights'}), 403)
user = User.query.get(id) if id != g.current_user.id else g.current_user
if user:
return jsonify(user.as_dict())
else:
Expand Down Expand Up @@ -341,16 +343,29 @@ def get_rooms():
@api.route('/room/<string:name>', methods=['GET'])
@auth.login_required
def get_room(name):
if not g.current_permissions.room_query:
room = Room.query.get(name)
if room not in g.current_user.current_rooms and not g.current_permissions.room_query:
return make_response(jsonify({'error': 'insufficient rights'}), 403)

room = Room.query.get(name)
if room:
return jsonify(room.as_dict())
else:
return make_response(jsonify({'error': 'room not found'}), 404)


@api.route('/room/<string:name>/layout', methods=['GET'])
@auth.login_required
def get_room_layout(name):
room = Room.query.get(name)
if room not in g.current_user.current_rooms and (not g.current_permissions.room_query or not g.current_permissions.layout_query):
return make_response(jsonify({'error': 'insufficient rights'}), 403)

if room:
return jsonify(room.layout.as_dict())
else:
return make_response(jsonify({'error': 'room not found'}), 404)


@api.route('/room', methods=['POST'])
@auth.login_required
def post_rooms():
Expand Down
2 changes: 1 addition & 1 deletion app/api/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def _create_room(name, label, data):
if not layout:
return False, "layout does not exist"
else:
layout = None
layout = Layout.from_json_file("default")

room = Room(
name=name,
Expand Down
2 changes: 1 addition & 1 deletion app/models/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Room(db.Model):

name = db.Column(db.String, primary_key=True)
label = db.Column(db.String, nullable=False)
layout_id = db.Column(db.Integer, db.ForeignKey("Layout.id"))
layout_id = db.Column(db.Integer, db.ForeignKey("Layout.id"), nullable=False)
read_only = db.Column(db.Boolean, default=False, nullable=False)
show_users = db.Column(db.Boolean, default=True, nullable=False)
show_latency = db.Column(db.Boolean, default=True, nullable=False)
Expand Down
7 changes: 4 additions & 3 deletions app/static/js/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ $(document).ready(() => {

let room_request = $.get({ url: uri + "/room/" + data['room'], beforeSend: headers });
let user_request = $.get({ url: uri + "/user/" + data['user'], beforeSend: headers });
let layout = $.get({ url: uri + "/room/" + data['room'] + "/layout", beforeSend: headers });
let history = $.get({ url: uri + "/user/" + data['user'] + "/logs", beforeSend: headers });

let room = await room_request;
let layout = $.get({ url: uri + "/layout/" + room.layout, beforeSend: headers });
apply_room_properties(room);

let user = await user_request;
Expand All @@ -96,8 +96,9 @@ $(document).ready(() => {
updateUsers();
apply_layout(await layout);
history = await history;
console.log(history[room.name]);
print_history(history[room.name]);
if (typeof print_history !== "undefined") {
print_history(history[room.name]);
}

}

Expand Down
15 changes: 14 additions & 1 deletion app/static/layouts/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,21 @@
"subtitle": "Default Room",
"html": [
{
"id": "layout-title",
"layout-type": "h1",
"layout-content": "This is the default layout. Please provide a layout for this room!"
}
]
],
"css": {
"#layout-title": {
"align-content": "left",
"padding": "50px 20px 15px"
}
},
"scripts": {
"incoming-text": "display-text",
"incoming-image": "display-image",
"submit-message": "send-message",
"print-history": "plain-history"
}
}
7 changes: 4 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ Slurk - A Lightweight Chat Server for Dialogue Experiments and Data Collection
:numbered:

slurk_about
slurk_installation
slurk_gettingstarted
slurk_multibots
slurk_layouts
slurk_bots
slurk_api
slurk_tools
slurk_deployment
slurk_amt

..
Expand All @@ -28,7 +27,9 @@ Slurk - A Lightweight Chat Server for Dialogue Experiments and Data Collection
meetup_main
meetup_deployment

**Slurk** (think "slack for mechanical turk"...) is a lightweight and easily extensible chat server built especially for conducting multimodal dialogue experiments or data collections. See :ref:`slurk_about` for a description of the main concepts. Or jump right in with the :ref:`slurk_quickstart` (after the :ref:`slurk_installation`, of course)!
**Slurk** (think "slack for mechanical turk"...) is a lightweight and easily extensible chat server built especially
for conducting multimodal dialogue experiments or data collections. See :ref:`slurk_about` for a description of the
main concepts. Or jump right in with the :ref:`slurk_quickstart` (after the :ref:`slurk_installation`, of course)!

Slurk is built in Python, on top of flask_ and flask-socketio_.

Expand Down
20 changes: 0 additions & 20 deletions docs/meetup_main.rst

This file was deleted.

28 changes: 21 additions & 7 deletions docs/slurk_about.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,30 @@ Some basic concepts
~~~~~~~~~~~~~~~~~~~~

Bots
Bots are little client programms (written in python, and connecting to the slurk server via `socket.io`) that can enter rooms as well. They can both interact with human clients (e.g. through text messages or images) and communicate with the server by sending commands and responding to socket events. Unlike human users, bots can be in several rooms, being responsible for handling certain dialogue *tasks*. Defining an experimental or data collection setting typically includes writing one or multiple bots.
Bots are little client programms (written in python, and connecting to the slurk server via `socket.io`) that can
enter rooms as well. They can both interact with human clients (e.g. through text messages or images) and communicate
with the server by sending commands and responding to socket events. Unlike human users, bots can be in several rooms,
being responsible for handling certain dialogue *tasks*. Defining an experimental or data collection setting typically
includes writing one or multiple bots.

Rooms
Rooms are collections of users (humans and bots) that can talk to each other. Human users are always in exactly one room.
The **Waiting Room** is a special room, realised by the `pairup_bot`, where users wait until a pre-determined number of members is reached (lets say, 2), in which case all members are moved to a newly created task-specific room.
Rooms are collections of users (humans and bots) that can talk to each other. Human users are always in exactly one
room. The pairup example bot provides the **Waiting Room**, where users wait until a pre-determined number of members
is reached (lets say, 2), in which case all members are moved to a newly created task-specific room.

Technical concepts
**Events**: Slurk is driven by events emitted by the server. All events have a certain type and corresponding information, which can be processed by bots and client-side scripts. The events used in Slurk are defined in the file `events.py`.
**Events**: Slurk is driven by events emitted by the server. All events have a certain type and corresponding
information, which can be processed by bots and client-side scripts.

**Commands**: Bots can communicate with the server using predefined commands, causing the server to emit corresponding events. For instance, they can be used to send room messages, connect or disconnect clients or alter the attributes of HTML elements.
**Slash-Commands** are a special kind of commands: Registered in bot files, they can be used by human users to control the bot, which in turn communicates with the server. These commands are prefixed with a slash as, for instance, in `/new_image_public`. In this example (taken from the `multi_bot`), the command triggers a change of what is shown in the display area, visible to all clients in the current room.
**API**: Bots can communicate with the server using a :ref:`slurk_api`, causing the server to emit corresponding
events. For instance, they can be used to create rooms, connect or disconnect clients or generate tokens for logging
in.

**Tokens**: To provide control over who is allowed to log into the chat (since we're not interested in running a public server here), access is regulated via tokens. Tokens need to be created in advance and link a user (who is logging in with the token) to a specific task / room type.
**Commands** are a special kind of interaction with the server: Registered via the API, they can be used by human
users to control the bot, which in turn communicates with the server. Depending on the layout, commands are usually
prefixed with a slash as, for instance, in `/new_image_public`. In this example, the command triggers a change of what
is shown in the display area, visible to all clients in the current room.

**Tokens**: To provide control over who is allowed to log into the chat (since we're not interested in running a
public server here), access is regulated via tokens. Tokens need to be created in advance and link a user (who is
logging in with the token) to a specific task / room type.
14 changes: 7 additions & 7 deletions docs/slurk_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Room
``uri`` URI to query this room
========================= =================================================================================

* ``GET /api/v2/rooms/<string:name>``
* ``GET /api/v2/room/<string:name>``

Returns the room by name:

Expand All @@ -89,7 +89,7 @@ Room
``users`` List of users who were associated with this room at least once
========================= =================================================================================

* ``POST /api/v2/rooms/``
* ``POST /api/v2/room/``

Creates a new room:

Expand All @@ -103,7 +103,7 @@ Room
``static`` ``True`` if this room can be selected as login room
========================= =================================================================================

* ``PUT /api/v2/rooms/<string:name>``
* ``PUT /api/v2/room/<string:name>``

Updates the room by name:

Expand All @@ -116,7 +116,7 @@ Room
``static`` ``True`` if this room can be selected as login room
========================= =================================================================================

* ``DELETE /api/v2/rooms/<string:name>``
* ``DELETE /api/v2/room/<string:name>``

Deletes the room by name if no associations to the room exist. Otherwise an error is returned.

Expand All @@ -125,7 +125,7 @@ Logging
-------


* ``GET /api/v2/rooms/<string:name>/logs``
* ``GET /api/v2/room/<string:name>/logs``

Returns the log of the room by name:

Expand All @@ -138,7 +138,7 @@ Logging
``data`` Arbitrary data which is stored alongside the entry
========================= =================================================================================

* ``GET /api/v2/users/<int:id>/logs``
* ``GET /api/v2/user/<int:id>/logs``

Returns a mapping for log entries for rooms of the specified user:

Expand All @@ -151,7 +151,7 @@ Logging
``data`` Arbitrary data which is stored alongside the entry
========================= =================================================================================

* ``POST /api/v2/users/<int:id>/logs``
* ``POST /api/v2/user/<int:id>/logs``

Creates a new log entry for the specified user

Expand Down
Loading

0 comments on commit ced0add

Please sign in to comment.