Skip to content

Commit

Permalink
add setup.cfg for a more readable package config + add test for syste…
Browse files Browse the repository at this point in the history
…mtags + test.sh script to ease test
  • Loading branch information
luffah committed May 10, 2021
1 parent 288d5d6 commit 2fb222c
Show file tree
Hide file tree
Showing 29 changed files with 400 additions and 119 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ services:
- docker

python:
- "3.6"
- 2.7
- 3.6

before_script:
- cd tests && docker-compose up --build -d
Expand All @@ -14,7 +15,7 @@ before_script:
# commands to run tests
script:
- docker-compose run --rm python-api python3 -m pytest --cov . --cov-report xml --cov-report term ..
- docker-compose run --rm python-api python ../example.py
- docker-compose run --rm python-api python ../examples/user_management.py

after_script:
- codecov
Expand Down
29 changes: 29 additions & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

This is Python wrapper for NextCloud's API had been made by…

Main contributors
`````````````````
- Matěj Týč `@matejak <https://github.com/matejak>` active from 2018
- Danil Topchiy `@danil-topchiy <https://github.com/danil-topchiy>` active 2018-2019


Refactoring contributors
````````````````````````
- Matěj Týč `@matejak <https://github.com/matejak>` active from 2018
- Danil Topchiy `@danil-topchiy <https://github.com/danil-topchiy>` active 2018-2019
- luffah `@luffah <https://github.com/luffah>` active 2021


Original code
`````````````
The repo was originally nammed NEXT-OCS-API-forPy in 2017
- どまお `@Dosugamea <https://github.com/Dosugamea>`


Patches
```````
- Hendrik Eckardt `@heck-gd <https://github.com/heck-gd>`
- Anonymous `@xr-muc <https://github.com/xr-muc>`
- tthmmts `@tthmmts <https://github.com/tthmmts>`
- Dylann Cordel `@webu <https://github.com/webu>` `@DylannCordel <https://github.com/DylannCordel>`
- scouderc `@scouderc <https://github.com/scouderc>`
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This is Python wrapper for NextCloud's API.
With it you can manage your NextCloud instances from Python scripts.

Tested with :
* NextCloud 14, python 3.7
* NextCloud 14, python 3.7 (automated test)
* NextCloud 20, python 2.7
* NextCloud 20, python 3.6

Expand Down
1 change: 1 addition & 0 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
requests>=2.0.1
pytest>=4.6
six
12 changes: 1 addition & 11 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,5 @@
#
# pip-compile --output-file requirements.txt requirements.in
#
atomicwrites==1.2.1 # via pytest
attrs==18.2.0 # via pytest
certifi==2018.11.29 # via requests
chardet==3.0.4 # via requests
idna==2.7 # via requests
more-itertools==4.3.0 # via pytest
pluggy==0.8.0 # via pytest
py==1.7.0 # via pytest
pytest==4.0.1
pytest==4.6.1
requests==2.20.1
six==1.11.0 # via more-itertools, pytest
urllib3==1.24.1 # via requests
69 changes: 69 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
[metadata]

name = nextcloud
version = 0.2
description= Python wrapper for NextCloud api
long_description = file: README.md
keywords = requests, api, wrapper, nextcloud, owncloud
license = GPLv3

url = https://nextcloud-api.readthedocs.io
project_urls =
Documentation = https://nextcloud-api.readthedocs.io
Source = https://github.com/EnterpriseyIntranet/nextcloud-API

author = EnterpriseyIntranet
author_email = [email protected]

platforms = any

classifiers =
Programming Language :: Python
Programming Language :: Python :: 2
Programming Language :: Python :: 3
Development Status :: 4 - Beta
Environment :: Web Environment
Intended Audience :: Developers
Topic :: Internet :: WWW/HTTP
Topic :: Software Development :: Libraries :: Python Modules
License :: OSI Approved :: GNU General Public License (GPL)
Operating System :: OS Independent

[options]
zip_safe = False
include_package_data = True

install_requires =
requests >=2.0.1, <3.0
six

[options.extras_require]
tests =
pytest >= 5.2

