Browse Source

reply_prefix(), link(), can_repost(), can_reply(), can_delete() and

can_favourite() were removed in favour of a properties in the
NetworkData object (since those values wouldn't change for a message.)
master
Julio Biason 15 years ago
parent
commit
c6f6cedab3
  1. 5
      docs/networkbase.rst
  2. 36
      mitterlib/network/__init__.py
  3. 124
      mitterlib/network/networkbase.py
  4. 63
      mitterlib/network/twitter.py

5
docs/networkbase.rst

@ -3,6 +3,11 @@
.. automodule:: networkbase .. automodule:: networkbase
NetworkUser -- Unified information about users
----------------------------------------------
.. autoclass:: NetworkUser
NetworkData -- Unified information about messages NetworkData -- Unified information about messages
------------------------------------------------- -------------------------------------------------

36
mitterlib/network/__init__.py

@ -252,12 +252,6 @@ class Networks(object):
self._save() self._save()
return results return results
def reply_prefix(self, message):
"""Return the prefix to be used in the reply for that message."""
assert(isinstance(message, NetworkData))
self._proxy()
return self.networks[message.network].reply_prefix(message)
def repost(self, message): def repost(self, message):
"""Repost a message in the user's timeline. The network used is """Repost a message in the user's timeline. The network used is
the same in the message.""" the same in the message."""
@ -304,11 +298,6 @@ class Networks(object):
self._save() self._save()
return data return data
def link(self, message):
"""Returns a link directly to the message."""
assert(isinstance(message, NetworkData))
return self.networks[message.network].link(message)
def replies(self, network=None): def replies(self, network=None):
"""Return a list of NetworkData objects for the replies for the user """Return a list of NetworkData objects for the replies for the user
messages.""" messages."""
@ -329,27 +318,4 @@ class Networks(object):
for shortcut in self._targets(network): for shortcut in self._targets(network):
requests = self.networks[shortcut].available_requests() requests = self.networks[shortcut].available_requests()
result[shortcut] = requests result[shortcut] = requests
return result return result
def can_delete(self, message):
"""Return True if the message can be deleted; False otherwise."""
assert(isinstance(message, NetworkData))
return self.networks[message.network].can_delete(message)
def can_reply(self, message):
"""Return True if the message can be replied; False otherwise."""
assert(isinstance(message, NetworkData))
return self.networks[message.network].can_reply(message)
def can_repost(self, message):
"""Return True if the message can be resposted; False otherwise."""
assert(isinstance(message, NetworkData))
return self.networks[message.network].can_repost(message)
def can_favourite(self, message):
"""Return True if the message can be favourited/unfavourited; False
otherwise."""
assert(isinstance(message, NetworkData))
return self.networks[message.network].can_favourite(message)
# TODO: Function to return a regexp for usernames

124
mitterlib/network/networkbase.py

@ -122,66 +122,71 @@ class NetworkUser(object):
class NetworkData(object): class NetworkData(object):
"""Provides an uniform way to access information about posts. The """Provides an uniform way to access information about posts."""
following fields should appear [*]_ [*]_:
**id** def __init__(self):
The message identification. *Optional* self.id = ''
"""The message identification. *Optional*"""
**author** self.author = None
Author of the message. A :class:`NetworkUser` object. """Author of the message. A :class:`NetworkUser` object.
*Required*"""
**message** self.message = ''
The message. *Required* """The message. *Required*"""
**message_time** self.message_time = None
Message timestamp (as a datetime object). Defaults to None. *Optional* """Message timestamp (as a datetime object). Defaults to None.
*Optional*"""
**favourite** self.favourite = False
Boolean indicating if the message was marked as "favourite" or not. """Boolean indicating if the message was marked as "favourite" or not.
*Optional* *Optional*"""
**parent** self.parent = None
The parent of this message, in case of a reply. *Optional* """The parent of this message, in case of a reply. *Optional*"""
**parent_owner** self.parent_owner = None
Owner of the parent message (in other words, "in reply to".) It will be """Owner of the parent message (in other words, "in reply to".)
a :class:`NetworkUser` object. *Optional* It will be a :class:`NetworkUser` object. *Optional*"""
**reposted_by** self.reposted_by = None
Author of the reposted message. A :class:`NetworkUser` object. """Author of the reposted message. A :class:`NetworkUser` object.
Some networks will return the original
user in a separate table (Twitter, in this case, returns the original
message with the original user in a "retweeted_status" structure.) In
this case, the network layer must return the original user in *author*
while the friend will be in *reposted_by*. *Optional*
**network** Some networks will return the original
The network id source of the message. Network classes don't need to user in a separate table (Twitter, in this case, returns the original
worry about this field themselves; :class:`Networks` will set it when message with the original user in a "retweeted_status" structure.) In
merging information from all networks. *Networks should NEVER fill this case, the network layer must return the original user in *author*
this field* while the friend will be in *reposted_by*. *Optional*"""
**protected** self.protected = False
Boolean indicating if the message is protected/private or not. """Boolean indicating if the message is protected/private or not."""
.. [*] Not all fields need to be filled if that would require more than self.deletable = False
one network call. """Boolean indicating if the message can be deleted."""
.. [*] Interfaces should be aware that optional fields may not be filled.
""" self.replyable = False
"""Boolean indicating if the message can be replied."""
self.repostable = False
"""Boolean indicating if the message can be reposted."""
self.favoritable = False
"""Boolean indicating if the message can be favorited."""
self.link = None
"""Link to the original message."""
self.reply_prefix = ''
"""Prefix to be used in messages when replying to this message."""
def __init__(self):
self.id = ''
self.author = None
self.message = ''
self.message_time = None
self.favourite = False
self.parent = None
self.parent_owner = None
self.reposted_by = None
self.network = '' self.network = ''
self.protected = False """The network id source of the message. Network classes don't need to
worry about this field themselves; :class:`Networks` will set it when
merging information from all networks. *Networks should NEVER fill
this field*"""
return
class NetworkBase(object): class NetworkBase(object):
@ -250,12 +255,6 @@ class NetworkBase(object):
# anyway? # anyway?
return None return None
def reply_prefix(self, message):
"""Return the prefix to be used in case the user requests a reply for
that message. *message* must be a :class:`NetworkData` object. Returns
a string."""
return ''
def repost(self, message): def repost(self, message):
"""Repost a message in your current timeline. *message* must be a """Repost a message in your current timeline. *message* must be a
valid :class:`NetworkData` object. Must return the id of the new valid :class:`NetworkData` object. Must return the id of the new
@ -297,21 +296,4 @@ class NetworkBase(object):
"""Return the number of requests the user can request before being """Return the number of requests the user can request before being
capped. If such limitation doesn't exist for the network, a negative capped. If such limitation doesn't exist for the network, a negative
number should be returned.""" number should be returned."""
return -1 return -1
def can_delete(self, message):
"""Return True if the message can be deleted; False otherwise."""
return False
def can_reply(self, message):
"""Return True if the message can be replied; False otherwise."""
return False
def can_repost(self, message):
"""Return True if the message can be resposted; False otherwise."""
return False
def can_favourite(self, message):
"""Return True if the message can be favourited/unfavourited; False
otherwise."""
return False

