mirror of
https://github.com/lucaspalomodevelop/indico-plugins.git
synced 2026-03-13 07:29:39 +00:00
Importer: Adapt contribution/subcontribution creation
This commit is contained in:
parent
ae9be2ebb4
commit
b60e2389dc
@ -16,9 +16,17 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from flask import jsonify, request
|
||||
from flask_pluginengine import current_plugin
|
||||
from pytz import timezone, utc
|
||||
from werkzeug.exceptions import NotFound
|
||||
|
||||
from indico.core.db import db
|
||||
from indico.modules.events.timetable.controllers import RHManageTimetableBase
|
||||
from indico.modules.events.timetable.models.entries import TimetableEntry, TimetableEntryType
|
||||
from MaKaC.webinterface.rh.base import RHProtected
|
||||
|
||||
|
||||
@ -36,3 +44,70 @@ class RHImportData(RHProtected):
|
||||
with plugin.plugin_context():
|
||||
data = {'records': importer.import_data(query, size)}
|
||||
return jsonify(data)
|
||||
|
||||
|
||||
class RHEndTimeBase(RHManageTimetableBase):
|
||||
"""Base class for the importer operations"""
|
||||
normalize_url_spec = {
|
||||
'locators': {
|
||||
lambda self: self.event_new
|
||||
},
|
||||
'preserved_args': {
|
||||
'importer_name'
|
||||
}
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _find_latest_end_dt(entries):
|
||||
latest_dt = None
|
||||
for entry in entries:
|
||||
if latest_dt is None or entry.end_dt > latest_dt:
|
||||
latest_dt = entry.end_dt
|
||||
return latest_dt
|
||||
|
||||
def _format_date(self, date):
|
||||
return date.astimezone(timezone(self.event_new.timezone)).strftime('%H:%M')
|
||||
|
||||
|
||||
class RHDayEndTime(RHEndTimeBase):
|
||||
"""Get the end_dt of the latest timetable entry or the event start_dt if no entry exist on that date"""
|
||||
|
||||
def _checkParams(self, params):
|
||||
RHEndTimeBase._checkParams(self, params)
|
||||
self.date = self.event_new.tzinfo.localize(datetime.strptime(request.args['selectedDay'], '%Y/%m/%d')).date()
|
||||
|
||||
def _process(self):
|
||||
event_start_date = db.cast(TimetableEntry.start_dt.astimezone(self.event_new.tzinfo), db.Date)
|
||||
entries = self.event_new.timetable_entries.filter(event_start_date == self.date)
|
||||
latest_end_dt = self._find_latest_end_dt(entries)
|
||||
if latest_end_dt is None:
|
||||
event_start = self.event_new.start_dt
|
||||
latest_end_dt = utc.localize(datetime.combine(self.date, event_start.time()))
|
||||
return self._format_date(latest_end_dt)
|
||||
|
||||
|
||||
class RHBlockEndTime(RHEndTimeBase):
|
||||
"""Return the end_dt of the latest timetable entry inside the block or the block start_dt if it is empty"""
|
||||
|
||||
normalize_url_spec = {
|
||||
'locators': {
|
||||
lambda self: self.timetable_entry
|
||||
},
|
||||
'preserved_args': {
|
||||
'importer_name'
|
||||
}
|
||||
}
|
||||
|
||||
def _checkParams(self, params):
|
||||
RHEndTimeBase._checkParams(self, params)
|
||||
self.date = timezone(self.event_new.timezone).localize(datetime.strptime(request.args['selectedDay'],
|
||||
'%Y/%m/%d'))
|
||||
self.timetable_entry = self.event_new.timetable_entries.filter_by(
|
||||
type=TimetableEntryType.SESSION_BLOCK, id=request.view_args['entry_id']).first_or_404()
|
||||
|
||||
def _process(self):
|
||||
entries = self.timetable_entry.children
|
||||
latest_end_dt = self._find_latest_end_dt(entries)
|
||||
if latest_end_dt is None:
|
||||
latest_end_dt = self.timetable_entry.start_dt
|
||||
return self._format_date(latest_end_dt)
|
||||
|
||||
@ -18,9 +18,10 @@ from __future__ import unicode_literals
|
||||
|
||||
from indico.core import signals
|
||||
from indico.core.plugins import IndicoPlugin, IndicoPluginBlueprint, plugin_url_rule_to_js, PluginCategory
|
||||
from indico.modules.events.timetable.views import WPManageTimetable
|
||||
|
||||
from indico_importer import _
|
||||
from indico_importer.controllers import RHGetImporters, RHImportData
|
||||
from indico_importer.controllers import RHGetImporters, RHImportData, RHDayEndTime, RHBlockEndTime
|
||||
|
||||
|
||||
class ImporterPlugin(IndicoPlugin):
|
||||
@ -33,8 +34,8 @@ class ImporterPlugin(IndicoPlugin):
|
||||
|
||||
def init(self):
|
||||
super(ImporterPlugin, self).init()
|
||||
# self.inject_js('importer_js', WPConfModifScheduleGraphic)
|
||||
# self.inject_css('importer_css', WPConfModifScheduleGraphic)
|
||||
self.inject_js('importer_js', WPManageTimetable)
|
||||
self.inject_css('importer_css', WPManageTimetable)
|
||||
self.connect(signals.event.timetable_buttons, self.get_timetable_buttons)
|
||||
self.importer_engines = {}
|
||||
|
||||
@ -59,3 +60,7 @@ class ImporterPlugin(IndicoPlugin):
|
||||
blueprint = IndicoPluginBlueprint('importer', __name__)
|
||||
blueprint.add_url_rule('/importers/<importer_name>/search', 'import_data', RHImportData, methods=('POST',))
|
||||
blueprint.add_url_rule('/importers/', 'importers', RHGetImporters)
|
||||
|
||||
blueprint.add_url_rule('/importers/<importer_name>/event/<confId>/day-end-date', 'day_end_date', RHDayEndTime)
|
||||
blueprint.add_url_rule('/importers/<importer_name>/event/<confId>/entry/<entry_id>/block-end-date', 'block_end_date',
|
||||
RHBlockEndTime)
|
||||
|
||||
@ -83,7 +83,7 @@
|
||||
* Checks if a dictionary contains empty person data.
|
||||
*/
|
||||
isPersonEmpty: function(person) {
|
||||
return person && (person.firstName || person.familyName);
|
||||
return !person || (!person.firstName && !person.familyName);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -96,6 +96,8 @@
|
||||
* @param finalCallback Function executed after finishing all requests.
|
||||
*/
|
||||
multipleIndicoRequest: function(reqList, successCallback, errorCallback, finalCallback) {
|
||||
return ImporterUtils._sendMultipleRequests(reqList, successCallback, errorCallback, finalCallback);
|
||||
/*
|
||||
if (reqList.length > 0) {
|
||||
indicoRequest( reqList[0].method, reqList[0].args, function(result, error) {
|
||||
if (result && successCallback) {
|
||||
@ -110,7 +112,42 @@
|
||||
} else if (finalCallback) {
|
||||
finalCallback();
|
||||
}
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
_sendMultipleRequests: function(reqList, onSuccess, onError, onComplete) {
|
||||
$.each(reqList, function(index, req) {
|
||||
ImporterUtils._sendRequest(req.url, req.args, onSuccess, onError);
|
||||
});
|
||||
if (onComplete) {
|
||||
onComplete();
|
||||
}
|
||||
},
|
||||
|
||||
_sendRequest: function(url, args, onSuccess, onError, onComplete) {
|
||||
$.ajax({
|
||||
url: url,
|
||||
method: 'POST',
|
||||
data: args,
|
||||
success: function(data) {
|
||||
if (data.success) {
|
||||
onSuccess(data.entries[0]);
|
||||
} else {
|
||||
// FIXME where is the error message?
|
||||
window.console.log(data);
|
||||
onError("An error occured while adding the contribution.");
|
||||
}
|
||||
},
|
||||
error: function(jqxhr, textStatus, errorThrown) {
|
||||
onError(textStatus + ': ' + errorThrown);
|
||||
},
|
||||
complete: onComplete
|
||||
});
|
||||
if (onComplete) {
|
||||
onComplete();
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -418,25 +455,28 @@
|
||||
self.info.set("startTime", this.destination.startDate.time.substr(0, 5));
|
||||
hook.set(true);
|
||||
} else {
|
||||
var method;
|
||||
var url;
|
||||
if (this.destination.entryType == 'Day') {
|
||||
method = 'schedule.event.getDayEndDate';
|
||||
// FIXME build URL in a better way
|
||||
url = '/importers/indico_importer/event/' + this.confId + '/day-end-date'
|
||||
}
|
||||
if (this.destination.entryType == 'Session') {
|
||||
method = 'schedule.slot.getDayEndDate';
|
||||
// FIXME build URL in a better way
|
||||
url = '/importers/indico_importer/event/' + this.confId + '/entry/' +
|
||||
this.destination.scheduleEntryId + '/block-end-date';
|
||||
}
|
||||
indicoRequest(method, {
|
||||
'confId': this.confId,
|
||||
'sessionId': this.destination.sessionId,
|
||||
'slotId': this.destination.sessionSlotId,
|
||||
'selectedDay': this.destination.startDate.date.replace(/-/g, '/')},
|
||||
function(result, error) {
|
||||
if (!error) {
|
||||
self.info.set("startTime", result.substr(11, 5));
|
||||
}
|
||||
$.ajax({
|
||||
url: url,
|
||||
data: {
|
||||
sessionId: this.destination.sessionId,
|
||||
slotId: this.destination.sessionSlotId,
|
||||
selectedDay: this.destination.startDate.date.replace(/-/g, '/')
|
||||
},
|
||||
success: function(data) {
|
||||
self.info.set('startTime', data);
|
||||
hook.set(true);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -492,6 +532,47 @@
|
||||
}
|
||||
},
|
||||
|
||||
_getUrl: function(legacy_method, eventId, day, destination) {
|
||||
var params = "?" + $.param({'day': day});
|
||||
if (legacy_method == 'schedule.event.addContribution') {
|
||||
// FIXME build URL in a better way
|
||||
return '/event/' + eventId + '/manage/timetable/add-contribution' + params;
|
||||
}
|
||||
if (legacy_method == 'schedule.slot.addContribution') {
|
||||
params += '&' + $.param({'session_block_id': destination.sessionSlotId});
|
||||
// FIXME build URL in a better way
|
||||
return '/event/' + eventId + '/manage/timetable/add-contribution' + params;
|
||||
}
|
||||
if (legacy_method == 'contribution.addSubContribution') {
|
||||
// FIXME build URL in a better way
|
||||
return '/event/' + eventId + '/manage/contributions/' + destination.contributionId +
|
||||
'/subcontributions/create';
|
||||
}
|
||||
// FIXME
|
||||
alert('Unsupported method: ' + legacy_method);
|
||||
},
|
||||
|
||||
_personLinkData: function(entry) {
|
||||
var linkDataEntry = function(author, primary, speaker) {
|
||||
return $.extend({
|
||||
'authorType': primary ? 1 : 2,
|
||||
'isSpeaker': speaker,
|
||||
'isSubmitter': !speaker
|
||||
}, author);
|
||||
};
|
||||
var linkData = [];
|
||||
if (!ImporterUtils.isPersonEmpty(entry.primaryAuthor)) {
|
||||
linkData.push(linkDataEntry(entry.primaryAuthor, true, false));
|
||||
}
|
||||
if (!ImporterUtils.isPersonEmpty(entry.secondaryAuthor)) {
|
||||
linkData.push(linkDataEntry(entry.secondaryAuthor, false, false));
|
||||
}
|
||||
if (!ImporterUtils.isPersonEmpty(entry.speaker)) {
|
||||
linkData.push(linkDataEntry(entry.speaker, false, true));
|
||||
}
|
||||
return linkData;
|
||||
},
|
||||
|
||||
_getButtons: function() {
|
||||
var self = this;
|
||||
return [
|
||||
@ -512,30 +593,40 @@
|
||||
each(self.entries.getValues(), function(entry) {
|
||||
entry = entry.getAll();
|
||||
var timeStr = ImporterUtils.minutesToTime(time);
|
||||
args.push({'method' : method,
|
||||
'args' : {'conference' : self.confId,
|
||||
'duration' : duration,
|
||||
'title' : entry.title?entry.title:"Untitled",
|
||||
'sessionId' : self.destination.sessionId,
|
||||
'slotId' : self.destination.sessionSlotId,
|
||||
'contribId' : self.destination.contributionId,
|
||||
'startDate' : date + " " + timeStr,
|
||||
'keywords' : [],
|
||||
'authors':ImporterUtils.isPersonEmpty(entry.primaryAuthor)?[entry.primaryAuthor]:[],
|
||||
'coauthors' : ImporterUtils.isPersonEmpty(entry.secondaryAuthor)?[entry.secondaryAuthor]:[],
|
||||
'presenters' : ImporterUtils.isPersonEmpty(entry.speaker)?[entry.speaker]:[],
|
||||
'roomInfo' : {},
|
||||
'field_content': entry.summary,
|
||||
'reportNumbers': entry.reportNumbers?
|
||||
[{'system': ImporterUtils.reportNumberSystems[self.importer], 'number': entry.reportNumbers}]:[],
|
||||
'materials': entry.materials}
|
||||
var params = {
|
||||
'csrf_token': $('#csrf-token').attr('content'),
|
||||
'title': entry.title ? entry.title : "Untitled",
|
||||
'description': entry.summary,
|
||||
'duration': [duration, 'minutes'],
|
||||
'references': '[]'
|
||||
}
|
||||
if (self.destination.entryType == "Contribution") {
|
||||
$.extend(params, {
|
||||
'speakers': Json.write(self._personLinkData(entry))
|
||||
});
|
||||
} else {
|
||||
$.extend(params, {
|
||||
'time': timeStr,
|
||||
//'keywords' : [],
|
||||
'person_link_data': Json.write(self._personLinkData(entry)),
|
||||
//'roomInfo' : {},
|
||||
'location_data': '{"address": "", "inheriting": true}',
|
||||
'type': '__None',
|
||||
//'reportNumbers': entry.reportNumbers?
|
||||
// [{'system': ImporterUtils.reportNumberSystems[self.importer], 'number': entry.reportNumbers}]:[],
|
||||
'materials': Json.write(entry.materials)
|
||||
});
|
||||
}
|
||||
args.push({
|
||||
'url': self._getUrl(method, self.confId, date, self.destination),
|
||||
'args': params
|
||||
});
|
||||
time += duration;
|
||||
});
|
||||
var successCallback = function(result) {
|
||||
if (exists(result.slotEntry) && self.timetable.contextInfo.id == result.slotEntry.id) {
|
||||
self.timetable._updateEntry(result, result.id);
|
||||
} else{
|
||||
} else {
|
||||
var timetable = self.timetable.parentTimetable?self.timetable.parentTimetable:self.timetable;
|
||||
timetable._updateEntry(result, result.id);
|
||||
}
|
||||
@ -832,13 +923,13 @@
|
||||
recordDiv.append(Html.div({}, Html.em({}, $t.gettext("Meeting")), ": ", record.get("meetingName")));
|
||||
}
|
||||
// Speaker, primary and secondary authors are stored in dictionaries. Their property have to be checked.
|
||||
if (ImporterUtils.isPersonEmpty(record.get("primaryAuthor"))) {
|
||||
if (!ImporterUtils.isPersonEmpty(record.get("primaryAuthor"))) {
|
||||
recordDiv.append(Html.div({}, Html.em({}, $t.gettext("Primary author")), ": ", this._getPersonString(record.get("primaryAuthor"))));
|
||||
}
|
||||
if (ImporterUtils.isPersonEmpty(record.get("secondaryAuthor"))) {
|
||||
if (!ImporterUtils.isPersonEmpty(record.get("secondaryAuthor"))) {
|
||||
recordDiv.append(Html.div({}, Html.em({}, $t.gettext("Secondary author")), ": ", this._getPersonString(record.get("secondaryAuthor"))));
|
||||
}
|
||||
if (ImporterUtils.isPersonEmpty(record.get("speaker"))) {
|
||||
if (!ImporterUtils.isPersonEmpty(record.get("speaker"))) {
|
||||
recordDiv.append(Html.div({}, Html.em({}, $t.gettext("Speaker")), ": ", this._getPersonString(record.get("speaker"))));
|
||||
}
|
||||
if (record.get("summary")) {
|
||||
@ -1356,7 +1447,7 @@
|
||||
|
||||
|
||||
$(function() {
|
||||
$('#timetableDiv').on('click', '.js-create-importer-dialog', function() {
|
||||
$('#timetable').on('click', '.js-create-importer-dialog', function() {
|
||||
var timetable = $(this).data('timetable');
|
||||
new ImportDialog(timetable);
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user