-import requests
-import re
-import json
import diaspy.models
+import diaspy.streams
+import diaspy.connection
-class Client:
- """This is the client class to connect to diaspora.
+class Client:
+ """This is the client class to connect to Diaspora.
"""
-
def __init__(self, pod, username, password):
"""
:param pod: The complete url of the diaspora pod to use.
:type username: str
:param password: The password used to log in.
:type password: str
-
"""
- self._token_regex = re.compile(r'content="(.*?)"\s+name="csrf-token')
+ self.connection = diaspy.connection.Connection(pod, username, password)
+ self.connection.login()
self.pod = pod
- self.session = requests.Session()
- self._login(username, password)
-
- def get_token(self):
- """This function gets a token needed for authentication in most cases
-
- :returns: string -- token used to authenticate
-
- """
-
- r = self.session.get(self.pod + '/stream')
- token = self._token_regex.search(r.text).group(1)
- return token
+ self.stream = diaspy.streams.Stream(self.connection, 'stream.json')
- def _login(self, username, password):
- """This function is used to connect to the pod and log in.
- .. note::
- This function shouldn't be called manually.
- """
- self._username = username
- self._password = password
- r = self.session.get(self.pod + '/users/sign_in')
- token = self._token_regex.search(r.text).group(1)
-
- data = {'user[username]': self._username,
- 'user[password]': self._password,
- 'authenticity_token': token,
- 'commit': ''}
-
- r = self.session.post(self.pod +
- '/users/sign_in',
- data=data,
- headers={'accept': 'application/json'})
-
- if r.status_code != 201:
- raise Exception(str(r.status_code) + ': Login failed.')
-
- def post(self, text, aspect_id='public', photos=None):
+ def post(self, text, aspect_ids='public', photos=None):
"""This function sends a post to an aspect
:param text: Text to post.
:type text: str
- :param aspect_id: Aspect id to send post to.
- :type aspect_id: str
+ :param aspect_ids: Aspect ids to send post to.
+ :type aspect_ids: str
:returns: diaspy.models.Post -- the Post which has been created
-
- """
- data = {'aspect_ids': aspect_id,
- 'status_message': {'text': text}}
-
- if photos:
- data['photos'] = photos
- r = self.session.post(self.pod +
- "/status_messages",
- data=json.dumps(data),
- headers={'content-type': 'application/json',
- 'accept': 'application/json',
- 'x-csrf-token': self.get_token()})
- if r.status_code != 201:
- raise Exception(str(r.status_code) + ': Post could not be posted.')
-
- return diaspy.models.Post(str(r.json()['id']), self)
-
- def get_user_info(self):
- """This function returns the current user's attributes.
-
- :returns: dict -- json formatted user info.
-
"""
- r = self.session.get(self.pod + '/bookmarklet')
- regex = re.compile(r'window.current_user_attributes = ({.*})')
- userdata = json.loads(regex.search(r.text).group(1))
- return userdata
+ post = self.stream.post(text, aspect_ids, photos)
+ return post
def post_picture(self, filename):
- aspects = self.get_user_info()['aspects']
- params = {}
- params['photo[pending]'] = 'true'
- params['set_profile_image'] = ''
- params['qqfile'] = filename
- for i, aspect in enumerate(aspects):
- params['photo[aspect_ids][%d]' % (i)] = aspect['id']
-
- data = open(filename, 'rb')
-
- headers = {'content-type': 'application/octet-stream',
- 'x-csrf-token': self.get_token(),
- 'x-file-name': filename}
-
- r = self.session.post(self.pod + '/photos', params=params, data=data, headers=headers)
-
- return r
+ """This method posts a picture to D*.
+ :param filename: Path to picture file.
+ :type filename: str
+ """
+ return self.stream.post_picture(filename)
+ def get_activity(self):
+ """This function returns activity stream.
+ :returns: diaspy.streams.Activity
+ """
+ activity = diaspy.streams.Activity(self.connection, 'activity.json')
+ return activity
def get_stream(self):
- """This functions returns a list of posts found in the stream.
-
- :returns: list -- list of Post objects.
+ """This functions returns stream.
+ :returns: diaspy.streams.Stream
"""
-
- data = {'authenticity_token': self.get_token()}
- r = self.session.get(self.pod + "/stream.json")
-
- if r.status_code != 200:
- raise Exception('wrong status code: ' + str(r.status_code))
-
- stream = r.json()
-
- posts = []
-
- for post in stream:
- posts.append(diaspy.models.Post(str(post['id']), self))
-
- return posts
+ self.stream.update()
+ return self.stream
def get_notifications(self):
"""This functions returns a list of notifications.
:returns: list -- list of json formatted notifications
-
"""
-
-
- data = {'authenticity_token': self.get_token()}
- r = self.session.get(self.pod + "/notifications.json")
+ r = self.connection.get('notifications.json')
if r.status_code != 200:
- raise Exception('wrong status code: ' + str(r.status_code))
+ raise Exception('wrong status code: {0}'.format(r.status_code))
notifications = r.json()
return notifications
-
def get_mentions(self):
- """This functions returns a list of posts the current user is being mentioned in.
+ """This functions returns a list of
+ posts the current user is being mentioned in.
:returns: list -- list of Post objects
-
"""
+ r = self.connection.get('mentions.json')
+
+ if r.status_code != 200:
+ raise Exception('wrong status code: {0}'.format(r.status_code))
+
+ mentions = r.json()
+ return [diaspy.models.Post(str(post['id']), self.connection) for post in mentions]
+ def get_tag(self, tag):
+ """This functions returns a list of posts containing the tag.
+ :param tag: Name of the tag
+ :type tag: str
- data = {'authenticity_token': self.get_token()}
- r = self.session.get(self.pod + "/mentions.json")
+ :returns: list -- list of Post objects
+ """
+ r = self.connection.get('tags/{0}.json'.format(tag))
if r.status_code != 200:
- raise Exception('wrong status code: ' + str(r.status_code))
+ raise Exception('wrong status code: {0}'.format(r.status_code))
- mentions = r.json()
+ tagged_posts = r.json()
+ return [diaspy.models.Post(str(post['id']), self.connection) for post in tagged_posts]
- posts = []
+ def get_mailbox(self):
+ """This functions returns a list of messages found in the conversation.
- for post in mentions:
- posts.append(diaspy.models.Post(str(post['id']), self))
+ :returns: list -- list of Conversation objects.
+ """
+ r = self.connection.get('conversations.json')
- return posts
+ if r.status_code != 200:
+ raise Exception('wrong status code: {0}'.format(r.status_code))
+
+ mailbox = r.json()
+ return [diaspy.conversations.Conversation(str(conversation['conversation']['id']), self.connection)
+ for conversation in mailbox]
def add_user_to_aspect(self, user_id, aspect_id):
""" this function adds a user to an aspect.
:type aspect_id: str
"""
-
- data = {'authenticity_token': self.get_token(),
+ data = {'authenticity_token': self.connection.getToken(),
'aspect_id': aspect_id,
'person_id': user_id}
- r = self.session.post(self.pod + '/aspect_memberships.json',
- data=data)
+ r = self.connection.post('aspect_memberships.json', data=data)
if r.status_code != 201:
- raise Exception('wrong status code: ' + str(r.status_code))
+ raise Exception('wrong status code: {0}'.format(r.status_code))
return r.json()
+ def add_aspect(self, aspect_name, visible=0):
+ """ This function adds a new aspect.
+ """
+ aspects = diaspy.streams.Aspects(self.connection)
+ aspects.add(aspect_name, visible)
+
def remove_user_from_aspect(self, user_id, aspect_id):
""" this function removes a user from an aspect.
:type aspect_id: str
"""
-
- data = {'authenticity_token': self.get_token(),
+ data = {'authenticity_token': self.connection.getToken(),
'aspect_id': aspect_id,
'person_id': user_id}
- r = self.session.delete(self.pod + '/aspect_memberships/42.json',
- data=data)
+ r = self.connection.delete('aspect_memberships/42.json',
+ data=data)
if r.status_code != 200:
- raise Exception('wrong status code: ' + str(r.status_code))
+ raise Exception('wrong status code: {0}'.format(r.status_code))
return r.json()
- def add_aspect(self, aspect_name, visible=0):
+ def remove_aspect(self, aspect_id):
""" This function adds a new aspect.
"""
+ data = {'authenticity_token': self.connection.getToken()}
- data = {'authenticity_token': self.get_token(),
- 'aspect[name]': aspect_name,
- 'aspect[contacts_visible]': visible}
+ r = self.connection.delete('aspects/{}'.format(aspect_id),
+ data=data)
- r = self.session.post(self.pod + '/aspects',
- data=data)
+ if r.status_code != 404:
+ raise Exception('wrong status code: {0}'.format(r.status_code))
- if r.status_code != 200:
- raise Exception('wrong status code: ' + str(r.status_code))
+ def new_conversation(self, contacts, subject, text):
+ """Start a new conversation.
- def remove_aspect(self, aspect_id):
- """ This function adds a new aspect.
+ :param contacts: recipients ids, no guids, comma sperated.
+ :type contacts: str
+ :param subject: subject of the message.
+ :type subject: str
+ :param text: text of the message.
+ :type text: str
"""
-
- data = {'authenticity_token': self.get_token()}
-
- r = self.session.delete(self.pod + '/aspects/' + aspect_id,
- data=data}
-
- if r.status_code != 404:
- raise Exception('wrong status code: ' + str(r.status_code))
+ data = {'contact_ids': contacts,
+ 'conversation[subject]': subject,
+ 'conversation[text]': text,
+ 'utf8': '✓',
+ 'authenticity_token': self.connection.getToken()}
+
+ r = self.connection.post('conversations/',
+ data=data,
+ headers={'accept': 'application/json'})
+ if r.status_code != 200:
+ raise Exception('{0}: Conversation could not be started.'
+ .format(r.status_code))
+ return r.json()