63
mitterlib/network/twitter.py

@ -118,6 +118,7 @@ class TwitterNetworkUser(NetworkUser):
convert twitter user information into a NetworkUser object.""" convert twitter user information into a NetworkUser object."""
def __init__(self, data): def __init__(self, data):
super(TwitterNetworkUser, self).__init__()
self.name = data['user']['name'] self.name = data['user']['name']
self.username = data['user']['screen_name'] self.username = data['user']['screen_name']
self.avatar = data['user']['profile_image_url'] self.avatar = data['user']['profile_image_url']
@ -127,14 +128,25 @@ 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
twitter data into a NetworkData object.""" twitter data into a NetworkData object."""
def __init__(self, data): def __init__(self, data, logged_user):
"""Class initialization. Receives a dictionary with a single tweet.""" """Class initialization. Receives a dictionary with a single tweet."""
NetworkData.__init__(self) super(TwitterNetworkData, self).__init__()
self.id = data['id'] self.id = data['id']
self.author = TwitterNetworkUser(data) self.author = TwitterNetworkUser(data)
self.message_time = _to_datetime(data['created_at']) self.message_time = _to_datetime(data['created_at'])
self.replyable = True # All messages are replyables
self.favoritable = True # All messages are favoritable
self.repostable = not (self.author.username == logged_user)
self.deletable = (self.author.username == logged_user)
self.link = 'http://twitter.com/%s/status/%s' % (
self.author.username, self.id)
self.reply_prefx = '@' + self.author.username + ' '
if 'protected' in data['user']: if 'protected' in data['user']:
# twitter protects all messages from a user, not per message. # twitter protects all messages from a user, not per message.
self.protected = data['user']['protected'] self.protected = data['user']['protected']
@ -411,18 +423,8 @@ class Connection(NetworkBase):
def message(self, message_id): def message(self, message_id):
"""Retrieves the information of one message.""" """Retrieves the information of one message."""
response = self._request('/statuses/show/%d.json' % (message_id)) response = self._request('/statuses/show/%d.json' % (message_id))
return TwitterNetworkData(response) return TwitterNetworkData(response,
self._options[self.NAMESPACE]['username'])
def link(self, message):
"""Return a link directly to the message."""
assert(isinstance(message, NetworkData))
return 'http://twitter.com/%s/status/%s' % (message.author.username,
message.id)
def reply_prefix(self, message):
"""Returns the prefix needed for a reply."""
assert(isinstance(message, NetworkData))
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
@ -472,7 +474,8 @@ class Connection(NetworkBase):
# too large. # too large.
# TODO: Some updates return the previous status, not the new one. Not # TODO: Some updates return the previous status, not the new one. Not
# sure what that means. # sure what that means.
return TwitterNetworkData(data) return TwitterNetworkData(data,
self._options[self.NAMESPACE]['username'])
def repost(self, message): def repost(self, message):
"""Repost a message.""" """Repost a message."""
@ -480,7 +483,8 @@ class Connection(NetworkBase):
body = urllib.urlencode({'id': message.id}) body = urllib.urlencode({'id': message.id})
resource = '/statuses/retweet/%d.json' % (message.id) resource = '/statuses/retweet/%d.json' % (message.id)
data = self._request(resource, body=body) data = self._request(resource, body=body)
return TwitterNetworkData(data) return TwitterNetworkData(data,
self._options[self.NAMESPACE]['username'])
def favourite(self, message): def favourite(self, message):
"""Mark a message as favourite.""" """Mark a message as favourite."""
@ -491,7 +495,8 @@ class Connection(NetworkBase):
else: else:
resource = '/favorites/destroy/%d.json' % (message.id) resource = '/favorites/destroy/%d.json' % (message.id)
data = self._request(resource, body=body) data = self._request(resource, body=body)
return TwitterNetworkData(data) return TwitterNetworkData(data,
self._options[self.NAMESPACE]['username'])
def delete_message(self, message): def delete_message(self, message):
"""Delete a message.""" """Delete a message."""
@ -504,26 +509,4 @@ class Connection(NetworkBase):
response = self._request(resource, body=body) response = self._request(resource, body=body)
_log.debug('Delete response: %s', response) _log.debug('Delete response: %s', response)
return True # Either we get a response or an exception before we reach return True # Either we get a response or an exception before we reach
# this. # this.
def can_delete(self, message):
"""Check if the message belongs to the user. If so, returns True;
False otherwise."""
assert(isinstance(message, NetworkData))
return (message.author.username ==
self._options[self.NAMESPACE]['username'])
def can_reply(self, message):
"""Always return True; Twitter allows replying to any messages,
including the ones from the user."""
return True
def can_repost(self, message):
"""Twitter ignores retweets from the user."""
assert(isinstance(message, NetworkData))
return not (message.author.username ==
self._options[self.NAMESPACE]['username'])
def can_favourite(self, message):
"""Always return True; Twitter allows favouriting/unfavouriting any
messages."""
return True
Loading…
Cancel
Save