aboutsummaryrefslogtreecommitdiffstats
path: root/pysite/views/api/bot/bigbrother.py
blob: 89697811abbc2c861a7d5fa434f7b33a0b0cdc1d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import json

from flask import jsonify
from schema import And, Optional, Schema

from pysite.base_route import APIView
from pysite.constants import ValidationTypes
from pysite.decorators import api_key, api_params
from pysite.mixins import DBMixin


GET_SCHEMA = Schema({
    # This is passed as a GET parameter, so it has to be a string
    Optional('user_id'): And(str, str.isnumeric, error="`user_id` must be a numeric string")
})

POST_SCHEMA = Schema({
    'user_id': And(str, str.isnumeric, error="`user_id` must be a numeric string"),
    'channel_id': And(str, str.isnumeric, error="`channel_id` must be a numeric string")
})

DELETE_SCHEMA = Schema({
    'user_id': And(str, str.isnumeric, error="`user_id` must be a numeric string")
})


NOT_A_NUMBER_JSON = json.dumps({
    'error_message': "The given `user_id` parameter is not a valid number"
})
NOT_FOUND_JSON = json.dumps({
    'error_message': "No entry for the requested user ID could be found."
})


class BigBrotherView(APIView, DBMixin):
    path = '/bot/bigbrother'
    name = 'bot.bigbrother'
    table_name = 'watched_users'

    @api_key
    @api_params(schema=GET_SCHEMA, validation_type=ValidationTypes.params)
    def get(self, params):
        """
        Without query parameters, returns a list of all monitored users.
        A parameter `user_id` can be specified to return a single entry,
        or a dictionary with the string field 'error_message' that tells why it failed.

        If the returned status is 200, has got either a list of entries
        or a single object (see above).

        If the returned status is 400, the `user_id` parameter was incorrectly specified.
        If the returned status is 404, the given `user_id` could not be found.
        See the 'error_message' field in the JSON response for more information.

        The user ID must be provided as query parameter.
        API key must be provided as header.
        """

        user_id = params.get('user_id')
        if user_id is not None:
            data = self.db.get(self.table_name, user_id)
            if data is None:
                return NOT_FOUND_JSON, 404
            return jsonify(data)

        else:
            data = self.db.pluck(self.table_name, ('user_id', 'channel_id')) or []
            return jsonify(data)

    @api_key
    @api_params(schema=POST_SCHEMA, validation_type=ValidationTypes.json)
    def post(self, data):
        """
        Adds a new entry to the database.
        Entries take the following form:
        {
            "user_id": ...,  # The user ID of the user being monitored, as a string.
            "channel_id": ...  # The channel ID that the user's messages will be relayed to, as a string.
        }

        If an entry for the given `user_id` already exists, it will be updated with the new channel ID.

        Returns 204 (ok, empty response) on success.

        Data must be provided as JSON.
        API key must be provided as header.
        """

        self.db.insert(
            self.table_name,
            {
                'user_id': data['user_id'],
                'channel_id': data['channel_id']
            },
            conflict='update'
        )

        return '', 204

    @api_key
    @api_params(schema=DELETE_SCHEMA, validation_type=ValidationTypes.params)
    def delete(self, params):
        """
        Removes an entry for the given `user_id`.

        Returns 204 (ok, empty response) on success.
        Returns 400 if the given `user_id` is invalid.

        The user ID must be provided as query parameter.
        API key must be provided as header.
        """

        self.db.delete(
            self.table_name,
            params['user_id']
        )

        return '', 204