Merge lp:~kai-mast/friends/fetch-twitter-images into lp:friends

Proposed by Kai Mast
Status: Merged
Merged at revision: 245
Proposed branch: lp:~kai-mast/friends/fetch-twitter-images
Merge into: lp:friends
Diff against target: 127 lines (+38/-21)
3 files modified
friends/protocols/twitter.py (+19/-5)
friends/tests/data/twitter-home.dat (+13/-12)
friends/tests/test_twitter.py (+6/-4)
To merge this branch: bzr merge lp:~kai-mast/friends/fetch-twitter-images
Reviewer Review Type Date Requested Status
Robert Bruce Park Approve
Kai Mast (community) Needs Resubmitting
Review via email: mp+197556@code.launchpad.net

Description of the change

Maybe this was too easy and I did something wrong. But for me this small change resulted in twitter posts now properly showing images.

To post a comment you must log in.
Revision history for this message
Robert Bruce Park (robru) wrote :

Please bring back the trailing comma at the end of url=permalink. It will make the diff nicer.

review: Needs Fixing
246. By Kai Mast

Added trailing comma

Revision history for this message
Kai Mast (kai-mast) wrote :

Done :)

Revision history for this message
Robert Bruce Park (robru) wrote :

Please specify a default value for picture because python's None value i don't think will work. So:

  picture = url.get('media_url', '')

Oh and please add a test for this as well (look at the existing tests, you might have to add some extra json if there isn't already a media_url key present in the example data).

247. By Kai Mast

Fixed most tests

248. By Kai Mast

Fixed final test

249. By Kai Mast

added a test for fetching the media_url

Revision history for this message
Kai Mast (kai-mast) wrote :

Tests added. The diff got a lot larger now because I changed the code to only adding the media_url if it exists (otherwise the tests break).

review: Needs Resubmitting
Revision history for this message
Kai Mast (kai-mast) wrote :

Btw, considering the second TODO I added. I was wondering, if I can just add a html tag at the protocol level? Or will this break internal processing?

Revision history for this message
Robert Bruce Park (robru) wrote :

What? No, I don't like your args dict creation at all. Put back the self._publish call the way it was, and just update the tests to reflect the new argument being called.

Also I'm not sure what you mean by "adding an html tag at the protocol level". The url field can only be one URL, because that's how friends-app interprets it. Putting HTML in there will break how friends-app displays it.

Revision history for this message
Robert Bruce Park (robru) wrote :

Also, why did you review as 'Resubmit'? Do you intend to create a new MP?

Revision history for this message
Adolfo Jayme Barrientos (fitojb) wrote :

> Also, why did you review as 'Resubmit'? Do you intend to create a new MP?
If Launchpad was less confusing... When I created my first MPs, I thought "Resubmit" was a way to indicate that a change was made to the MP - MP reviews display similarly to bug statuses in LP, so one can think they work the same way. </sorry_for_intruding>

Revision history for this message
Robert Bruce Park (robru) wrote :

Adolfo, are there any launchpad projects you don't subscribe to? ;-)

Revision history for this message
Kai Mast (kai-mast) wrote :

@Adolfo: yes that is exactly what I thought

Robert, if I don't use the args dictionary I woudl have to add link_picture='' to some of the tests. That was in my eyes a worse than adding the dictionary, but if you prefer that I will do so.

What I mean with the other post was the following: The t.co link is currently replaced with the long link instead of the pretty display link. The easiest way to solve this would be to directly insert an html tag at line 37.
But there seems to be some processing at a higer level that replaces links by HTML tags, so I don't know it if this would break in such a case...

Revision history for this message
Kai Mast (kai-mast) wrote :

I just tested the latter on my branch and it seems to work :)

So we would have:
<a href='http://twitter.com/yunorno/status/114080493036773378/photo/1'>pic.twitter.com/rJC5Pxsu</a>

Instead of:
<a href="http://twitter.com/yunorno/status/114080493036773378/photo/1">http://twitter.com/yunorno/status/114080493036773378/photo/1</a>

Revision history for this message
Robert Bruce Park (robru) wrote :

Oh right, it's starting to come back to me now, we do have some code in the linkifier regex that stops it linkifying links that are already linkified, so that just might work.

yes, please change back the args dict / _publish call and update all the tests to expect "link_picture=''". I find a dozen lines of "args args args args args args args" with the accompanying bracket notation really ugly. Strongly prefer direct kwargs on the _publish method invocation.

250. By Kai Mast

Fixed displaying URLs

251. By Kai Mast

Removed args dictionary

252. By Kai Mast

Fixed indendation of publish call

253. By Kai Mast

Removed spaces in params

Revision history for this message
Kai Mast (kai-mast) wrote :

Args dictionary removed...

254. By Kai Mast

