| 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
 | # coding=utf-8
from weakref import ref
from flask import Blueprint
from rethinkdb.ast import Table
from pysite.constants import DEBUG_MODE
from pysite.database import RethinkDB
class DBMixin:
    """
    Mixin for classes that make use of RethinkDB. It can automatically create a table with the specified primary
    key using the attributes set at class-level.
    This class is intended to be mixed in alongside one of the other view classes. For example:
    >>> class MyView(APIView, DBMixin):
    ...     name = "my_view"  # Flask internal name for this route
    ...     path = "/my_view"  # Actual URL path to reach this route
    ...     table_name = "my_table"  # Name of the table to create
    ...     table_primary_key = "username"  # Primary key to set for this table
    This class will also work with Websockets:
    >>> class MyWebsocket(WS, DBMixin):
    ...     name = "my_websocket"
    ...     path = "/my_websocket"
    ...     table_name = "my_table"
    ...     table_primary_key = "username"
    You may omit `table_primary_key` and it will be defaulted to RethinkDB's default column - "id".
    """
    table_name = ""  # type: str
    table_primary_key = "id"  # type: str
    @classmethod
    def setup(cls: "DBMixin", manager: "pysite.route_manager.RouteManager", blueprint: Blueprint):
        """
        Set up the view by creating the table specified by the class attributes - this will also deal with multiple
        inheritance by calling `super().setup()` as appropriate.
        :param manager: Instance of the current RouteManager (used to get a handle for the database object)
        :param blueprint: Current Flask blueprint
        """
        if hasattr(super(), "setup"):
            super().setup(manager, blueprint)  # pragma: no cover
        if not cls.table_name:
            raise RuntimeError("Routes using DBViewMixin must define `table_name`")
        cls._db = ref(manager.db)
        if DEBUG_MODE:
            manager.db.create_table(cls.table_name, primary_key=cls.table_primary_key)
    @property
    def table(self) -> Table:
        return self.db.query(self.table_name)
    @property
    def db(self) -> RethinkDB:
        return self._db()
class OauthMixin:
    """
    Mixin for the classes that need access to a logged in user's information. This class should be used
    to grant route's access to user information, such as name, email, id, ect.
    There will almost never be a need for someone to inherit this, as BaseView does that for you.
    This class will add 3 properties to your route:
        * logged_in (bool): True if user is registered with the site, False else wise.
        * user_data (dict): A dict that looks like this:
        {
            "user_id": Their discord ID,
            "username": Their discord username (without discriminator),
            "discriminator": Their discord discriminator,
            "email": Their email, in which is connected to discord
        }
        user_data returns None, if the user isn't logged in.
        * oauth (OauthBackend): The instance of pysite.oauth.OauthBackend, connected to the RouteManager.
    """
    @classmethod
    def setup(cls: "OauthMixin", manager: "pysite.route_manager.RouteManager", blueprint: Blueprint):
        if hasattr(super(), "setup"):
            super().setup(manager, blueprint)  # pragma: no cover
        cls._oauth = ref(manager.oauth_backend)
    @property
    def logged_in(self) -> bool:
        return self.user_data is not None
    @property
    def user_data(self) -> dict:
        return self.oauth.user_data()
    @property
    def oauth(self):
        return self._oauth()
 |