*docstrings* -> *docs/* -> *manual/*
+----
+
+#### Known issues
+
+* __bug__: `diaspy` has problems/can't connect to pods using SNI (this is an issue with requests/urllib3/python),
+
----
**`0.4.1-rc.2` (2013-09-06):**
* __new__: `diaspy.search.Search.tags()` method for getting tag suggestions,
+* __new__: `diaspy.settings.Profile.getName()` method,
+* __new__: `diaspy.settings.Profile.getBio()` method,
+* __new__: `diaspy.settings.Profile.getLocation()` method,
+* __new__: `diaspy.settings.Profile.getLocation()` method,
+* __new__: `diaspy.settings.Profile.getGender()` method,
+* __new__: `diaspy.settings.Profile.getBirthDate()` method,
+* __new__: `diaspy.settings.Profile.isSearchable()` method,
+* __new__: `diaspy.settings.Profile.isNSFW()` method,
* __upd__: `remeber_me` parameter in `diaspy.connection.Connection.login()`,
* __upd__: you must supply `username` and `password` parameters on init of `diaspy.connection.Connection`,
+* __upd__: you must update your testconf.py (new fields are required for settings tests),
+* __upd__: `diaspy.settings.Settings` renamed to `diaspy.settings.Account`,
* __rem__: `username` and `password` parameters removed from `diaspy.connection.Connection.login()`
must be supplied on init,
"""
+import json
import re
import requests
-import json
import warnings
from diaspy import errors
if userdata is None: userdata = self._userinfo_regex_2.search(request.text)
if userdata is None: raise errors.DiaspyError('cannot find user data')
userdata = userdata.group(1)
- warnings.warn(userdata)
return json.loads(userdata)
def _fetchtoken(self):
:returns: token string
"""
request = self.get('stream')
- if DEBUG: print('_fetchtoken(): status code:', request.status_code)
token = self._token_regex.search(request.text).group(1)
self._token = token
return token
class Profile():
"""Provides profile editing methods.
"""
+ firstname_regexp = re.compile('<input id="profile_first_name" name="profile\[first_name\]" type="text" value="(.*?)" />')
+ lastname_regexp = re.compile('<input id="profile_last_name" name="profile\[last_name\]" type="text" value="(.*?)" />')
+ bio_regexp = re.compile('<textarea id="profile_bio" name="profile\[bio\]" placeholder="Fill me out" rows="5">\n(.*?)</textarea>')
+ location_regexp = re.compile('<input id="profile_location" name="profile\[location\]" placeholder="Fill me out" type="text" value="(.*?)" />')
+ gender_regexp = re.compile('<input id="profile_gender" name="profile\[gender\]" placeholder="Fill me out" type="text" value="(.*?)" />')
+ birth_year_regexp = re.compile('<option selected="selected" value="([0-9]{4,4})">[0-9]{4,4}</option>')
+ birth_month_regexp = re.compile('<option selected="selected" value="([0-9]{1,2})">(.*?)</option>')
+ birth_day_regexp = re.compile('<option selected="selected" value="([0-9]{1,2})">[0-9]{1,2}</option>')
+ is_searchable_regexp = re.compile('<input checked="checked" id="profile_searchable" name="profile\[searchable\]" type="checkbox" value="(.*?)" />')
+ is_nsfw_regexp = re.compile('<input checked="checked" id="profile_nsfw" name="profile\[nsfw\]" type="checkbox" value="(.*?)" />')
+
def __init__(self, connection):
self._connection = connection
self.data = {'utf-8': '✓',
'profile[date][day]': '',
}
+ def getName(self):
+ """Returns two-tuple: (first, last) name.
+ """
+ html = self._connection.get('profile/edit').text
+ first = self.firstname_regexp.search(html).group(1)
+ last = self.lastname_regexp.search(html).group(1)
+ return (first, last)
+
+ def getBio(self):
+ """Returns user bio.
+ """
+ html = self._connection.get('profile/edit').text
+ bio = self.bio_regexp.search(html).group(1)
+ return bio
+
+ def getLocation(self):
+ """Returns location string.
+ """
+ html = self._connection.get('profile/edit').text
+ location = self.location_regexp.search(html).group(1)
+ return location
+
+ def getGender(self):
+ """Returns location string.
+ """
+ html = self._connection.get('profile/edit').text
+ gender = self.gender_regexp.search(html).group(1)
+ return gender
+
+ def getBirthDate(self, named_month=False):
+ """Returns three-tuple: (year, month, day).
+
+ :param named_month: if True, return name of the month instead of integer
+ :type named_month: bool
+ """
+ html = self._connection.get('profile/edit').text
+ year = self.birth_year_regexp.search(html)
+ if year is None: year = -1
+ else: year = int(year.group(1))
+ month = self.birth_month_regexp.search(html)
+ if month is None:
+ if named_month: month = ''
+ else: month = -1
+ else:
+ if named_month:
+ month = month.group(2)
+ else:
+ month = int(month.group(1))
+ day = self.birth_day_regexp.search(html)
+ if day is None: day = -1
+ else: day = int(day.group(1))
+ return (year, month, day)
+
+ def isSearchable(self):
+ """Returns True if profile is searchable.
+ """
+ html = self._connection.get('profile/edit').text
+ searchable = self.is_searchable_regexp.search(html)
+ # this is because value="true" in every case so we just
+ # check if the field is "checked"
+ if searchable is None: searchable = False # if it isn't - the regexp just won't match
+ else: searchable = True
+ return searchable
+
+ def isNSFW(self):
+ """Returns True if profile is marked as NSFW.
+ """
+ html = self._connection.get('profile/edit').text
+ nsfw = self.is_nsfw_regexp.search(html)
+ if nsfw is None: nsfw = False
+ else: nsfw = True
+ return nsfw
+
def setName(self, first='', last=''):
"""Set first name.
"""
data['profile[first_name]'] = first
data['profile[last_name]'] = last
data['authenticity_token'] = repr(self._connection)
- print(data)
request = self._connection.post('profile', data=data, allow_redirects=False)
return request.status_code
-class Settings():
+class Account():
"""This object is used to get access to user's settings on
Diaspora* and provides interface for downloading user's stuff.
"""
--- /dev/null
+## Configuration file for `diaspy` test suite (./tests.py)
+
+Developer/tester has to create their own `testconf.py` file
+because it is appended to `.gitignore` to avoid accidental
+upload of personal data.
+
+
+#### You have to set the variables yourself!
+#### Their values have to be valid!
+
+Template file:
+
+ # Here is a configuration file for test suite for diaspy.
+ # Fill it with correct data.
+ #
+ # Fields are explained in testconf.md file.
+
+
+ # Your login details
+ __pod__ = 'https://pod.orkz.net'
+ __username__ = 'marekjm'
+ __passwd__ = 'mAreKJmonDiASporA'
+
+
+ # D* identifiers
+ diaspora_id = 'marekjm@pod.orkz.net'
+ guid = 'fd4ac447f2d267fa'
+
+
+ # Details of your account
+ diaspora_name = 'Marek Marecki'
+ user_names_tuple = ('Marek', 'Marecki')
+ user_location_string = 'Poland'
+ user_gender_string = 'Dude'
+ user_date_of_birth = (1995, 3, 22)
+ # remember about language you've set!
+ user_date_of_birth_named = (1995, 'March', 22)
+ user_is_searchable = True
+ user_is_nsfw = False
+
+
+ # both names are created
+ test_aspect_name = 'diaspy-test'
+
+ # but this one will be deletd `by name`
+ test_aspect_name_fake = 'diaspy-test-fake'
+
+ # don't change needed for tests to work
+ test_aspect_id = -1
+++ /dev/null
-## Configuration file for `diaspy` test suite (./tests.py)
-
-Developer/tester has to create their own `testconf.py` file
-because it is appended to `.gitignore` to avoid accidental
-posting of personal data (passsword for D*).
-
-
-#### You have to set the variables yourself!
-#### Their values have to be valid!
-
-Template file:
-
- __pod__ = 'https://pod.example.com'
- __username__ = 'user'
- __passwd__ = 'strong_password'
- diaspora_id = 'user@pod.example.com'
- guid = '12345678abcdefgh'
- # your name as others see it
- diaspora_name = 'Marek Marecki'
-
- # both names are created
- test_aspect_name = 'diaspy-test'
- # but this one will be deletd `by name`
- test_aspect_name_fake = 'diaspy-test-fake'
-
- # needed here for tests to work
- test_aspect_id = -1
#### TEST SUITE CODE ####
#######################################
class ConnectionTest(unittest.TestCase):
- def testLoginWithoutUsername(self):
- connection = diaspy.connection.Connection(pod=__pod__)
- self.assertRaises(diaspy.errors.LoginError, connection.login, password='foo')
-
- def testLoginWithoutPassword(self):
- connection = diaspy.connection.Connection(pod=__pod__)
- self.assertRaises(diaspy.errors.LoginError, connection.login, username='user')
-
def testGettingUserInfo(self):
info = test_connection.getUserInfo()
self.assertEqual(dict, type(info))
class SettingsTests(unittest.TestCase):
+ profile = diaspy.settings.Profile(test_connection)
+ settings = diaspy.settings.Account(test_connection)
+
+ def testGettingName(self):
+ self.assertEqual(testconf.user_names_tuple, self.profile.getName())
+
+ def testGettingLocation(self):
+ self.assertEqual(testconf.user_location_string, self.profile.getLocation())
+
+ def testGettingGender(self):
+ self.assertEqual(testconf.user_gender_string, self.profile.getGender())
+
+ def testGettingBirthDate(self):
+ self.assertEqual(testconf.user_date_of_birth, self.profile.getBirthDate(named_month=False))
+ self.assertEqual(testconf.user_date_of_birth_named, self.profile.getBirthDate(named_month=True))
+
+ def testGettingInfoIfProfileIsSearchable(self):
+ self.assertEqual(testconf.user_is_searchable, self.profile.isSearchable())
+
+ def testGettingInfoIfProfileIsNSFW(self):
+ self.assertEqual(testconf.user_is_nsfw, self.profile.isNSFW())
+
def testGettingLanguages(self):
- settings = diaspy.settings.Settings(test_connection)
- self.assertIn(('English', 'en'), settings.getLanguages())
+ self.assertIn(('English', 'en'), self.settings.getLanguages())
+
if __name__ == '__main__':
print('Hello World!')