#[tool:pytest]
#addopts = --verbose --pylint-rcfile=setup.cfg
# --pylint --pycodestyle

[pycodestyle]
max-line-length=120
ignore=E4,E7,W3

# Configuration for pylint
[MASTER]
ignore=CVS
good-names=logger,e,i,j,n,m,f,_

[MESSAGES CONTROL]
disable=all
enable=unused-import,
fixme,
useless-object-inheritance,
unused-variable,
unused-argument,
unexpected-keyword-arg,
string,
unreachable,
invalid-name,
logging-not-lazy,
unnecesary-pass
59 changes: 26 additions & 33 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,31 @@
import os
import setuptools
"""
Setup script
Usage :
python setup.py build
python setup.py install
SETUPDIR = os.path.dirname(__file__)
PKGDIR = os.path.join(SETUPDIR, 'src')
For repository admin:
python setup.py publish
with open(os.path.join(SETUPDIR, 'README.md'), 'r') as f:
long_description = f.read()
For testing:
test.sh
"""
import os
import sys
from setuptools import setup, find_packages

# 'setup.py publish' shortcut.
if sys.argv[-1] == 'publish':
# see https://twine.readthedocs.io/en/latest/
os.system('%s %s sdist bdist_wheel' % (sys.executable, sys.argv[0]))
os.system('twine upload dist/*')
sys.exit()

setuptools.setup(
name='nextcloud',
version='0.0.2',
author='EnterpriseyIntranet',
description="Python wrapper for NextCloud api",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/EnterpriseyIntranet/nextcloud-API",
packages=setuptools.find_packages(PKGDIR),
include_package_data=True,
install_requires=[
'requests >= 2.0.1',
'six'
],
package_dir={'': 'src'},
classifiers=[
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 3',
'Development Status :: 4 - Beta',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Software Development :: Libraries :: Python Modules',
'License :: OSI Approved :: GNU General Public License (GPL)',
"Operating System :: OS Independent",
],
setup(
# see setup.cfg
# some variables are defined here for retro compat with setuptools >= 33
package_dir = {'': 'src'},
packages=find_packages(where=r'./src'),
long_description_content_type = 'text/markdown'
)
8 changes: 5 additions & 3 deletions src/nextcloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,19 @@ def login(self, user=None, password=None, auth=None):
client=self)

def with_attr(self, **kwargs):
if 'auth' in kwargs:
if 'auth' in kwargs or 'endpoint' in kwargs or 'endpoint' in kwargs:
return self.with_auth(**kwargs)
if 'session_kwargs' in kwargs:
return self.with_auth(self.session.auth, **kwargs)
return self.with_auth(auth=self.session.auth, **kwargs)
return self.__class__(session=self.session, **kwargs)

def with_auth(self, auth=None, **kwargs):
init_kwargs = {'session_kwargs': self.session._session_kwargs,
'json_output': self.json_output}
init_kwargs.update(kwargs)
return self.__class__(self.session.url, auth=auth, **init_kwargs)
if 'endpoint' in kwargs:
return self.__class__(auth=auth, **init_kwargs)
return self.__class__(endpoint=self.session.url, auth=auth, **init_kwargs)

def logout(self):
if self.session.session:
Expand Down
22 changes: 16 additions & 6 deletions src/nextcloud/api_wrappers/systemtags.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ def get_related_files(self, path=''):
)
return ret.data or []

def delete(self):
"""
Delete current tag
:returns: True if success
"""
_id = int(self.id)
ret = self._wrapper.delete_systemtag(tag_id=_id)
return ret.is_ok


class File(webdav.File):