Fixed a small issue that was not cached by the test

Revision history for this message
Robert Bruce Park (robru) wrote :

Ok, this is starting to look really good to me now ;-)

Please:

1. Strip trailing whitespace

2. Add trailing comma to last argument of self._publish() (adding it now means the diff won't be ugly later if we have to add another argument at the end)

3. "picture = ''; if 'media_url' in url: picture = url.get('media_url')" should just be "picture = url.get('media_url', '')"

4. "if display_url is not ''" is really ugly. At the very least, it should just be "if display_url:", however I don't like the two different "message = message[...]" lines, I think we can do better than this. Please try something like this instead:

expanded_url = url.get('expanded_url', '')
display_url = url.get('display_url', '')
other_url = url.get('url', '')
picture_url = url.get('media_url', '')

if None not in (begin, end):
    message = ''.join(
        message[:begin],
        '<a href="',
        (expanded_url or display_url or other_url),
        '">',
        (display_url or expanded_url or other_url),
        '</a>',
        message[end:])

This is a much more concise/pythonic way of expressing the same thought, and it's also a little bit more robust in the case of missing keys from the url dict.

review: Needs Fixing
255. By Kai Mast

Formatted code as suggested

256. By Kai Mast

Removed trailing whitespace

257. By Kai Mast

Fixed wrong indentation

Revision history for this message
Kai Mast (kai-mast) wrote :

I hink I did what you said.

Its my first time touching reallife python code so I have no idea of coding style. Thanks for the feedback.

Revision history for this message
Robert Bruce Park (robru) wrote :

Ok, yes it looks very good to me now. I see you caught a bug I wrote, since I forgot to put the arguments to 'join' in a list ;-)

I will try to test this a bit more thoroughly later today. Thanks!

Revision history for this message
Robert Bruce Park (robru) wrote :

