From 8993810c7fd7161af4be13e451f062a391af2af0 Mon Sep 17 00:00:00 2001 From: Marek Marecki Date: Sat, 13 Apr 2013 00:29:52 +0200 Subject: [PATCH] `Connection()` object works, `diaply/client.py` partialy ported --- diaspy/client.py | 38 ++++++------------ diaspy/connection.py | 95 ++++++++++++++++++++++++++++++++++++++++++++ tests.py | 15 ------- 3 files changed, 108 insertions(+), 40 deletions(-) diff --git a/diaspy/client.py b/diaspy/client.py index a255a26..44c01fe 100644 --- a/diaspy/client.py +++ b/diaspy/client.py @@ -2,6 +2,7 @@ import requests import re import json import diaspy.models +import diaspy.connection class Client: @@ -16,12 +17,10 @@ class Client: :param password: The password used to log in. :type password: str """ - self._token_regex = re.compile(r'content="(.*?)"\s+name="csrf-token') + self.connection = diaspy.connection.Connection(pod, username, password) + self.connection.login() self.pod = pod - self.session = requests.Session() self._post_data = {} - self._setlogindata(username, password) - self._login() def _sessionget(self, string): """This method gets data from session. @@ -33,7 +32,8 @@ class Client: :param string: URL to get without the pod's URL and slash eg. 'stream'. :type string: str """ - return self.session.get('{0}/{1}'.format(self.pod, string)) + request = self.connection.get(string) + return request def _sessionpost(self, string, data, headers={}, params={}): """This method posts data to session. @@ -50,15 +50,7 @@ class Client: :param params: Parameters (optional). :type params: dict """ - string = '{0}/{1}'.format(self.pod, string) - if headers and params: - request = self.session.post(string, data=data, headers=headers, params=params) - elif headers and not params: - request = self.session.post(string, data=data, headers=headers) - elif not headers and params: - request = self.session.post(string, data=data, params=params) - else: - request = self.session.post(string, data=data) + request = self.connection.post(string, data, headers, params) return request def _sessiondelete(self, string, data, headers={}): @@ -71,11 +63,7 @@ class Client: :param headers: Headers to use (optional). :type headers: dict """ - string = '{0}/{1}'.format(self.pod, string) - if headers: - request = self.session.delete(string, data=data, headers=headers) - else: - request = self.session.delete(string, data=data) + request = self.connection.delete(string, data, headers) return request def get_token(self): @@ -83,7 +71,7 @@ class Client: :returns: string -- token used to authenticate """ - r = self._sessionget('stream') + r = self.connect.get('stream') token = self._token_regex.search(r.text).group(1) return token @@ -157,7 +145,7 @@ class Client: :returns: dict -- json formatted user info. """ - r = self._sessionget('bookmarklet') + r = self.connection.get('bookmarklet') regex = re.compile(r'window.current_user_attributes = ({.*})') userdata = json.loads(regex.search(r.text).group(1)) return userdata @@ -190,12 +178,12 @@ class Client: :returns: list -- list of Post objects. """ - r = self._sessionget('stream.json') + request = self.connection.get('stream.json') - if r.status_code != 200: - raise Exception('wrong status code: {0}'.format(r.status_code)) + if request.status_code != 200: + raise Exception('wrong status code: {0}'.format(request.status_code)) - stream = r.json() + stream = request.json() return [diaspy.models.Post(str(post['id']), self) for post in stream] def get_notifications(self): diff --git a/diaspy/connection.py b/diaspy/connection.py index 0455574..1abcfc3 100644 --- a/diaspy/connection.py +++ b/diaspy/connection.py @@ -1,11 +1,106 @@ #!/usr/bin/env python +import re +import requests + class Connection(): """Object representing connection with the server. It is pushed around internally and is considered private. """ def __init__(self, pod, username='', password=''): + """ + :param pod: The complete url of the diaspora pod to use. + :type pod: str + :param username: The username used to log in. + :type username: str + :param password: The password used to log in. + :type password: str + """ self.pod = pod + self.session = requests.Session() + self._token_regex = re.compile(r'content="(.*?)"\s+name="csrf-token') + self._setlogin(username, password) + + def get(self, string): + """This method gets data from session. + Performs additional checks if needed. + + Example: + To obtain 'foo' from pod one should call `_sessionget('foo')`. + + :param string: URL to get without the pod's URL and slash eg. 'stream'. + :type string: str + """ + return self.session.get('{0}/{1}'.format(self.pod, string)) + + def post(self, string, data, headers={}, params={}): + """This method posts data to session. + Performs additional checks if needed. + + Example: + To post to 'foo' one should call `_sessionpost('foo', data={})`. + + :param string: URL to post without the pod's URL and slash eg. 'status_messages'. + :type string: str + :param data: Data to post. + :param headers: Headers (optional). + :type headers: dict + :param params: Parameters (optional). + :type params: dict + """ + string = '{0}/{1}'.format(self.pod, string) + if headers and params: + request = self.session.post(string, data=data, headers=headers, params=params) + elif headers and not params: + request = self.session.post(string, data=data, headers=headers) + elif not headers and params: + request = self.session.post(string, data=data, params=params) + else: + request = self.session.post(string, data=data) + return request + + def delete(self, string, data, headers={}): + """This method lets you send delete request to session. + Performs additional checks if needed. + + :param string: URL to use. + :type string: str + :param data: Data to use. + :param headers: Headers to use (optional). + :type headers: dict + """ + string = '{0}/{1}'.format(self.pod, string) + if headers: + request = self.session.delete(string, data=data, headers=headers) + else: + request = self.session.delete(string, data=data) + return request + + def _setlogin(self, username, password): + """This function is used to set data for login. + .. note:: + It should be called before _login() function. + """ self.username, self.password = username, password + self.login_data = {'user[username]': self.username, + 'user[password]': self.password, + 'authenticity_token': self.getToken()} + + def login(self): + """This function is used to connect to the pod and log in. + """ + r = self.post('users/sign_in', + data=self.login_data, + headers={'accept': 'application/json'}) + if r.status_code != 201: + raise Exception('{0}: Login failed.'.format(r.status_code)) + + def getToken(self): + """This function gets a token needed for authentication in most cases + :returns: string -- token used to authenticate + """ + r = self.get('stream') + token = self._token_regex.search(r.text).group(1) + return token diff --git a/tests.py b/tests.py index e3d6e2c..3030510 100644 --- a/tests.py +++ b/tests.py @@ -18,21 +18,6 @@ __passwd__ = testconf.__passwd__ class ClientTests(unittest.TestCase): - def testInitialization(self): - client = diaspy.client.Client(pod=__pod__, - username=__username__, - password=__passwd__) - self.assertEqual(__pod__, client.pod) - self.assertEqual(__username__, client._username) - self.assertEqual(__passwd__, client._password) - self.assertEqual({}, client._post_data) - self.assertEqual(client._token_regex, - re.compile(r'content="(.*?)"\s+name="csrf-token')) - self.assertEqual(client._login_data['user[username]'], __username__) - self.assertEqual(client._login_data['user[password]'], __passwd__) - self.assertEqual(client._login_data['authenticity_token'], - client.get_token()) - def testGettingUserInfo(self): client = diaspy.client.Client(__pod__, __username__, __passwd__) info = client.get_user_info() -- 2.25.1