4 """This module abstracts connection to pod.
13 from diaspy
import errors
20 """Object representing connection with the pod.
22 _token_regex
= re
.compile(r
'content="(.*?)"\s+name="csrf-token')
24 def __init__(self
, pod
, username
, password
, schema
='https'):
26 :param pod: The complete url of the diaspora pod to use.
28 :param username: The username used to log in.
30 :param password: The password used to log in.
34 self
._session
= requests
.Session()
35 self
._login
_data
= {'user[remember_me]': 1, 'utf8': '✓'}
38 self
._diaspora
_session
= ''
39 self
._cookies
= self
._fetchcookies
()
41 #self._setlogin(username, password)
42 self
._login
_data
= {'user[username]': username
,
43 'user[password]': password
,
44 'authenticity_token': self
._fetchtoken
()}
46 except requests
.exceptions
.MissingSchema
:
47 self
.pod
= '{0}://{1}'.format(schema
, self
.pod
)
48 warnings
.warn('schema was missing')
54 self
._login
_data
= {'user[username]': username
,
55 'user[password]': password
,
56 'authenticity_token': self
._fetchtoken
()}
57 except Exception as e
:
58 raise errors
.LoginError('cannot create login data (caused by: {0})'.format(e
))
60 def _fetchcookies(self
):
61 request
= self
.get('stream')
62 return request
.cookies
65 """Returns token string.
66 It will be easier to change backend if programs will just use:
68 instead of calling a specified method.
70 return self
._fetchtoken
()
72 def get(self
, string
, headers
={}, params
={}, direct
=False, **kwargs
):
73 """This method gets data from session.
74 Performs additional checks if needed.
77 To obtain 'foo' from pod one should call `get('foo')`.
79 :param string: URL to get without the pod's URL and slash eg. 'stream'.
81 :param direct: if passed as True it will not be expanded
84 if not direct
: url
= '{0}/{1}'.format(self
.pod
, string
)
86 return self
._session
.get(url
, params
=params
, headers
=headers
, **kwargs
)
88 def post(self
, string
, data
, headers
={}, params
={}, **kwargs
):
89 """This method posts data to session.
90 Performs additional checks if needed.
93 To post to 'foo' one should call `post('foo', data={})`.
95 :param string: URL to post without the pod's URL and slash eg. 'status_messages'.
97 :param data: Data to post.
98 :param headers: Headers (optional).
100 :param params: Parameters (optional).
103 string
= '{0}/{1}'.format(self
.pod
, string
)
104 request
= self
._session
.post(string
, data
, headers
=headers
, params
=params
, **kwargs
)
107 def put(self
, string
, data
=None, headers
={}, params
={}, **kwargs
):
108 """This method PUTs to session.
110 string
= '{0}/{1}'.format(self
.pod
, string
)
111 if data
is not None: request
= self
._session
.put(string
, data
, headers
=headers
, params
=params
, **kwargs
)
112 else: request
= self
._session
.put(string
, headers
=headers
, params
=params
, **kwargs
)
115 def delete(self
, string
, data
, headers
={}, **kwargs
):
116 """This method lets you send delete request to session.
117 Performs additional checks if needed.
119 :param string: URL to use.
121 :param data: Data to use.
122 :param headers: Headers to use (optional).
125 string
= '{0}/{1}'.format(self
.pod
, string
)
126 request
= self
._session
.delete(string
, data
=data
, headers
=headers
, **kwargs
)
129 def _setlogin(self
, username
, password
):
130 """This function is used to set data for login.
133 It should be called before _login() function.
135 self
._login
_data
= {'user[username]': username
,
136 'user[password]': password
,
137 'authenticity_token': self
._fetchtoken
()}
140 """Handles actual login request.
141 Raises LoginError if login failed.
143 request
= self
.post('users/sign_in',
144 data
=self
._login
_data
,
145 allow_redirects
=False)
146 if request
.status_code
!= 302:
147 raise errors
.LoginError('{0}: login failed'.format(request
.status_code
))
149 def login(self
, remember_me
=1):
150 """This function is used to log in to a pod.
151 Will raise LoginError if password or username was not specified.
153 if not self
._login
_data
['user[username]'] or not self
._login
_data
['user[password]']:
154 raise errors
.LoginError('username and/or password is not specified')
155 self
._login
_data
['user[remember_me]'] = remember_me
156 status
= self
._login
()
157 self
._login
_data
= {}
161 """Logs out from a pod.
162 When logged out you can't do anything.
164 self
.get('users/sign_out')
167 def podswitch(self
, pod
, username
, password
):
168 """Switches pod from current to another one.
171 self
._setlogin
(username
, password
)
174 def _fetchtoken(self
):
175 """This method tries to get token string needed for authentication on D*.
177 :returns: token string
179 request
= self
.get('stream')
180 token
= self
._token
_regex
.search(request
.text
).group(1)
184 def get_token(self
, fetch
=True):
185 """This function returns a token needed for authentication in most cases.
186 **Notice:** using repr() is recommended method for getting token.
188 Each time it is run a _fetchtoken() is called and refreshed token is stored.
190 It is more safe to use than _fetchtoken().
191 By setting new you can request new token or decide to get stored one.
192 If no token is stored new one will be fetched anyway.
194 :returns: string -- token used to authenticate
197 if fetch
or not self
._token
: self
._fetchtoken
()
198 except requests
.exceptions
.ConnectionError
as e
:
199 warnings
.warn('{0} was cought: reusing old token'.format(e
))
201 if not self
._token
: raise errors
.TokenError('cannot obtain token and no previous token found for reuse')
204 def getSessionToken(self
):
205 """Returns session token string (_diaspora_session).
207 return self
._diaspora
_session