Ok, gave this a proper test, it looks really good! Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'friends/protocols/twitter.py'
--- friends/protocols/twitter.py 2013-07-23 08:17:16 +0000
+++ friends/protocols/twitter.py 2013-12-05 19:59:40 +0000
@@ -119,16 +119,29 @@
119 tweet_id=tweet_id)119 tweet_id=tweet_id)
120120
121 message = tweet.get('text', '')121 message = tweet.get('text', '')
122 picture_url = ''
122123
123 # Resolve t.co links.124 # Resolve t.co links.
125 #TODO support more than one media file
124 entities = tweet.get('entities', {})126 entities = tweet.get('entities', {})
125 for url in (entities.get('urls', []) + entities.get('media', [])):127 for url in (entities.get('urls', []) + entities.get('media', [])):
126 begin, end = url.get('indices', (None, None))128 begin, end = url.get('indices', (None, None))
127 destination = (url.get('expanded_url') or129
128 url.get('display_url') or130 expanded_url = url.get('expanded_url', '')
129 url.get('url'))131 display_url = url.get('display_url', '')
130 if None not in (begin, end, destination):132 other_url = url.get('url', '')
131 message = message[:begin] + destination + message[end:]133 picture_url = url.get('media_url', '')
134
135 # Friends has no notion of display URLs, so this is handled at the protocol level
136 if None not in (begin, end):
137 message = ''.join([
138 message[:begin],
139 '<a href="',
140 (expanded_url or display_url or other_url),
141 '">',
142 (display_url or expanded_url or other_url),
143 '</a>',
144 message[end:]])
132145
133 self._publish(146 self._publish(
134 message_id=tweet_id,147 message_id=tweet_id,
@@ -142,6 +155,7 @@
142 icon_uri=avatar_url.replace('_normal.', '.'),155 icon_uri=avatar_url.replace('_normal.', '.'),
143 liked=tweet.get('favorited', False),156 liked=tweet.get('favorited', False),
144 url=permalink,157 url=permalink,
158 link_picture=picture_url,
145 )159 )
146 return permalink160 return permalink
147161
148162
=== modified file 'friends/tests/data/twitter-home.dat'
--- friends/tests/data/twitter-home.dat 2012-10-13 01:27:15 +0000
+++ friends/tests/data/twitter-home.dat 2013-12-05 19:59:40 +0000
@@ -100,17 +100,18 @@
100 "id_str": "240556426106372096",100 "id_str": "240556426106372096",
101 "in_reply_to_user_id_str": null,101 "in_reply_to_user_id_str": null,
102 "entities": {102 "entities": {
103 "urls": [103 "media":[{"type":"photo",
104 {104 "sizes":{
105 "expanded_url": "http://blogs.ischool.berkeley.edu/i290-abdt-s12/",105 "thumb":{"h":150, "resize":"crop", "w":150},
106 "url": "http://t.co/bfj7zkDJ",106 "large":{"h":238, "resize":"fit", "w":226},
107 "indices": [107 "medium":{"h":238, "resize":"fit", "w":226},
108 79,108 "small":{"h":238, "resize":"fit", "w":226}},
109 99109 "indices":[78,98], "url":"http://t.co/rJC5Pxsu",
110 ],110 "media_url":"http://p.twimg.com/AZVLmp-CIAAbkyy.jpg",
111 "display_url": "blogs.ischool.berkeley.edu/i290-abdt-s12/"111 "display_url":"pic.twitter.com\/rJC5Pxsu",
112 }112 "id":114080493040967680, "id_str":"114080493040967680",
113 ],113 "expanded_url": "http://twitter.com/yunorno/status/114080493036773378/photo/1",
114 "media_url_https":"https://p.twimg.com/AZVLmp-CIAAbkyy.jpg"}],
114 "hashtags": [115 "hashtags": [
115116
116 ],117 ],
@@ -137,7 +138,7 @@
137 }138 }
138 ]139 ]
139 },140 },
140 "text": "lecturing at the \"analyzing big data with twitter\" class at @cal with @othman http://t.co/bfj7zkDJ",141 "text": "lecturing at the \"analyzing big data with twitter\" class at @cal with @othman http://t.co/rJC5Pxsu",
141 "contributors": null,142 "contributors": null,
142 "id": 240556426106372096,143 "id": 240556426106372096,
143 "retweet_count": 3,144 "retweet_count": 3,
144145
=== modified file 'friends/tests/test_twitter.py'
--- friends/tests/test_twitter.py 2013-11-01 17:27:51 +0000
+++ friends/tests/test_twitter.py 2013-12-05 19:59:40 +0000
@@ -133,6 +133,7 @@
133 self.assertEqual(3, TestModel.get_n_rows())133 self.assertEqual(3, TestModel.get_n_rows())
134134
135 # This test data was ripped directly from Twitter's API docs.135 # This test data was ripped directly from Twitter's API docs.
136
136 expected = [137 expected = [
137 ['twitter', 88, '240558470661799936',138 ['twitter', 88, '240558470661799936',
138 'messages', 'OAuth Dancer', '119476949', 'oauth_dancer', False,139 'messages', 'OAuth Dancer', '119476949', 'oauth_dancer', False,
@@ -144,13 +145,13 @@
144 ['twitter', 88, '240556426106372096',145 ['twitter', 88, '240556426106372096',
145 'messages', 'Raffi Krikorian', '8285392', 'raffi', False,146 'messages', 'Raffi Krikorian', '8285392', 'raffi', False,
146 '2012-08-28T21:08:15Z', 'lecturing at the "analyzing big data '147 '2012-08-28T21:08:15Z', 'lecturing at the "analyzing big data '
147 'with twitter" class at @cal with @othman '148 'with twitter" class at @cal with @othman '
148 '<a href="http://blogs.ischool.berkeley.edu/i290-abdt-s12/">'149 '<a href="http://twitter.com/yunorno/status/114080493036773378/photo/1">'
149 'http://blogs.ischool.berkeley.edu/i290-abdt-s12/</a>',150 'pic.twitter.com/rJC5Pxsu</a>',
150 'https://si0.twimg.com/profile_images/1270234259/'151 'https://si0.twimg.com/profile_images/1270234259/'
151 'raffi-headshot-casual.png',152 'raffi-headshot-casual.png',
152 'https://twitter.com/raffi/status/240556426106372096',153 'https://twitter.com/raffi/status/240556426106372096',
153 0, False, '', '', '', '', '', '', '', 0.0, 0.0,154 0, False, 'http://p.twimg.com/AZVLmp-CIAAbkyy.jpg', '', '', '', '', '', '', 0.0, 0.0,
154 ],155 ],
155 ['twitter', 88, '240539141056638977',156 ['twitter', 88, '240539141056638977',
156 'messages', 'Taylor Singletary', '819797', 'episod', False,157 'messages', 'Taylor Singletary', '819797', 'episod', False,
@@ -313,6 +314,7 @@
313 liked=False, sender='Bob', stream='private',314 liked=False, sender='Bob', stream='private',
314 url='https://twitter.com/some_guy/status/1452456',315 url='https://twitter.com/some_guy/status/1452456',
315 icon_uri='https://example.com/bob.jpg',316 icon_uri='https://example.com/bob.jpg',
317 link_picture='',
316 sender_nick='some_guy', sender_id='', from_me=False,318 sender_nick='some_guy', sender_id='', from_me=False,
317 timestamp='2012-11-04T17:14:52Z', message='Does my avatar show up?',319 timestamp='2012-11-04T17:14:52Z', message='Does my avatar show up?',
318 message_id='1452456')320 message_id='1452456')

Subscribers

People subscribed via source and target branches

to all changes: