2019-08-29 02:16:39 +00:00
|
|
|
from abc import abstractmethod
|
|
|
|
from django import forms
|
|
|
|
from rest_framework.response import Response
|
|
|
|
from rest_framework import status
|
2019-08-31 16:26:29 +00:00
|
|
|
from app.plugins import get_current_plugin, logger
|
2019-08-29 02:16:39 +00:00
|
|
|
from app.plugins.views import TaskView
|
|
|
|
from ..platform_helper import get_platform_by_name
|
|
|
|
from ..platform_extension import PlatformExtension, StringField
|
|
|
|
|
|
|
|
class CloudLibrary(PlatformExtension):
|
2019-08-31 21:56:48 +00:00
|
|
|
"""A Cloud Library is an online platform that has images organized in folders or albums.
|
2019-08-29 02:16:39 +00:00
|
|
|
It differs from a Cloud Platform, in the way that it can also list all folders it contains, so that a user can
|
|
|
|
choose to import a specific folder from a list, instead of a URL."""
|
|
|
|
|
|
|
|
def __init__(self, name, folder_url_example):
|
|
|
|
super().__init__(name, folder_url_example)
|
|
|
|
|
|
|
|
def get_form_fields(self):
|
|
|
|
return [self.get_server_url_field()]
|
|
|
|
|
|
|
|
def get_api_views(self):
|
|
|
|
return [("cloudlibrary/(?P<platform_name>[^/.]+)/listfolders", GetAllFoldersTaskView.as_view())]
|
|
|
|
|
|
|
|
def serialize(self, **kwargs):
|
|
|
|
base_payload = {'name': self.name, 'folder_url_example': self.folder_url_example}
|
|
|
|
if kwargs['user'] != None:
|
|
|
|
ds = get_current_plugin().get_user_data_store(kwargs['user'])
|
|
|
|
server_url_field = self.get_server_url_field()
|
2019-08-31 21:56:48 +00:00
|
|
|
stored_value = server_url_field.get_stored_value(ds)
|
|
|
|
if stored_value != server_url_field.default_value:
|
2019-08-29 02:16:39 +00:00
|
|
|
# If the user is set, and there is a server url set, then consider this platform as
|
|
|
|
# a library. Otherwise, consider it a plain platform
|
|
|
|
base_payload['type'] = 'library'
|
2019-08-31 21:56:48 +00:00
|
|
|
base_payload[server_url_field.key] = stored_value
|
2019-08-29 02:16:39 +00:00
|
|
|
return base_payload
|
|
|
|
|
|
|
|
base_payload['type'] = 'platform'
|
|
|
|
return base_payload
|
|
|
|
|
|
|
|
def get_server_url_field(self):
|
|
|
|
return ServerURLField(self.name)
|
|
|
|
|
2019-08-31 16:26:29 +00:00
|
|
|
def verify_server_url(self, server_url):
|
|
|
|
try:
|
|
|
|
# Define the API url we will call to get all the folders in the server
|
|
|
|
folder_list_api_url = self.build_folder_list_api_url(server_url)
|
|
|
|
# Call the API
|
|
|
|
payload = self.call_api(folder_list_api_url)
|
|
|
|
# Parse the payload into File instances
|
|
|
|
self.parse_payload_into_folders(payload)
|
|
|
|
# If I could parse it, then everything is ok
|
|
|
|
return "OK"
|
|
|
|
except Exception as e:
|
|
|
|
logger.error(str(e))
|
|
|
|
return "Error. Invalid server URL."
|
|
|
|
|
2019-08-29 02:16:39 +00:00
|
|
|
def list_folders_in_server(self, server_url):
|
|
|
|
# Define the API url we will call to get all the folders in the server
|
|
|
|
folder_list_api_url = self.build_folder_list_api_url(server_url)
|
|
|
|
# Call the API
|
|
|
|
payload = self.call_api(folder_list_api_url)
|
|
|
|
# Parse the payload into File instances
|
|
|
|
folders = self.parse_payload_into_folders(payload)
|
|
|
|
# Let the specific platform do some processing with the folders (if necessary)
|
|
|
|
folders = self.library_folder_processing(folders)
|
|
|
|
# Return all folders
|
|
|
|
return folders
|
|
|
|
|
|
|
|
def library_folder_processing(self, files):
|
|
|
|
"""This method does nothing, but each platform might want to do some processing of the folders and they can, by overriding this method"""
|
|
|
|
return files
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
def build_folder_list_api_url(self, server_url):
|
|
|
|
"""Build the url of the API that lists all the folders in the server"""
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
def parse_payload_into_folders(self, payload):
|
|
|
|
"""Parse the api payload and return Folder instances"""
|
|
|
|
|
|
|
|
class ServerURLField(StringField):
|
|
|
|
def __init__(self, platform_name):
|
|
|
|
super().__init__('server_url', platform_name, '')
|
2019-08-31 16:26:29 +00:00
|
|
|
self.platform_name = platform_name
|
2019-08-29 02:16:39 +00:00
|
|
|
|
|
|
|
def get_django_field(self, user_data_store):
|
|
|
|
return forms.URLField(
|
|
|
|
label="Server URL",
|
|
|
|
help_text="Please insert the URL of the Piwigo server",
|
|
|
|
required=False,
|
|
|
|
max_length=1024,
|
|
|
|
widget=forms.URLInput(attrs={"placeholder": "http://piwigo-server.com"}),
|
2019-08-31 16:26:29 +00:00
|
|
|
initial=self.get_stored_value(user_data_store),
|
|
|
|
validators=[self.validate_server_url])
|
|
|
|
|
|
|
|
def validate_server_url(self, server_url_to_validate):
|
|
|
|
result = get_platform_by_name(self.platform_name).verify_server_url(server_url_to_validate)
|
|
|
|
if result != "OK":
|
|
|
|
raise forms.ValidationError(result)
|
2019-08-29 02:16:39 +00:00
|
|
|
|
|
|
|
class GetAllFoldersTaskView(TaskView):
|
|
|
|
def get(self, request, platform_name):
|
|
|
|
platform = get_platform_by_name(platform_name)
|
|
|
|
|
|
|
|
if platform == None:
|
|
|
|
return Response({'error': 'Failed to find a platform with the name \'{}\''.format(platform_name)}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
|
|
|
|
ds = get_current_plugin().get_user_data_store(request.user)
|
|
|
|
|
|
|
|
server_url_field = platform.get_server_url_field()
|
|
|
|
server_url = server_url_field.get_stored_value(ds)
|
|
|
|
|
|
|
|
if server_url == server_url_field.default_value:
|
|
|
|
return Response({'error': 'You can\'t ask for the folders when there is no server configured'}, status=status.HTTP_412_PRECONDITION_FAILED)
|
|
|
|
|
|
|
|
folders = platform.list_folders_in_server(server_url)
|
|
|
|
|
|
|
|
return Response({'folders': [folder.serialize() for folder in folders]}, status=status.HTTP_200_OK)
|