nextcloud links 90% working

This commit is contained in:
vabene1111 2019-11-14 12:42:26 +01:00
parent 2114ed037a
commit c8df93dd5f
8 changed files with 157 additions and 7 deletions

View File

@ -81,7 +81,7 @@ class StorageForm(forms.ModelForm):
class SyncForm(forms.ModelForm): class SyncForm(forms.ModelForm):
class Meta: class Meta:
model = Sync model = Sync
fields = ('storage', 'path') fields = ('storage', 'path', 'active')
class BatchEditForm(forms.Form): class BatchEditForm(forms.Form):

View File

@ -0,0 +1,23 @@
# Generated by Django 2.2.7 on 2019-11-14 09:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0006_comment'),
]
operations = [
migrations.AddField(
model_name='sync',
name='active',
field=models.BooleanField(default=True),
),
migrations.AlterField(
model_name='storage',
name='method',
field=models.CharField(choices=[('DB', 'Dropbox'), ('DAV', 'WebDAV')], default='DB', max_length=128),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.7 on 2019-11-14 09:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0007_auto_20191114_1044'),
]
operations = [
migrations.AlterField(
model_name='storage',
name='method',
field=models.CharField(choices=[('DB', 'Dropbox'), ('NEXTCLOUD', 'Nextcloud')], default='DB', max_length=128),
),
]

View File

@ -4,8 +4,8 @@ from django.db import models
class Storage(models.Model): class Storage(models.Model):
DROPBOX = 'DB' DROPBOX = 'DB'
DAV = 'DAV' NEXTCLOUD = 'NEXTCLOUD'
STORAGE_TYPES = ((DROPBOX, 'Dropbox'), (DAV, 'WebDAV')) STORAGE_TYPES = ((DROPBOX, 'Dropbox'), (NEXTCLOUD, 'Nextcloud'))
name = models.CharField(max_length=128) name = models.CharField(max_length=128)
method = models.CharField(choices=STORAGE_TYPES, max_length=128, default=DROPBOX) method = models.CharField(choices=STORAGE_TYPES, max_length=128, default=DROPBOX)
@ -21,6 +21,7 @@ class Storage(models.Model):
class Sync(models.Model): class Sync(models.Model):
storage = models.ForeignKey(Storage, on_delete=models.PROTECT) storage = models.ForeignKey(Storage, on_delete=models.PROTECT)
path = models.CharField(max_length=512, default="") path = models.CharField(max_length=512, default="")
active = models.BooleanField(default=True)
last_checked = models.DateTimeField() last_checked = models.DateTimeField()
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)

View File

@ -0,0 +1,96 @@
import os
from datetime import datetime
import json
import webdav3.client as wc
import requests
import xmltodict
from requests.auth import HTTPBasicAuth
from cookbook.models import Recipe, RecipeImport, SyncLog
from cookbook.provider.provider import Provider
class Nextcloud(Provider):
@staticmethod
def import_all(monitor):
options = {
'webdav_hostname': monitor.storage.url + '/remote.php/dav/files/' + monitor.storage.username,
'webdav_login': monitor.storage.username,
'webdav_password': monitor.storage.password
}
client = wc.Client(options)
files = client.list(monitor.path)
files.pop(0) # remove first element because its the folder itself
import_count = 0
for file in files:
path = monitor.path + '/' + file
if not Recipe.objects.filter(file_path=path).exists() and not RecipeImport.objects.filter(file_path=path).exists():
name = os.path.splitext(file)[0]
new_recipe = RecipeImport(name=name, file_path=path, storage=monitor.storage)
new_recipe.save()
import_count += 1
log_entry = SyncLog(status='SUCCESS', msg='Imported ' + str(import_count) + ' recipes', sync=monitor)
log_entry.save()
monitor.last_checked = datetime.now()
monitor.save()
return True
@staticmethod
def url_from_ocs_response(response):
if response['ocs']['data']:
elements = response['ocs']['data']['element']
if isinstance(elements, list):
for element in elements:
if element['share_type'] == '3':
return element['url']
else:
if elements['share_type'] == '3':
return elements['url']
return False
@staticmethod
def create_share_link(recipe):
url = recipe.storage.url + '/ocs/v2.php/apps/files_sharing/api/v1/shares'
headers = {
"OCS-APIRequest": "true",
"Content-Type": "application/x-www-form-urlencoded"
}
data = {
"path": recipe.file_path,
"shareType ": 3
}
r = requests.post(url, headers=headers, auth=HTTPBasicAuth(recipe.storage.username, recipe.storage.password), data=json.dumps(data))
json_response = xmltodict.parse(r.text)
return Nextcloud.url_from_ocs_response(json_response)
@staticmethod
def get_share_link(recipe):
url = recipe.storage.url + '/ocs/v2.php/apps/files_sharing/api/v1/shares?path=' + recipe.file_path
headers = {
"OCS-APIRequest": "true",
"Content-Type": "application/xml"
}
r = requests.get(url, headers=headers, auth=HTTPBasicAuth(recipe.storage.username, recipe.storage.password))
json_response = xmltodict.parse(r.text)
url = Nextcloud.url_from_ocs_response(json_response)
if url:
return url
return Nextcloud.create_share_link(recipe)

View File

@ -8,6 +8,7 @@ from django.shortcuts import redirect
from cookbook.models import Recipe, Sync, Storage from cookbook.models import Recipe, Sync, Storage
from cookbook.provider import dropbox from cookbook.provider import dropbox
from cookbook.provider.dropbox import Dropbox from cookbook.provider.dropbox import Dropbox
from cookbook.provider.nextcloud import Nextcloud
@login_required @login_required
@ -20,13 +21,17 @@ def get_file_link(request, recipe_id):
if recipe.link == "": if recipe.link == "":
recipe.link = Dropbox.get_share_link(recipe) # TODO response validation recipe.link = Dropbox.get_share_link(recipe) # TODO response validation
recipe.save() recipe.save()
if recipe.storage.method == Storage.NEXTCLOUD:
if recipe.link == "":
recipe.link = Nextcloud.get_share_link(recipe) # TODO response validation
#recipe.save()
return HttpResponse(recipe.link) return HttpResponse(recipe.link)
@login_required @login_required
def sync_all(request): def sync_all(request):
monitors = Sync.objects.all() monitors = Sync.objects.filter(active=True)
error = False error = False
for monitor in monitors: for monitor in monitors:
@ -34,6 +39,10 @@ def sync_all(request):
ret = Dropbox.import_all(monitor) ret = Dropbox.import_all(monitor)
if not ret: if not ret:
error = True error = True
if monitor.storage.method == Storage.NEXTCLOUD:
ret = Nextcloud.import_all(monitor)
if not ret:
error = True
if not error: if not error:
messages.add_message(request, messages.SUCCESS, _('Sync successful!')) messages.add_message(request, messages.SUCCESS, _('Sync successful!'))

View File

@ -1,12 +1,15 @@
six lxml
requests
markdown
django django
django-tables2 django-tables2
django-filter django-filter
django-crispy-forms django-crispy-forms
djangorestframework djangorestframework
django-autocomplete-light django-autocomplete-light
six
requests
markdown
webdavclient3
xmltodict
python-dotenv==0.7.1 python-dotenv==0.7.1
psycopg2==2.7.4 psycopg2==2.7.4
gunicorn==19.7.1 gunicorn==19.7.1