Completed
Push — master ( 48705d...f806b4 )
by Matěj
22s
created

nextcloud.requester   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 157
Duplicated Lines 12.74 %

Importance

Changes 0
Metric Value
wmc 26
eloc 109
dl 20
loc 157
rs 10
c 0
b 0
f 0

17 Methods

Rating   Name   Duplication   Size   Complexity  
A Requester.get() 0 5 1
A WebDAVRequester.report() 0 5 1
A Requester.post() 0 5 1
A WebDAVRequester.download() 0 5 1
A WebDAVRequester.propfind() 0 5 1
A OCSRequester.rtn() 0 2 1
A Requester.put() 0 5 1
A WebDAVRequester.move() 10 10 2
A Requester.get_full_url() 0 22 5
A Requester.__init__() 0 13 1
A WebDAVRequester.proppatch() 0 5 1
A WebDAVRequester.copy() 10 10 2
A WebDAVRequester.rtn() 0 2 1
A Requester.delete() 0 5 1
A Requester.rtn() 0 5 2
A WebDAVRequester.make_collection() 0 5 1
A WebDAVRequester.__init__() 0 2 1

1 Function

Rating   Name   Duplication   Size   Complexity  
A catch_connection_error() 0 8 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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