From: Marek Marecki Date: Mon, 2 Sep 2013 15:36:56 +0000 (+0200) Subject: Merge branch 'fladrian-patch-for-d-0.2.0.0' into devel X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=73a9e0d35ee7f3af1e26ad43dad0c03258de7a85;p=diaspy.git Merge branch 'fladrian-patch-for-d-0.2.0.0' into devel Conflicts: diaspy/connection.py --- 73a9e0d35ee7f3af1e26ad43dad0c03258de7a85 diff --cc Changelog.markdown index eaa2c1a,790cc0c..fcd4092 --- a/Changelog.markdown +++ b/Changelog.markdown @@@ -21,34 -21,14 +21,42 @@@ up-to-date than manual and if conflict ---- --#### Version `0.4.1` (2013-08-): ++#### Version `0.4.1` (2013-09-): + +Login and authentication procedure backend received major changes in this version. +There are no longer `username` and `password` variables in `Connection` object. +Instead, credentials are stored (together with the token) in single variable `_login_data`. +This is preserved until you call `login()` at which point credentials are erased and +only token is left -- it can be obtained by calling `repr(Connection)`. + ++Also, this release is compatible with DIASPORA\* 0.2.0.0 but should still support ++pods running on older versions. ++ ++And the test suite was updated. Yay! ++ ++**`0.4.1-rc.1` (2013-09-02):** * __new__: `__getitem__()` in `diaspy.models.Post`, +* __new__: `__dict__()` in `diaspy.models.Post`, +* __new__: `guid` argument in `diaspy.models.Post.__init__()`, * __new__: `json()` method in `diaspy.streams.Generic` adds the possibility to export streams to JSON, * __new__: `full()` method in `diaspy.streams.Generic` will try to fetch full stream (containing all posts), * __new__: `setEmail()` method in `diaspy.settings.Settings`, * __new__: `setLanguage()` method in `diaspy.settings.Settings`, * __new__: `downloadPhotos()` method in `diaspy.settings.Settings`, +* __new__: `backtime` argument in `more()` method in `diaspy.streams.Generic`, +* __new__: `DiaspyError` will be raised when connection is created with empty password and/or username, - * __new__: `getSessionToken()` method in `diaspy.connection.Connection`, ++* __new__: `getSessionToken()` method in `diaspy.connection.Connection` returns string from `_diaspora_session` cookie, ++* __new__: `direct` parameter in `diaspy.connection.Connection().get()` allowing to disable pod expansion, + +* __upd__: if `Post()` is created with fetched comments, data will also be fetched as a dependency, +* __upd__: `id` argument type is now `int` (`diaspy.models.Post.__init__()`), +* __upd__: `Search().lookup_user()` renamed to `Search().lookupUser()`, +* __upd__: `diaspy.messages` renamed to `diaspy.conversations` (but will be accessible under both names for this and next release), +* __upd__: `LoginError` moved to `diaspy.errors`, +* __upd__: `TokenError` moved to `diaspy.errors`, +* __upd__: `diaspy.connection.Connection.podswitch()` gained two new positional arguments: `username` and `password`, ++* __upd__: `aspect_id` renamed to `id` in `diaspy.streams.Aspects().remove()`, * __fix__: fixed some bugs in regular expressions used by `diaspy` internals (html tag removal, so you get nicer notifications), diff --cc diaspy/__init__.py index aabd59f,7e12ab6..dbc2b60 --- a/diaspy/__init__.py +++ b/diaspy/__init__.py @@@ -8,4 -7,4 +8,4 @@@ import diaspy.notifications as notifica import diaspy.settings as settings - __version__ = '0.4.1' -__version__ = '0.4.0.1' ++__version__ = '0.4.1-rc.1' diff --cc diaspy/connection.py index 51f3449,5d0b182..e0d4352 --- a/diaspy/connection.py +++ b/diaspy/connection.py @@@ -52,9 -51,9 +52,9 @@@ class Connection() repr(connection) instead of calling a specified method. """ - return self.get_token() + return self._token -- def get(self, string, headers={}, params={}): ++ def get(self, string, headers={}, params={}, direct=False): """This method gets data from session. Performs additional checks if needed. @@@ -63,8 -62,8 +63,12 @@@ :param string: URL to get without the pod's URL and slash eg. 'stream'. :type string: str ++ :param direct: if passed as True it will not be expanded ++ :type direct: bool """ - return self._session.get('{0}/{1}'.format(self.pod, string), params=params, headers=headers) - return self.session.get('{0}/{1}'.format(self.pod, string), params=params, headers=headers) ++ if not direct: url = '{0}/{1}'.format(self.pod, string) ++ else: url = string ++ return self._session.get(url, params=params, headers=headers) def post(self, string, data, headers={}, params={}): """This method posts data to session. @@@ -122,11 -122,10 +126,10 @@@ Raises LoginError if login failed. """ request = self.post('users/sign_in', - data=self._login_data, - headers={'accept': 'application/json,text/html'}) - data=self.login_data) - if request.status_code != 200: - print(request) - raise LoginError('{0}: login failed'.format(request.status_code)) ++ data=self._login_data) + if request.status_code not in [200, 201]: + raise errors.LoginError('{0}: login failed'.format(request.status_code)) - print(request.headers) ++ self._diaspora_session = request.cookies['_diaspora_session'] def login(self, username='', password=''): """This function is used to log in to a pod. @@@ -157,15 -155,12 +160,13 @@@ :returns: dict -- json formatted user info. """ - if self._userdata == {} or fetch: - request = self.get('bookmarklet') - userdata = self._userinfo_regex.search(request.text) - if userdata is None: userdata = self._userinfo_regex_2.search(request.text) - if userdata is None: raise errors.DiaspyError('cannot find user data') - userdata = userdata.group(1) - print(userdata) - self._userdata = json.loads(userdata) - return self._userdata + request = self.get('bookmarklet') - try: - userdata = json.loads(self._userinfo_regex.search(request.text).group(1)) - except AttributeError: - raise errors.DiaspyError('cannot find user data') - return userdata ++ userdata = self._userinfo_regex.search(request.text) ++ if userdata is None: userdata = self._userinfo_regex_2.search(request.text) ++ if userdata is None: raise errors.DiaspyError('cannot find user data') ++ userdata = userdata.group(1) ++ warnings.warn(userdata) ++ return json.loads(userdata) def _fetchtoken(self): """This method tries to get token string needed for authentication on D*. @@@ -174,13 -169,17 +175,19 @@@ """ request = self.get('stream') token = self._token_regex.search(request.text).group(1) - self.token = token + self._token = token return token - def get_token(self, fetch=False): + def get_token(self, fetch=True): """This function returns a token needed for authentication in most cases. + **Notice:** using repr() is recommended method for getting token. + + Each time it is run a _fetchtoken() is called and refreshed token is stored. + + It is more safe to use than _fetchtoken(). + By setting new you can request new token or decide to get stored one. + If no token is stored new one will be fetched anyway. + :returns: string -- token used to authenticate """ try: diff --cc diaspy/people.py index c86067d,c86067d..c20283f --- a/diaspy/people.py +++ b/diaspy/people.py @@@ -99,7 -99,7 +99,7 @@@ class User() """Fetch user data and posts using Diaspora handle. """ pod, user = sephandle(self.handle) -- request = self._connection.session.get('{0}://{1}/u/{2}.json'.format(protocol, pod, user)) ++ request = self._connection.get('{0}://{1}/u/{2}.json'.format(protocol, pod, user), direct=True) self._postproc(request) def fetchguid(self): diff --cc diaspy/streams.py index d6ffaed,1d06a50..66036c7 --- a/diaspy/streams.py +++ b/diaspy/streams.py @@@ -356,7 -322,7 +356,7 @@@ class Aspects(Generic) id = self.getAspectID(aspect_name) return Aspect(self._connection, id) -- def remove(self, aspect_id=-1, name=''): ++ def remove(self, id=-1, name=''): """This method removes an aspect. You can give it either id or name of the aspect. When both are specified, id takes precedence over name. @@@ -369,10 -335,10 +369,10 @@@ :param name: name of aspect to remove :type name: str """ -- if aspect_id == -1 and name: aspect_id = self.getAspectID(name) ++ if id == -1 and name: id = self.getAspectID(name) data = {'_method': 'delete', 'authenticity_token': self._connection.get_token()} -- request = self._connection.post('aspects/{0}'.format(aspect_id), data=data) ++ request = self._connection.post('aspects/{0}'.format(id), data=data) if request.status_code not in [200, 302, 500]: raise Exception('wrong status code: {0}: cannot remove aspect'.format(request.status_code)) diff --cc tests.py index 500a62f,83c9e39..2eade92 --- a/tests.py +++ b/tests.py @@@ -40,6 -40,6 +40,15 @@@ test_connection = diaspy.connection.Con test_connection.login() print('[ CONNECTED ]\n') ++# Setup test aspects ++print('Adding test aspects...\t', end='') ++diaspy.streams.Aspects(test_connection).add(testconf.test_aspect_name_fake) ++testconf.test_aspect_id = diaspy.streams.Aspects(test_connection).add(testconf.test_aspect_name).id ++print('OK') ++ ++print([i['name'] for i in test_connection.getUserInfo()['aspects']]) ++ ++ post_text = '#diaspy test no. {0}'.format(test_count) @@@ -68,6 -68,6 +77,32 @@@ class MessagesTests(unittest.TestCase) self.assertEqual(diaspy.models.Conversation, type(mailbox[i])) ++class AspectsTests(unittest.TestCase): ++ def testAspectsGettingID(self): ++ aspects = diaspy.streams.Aspects(test_connection) ++ id = aspects.getAspectID(testconf.test_aspect_name) ++ self.assertEqual(testconf.test_aspect_id, id) ++ ++ def testAspectsRemoveById(self): ++ aspects = diaspy.streams.Aspects(test_connection) ++ for i in test_connection.getUserInfo()['aspects']: ++ if i['name'] == testconf.test_aspect_name: ++ print(i['id'], end=' ') ++ aspects.remove(id=i['id']) ++ break ++ names = [i['name'] for i in test_connection.getUserInfo()['aspects']] ++ print(names) ++ self.assertNotIn(testconf.test_aspect_name, names) ++ ++ def testAspectsRemoveByName(self): ++ aspects = diaspy.streams.Aspects(test_connection) ++ print(testconf.test_aspect_name_fake, end=' ') ++ aspects.remove(name=testconf.test_aspect_name_fake) ++ names = [i['name'] for i in test_connection.getUserInfo()['aspects']] ++ print(names) ++ self.assertNotIn(testconf.test_aspect_name_fake, names) ++ ++ class StreamTest(unittest.TestCase): def testGetting(self): stream = diaspy.streams.Generic(test_connection) @@@ -107,26 -107,26 +142,6 @@@ ft = diaspy.streams.FollowedTags(test_connection) ft.add('test') -- def testAspectsAdd(self): -- aspects = diaspy.streams.Aspects(test_connection) -- aspects.add(testconf.test_aspect_name_fake) -- testconf.test_aspect_id = aspects.add(testconf.test_aspect_name).id -- -- def testAspectsGettingID(self): -- aspects = diaspy.streams.Aspects(test_connection) -- id = aspects.getAspectID(testconf.test_aspect_name) -- self.assertEqual(testconf.test_aspect_id, id) -- -- def testAspectsRemoveById(self): -- aspects = diaspy.streams.Aspects(test_connection) -- aspects.remove(testconf.test_aspect_id) -- self.assertEqual(-1, aspects.getAspectID(testconf.test_aspect_name)) -- -- def testAspectsRemoveByName(self): -- aspects = diaspy.streams.Aspects(test_connection) -- aspects.remove(name=testconf.test_aspect_name_fake) -- self.assertEqual(-1, aspects.getAspectID(testconf.test_aspect_name_fake)) -- def testActivity(self): activity = diaspy.streams.Activity(test_connection)