mirror of
https://github.com/lucaspalomodevelop/indico-plugins.git
synced 2026-03-12 23:27:22 +00:00
Merge branch '2.2-maintenance'
This commit is contained in:
commit
25d262a71f
4
ursh/MANIFEST.in
Normal file
4
ursh/MANIFEST.in
Normal file
@ -0,0 +1,4 @@
|
||||
graft indico_ursh/static
|
||||
graft indico_ursh/translations
|
||||
|
||||
global-exclude *.pyc __pycache__ .keep
|
||||
13
ursh/indico_ursh/__init__.py
Normal file
13
ursh/indico_ursh/__init__.py
Normal file
@ -0,0 +1,13 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2019 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 __future__ import unicode_literals
|
||||
|
||||
from indico.util.i18n import make_bound_gettext
|
||||
|
||||
|
||||
_ = make_bound_gettext('ursh')
|
||||
19
ursh/indico_ursh/blueprint.py
Normal file
19
ursh/indico_ursh/blueprint.py
Normal file
@ -0,0 +1,19 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2019 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 __future__ import unicode_literals
|
||||
|
||||
from indico.core.plugins import IndicoPluginBlueprint
|
||||
|
||||
from indico_ursh.controllers import RHCustomShortURLPage, RHGetShortURL, RHShortURLPage
|
||||
|
||||
|
||||
blueprint = IndicoPluginBlueprint('ursh', 'indico_ursh')
|
||||
blueprint.add_url_rule('/ursh', 'get_short_url', RHGetShortURL, methods=('POST',))
|
||||
blueprint.add_url_rule('/url-shortener', 'shorten_url', RHShortURLPage)
|
||||
blueprint.add_url_rule('/event/<confId>/manage/short-url', 'shorten_event_url', RHCustomShortURLPage,
|
||||
methods=('GET', 'POST'))
|
||||
150
ursh/indico_ursh/client/index.js
Normal file
150
ursh/indico_ursh/client/index.js
Normal file
@ -0,0 +1,150 @@
|
||||
// This file is part of the Indico plugins.
|
||||
// Copyright (C) 2002 - 2019 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.
|
||||
|
||||
/* global $T:false */
|
||||
|
||||
import {handleAxiosError, indicoAxios} from 'indico/utils/axios';
|
||||
|
||||
const $t = $T.domain('ursh');
|
||||
|
||||
function _showTip(element, msg, hideEvent = 'unfocus') {
|
||||
element.qtip({
|
||||
content: {
|
||||
text: msg,
|
||||
},
|
||||
hide: {
|
||||
event: hideEvent,
|
||||
fixed: true,
|
||||
delay: 700,
|
||||
},
|
||||
show: {
|
||||
event: false,
|
||||
ready: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function _makeUrshRequest(originalURL) {
|
||||
const urshEndpoint = '/ursh';
|
||||
|
||||
let response;
|
||||
try {
|
||||
response = await indicoAxios.post(urshEndpoint, {
|
||||
original_url: originalURL,
|
||||
});
|
||||
} catch (error) {
|
||||
handleAxiosError(error);
|
||||
return;
|
||||
}
|
||||
|
||||
return response.data.url;
|
||||
}
|
||||
|
||||
function _validateAndFormatURL(url) {
|
||||
if (!url) {
|
||||
throw Error($t.gettext('Please fill in a URL to shorten'));
|
||||
}
|
||||
|
||||
// if protocol is missing, prepend it
|
||||
if (url.startsWith(location.hostname)) {
|
||||
url = `${location.protocol}//${url}`;
|
||||
}
|
||||
|
||||
// regular expression, because I.E. does not like the URL class
|
||||
// provides minimal validation, leaving the serious job to the server
|
||||
const re = RegExp(`^([\\d\\w]+:)//([^/ .]+(?:\\.[^/ .]+)*)(/.*)?$`);
|
||||
const urlTokens = url.match(re);
|
||||
if (!urlTokens) {
|
||||
throw Error($t.gettext('This does not look like a valid URL'));
|
||||
}
|
||||
|
||||
// extract tokens
|
||||
const hostname = urlTokens[2];
|
||||
const path = urlTokens[3] ? urlTokens[3] : '/';
|
||||
|
||||
const protocol = location.protocol; // patch protocol to match server
|
||||
if (hostname !== location.hostname) {
|
||||
throw Error($t.gettext('Invalid host: only Indico URLs are allowed'));
|
||||
}
|
||||
|
||||
return `${protocol}//${hostname}${path}`;
|
||||
}
|
||||
|
||||
function _getUrshInput(input) {
|
||||
const inputURL = input.val().trim();
|
||||
input.val(inputURL);
|
||||
|
||||
try {
|
||||
const formattedURL = _validateAndFormatURL(inputURL);
|
||||
input.val(formattedURL);
|
||||
return formattedURL;
|
||||
} catch (err) {
|
||||
_showTip(input, err.message);
|
||||
input.focus().select();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function _handleUrshPageInput(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
const input = $('#ursh-shorten-input');
|
||||
const originalURL = _getUrshInput(input);
|
||||
if (originalURL) {
|
||||
const result = await _makeUrshRequest(originalURL);
|
||||
if (result) {
|
||||
const outputElement = $('#ursh-shorten-output');
|
||||
$('#ursh-shorten-response-form').slideDown();
|
||||
outputElement.val(result);
|
||||
outputElement.select();
|
||||
} else {
|
||||
_showTip(input, $t.gettext('This does not look like a valid URL'));
|
||||
input.focus().select();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function _handleUrshClick(evt) {
|
||||
evt.preventDefault();
|
||||
const originalURL = evt.target.dataset.originalUrl;
|
||||
const result = await _makeUrshRequest(originalURL);
|
||||
$(evt.target).copyURLTooltip(result, 'unfocus');
|
||||
}
|
||||
|
||||
function _validateUrshCustomShortcut(shortcut) {
|
||||
return shortcut.length >= 5;
|
||||
}
|
||||
|
||||
$(document)
|
||||
.on('click', '#ursh-shorten-button', _handleUrshPageInput)
|
||||
.on('keydown', '#ursh-shorten-input', evt => {
|
||||
if (evt.key === 'Enter') {
|
||||
_handleUrshPageInput(evt);
|
||||
}
|
||||
})
|
||||
.on('click', '.ursh-get', _handleUrshClick)
|
||||
.on('input', '#ursh-custom-shortcut-input', evt => {
|
||||
const value = $(evt.target).val();
|
||||
$('#ursh-custom-shortcut-submit-button').prop('disabled', !_validateUrshCustomShortcut(value));
|
||||
})
|
||||
.on('mouseenter', '#ursh-custom-shortcut-submit-button', evt => {
|
||||
if (evt.target.disabled) {
|
||||
_showTip(
|
||||
$(evt.target),
|
||||
$t.gettext('Please check that the shortcut is correct'),
|
||||
'mouseleave'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
$(document).ready(() => {
|
||||
// keep dropdown menu open when clicking on an entry
|
||||
$('.ursh-dropdown')
|
||||
.next('ul')
|
||||
.find('li a')
|
||||
.on('menu_select', () => true);
|
||||
});
|
||||
103
ursh/indico_ursh/controllers.py
Normal file
103
ursh/indico_ursh/controllers.py
Normal file
@ -0,0 +1,103 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2019 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 __future__ import unicode_literals
|
||||
|
||||
import posixpath
|
||||
|
||||
from flask import jsonify, request, session
|
||||
from flask_pluginengine import render_plugin_template
|
||||
from werkzeug.exceptions import BadRequest
|
||||
from werkzeug.urls import url_parse
|
||||
|
||||
from indico.core.config import config
|
||||
from indico.modules.events.management.controllers import RHManageEventBase
|
||||
from indico.web.rh import RH
|
||||
from indico.web.util import jsonify_template
|
||||
|
||||
from indico_ursh import _
|
||||
from indico_ursh.util import register_shortcut, request_short_url, strip_end
|
||||
from indico_ursh.views import WPShortenURLPage
|
||||
|
||||
|
||||
CUSTOM_SHORTCUT_ALPHABET = frozenset('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-')
|
||||
|
||||
|
||||
class RHGetShortURL(RH):
|
||||
"""Make a request to the URL shortening service"""
|
||||
|
||||
@staticmethod
|
||||
def _resolve_full_url(original_url):
|
||||
if url_parse(original_url).host:
|
||||
return original_url
|
||||
original_url = original_url.lstrip('/')
|
||||
return posixpath.join(config.BASE_URL, original_url)
|
||||
|
||||
@staticmethod
|
||||
def _check_host(full_url):
|
||||
if url_parse(full_url).host != url_parse(config.BASE_URL).host:
|
||||
raise BadRequest('Invalid host for URL shortening service')
|
||||
|
||||
def _process(self):
|
||||
original_url = request.json.get('original_url')
|
||||
full_url = self._resolve_full_url(original_url)
|
||||
self._check_host(full_url)
|
||||
short_url = request_short_url(full_url)
|
||||
return jsonify(url=short_url)
|
||||
|
||||
|
||||
class RHShortURLPage(RH):
|
||||
"""Provide a simple page, where users can submit a URL to be shortened"""
|
||||
|
||||
def _process(self):
|
||||
return WPShortenURLPage.render_template('ursh_shortener_page.html')
|
||||
|
||||
|
||||
class RHCustomShortURLPage(RHManageEventBase):
|
||||
"""Provide a simple page, where users can submit a URL to be shortened"""
|
||||
|
||||
def _make_absolute_url(self, url):
|
||||
return posixpath.join(config.BASE_URL, url[1:]) if url.startswith('/') else url
|
||||
|
||||
def _get_error_msg(self, result):
|
||||
if result['status'] == 409:
|
||||
return _('Shortcut already exists')
|
||||
elif result['status'] == 400:
|
||||
return _('Malformed shortcut')
|
||||
return result['error'].get('description')
|
||||
|
||||
def _process_args(self):
|
||||
from indico_ursh.plugin import UrshPlugin
|
||||
super(RHCustomShortURLPage, self)._process_args()
|
||||
api_host = url_parse(UrshPlugin.settings.get('api_host'))
|
||||
self.ursh_host = strip_end(api_host.to_url(), api_host.path[1:]).rstrip('/') + '/'
|
||||
|
||||
def _process_GET(self):
|
||||
original_url = self._make_absolute_url(request.args['original_url'])
|
||||
return WPShortenURLPage.render_template('ursh_custom_shortener_page.html',
|
||||
event=self.event,
|
||||
ursh_host=self.ursh_host,
|
||||
original_url=original_url,
|
||||
submitted=False)
|
||||
|
||||
def _process_POST(self):
|
||||
original_url = self._make_absolute_url(request.args['original_url'])
|
||||
shortcut = request.form['shortcut'].strip()
|
||||
|
||||
if not (set(shortcut) <= CUSTOM_SHORTCUT_ALPHABET):
|
||||
raise BadRequest('Invalid shortcut')
|
||||
|
||||
result = register_shortcut(original_url, shortcut, session.user)
|
||||
|
||||
if result.get('error'):
|
||||
kwargs = {'success': False, 'msg': self._get_error_msg(result)}
|
||||
else:
|
||||
kwargs = {'success': True, 'shorturl': result['short_url']}
|
||||
|
||||
return jsonify_template('ursh_custom_shortener_page.html', render_plugin_template,
|
||||
event=self.event, ursh_host=self.ursh_host, shortcut=shortcut,
|
||||
original_url=original_url, submitted=True, **kwargs)
|
||||
58
ursh/indico_ursh/plugin.py
Normal file
58
ursh/indico_ursh/plugin.py
Normal file
@ -0,0 +1,58 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2019 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 __future__ import unicode_literals
|
||||
|
||||
from flask_pluginengine import render_plugin_template
|
||||
from wtforms.fields.core import StringField
|
||||
from wtforms.fields.html5 import URLField
|
||||
from wtforms.validators import DataRequired
|
||||
|
||||
from indico.core.plugins import IndicoPlugin
|
||||
from indico.web.forms.base import IndicoForm
|
||||
from indico.web.views import WPBase
|
||||
|
||||
from indico_ursh import _
|
||||
from indico_ursh.blueprint import blueprint
|
||||
|
||||
|
||||
class SettingsForm(IndicoForm):
|
||||
api_key = StringField(_('API key'), [DataRequired()],
|
||||
description=_('The API key to access the <tt>ursh</tt> service'))
|
||||
api_host = URLField(_('API host'), [DataRequired()],
|
||||
description=_('The <tt>ursh</tt> API host, providing the interface to generate short URLs'))
|
||||
|
||||
|
||||
class UrshPlugin(IndicoPlugin):
|
||||
"""URL Shortener
|
||||
|
||||
Provides a URL shortening service for indico assets, events, etc.
|
||||
"""
|
||||
|
||||
configurable = True
|
||||
settings_form = SettingsForm
|
||||
default_settings = {
|
||||
'api_key': '',
|
||||
'api_host': '',
|
||||
}
|
||||
|
||||
def init(self):
|
||||
super(UrshPlugin, self).init()
|
||||
self.template_hook('url-shortener', self._inject_ursh_link)
|
||||
self.template_hook('page-footer', self._inject_ursh_footer)
|
||||
self.inject_bundle('main.js', WPBase)
|
||||
|
||||
def get_blueprints(self):
|
||||
return blueprint
|
||||
|
||||
def _inject_ursh_link(self, target=None, event=None, dropdown=False, element_class='', text='', **kwargs):
|
||||
if self.settings.get('api_key') and self.settings.get('api_host') and (target or event):
|
||||
return render_plugin_template('ursh_link.html', target=target, event=event,
|
||||
dropdown=dropdown, element_class=element_class, text=text, **kwargs)
|
||||
|
||||
def _inject_ursh_footer(self, **kwargs):
|
||||
return render_plugin_template('ursh_footer.html')
|
||||
57
ursh/indico_ursh/templates/ursh_custom_shortener_page.html
Normal file
57
ursh/indico_ursh/templates/ursh_custom_shortener_page.html
Normal file
@ -0,0 +1,57 @@
|
||||
{% extends 'layout/base.html' %}
|
||||
|
||||
{% block page_class %}fixed-width-standalone-text-page{% endblock %}
|
||||
|
||||
{% block title -%}
|
||||
{% trans %}Create custom shortcut{% endtrans %}
|
||||
{%- endblock %}
|
||||
|
||||
{% block content -%}
|
||||
{% if submitted and not success %}
|
||||
<div class="error-message-box">
|
||||
<div class="message-box-content">
|
||||
<span class="icon"></span>
|
||||
<div class="message-text">{% trans %}Custom URL creation failed:{% endtrans %} {{ msg }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% elif submitted and success %}
|
||||
<div class="success-message-box">
|
||||
<div class="message-box-content">
|
||||
<span class="icon"></span>
|
||||
<div class="message-text">{% trans %}Custom URL created successfully{% endtrans %}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<p>{% trans %}Creating a custom shortcut for the following URL:{% endtrans %}</p>
|
||||
<div class="i-has-action">
|
||||
<input type="url" style="font-family:monospace;" value="{{ original_url }}" disabled>
|
||||
</div>
|
||||
<p>{% trans %}Please enter the desired shortcut below (at least 5 chars).{% endtrans %}</p>
|
||||
<form method="POST">
|
||||
<div class="i-has-action">
|
||||
<button type="button" class="i-button" style="font-family:monospace;" disabled>
|
||||
{{- ursh_host -}}
|
||||
</button>
|
||||
<input id="ursh-custom-shortcut-input" name="shortcut" type="text" style="font-family:monospace;"
|
||||
spellcheck="false" autocomplete="off" autocapitalize="off"
|
||||
pattern="^[0-9a-zA-Z-]{5,}$"
|
||||
{% if shortcut %}value="{{ shortcut }}"{% endif %}
|
||||
placeholder="{% trans %}Enter a shortcut...{% endtrans %}">
|
||||
<button id="ursh-custom-shortcut-submit-button" type="submit" class="i-button" disabled>
|
||||
{% trans -%}Create{%- endtrans %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<script>
|
||||
$(document).ready(() => {
|
||||
$('#ursh-custom-shortcut-input').focus().select();
|
||||
});
|
||||
</script>
|
||||
{% if submitted and success and shorturl %}
|
||||
<script>
|
||||
$(document).ready(() => {
|
||||
$('#ursh-custom-shortcut-input').copyURLTooltip({{ shorturl | tojson }}, 'unfocus');
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{%- endblock %}
|
||||
23
ursh/indico_ursh/templates/ursh_dropdown.html
Normal file
23
ursh/indico_ursh/templates/ursh_dropdown.html
Normal file
@ -0,0 +1,23 @@
|
||||
<a href="" class="arrow js-dropdown ursh-dropdown {{ element_class }}" data-toggle="dropdown"
|
||||
title="{% trans %}Short URL options{% endtrans %}"></a>
|
||||
<ul class="i-dropdown">
|
||||
<li>
|
||||
<a class="ursh-get"
|
||||
data-original-url="{{ target }}">
|
||||
{{ trans }}Get short URL{{ end_trans }}
|
||||
</a>
|
||||
</li>
|
||||
{%- if allow_create %}
|
||||
<li>
|
||||
<a href="{{ url_for('plugin_ursh.shorten_url_custom') }}"
|
||||
class="ursh-create" data-original-url="{{ target }}"
|
||||
data-title="{{ _('Create short URL') }}"
|
||||
data-href="{{ url_for('plugin_ursh.shorten_url_custom') }}"
|
||||
data-params='{"original_url": "{{ target }}"}'
|
||||
data-ajax-dialog
|
||||
data-hide-page-header>
|
||||
{{ trans }}Create custom short URL{{ end_trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif -%}
|
||||
</ul>
|
||||
8
ursh/indico_ursh/templates/ursh_footer.html
Normal file
8
ursh/indico_ursh/templates/ursh_footer.html
Normal file
@ -0,0 +1,8 @@
|
||||
<a href="{{ url_for('plugin_ursh.shorten_url') }}"
|
||||
data-title="{{ _("URL Shortener") }}"
|
||||
data-href="{{ url_for('plugin_ursh.shorten_url', url=request.url) }}"
|
||||
data-ajax-dialog
|
||||
data-hide-page-header
|
||||
data-close-button>
|
||||
{% trans %}URL Shortener{% endtrans %}
|
||||
</a>
|
||||
32
ursh/indico_ursh/templates/ursh_link.html
Normal file
32
ursh/indico_ursh/templates/ursh_link.html
Normal file
@ -0,0 +1,32 @@
|
||||
{% set event_manager = event and event.can_manage(session.user) %}
|
||||
{% set target = event.url if event else target %}
|
||||
{% if dropdown or event_manager %}
|
||||
<a href="#" class="arrow js-dropdown ursh-dropdown {{ classes }}" data-toggle="dropdown"
|
||||
title="{% trans %}Short URL options{% endtrans %}"></a>
|
||||
<ul class="i-dropdown">
|
||||
<li>
|
||||
<a class="ursh-get" data-original-url="{{ target }}">
|
||||
{{ trans }}Get short URL{{ end_trans }}
|
||||
</a>
|
||||
</li>
|
||||
{%- if event_manager %}
|
||||
<li>
|
||||
<a href="{{ url_for('plugin_ursh.shorten_event_url', event) }}"
|
||||
class="ursh-create" data-original-url="{{ target }}"
|
||||
data-title="{{ _('Create short URL') }}"
|
||||
data-href="{{ url_for('plugin_ursh.shorten_event_url', event) }}"
|
||||
data-params='{"original_url": "{{ target }}"}'
|
||||
data-ajax-dialog
|
||||
data-hide-page-header>
|
||||
{{ trans }}Create custom short URL{{ end_trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif -%}
|
||||
</ul>
|
||||
{% else %}
|
||||
<a class="ursh-get {{ classes }}"
|
||||
title="{% trans %}Obtain short URL{% endtrans %}"
|
||||
data-original-url="{{ target }}">
|
||||
{{- text -}}
|
||||
</a>
|
||||
{% endif %}
|
||||
36
ursh/indico_ursh/templates/ursh_shortener_page.html
Normal file
36
ursh/indico_ursh/templates/ursh_shortener_page.html
Normal file
@ -0,0 +1,36 @@
|
||||
{% extends 'layout/base.html' %}
|
||||
|
||||
{% block page_class %}fixed-width-standalone-text-page{% endblock %}
|
||||
|
||||
{% block title -%}
|
||||
{% trans %}URL Shortener{% endtrans %}
|
||||
{%- endblock %}
|
||||
|
||||
{% block content -%}
|
||||
<p>
|
||||
{% trans -%}
|
||||
In this page, you can generate short links for any Indico URL.
|
||||
Just enter the URL below and click "Shorten".
|
||||
{%- endtrans %}
|
||||
</p>
|
||||
<div id="ursh-shorten-request-form" class="i-has-action">
|
||||
<input id="ursh-shorten-input" name="ursh-shorten-original-url" type="url" style="font-family:monospace;"
|
||||
spellcheck="false" autocomplete="off" autocapitalize="off"
|
||||
value="{{ request.args.url }}"
|
||||
placeholder="{% trans %}Enter an Indico URL to shorten...{% endtrans %}">
|
||||
<button id="ursh-shorten-button" type="button" class="i-button">{% trans %}Shorten{% endtrans %}</button>
|
||||
</div>
|
||||
<div id="ursh-shorten-response-form" class="i-has-action" style="margin-top:1em;display:none">
|
||||
<input id="ursh-shorten-output" name="ursh-shorten-short-url" type="url" style="font-family:monospace;"
|
||||
spellcheck="false" autocomplete="off" autocapitalize="off" readonly>
|
||||
<button type="button" class="i-button icon-clipboard js-copy-to-clipboard"
|
||||
title="{% trans %}Copy to clipboard{% endtrans %}"
|
||||
data-clipboard-target="#ursh-shorten-output"></button>
|
||||
</div>
|
||||
<p>
|
||||
{% trans -%}
|
||||
<strong>Tip:</strong> You can also generate short links by using the quick-links in various
|
||||
places within Indico! Just look for the <span class="icon-link"></span> icon.
|
||||
{%- endtrans %}
|
||||
</p>
|
||||
{%- endblock %}
|
||||
61
ursh/indico_ursh/util.py
Normal file
61
ursh/indico_ursh/util.py
Normal file
@ -0,0 +1,61 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2019 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 __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
import posixpath
|
||||
|
||||
import requests
|
||||
from werkzeug.exceptions import ServiceUnavailable
|
||||
|
||||
|
||||
def _get_settings():
|
||||
from indico_ursh.plugin import UrshPlugin
|
||||
api_key = UrshPlugin.settings.get('api_key')
|
||||
api_host = UrshPlugin.settings.get('api_host')
|
||||
|
||||
if not api_key or not api_host:
|
||||
raise ServiceUnavailable('Not configured')
|
||||
|
||||
return api_key, api_host
|
||||
|
||||
|
||||
def request_short_url(original_url):
|
||||
from indico_ursh.plugin import UrshPlugin
|
||||
api_key, api_host = _get_settings()
|
||||
headers = {'Authorization': 'Bearer {api_key}'.format(api_key=api_key), 'Content-Type': 'application/json'}
|
||||
url = posixpath.join(api_host, 'api/urls/')
|
||||
|
||||
response = requests.post(url, data=json.dumps({'url': original_url, 'allow_reuse': True}), headers=headers)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
UrshPlugin.logger.info('Shortcut created: %s -> %s', data['shortcut'], original_url)
|
||||
return data['short_url']
|
||||
|
||||
|
||||
def register_shortcut(original_url, shortcut, user):
|
||||
from indico_ursh.plugin import UrshPlugin
|
||||
api_key, api_host = _get_settings()
|
||||
headers = {'Authorization': 'Bearer {api_key}'.format(api_key=api_key), 'Content-Type': 'application/json'}
|
||||
url = posixpath.join(api_host, 'api/urls', shortcut)
|
||||
data = {'url': original_url, 'allow_reuse': True, 'meta': {'indico.user': user.id}}
|
||||
|
||||
response = requests.put(url, data=json.dumps(data), headers=headers)
|
||||
if not (400 <= response.status_code < 500):
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
if not data.get('error'):
|
||||
UrshPlugin.logger.info('Shortcut created: %s -> %s', data['shortcut'], original_url)
|
||||
return data
|
||||
|
||||
|
||||
def strip_end(text, suffix):
|
||||
if not text.endswith(suffix):
|
||||
return text
|
||||
return text[:len(text) - len(suffix)]
|
||||
16
ursh/indico_ursh/views.py
Normal file
16
ursh/indico_ursh/views.py
Normal file
@ -0,0 +1,16 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2019 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 __future__ import unicode_literals
|
||||
|
||||
from indico.core.plugins import WPJinjaMixinPlugin
|
||||
from indico.web.views import WPDecorated
|
||||
|
||||
|
||||
class WPShortenURLPage(WPJinjaMixinPlugin, WPDecorated):
|
||||
def _get_body(self, params):
|
||||
return self._get_page_content(params)
|
||||
34
ursh/setup.py
Normal file
34
ursh/setup.py
Normal file
@ -0,0 +1,34 @@
|
||||
# This file is part of the Indico plugins.
|
||||
# Copyright (C) 2002 - 2019 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 __future__ import unicode_literals
|
||||
|
||||
from setuptools import find_packages, setup
|
||||
|
||||
|
||||
setup(
|
||||
name='indico-plugin-ursh',
|
||||
version='2.2',
|
||||
description='URL shortening service for Indico',
|
||||
url='https://github.com/indico/indico-plugins',
|
||||
license='MIT',
|
||||
author='Indico Team',
|
||||
author_email='indico-team@cern.ch',
|
||||
packages=find_packages(),
|
||||
zip_safe=False,
|
||||
include_package_data=True,
|
||||
install_requires=[
|
||||
'indico>=2.2.dev0',
|
||||
],
|
||||
classifiers=[
|
||||
'Environment :: Plugins',
|
||||
'Environment :: Web Environment',
|
||||
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
|
||||
'Programming Language :: Python :: 2.7'
|
||||
],
|
||||
entry_points={'indico.plugins': {'ursh = indico_ursh.plugin:UrshPlugin'}}
|
||||
)
|
||||
5
ursh/webpack-bundles.json
Normal file
5
ursh/webpack-bundles.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"entry": {
|
||||
"main": "./index.js"
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user