Browse Source

Created a NetworkUser object, to be used by NetworkData and to

NetworkBase, so every protocol can have an attached information about
the user.
master
Julio Biason 15 years ago
parent
commit
b7f5cfd696
  1. 52
      mitterlib/network/networkbase.py
  2. 40
      mitterlib/network/twitter.py
  3. 21
      mitterlib/ui/ui_pygtk.py

52
mitterlib/network/networkbase.py

@ -105,12 +105,9 @@ class MessageTooLongWarning(NetworkWarning):
# The classes # The classes
#-------------------------------------------------------------------- #--------------------------------------------------------------------
class NetworkData(object): class NetworkUser(object):
"""Provides an uniform way to access information about posts. The """Provides an uniform way to access information about users. The
following fields should appear [*]_ [*]_: following fields should appear:
**id**
The message identification. *Optional*
**name** **name**
The name to be displayed as author of the message. *Required* The name to be displayed as author of the message. *Required*
@ -120,6 +117,22 @@ class NetworkData(object):
**avatar** **avatar**
URL to the author avatar. *Optional* URL to the author avatar. *Optional*
"""
def __init__(self):
self.name = ''
self.username = ''
self.avatar = ''
class NetworkData(object):
"""Provides an uniform way to access information about posts. The
following fields should appear [*]_ [*]_:
**id**
The message identification. *Optional*
**author**
Author of the message. A :class:`NetworkUser` object.
**message** **message**
The message. *Required* The message. *Required*
@ -135,16 +148,17 @@ class NetworkData(object):
The parent of this message, in case of a reply. *Optional* The parent of this message, in case of a reply. *Optional*
**parent_owner** **parent_owner**
Username of the owner of the parent message (in other words, "in reply Owner of the parent message (in other words, "in reply to".) It will be
to".) *Optional* a :class:`NetworkUser` object. *Optional*
**reposted_by** **reposted_by**
Username friend of the current user that reposted that message. Some Author of the reposted message. A :class:`NetworkUser` object.
networks will return the original user in a separate table (Twitter,
in this case, returns the original message with the original user Some networks will return the original
in a "retweeted_status" structure.) In this case, the network layer user in a separate table (Twitter, in this case, returns the original
will must return the original user in *name*, *username* and *avatar*, message with the original user in a "retweeted_status" structure.) In
while the friend username will be moved to *reposted_by*. *Optional* this case, the network layer must return the original user in *author*
while the friend will be in *reposted_by*. *Optional*
**network** **network**
The network id source of the message. Network classes don't need to The network id source of the message. Network classes don't need to
@ -162,15 +176,13 @@ class NetworkData(object):
def __init__(self): def __init__(self):
self.id = '' self.id = ''
self.name = '' self.author = None
self.username = ''
self.avatar = ''
self.message = '' self.message = ''
self.message_time = None self.message_time = None
self.favourite = False self.favourite = False
self.parent = '' self.parent = None
self.parent_owner = '' self.parent_owner = None
self.reposted_by = '' self.reposted_by = None
self.network = '' self.network = ''
self.protected = False self.protected = False

40
mitterlib/network/twitter.py

@ -30,7 +30,7 @@ import gettext
from httplib import BadStatusLine from httplib import BadStatusLine
from socket import error as socketError from socket import error as socketError
from networkbase import NetworkBase, NetworkData, auth_options, \ from networkbase import NetworkBase, NetworkData, NetworkUser, auth_options, \
NetworkDNSError, NetworkBadStatusLineError, NetworkLowLevelError, \ NetworkDNSError, NetworkBadStatusLineError, NetworkLowLevelError, \
NetworkInvalidResponseError, NetworkPermissionDeniedError, \ NetworkInvalidResponseError, NetworkPermissionDeniedError, \
MessageTooLongWarning MessageTooLongWarning
@ -113,6 +113,15 @@ def _make_datetime(response):
return result return result
class TwitterNetworkUser(NetworkUser):
"""A simple wrapper around :class:`NetwokrUser`, to make things easier to
convert twitter user information into a NetworkUser object."""
def __init__(self, data):
self.name = data['user']['name']
self.username = data['user']['screen_name']
self.avatar = data['user']['profile_image_url']
class TwitterNetworkData(NetworkData): class TwitterNetworkData(NetworkData):
"""A simple wrapper around NetworkData, to make things easier to convert """A simple wrapper around NetworkData, to make things easier to convert
@ -123,9 +132,7 @@ class TwitterNetworkData(NetworkData):
NetworkData.__init__(self) NetworkData.__init__(self)
self.id = data['id'] self.id = data['id']
self.name = data['user']['name'] self.author = TwitterNetworkUser(data)
self.username = data['user']['screen_name']
self.avatar = data['user']['profile_image_url']
self.message_time = _to_datetime(data['created_at']) self.message_time = _to_datetime(data['created_at'])
if 'protected' in data['user']: if 'protected' in data['user']:
@ -136,16 +143,14 @@ class TwitterNetworkData(NetworkData):
self.favourited = data['favorited'] self.favourited = data['favorited']
if 'in_reply_to_status_id' in data and data['in_reply_to_status_id']: if 'in_reply_to_status_id' in data and data['in_reply_to_status_id']:
owner = NetworkUser()
owner.username = data['in_reply_to_screen_name']
# TODO: Check if we have the other data.
self.parent = int(data['in_reply_to_status_id']) self.parent = int(data['in_reply_to_status_id'])
self.parent_owner = data['in_reply_to_screen_name']
if 'retweeted_status' in data: if 'retweeted_status' in data:
self.reposted_by = self.username self.reposted_by = self.author
self.author = TwitterNetworkUser(data['retweeted_status'])
retweet_user = data['retweeted_status']['user']
self.name = retweet_user['name']
self.username = retweet_user['screen_name']
self.avatar = retweet_user['profile_image_url']
self.id = data['retweeted_status']['id'] self.id = data['retweeted_status']['id']
# also switch the text for the original text. # also switch the text for the original text.
@ -393,13 +398,13 @@ class Connection(NetworkBase):
def link(self, message): def link(self, message):
"""Return a link directly to the message.""" """Return a link directly to the message."""
assert(isinstance(message, NetworkData)) assert(isinstance(message, NetworkData))
return 'http://twitter.com/%s/status/%s' % (message.username, return 'http://twitter.com/%s/status/%s' % (message.author.username,
message.id) message.id)
def reply_prefix(self, message): def reply_prefix(self, message):
"""Returns the prefix needed for a reply.""" """Returns the prefix needed for a reply."""
assert(isinstance(message, NetworkData)) assert(isinstance(message, NetworkData))
return '@' + message.username + ' ' return '@' + message.author.username + ' '
def replies(self): def replies(self):
"""Return a list of NetworkData objects for the replies for the user """Return a list of NetworkData objects for the replies for the user
@ -434,8 +439,8 @@ class Connection(NetworkBase):
# start with the username of the original user, we add it # start with the username of the original user, we add it
# for the user. # for the user.
if not status.startswith('@' + reply_to.username): if not status.startswith('@' + reply_to.author.username):
body['status'] = '@' + reply_to.username + ' ' + \ body['status'] = '@' + reply_to.author.username + ' ' + \
status status
else: else:
body['in_reply_to_status_id'] = reply_to body['in_reply_to_status_id'] = reply_to
@ -486,7 +491,8 @@ class Connection(NetworkBase):
"""Check if the message belongs to the user. If so, returns True; """Check if the message belongs to the user. If so, returns True;
False otherwise.""" False otherwise."""
assert(isinstance(message, NetworkData)) assert(isinstance(message, NetworkData))
return (message.username == self._options[self.NAMESPACE]['username']) return (message.author.username ==
self._options[self.NAMESPACE]['username'])
def can_reply(self, message): def can_reply(self, message):
"""Always return True; Twitter allows replying to any messages, """Always return True; Twitter allows replying to any messages,
@ -496,7 +502,7 @@ class Connection(NetworkBase):
def can_repost(self, message): def can_repost(self, message):
"""Twitter ignores retweets from the user.""" """Twitter ignores retweets from the user."""
assert(isinstance(message, NetworkData)) assert(isinstance(message, NetworkData))
return not (message.username == return not (message.author.username ==
self._options[self.NAMESPACE]['username']) self._options[self.NAMESPACE]['username'])
def can_favourite(self, message): def can_favourite(self, message):

21
mitterlib/ui/ui_pygtk.py

@ -608,7 +608,7 @@ class Interface(object):
userpic.""" userpic."""
data = store.get_value(position, 0) data = store.get_value(position, 0)
pic = data.avatar pic = data.author.avatar
cell.set_property('pixbuf', self._avatars[pic]) cell.set_property('pixbuf', self._avatars[pic])
return return
@ -625,8 +625,8 @@ class Interface(object):
# unescape escaped entities that pango is not okay with # unescape escaped entities that pango is not okay with
message_values['message'] = html_escape(data.message) message_values['message'] = html_escape(data.message)
message_values['username'] = html_escape(data.username) message_values['username'] = html_escape(data.author.username)
message_values['full_name'] = html_escape(data.name) message_values['full_name'] = html_escape(data.author.name)
message_values['message_age'] = time message_values['message_age'] = time
# highlight URLs # highlight URLs
@ -657,11 +657,11 @@ class Interface(object):
info = [] info = []
if data.reposted_by: if data.reposted_by:
info.append(_(' &#8212; <i>reposted by %s</i>') % info.append(_(' &#8212; <i>reposted by %s</i>') %
(data.reposted_by)) (data.reposted_by.username))
if data.parent_owner: if data.parent_owner:
info.append(_(' &#8212; <i>in reply to %s</i>') % info.append(_(' &#8212; <i>in reply to %s</i>') %
(data.parent_owner)) (data.parent_owner.username))
if data.protected: if data.protected:
message_values['protected_status'] = ( message_values['protected_status'] = (
@ -781,7 +781,7 @@ class Interface(object):
"""Using the results from the request, fill a gtk.Store.""" """Using the results from the request, fill a gtk.Store."""
for message in data: for message in data:
message.read = False message.read = False
pic = message.avatar pic = message.author.avatar
if not pic in self._avatars: if not pic in self._avatars:
# set the user avatar to the default image, so it won't get # set the user avatar to the default image, so it won't get
# queued again. Once downloaded, the _post_download_pic will # queued again. Once downloaded, the _post_download_pic will
@ -817,7 +817,8 @@ class Interface(object):
count = len(text) count = len(text)
if self._reply_message_id: if self._reply_message_id:
suffix = _('(replying to %s)') % (self._reply_message_id.username) suffix = _('(replying to %s)') % (
self._reply_message_id.author.username)
else: else:
suffix = '' suffix = ''
@ -1030,7 +1031,7 @@ class Interface(object):
(model, iter) = grid.get_selection().get_selected() (model, iter) = grid.get_selection().get_selected()
message = model.get_value(iter, 0) message = model.get_value(iter, 0)
self._update_statusbar(_('Reposting %s message...') % self._update_statusbar(_('Reposting %s message...') %
(message.username)) (message.author.username))
self._threads.add_work(self._post_repost_message, self._threads.add_work(self._post_repost_message,
self._exception_repost_message, self._exception_repost_message,
self._connection.repost, self._connection.repost,
@ -1049,7 +1050,7 @@ class Interface(object):
display = _('Removing message from %s from favorites...') display = _('Removing message from %s from favorites...')
else: else:
display = _('Marking message from %s as favorite...') display = _('Marking message from %s as favorite...')
self._update_statusbar(display % (message.username)) self._update_statusbar(display % (message.author.username))
self._threads.add_work(self._post_favourite_message, self._threads.add_work(self._post_favourite_message,
self._exception_favourite_message, self._exception_favourite_message,
self._connection.favourite, self._connection.favourite,
@ -1623,4 +1624,4 @@ class Interface(object):
'protected/private.', 'protected/private.',
metavar='CHAR', metavar='CHAR',
default=_('<small>(protected)</small>'), default=_('<small>(protected)</small>'),
is_cmd_option=False) is_cmd_option=False)

Loading…
Cancel
Save