Completed
Push — master ( 22cbe7...53ce72 )
by Matěj
22s queued 12s
created

nextcloud.requester.WebDAVRequester.report()   A

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nop 3
1
# -*- coding: utf-8 -*-
2
import requests
3
from functools import wraps
4
5
from .response import WebDAVResponse, OCSResponse
6
7
8
class NextCloudConnectionError(Exception):
9
    """ A connection error occurred """
10
11
12
def catch_connection_error(func):
13
    @wraps(func)
14
    def wrapper(*args, **kwargs):
15
        try:
16
            return func(*args, **kwargs)
17
        except requests.RequestException as e:
18
            raise NextCloudConnectionError("Failed to establish connection to NextCloud",
19
                                           getattr(e.request, 'url', None), e)
20
    return wrapper
21
22
23
class Requester(object):
24
    def __init__(self, endpoint, user, passwd, json_output=False):
25
        self.query_components = []
26
27
        self.json_output = json_output
28
29
        self.base_url = endpoint
30
31
        self.h_get = {"OCS-APIRequest": "true"}
32
        self.h_post = {"OCS-APIRequest": "true",
33
                       "Content-Type": "application/x-www-form-urlencoded"}
34
        self.auth_pk = (user, passwd)
35
        self.API_URL = None
36
        self.SUCCESS_CODE = None
37
38
    def rtn(self, resp):
39
        if self.json_output:
40
            return resp.json()
41
        else:
42
            return resp.content.decode("UTF-8")
43
44
    @catch_connection_error
45
    def get(self, url="", params=None):
46
        url = self.get_full_url(url)
47
        res = requests.get(url, auth=self.auth_pk, headers=self.h_get, params=params)
48
        return self.rtn(res)
49
50
    @catch_connection_error
51
    def post(self, url="", data=None):
52
        url = self.get_full_url(url)
53
        res = requests.post(url, auth=self.auth_pk, data=data, headers=self.h_post)
54
        return self.rtn(res)
55
56
    @catch_connection_error
57
    def put_with_timestamp(self, url="", data=None, timestamp=None):
58
        h_post = self.h_post
59
        if isinstance(timestamp, (float, int)):
60
            h_post["X-OC-MTIME"] = f"{timestamp:.0f}"
61
        url = self.get_full_url(url)
62
        res = requests.put(url, auth=self.auth_pk, data=data, headers=h_post)
63
        return self.rtn(res)
64
65
    @catch_connection_error
66
    def put(self, url="", data=None):
67
        url = self.get_full_url(url)
68
        res = requests.put(url, auth=self.auth_pk, data=data, headers=self.h_post)
69
        return self.rtn(res)
70
71
    @catch_connection_error
72
    def delete(self, url="", data=None):
73
        url = self.get_full_url(url)
74
        res = requests.delete(url, auth=self.auth_pk, data=data, headers=self.h_post)
75
        return self.rtn(res)
76
77
    def get_full_url(self, additional_url=""):
78
        """
79
        Build full url for request to NextCloud api
80
81
        Construct url from self.base_url, self.API_URL, additional_url (if given),
82
        add format=json param if self.json
83
84
        :param additional_url: str
85
            add to url after api_url
86
        :return: str
87
        """
88
        if additional_url and not str(additional_url).startswith("/"):
89
            additional_url = "/{}".format(additional_url)
90
91
        if self.json_output:
92
            self.query_components.append("format=json")
93
94
        ret = "{base_url}{api_url}{additional_url}".format(
95
            base_url=self.base_url, api_url=self.API_URL, additional_url=additional_url)
96
97
        if self.json_output:
98
            ret += "?format=json"
99
        return ret
100
101
102
class OCSRequester(Requester):
103
    """ Requester for OCS API """
104
105
    def rtn(self, resp):
106
        return OCSResponse(response=resp,
107
                           json_output=self.json_output, success_code=self.SUCCESS_CODE)
108
109
110
class WebDAVRequester(Requester):
111
    """ Requester for WebDAV API """
112
113
    def __init__(self, *args, **kwargs):
114
        super(WebDAVRequester, self).__init__(*args, **kwargs)
115
116
    def rtn(self, resp, data=None):
117
        return WebDAVResponse(response=resp, data=data)
118
119
    @catch_connection_error
120
    def propfind(self, additional_url="", headers=None, data=None):
121
        url = self.get_full_url(additional_url=additional_url)
122
        res = requests.request('PROPFIND', url, auth=self.auth_pk, headers=headers, data=data)
123
        return self.rtn(res)
124
125
    @catch_connection_error
126
    def proppatch(self, additional_url="", data=None):
127
        url = self.get_full_url(additional_url=additional_url)
128
        res = requests.request('PROPPATCH', url, auth=self.auth_pk, data=data)
129
        return self.rtn(resp=res)
130
131
    @catch_connection_error
132
    def report(self, additional_url="", data=None):
133
        url = self.get_full_url(additional_url=additional_url)
134
        res = requests.request('REPORT', url, auth=self.auth_pk, data=data)
135
        return self.rtn(resp=res)
136
137
    @catch_connection_error
138
    def download(self, url="", params=None):
139
        url = self.get_full_url(url)
140
        res = requests.get(url, auth=self.auth_pk, headers=self.h_get, params=params)
141
        return self.rtn(resp=res, data=res.content)
142
143
    @catch_connection_error
144
    def make_collection(self, additional_url=""):
145
        url = self.get_full_url(additional_url=additional_url)
146
        res = requests.request("MKCOL", url=url, auth=self.auth_pk)
147
        return self.rtn(resp=res)
148
149 View Code Duplication
    @catch_connection_error
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
150
    def move(self, url, destination, overwrite=False):
151
        url = self.get_full_url(additional_url=url)
152
        destionation_url = self.get_full_url(additional_url=destination)
153
        headers = {
154
            "Destination": destionation_url.encode('utf-8'),
155
            "Overwrite": "T" if overwrite else "F"
156
        }
157
        res = requests.request("MOVE", url=url, auth=self.auth_pk, headers=headers)
158
        return self.rtn(resp=res)
159
160 View Code Duplication
    @catch_connection_error
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
161
    def copy(self, url, destination, overwrite=False):
162
        url = self.get_full_url(additional_url=url)
163
        destionation_url = self.get_full_url(additional_url=destination)
164
        headers = {
165
            "Destination": destionation_url,
166
            "Overwrite": "T" if overwrite else "F"
167
        }
168
        res = requests.request("COPY", url=url, auth=self.auth_pk, headers=headers)
169
        return self.rtn(resp=res)
170