Permalink
Browse files

refactored fetch_likes and fetch_reposts, rewrote tests

  • Loading branch information...
1 parent 7ce21c2 commit 1ec32fc4fd4fe9c829889cacc9526bd36e57d60a @ramusus committed Mar 31, 2013
Showing with 93 additions and 55 deletions.
  1. +1 −0 .travis.yml
  2. +2 −2 setup.py
  3. +1 −1 vkontakte_wall/__init__.py
  4. +65 −42 vkontakte_wall/models.py
  5. +24 −10 vkontakte_wall/tests.py
View
@@ -8,6 +8,7 @@ install:
- pip install simplejson --use-mirrors
- pip install factory_boy --use-mirrors
- pip install coveralls --use-mirrors
+ - pip install mock --use-mirrors
- pip install . --use-mirrors
script:
- coverage run --source=vkontakte_wall quicktest.py vkontakte_wall
View
@@ -14,8 +14,8 @@
include_package_data=True,
zip_safe=False, # because we're including media that Django needs
install_requires=[
- 'django-vkontakte-api>=0.3.4',
- 'django-vkontakte-users>=0.3.0',
+ 'django-vkontakte-api>=0.3.7',
+ 'django-vkontakte-users>=0.3.2',
'django-vkontakte-groups>=0.3.0',
],
classifiers=[
@@ -1,2 +1,2 @@
-VERSION = (0, 3, 2)
+VERSION = (0, 3, 3)
__version__ = '.'.join(map(str, VERSION))
@@ -66,14 +66,14 @@ def fetch_group_wall(self, group, offset=0, count=None, own=False, after=None):
log.error(e)
continue
- post.raw_html = unicode(item)
- post.save()
- parsed.send(sender=Post, instance=post, container=item)
-
if after and post.date < after:
need_cut = True
break
+ post.raw_html = unicode(item)
+ post.save()
+ parsed.send(sender=Post, instance=post, container=item)
+
if len(items) == 20 and not need_cut:
return self.fetch_group_wall(group, offset=current_count, count=count, own=own, after=after)
elif after and need_cut:
@@ -316,40 +316,51 @@ def fetch_likes(self, offset=0):
'''
post_data = {
- 'act':'a_get_members',
+ 'act': 'show',
'al': 1,
- 'object': 'wall%s' % self.remote_id,
- 'only_content': 1,
- 'published': 0,
- 'tab': 0,
- 'offset': offset,
+ 'w': 'likes/wall%s' % self.remote_id,
}
+ if offset == 0:
+ number_on_page = 120
+ post_data['loc'] = 'wall%s' % self.remote_id,
+ else:
+ number_on_page = 60
+ post_data['offset'] = offset
+
log.debug('Fetching likes of post "%s" of group "%s", offset %d' % (self.remote_id, self.wall_owner, offset))
- parser = VkontakteWallParser().request('/like.php', data=post_data)
+ parser = VkontakteWallParser().request('/wkview.php', data=post_data)
if offset == 0:
- title = parser.content_bs.find('h4')
- if title:
- try:
- self.likes = int(title.text.split(' ')[1])
- self.save()
- except:
- log.warning('Strange format of h4 container: "%s"' % title.text)
+ try:
+ self.likes = int(parser.content_bs.find('a', {'id': 'wk_likes_tablikes'}).find('nobr').text.split()[0])
+ self.save()
+ except:
+ log.warning('Strange markup of first page likes response: "%s"' % parser.content)
self.like_users.clear()
- avatars = parser.content_bs.findAll('div', {'class': 'liked_box_row'})
- for avatar in avatars:
- user = User.remote.get_by_slug(avatar.findAll('a')[1]['href'][1:])
+ #<div class="wk_likes_liker_row inl_bl" id="wk_likes_liker_row722246">
+ # <div class="wk_likes_likerph_wrap" onmouseover="WkView.likesBigphOver(this, 722246)">
+ # <a class="wk_likes_liker_ph" href="/kicolenka">
+ # <img class="wk_likes_liker_img" src="http://cs418825.vk.me/v418825246/6cf8/IBbSfmDz6R8.jpg" width="100" height="100" />
+ # </a>
+ # </div>
+ # <div class="wk_likes_liker_name"><a class="wk_likes_liker_lnk" href="/kicolenka">Оля Киселева</a></div>
+ #</div>
+
+ items = parser.content_bs.findAll('div', {'class': re.compile(r'^wk_likes_liker_row')})
+ for item in items:
+ user_link = item.find('a', {'class': 'wk_likes_liker_lnk'})
+ user = User.remote.get_by_slug(user_link['href'][1:])
if user:
- user.first_name = avatar.findAll('a')[1].text
- user.photo = avatar.find('img')['src']
+ user.set_name(user_link.text)
+ user.photo = item.find('img', {'class': 'wk_likes_liker_img'})['src']
user.save()
self.like_users.add(user)
- if len(avatars) == 24:
- self.fetch_likes(offset=offset+24)
+ if len(items) == number_on_page:
+ self.fetch_likes(offset=offset+number_on_page)
def fetch_reposts(self, offset=0):
'''
@@ -359,37 +370,49 @@ def fetch_reposts(self, offset=0):
* repost_users - users, who repost this post
'''
post_data = {
- 'act':'a_get_members',
+ 'act': 'show',
'al': 1,
- 'object': 'wall%s' % self.remote_id,
- 'only_content': 1,
- 'published': 1,
- 'tab': 1,
- 'offset': offset,
+ 'w': 'shares/wall%s' % self.remote_id,
}
+ if offset == 0:
+ number_on_page = 40
+ post_data['loc'] = 'wall%s' % self.remote_id,
+ else:
+ number_on_page = 20
+ post_data['offset'] = offset
+
log.debug('Fetching reposts of post "%s" of group "%s", offset %d' % (self.remote_id, self.wall_owner, offset))
- parser = VkontakteWallParser().request('/like.php', data=post_data)
+ parser = VkontakteWallParser().request('/wkview.php', data=post_data)
if offset == 0:
- title = parser.content_bs.find('h4')
- if title:
- self.reposts = int(title.text.split(' ')[0])
+ try:
+ self.reposts = int(parser.content_bs.find('a', {'id': 'wk_likes_tabshares'}).find('nobr').text.split()[0])
self.save()
+ except:
+ log.warning('Strange markup of first page shares response: "%s"' % parser.content)
self.repost_users.clear()
- avatars = parser.content_bs.findAll('div', {'class': 'liked_box_row'})
- for avatar in avatars:
- user = User.remote.get_by_slug(avatar.findAll('a')[1]['href'][1:])
+ #<div id="post65120659_2341" class="post post_copy" onmouseover="wall.postOver('65120659_2341')" onmouseout="wall.postOut('65120659_2341')" data-copy="-16297716_126261" onclick="wall.postClick('65120659_2341', event)">
+ # <div class="post_table">
+ # <div class="post_image">
+ # <a class="post_image" href="/vano0ooooo"><img src="/images/camera_c.gif" width="50" height="50"/></a>
+ # </div>
+ # <div class="wall_text"><a class="author" href="/vano0ooooo" data-from-id="65120659">Иван Панов</a> <div id="wpt65120659_2341"></div><table cellpadding="0" cellspacing="0" class="published_by_wrap">
+
+ items = parser.content_bs.findAll('div', {'id': re.compile('^post')})
+ for item in items:
+ user_link = item.find('a', {'class': 'author'})
+ user = User.remote.get_by_slug(user_link['href'][1:])
if user:
- user.first_name = avatar.findAll('a')[1].text
- user.photo = avatar.find('img')['src']
+ user.set_name(user_link.text)
+ user.photo = item.find('a', {'class': 'post_image'}).find('img')['src']
user.save()
self.repost_users.add(user)
- if len(avatars) == 24:
- self.fetch_reposts(offset=offset+24)
+ if len(items) == number_on_page:
+ self.fetch_reposts(offset=offset+number_on_page)
class Comment(WallAbstractModel):
class Meta:
@@ -5,6 +5,7 @@
from vkontakte_users.models import User
from datetime import datetime
import simplejson as json
+import mock
USER_ID = 5223304
POST_ID = '5223304_130'
@@ -47,6 +48,17 @@ def test_fetch_group_wall(self):
self.assertTrue(posts[0].comments + posts[1].comments > 0)
self.assertTrue(len(posts[0].text) > 0)
+ # testing after parameter
+ after = Post.objects.order_by('date')[0].date
+
+ Post.objects.all().delete()
+ self.assertEqual(Post.objects.count(), 0)
+
+ posts = group.fetch_posts(after=after)
+
+ self.assertTrue(len(posts), 10)
+ self.assertEqual(Post.objects.count(), 10)
+
def test_fetch_group_open_wall(self):
group = GroupFactory.create(remote_id=OPEN_WALL_GROUP_ID, screen_name=OPEN_WALL_GROUP_SCREEN_NAME)
@@ -77,7 +89,8 @@ def test_fetch_user_post_comments(self):
post.fetch_comments(all=True)
# self.assertTrue(Comment.objects.count() > len(comments)) only 1 comment
- def test_fetch_group_post_comments(self):
+ @mock.patch('vkontakte_users.models.User.remote.get_by_slug', side_effect=lambda s: UserFactory.create())
+ def test_fetch_group_post_comments(self, *args, **kwargs):
group = GroupFactory.create(remote_id=GROUP_ID, screen_name=GROUP_SCREEN_NAME)
post = PostFactory.create(remote_id=GROUP_POST_ID, wall_owner=group)
@@ -103,26 +116,27 @@ def test_fetch_group_post_comments(self):
# self.assertEqual(comments[0].post, post)
# self.assertEqual(post.comments, len(comments))
- def test_fetch_post_reposts(self):
+ @mock.patch('vkontakte_users.models.User.remote.get_by_slug', side_effect=lambda s: UserFactory.create())
+ def test_fetch_post_reposts(self, *args, **kwargs):
post = PostFactory.create(remote_id=GROUP_POST_ID)
self.assertEqual(post.reposts, 0)
self.assertEqual(post.repost_users.count(), 0)
post.fetch_reposts()
- self.assertNotEqual(post.reposts, 0)
- self.assertNotEqual(post.repost_users.count(), 0)
+ self.assertTrue(post.reposts >= 38)
+ self.assertTrue(post.repost_users.count() >= 38)
- def test_fetch_post_likes(self):
+ @mock.patch('vkontakte_users.models.User.remote.get_by_slug', side_effect=lambda s: UserFactory.create())
+ def test_fetch_post_likes(self, *args, **kwargs):
post = PostFactory.create(remote_id=GROUP_POST_ID)
self.assertEqual(post.likes, 0)
self.assertEqual(post.like_users.count(), 0)
post.fetch_likes()
- self.assertNotEqual(post.likes, 0)
- self.assertNotEqual(post.like_users.count(), 0)
- self.assertTrue(post.like_users.count() > 24)
+ self.assertTrue(post.likes > 120)
+ self.assertTrue(post.like_users.count() > 120)
def test_parse_post(self):
@@ -157,7 +171,7 @@ def test_parse_post(self):
self.assertEqual(instance.reposts, 3)
self.assertEqual(instance.comments, 4)
self.assertEqual(instance.text, 'qwerty')
- self.assertEqual(instance.date, datetime(2011,2,22,9,0,0))
+ self.assertTrue(isinstance(instance.date, datetime))
def test_parse_comments(self):
@@ -174,8 +188,8 @@ def test_parse_comments(self):
self.assertEqual(instance.remote_id, '1_2505')
self.assertEqual(instance.text, u'Добрый день , кароче такая идея когда опросы создаешь вместо статуса - можно выбрать аудитории опрашиваемых, например только женский или мужской пол могут участвовать (то бишь голосовать в опросе).')
- self.assertEqual(instance.date, datetime(2011,2,22,9,0,0))
self.assertEqual(instance.author, author)
+ self.assertTrue(isinstance(instance.date, datetime))
instance.parse(json.loads(response)['response'][2])
instance.save()

0 comments on commit 1ec32fc

Please sign in to comment.