|
|
@ -105,14 +105,6 @@ def _to_datetime(server_str): |
|
|
|
return datetime.datetime(year, month, day, hour, minute, second) |
|
|
|
return datetime.datetime(year, month, day, hour, minute, second) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _make_datetime(response): |
|
|
|
|
|
|
|
"""Converts dates on responses to datetime objects.""" |
|
|
|
|
|
|
|
result = [] |
|
|
|
|
|
|
|
for tweet in response: |
|
|
|
|
|
|
|
result.append(TwitterNetworkData(tweet)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TwitterNetworkUser(NetworkUser): |
|
|
|
class TwitterNetworkUser(NetworkUser): |
|
|
|
"""A simple wrapper around :class:`NetwokrUser`, to make things easier to |
|
|
|
"""A simple wrapper around :class:`NetwokrUser`, to make things easier to |
|
|
|
convert twitter user information into a NetworkUser object.""" |
|
|
|
convert twitter user information into a NetworkUser object.""" |
|
|
@ -186,6 +178,14 @@ class Connection(NetworkBase): |
|
|
|
NAMESPACE = 'Twitter' |
|
|
|
NAMESPACE = 'Twitter' |
|
|
|
SHORTCUT = 'tw' # TODO: find a way to move this to the config file |
|
|
|
SHORTCUT = 'tw' # TODO: find a way to move this to the config file |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, options): |
|
|
|
|
|
|
|
self._options = options |
|
|
|
|
|
|
|
self._user = None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#------------------------------------------------------------ |
|
|
|
|
|
|
|
# Properties |
|
|
|
|
|
|
|
#------------------------------------------------------------ |
|
|
|
|
|
|
|
|
|
|
|
@property |
|
|
|
@property |
|
|
|
def is_setup(self): |
|
|
|
def is_setup(self): |
|
|
|
"""Return True or False if the network is setup/enabled.""" |
|
|
|
"""Return True or False if the network is setup/enabled.""" |
|
|
@ -213,10 +213,6 @@ class Connection(NetworkBase): |
|
|
|
_log.debug("User: %s" % (self._user)) |
|
|
|
_log.debug("User: %s" % (self._user)) |
|
|
|
return self._user |
|
|
|
return self._user |
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, options): |
|
|
|
|
|
|
|
self._options = options |
|
|
|
|
|
|
|
self._user = None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property |
|
|
|
@property |
|
|
|
def server(self): |
|
|
|
def server(self): |
|
|
|
if self._options[self.NAMESPACE]['https']: |
|
|
|
if self._options[self.NAMESPACE]['https']: |
|
|
@ -224,6 +220,11 @@ class Connection(NetworkBase): |
|
|
|
else: |
|
|
|
else: |
|
|
|
return self._options[self.NAMESPACE]['server_url'] |
|
|
|
return self._options[self.NAMESPACE]['server_url'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#------------------------------------------------------------ |
|
|
|
|
|
|
|
# Private functions |
|
|
|
|
|
|
|
#------------------------------------------------------------ |
|
|
|
|
|
|
|
|
|
|
|
def _common_headers(self): |
|
|
|
def _common_headers(self): |
|
|
|
"""Returns a string with the normal headers we should add on every |
|
|
|
"""Returns a string with the normal headers we should add on every |
|
|
|
request""" |
|
|
|
request""" |
|
|
@ -299,61 +300,12 @@ class Connection(NetworkBase): |
|
|
|
|
|
|
|
|
|
|
|
return json.loads(data) |
|
|
|
return json.loads(data) |
|
|
|
|
|
|
|
|
|
|
|
# |
|
|
|
def _make_datetime(self, response): |
|
|
|
# New network style methods |
|
|
|
"""Converts dates on responses to datetime objects.""" |
|
|
|
# |
|
|
|
result = [] |
|
|
|
|
|
|
|
for tweet in response: |
|
|
|
AUTH = [ |
|
|
|
result.append(TwitterNetworkData(tweet, self.user.username)) |
|
|
|
{'name': 'username', |
|
|
|
return result |
|
|
|
'flags': ['-u', '--username'], |
|
|
|
|
|
|
|
'prompt': _('Username'), |
|
|
|
|
|
|
|
'help': _('Your twitter username'), |
|
|
|
|
|
|
|
'type': 'str'}, |
|
|
|
|
|
|
|
{'name': 'password', |
|
|
|
|
|
|
|
'flags': ['-p', '--password'], |
|
|
|
|
|
|
|
'prompt': _('Password'), |
|
|
|
|
|
|
|
'help': _('Your twitter password'), |
|
|
|
|
|
|
|
'type': 'passwd'}] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
|
|
|
|
def options(self, options): |
|
|
|
|
|
|
|
"""Add options related to Twitter.""" |
|
|
|
|
|
|
|
# Rememeber to update the CHEAT-CODES file if you add/remove any |
|
|
|
|
|
|
|
# options. |
|
|
|
|
|
|
|
options.add_group(self.NAMESPACE, 'Twitter network') |
|
|
|
|
|
|
|
options.add_option('-s', '--no-https', |
|
|
|
|
|
|
|
group=self.NAMESPACE, |
|
|
|
|
|
|
|
option='https', |
|
|
|
|
|
|
|
default=True, # Secure connections by default |
|
|
|
|
|
|
|
help=_('Disable HTTPS (secure) connection with Twitter.'), |
|
|
|
|
|
|
|
action='store_false') |
|
|
|
|
|
|
|
options.add_option( |
|
|
|
|
|
|
|
group=self.NAMESPACE, |
|
|
|
|
|
|
|
option='last_tweet', |
|
|
|
|
|
|
|
default=0, |
|
|
|
|
|
|
|
is_cmd_option=False) |
|
|
|
|
|
|
|
options.add_option( |
|
|
|
|
|
|
|
group=self.NAMESPACE, |
|
|
|
|
|
|
|
option='last_reply', |
|
|
|
|
|
|
|
default=0, |
|
|
|
|
|
|
|
is_cmd_option=False) |
|
|
|
|
|
|
|
options.add_option( |
|
|
|
|
|
|
|
group=self.NAMESPACE, |
|
|
|
|
|
|
|
option='server_url', |
|
|
|
|
|
|
|
default='http://api.twitter.com/1', |
|
|
|
|
|
|
|
is_cmd_option=False) |
|
|
|
|
|
|
|
options.add_option( |
|
|
|
|
|
|
|
group=self.NAMESPACE, |
|
|
|
|
|
|
|
option='secure_server_url', |
|
|
|
|
|
|
|
default='https://api.twitter.com/1', |
|
|
|
|
|
|
|
is_cmd_option=False) |
|
|
|
|
|
|
|
options.add_option( |
|
|
|
|
|
|
|
group=self.NAMESPACE, |
|
|
|
|
|
|
|
option='message_threshold', |
|
|
|
|
|
|
|
default=16, |
|
|
|
|
|
|
|
is_cmd_option=False) |
|
|
|
|
|
|
|
auth_options(self.NAMESPACE, options, self.AUTH) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _timeline(self, config_var, url): |
|
|
|
def _timeline(self, config_var, url): |
|
|
|
"""Request one of the lists of tweets.""" |
|
|
|
"""Request one of the lists of tweets.""" |
|
|
@ -392,7 +344,7 @@ class Connection(NetworkBase): |
|
|
|
if top_tweet_id > high_id: |
|
|
|
if top_tweet_id > high_id: |
|
|
|
high_id = top_tweet_id |
|
|
|
high_id = top_tweet_id |
|
|
|
|
|
|
|
|
|
|
|
response_data = _make_datetime(response) |
|
|
|
response_data = self._make_datetime(response) |
|
|
|
result.extend(response_data) |
|
|
|
result.extend(response_data) |
|
|
|
page += 1 # Request the next page |
|
|
|
page += 1 # Request the next page |
|
|
|
|
|
|
|
|
|
|
@ -416,6 +368,66 @@ class Connection(NetworkBase): |
|
|
|
|
|
|
|
|
|
|
|
return result |
|
|
|
return result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#------------------------------------------------------------ |
|
|
|
|
|
|
|
# Network Options |
|
|
|
|
|
|
|
#------------------------------------------------------------ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AUTH = [ |
|
|
|
|
|
|
|
{'name': 'username', |
|
|
|
|
|
|
|
'flags': ['-u', '--username'], |
|
|
|
|
|
|
|
'prompt': _('Username'), |
|
|
|
|
|
|
|
'help': _('Your twitter username'), |
|
|
|
|
|
|
|
'type': 'str'}, |
|
|
|
|
|
|
|
{'name': 'password', |
|
|
|
|
|
|
|
'flags': ['-p', '--password'], |
|
|
|
|
|
|
|
'prompt': _('Password'), |
|
|
|
|
|
|
|
'help': _('Your twitter password'), |
|
|
|
|
|
|
|
'type': 'passwd'}] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
|
|
|
|
def options(self, options): |
|
|
|
|
|
|
|
"""Add options related to Twitter.""" |
|
|
|
|
|
|
|
# Rememeber to update the CHEAT-CODES file if you add/remove any |
|
|
|
|
|
|
|
# options. |
|
|
|
|
|
|
|
options.add_group(self.NAMESPACE, 'Twitter network') |
|
|
|
|
|
|
|
options.add_option('-s', '--no-https', |
|
|
|
|
|
|
|
group=self.NAMESPACE, |
|
|
|
|
|
|
|
option='https', |
|
|
|
|
|
|
|
default=True, # Secure connections by default |
|
|
|
|
|
|
|
help=_('Disable HTTPS (secure) connection with Twitter.'), |
|
|
|
|
|
|
|
action='store_false') |
|
|
|
|
|
|
|
options.add_option( |
|
|
|
|
|
|
|
group=self.NAMESPACE, |
|
|
|
|
|
|
|
option='last_tweet', |
|
|
|
|
|
|
|
default=0, |
|
|
|
|
|
|
|
is_cmd_option=False) |
|
|
|
|
|
|
|
options.add_option( |
|
|
|
|
|
|
|
group=self.NAMESPACE, |
|
|
|
|
|
|
|
option='last_reply', |
|
|
|
|
|
|
|
default=0, |
|
|
|
|
|
|
|
is_cmd_option=False) |
|
|
|
|
|
|
|
options.add_option( |
|
|
|
|
|
|
|
group=self.NAMESPACE, |
|
|
|
|
|
|
|
option='server_url', |
|
|
|
|
|
|
|
default='http://api.twitter.com/1', |
|
|
|
|
|
|
|
is_cmd_option=False) |
|
|
|
|
|
|
|
options.add_option( |
|
|
|
|
|
|
|
group=self.NAMESPACE, |
|
|
|
|
|
|
|
option='secure_server_url', |
|
|
|
|
|
|
|
default='https://api.twitter.com/1', |
|
|
|
|
|
|
|
is_cmd_option=False) |
|
|
|
|
|
|
|
options.add_option( |
|
|
|
|
|
|
|
group=self.NAMESPACE, |
|
|
|
|
|
|
|
option='message_threshold', |
|
|
|
|
|
|
|
default=16, |
|
|
|
|
|
|
|
is_cmd_option=False) |
|
|
|
|
|
|
|
auth_options(self.NAMESPACE, options, self.AUTH) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#------------------------------------------------------------ |
|
|
|
|
|
|
|
# NetworkBase required functions |
|
|
|
|
|
|
|
#------------------------------------------------------------ |
|
|
|
|
|
|
|
|
|
|
|
def messages(self): |
|
|
|
def messages(self): |
|
|
|
"""Return a list of NetworkData objects for the main "timeline".""" |
|
|
|
"""Return a list of NetworkData objects for the main "timeline".""" |
|
|
|
return self._timeline('last_tweet', '/statuses/home_timeline.json') |
|
|
|
return self._timeline('last_tweet', '/statuses/home_timeline.json') |
|
|
@ -423,8 +435,7 @@ 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.user.username) |
|
|
|
self._options[self.NAMESPACE]['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 |
|
|
@ -474,8 +485,7 @@ 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.user.username) |
|
|
|
self._options[self.NAMESPACE]['username']) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def repost(self, message): |
|
|
|
def repost(self, message): |
|
|
|
"""Repost a message.""" |
|
|
|
"""Repost a message.""" |
|
|
@ -483,8 +493,7 @@ 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.user.username) |
|
|
|
self._options[self.NAMESPACE]['username']) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def favourite(self, message): |
|
|
|
def favourite(self, message): |
|
|
|
"""Mark a message as favourite.""" |
|
|
|
"""Mark a message as favourite.""" |
|
|
@ -495,8 +504,7 @@ 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.user.username) |
|
|
|
self._options[self.NAMESPACE]['username']) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def delete_message(self, message): |
|
|
|
def delete_message(self, message): |
|
|
|
"""Delete a message.""" |
|
|
|
"""Delete a message.""" |
|
|
@ -509,4 +517,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. |
|
|
|