Changeset 92928f in indico


Ignore:
Timestamp:
12/01/11 11:22:40 (18 months ago)
Author:
Jose Benito <jose.benito.gonzalez@…>
Branches:
master, hello-world-walkthrough, ipv6, v0.98-series, v0.98.2, v0.98.3, v0.98b2, v0.99, 051b2622c51afb171a1dedb46a0df4fbb0cbd02e, d9941f8582b36b24821a11ea5ba16fda6a457fb1
Children:
addcba
Parents:
32c576
git-author:
Matthew Pugh <matthew.alexander.pugh@…> (11/10/11 17:18:10)
git-committer:
Jose Benito <jose.benito.gonzalez@…> (12/01/11 11:22:40)
Message:

[FTR] Vidyo bookings to sessions & contributions

Location:
indico
Files:
2 added
15 edited

Legend:

Unmodified
Added
Removed
  • indico/MaKaC/errors.py

    rd8fbd8 r92928f  
    186186    """ 
    187187    pass 
     188 
  • indico/MaKaC/plugins/Collaboration/Vidyo/collaboration.py

    rc53d5c r92928f  
    3434from MaKaC.common.mail import GenericMailer 
    3535from MaKaC.common.externalOperationsManager import ExternalOperationsManager 
     36from MaKaC.plugins.Collaboration.Vidyo.pages import ServiceInformation 
    3637 
    3738class CSBooking(CSBookingBase): 
     
    5859    _hasEventDisplay = True 
    5960 
     61    _linkVideoType = None 
     62    _linkVideoId = None 
     63    _serviceInformation = ServiceInformation() # See method getSections() 
     64 
    6065    _commonIndexes = ["All Videoconference"] 
    6166 
     
    6570        "displayPin": (bool, False), 
    6671        "displayURL": (bool, True), 
    67         "displayPhoneNumbers": (bool, True)} 
     72        "displayPhoneNumbers": (bool, True), 
     73        "videoLinkType": (str, ''), 
     74        "videoLinkContribution": (str, ''), 
     75        "videoLinkSession": (str, '')} 
    6876 
    6977    _complexParameters = ["pin", "hasPin", "owner"] 
     
    113121        pass 
    114122 
     123    def getBookingParams(self): 
     124        """ Overloaded method to append which contribution or session (if any)  
     125            this booking is linked to for the managerial view.  
     126        """ 
     127 
     128        params = super(CSBooking, self).getBookingParams() 
     129        linkText = "" 
     130        import re 
     131 
     132        if self.hasSessionOrContributionLink(): 
     133            title = "" 
     134 
     135            # Should move this into a utility function. 
     136            confId = re.search('(?<=a)\d+', self._linkVideoId) 
     137            sessId = re.search('(?<=s)\d+', self._linkVideoId) 
     138            contId = re.search('(?<=t)\d+', self._linkVideoId) 
     139 
     140            from MaKaC.conference import ConferenceHolder 
     141            ch = ConferenceHolder() 
     142            ch = ch.getById(confId.group()) 
     143 
     144            if self.isLinkedToConribution(): 
     145                title = ch.getContributionById(contId.group()).getTitle() 
     146            else: 
     147                title = ch.getSessionById(sessId.group()).getTitle() 
     148 
     149            linkText = title + " (" + self._linkVideoType + ")" 
     150        else: 
     151            linkText = _("Whole event.") 
     152 
     153        params["linkText"] = linkText 
     154        return params 
     155 
    115156    def getOwner(self): 
    116157        """ Returns the owner, fossilized, so that it is used by the collaboration core 
     
    187228    def setChecksDone(self, checksDone): 
    188229        self._checksDone = checksDone 
     230 
     231    def hasBookingInformation(self): 
     232        """ Determines whether this booking has further information associated  
     233            with it, i.e. a ServiceInformation attribute, for populating  
     234            drop-down 'more info. 
     235        """ 
     236        return hasattr(self, "_serviceInformation") 
     237 
     238    def getBookingInformation(self): 
     239        """ For retreiving the ServiceInformation sections dict built for the  
     240            Event Header, delegated here for use with Vidyo only at this time. 
     241            If event linking is required for other video services, this will  
     242            need to be moved to parent or some other mechanism implemented. 
     243        """ 
     244        return self._serviceInformation.getInformation(self, True) 
     245 
     246    ## methods relating to the linking of Vidyo objects to Contributions & Sessions 
     247 
     248    def hasSessionOrContributionLink(self): 
     249        return (self.isLinkedToConribution() or self.isLinkedToSession()) 
     250 
     251    def isLinkedToSession(self): 
     252        return (self._linkVideoType == "session") 
     253 
     254    def isLinkedToConribution(self): 
     255        return (self._linkVideoType == "contribution") 
     256 
     257    def getLinkId(self): 
     258        """ Returns the unique ID of the Contribution or Session which this  
     259            object is associated with, completely agnostic of the link type. 
     260            Returns None if no association (default) found. 
     261        """ 
     262        if not self.hasSessionOrContributionLink(): 
     263            return None 
     264         
     265        return self._linkVideoId 
     266 
     267    def getLinkIdDict(self): 
     268        """ Returns a dictionary of structure linkType (session | contribution)  
     269            : unique ID of referenced object. 
     270            Returns None if no association is found. 
     271        """ 
     272        linkId = self.getLinkId() 
     273 
     274        if linkId == None: 
     275            return linkId 
     276 
     277        return {self._linkVideoType : linkId} 
     278 
     279    def getLinkType(self): 
     280        """ Returns a string denoting the link type, that is whether linked  
     281            to a session or contribution. 
     282        """ 
     283 
     284        return self._linkVideoType 
     285 
     286    def setLinkType(self, linkDict): 
     287        """ Accepts a dictionary of linkType: linkId """ 
     288 
     289        self._linkVideoType = linkDict.keys()[0] 
     290        self._linkVideoId = linkDict.values()[0] 
     291 
     292    def resetLinkParams(self): 
     293        """ Removes all association with a Session or Contribution from this 
     294            CSBooking only.  
     295        """ 
     296 
     297        self._linkVideoType = self._linkVideoId = None 
    189298 
    190299    ## overriding methods 
     
    224333            Returns a VidyoError if there is a problem, such as the name being duplicated. 
    225334        """ 
    226         result = ExternalOperationsManager.execute(self, "createRoom", VidyoOperations.createRoom, self) 
    227  
     335        #result = ExternalOperationsManager.execute(self, "createRoom", VidyoOperations.createRoom, self) 
     336        result = True 
    228337        if isinstance(result, VidyoError): 
    229338            return result 
    230339 
    231340        else: 
     341            # Link to a Session or Contribution if requested 
     342            if not self._bookingParams["videoLinkType"] == "None": 
     343                params = self._bookingParams 
     344                linkId = params["videoLinkSession"] if params["videoLinkType"] == "session" \ 
     345                    else params["videoLinkContribution"] 
     346                self.setLinkType({params["videoLinkType"] : linkId}) 
    232347            self._roomId = str(result.roomID) #we need to convert values read to str or there will be a ZODB exception 
    233348            self._extension = str(result.extension) 
     
    242357        """ 
    243358        result = ExternalOperationsManager.execute(self, "modifyRoom", VidyoOperations.modifyRoom, self, oldBookingParams) 
    244  
    245359        if isinstance(result, VidyoError): 
    246360            if result.getErrorType() == 'unknownRoom': 
    247361                self.setBookingNotPresent() 
    248362            return result 
    249  
    250363        else: 
    251364            self._extension = str(result.extension) 
     
    293406        """ 
    294407        result = VidyoOperations.queryRoom(self, self._roomId) 
    295  
    296408        if isinstance(result, VidyoError): 
    297409            self.setBookingNotPresent() 
  • indico/MaKaC/plugins/Collaboration/Vidyo/pages.py

    rc87441 r92928f  
    222222            'lines' : [booking.getBookingParamByName("roomDescription")], 
    223223        }) 
     224 
    224225        return sections 
    225226 
  • indico/MaKaC/plugins/Collaboration/Vidyo/tpls/Main.js

    r416423 r92928f  
    11{ 
     2    ajaxPendingAll : false, 
     3 
    24    start : function(booking, iframeElement) { 
    35        window.open(booking.url); 
     
    156158            Html.td({}, formatDateTimeCS(booking.modificationDate)))); 
    157159 
     160        infoTbody.append(Html.tr({}, 
     161            Html.td("collaborationInfoLeftCol", $T('Linked to:')), 
     162            Html.td({}, booking.bookingParams.linkText))); 
     163 
    158164        return Html.div({}, Html.table({}, infoTbody)); 
    159165    }, 
    160166 
    161     onCreate: function(bookingPopup) { 
    162         vidyoOwnerField = new SingleUserField(${ jsonEncode(LoggedInUser) }, 
     167    observeRadioButtons: function(vidyoComponents) { 
     168        vidyoComponents["link"].observe(function(value){ 
     169            switch(value) { 
     170            case"session": 
     171                if (vidyoComponents["changed"] == false) { 
     172                    vidyoComponents["dummy"] = $('#videoEventLinkSelection').html(); 
     173                    vidyoComponents["changed"] = true; 
     174                } 
     175                $E('videoEventLinkSelection').set(vidyoComponents["session"].draw()); 
     176                break; 
     177            case"contribution": 
     178                if (vidyoComponents["changed"] == false) { 
     179                    vidyoComponents["dummy"] = $('#videoEventLinkSelection').html(); 
     180                    vidyoComponents["changed"] = true; 
     181                } 
     182                $E('videoEventLinkSelection').set(vidyoComponents["contribution"].draw()); 
     183                break; 
     184            case"None": 
     185            default: 
     186                if (vidyoComponents["changed"]) { 
     187                    $('#videoEventLinkSelection').html(vidyoComponents["dummy"]); 
     188                } 
     189                break; 
     190            } 
     191        }); 
     192    }, 
     193 
     194    getVidyoComponents : function(ajaxPending) { 
     195        var self = this; 
     196        var params = {conference : confId}; 
     197 
     198        return { 
     199            params : params, 
     200            ownerField : new SingleUserField(${ jsonEncode(LoggedInUser) }, 
    163201                'owner', 
    164202                true, true, null, 
    165203                null, false, 
    166204                false, false, 
    167                 singleUserNothing, singleUserNothing); 
    168         $E('owner').set(vidyoOwnerField.draw()); 
    169  
    170         var vidyoPinField = new ShowablePasswordField('pin', '', false); 
    171         $E('PINField').set(vidyoPinField.draw()); 
    172  
    173         bookingPopup.addComponent(vidyoOwnerField); 
    174         bookingPopup.addComponent(vidyoPinField); 
    175  
    176         vidyoDrawContextHelpIcons(vidyoPinField); 
     205                singleUserNothing, singleUserNothing), 
     206            pinField : new ShowablePasswordField('pin', '', false), 
     207            link : new RadioFieldWidget([ 
     208                 ['None', $T("Leave default Vidyo association.")], 
     209                 ['contribution', $T("Link to a contribution.")], 
     210                 ['session', $T("Link to a session.")] 
     211             ], 'nobulletsListInline','videoLinkType'), 
     212            session : new SelectRemoteWidget('event.sessions.listAll',  
     213                params, function() { 
     214                    if (ajaxPending !== false) { 
     215                        ajaxPending["session"].resolve(); 
     216                    } 
     217                }, 'videoLinkSession'), 
     218            contribution : new SelectRemoteWidget('event.contributions.listAll',  
     219                params, function() { 
     220                    if (ajaxPending !== false) { 
     221                        ajaxPending["contribution"].resolve(); 
     222                    } 
     223                }, 'videoLinkContribution'), 
     224            dummy : "", 
     225            changed : false 
     226        }; 
     227    }, 
     228 
     229    onCreate: function(bookingPopup) { 
     230        var self = this; 
     231        var vidyoComponents = self.getVidyoComponents(); 
     232 
     233        $E('owner').set(vidyoComponents["ownerField"].draw()); 
     234        $E('PINField').set(vidyoComponents["pinField"].draw()); 
     235        $E('videoEventLinkType').set(vidyoComponents["link"].draw()); 
     236        vidyoComponents["link"].select('None'); 
     237        self.observeRadioButtons(vidyoComponents); 
     238 
     239        bookingPopup.addComponent(vidyoComponents["ownerField"]); 
     240        bookingPopup.addComponent(vidyoComponents["pinField"]); 
     241        bookingPopup.addComponent(vidyoComponents["link"]); 
     242        bookingPopup.addComponent(vidyoComponents["session"]); 
     243        bookingPopup.addComponent(vidyoComponents["contribution"]); 
     244        vidyoDrawContextHelpIcons(vidyoComponents["pinField"]); 
    177245    }, 
    178246 
    179247    onEdit: function(booking, bookingPopup) { 
    180         vidyoOwnerField = new SingleUserField(null, 
    181                 'owner', 
    182                 true, true, null, 
    183                 null, false, 
    184                 false, false, 
    185                 singleUserNothing, singleUserNothing); 
    186         $E('owner').set(vidyoOwnerField.draw()); 
    187  
    188         var vidyoPinField = new ShowablePasswordField('pin', '', false); 
    189         $E('PINField').set(vidyoPinField.draw()); 
    190  
    191         bookingPopup.addComponent(vidyoOwnerField); 
    192         bookingPopup.addComponent(vidyoPinField); 
    193  
    194         vidyoDrawContextHelpIcons(); 
     248        var self = this; 
     249        var ajaxPending = { 
     250                session : $.Deferred(), 
     251                contribution : $.Deferred() 
     252        }; 
     253        var vidyoComponents = self.getVidyoComponents(ajaxPending); 
     254 
     255        $E('owner').set(vidyoComponents["ownerField"].draw()); 
     256        $E('PINField').set(vidyoComponents["pinField"].draw()); 
     257        $E('videoEventLinkType').set(vidyoComponents["link"].draw()); 
     258        self.observeRadioButtons(vidyoComponents); 
     259 
     260        $.when(ajaxPending["session"], ajaxPending["contribution"]).done(function() { 
     261            self.ajaxPendingAll.resolve(); 
     262        }); 
     263 
     264        bookingPopup.addComponent(vidyoComponents["ownerField"]); 
     265        bookingPopup.addComponent(vidyoComponents["pinField"]); 
     266        bookingPopup.addComponent(vidyoComponents["session"]); 
     267        bookingPopup.addComponent(vidyoComponents["contribution"]); 
     268        bookingPopup.addComponent(vidyoComponents["link"]); /* This must be the last component added. */ 
     269        vidyoDrawContextHelpIcons(vidyoComponents["pinField"]); 
    195270    }, 
    196271 
    197272 
    198273    beforeCreate: function(pluginName, conferenceId) { 
    199         var allowCreation = true; 
    200  
    201         each(bookings, function(booking) { 
    202             if (booking.type == 'Vidyo') { 
    203                 allowCreation = false; 
    204             } 
    205         }); 
    206  
    207         if (!allowCreation) { 
    208             CSErrorPopup($T("Whoops..."), 
    209                          [Html.unescaped.div({}, 
    210                                    $T("There is already a Vidyo booking present. " + 
    211                                       "Right now it is only possible to create " + 
    212                                       "<strong>a single Vidyo booking per event</strong>. " + 
    213                                       "Please delete it if you want to create a new one."))]); 
    214         } 
    215  
    216         return allowCreation; 
     274        return true; 
    217275    }, 
    218276 
     
    254312    } 
    255313} 
     314 
  • indico/MaKaC/plugins/Collaboration/Vidyo/tpls/NewBookingForm.tpl

    rc0de5a r92928f  
    1515        <td> 
    1616            <textarea rows="3" cols="60" name="roomDescription">${ EventDescription }</textarea> 
     17        </td> 
     18    </tr> 
     19 
     20    <tr> 
     21        <td class="bookingFormFieldLink" style="vertical-align: top;"> 
     22            <span>Event linking</span> 
     23        </td> 
     24        <td> 
     25            <span id="videoEventLinkType"></span> 
     26            <span id="videoEventLinkSelection"> 
     27                <select id="dummy" disabled="disabled"> 
     28                    <option>${_('Default association')}</option> 
     29                </select> 
     30            </span> 
    1731        </td> 
    1832    </tr> 
  • indico/MaKaC/plugins/Collaboration/base.py

    r5983d12 r92928f  
    2828from MaKaC.webinterface import wcomponents, urlHandlers 
    2929from MaKaC.plugins import PluginsHolder 
    30 from MaKaC.errors import MaKaCError 
     30from MaKaC.errors import MaKaCError, NoReportError 
    3131from MaKaC.services.interface.rpc.common import ServiceError 
    3232from MaKaC.common.timezoneUtils import nowutc 
     
    4848from MaKaC.common.fossilize import Fossilizable, fossilizes 
    4949from MaKaC.common.externalOperationsManager import ExternalOperationsManager 
     50from BTrees.OOBTree import OOBTree 
    5051 
    5152from MaKaC.plugins.Collaboration.fossils import ICSErrorBaseFossil, ICSSanitizationErrorFossil,\ 
     
    7576        # an index of bookings by type. The key will be a booking type (string), the value a list of booking id 
    7677        self._bookingsByType = {} 
     78 
     79        # an index of bookings to video services by event.uniqueId : video.uniqueId pairind.  
     80        self._bookingsToVideoServices = OOBTree() 
    7781 
    7882        # a list of ids with hidden bookings 
     
    237241                    return createResult 
    238242                else: 
     243                    uniqueId = None 
     244 
     245                    if bookingParams['videoLinkType'] == "session": 
     246                        uniqueId = bookingParams['videoLinkSession'] 
     247                    elif bookingParams['videoLinkType'] == "contribution": 
     248                        uniqueId = bookingParams['videoLinkContribution'] 
     249 
     250                    if (self.hasVideoService(uniqueId)): # Restriction: 1 video service per session or contribution. 
     251                        raise NoReportError(_('Only one video service per contribution or session is allowed.')) 
     252 
    239253                    self._bookings[newId] = newBooking 
    240254                    self._bookingsByType.setdefault(bookingType,[]).append(newId) 
     
    244258                    self._notifyModification() 
    245259 
     260                    if uniqueId is not None: # if we're here and uniqueId has a value, register the video service. 
     261                        self.addVideoService(uniqueId, newBooking) 
     262 
    246263                    if MailTools.needToSendEmails(bookingType): 
    247264                        newBooking._sendNotifications('new') 
     
    269286 
    270287        booking = self.getBooking(bookingId) 
    271  
    272288 
    273289        oldStartDate = booking.getStartDate() 
     
    297313                    self.getHiddenBookings().remove(booking.getId()) 
    298314 
     315                eventLinkUpdated = False 
     316                if booking.hasSessionOrContributionLink(): 
     317                    oldLinkData = booking.getLinkIdDict() 
     318                    oldLinkId = oldLinkData.values()[0] 
     319 
     320                    # Details changed, we need to remove the association and re-create it 
     321                    if not (oldLinkData.has_key(bookingParams['videoLinkType']) 
     322                        and ((oldLinkId == bookingParams['videoLinkSession'])  
     323                        or (oldLinkId == bookingParams['videoLinkContribution']))): 
     324 
     325                        self.removeVideoSingleService(booking.getLinkId(), booking) 
     326                        eventLinkUpdated = True 
     327 
     328                if eventLinkUpdated or bookingParams['videoLinkType'] != "None": 
     329                    newLinkId = None 
     330                    if bookingParams['videoLinkType'] == "session": 
     331                        newLinkId = bookingParams['videoLinkSession'] 
     332                    elif bookingParams['videoLinkType'] == "contribution": 
     333                        newLinkId = bookingParams['videoLinkContribution'] 
     334 
     335                    if self.hasVideoService(booking.getLinkId(), booking): 
     336                        pass # No change in the event linking 
     337                    elif newLinkId is not None: 
     338                        if (self.hasVideoService(newLinkId)): # Only one booking per item 
     339                            raise NoReportError(_('Only one video service per contribution or session is allowed.')) 
     340                        else: 
     341                            self.addVideoService(newLinkId, booking) 
     342                            booking.setLinkType({bookingParams['videoLinkType']: newLinkId}) 
     343                    else: # If it's still None, event linking has been completely removed. 
     344                        booking.resetLinkParams() 
     345 
    299346                self._changeStartDateInIndex(booking, oldStartDate, booking.getStartDate()) 
    300347                self._changeModificationDateInIndex(booking, oldModificationDate, modificationDate) 
     
    346393        booking = self.getBooking(id) 
    347394        bookingType = booking.getType() 
     395        bookingLinkId = booking.getLinkId() 
    348396 
    349397        removeResult = booking._delete() 
     
    358406                self.getHiddenBookings().remove(id) 
    359407 
     408            # If there is an association to a session or contribution, remove it 
     409            if bookingLinkId is not None: 
     410                self.removeVideoSingleService(bookingLinkId, booking) 
    360411            self._unindexBooking(booking) 
    361412 
     
    872923 
    873924        return list 
     925 
     926    def addVideoService(self, uniqueId, videoService): 
     927        """ Adds a video service to Contribution / Session link in the tracking 
     928            dictionary in order {uniqueId : videoService} 
     929        """ 
     930 
     931        if self.getVideoServices().has_key(uniqueId): 
     932            self.getVideoServices()[uniqueId].append(videoService) 
     933        else: 
     934            self.getVideoServices()[uniqueId] = [videoService] 
     935 
     936    def removeVideoAllServices(self, uniqueId): 
     937        """ Removes all associations of Contributions / Sessions with video  
     938            services from the dictionary, key included. 
     939        """ 
     940 
     941        if not self.hasVideoService(uniqueId): 
     942            return None 
     943 
     944        del self.getVideoServices()[uniqueId] 
     945 
     946    def removeVideoSingleService(self, uniqueId, videoService): 
     947        """ Removes a specific video service from a specific contribution. As  
     948            the list of services is unordered, iterate through to match for  
     949            removal - performance cost therefore occurs here. 
     950        """ 
     951 
     952        if not self.hasVideoService(uniqueId): 
     953            return None 
     954 
     955        target = self.getVideoServicesById(uniqueId) 
     956 
     957        for service in target: 
     958            if service == videoService: 
     959                target.remove(service) 
     960                break 
     961 
     962        # There are no more entries, therefore remove the dictionary entry too. 
     963        if len(target) == 0: 
     964            self.removeVideoAllServices(uniqueId) 
     965 
     966    def getVideoServices(self): 
     967        """ Returns the OOBTree associating event unique IDs with the List 
     968            of video services associated. 
     969        """ 
     970 
     971        if not hasattr(self, "_bookingsToVideoServices"): 
     972            self._bookingsToVideoServices = OOBTree() 
     973 
     974        return self._bookingsToVideoServices 
     975 
     976    def getVideoServicesById(self, uniqueId): 
     977        """ Returns a list of video services associated with the uniqueId 
     978            for printing in event timetable. Returns None if no video services  
     979            are found. 
     980        """ 
     981 
     982        if not self.hasVideoService(uniqueId): 
     983            return None 
     984 
     985        return self.getVideoServices()[uniqueId]  
     986 
     987    def hasVideoService(self, uniqueId, service=None): 
     988        """ Returns True if the uniqueId of the Contribution or Session provided  
     989            has an entry in the self._bookingsToVideoServices dictionary, thusly  
     990            denoting the presence of linked bookings. Second parameter is for more  
     991            specific matching, i.e. returns True if unique ID is associated with  
     992            specific service. 
     993        """ 
     994        if service is None: 
     995            return self.getVideoServices().has_key(uniqueId) 
     996 
     997        if self.getVideoServices().has_key(uniqueId): 
     998            for serv in self.getVideoServicesById(uniqueId): 
     999                if serv == service: 
     1000                    return True 
     1001        else: 
     1002            return self.getVideoServices().has_key(uniqueId) 
    8741003 
    8751004    def isAnyRequestAccepted(self): 
     
    19672096    def invalidFields(self): 
    19682097        return self._invalidFields 
    1969  
    19702098 
    19712099class CollaborationException(MaKaCError): 
  • indico/MaKaC/plugins/Collaboration/tpls/EventDetailBanner.tpl

    r7319f3 r92928f  
    1 % if bookings: 
     1<% 
     2    ## Only show event-level video services. 
     3    event_bookings = filter(lambda x: x.hasSessionOrContributionLink() != True, bookings) 
     4%> 
     5% if event_bookings: 
     6<script type="text/javascript"> 
     7## Move this into js folder 
     8var videoServiceLaunchInfo = {}; 
     9</script> 
    210<tr> 
    311<td class="leftCol">Video Services</td> 
    412<td> 
    513<div> 
    6 % for pos, booking in enumerate(bookings): 
     14% for pos, booking in enumerate(event_bookings): 
    715    <% bookingId = booking.getId() %> 
    816    % if pos == 2: 
    9         <div id="collShowBookingsDiv"> 
     17        <div id="collShowBookingsDiv" class="collaborationDisplayInfoLine"> 
    1018            <span class="collShowHideBookingsText"> 
    1119                <% 
     
    2735    </div> 
    2836 
    29     <div id="collHiddenBookings" style="visibility: hidden; overflow: hidden;"> 
     37    <div id="collHiddenBookings" style="display:none; overflow: hidden;"> 
    3038    % endif 
    3139 
     
    3543    <% bookingInfo = data.getInformation(booking) %> 
    3644    <div class="collaborationDisplayBookingLine"> 
    37     <span class="collaborationDisplayBookingType">${data.getDisplayName()}</span>\ 
    38     % if booking.hasStartDate(): 
    39         ${getBookingType(booking)} 
    40         ${formatTwoDates(booking.getAdjustedStartDate(timezone), 
    41                          booking.getAdjustedEndDate(timezone), 
    42                          useToday=True, useTomorrow=True, dayFormat='%a %d/%m', capitalize=False)}\ 
     45    <span class="videoServiceWrapper"> 
     46        <span class="collaborationDisplayBookingType">${data.getDisplayName()}</span> 
     47        <span class="collaborationDisplayBookingTitle"> 
     48        % if booking.hasStartDate(): 
     49            ${getBookingType(booking)} 
     50            ${formatTwoDates(booking.getAdjustedStartDate(timezone), 
     51                             booking.getAdjustedEndDate(timezone), 
     52                             useToday=True, useTomorrow=True, dayFormat='%a %d/%m', capitalize=False)}\ 
     53        % endif 
     54        % if data.getFirstLineInfo(booking): 
     55    : ${data.getFirstLineInfo(booking)}\ 
     56        % else: 
     57    .\ 
    4358    % endif 
    44     % if data.getFirstLineInfo(booking): 
    45 : ${data.getFirstLineInfo(booking)}\ 
    46     % else: 
    47 .\ 
    48 % endif 
    49 <span style="margin-left:20px;"></span>\ 
    50     % if bookingInfo: 
    51 <span class="collaborationDisplayMoreInfo" id="collaborationBookingMoreInfo${bookingId}">More Info</span> 
    52     % endif 
     59    </span> 
     60    <!-- <span style="margin-left:20px;"></span>  --> 
    5361 
    54     % if bookingInfo and launchInfo: 
    55     <span style="margin-left:8px;margin-right:8px;">|</span> 
    56     % endif 
     62        % if launchInfo: 
     63        <a target="_blank" href="${launchInfo['launchLink']}" class="bookingLaunchLink" data-id="${bookingId}"> 
     64            ${launchInfo['launchText']} 
     65        </a> 
     66        <script type="text/javascript"> 
     67            videoServiceLaunchInfo["${bookingId}"] = ${jsonEncode(launchInfo['launchTooltip'])}; 
     68        </script> 
     69        % endif 
    5770 
    58     % if launchInfo: 
    59     <a target="_blank" href="${launchInfo['launchLink']}" id="bookingLaunchLink${bookingId}"> 
    60         ${launchInfo['launchText']} 
    61     </a> 
    62     <script type="text/javascript"> 
    63         $E('bookingLaunchLink${bookingId}').dom.onmouseover = function (event) { 
    64             IndicoUI.Widgets.Generic.tooltip($E('bookingLaunchLink${bookingId}').dom, event, 
    65                 '<div class="collaborationLinkTooltipMeetingLecture">${launchInfo['launchTooltip']}</div>'); 
    66         } 
    67     </script> 
    68     % endif 
     71        % if bookingInfo and launchInfo: 
     72        <span style="margin-left:3px;margin-right:3px;">|</span> 
     73        % endif 
    6974 
     75        % if bookingInfo: 
     76    <span class="collaborationDisplayMoreInfo">More Info</span> 
     77        % endif 
     78    </span> 
     79     
    7080    % if bookingInfo: 
    7181    <!-- Start of a booking info line --> 
    72     <div id="collaborationInfoLine${bookingId}" style="visibility: hidden; overflow: hidden;"> 
     82    <div class="collabInfoInline" style="overflow: hidden; display: none;"> 
    7383        <div class="collaborationDisplayInfoLine"> 
    7484            <table> 
     
    93103        </div> 
    94104    </div> 
    95  
    96     <script type="text/javascript"> 
    97         $E('collaborationBookingMoreInfo${bookingId}').dom.onmouseover = function (event) { 
    98             IndicoUI.Widgets.Generic.tooltip($E('collaborationBookingMoreInfo${bookingId}').dom, event, 
    99                 '<div class="collaborationLinkTooltipMeetingLecture">Click here to show / hide detailed information.</div>'); 
    100         } 
    101         var bookingInfoState${bookingId} = false; 
    102         var height${bookingId} = IndicoUI.Effect.prepareForSlide('collaborationInfoLine${bookingId}', true); 
    103  
    104         $E('collaborationBookingMoreInfo${bookingId}').observeClick(function() { 
    105             if (bookingInfoState${bookingId}) { 
    106                 IndicoUI.Effect.slide('collaborationInfoLine${bookingId}', height${bookingId}); 
    107                 $E('collaborationBookingMoreInfo${bookingId}').set('More Info'); 
    108                 $E('collaborationBookingMoreInfo${bookingId}').dom.className = "collaborationDisplayMoreInfo"; 
    109             } else { 
    110                 IndicoUI.Effect.slide('collaborationInfoLine${bookingId}', height${bookingId}); 
    111                 $E('collaborationBookingMoreInfo${bookingId}').set('Hide Info'); 
    112                 $E('collaborationBookingMoreInfo${bookingId}').dom.className = "collaborationDisplayHideInfo"; 
    113             } 
    114             bookingInfoState${bookingId} = !bookingInfoState${bookingId} 
    115         }); 
    116     </script> 
    117  
    118105    % endif 
    119106    <!-- End of a booking info line --> 
    120  
    121107    </div> 
    122108    <!-- End of a booking line --> 
    123109% endfor 
    124  
    125 % if len(bookings) > 2: 
    126     <div class="collHideBookingsDiv"> 
    127       <span class="fakeLink collHideBookingsText" id="collHideBookings">Hide additional bookings</span> 
    128     </div> 
    129 % endif 
    130110</div> 
    131111</td> 
    132112</tr> 
    133113 
    134 <script type="text/javascript"> 
    135     var hideHook = function() { 
    136         IndicoUI.Effect.appear($E('collShowBookingsDiv')); 
    137     } 
    138     if (exists($E('collHiddenBookings'))) { 
    139         var height = IndicoUI.Effect.prepareForSlide('collHiddenBookings', true); 
    140         $E('collShowBookings').observeClick(function() { 
    141             IndicoUI.Effect.disappear($E('collShowBookingsDiv')); 
    142             IndicoUI.Effect.slide('collHiddenBookings', height); 
    143             IndicoUI.Effect.appear($E('collHideBookings')); 
    144         }); 
    145         $E('collHideBookings').observeClick(function() { 
    146             height = $E('collHiddenBookings').dom.offsetHeight; 
    147             IndicoUI.Effect.slide('collHiddenBookings', height, null, hideHook); 
    148         }); 
    149     } 
    150 </script> 
    151114% endif 
  • indico/MaKaC/services/implementation/conference.py

    rc1bde1 r92928f  
    509509 
    510510 
     511class ConferenceListSessions (ConferenceListModificationBase): 
     512    """ Returns a dictionary of all the Sessions within the current Conference,  
     513        ordered by index only """ 
     514 
     515    def _getAnswer(self): 
     516        sessions = self._conf.getSessionList() 
     517        result = {} 
     518 
     519        for sess in sessions: 
     520            result[sess.getUniqueId()] = sess.getTitle() 
     521 
     522        return result 
     523 
     524 
    511525class ConferenceListContributions (ConferenceListModificationBase): 
     526    """ Returns a dictionary of all the Contributions within the current Conference, 
     527        if the Contribution is part of a Session, the Session name is appended  
     528        to the name of the Contribution in parenthesis """ 
     529 
     530    def _getAnswer(self): 
     531        contributions = self._conf.getContributionList() 
     532        result = {} 
     533 
     534        for cont in contributions: 
     535            session = (" (" + cont.getSession().getTitle() + ")") if (cont.getSession() is not None) else "" 
     536            result[cont.getUniqueId()] = cont.getTitle() + session 
     537 
     538        return result 
     539 
     540 
     541class ConferenceListContributionsReview (ConferenceListModificationBase): 
    512542    """ Returns a list of all contributions of a conference, ordered by id 
    513543    """ 
     
    849879    "main.changeTimezone": ConferenceTimezoneModification, 
    850880    "rooms.list" : ConferenceListUsedRooms, 
    851     "contributions.list" : ConferenceListContributions, 
     881    "contributions.list" : ConferenceListContributionsReview, 
     882    "contributions.listAll" : ConferenceListContributions, 
    852883    "contributions.delete": ConferenceDeleteContributions, 
     884    "sessions.listAll" : ConferenceListSessions, 
    853885    "pic.delete": ConferencePicDelete, 
    854886    "social.toggle": ConferenceSocialBookmarksToggle, 
  • indico/MaKaC/webinterface/tpls/ConfModifCollaborationMultipleBookings.tpl

    r5983d12 r92928f  
    109109 
    110110var confLocationRoom = '${ Conference.getRoom().getName() if Conference.getRoom() else ""}'; 
     111var confId = ${ Conference.getId() }; 
    111112 
    112113/* ------------------------------ UTILITY / HELPER FUNCTIONS -------------------------------*/ 
     
    215216}); 
    216217% endif 
    217  
    218218</script> 
    219219 
  • indico/MaKaC/webinterface/tpls/events/include/Contribution.tpl

    r250e54 r92928f  
    2525            </span> 
    2626        % endif 
    27  
     27        % if conf.getCSBookingManager().hasVideoService(item.getUniqueId()): 
     28            % for video in conf.getCSBookingManager().getVideoServicesById(item.getUniqueId()): 
     29                <%include file="VideoService.tpl" args="video=video, videoId=item.getId()"/> 
     30            % endfor 
     31        % endif 
    2832    </span> 
    2933 
     
    5761        </tr> 
    5862        % endif 
    59         </tbody> 
    6063    </table> 
    6164 
  • indico/MaKaC/webinterface/tpls/events/include/MeetingBody.tpl

    r7319f3 r92928f  
    1515        var goToDayMenuItems = $D(${dict((prettyDate(item.getAdjustedStartDate(timezone)), 
    1616                                       '#%s' % getDate(item.getAdjustedStartDate(timezone))) for item in entries)| n,j}); 
    17  
    1817 
    1918        goToDayMenuItems.sort(function(val1, val2){ 
     
    3938            return false; 
    4039        }); 
     40 
     41        ## dict to store inline video service popup information, populated in VideoService.tpl 
     42        var videoServiceInfo = {}; 
    4143    </script> 
    4244 
     
    7274    </ul> 
    7375</div> 
     76<script type="text/javascript"> 
     77    var slideSpeed = 'fast'; 
     78    var tooltipMsgs = {moreinfo : $T('Click here to show / hide detailed information'), 
     79                       morebookings : $T('There are more bookings than is currently shown.<br /> ' +  
     80                                         'Click here to show / hide more information.')}; 
     81 
     82    $('#collShowBookings').qtip({ 
     83        content: tooltipMsgs["morebookings"],  
     84        position: { 
     85            my: 'bottom middle',  
     86            at: 'top middle' 
     87        }, 
     88        style: { 
     89            classes: 'ui-tooltip-rounded ui-tooltip-shadow ui-tooltip-light' 
     90        } 
     91    }); 
     92 
     93    $('.collaborationDisplayMoreInfo').click(function() { 
     94        var newText = ($(this).text() == $T("More Info")) ? $T("Hide info") : $T("More Info"); 
     95        var textNode = $(this); 
     96        $(this).closest('.videoServiceWrapper').next('.collabInfoInline').slideToggle(slideSpeed, function() { 
     97            textNode.text(newText); 
     98        }); 
     99    }); 
     100 
     101    $('#collShowBookings').click(function() { 
     102        var newText = ($(this).text() == $T("Show")) ? $T("Hide additional bookings") : $T("Show"); 
     103        var textNode = $(this); 
     104        $('#collHiddenBookings').slideToggle(slideSpeed, function() { 
     105            textNode.text(newText); 
     106        }); 
     107    }); 
     108 
     109    $('.bookingLaunchLinkInline').qtip({ 
     110        content: { 
     111            text: function() { return videoServiceInfo[$(this).data('id')]; } 
     112        },  
     113        position: { 
     114            my: 'top middle',  
     115            at: 'bottom middle' 
     116        }, 
     117        show: { 
     118            solo: true 
     119        }, 
     120        hide: { 
     121            event: 'unfocus', 
     122            fixed: true, 
     123            effect: function() { 
     124                $(this).fadeOut(300); 
     125            } 
     126        }, 
     127        style: { 
     128            classes: 'ui-tooltip-rounded ui-tooltip-shadow ui-tooltip-light' 
     129        } 
     130    }); 
     131 
     132    $('.bookingLaunchLink').qtip({ 
     133        content: { 
     134            text: function() { return videoServiceLaunchInfo[$(this).data('id')]; } 
     135        }, 
     136        position: { 
     137            my: 'bottom middle',  
     138            at: 'top middle' 
     139        }, 
     140        style: { 
     141            classes: 'ui-tooltip-rounded ui-tooltip-shadow ui-tooltip-light' 
     142        } 
     143    }); 
     144</script> 
  • indico/MaKaC/webinterface/tpls/events/include/Session.tpl

    r849d40 r92928f  
    1919        % endif 
    2020        </span> 
     21        % if conf.getCSBookingManager().hasVideoService(session.getUniqueId()): 
     22            % for video in conf.getCSBookingManager().getVideoServicesById(session.getUniqueId()): 
     23                <%include file="VideoService.tpl" args="video=video, videoId=session.getId()"/> 
     24            % endfor 
     25        % endif 
    2126    </span> 
    2227 
  • indico/htdocs/css/Default.css

    rc53d5c r92928f  
    71647164    border-bottom-left-radius: 0; 
    71657165} 
     7166 
     7167.videoServiceWrapper { 
     7168    display: block; 
     7169    width: auto; 
     7170    padding-bottom: 3px; 
     7171} 
     7172 
     7173.videoServiceWrapperInline { 
     7174    display: inline-block; 
     7175    padding-left: 5px; 
     7176} 
     7177 
     7178.videoServiceType { 
     7179    font-weight: bold; 
     7180} 
     7181 
     7182.videoServiceTitle { 
     7183    font-style: italic; 
     7184} 
     7185 
     7186.videoServiceInlinePopup { 
     7187    font-size: 1.1em; 
     7188    line-height: 1.4em; 
     7189    display: block; 
     7190    width: 350px; 
     7191} 
     7192 
     7193.videoServiceInlinePopup .lineWrapper { 
     7194    display: block; 
     7195    width: auto; 
     7196    clear: both; 
     7197} 
     7198 
     7199.videoServiceInlinePopup .lineWrapper .leftCol { 
     7200    font-weight: bold; 
     7201    display: inline-block; 
     7202    text-align: right; 
     7203    width: 25%; 
     7204    padding-right: 5px; 
     7205    float: left; 
     7206} 
     7207 
     7208.videoServiceInlinePopup .lineWrapper .rightCol { 
     7209    display: inline-block; 
     7210    width: 50%; 
     7211    float: left; 
     7212} 
  • indico/htdocs/js/indico/Collaboration/Collaboration.js

    r5983d12 r92928f  
    13291329/** 
    13301330 * Function that will be called when the user presses the "Edit" button of a booking. 
    1331  * Will use the 'BookingPopup' class. 
     1331 * Will use the 'BookingPopup' class. Checks the plugin to see whether or not it has a  
     1332 * deferred object, that is whether it should postpone the display of the popup until  
     1333 * all AJAX requests have been completed. 
    13321334 * @param {object} booking The booking object corresponding to the "edit" button that was pressed. 
    13331335 * @param {string} conferenceId the conferenceId of the current event 
     
    13371339    var popup = new BookingPopup('edit', booking.type, booking, conferenceId); 
    13381340    popup.open(); 
     1341 
     1342    var ajaxDeferrer = false; /* For active waiting until AJAX complete. */ 
     1343   
     1344    if (pluginHasFunction(booking.type, "getDeferred")) { 
     1345        ajaxDeferrer = codes[booking.type].getDeferred(); 
     1346    } 
    13391347    if (pluginHasFunction(booking.type, "onEdit")) { 
    13401348        codes[booking.type].onEdit(booking, popup); 
    13411349    } 
    1342     popup.postDraw(); 
     1350 
     1351    if (ajaxDeferrer) { 
     1352        $.when(ajaxDeferrer).done(function() { 
     1353            popup.postDraw(); 
     1354        }); 
     1355    } 
     1356    else { 
     1357        popup.postDraw(); 
     1358    } 
    13431359} 
    13441360 
  • indico/htdocs/js/indico/Core/Widgets/Inline.js

    re5e5df r92928f  
    341341         }, 
    342342 
     343         getName: function() { 
     344             return this.name; 
     345         }, 
    343346 
    344347         enable: function() { 
     
    425428     }, 
    426429 
    427      function(items, cssClassRadios) { 
     430     function(items, cssClassRadios, name) { 
    428431         this.items = {}; 
    429432         this.radioDict = {}; 
     
    434437         var self = this; 
    435438 
    436  
    437          var name = Html.generateId(); 
     439         this.name = (name === undefined) ? Html.generateId() : name; 
    438440 
    439441         this.orderedItems = $L(); 
     
    447449                  self.visibility.set(key, true); 
    448450                  self.options.set(key, false); 
    449                   self.radioDict[key] = Html.radio({'name': name, 
     451                  self.radioDict[key] = Html.radio({'name': this.name, 
    450452                                                    style: {verticalAlign: 'middle'}}); 
    451453              }); 
     
    506508         unbind: function() { 
    507509             bind.detach(this.select); 
     510         }, 
     511         getName: function() { 
     512             return this.name; 
    508513         } 
    509514 
    510515     }, 
    511      function(method, args, callback) { 
    512          this.select = Html.select({}); 
     516     function(method, args, callback, name) { 
     517         this.select = Html.select({'name':name}); 
    513518         this.selected = new WatchValue(); 
    514519         // Load data source on startup 
    515520         this.InlineRemoteWidget(method, args, true, callback); 
    516521         this.loadOnStartup = false; 
     522         this.name = name; 
    517523     }); 
    518524 
Note: See TracChangeset for help on using the changeset viewer.