diff --git a/doc.md b/doc.md index c5092bf..bf3a7f0 100644 --- a/doc.md +++ b/doc.md @@ -31,6 +31,23 @@
  • Delete file
  • +
  • + User + +
  • +
  • + Group + +
  • @@ -429,3 +446,189 @@ None **Return Type** A Response Instance + + +## User ## + +### Get accounts ### +**Request Parameters** + +None + +**Sample Case** + +```python + + import seafileapi + + client = seafileapi.connect('http://127.0.0.1:8000', 'test@admin.com', 'password') + accounts = client.users.get_accounts() +``` + +**Return Type** + +A list of dictionnary containing source and email keys. + +**Exception** + +TBD + +### Create account ### +**Request Parameters** + +* email -- email as login name +* password -- plain text password +* name -- full text display name +* groups_names -- list of groups' names to add this user to +* note -- description / comment / whatever +* is_staff -- is admin, default False +* is_active -- can connect, default True + + +**Sample Case** + +```python + + import seafileapi + + client = seafileapi.connect('http://127.0.0.1:8000', 'test@admin.com', 'password') + accounts = client.users.create_account('test@admin.com', 'password', 'Test user', ['admins']) +``` + +**Return Type** + +A dictionnary, containing the created user. + +**Exception** + +TBD + + +### Delete account ### +**Request Parameters** + +* email -- email as login name + + +**Sample Case** + +```python + + import seafileapi + + client = seafileapi.connect('http://127.0.0.1:8000', 'test@admin.com', 'password') + accounts = client.users.delete_account('test@admin.com') +``` + +**Return Type** + +TBD + +**Exception** + +TBD + + +### Add account to group ### +**Request Parameters** + +* username -- email as login name +* groups_name -- group's name to add this user to + +**Sample Case** + +```python + + import seafileapi + + client = seafileapi.connect('http://127.0.0.1:8000', 'test@admin.com', 'password') + accounts = client.users.add_account_to_group('test@admin.com', 'admins') +``` + +**Return Type** + +TBD + +**Exception** + +TBD + + + + +## Group ## + +### Get groups ### +**Request Parameters** + +None + +**Sample Case** + +```python + + import seafileapi + + client = seafileapi.connect('http://127.0.0.1:8000', 'test@admin.com', 'password') + groups = client.groups.get_groups() +``` + +**Return Type** + +A list of groups. + +**Exception** + +TBD + + + +### Create group ### +**Request Parameters** + +* group_name -- group's name + + +**Sample Case** + +```python + + import seafileapi + + client = seafileapi.connect('http://127.0.0.1:8000', 'test@admin.com', 'password') + accounts = client.groups.create_group('admins') +``` + +**Return Type** + +TBD + +**Exception** + +TBD + + +### Delete group ### +**Request Parameters** + +* group_name -- group's name + + +**Sample Case** + +```python + + import seafileapi + + client = seafileapi.connect('http://127.0.0.1:8000', 'test@admin.com', 'password') + accounts = client.groups.delete_group('admin') +``` + +**Return Type** + +TBD + +**Exception** + +TBD + diff --git a/seafileapi/client.py b/seafileapi/client.py index 9bf79ee..75137de 100644 --- a/seafileapi/client.py +++ b/seafileapi/client.py @@ -2,6 +2,9 @@ from seafileapi.utils import urljoin from seafileapi.exceptions import ClientHttpError from seafileapi.repos import Repos +from seafileapi.group import Groups +from seafileapi.user import Users + class SeafileApiClient(object): """Wraps seafile web api""" @@ -15,6 +18,7 @@ def __init__(self, server, username=None, password=None, token=None): self.repos = Repos(self) self.groups = Groups(self) + self.users = Users(self) if token is None: self._get_token() @@ -43,6 +47,9 @@ def get(self, *args, **kwargs): def post(self, *args, **kwargs): return self._send_request('POST', *args, **kwargs) + def put(self, *args, **kwargs): + return self._send_request('PUT', *args, **kwargs) + def delete(self, *args, **kwargs): return self._send_request('delete', *args, **kwargs) @@ -57,18 +64,12 @@ def _send_request(self, method, url, *args, **kwargs): expected = kwargs.pop('expected', 200) if not hasattr(expected, '__iter__'): expected = (expected, ) + resp = requests.request(method, url, *args, **kwargs) if resp.status_code not in expected: msg = 'Expected %s, but get %s' % \ (' or '.join(map(str, expected)), resp.status_code) + msg += '\n' + resp.content.decode('utf-8') raise ClientHttpError(resp.status_code, msg) return resp - - -class Groups(object): - def __init__(self, client): - pass - - def create_group(self, name): - pass diff --git a/seafileapi/files.py b/seafileapi/files.py index d36f2ea..0ee01de 100644 --- a/seafileapi/files.py +++ b/seafileapi/files.py @@ -2,6 +2,7 @@ import os import posixpath import re +import sys from seafileapi.utils import querystr, utf8lize ZERO_OBJ_ID = '0000000000000000000000000000000000000000' @@ -157,12 +158,17 @@ def upload(self, fileobj, filename): Return a :class:`SeafFile` object of the newly uploaded file. """ if isinstance(fileobj, str): - fileobj = io.BytesIO(fileobj) + if sys.version_info.major > 2: + fileobj = io.BytesIO(bytes(fileobj, 'UTF-8')) + else: + fileobj = io.BytesIO(fileobj) + upload_url = self._get_upload_link() files = { 'file': (filename, fileobj), 'parent_dir': self.path, } + # print(files) self.client.post(upload_url, files=files) return self.repo.get_file(posixpath.join(self.path, filename)) diff --git a/seafileapi/group.py b/seafileapi/group.py index 731d7ef..bfeccf1 100644 --- a/seafileapi/group.py +++ b/seafileapi/group.py @@ -1,22 +1,87 @@ - -class Group(object): - def __init__(self, client, group_id, group_name): +class Groups(object): + def __init__(self, client): + """ + client -- Seafile client object + """ self.client = client - self.group_id = group_id - self.group_name = group_name - def list_memebers(self): - pass + def get_groups(self): + """ + Returns list of groups + """ + resp = self.client.get('/api2/groups/') + value = resp.json() + return value['groups'] + +# def get_group_members(self, group_name): +# """ +# Returns list of members of a group +# """ +# groups = self.get_groups() +# found = False +# for i in groups: +# if i['name'] == group_name: +# url = '/api2/groups/{}/members/'.format(i['id']) +# resp = self.client.get(url) +# found = True +# break +# value = resp.json() +# return value + + def create_group(self, group_name): + """ + Creates group + + group_name -- name + """ + data = { + 'group_name': group_name, + } + resp = self.client.put( + '/api2/groups/', + data=data, + ) + value = resp.json() + return value + + def delete_group(self, group_name): + """ + Delete group + + group_name -- name + """ + url = '/api2/groups/{}'.format(self.get_id_from_group_name(group_name)) + resp = self.client.delete(url) + value = resp.json() + return value - def delete(self): - pass + def get_id_from_group_name(self, group_name): + groups = self.get_groups() + for i in groups: + if i['name'] == group_name: + return i['id'] - def add_member(self, username): - pass + raise ValueError('Group {} not found'.format(group_name)) - def remove_member(self, username): - pass - def list_group_repos(self): - pass +# class Group(object): +# def __init__(self, client, group_id, group_name): +# self.client = client +# self.group_id = group_id +# self.group_name = group_name +# +# def list_memebers(self): +# pass +# +# def delete(self): +# pass +# +# def add_member(self, username): +# pass +# +# def remove_member(self, username): +# pass +# +# def list_group_repos(self): +# pass diff --git a/seafileapi/repo.py b/seafileapi/repo.py index ded895e..ab7dac5 100644 --- a/seafileapi/repo.py +++ b/seafileapi/repo.py @@ -1,4 +1,8 @@ -from urllib import urlencode +import sys +if sys.version_info.major > 2: + from urllib.parse import urlencode +else: + from urllib import urlencode from seafileapi.utils import utf8lize from seafileapi.files import SeafDir, SeafFile from seafileapi.utils import raise_does_not_exist diff --git a/seafileapi/user.py b/seafileapi/user.py new file mode 100644 index 0000000..2d1101c --- /dev/null +++ b/seafileapi/user.py @@ -0,0 +1,101 @@ +from group import Group + + +class Users(object): + def __init__(self, client): + """ + client -- Seafile client object + """ + self.client = client + + def get_accounts(self): + """ + Returns accounts list such as : + + [{'source': 'DB', 'email': 'test@seafiletest.com'}, + {'source': 'DB', 'email': 'admin@seafiletest.com'}] + """ + url = '/api2/accounts/' + resp = self.client.get(url) + return resp.json() + + def create_account(self, email, password, groups_names=[], name='', note='', is_staff=False, is_active=True): + """ + Creates account + + email -- email as login name + password -- plain text password + name -- full text display name + groups_names -- list of groups' names to add this user to + note -- description / comment / whatever + is_staff -- is admin, default False + is_active -- can connect, default True + """ + data = { + 'password': password, + 'is_staff': is_staff, + 'is_active': is_active, + 'name': name[0:64], + 'note': note, + # 'storage': 'DB', + } + url = '/api2/accounts/{}/'.format(email) + resp = self.client.put( + url, + data=data, + expected=[200, 201], + ) + user = resp.json() + for group_name in groups_names: + self.add_user_to_group(username=email, group_name=group_name) + + return user + + def delete_account(self, email): + """ + Delete account + + email -- email as login name + """ + url = '/api2/accounts/{}/'.format(email) + resp = self.client.delete(url) + value = resp.json() + return value + + def add_account_to_group(self, username, group_name): + """ + Adds given username (email) to group (by group name) + + username -- email / login name + group_name -- group to add user to + """ + data = { + 'user_name': username, + } + url = '/api2/groups/{}/members/'.format(self.__get_id_from_group_name__(group_name)) + resp = self.client.put( + url, data=data, + ) + + return resp.json() + + def __get_groups__(self): + manage_group = Group(self.client) + return manage_group.get_groups() + + def __get_id_from_group_name__(self, group_name): + manage_group = Group(self.client) + return manage_group.get_id_from_group_name(group_name) + + + +""" +import __init__ +c=__init__.connect('http://127.0.0.1:8000', 'admin@seafiletest.com', 'adminadmin') +from user import User +u=User(c) +u.create_account('none5@xael.org', 'node99', ['test'], 'Alexandre') +# u.delete_group('TEST2') +# u.delete_account('none4@xael.org') +u.get_group_members('test') +""" diff --git a/seafileapi/utils.py b/seafileapi/utils.py index b529880..e4f4583 100644 --- a/seafileapi/utils.py +++ b/seafileapi/utils.py @@ -1,7 +1,13 @@ import string import random from functools import wraps -from urllib import urlencode + +import sys +if sys.version_info.major > 2: + from urllib.parse import urlencode +else: + from urllib import urlencode + from seafileapi.exceptions import ClientHttpError, DoesNotExist def randstring(length=0): @@ -28,7 +34,7 @@ def decorator(func): def wrapped(*args, **kwargs): try: return func(*args, **kwargs) - except ClientHttpError, e: + except ClientHttpError as e: if e.code == 404: raise DoesNotExist(msg) else: @@ -37,8 +43,13 @@ def wrapped(*args, **kwargs): return decorator def to_utf8(obj): - if isinstance(obj, unicode): - return obj.encode('utf-8') + if sys.version_info.major > 2: + return obj + else: + unicode_type = unicode + if isinstance(obj, unicode_type): + return obj.encode('utf-8') + return obj def querystr(**kwargs): @@ -46,12 +57,19 @@ def querystr(**kwargs): def utf8lize(obj): if isinstance(obj, dict): - return {k: to_utf8(v) for k, v in obj.iteritems()} + if sys.version_info.major > 2: + return {k: to_utf8(v) for k, v in obj.items()} + else: + return {k: to_utf8(v) for k, v in obj.iteritems()} if isinstance(obj, list): return [to_utf8(x) for x in ob] - if instance(obj, unicode): - return obj.encode('utf-8') + if sys.version_info.major > 2: + return obj + else: + unicode_type = unicode + if instance(obj, unicode_type): + return obj.encode('utf-8') return obj diff --git a/setup.py b/setup.py index d2165df..095c10a 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -__version__ = '0.1.1' +__version__ = '0.3.0' setup(name='seafileapi', diff --git a/tests/test_files.py b/tests/test_files.py index 5509da0..39f907e 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -1,6 +1,7 @@ #coding: UTF-8 import os +import sys import pytest from tests.utils import randstring, datafile, filesize @@ -59,10 +60,16 @@ def test_upload_file(repo, parentpath): fname = 'aliedit.tar.gz' fpath = datafile(fname) - with open(fpath, 'r') as fp: + + if sys.version_info.major > 2: + mode = 'rb' + else: + mode = 'r' + + with open(fpath, mode) as fp: testfile = parentdir.upload(fp, fname) - with open(fpath, 'r') as fp: + with open(fpath, mode) as fp: fcontent = fp.read() assert testfile.size == filesize(fpath) @@ -85,7 +92,11 @@ def test_upload_string_as_file_content(repo): # test pass as string as file content when upload file rootdir = repo.get_dir('/') fname = u'testfile-%s' % randstring() - fcontent = 'line 1\nline 2\n\r' + if sys.version_info.major > 2: + fcontent = b'line 1\nline 2\n\r' + else: + fcontent = 'line 1\nline 2\n\r' + f = rootdir.upload(fcontent, fname) assert f.name == fname assert f.get_content() == fcontent diff --git a/tests/utils.py b/tests/utils.py index 63cc8d6..de0d5ab 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -3,7 +3,7 @@ import random def randstring(length=12): - return ''.join(random.choice(string.lowercase) for i in range(length)) + return ''.join(random.choice(string.ascii_lowercase) for i in range(length)) def datafile(filename): return os.path.join(os.path.dirname(__file__), 'data', filename)