File: __init__.py

package info (click to toggle)
python-synologydsm-api 2.7.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,380 kB
  • sloc: python: 27,239; sh: 25; makefile: 2
file content (359 lines) | stat: -rw-r--r-- 13,084 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
"""Library tests."""

from json import JSONDecodeError
from urllib.parse import urlencode

import aiohttp

from synology_dsm import SynologyDSM
from synology_dsm.api.core.external_usb import SynoCoreExternalUSB
from synology_dsm.api.core.security import SynoCoreSecurity
from synology_dsm.api.core.share import SynoCoreShare
from synology_dsm.api.core.system import SynoCoreSystem
from synology_dsm.api.core.upgrade import SynoCoreUpgrade
from synology_dsm.api.core.utilization import SynoCoreUtilization
from synology_dsm.api.download_station import SynoDownloadStation
from synology_dsm.api.dsm.information import SynoDSMInformation
from synology_dsm.api.dsm.network import SynoDSMNetwork
from synology_dsm.api.file_station import SynoFileStation
from synology_dsm.api.photos import SynoPhotos
from synology_dsm.api.storage.storage import SynoStorage
from synology_dsm.api.surveillance_station import SynoSurveillanceStation
from synology_dsm.api.virtual_machine_manager import SynoVirtualMachineManager
from synology_dsm.const import API_AUTH, API_INFO
from synology_dsm.exceptions import SynologyDSMRequestException

from .api_data.dsm_5 import (
    DSM_5_API_INFO,
    DSM_5_AUTH_LOGIN,
    DSM_5_AUTH_LOGIN_2SA,
    DSM_5_AUTH_LOGIN_2SA_OTP,
    DSM_5_CORE_UTILIZATION,
    DSM_5_DSM_INFORMATION,
    DSM_5_DSM_NETWORK,
    DSM_5_STORAGE_STORAGE_DS410J_RAID5_4DISKS_1VOL,
)
from .api_data.dsm_6 import (
    DSM_6_API_INFO,
    DSM_6_API_INFO_SURVEILLANCE_STATION,
    DSM_6_AUTH_LOGIN,
    DSM_6_AUTH_LOGIN_2SA,
    DSM_6_AUTH_LOGIN_2SA_OTP,
    DSM_6_CORE_SECURITY,
    DSM_6_CORE_SECURITY_UPDATE_OUTOFDATE,
    DSM_6_CORE_SHARE,
    DSM_6_CORE_SYSTEM_DS918_PLUS,
    DSM_6_CORE_UPGRADE_TRUE,
    DSM_6_CORE_UTILIZATION,
    DSM_6_CORE_UTILIZATION_ERROR_1055,
    DSM_6_DOWNLOAD_STATION_INFO_CONFIG,
    DSM_6_DOWNLOAD_STATION_INFO_INFO,
    DSM_6_DOWNLOAD_STATION_STAT_INFO,
    DSM_6_DOWNLOAD_STATION_TASK_LIST,
    DSM_6_DSM_INFORMATION,
    DSM_6_DSM_NETWORK_2LAN_1PPPOE,
    DSM_6_STORAGE_STORAGE_DS213_PLUS_SHR1_2DISKS_2VOLS,
    DSM_6_STORAGE_STORAGE_DS918_PLUS_RAID5_3DISKS_1VOL,
    DSM_6_STORAGE_STORAGE_DS1515_PLUS_SHR2_10DISKS_1VOL_WITH_EXPANSION,
    DSM_6_STORAGE_STORAGE_DS1819_PLUS_SHR2_8DISKS_1VOL,
    DSM_6_SURVEILLANCE_STATION_CAMERA_EVENT_MD_PARAM_SAVE,
    DSM_6_SURVEILLANCE_STATION_CAMERA_EVENT_MOTION_ENUM,
    DSM_6_SURVEILLANCE_STATION_CAMERA_GET_LIVE_VIEW_PATH,
    DSM_6_SURVEILLANCE_STATION_CAMERA_LIST,
    DSM_6_SURVEILLANCE_STATION_HOME_MODE_GET_INFO,
    DSM_6_SURVEILLANCE_STATION_HOME_MODE_SWITCH,
)
from .api_data.dsm_7 import (
    DSM_7_API_INFO,
    DSM_7_AUTH_LOGIN,
    DSM_7_AUTH_LOGIN_2SA,
    DSM_7_AUTH_LOGIN_2SA_OTP,
    DSM_7_CORE_EXTERNAL_USB_DS1821_PLUS_EXTERNAL_USB,
    DSM_7_CORE_EXTERNAL_USB_DS1821_PLUS_NO_EXTERNAL_USB,
    DSM_7_CORE_UPGRADE_TRUE,
    DSM_7_DSM_INFORMATION,
    DSM_7_FILE_STATION_FILES,
    DSM_7_FILE_STATION_FOLDERS,
    DSM_7_FOTO_ALBUMS,
    DSM_7_FOTO_ITEMS,
    DSM_7_FOTO_ITEMS_SEARCHED,
    DSM_7_FOTO_ITEMS_SHARED_ALBUM,
    DSM_7_FOTO_SHARED_ITEMS,
    DSM_7_VMM_GUESTS,
)
from .const import (
    DEVICE_TOKEN,
    ERROR_AUTH_INVALID_CREDENTIALS,
    ERROR_AUTH_MAX_TRIES,
    ERROR_AUTH_OTP_AUTHENTICATE_FAILED,
    ERROR_INSUFFICIENT_USER_PRIVILEGE,
)

