From: Marek Marecki Date: Sun, 8 Sep 2013 10:32:43 +0000 (+0200) Subject: Setters for profile information implemented X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=3def6e18f205e511987cc643ccfeaa0784845101;p=diaspy.git Setters for profile information implemented --- diff --git a/Changelog.markdown b/Changelog.markdown index 621018c..e36467a 100644 --- a/Changelog.markdown +++ b/Changelog.markdown @@ -40,6 +40,21 @@ pods running on older versions. And the test suite was updated. Yay! + +**`0.4.1-rc.3` (2013-09-08):** + +* __new__: `diaspy.settings.Profile.load()` method for loading profile information, +* __new__: `diaspy.settings.Profile.update()` method for updating profile information, +* __new__: `diaspy.settings.Profile.setName()` method, +* __new__: `diaspy.settings.Profile.setBio()` method, +* __new__: `diaspy.settings.Profile.setLocation()` method, +* __new__: `diaspy.settings.Profile.setTags()` method, +* __new__: `diaspy.settings.Profile.setGender()` method, +* __new__: `diaspy.settings.Profile.setBirthDate()` method, +* __new__: `diaspy.settings.Profile.setSearchable()` method, +* __new__: `diaspy.settings.Profile.setNSFW()` method, + + **`0.4.1-rc.2` (2013-09-06):** * __new__: `diaspy.search.Search.tags()` method for getting tag suggestions, @@ -53,11 +68,13 @@ And the test suite was updated. Yay! * __new__: `diaspy.settings.Profile.isNSFW()` method, * __new__: `provider_display_name` parameter in `diaspy.streams.Stream.post()` (thanks @svbergerem), + * __upd__: `remeber_me` parameter in `diaspy.connection.Connection.login()`, * __upd__: you must supply `username` and `password` parameters on init of `diaspy.connection.Connection`, * __upd__: you must update your testconf.py (new fields are required for settings tests), * __upd__: `diaspy.settings.Settings` renamed to `diaspy.settings.Account`, + * __rem__: `username` and `password` parameters removed from `diaspy.connection.Connection.login()` must be supplied on init, @@ -77,6 +94,7 @@ And the test suite was updated. Yay! * __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()`, @@ -86,8 +104,8 @@ And the test suite was updated. Yay! * __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), + +* __fix__: fixed some bugs in regular expressions used by `diaspy` internals (html tag removal, so you get nicer notifications), * __fix__: fixed authentication issues, @@ -100,25 +118,30 @@ Also, this release if first to officially released fork version. * __dep__: `diaspy.client` is officially deprecated (will be removed in `0.4.1`), + * __upd__: `diaspy.conversations` renamed to `diaspy.messages`, * __udp__: `diaspy.conversations.Conversation` moved to `diaspy.models`, + * __new__: `diaspy.messages.Mailbox()` object representing diaspora\* mailbox, ---- -Version `0.3.2` (2013-08-20): +#### Version `0.3.2` (2013-08-20): * __upd__: `diaspy.connection.getUserData()` raises `DiaspyError` when it cannot find user data, + * __rem__: `diaspy.client.Client` must be explicitly imported, ---- -Version `0.3.1` (2013-07-12): +#### Version `0.3.1` (2013-07-12): * __upd__: `diaspy.people.sephandle()` raises `InvalidHandleError` instead of `UserError` * __upd__: `models.Post()._fetch()` renamed to `_fetchdata()` (because of new `_fetchcomments()` method) + + * __new__: `models.Comment()` object: wrapper for comments, not to be created manually * __new__: `comments` parameter in `models.Post`: defines whether to fetch post's commets * __new__: `connection.Connection` has new parameter in `__init__()`: it's `schema` @@ -137,7 +160,7 @@ When it comes to posts, we are now able to fetch comments. ---- -Version `0.3.0` (2013-07-07): +#### Version `0.3.0` (2013-07-07): First edition of Changelog for `diaspy`. Developers should update their code as version `0.3.0` may not be fully @@ -148,4 +171,4 @@ theory, not worry about this update. Version `0.3.0` introduces few new features, fixes several bugs and brings a bit of redesign and refactoring od `diaspy`'s code. ----- +  diff --git a/diaspy/__init__.py b/diaspy/__init__.py index b588f04..4621ccc 100644 --- a/diaspy/__init__.py +++ b/diaspy/__init__.py @@ -8,4 +8,4 @@ import diaspy.notifications as notifications import diaspy.settings as settings -__version__ = '0.4.1-rc.2' +__version__ = '0.4.1-rc.3' diff --git a/diaspy/settings.py b/diaspy/settings.py index 27cd904..98aa0ce 100644 --- a/diaspy/settings.py +++ b/diaspy/settings.py @@ -11,8 +11,120 @@ import warnings from diaspy import errors, streams +class Account(): + """Provides interface to account settings. + """ + def __init__(self, connection): + self._connection = connection + + def downloadxml(self): + """Returns downloaded XML. + """ + request = self._connection.get('user/export') + return request.text + + def downloadPhotos(self, size='large', path='.', mark_nsfw=True, _critical=False, _stream=None): + """Downloads photos into the current working directory. + Sizes are: large, medium, small. + Filename is: {post_guid}_{photo_guid}.{extension} + + Normally, this method will catch urllib-generated errors and + just issue warnings about photos that couldn't be downloaded. + However, with _critical param set to True errors will become + critical - the will be reraised in finally block. + + :param size: size of the photos to download - large, medium or small + :type size: str + :param path: path to download (defaults to current working directory + :type path: str + :param mark_nsfw: will append '-nsfw' to images from posts marked as nsfw, + :type mark_nsfw: bool + :param _stream: diaspy.streams.Generic-like object (only for testing) + :param _critical: if True urllib errors will be reraised after generating a warning (may be removed) + + :returns: integer, number of photos downloaded + """ + photos = 0 + if _stream is None: + stream = streams.Activity(self._connection) + stream.full() + else: + stream = _stream + for i, post in enumerate(stream): + if post['nsfw'] is not False: nsfw = '-nsfw' + else: nsfw = '' + if post['photos']: + for n, photo in enumerate(post['photos']): + name = '{0}_{1}{2}.{3}'.format(post['guid'], photo['guid'], nsfw, photo['sizes'][size].split('.')[-1]) + filename = os.path.join(path, name) + try: + urllib.request.urlretrieve(url=photo['sizes'][size], filename=filename) + except (urllib.error.HTTPError, urllib.error.URLError) as e: + warnings.warn('downloading image {0} from post {1}: {2}'.format(photo['guid'], post['guid'], e)) + finally: + if _critical: raise + photos += 1 + return photos + + def setEmail(self, email): + """Changes user's email. + """ + data = {'_method': 'put', 'utf8': '✓', 'user[email]': email, 'authenticity_token': repr(self._connection)} + request = self._connection.post('user', data=data, allow_redirects=False) + + def getEmail(self): + """Returns currently used email. + """ + data = self._connection.get('user/edit') + email = re.compile('')+1:item.rfind('<')] + identifier = item[item.find('"')+1:] + identifier = identifier[:identifier.find('"')] + languages.append((name, identifier)) + return languages + + +class Privacy(): + """Provides interface to provacy settings. + """ + def __init__(self, connection): + self._connection = connection + + class Profile(): - """Provides profile editing methods. + """Provides interface to profile settigns. + + WARNING: + + Because of the way update requests for profile are created every field must be sent. + The `load()` method is used to load all information into the dictionary. + Setters can then be used to adjust the data. + Finally, `update()` can be called to send data back to pod. """ firstname_regexp = re.compile('') lastname_regexp = re.compile('') @@ -49,28 +161,6 @@ class Profile(): """ return self._connection.get('profile/edit').text - def load(self): - """Loads profile data into self.data dictionary. - **Notice:** Not all keys are loaded yet. - """ - self.data['profile[first_name]'], self.data['profile[last_name]'] = self.getName() - self.data['profile[bio]'] = self.getBio() - self.data['profile[location]'] = self.getLocation() - self.data['profile[gender]'] = self.getGender() - year, month, day = self.getBirthDate(named_month=False) - self.data['profile[date][]'] = year - self.data['profile[date][]'] = month - self.data['profile[date][]'] = day - self._loaded = True - - def update(self): - """Updates profile information. - """ - if not self._loaded: raise errors.DiaspyError('profile was not loaded') - data['authenticity_token'] = repr(self._connection) - request = self._connection.post('profile', data=json.dumps(data), allow_redirects=False) - return request.status_code - def getName(self): """Returns two-tuple: (first, last) name. """ @@ -145,101 +235,75 @@ class Profile(): else: nsfw = True return nsfw + def setName(self, first, last): + """Set first and last name. + """ + self.data['profile[first_name]'] = first + self.data['profile[last_name]'] = last -class Account(): - """This object is used to get access to user's settings on - Diaspora* and provides interface for downloading user's stuff. - """ - def __init__(self, connection): - self._connection = connection - - def downloadxml(self): - """Returns downloaded XML. + def setTags(self, tags): + """Sets tags that describe the user. """ - request = self._connection.get('user/export') - return request.text + self.data['tags'] = ', '.join(['#{}'.format(tag) for tag in tags]) - def downloadPhotos(self, size='large', path='.', mark_nsfw=True, _critical=False, _stream=None): - """Downloads photos into the current working directory. - Sizes are: large, medium, small. - Filename is: {post_guid}_{photo_guid}.{extension} + def setBio(self, bio): + """Set bio of a user. + """ + self.data['profile[bio]'] = bio - Normally, this method will catch urllib-generated errors and - just issue warnings about photos that couldn't be downloaded. - However, with _critical param set to True errors will become - critical - the will be reraised in finally block. + def setLocation(self, location): + """Set location of a user. + """ + self.data['profile[location]'] = location - :param size: size of the photos to download - large, medium or small - :type size: str - :param path: path to download (defaults to current working directory - :type path: str - :param mark_nsfw: will append '-nsfw' to images from posts marked as nsfw, - :type mark_nsfw: bool - :param _stream: diaspy.streams.Generic-like object (only for testing) - :param _critical: if True urllib errors will be reraised after generating a warning (may be removed) + def setGender(self, gender): + """Set gender of a user. + """ + self.data['profile[gender]'] = gender - :returns: integer, number of photos downloaded + def setBirthDate(self, year, month, day): + """Set birth date of a user. """ - photos = 0 - if _stream is None: - stream = streams.Activity(self._connection) - stream.full() - else: - stream = _stream - for i, post in enumerate(stream): - if post['nsfw'] is not False: nsfw = '-nsfw' - else: nsfw = '' - if post['photos']: - for n, photo in enumerate(post['photos']): - name = '{0}_{1}{2}.{3}'.format(post['guid'], photo['guid'], nsfw, photo['sizes'][size].split('.')[-1]) - filename = os.path.join(path, name) - try: - urllib.request.urlretrieve(url=photo['sizes'][size], filename=filename) - except (urllib.error.HTTPError, urllib.error.URLError) as e: - warnings.warn('downloading image {0} from post {1}: {2}'.format(photo['guid'], post['guid'], e)) - finally: - if _critical: raise - photos += 1 - return photos + self.data['profile[date][year]'] = year + self.data['profile[date][month]'] = month + self.data['profile[date][day]'] = day - def setEmail(self, email): - """Changes user's email. + def setSearchable(self, searchable): + """Set user's searchable status. """ - data = {'_method': 'put', 'utf8': '✓', 'user[email]': email, 'authenticity_token': repr(self._connection)} - request = self._connection.post('user', data=data, allow_redirects=False) + self.data['profile[searchable]'] = json.dumps(searchable) - def getEmail(self): - """Returns currently used email. + def setNSFW(self, nsfw): + """Set user NSFW status. """ - data = self._connection.get('user/edit') - email = re.compile('')+1:item.rfind('<')] - identifier = item[item.find('"')+1:] - identifier = identifier[:identifier.find('"')] - languages.append((name, identifier)) - return languages + +class Services(): + """Provides interface to services settings. + """ + def __init__(self, connection): + self._connection = connection