| Version 19 (modified by dmartinc, 3 years ago) (diff) |
|---|
(Note: this page is currently under construction)
A. Introduction - some concepts
A.1. What is a plugin?
Shortly put, a plugin is a part of Indico that is optional. They usually deal with external systems that the organization using Indico may or may not have. Therefore, organizations that use Indico can easily decide to use or not use them, or even remove their code from Indico.
Plugins in Indico are organized into Plugin Systems. Collaboration is one of those systems, and deals with videoconference systems (where you can book videoconferencing resources) and Service Requests such as a request to record an event. The first kind of plugins deal with external systems and use these system's APIs. The second kind of plugins usually help communicate (for example by email) a service responsible and an event manager. Other Plugin Systems in Indico include Epayment and Room Booking.
A.2. The Collaboration plugins core
The Collaboration plugins core (or core for short in this guide) is the part of Indico that interacts with the plugins:
- It defines the interface between Indico and the plugins.
- It calls the plugins' functions when it is necessary.
- It takes care of many common tasks so that the plugins do not have to implement them.
- It provides helper / utility functions to the plugins.
The core is present both in the server side (Python code) and the client side (HTML, CSS and Javascript code).
A.3. Bookings and requests
Among the Collaboration plugins, there are two sub-types of plugins so far:
- Booking plugins: they provide the user with a form where they can book resources in an external system. In most cases, there can be multiple bookings of the same type for the same Indico event. This means that in the database, there will be multiple "Booking" objects of the same type associated to an event.
- Request plugins: they provide the user with a form where they can request a service. For each Indico event, there can be only one Request of a given type.
Examples of Booking plugins are: EVO, CERNMCU, Vidyo. Examples of Reques plugins are Recording Request and Webcast Request.
A.4. Pages generated by Collaboration plugins
The Collaboration plugins will generate pages / information that will appear in several places in Indico:
- In the management interface of an Indico Event, in the Video Services section (left menu). Each plugin will appear in a given tab. Several plugins can share a tab (such as EVO, CERNMCU and Vidyo) or be alone in their own tab (like Recording Request).
- In the display page of events, for the Booking plugins. When a booking has been done in an external system, the Event manager can decide to show information about it on the event's display page to allow normal users to join the Videoconference.
- In the Server Admin interface, in the Plugins section, under the Collaboration tab. Each plugin will be represented in a sub-tab under which the plugin's options and actions will appear.
- In the Video Services Overview page, where Bookings and Requests are indexed (if the respective plugin wishes to) and queries can be made to have a global view.
B. Creating a new plugin
To create a new plugin, the best way to start is to copy one of the existing plugin's folder.
For example, if developing a new Videoconference booking plugin, one may make a copy of the EVO folder in MaKaC/plugins. If developing a new request plugin, one may copy the RecordingRequest folder.
Choose a name for your plugin, and rename the folder to this name.
Then head to the __init__.py file inside your plugin folder. Change the pluginName variable to the name of your plugin, and the pluginDescription variable to some description of your plugin that will be visible in the Server Admin > Plugins web interface.
It is strongly advised to use the same name for the plugin folder and the pluginName variable.
Voilà, you have a new plugin! However if you started creating a folder from scratch you should read the next section which explains the different files inside the folder, many of them are compulsory.
C. Plugin file structure
[TODO] This section will explain the different files of a Plugin, giving a short summary for each and specifying if a given file is optional or compulsory.
D. Configuring a plugin
D.1. Plugin characteristics
Different plugins cover different concepts or have different needs. In the collaboration.py file of each plugin, inside the CSBooking class, several class attributes can be defined that will help the Collaboration core know what to expect when dealing with the plugin.
All these class attributes are defined with their default values in the CSBookingBase class inside MaKaC/plugins/Collaboration/base.py. If you like the default value of a class attribute, you do not need to write it again in your CSBooking class, although sometimes it is not bad to do it anyway, for clarity.
List of class attributes and their functions:
- _allowMultiple: True by default. Should be False if the plugin does not wish to allow that more than one CSBooking object of its type should be created for each Indico Event. This is what distinguishes Booking-type plugins from Request-type plugins.
- _hasStart: False by default. Should be True if the plugin has a "start" concept, which means a "Start" button will appear next to a created Booking, allowing the Event Manager to start the Videoconference.
- _hasStop: False by default. Should be True if the plugin has a "stop" concept, which means a "Stop" button will appear next to a created Booking, allowing the Event Manager to stop the Videoconference.
- _hasStartStopAll: False by default. Should be True if the plugin has _hasStart == True and/or _hasStop == True, and they want "Start All" / "Stop All" buttons to appear for their bookings. These buttons will allow to start / stop all of the bookings at once (of all the plugins in the same tab who have _hasStartStopAll == True).
- _requiresServerCallForStart : False by default. Should be True if the plugin has _hasStart == True and wishes that the CSBooking object on the server side should be notified when the Event Manager clicks on the "Start" button, by calling CSBooking 's _start() method.
- _requiresServerCallForStop : False by default. Analogous to _requiresServerCallForStart, but for the "Stop" action.
- _requiresClientCallForStart : False by default. Should be True if the the plugin wishes a Javascript function to be called when the Event Manager presses the "Start" button. The function called will be the start() function in Main.js.
- _requiresClientCallForStop : False by default. Should be True if the the plugin wishes a Javascript function to be called when the Event Manager presses the "Stop" button. The function called will be the stop() function in Main.js.
- _hasCheckStatus: False by default. Should be True if the plugin has a "check status" concept, which means a "Check status" button will appear next to the Booking / Request status, allowing the Event Manager to reload all the information of the Booking / Request from the Indico Server into his browser.
- _hasAcceptReject: False by default. Should be True if the plugin has a "check status" concept. In that case, "Accept" and "Reject" buttons will appear next to the Booking / Request status, only visible to plugin admins or server admins, who can use them to change the state of the Booking / Request object to "Accepted" or "Rejected".
- _needsBookingParamsCheck : False by default. Should be True if the the plugin wishes to check the Booking / Request parameters in the server after the booking is created / edited. In that case, the _checkBookingParams() method of the plugin's CSBooking class will be called to verify the parameters.
- _needsToBeNotifiedOnView: False by default. Should be True if the plugin wishes its CSBooking objects to be notifies when an user "sees" the booking, for example when returning the list of booking. The _notifyOnView() method of the plugin's CSBooking class will be called.
- _shouldBeIndexed: True by default. Should be False if the plugin does not wish to allow its CSBooking objects to be indexed, i.e. to appear in the Video Services Overview page.
- _commonIndexes: [] by default. A list of strings. Useful when _shouldBeIndexed == True. If left empty, the plugin's CSBooking object will appear in the "All" index and in the plugin's own index, but not in any shared index. If set to ["Videoconference"], for example, they will also appear in the common "Videoconference" index. For example, currently EVO, CERNMCU and Vidyo bookings appear in this index.
- _hasStartDate: True by default. Should be True if the plugin's CSBooking objects have a start date attribute. This will allow the Collaboration Core to index these objects by start date.
- _hasEventDisplay : False by default. Should be True if the plugin's CSBooking objects wish to be displayed in the Event's display page.
- _hasTitle: False by default. Useful if _hasEventDisplay == True. Should be True if the plugin's CSBooking objects have a Title. This will affect how the objects appear in the Event display page.
- _adminOnly: False by default. If set to True, only Server Admins, Video Services Admins, and Plugin Admins (for the corresponding Plugin) will be able to interact with the plugin / see the plugin's tab in the Video Services section of the events. It will not stop normal users from seeing information about bookins in Events Display pages (if any, and if the booking is not Hidden).
It is recommended to see the values of these class attributes defined by each existing plugin in their collaboration.py file.
D.2. Plugin options
As other types of plugins, Collaboration plugins can define Options with different attributes. The options' values will be stored in the database. Options are useful to store things such as the remote system URL, the plugin list of admins, etc. In other words, things that should be in the database not attached to any Event in particular, but of global scope in Indico.
Options are defined in the options.py file. More information on the declaration syntax, and how to read their values in your plugin's code, can be found in the Plugin System page, in the corresponding section.
It's compulsory for Collaboration Plugins to declare the following options:
- tab: the name of the tab, in the Video Services section of an Indico Event's management interface, that this plugin will appear in.
- allowedOn: a list of one to three strings. The strings inside the list can be: "conference", "meeting" or "simple_event" (this last one representing lecture events). The Collaboration Core will allow the plugin to appear only for these kind of events.
- admins: put an empty list as defaultValue. Here the plugin admins (Avatar objects) will be stored.
E. Programming the client side Event Management pages
This section will describe how to design and implement the pages and dialogs that your plugin will show in the Video Services section of an event's management interface.
We will cover both how to render the initial dialog / page in the browser, the Javascript that will be called on different occasions, and how to call services (AJAX requests) on the server.
E.1. Dialog vs page form
Depending on the the value you chose for CSBooking._allowMultiple (see D.1.), your plugin will be shown differently in the Video Services section.
If CSBooking._allowMultiple == True, you are allowing several CSBooking objects for the event. Most Booking plugins will fall into this category. Therefore, it makes sense that these bookings will be shown in a list. The list will look like this:
Pressing the "create" button will open a creation dialog, with a form to fill in the booking details. This dialog will also be used when editing an existing booking.
However, if CSBooking._allowMultiple == False, you are only allowing one CSBooking object of that type for the event. Most Request plugins will fall into this category. In this case, the form to fill in the details about the booking / request will appear directly in the webpage, without a button to open a dialog.
The way you write your code if greatly affected by your choice in this regard.
E.2. Designing your dialog / form
E.2.1. The NewBookingForm.tpl file
The HTML code that will appear in your dialog / form is in the NewBookingForm.tpl file.
In this file, you can write mixed HTML and Python code, like any other .tpl file in Indico. You can do conditions and loops in Python in order to generate your HTML.
If you use any Python variables in this file, they have to be declared in the WNewBookingForm class in the pages.py file.
There is however one exception: because of the way the HTML code has to be injected into the dialogs, any <script type="text/javascript"> blocks will NOT work in NewBookingForm.tpl. They will however work if your plugin's form is not a dialog but a page. You can however add Javascript inside things such as onclick attributes and so on. The rest of the Javascript, you will have to write in the Main.js and Extra.js files.
E.2.1. The WNewBookingForm class
Inside the pages.py file, even if you do not need any Python variables inside NewBookingForm.tpl, you must declare a WNewBookingForm class that inherits from WCSPageTemplateBase:
from MaKaC.plugins.Collaboration.base import WCSPageTemplateBase class WNewBookingForm(WCSPageTemplateBase): def getVars(self): vars = WCSPageTemplateBase.getVars(self) ## Assign your variables into the vars dictionary here, example: vars["Title"] = self._conf.getTitle() return vars
The getVars() method is only necessary if you need to have Python variables in NewBookingForm.tpl (which is most often the case anyway).
Because you are inheriting from WCSPageTemplateBase, the following attributes are available for you in self:
- self._conf: a Conference object. The event you are working with.
- self._user: an Avatar object. The currently logged in user (there's always one since we are in the Management interface).
- self._pluginName: a string with the name of your own plugin.
- self._ph: the PluginsHolder object, that you can use to access information about all the plugins (see the Plugin System guide)
- self._plugin: a Plugin object. Your own Plugin object, actually. See the Plugin System guide again.
- self._XXXOptions: a dictionary whose values are the plugin's PluginOption objects, which you could access through self._plugin but the WCSPageTemplateBase class build for you for convenience. Replace XXX by your plugin's name.
E.3. Javascript interface between core and plugins
On certain events, such as when the user clicks on the Create button to create a booking, or when the Send Request button is pressed to send a request, certain Javascript functions from your plugins will be called by the core.
These functions are placed in the WMain.js file. So that the core can call them, they have to have particular names. The functions must be organized into an object / dictionary, for example:
//Contents of the Main.js file: { checkParams: function() { // function code here }, errorHandler: function(event, error) { // function code here } }
Important note: never put a comma after the "}" of the last function! Firefox will not catch error but IE will and it will not be easy to debug without appropriate tools. Same goes for any list or object declaration: never put a comma after the last element. This happens often when you copy/paste without paying attention.
(to be continued)
E.4. Custom Javascript
E.5. Calling services
E.6. Context help
F. Programming the server side
F.1. Booking parameters. Information stored in the DB
F.2. Complex parameters
F.3. Implementing methods
F.4. E-mails
F.5. Custom services
In the server, Service classes who take AJAX requests from the client are located in the plugin's services.py file.
Each of your services has to be a class similar to this one:
from MaKaC.services.implementation.collaboration import CollaborationPluginServiceBase class XXXXXService(CollaborationPluginServiceBase): def _checkParams(self): # parameter parsing / treatment here. raise exception if invalid parameters def _getAnswer(self): # answer building here. a JSON serializable object, such as a primitive type, or a list of strings, or a fossil, should be returned
XXXXX is the name of the service as you wrote it in the service call made in Javascript (see section E.5. Calling Services), in camelcase with initial capital letter. You can see examples in the RecordingRequest and WebcastRequest plugins.
Inheritance from CollaborationPluginServiceBase is compulsory. It gives you these benefits:
- You don't need to implement _checkProtection like for a normal service. Your service will be called by the CollaborationCustomPluginService service, which will take care of making sure that only people with proper permissions can perform your operation (only admins if the plugin is an admin service, or only managers otherwise). However you can implement the method if you like to perform additional checks.
- You already have the following attributes available:
- self._params : like any Indico service, this is a dictionary with the call parameters.
- self._aw: an AccessWrapper object with a getUser() method that will return the logged in user as an Avatar instance.
- self._conf: the Conference object corresponding to the Indico Event we are working with (this is provided by CollaborationBase which CollaborationPluginServiceBase inherits from).
- self._CSBookingManager: the CSBookingManager object attached to the Event (this is provided by CollaborationBase which CollaborationPluginServiceBase inherits from).
_getAnswer() will be always called after _checkParams(). If you do implement _checkProtection, it will be called between _getAnswer() and _checkParams().
Normally in _checkParams() you verify the parameters and build the objects you will work with in _getAnswer(), putting them in self. Then in _getAnswer() you build the asnwer and return a JSON serializable object, i.e. a primitive type, or a list of strings, or a fossil / pickled object. This is no different from normal Indico services.
G. Other programming
G.1. Display pages
G.1.1. For events of type conference
G.1.2. For events of lecture and meeting
G.2. Errors and exceptions
G.3. Fossils
H. Utility functions available
H.1. CollaborationTools class
H.2. MailTools class
H.3. Javascript helper functions
I. Tasks performed by the core
I.1. Indexation
I.2. Time synchronization
I.3. Hidden bookings
Attachments (3)
-
Booking list.png
(34.0 KB) -
added by dmartinc 3 years ago.
Booking list screenshot
-
EVO creation dialog.png
(25.8 KB) -
added by dmartinc 3 years ago.
EVO creation dialog screenshot
-
Recording Request Form.png
(45.1 KB) -
added by dmartinc 3 years ago.
Recording Request form screenshot
Download all attachments as: .zip