API_SWITCHER = {
    5: {
        "API_INFO": DSM_5_API_INFO,
        "AUTH_LOGIN": DSM_5_AUTH_LOGIN,
        "AUTH_LOGIN_2SA": DSM_5_AUTH_LOGIN_2SA,
        "AUTH_LOGIN_2SA_OTP": DSM_5_AUTH_LOGIN_2SA_OTP,
        "DSM_INFORMATION": DSM_5_DSM_INFORMATION,
        "DSM_NETWORK": DSM_5_DSM_NETWORK,
        "CORE_UTILIZATION": DSM_5_CORE_UTILIZATION,
        "STORAGE_STORAGE": {
            "RAID": DSM_5_STORAGE_STORAGE_DS410J_RAID5_4DISKS_1VOL,
        },
    },
    6: {
        "API_INFO": DSM_6_API_INFO,
        "AUTH_LOGIN": DSM_6_AUTH_LOGIN,
        "AUTH_LOGIN_2SA": DSM_6_AUTH_LOGIN_2SA,
        "AUTH_LOGIN_2SA_OTP": DSM_6_AUTH_LOGIN_2SA_OTP,
        "DSM_INFORMATION": DSM_6_DSM_INFORMATION,
        "DSM_NETWORK": DSM_6_DSM_NETWORK_2LAN_1PPPOE,
        "CORE_SECURITY": DSM_6_CORE_SECURITY,
        "CORE_SHARE": DSM_6_CORE_SHARE,
        "CORE_SYSTEM": DSM_6_CORE_SYSTEM_DS918_PLUS,
        "CORE_UTILIZATION": DSM_6_CORE_UTILIZATION,
        "CORE_UPGRADE": DSM_6_CORE_UPGRADE_TRUE,
        "STORAGE_STORAGE": {
            "RAID": DSM_6_STORAGE_STORAGE_DS918_PLUS_RAID5_3DISKS_1VOL,
            "SHR1": DSM_6_STORAGE_STORAGE_DS213_PLUS_SHR1_2DISKS_2VOLS,
            "SHR2": DSM_6_STORAGE_STORAGE_DS1819_PLUS_SHR2_8DISKS_1VOL,
            "SHR2_EXPANSION": DSM_6_STORAGE_STORAGE_DS1515_PLUS_SHR2_10DISKS_1VOL_WITH_EXPANSION,  # noqa: B950
        },
    },
    7: {
        "API_INFO": DSM_7_API_INFO,
        "AUTH_LOGIN": DSM_7_AUTH_LOGIN,
        "AUTH_LOGIN_2SA": DSM_7_AUTH_LOGIN_2SA,
        "AUTH_LOGIN_2SA_OTP": DSM_7_AUTH_LOGIN_2SA_OTP,
        "CORE_UPGRADE": DSM_7_CORE_UPGRADE_TRUE,
        "DSM_INFORMATION": DSM_7_DSM_INFORMATION,
        "FOTO_ALBUMS": DSM_7_FOTO_ALBUMS,
        "FOTO_ITEMS": DSM_7_FOTO_ITEMS,
        "VMM_GUESTS": DSM_7_VMM_GUESTS,
    },
}


