From 477daec6a41264ac44dc465a7c415318e655d931 Mon Sep 17 00:00:00 2001 From: manzari Date: Sun, 10 May 2020 12:13:02 +0200 Subject: [PATCH 1/4] add file upload support for nextcloud --- motioneye/templates/main.html | 9 ++-- motioneye/uploadservices.py | 82 +++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/motioneye/templates/main.html b/motioneye/templates/main.html index 5d39a9e86..3aab57f01 100644 --- a/motioneye/templates/main.html +++ b/motioneye/templates/main.html @@ -454,16 +454,17 @@ + ? - + {{ _("Servila Adreso") }} ? - + {{ _("Servila haveno") }} ? @@ -493,12 +494,12 @@ ? - + {{ _("Uzantnomo") }} ? - + {{ _("Pasvorto") }} ? diff --git a/motioneye/uploadservices.py b/motioneye/uploadservices.py index 9bc800638..e2030ff4d 100644 --- a/motioneye/uploadservices.py +++ b/motioneye/uploadservices.py @@ -29,6 +29,7 @@ import boto3 import pycurl +import base64 from motioneye import settings, utils @@ -845,6 +846,87 @@ def _request_credentials(self, authorization_key): return {'access_token': data['access_token']} +class Nextcloud(UploadService): + NAME = 'nextcloud' + + def __init__(self, camera_id): + self._server = None + self._port = None + self._username = None + self._password = None + self._location = None + + UploadService.__init__(self, camera_id) + + def _get_base_url(self): + scheme = 'http://' + if self._port == 443: + scheme = 'https://' + url = scheme + self._server + ':' + str(self._port) + '/remote.php/dav/files/' + self._username + '/' + return url + + def _request(self, url, method, data=None): + self.debug('request: ' + method + ' ' + url) + request = urllib2.Request(url, data=data) + request.get_method = lambda: method + base64string = base64.b64encode('%s:%s' % (self._username, self._password)) + request.add_header("Authorization", "Basic %s" % base64string) + if data is not None: + request.add_header('Content-Length', '%d' % len(data)) + try: + utils.urlopen(request) + except urllib2.HTTPError as e: + if method == 'MKCOL' and e.code == 405: + self.debug('MKCOL failed with code 405, this is normal if the folder exists') + else: + raise e + + def _make_dirs(self, path): + dir_url = self._get_base_url() + for folder in path.strip('/').split('/'): + dir_url = dir_url + folder + '/' + self._request(dir_url, 'MKCOL') + + def test_access(self): + try: + test_path = self._location.strip('/') + '/' + str(time.time()) + self._make_dirs(test_path) + self._request(self._get_base_url() + test_path, 'DELETE') + return True + except Exception as e: + self.error(str(e), exc_info=True) + return str(e) + + def upload_data(self, filename, mime_type, data, ctime, camera_name): + path = self._location.strip('/') + '/' + os.path.dirname(filename) + '/' + filename = os.path.basename(filename) + self._make_dirs(path) + self.debug('uploading %s of %s bytes' % (filename, len(data))) + self._request(self._get_base_url() + path + filename, 'PUT', bytearray(data)) + self.debug('upload done') + + def dump(self): + return { + 'server': self._server, + 'port': self._port, + 'username': self._username, + 'password': self._password, + 'location': self._location + } + + def load(self, data): + if data.get('server') is not None: + self._server = data['server'] + if data.get('port') is not None: + self._port = int(data['port']) + if data.get('username') is not None: + self._username = data['username'] + if data.get('password') is not None: + self._password = data['password'] + if data.get('location'): + self._location = data['location'] + + class FTP(UploadService): NAME = 'ftp' CONN_LIFE_TIME = 60 # don't keep an FTP connection for more than 1 minute From cdb2b72cbfb2d745b5b02b002d7088384dd45f92 Mon Sep 17 00:00:00 2001 From: manzari <22736528+manzari@users.noreply.github.com> Date: Thu, 24 Mar 2022 14:58:20 +0530 Subject: [PATCH 2/4] nextcloud to webdav --- motioneye/templates/main.html | 10 +++++----- motioneye/uploadservices.py | 36 +++++++++++++---------------------- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/motioneye/templates/main.html b/motioneye/templates/main.html index 3aab57f01..5340d831e 100644 --- a/motioneye/templates/main.html +++ b/motioneye/templates/main.html @@ -454,17 +454,17 @@ - + ? - + {{ _("Servila Adreso") }} ? - + {{ _("Servila haveno") }} ? @@ -494,12 +494,12 @@ ? - + {{ _("Uzantnomo") }} ? - + {{ _("Pasvorto") }} ? diff --git a/motioneye/uploadservices.py b/motioneye/uploadservices.py index e2030ff4d..8047fd6d5 100644 --- a/motioneye/uploadservices.py +++ b/motioneye/uploadservices.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from base64 import b64encode import datetime import ftplib import io @@ -29,7 +30,6 @@ import boto3 import pycurl -import base64 from motioneye import settings, utils @@ -846,8 +846,8 @@ def _request_credentials(self, authorization_key): return {'access_token': data['access_token']} -class Nextcloud(UploadService): - NAME = 'nextcloud' +class Webdav(UploadService): + NAME = 'webdav' def __init__(self, camera_id): self._server = None @@ -858,31 +858,24 @@ def __init__(self, camera_id): UploadService.__init__(self, camera_id) - def _get_base_url(self): - scheme = 'http://' - if self._port == 443: - scheme = 'https://' - url = scheme + self._server + ':' + str(self._port) + '/remote.php/dav/files/' + self._username + '/' - return url - - def _request(self, url, method, data=None): + def _request(self, url, method, body=None): + base64string = b64encode(f'{self._username}:{self._password}') + headers = { 'Authorization' : 'Basic %s' % base64string } + if body is not None: + headers.update('Content-Length', '%d' % len(body)) self.debug('request: ' + method + ' ' + url) - request = urllib2.Request(url, data=data) + request = urllib.request.Request(url, data=body, headers=headers) request.get_method = lambda: method - base64string = base64.b64encode('%s:%s' % (self._username, self._password)) - request.add_header("Authorization", "Basic %s" % base64string) - if data is not None: - request.add_header('Content-Length', '%d' % len(data)) try: utils.urlopen(request) - except urllib2.HTTPError as e: + except urllib.HTTPError as e: if method == 'MKCOL' and e.code == 405: self.debug('MKCOL failed with code 405, this is normal if the folder exists') else: raise e def _make_dirs(self, path): - dir_url = self._get_base_url() + dir_url = self._server for folder in path.strip('/').split('/'): dir_url = dir_url + folder + '/' self._request(dir_url, 'MKCOL') @@ -891,7 +884,7 @@ def test_access(self): try: test_path = self._location.strip('/') + '/' + str(time.time()) self._make_dirs(test_path) - self._request(self._get_base_url() + test_path, 'DELETE') + self._request(self._server + test_path, 'DELETE') return True except Exception as e: self.error(str(e), exc_info=True) @@ -902,13 +895,12 @@ def upload_data(self, filename, mime_type, data, ctime, camera_name): filename = os.path.basename(filename) self._make_dirs(path) self.debug('uploading %s of %s bytes' % (filename, len(data))) - self._request(self._get_base_url() + path + filename, 'PUT', bytearray(data)) + self._request(self._server + path + filename, 'PUT', bytearray(data)) self.debug('upload done') def dump(self): return { 'server': self._server, - 'port': self._port, 'username': self._username, 'password': self._password, 'location': self._location @@ -917,8 +909,6 @@ def dump(self): def load(self, data): if data.get('server') is not None: self._server = data['server'] - if data.get('port') is not None: - self._port = int(data['port']) if data.get('username') is not None: self._username = data['username'] if data.get('password') is not None: From b35e96446b644740d93c5c42288747b96c7aa6d3 Mon Sep 17 00:00:00 2001 From: manzari <22736528+manzari@users.noreply.github.com> Date: Thu, 24 Mar 2022 15:07:20 +0530 Subject: [PATCH 3/4] nextcloud to webdav --- motioneye/uploadservices.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/motioneye/uploadservices.py b/motioneye/uploadservices.py index 8047fd6d5..3250e48bb 100644 --- a/motioneye/uploadservices.py +++ b/motioneye/uploadservices.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from base64 import b64encode import datetime import ftplib import io @@ -27,6 +26,7 @@ import urllib.error import urllib.parse import urllib.request +from base64 import b64encode import boto3 import pycurl @@ -860,7 +860,7 @@ def __init__(self, camera_id): def _request(self, url, method, body=None): base64string = b64encode(f'{self._username}:{self._password}') - headers = { 'Authorization' : 'Basic %s' % base64string } + headers = {'Authorization': 'Basic %s' % base64string} if body is not None: headers.update('Content-Length', '%d' % len(body)) self.debug('request: ' + method + ' ' + url) @@ -870,7 +870,9 @@ def _request(self, url, method, body=None): utils.urlopen(request) except urllib.HTTPError as e: if method == 'MKCOL' and e.code == 405: - self.debug('MKCOL failed with code 405, this is normal if the folder exists') + self.debug( + 'MKCOL failed with code 405, this is normal if the folder exists' + ) else: raise e @@ -894,7 +896,7 @@ def upload_data(self, filename, mime_type, data, ctime, camera_name): path = self._location.strip('/') + '/' + os.path.dirname(filename) + '/' filename = os.path.basename(filename) self._make_dirs(path) - self.debug('uploading %s of %s bytes' % (filename, len(data))) + self.debug(f'uploading {filename} of {len(data)} bytes') self._request(self._server + path + filename, 'PUT', bytearray(data)) self.debug('upload done') @@ -903,7 +905,7 @@ def dump(self): 'server': self._server, 'username': self._username, 'password': self._password, - 'location': self._location + 'location': self._location, } def load(self, data): From d5ae418b33d69c07f1c5f6f25871169ebd2603d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Mar 2022 23:55:18 +0000 Subject: [PATCH 4/4] Bump actions/cache from 2 to 3.0.1 Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3.0.1. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v2...v3.0.1) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index f4c92a597..768de88f6 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -33,7 +33,7 @@ jobs: - uses: docker/setup-buildx-action@v1 - name: Cache Docker layers - uses: actions/cache@v2 + uses: actions/cache@v3.0.1 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }}