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. 34
      mitterlib/network/__init__.py
  3. 112
      mitterlib/network/networkbase.py
  4. 61
      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
------------------------------------------------- -------------------------------------------------

34
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."""
@ -330,26 +319,3 @@ class Networks(object):
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

112
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 Some networks will return the original
user in a separate table (Twitter, in this case, returns 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 message with the original user in a "retweeted_status" structure.) In
this case, the network layer must return the original user in *author* this case, the network layer must return the original user in *author*
while the friend will be in *reposted_by*. *Optional* while the friend will be in *reposted_by*. *Optional*"""
**network** self.protected = False
The network id source of the message. Network classes don't need to """Boolean indicating if the message is protected/private or not."""
worry about this field themselves; :class:`Networks` will set it when
merging information from all networks. *Networks should NEVER fill
this field*
**protected** self.deletable = False
Boolean indicating if the message is protected/private or not. """Boolean indicating if the message can be deleted."""
.. [*] Not all fields need to be filled if that would require more than self.replyable = False
one network call. """Boolean indicating if the message can be replied."""
.. [*] Interfaces should be aware that optional fields may not be filled.
""" 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
@ -298,20 +297,3 @@ class NetworkBase(object):
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

61
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."""
@ -505,25 +510,3 @@ class Connection(NetworkBase):
_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