VALID_HOST = "nas.mywebsite.me"
VALID_PORT = "5001"
VALID_HTTPS = True
VALID_VERIFY_SSL = True
VALID_USER = "valid_user"
VALID_USER_2SA = "valid_user_2sa"
VALID_PASSWORD = "valid_password"  # noqa: S105
VALID_OTP = "123456"

USER_MAX_TRY = "user_max"


class SynologyDSMMock(SynologyDSM):
    """Mocked SynologyDSM."""

    API_URI = "api="

    def __init__(
        self,
        session,
        dsm_ip,
        dsm_port,
        username,
        password,
        use_https=False,
        timeout=10,
        device_token=None,
        debugmode=False,
    ):
        """Constructor method."""
        SynologyDSM.__init__(
            self,
            session,
            dsm_ip,
            dsm_port,
            username,
            password,
            use_https,
            timeout,
            device_token,
            debugmode,
        )

        self.dsm_version = 6  # 5 or 6
        self.disks_redundancy = "RAID"  # RAID or SHR[number][_EXPANSION]
        self.error = False
        self.with_surveillance = False
        self.usb_device_connected = True

    async def _execute_request(
        self, method, url, params, raw_response_content, **kwargs
    ):
        url = str(url)
        url += urlencode(params or {})

        if "no_internet" in url:
            raise SynologyDSMRequestException(
                aiohttp.ClientError(
                    "<urllib3.connection.VerifiedHTTPSConnection object at "
                    "0x106c1f250>: Failed to establish a new connection: "
                    "[Errno 8] nodename nor servname provided, or not known"
                )
            )

        if VALID_HOST not in url:
            raise SynologyDSMRequestException(
                aiohttp.ClientError(
                    "<urllib3.connection.HTTPConnection object at 0x10d6f8090>:"
                    " Failed to establish a new connection: [Errno 8] nodename "
                    "nor servname provided, or not known"
                )
            )

        if VALID_PORT not in url and "https" not in url:
            raise SynologyDSMRequestException(
                JSONDecodeError("Expecting value", "<html>document</html>", 0)
            )

        if VALID_PORT not in url:
            raise SynologyDSMRequestException(
                aiohttp.ClientError(
                    "[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1076)"
                )
            )

        if "https" not in url:
            raise SynologyDSMRequestException(aiohttp.ClientError("Bad request"))

        if API_INFO in url:
            if self.with_surveillance:
                return DSM_6_API_INFO_SURVEILLANCE_STATION
            return API_SWITCHER[self.dsm_version]["API_INFO"]

        if API_AUTH in url:
            if VALID_USER_2SA in url and VALID_PASSWORD in url:
                if "otp_code" not in url and "device_id" not in url:
                    return API_SWITCHER[self.dsm_version]["AUTH_LOGIN_2SA"]

                if "device_id" in url and DEVICE_TOKEN in url:
                    return API_SWITCHER[self.dsm_version]["AUTH_LOGIN"]

                if "otp_code" in url:
                    if VALID_OTP in url:
                        return API_SWITCHER[self.dsm_version]["AUTH_LOGIN_2SA_OTP"]
                    return ERROR_AUTH_OTP_AUTHENTICATE_FAILED

            if VALID_USER in url and VALID_PASSWORD in url:
                return API_SWITCHER[self.dsm_version]["AUTH_LOGIN"]

            if USER_MAX_TRY in url:
                return ERROR_AUTH_MAX_TRIES

            return ERROR_AUTH_INVALID_CREDENTIALS

        if self.API_URI in url:
            if not self._session_id:
                return ERROR_INSUFFICIENT_USER_PRIVILEGE

            if SynoCoreExternalUSB.API_KEY in url:
                if self.usb_device_connected:
                    return DSM_7_CORE_EXTERNAL_USB_DS1821_PLUS_EXTERNAL_USB
                if not self.usb_device_connected:
                    return DSM_7_CORE_EXTERNAL_USB_DS1821_PLUS_NO_EXTERNAL_USB

            if SynoCoreSecurity.API_KEY in url:
                if self.error:
                    return DSM_6_CORE_SECURITY_UPDATE_OUTOFDATE
                return API_SWITCHER[self.dsm_version]["CORE_SECURITY"]

            if SynoCoreShare.API_KEY in url:
                return API_SWITCHER[self.dsm_version]["CORE_SHARE"]

            if SynoCoreSystem.API_KEY in url:
                if SynoCoreUtilization.API_KEY in url:
                    if self.error:
                        return DSM_6_CORE_UTILIZATION_ERROR_1055
                    return API_SWITCHER[self.dsm_version]["CORE_UTILIZATION"]
                return API_SWITCHER[self.dsm_version]["CORE_SYSTEM"]

            if SynoCoreUpgrade.API_KEY in url:
                return API_SWITCHER[self.dsm_version]["CORE_UPGRADE"]

            if SynoDSMInformation.API_KEY in url:
                return API_SWITCHER[self.dsm_version]["DSM_INFORMATION"]

            if SynoDSMNetwork.API_KEY in url:
                return API_SWITCHER[self.dsm_version]["DSM_NETWORK"]

            if SynoDownloadStation.INFO_API_KEY in url:
                if "GetInfo" in url:
                    return DSM_6_DOWNLOAD_STATION_INFO_INFO
                if "GetConfig" in url:
                    return DSM_6_DOWNLOAD_STATION_INFO_CONFIG
            if SynoDownloadStation.STAT_API_KEY in url:
                if "GetInfo" in url:
                    return DSM_6_DOWNLOAD_STATION_STAT_INFO
            if SynoDownloadStation.TASK_API_KEY in url:
                if "List" in url:
                    return DSM_6_DOWNLOAD_STATION_TASK_LIST

            if SynoFileStation.LIST_API_KEY in url:
                if "list_share" in url:
                    return DSM_7_FILE_STATION_FOLDERS
                if "list" in url:
                    return DSM_7_FILE_STATION_FILES

            if SynoPhotos.BROWSE_ALBUMS_API_KEY in url:
                return DSM_7_FOTO_ALBUMS

            if SynoPhotos.BROWSE_ITEM_API_KEY in url:
                if "passphrase" in url:
                    return DSM_7_FOTO_ITEMS_SHARED_ALBUM
                return DSM_7_FOTO_ITEMS

            if SynoPhotos.SEARCH_API_KEY in url:
                return DSM_7_FOTO_ITEMS_SEARCHED

            if SynoPhotos.BROWSE_ITEM_FOTOTEAM_API_KEY in url:
                return DSM_7_FOTO_SHARED_ITEMS

            if SynoVirtualMachineManager.GUEST_API_KEY in url:
                return DSM_7_VMM_GUESTS

            if SynoStorage.API_KEY in url:
                return API_SWITCHER[self.dsm_version]["STORAGE_STORAGE"][
                    self.disks_redundancy
                ]

            if SynoSurveillanceStation.CAMERA_API_KEY in url:
                if "GetLiveViewPath" in url:
                    return DSM_6_SURVEILLANCE_STATION_CAMERA_GET_LIVE_VIEW_PATH
                if "List" in url:
                    assert params["version"] == 7
                    return DSM_6_SURVEILLANCE_STATION_CAMERA_LIST
                if "MDParamSave" in url:
                    return DSM_6_SURVEILLANCE_STATION_CAMERA_EVENT_MD_PARAM_SAVE
                if "MotionEnum" in url:
                    return DSM_6_SURVEILLANCE_STATION_CAMERA_EVENT_MOTION_ENUM

            if SynoSurveillanceStation.HOME_MODE_API_KEY in url:
                if "GetInfo" in url:
                    return DSM_6_SURVEILLANCE_STATION_HOME_MODE_GET_INFO
                if "Switch" in url:
                    return DSM_6_SURVEILLANCE_STATION_HOME_MODE_SWITCH

            if (
                "SYNO.FileStation.Upload" in url
                and "upload" in url
                and "file_already_exists" in kwargs["files"]["file"]
            ):
                return {"error": {"code": 1805}, "success": False}

            if (
                "SYNO.DownloadStation2.Task" in url
                and "create" in url
                and "test_not_exists" in url
            ):
                return {"error": {"code": 408}, "success": False}

            return {"success": False}

        return None