mirror of
https://github.com/lucaspalomodevelop/indico-plugins.git
synced 2026-03-12 23:27:22 +00:00
OwnCloud: Add plugin (#173)
This commit is contained in:
parent
0eb4d54e6c
commit
f0c90988bf
6
owncloud/MANIFEST.in
Normal file
6
owncloud/MANIFEST.in
Normal file
@ -0,0 +1,6 @@
|
||||
graft indico_owncloud/client
|
||||
graft indico_owncloud/static
|
||||
graft indico_owncloud/templates
|
||||
graft indico_owncloud/translations
|
||||
|
||||
global-exclude *.pyc __pycache__ .keep
|
||||
13
owncloud/README.md
Normal file
13
owncloud/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# OwnCloud integration plugin
|
||||
|
||||
This plugin enables integration with an ownCloud server, initially for the
|
||||
purpose of attaching materials to an event or category. A new "from the cloud"
|
||||
button shows up in the materials section which enables a manager to log into his
|
||||
ownCloud account and pick files from his personal storage. Those files will be
|
||||
copied as attachments.
|
||||
|
||||
## Changelog
|
||||
|
||||
### 3.2
|
||||
|
||||
- Initial release for Indico 3.2
|
||||
11
owncloud/indico_owncloud/__init__.py
Normal file
11
owncloud/indico_owncloud/__init__.py
Normal file
@ -0,0 +1,11 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2022 CERN
|
||||
#
|
||||
# The Indico plugins are free software; you can redistribute
|
||||
# them and/or modify them under the terms of the MIT License;
|
||||
# see the LICENSE file for more details.
|
||||
|
||||
from indico.util.i18n import make_bound_gettext
|
||||
|
||||
|
||||
_ = make_bound_gettext('owncloud')
|
||||
17
owncloud/indico_owncloud/blueprint.py
Normal file
17
owncloud/indico_owncloud/blueprint.py
Normal file
@ -0,0 +1,17 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2022 CERN
|
||||
#
|
||||
# The Indico plugins are free software; you can redistribute
|
||||
# them and/or modify them under the terms of the MIT License;
|
||||
# see the LICENSE file for more details.
|
||||
|
||||
from indico.core.plugins import IndicoPluginBlueprint
|
||||
|
||||
from indico_owncloud.controllers import RHAddCategoryAttachmentOwncloud, RHAddEventAttachmentOwncloud
|
||||
|
||||
|
||||
blueprint = IndicoPluginBlueprint('owncloud', 'indico_owncloud')
|
||||
blueprint.add_url_rule('/category/<int:category_id>/manage/attachments/add/owncloud', 'owncloud_category',
|
||||
RHAddCategoryAttachmentOwncloud, methods=('GET', 'POST'), defaults={'object_type': 'category'})
|
||||
blueprint.add_url_rule('/event/<int:event_id>/manage/attachments/add/owncloud', 'owncloud_event',
|
||||
RHAddEventAttachmentOwncloud, methods=('GET', 'POST'), defaults={'object_type': 'event'})
|
||||
21
owncloud/indico_owncloud/client/index.js
Normal file
21
owncloud/indico_owncloud/client/index.js
Normal file
@ -0,0 +1,21 @@
|
||||
// This file is part of the Indico plugins.
|
||||
// Copyright (C) 2002 - 2022 CERN
|
||||
//
|
||||
// The Indico plugins are free software; you can redistribute
|
||||
// them and/or modify them under the terms of the MIT License;
|
||||
// see the LICENSE file for more details.
|
||||
|
||||
// eslint-disable-next-line import/unambiguous
|
||||
window.setupOwncloudFilePickerWidget = ({filepickerUrl, fieldId}) => {
|
||||
window.addEventListener('message', message => {
|
||||
const iframe = document.querySelector('#owncloud_filepicker-file-picker');
|
||||
if (
|
||||
message.origin === filepickerUrl &&
|
||||
message.source === iframe.contentWindow &&
|
||||
message.data &&
|
||||
message.data.files
|
||||
) {
|
||||
document.getElementById(`${fieldId}-files`).value = message.data.files.join('\n');
|
||||
}
|
||||
});
|
||||
};
|
||||
23
owncloud/indico_owncloud/client/style.scss
Normal file
23
owncloud/indico_owncloud/client/style.scss
Normal file
@ -0,0 +1,23 @@
|
||||
// This file is part of the Indico plugins.
|
||||
// Copyright (C) 2002 - 2022 CERN
|
||||
//
|
||||
// The Indico plugins are free software; you can redistribute
|
||||
// them and/or modify them under the terms of the MIT License;
|
||||
// see the LICENSE file for more details.
|
||||
|
||||
@import 'base/palette';
|
||||
|
||||
form#attachment-owncloudfilepicker-form.full-width .owncloudfilepicker {
|
||||
width: 770px;
|
||||
height: 280px;
|
||||
border: 1px solid $light-gray;
|
||||
}
|
||||
|
||||
.owncloudfilepicker {
|
||||
border: 0px none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.button-label {
|
||||
margin-left: 0.4rem;
|
||||
}
|
||||
64
owncloud/indico_owncloud/controllers.py
Normal file
64
owncloud/indico_owncloud/controllers.py
Normal file
@ -0,0 +1,64 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2022 CERN
|
||||
#
|
||||
# The Indico plugins are free software; you can redistribute
|
||||
# them and/or modify them under the terms of the MIT License;
|
||||
# see the LICENSE file for more details.
|
||||
|
||||
import mimetypes
|
||||
|
||||
import requests
|
||||
from flask import flash, session
|
||||
from flask_pluginengine import render_plugin_template
|
||||
|
||||
from indico.core.db import db
|
||||
from indico.modules.attachments.controllers.management.base import (_get_folders_protection_info,
|
||||
_render_attachment_list, _render_protection_message)
|
||||
from indico.modules.attachments.controllers.management.category import RHCategoryAttachmentManagementBase
|
||||
from indico.modules.attachments.controllers.management.event import RHEventAttachmentManagementBase
|
||||
from indico.modules.attachments.models.attachments import Attachment, AttachmentFile, AttachmentType
|
||||
from indico.modules.attachments.models.folders import AttachmentFolder
|
||||
from indico.util.fs import secure_client_filename
|
||||
from indico.web.util import jsonify_data, jsonify_template
|
||||
|
||||
from indico_owncloud import _
|
||||
from indico_owncloud.forms import AddAttachmentOwncloudForm
|
||||
|
||||
|
||||
class AddAttachmentOwncloudMixin:
|
||||
"""Add cloud storage attachment."""
|
||||
|
||||
def _process(self):
|
||||
form = AddAttachmentOwncloudForm(linked_object=self.object)
|
||||
if form.validate_on_submit():
|
||||
files = form.data['owncloud_filepicker']['files']
|
||||
folder = form.data['folder'] or AttachmentFolder.get_or_create_default(linked_object=self.object)
|
||||
for f in files:
|
||||
filename = f.split('/')[-1].split('?')[0]
|
||||
local_filename = secure_client_filename(filename)
|
||||
attachment = Attachment(folder=folder, user=session.user, title=local_filename,
|
||||
type=AttachmentType.file, protection_mode=form.data['protection_mode'])
|
||||
if attachment.is_self_protected:
|
||||
attachment.acl = form.data['acl']
|
||||
content_type = mimetypes.guess_type(local_filename)[0] or 'application/octet-stream'
|
||||
attachment.file = AttachmentFile(user=session.user, filename=local_filename, content_type=content_type)
|
||||
|
||||
file_response = requests.get(f)
|
||||
file_response.raise_for_status()
|
||||
attachment.file.save(file_response.content)
|
||||
|
||||
db.session.add(attachment)
|
||||
db.session.flush()
|
||||
flash(_('Attachment added'))
|
||||
return jsonify_data(attachment_list=_render_attachment_list(self.object))
|
||||
return jsonify_template('add_owncloud_files.html', _render_func=render_plugin_template, form=form,
|
||||
protection_message=_render_protection_message(self.object),
|
||||
folders_protection_info=_get_folders_protection_info(self.object))
|
||||
|
||||
|
||||
class RHAddCategoryAttachmentOwncloud(AddAttachmentOwncloudMixin, RHCategoryAttachmentManagementBase):
|
||||
pass
|
||||
|
||||
|
||||
class RHAddEventAttachmentOwncloud(AddAttachmentOwncloudMixin, RHEventAttachmentManagementBase):
|
||||
pass
|
||||
45
owncloud/indico_owncloud/forms.py
Normal file
45
owncloud/indico_owncloud/forms.py
Normal file
@ -0,0 +1,45 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2022 CERN
|
||||
#
|
||||
# The Indico plugins are free software; you can redistribute
|
||||
# them and/or modify them under the terms of the MIT License;
|
||||
# see the LICENSE file for more details.
|
||||
|
||||
from wtforms import Field
|
||||
from wtforms.validators import DataRequired, ValidationError
|
||||
|
||||
from indico.core.config import config
|
||||
from indico.modules.attachments.forms import AttachmentFormBase
|
||||
from indico.util.i18n import _
|
||||
from indico.web.forms.widgets import JinjaWidget
|
||||
|
||||
from indico_owncloud.util import get_filepicker_url
|
||||
|
||||
|
||||
class IndicoOwncloudField(Field):
|
||||
widget = JinjaWidget('owncloud_filepicker_widget.html', plugin='owncloud', single_line=True, single_kwargs=True)
|
||||
|
||||
def __init__(self, label=None, validators=None, **kwargs):
|
||||
super().__init__(label, validators, **kwargs)
|
||||
self.filepicker_url = get_filepicker_url()
|
||||
self.origin = config.BASE_URL
|
||||
|
||||
def process_formdata(self, valuelist):
|
||||
if valuelist:
|
||||
self.data = {'files': [f.rstrip() for f in valuelist[0].split('\n')]}
|
||||
|
||||
|
||||
class AttachmentOwncloudFormMixin:
|
||||
owncloud_filepicker = IndicoOwncloudField(_('Files'), [DataRequired()])
|
||||
|
||||
def validate_owncloud_filepicker(self, field):
|
||||
if self.owncloud_filepicker.data and self.owncloud_filepicker.data['files'] == ['']:
|
||||
raise ValidationError("Select files to add and click 'Select resources'")
|
||||
|
||||
|
||||
class AddAttachmentOwncloudForm(AttachmentOwncloudFormMixin, AttachmentFormBase):
|
||||
pass
|
||||
|
||||
|
||||
class EditAttachmentOwncloudForm(AttachmentOwncloudFormMixin, AttachmentFormBase):
|
||||
pass
|
||||
66
owncloud/indico_owncloud/plugin.py
Normal file
66
owncloud/indico_owncloud/plugin.py
Normal file
@ -0,0 +1,66 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2022 CERN
|
||||
#
|
||||
# The Indico plugins are free software; you can redistribute
|
||||
# them and/or modify them under the terms of the MIT License;
|
||||
# see the LICENSE file for more details.
|
||||
|
||||
from flask_pluginengine.plugin import render_plugin_template
|
||||
from wtforms.fields import StringField, URLField
|
||||
from wtforms.validators import DataRequired
|
||||
|
||||
from indico.core.plugins import IndicoPlugin
|
||||
from indico.modules.attachments.views import WPEventAttachments
|
||||
from indico.modules.categories.views import WPCategoryManagement
|
||||
from indico.modules.events.views import WPConferenceDisplay, WPSimpleEventDisplay
|
||||
from indico.web.forms.base import IndicoForm
|
||||
|
||||
from indico_owncloud import _
|
||||
from indico_owncloud.blueprint import blueprint
|
||||
from indico_owncloud.util import is_configured
|
||||
|
||||
|
||||
class PluginSettingsForm(IndicoForm):
|
||||
filepicker_url = URLField(_('File-picker URL'), [DataRequired()])
|
||||
service_name = StringField(_('Service name'), [],
|
||||
description=_('A customized name for the cloud service. If empty, the default '
|
||||
"'The cloud' will be used."))
|
||||
button_icon_url = URLField(_('Custom icon URL'), [],
|
||||
description=_('URL for a customized icon to show in the add attachment button. If '
|
||||
'empty, the default cloud icon will be used'))
|
||||
|
||||
|
||||
class OwncloudPlugin(IndicoPlugin):
|
||||
"""OwnCloud integration
|
||||
|
||||
Provides an integration with OwnCloud storage servers, enabling managers
|
||||
to attach files to categories/events from their cloud storage.
|
||||
"""
|
||||
configurable = True
|
||||
settings_form = PluginSettingsForm
|
||||
default_settings = {
|
||||
'filepicker_url': '',
|
||||
'service_name': '',
|
||||
'button_icon_url': '',
|
||||
}
|
||||
|
||||
def init(self):
|
||||
super().init()
|
||||
self.template_hook('attachment-sources', self._inject_owncloud_button)
|
||||
self.inject_bundle('owncloud.js', WPEventAttachments)
|
||||
self.inject_bundle('owncloud.js', WPSimpleEventDisplay)
|
||||
self.inject_bundle('owncloud.js', WPConferenceDisplay)
|
||||
self.inject_bundle('owncloud.js', WPCategoryManagement)
|
||||
self.inject_bundle('main.css', WPEventAttachments)
|
||||
self.inject_bundle('main.css', WPSimpleEventDisplay)
|
||||
self.inject_bundle('main.css', WPConferenceDisplay)
|
||||
self.inject_bundle('main.css', WPCategoryManagement)
|
||||
|
||||
def get_blueprints(self):
|
||||
return blueprint
|
||||
|
||||
def _inject_owncloud_button(self, linked_object=None, **kwargs):
|
||||
if is_configured():
|
||||
return render_plugin_template('owncloud_button.html', id=linked_object.id, linked_object=linked_object,
|
||||
service_name=self.settings.get('service_name'),
|
||||
button_icon_url=self.settings.get('button_icon_url'))
|
||||
34
owncloud/indico_owncloud/templates/add_owncloud_files.html
Normal file
34
owncloud/indico_owncloud/templates/add_owncloud_files.html
Normal file
@ -0,0 +1,34 @@
|
||||
{% from 'forms/_form.html' import form_header, form_footer, form_rows, form_row %}
|
||||
|
||||
{%- block content %}
|
||||
{{ form_header(form, id='attachment-owncloudfilepicker-form', classes=('full-width')) }}
|
||||
{{ form_row(form.owncloud_filepicker, skip_label=true) }}
|
||||
{{ form_rows(form, fields=('folder', 'protected', 'acl')) }}
|
||||
{{ protection_message | safe }}
|
||||
{% call form_footer(attach_form) %}
|
||||
<input class="i-button big highlight" type="submit" value="{% trans %}Add{% endtrans %}">
|
||||
<button class="i-button big" data-button-back>{% trans %}Cancel{% endtrans %}</button>
|
||||
{% endcall %}
|
||||
<script>
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
$('#{{ form.folder.id }}').nullableselector();
|
||||
const form = $('#attachment-owncloudfilepicker-form');
|
||||
aclIfProtected(
|
||||
$('#{{ form.protected.id }}'),
|
||||
$('#{{ form.acl.id }}'),
|
||||
form.find('.protected-protection-message'),
|
||||
form.find('.inheriting-protection-message'),
|
||||
$('#{{ form.folder.id }}')
|
||||
);
|
||||
messageIfFolderProtected(
|
||||
$('#{{ form.protected.id }}'), $('#{{ form.folder.id }}'),
|
||||
{{ folders_protection_info | tojson }},
|
||||
$('.protected-protection-message'),
|
||||
$('.inheriting-protection-message'),
|
||||
$('.folder-protection-message')
|
||||
);
|
||||
})();
|
||||
</script>
|
||||
{%- endblock %}
|
||||
10
owncloud/indico_owncloud/templates/owncloud_button.html
Normal file
10
owncloud/indico_owncloud/templates/owncloud_button.html
Normal file
@ -0,0 +1,10 @@
|
||||
{% set service_name = service_name or _('the cloud') %}
|
||||
<a href="#" class="i-button js-dialog-action"
|
||||
data-href="{{ url_for_plugin('owncloud.owncloud_event', event_id=id) }}"
|
||||
data-title="{%- trans -%}Add files from {{ service_name }}{%- endtrans -%}">
|
||||
<span class="{{ 'icon-cloud2' if not button_icon_url }}"></span>
|
||||
{%- if button_icon_url -%}
|
||||
<img height="24" src="{{ button_icon_url }}">
|
||||
{%- endif -%}
|
||||
<span class="button-label">{%- trans -%}From {{ service_name }}{%- endtrans -%}</span>
|
||||
</a>
|
||||
@ -0,0 +1,20 @@
|
||||
{% extends 'forms/base_widget.html' %}
|
||||
|
||||
{% block html %}
|
||||
{% set src = field.filepicker_url + '?origin=' + field.origin %}
|
||||
<div class="i-form-field-fixed-width">
|
||||
<input type="hidden" name="{{ field.name }}" id="{{ field.id }}-files" {{ input_args | html_params }}>
|
||||
<span id="{{ field.id }}-container">
|
||||
<iframe id="{{ field.id }}-file-picker" class="owncloudfilepicker" src="{{ src }}"></iframe>
|
||||
</span>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block javascript %}
|
||||
<script>
|
||||
setupOwncloudFilePickerWidget({
|
||||
filepickerUrl: {{ field.filepicker_url | tojson }},
|
||||
fieldId: {{ field.id | tojson }},
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
73
owncloud/indico_owncloud/translations/messages.pot
Normal file
73
owncloud/indico_owncloud/translations/messages.pot
Normal file
@ -0,0 +1,73 @@
|
||||
# Translations template for PROJECT.
|
||||
# Copyright (C) 2022 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2022-03-16 15:30+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.9.1\n"
|
||||
|
||||
#: indico_owncloud/controllers.py:51
|
||||
msgid "Attachment added"
|
||||
msgstr ""
|
||||
|
||||
#: indico_owncloud/forms.py:34
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#: indico_owncloud/plugin.py:24
|
||||
msgid "File-picker URL"
|
||||
msgstr ""
|
||||
|
||||
#: indico_owncloud/plugin.py:25
|
||||
msgid "Service name"
|
||||
msgstr ""
|
||||
|
||||
#: indico_owncloud/plugin.py:26
|
||||
msgid ""
|
||||
"A customized name for the cloud service. If empty, the default 'The "
|
||||
"cloud' will be used."
|
||||
msgstr ""
|
||||
|
||||
#: indico_owncloud/plugin.py:28
|
||||
msgid "Custom icon URL"
|
||||
msgstr ""
|
||||
|
||||
#: indico_owncloud/plugin.py:29
|
||||
msgid ""
|
||||
"URL for a customized icon to show in the add attachment button. If empty,"
|
||||
" the default cloud icon will be used"
|
||||
msgstr ""
|
||||
|
||||
#: indico_owncloud/templates/add_owncloud_files.html:9
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
|
||||
#: indico_owncloud/templates/add_owncloud_files.html:10
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: indico_owncloud/templates/owncloud_button.html:1
|
||||
msgid "the cloud"
|
||||
msgstr ""
|
||||
|
||||
#: indico_owncloud/templates/owncloud_button.html:4
|
||||
#, python-format
|
||||
msgid "Add files from %(service_name)s"
|
||||
msgstr ""
|
||||
|
||||
#: indico_owncloud/templates/owncloud_button.html:9
|
||||
#, python-format
|
||||
msgid "From %(service_name)s"
|
||||
msgstr ""
|
||||
|
||||
18
owncloud/indico_owncloud/util.py
Normal file
18
owncloud/indico_owncloud/util.py
Normal file
@ -0,0 +1,18 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2022 CERN
|
||||
#
|
||||
# The Indico plugins are free software; you can redistribute
|
||||
# them and/or modify them under the terms of the MIT License;
|
||||
# see the LICENSE file for more details.
|
||||
|
||||
def is_configured():
|
||||
"""Check whether the plugin is properly configured."""
|
||||
from indico_owncloud.plugin import OwncloudPlugin
|
||||
|
||||
return bool(OwncloudPlugin.settings.get('filepicker_url'))
|
||||
|
||||
|
||||
def get_filepicker_url():
|
||||
from indico_owncloud.plugin import OwncloudPlugin
|
||||
|
||||
return OwncloudPlugin.settings.get('filepicker_url').rstrip('/')
|
||||
30
owncloud/setup.cfg
Normal file
30
owncloud/setup.cfg
Normal file
@ -0,0 +1,30 @@
|
||||
[metadata]
|
||||
name = indico-plugin-owncloud
|
||||
version = 3.2-dev
|
||||
description = Integrates ownCloud storage as a source for materials
|
||||
long_description = file: README.md
|
||||
long_description_content_type = text/markdown; charset=UTF-8; variant=GFM
|
||||
url = https://github.com/indico/indico-plugins
|
||||
license = MIT
|
||||
author = Indico Team
|
||||
author_email = indico-team@cern.ch
|
||||
classifiers =
|
||||
Environment :: Plugins
|
||||
Environment :: Web Environment
|
||||
License :: OSI Approved :: MIT License
|
||||
Programming Language :: Python :: 3.9
|
||||
|
||||
[options]
|
||||
packages = find:
|
||||
zip_safe = false
|
||||
include_package_data = true
|
||||
python_requires = ~=3.9.0
|
||||
install_requires =
|
||||
indico>=3.2.dev0
|
||||
|
||||
[options.entry_points]
|
||||
indico.plugins =
|
||||
owncloud = indico_owncloud.plugin:OwncloudPlugin
|
||||
|
||||
[pydocstyle]
|
||||
ignore = D100,D101,D102,D103,D104,D105,D107,D203,D213
|
||||
11
owncloud/setup.py
Normal file
11
owncloud/setup.py
Normal file
@ -0,0 +1,11 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2022 CERN
|
||||
#
|
||||
# The Indico plugins are free software; you can redistribute
|
||||
# them and/or modify them under the terms of the MIT License;
|
||||
# see the LICENSE file for more details.
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
setup()
|
||||
6
owncloud/webpack-bundles.json
Normal file
6
owncloud/webpack-bundles.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"entry": {
|
||||
"owncloud": "./index.js",
|
||||
"main": "./style.scss"
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user