-
Notifications
You must be signed in to change notification settings - Fork 3
/
user.py
256 lines (210 loc) · 8.62 KB
/
user.py
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
from datetime import datetime
from typing import TYPE_CHECKING, Dict, List
import aiohttp
from .helpers.apraw_base import aPRAWBase
from .helpers.generator import ListingGenerator
from .helpers.streamable import Streamable
from .reddit.redditor import Redditor
from ..endpoints import API_PATH
if TYPE_CHECKING:
from ..reddit import Reddit
class User:
"""
A class to store the authentication credentials and handle ratelimit information.
Members
-------
reddit: Reddit
The :class:`~apraw.Reddit` instance with which requests are made.
username: str
The username given to the Reddit instance or obtained via ``praw.ini``.
password: str
The password given to the Reddit instance or obtained via ``praw.ini``.
client_id: str
The client ID given to the Reddit instance or obtained via ``praw.ini``.
client_secret: str
The client secret given to the Reddit instance or obtained via ``praw.ini``.
user_agent: str
The user agent given to the Reddit instance or defaulted to aPRAW's version.
password_grant: str
The data to be used when making a token request with the 'password' ``grant_type``.
access_data: Dict
A dictionary containing the access token and user agent for request headers.
token_expires: datetime
The datetime on which the previously retrieved token will expire. Defaults to the past to obtain a token
immediately the first time.
ratelimit_remaining: int
The number of requests remaining in the current ratelimit window.
ratelimit_used: int
The number of requests previously used in the current ratelimit window.
ratelimit_reset: datetime
The datetime on which the ratelimit window will be reset.
"""
def __init__(self, reddit: 'Reddit', username: str, password: str, client_id: str,
client_secret: str, user_agent: str):
"""
Create an instance of the authenticated user.
Parameters
----------
reddit: Reddit
The :class:`~apraw.Reddit` instance with which requests are made.
username: str
The username given to the Reddit instance or obtained via ``praw.ini``.
password: str
The password given to the Reddit instance or obtained via ``praw.ini``.
client_id: str
The client ID given to the Reddit instance or obtained via ``praw.ini``.
client_secret: str
The client secret given to the Reddit instance or obtained via ``praw.ini``.
user_agent: str
The user agent given to the Reddit instance or defaulted to aPRAW's version.
Raises
------
Exception
If the login credentials given are empty or incomplete.
"""
self.reddit = reddit
self.username = username
self.password = password
self.client_id = client_id
self.client_secret = client_secret
self.user_agent = user_agent
if self.username == "" or self.password == "" or self.client_id == "" or self.client_secret == "":
raise Exception(
"No login information given or login information incomplete.")
self.password_grant = "grant_type=password&username={}&password={}".format(
self.username, self.password)
self._auth_session = None
self._client_session = None
self._auth_user = None
self.access_data = None
self.token_expires = datetime.now()
self.ratelimit_remaining = 0
self.ratelimit_used = 0
self.ratelimit_reset = datetime.now()
async def auth_session(self) -> aiohttp.ClientSession:
"""
Retrieve an ``aiohttp.ClientSesssion`` with which the authentication token can be obtained.
Returns
-------
session: aiohttp.ClientSession
The session using the BasicAuth setup to obtain tokens with.
"""
if self._auth_session is None:
auth = aiohttp.BasicAuth(
login=self.client_id,
password=self.client_secret)
self._auth_session = aiohttp.ClientSession(auth=auth)
return self._auth_session
async def client_session(self) -> aiohttp.ClientSession:
"""
Retrieve the ``aiohttp.ClientSesssion`` with which regular requests are made.
Returns
-------
session: aiohttp.ClientSession
The session with which requests should be made.
"""
if self._client_session is None:
self._client_session = aiohttp.ClientSession()
return self._client_session
async def close(self):
await self.auth_session.close()
await self.client_session.close()
async def me(self) -> 'AuthenticatedUser':
"""
Retrieve an instance of :class:`~apraw.models.AuthenticatedUser` for the logged-in user.
Returns
-------
user: AuthenticatedUser
The logged-in user.
"""
if not self._auth_user:
data = await self.reddit.get_request(API_PATH["me"])
self._auth_user = AuthenticatedUser(self.reddit, data)
return self._auth_user
class AuthenticatedUser(Redditor):
"""
The model representing the logged-in user.
This model inherits from :class:`~apraw.models.Redditor` and thus all its attributes and features. View those docs
for further information.
Members
-------
reddit: Reddit
The :class:`~apraw.Reddit` instance with which requests are made.
data: Dict
The data obtained from the /about endpoint.
"""
def __init__(self, reddit: 'Reddit', data: Dict):
"""
Create an instance of AuthenticatedUser.
Parameters
----------
reddit : Reddit
The :class:`~apraw.Reddit` instance with which requests are made.
data : Dict
The data obtained from the /about endpoint.
"""
super().__init__(reddit, data)
self._karma = list()
async def karma(self) -> List['Karma']:
"""
Retrieve the karma breakdown for the logged-in user.
Returns
-------
karma: List[Karma]
The parsed ``KarmaList`` for the logged-in user.
"""
if not self._karma:
resp = await self.reddit.get_request(API_PATH["me_karma"])
self._karma = [Karma(self.reddit, d) for d in resp["data"]]
return self._karma
@Streamable.streamable
async def inbox(self, *args, **kwargs) -> ListingGenerator:
return ListingGenerator(self.reddit, API_PATH["message_inbox"], *args, **kwargs)
@Streamable.streamable
async def sent(self, *args, **kwargs) -> ListingGenerator:
return ListingGenerator(self.reddit, API_PATH["message_sent"], *args, **kwargs)
@Streamable.streamable
async def unread(self, *args, **kwargs) -> ListingGenerator:
return ListingGenerator(self.reddit, API_PATH["message_unread"], *args, **kwargs)
class Karma(aPRAWBase):
"""
A model representing subreddit karma.
Members
-------
reddit: Reddit
The :class:`~apraw.Reddit` instance with which requests are made.
data: Dict
The data obtained from the /about endpoint.
**Typical Attributes**
This table describes attributes that typically belong to objects of this
class. Attributes are dynamically provided by the :class:`~apraw.models.aPRAWBase` class
and may vary depending on the status of the response and expected objects.
================= ===================================================
Attribute Description
================= ===================================================
``sr`` The name of the subreddit the karma was obtained on
``comment_karma`` The amount of karma obtained on the subreddit.
``link_karma`` The amount of link karma obtained on the subreddit.
================= ===================================================
"""
def __init__(self, reddit: 'Reddit', data: Dict):
"""
Create an instance of Karma
Parameters
----------
reddit : Reddit
An instance of :class:`~apraw.Reddit`with which requests are made.
data : Dict
The data obtained from the /about endpoint.
"""
super().__init__(reddit, data)
self._subreddit = None
async def subreddit(self):
"""
Retrieve the subreddit on which the karma was obtained.
Returns
-------
subreddit: Subreddit
The subreddit on which the karma was obtained.
"""
return await self._reddit.subreddit(self.sr)