New stuff for version 0.4.1 detailed decription in Changelog
authorMarek Marecki <marekjm@taistelu.com>
Thu, 22 Aug 2013 20:50:21 +0000 (22:50 +0200)
committerMarek Marecki <marekjm@taistelu.com>
Thu, 22 Aug 2013 20:50:21 +0000 (22:50 +0200)
Changelog.markdown
diaspy/models.py
diaspy/settings.py
diaspy/streams.py

index 92eb64353e0a892cbed6cd6f4783fe9974f51c22..790cc0c9b9d0c950b53ff0547b21b6604405b217 100644 (file)
@@ -19,6 +19,21 @@ up-to-date than manual and if conflicts appear they should follow the order:
 *docstrings* -> *docs/* -> *manual/*
 
 
+----
+
+#### Version `0.4.1` (2013-08-):
+
+* __new__:  `__getitem__()` in `diaspy.models.Post`,
+* __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`,
+
+* __fix__:  fixed some bugs in regular expressions used by `diaspy` internals
+            (html tag removal, so you get nicer notifications),
+
+
 ----
 
 #### Version `0.4.0` (2013-08-20):
index fb592cca0fe95cf57d381adf40aa1611d73ba008..a832b0d4ae3af62a414679541c60b08b696da526 100644 (file)
@@ -343,6 +343,9 @@ class Post():
         """
         return self.data['text']
 
+    def __getitem__(self, key):
+        return self.data[key]
+
     def _fetchdata(self):
         """This function retrieves data of the post.
         """
index bbb6ffea0ff4dca0019455bc421883cd11f1db36..245d3b4879b73484512d201ff7e8a7a23ad7fc76 100644 (file)
@@ -3,10 +3,12 @@
 
 
 import json
+import os
 import re
 import urllib
+import warnings
 
-from diaspy import errors
+from diaspy import errors, streams
 
 
 class Settings():
@@ -17,9 +19,49 @@ class Settings():
         self._connection = connection
     
     def downloadxml(self):
+        """Returns downloaded XML.
+        """
         request = self._connection.get('user/export')
         return request.text
 
+    def downloadPhotos(self, size='large', path='.', _critical=False, _stream=None):
+        """Downloads photos into the current working directory.
+        Sizes are: large, medium, small.
+        Filename is: {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 _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 not None: stream = _stream
+        else: stream = streams.Activity
+        stream = stream(self._connection)
+        stream.full()
+        for i, post in enumerate(stream):
+            if post['photos']:
+                for n, photo in enumerate(post['photos']):
+                    name = '{0}.{1}'.format(photo['guid'], 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.
         """
index 36ff2362fc58c909349bccb45ebcb6bba8e8b152..1d06a50a1ea0b5702ef4fd0cf4ebdf4cf56e0dd6 100644 (file)
@@ -127,11 +127,40 @@ class Generic():
         new_stream = self._obtain(max_time=max_time)
         self._expand(new_stream)
 
+    def full(self):
+        """Fetches full stream - containing all posts.
+        WARNING: this can be a **VERY** time consuming function on slow connections of massive streams.
+
+        :returns: integer, lenght of the stream
+        """
+        oldstream = self.copy()
+        self.more()
+        while len(oldstream) != len(self):
+            oldstream = self.copy()
+            self.more()
+        return len(self)
+
     def copy(self):
         """Returns copy (list of posts) of current stream.
         """
         return [p for p in self._stream]
 
+    def json(self, comments=False):
+        """Returns JSON encoded string containing stream's data.
+
+        :param comments: to include comments or not to include 'em, that is the question this param holds answer to
+        :type comments: bool
+        """
+        stream = [post for post in self._stream]
+        if comments:
+            for i, post in enumerate(stream):
+                post._fetchcomments()
+                comments = [c.data for c in post.comments]
+                post['interactions']['comments'] = comments
+                stream[i] = post
+        stream = [post.data for post in stream]
+        return json.dumps(stream)
+
 
 class Outer(Generic):
     """Object used by diaspy.models.User to represent