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 14 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
NetworkUser -- Unified information about users
----------------------------------------------
.. autoclass:: NetworkUser
NetworkData -- Unified information about messages
-------------------------------------------------

36
mitterlib/network/__init__.py

@ -252,12 +252,6 @@ class Networks(object):
self._save()
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):
"""Repost a message in the user's timeline. The network used is
the same in the message."""
@ -304,11 +298,6 @@ class Networks(object):
self._save()
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):
"""Return a list of NetworkData objects for the replies for the user
messages."""
@ -329,27 +318,4 @@ class Networks(object):
for shortcut in self._targets(network):
requests = self.networks[shortcut].available_requests()
result[shortcut] = requests
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
return result

124
mitterlib/network/networkbase.py

@ -122,66 +122,71 @@ class NetworkUser(object):
class NetworkData(object):
"""Provides an uniform way to access information about posts. The
following fields should appear [*]_ [*]_:
"""Provides an uniform way to access information about posts."""
**id**
The message identification. *Optional*
def __init__(self):
self.id = ''
"""The message identification. *Optional*"""
**author**
Author of the message. A :class:`NetworkUser` object.
self.author = None
"""Author of the message. A :class:`NetworkUser` object.
*Required*"""
**message**
The message. *Required*
self.message = ''
"""The message. *Required*"""
**message_time**
Message timestamp (as a datetime object). Defaults to None. *Optional*
self.message_time = None
"""Message timestamp (as a datetime object). Defaults to None.
*Optional*"""
**favourite**
Boolean indicating if the message was marked as "favourite" or not.
*Optional*
self.favourite = False
"""Boolean indicating if the message was marked as "favourite" or not.
*Optional*"""
**parent**
The parent of this message, in case of a reply. *Optional*
self.parent = None
"""The parent of this message, in case of a reply. *Optional*"""
**parent_owner**
Owner of the parent message (in other words, "in reply to".) It will be
a :class:`NetworkUser` object. *Optional*
self.parent_owner = None
"""Owner of the parent message (in other words, "in reply to".)
It will be a :class:`NetworkUser` object. *Optional*"""
**reposted_by**
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*
self.reposted_by = None
"""Author of the reposted message. A :class:`NetworkUser` object.
**network**
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*
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*"""
**protected**
Boolean indicating if the message is protected/private or not.
self.protected = False
"""Boolean indicating if the message is protected/private or not."""
.. [*] Not all fields need to be filled if that would require more than
one network call.
.. [*] Interfaces should be aware that optional fields may not be filled.
"""
self.deletable = False
"""Boolean indicating if the message can be deleted."""
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.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):
@ -250,12 +255,6 @@ class NetworkBase(object):
# anyway?
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):
"""Repost a message in your current timeline. *message* must be a
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
capped. If such limitation doesn't exist for the network, a negative
number should be returned."""
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
return -1

63
mitterlib/network/twitter.py

@ -118,6 +118,7 @@ class TwitterNetworkUser(NetworkUser):
convert twitter user information into a NetworkUser object."""
def __init__(self, data):
super(TwitterNetworkUser, self).__init__()
self.name = data['user']['name']
self.username = data['user']['screen_name']
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
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."""
NetworkData.__init__(self)
super(TwitterNetworkData, self).__init__()
self.id = data['id']
self.author = TwitterNetworkUser(data)
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']:
# twitter protects all messages from a user, not per message.
self.protected = data['user']['protected']
@ -411,18 +423,8 @@ class Connection(NetworkBase):
def message(self, message_id):
"""Retrieves the information of one message."""
response = self._request('/statuses/show/%d.json' % (message_id))
return TwitterNetworkData(response)
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 + ' '
return TwitterNetworkData(response,
self._options[self.NAMESPACE]['username'])
def replies(self):
"""Return a list of NetworkData objects for the replies for the user
@ -472,7 +474,8 @@ class Connection(NetworkBase):
# too large.
# TODO: Some updates return the previous status, not the new one. Not
# sure what that means.
return TwitterNetworkData(data)
return TwitterNetworkData(data,
self._options[self.NAMESPACE]['username'])
def repost(self, message):
"""Repost a message."""
@ -480,7 +483,8 @@ class Connection(NetworkBase):
body = urllib.urlencode({'id': message.id})
resource = '/statuses/retweet/%d.json' % (message.id)
data = self._request(resource, body=body)
return TwitterNetworkData(data)
return TwitterNetworkData(data,
self._options[self.NAMESPACE]['username'])
def favourite(self, message):
"""Mark a message as favourite."""
@ -491,7 +495,8 @@ class Connection(NetworkBase):
else:
resource = '/favorites/destroy/%d.json' % (message.id)
data = self._request(resource, body=body)
return TwitterNetworkData(data)
return TwitterNetworkData(data,
self._options[self.NAMESPACE]['username'])
def delete_message(self, message):
"""Delete a message."""
@ -504,26 +509,4 @@ class Connection(NetworkBase):
response = self._request(resource, body=body)
_log.debug('Delete response: %s', response)
return True # Either we get a response or an exception before we reach
# 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
# this.
Loading…
Cancel
Save