Expand Down Expand Up @@ -114,11 +124,11 @@ def get_systemtag(self, name):
:returns: Tag
"""
return self._get_tags_from_response(
self.fetch_sytemtag(name, json_output=False),
self.fetch_systemtag(name, json_output=False),
one=True
)

def fetch_sytemtag(self, name, fields=None, json_output=None):
def fetch_systemtag(self, name, fields=None, json_output=None):
"""
Get attributes of a nammed tag
Expand Down Expand Up @@ -181,11 +191,11 @@ def delete_systemtag(self, name=None, tag_id=None):
:returns: requester response
"""
if not tag_id:
resp = self.get_sytemtag(name, ['id'], json_output=False)
resp = self.fetch_systemtag(name, ['id'], json_output=False)
if resp.data:
tag_id = resp.data[0].id
if not tag_id: # lint only
return None
if not tag_id: # lint only
return resp
resp = self.requester.delete(url=(str(tag_id)))
return resp

Expand All @@ -203,7 +213,7 @@ def _get_fileid_from_path(self, path):
return _id

def _get_systemtag_id_from_name(self, name):
resp = self.client.fetch_sytemtag(name, ['id'], json_output=False)
resp = self.client.fetch_systemtag(name, ['id'], json_output=False)
tag_id = None
if resp.data:
tag_id = int(resp.data[0].id)
Expand Down
10 changes: 6 additions & 4 deletions src/nextcloud/common/simplexml.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
def _prepare_xml_parsing(string):
return encode_string(string)

def _safe_xml_val(val):
if isinstance(val, int):
val = str(val)
return val

class SimpleXml:
"""
Expand Down Expand Up @@ -40,7 +44,7 @@ def _to_field_vals_list(cls, fields_hash):
else:
vals = fields_hash[field_type]
for field in vals:
props_xml['{}:{}'.format(field_type, field)] = vals[field]
props_xml['{}:{}'.format(field_type, field)] = _safe_xml_val(vals[field])

return props_xml

Expand Down Expand Up @@ -86,9 +90,7 @@ def build_propfind_datas(cls, instr=None, filter_rules=None, fields=None):
for k in rules:
rule = ET.SubElement(rule_group, k)
val = rules[k]
if isinstance(val, int):
val = str(val)
rule.text = val
rule.text = _safe_xml_val(val)

return cls._tostring(root)

Expand Down
8 changes: 8 additions & 0 deletions src/nextcloud/common/value_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
Extra tools for value parsing
"""
from datetime import datetime
import os
from nextcloud.compat import datetime_to_timestamp


def datetime_to_expire_date(date):
return date.strftime("%Y-%m-%d")


def timestamp_to_epoch_time(rfc1123_date=''):
"""
literal date time string (use in DAV:getlastmodified) to Epoch time
Expand All @@ -19,8 +24,11 @@ def timestamp_to_epoch_time(rfc1123_date=''):
int or None : Epoch time, if date string value is invalid return None
"""
try:
_tz = os.environ.get('TZ', '')
os.environ['TZ'] = 'UTC'
_time = datetime.strptime(
rfc1123_date, '%a, %d %b %Y %H:%M:%S GMT')
os.environ['TZ'] = _tz
except ValueError:
return
else:
Expand Down
2 changes: 1 addition & 1 deletion src/nextcloud/requester.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"""
from .response import WebDAVResponse, OCSResponse
from .compat import encode_string
from .session import catch_connection_error
from .session import catch_connection_error, NextCloudConnectionError


# from six.moves.urllib import parse
Expand Down
18 changes: 12 additions & 6 deletions src/nextcloud/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class BaseResponse(object):
def __init__(self, response, data=None, json_output=True,
status_code=None, success_code=None, **kwargs):
self.raw = response
self.data = data or (
self.data = data if data is not None else (
response.json() if json_output else response.content.decode('UTF-8')
)
self.status_code = status_code or response.status_code
Expand Down Expand Up @@ -58,16 +58,22 @@ def __init__(self, response, json_output=True, success_code=None):
full_data = None
meta = None
status_code = None

if (success_code or json_output):
try:
full_data = response.json()
meta = full_data['ocs']['meta']
status_code = meta['statuscode']
if json_output:
data = full_data['ocs']['data']
if 'ocs' in full_data:
ocs_data = full_data['ocs']
meta = ocs_data['meta']
status_code = meta['statuscode']
if json_output:
data = ocs_data['data']
else:
data = full_data
meta = data
status_code = -1
except JSONDecodeError:
data = {'message': 'Unable to parse JSON response'}
meta = data
status_code = -1

super(OCSResponse, self).__init__(response, data=data,
Expand Down
Loading

0 comments on commit 2fb222c

Please sign in to comment.