def url(self): # explicit _external=False since offline site creation forces # _external=True if not specified and we want to be able to mangle # the generated urls into something suitable as filenames if self.is_user_link: return self.link_url elif (self.is_internal_link or self.is_plugin_link) and not self.default_data.endpoint: return None elif self.is_internal_link: data = self.default_data if data.static_site and isinstance(data.static_site, basestring) and g.get('static_site'): return data.static_site kwargs = {} if self.name == 'timetable': from indico.modules.events. layout import layout_settings if layout_settings.get(self.event_ref, 'timetable_by_room'): kwargs['layout'] = 'room' if layout_settings.get(self.event_ref, 'timetable_detailed'): start_date = self.event_ref.start_dt_local kwargs['_anchor'] = start_date.strftime('%Y%m%d.detailed') return url_for(data.endpoint, self.event_ref, _external=False, **kwargs) elif self.is_plugin_link: from indico.core.plugins import url_for_plugin return url_for_plugin(self.default_data.endpoint, self.event_ref, _external=False) elif self.is_page: return url_for('event_pages.page_display', self.event_ref, page_id=self.page_id, slug=slugify(self.title, fallback=None), _external=False) else: return None
def getVars(self): vars = wcomponents.WTemplated.getVars( self ) vars["logo"] = "" if self.event.has_logo: vars["logoURL"] = self.event.logo_url vars["logo"] = '<img src="{}" alt="{}" border="0" class="confLogo">'.format( vars["logoURL"], escape_html(self.event.title.encode('utf-8'), escape_quotes=True)) vars["confTitle"] = self.event.title.encode('utf-8') vars["displayURL"] = self.event.url start_dt_local = self.event.start_dt_display.astimezone(self.event.display_tzinfo) end_dt_local = self.event.end_dt_display.astimezone(self.event.display_tzinfo) vars["timezone"] = self.event.display_tzinfo.zone vars["confDateInterval"] = _("from {start} to {end}").format(start=format_date(start_dt_local, format='long'), end=format_date(end_dt_local, format='long')) if start_dt_local.strftime("%d%B%Y") == end_dt_local.strftime("%d%B%Y"): vars["confDateInterval"] = format_date(start_dt_local, format='long') elif start_dt_local.strftime("%B%Y") == end_dt_local.strftime("%B%Y"): vars["confDateInterval"] = "%s-%s %s" % (start_dt_local.day, end_dt_local.day, format_date(start_dt_local, format='MMMM yyyy')) vars["confLocation"] = self.event.venue_name vars["body"] = self._body vars['menu'] = menu_entries_for_event(self.event) vars["bgColorCode"] = layout_settings.get(self._conf, 'header_background_color').replace("#", "") vars["textColorCode"] = layout_settings.get(self._conf, 'header_text_color').replace("#", "") vars["confId"] = self._conf.id vars["conf"] = self._conf return vars
def _applyConfDisplayDecoration(self, body): frame = WConfDisplayFrame(self._conf) event = self._conf.as_event announcement = '' if layout_settings.get(event, 'show_announcement'): announcement = layout_settings.get(event, 'announcement') frameParams = { "confModifURL": url_for('event_management.settings', event), "logoURL": self.logo_url, "currentURL": request.url, "announcement": announcement, 'active_menu_entry_id': self.sidemenu_option } if self.event.has_logo: frameParams["logoURL"] = self.logo_url body = ''' <div class="confBodyBox clearfix {}"> <div class="mainContent"> <div class="col2"> {} </div> </div> </div> '''.format('event-locked' if event.is_locked else '', encode_if_unicode(body)) return frame.getHTML(body, frameParams)
def url(self): # explicit _external=False since offline site creation forces # _external=True if not specified and we want to be able to mangle # the generated urls into something suitable as filenames if self.is_user_link: return self.link_url elif self.is_internal_link: data = self.default_data if data.static_site and isinstance(data.static_site, basestring) and ContextManager.get('offlineMode'): return data.static_site kwargs = {} if self.name == 'timetable': from indico.modules.events. layout import layout_settings if layout_settings.get(self.event, 'timetable_by_room'): kwargs['ttLyt'] = 'room' if layout_settings.get(self.event, 'timetable_detailed'): start_date = self.event.getSchedule().getAdjustedStartDate() kwargs['_anchor'] = start_date.strftime('%Y%m%d.detailed') return url_for(data.endpoint, self.event, _external=False, **kwargs) elif self.is_plugin_link: from indico.core.plugins import url_for_plugin return url_for_plugin(self.default_data.endpoint, self.event, _external=False) elif self.is_page: return url_for('event_pages.page_display', self.event, page_id=self.page_id, slug=slugify(self.title), _external=False) else: return None
def get_css_url(event, force_theme=None, for_preview=False): """Builds the URL of a CSS resource. :param event: The `Event` to get the CSS url for :param force_theme: The ID of the theme to override the custom CSS resource only if it exists :param for_preview: Whether the URL is used in the CSS preview page :return: The URL to the CSS resource """ from indico.modules.events.layout import layout_settings css_base = url_parse(Config.getInstance().getCssConfTemplateBaseURL()).path if force_theme and force_theme != '_custom': return '{}/{}'.format(css_base, force_theme) elif for_preview and force_theme is None: return None elif force_theme == '_custom' or layout_settings.get( event, 'use_custom_css'): if not event.has_stylesheet: return None return url_for('event_layout.css_display', event, slug=event.stylesheet_metadata['hash']) elif layout_settings.get(event, 'theme'): return '{}/{}'.format(css_base, layout_settings.get(event, 'theme'))
def _get_layout_params(self): bg_color = layout_settings.get(self.event, 'header_background_color').replace('#', '').lower() text_color = layout_settings.get(self.event, 'header_text_color').replace('#', '').lower() announcement = '' if layout_settings.get(self.event, 'show_announcement'): announcement = layout_settings.get(self.event, 'announcement') return { 'menu': menu_entries_for_event(self.event), 'active_menu_item': self.sidemenu_option, 'bg_color_css': 'background: #{0}; border-color: #{0};'.format(bg_color) if bg_color else '', 'text_color_css': 'color: #{};'.format(text_color) if text_color else '', 'announcement': announcement }
def render_event_header(event, conference_layout=False, theme=None, theme_override=False): print_url = _get_print_url(event, theme, theme_override) if not conference_layout else None show_nav_bar = event.type_ != EventType.conference or layout_settings.get(event, 'show_nav_bar') themes = {tid: {'name': data['title'], 'user_visible': data.get('user_visible')} for tid, data in theme_settings.get_themes_for(event.type_.name).viewitems()} return render_template('events/header.html', event=event, print_url=print_url, show_nav_bar=show_nav_bar, themes=themes, theme=theme)
def _getBody(self, params): attached_items = self.event.attached_items folders = [ folder for folder in attached_items.get('folders', []) if folder.title != 'Internal Page Files' ] files = attached_items.get('files', []) lectures = [] if self.event.series is not None and self.event.series.show_links: lectures = (Event.query.with_parent( self.event.series).filter(Event.id != self.event.id).options( load_only('series_pos', 'id')).order_by(Event.series_pos).all()) plugin = self.theme.get('plugin') tpl_name = self.theme['template'] tpl = ((plugin.name + tpl_name) if (plugin and tpl_name[0] == ':') else posixpath.join( 'events/display', tpl_name)) rv = render_template(tpl, event=self.event, category=self.event.category.title, timezone=self.event.display_tzinfo, theme_settings=self.theme.get('settings', {}), theme_user_settings=layout_settings.get( self.event, 'timetable_theme_settings'), files=files, folders=folders, lectures=lectures) return rv.encode('utf-8')
def render_event_footer(event, dark=False): location = event.venue_name if event.room_name: location = '{} ({})'.format(event.room_name, location) description = '{}\n\n{}'.format(truncate(event.description, 1000), event.short_external_url).strip() google_calendar_params = { 'action': 'TEMPLATE', 'text': event.title, 'dates': '{}/{}'.format(event.start_dt.strftime('%Y%m%dT%H%M%SZ'), event.end_dt.strftime('%Y%m%dT%H%M%SZ')), 'details': description, 'location': location, 'trp': False, 'sprop': [event.external_url, 'name:indico'] } social_settings_data = social_settings.get_all() show_social = social_settings_data['enabled'] and layout_settings.get( event, 'show_social_badges') return render_template('events/footer.html', event=event, dark=dark, social_settings=social_settings_data, show_social=show_social, google_calendar_params=google_calendar_params)
def _add_conference_search_box(self, event, **kwargs): if layout_settings.get(event, 'is_searchable') and not g.get('static_site'): form = self.engine_plugin.search_form(prefix='search-', csrf_enabled=False) return render_engine_or_search_template( 'searchbox_conference.html', event=event, form=form)
def theme(self): from indico.modules.events.layout import layout_settings, theme_settings theme = layout_settings.get(self, 'timetable_theme') if theme and theme in theme_settings.get_themes_for(self.type): return theme else: return theme_settings.defaults[self.type]
def _make_theme_settings_form(event, theme): try: settings = theme_settings.themes[theme]['user_settings'] except KeyError: return None form_class = type(b'ThemeSettingsForm', (IndicoForm, ), {}) for name, field_data in settings.iteritems(): field_type = field_data['type'] field_class = getattr(indico_fields, field_type, None) or getattr( wtforms_fields, field_type, None) if not field_class: raise Exception('Invalid field type: {}'.format(field_type)) label = field_data['caption'] description = field_data.get('description') validators = [DataRequired()] if field_data.get('required') else [] field = field_class(label, validators, description=description, **field_data.get('kwargs', {})) setattr(form_class, name, field) defaults = { name: field_data.get('defaults') for name, field_data in settings.iteritems() } if theme == event.theme: defaults.update(layout_settings.get(event, 'timetable_theme_settings')) return form_class(csrf_enabled=False, obj=FormDefaults(defaults), prefix='tt-theme-settings-')
def format_display_full_name(user, obj): from indico.modules.events.layout import layout_settings name_format = layout_settings.get( g.rh.event, 'name_format') if 'rh' in g and hasattr(g.rh, 'event') else None if name_format is None: name_format = user.settings.get( 'name_format') if user else NameFormat.first_last upper = name_format in (NameFormat.first_last_upper, NameFormat.f_last_upper, NameFormat.last_f_upper, NameFormat.last_first_upper) if name_format in (NameFormat.first_last, NameFormat.first_last_upper): return obj.get_full_name(last_name_first=False, last_name_upper=upper, abbrev_first_name=False) elif name_format in (NameFormat.last_first, NameFormat.last_first_upper): return obj.get_full_name(last_name_first=True, last_name_upper=upper, abbrev_first_name=False) elif name_format in (NameFormat.last_f, NameFormat.last_f_upper): return obj.get_full_name(last_name_first=True, last_name_upper=upper, abbrev_first_name=True) elif name_format in (NameFormat.f_last, NameFormat.f_last_upper): return obj.get_full_name(last_name_first=False, last_name_upper=upper, abbrev_first_name=True) else: raise ValueError('Invalid name format: {}'.format(name_format))
def _inject_conference_home(event, **kwargs): if not layout_settings.get(event, 'show_vc_rooms'): return res = VCRoomEventAssociation.find_for_event(event, only_linked_to_event=True) event_vc_rooms = [event_vc_room for event_vc_room in res.all() if event_vc_room.vc_room.plugin is not None] if event_vc_rooms: return render_template('vc/conference_home.html', event=event, event_vc_rooms=event_vc_rooms)
def _getBody(self, params): attached_items = self.event.attached_items folders = [folder for folder in attached_items.get('folders', []) if folder.title != 'Internal Page Files'] files = attached_items.get('files', []) lectures = [] if self.event.series is not None and self.event.series.show_links: lectures = (Event.query.with_parent(self.event.series) .filter(Event.id != self.event.id) .options(load_only('series_pos', 'id')) .order_by(Event.series_pos) .all()) plugin = self.theme.get('plugin') tpl_name = self.theme['template'] tpl = ((plugin.name + tpl_name) if (plugin and tpl_name[0] == ':') else posixpath.join('events/display', tpl_name)) rv = render_template(tpl, event=self.event, category=self.event.category.title, timezone=self.event.display_tzinfo, theme_settings=self.theme.get('settings', {}), theme_user_settings=layout_settings.get(self.event, 'timetable_theme_settings'), files=files, folders=folders, lectures=lectures) return rv.encode('utf-8')
def getVars( self ): from indico.web.http_api.util import generate_public_auth_request vars = WHeader.getVars( self ) vars["categurl"] = self._conf.as_event.category.url vars["conf"] = vars["target"] = self._conf vars["imgLogo"] = Config.getInstance().getSystemIconURL("miniLogo") vars["MaKaCHomeURL"] = self._conf.as_event.category.url # Default values to avoid NameError while executing the template styles = theme_settings.get_themes_for("conference") vars["viewoptions"] = [{'id': theme_id, 'name': data['title']} for theme_id, data in sorted(styles.viewitems(), key=lambda x: x[1]['title'])] vars["SelectedStyle"] = "" vars["pdfURL"] = "" vars["displayURL"] = str(urlHandlers.UHConferenceOtherViews.getURL(self._conf)) # Setting the buttons that will be displayed in the header menu vars["showFilterButton"] = False vars["showMoreButton"] = True vars["showExportToICal"] = True vars["showExportToPDF"] = False vars["showDLMaterial"] = True vars["showLayout"] = True vars["displayNavigationBar"] = layout_settings.get(self._conf, 'show_nav_bar') # This is basically the same WICalExportBase, but we need some extra # logic in order to have the detailed URLs apiMode = api_settings.get('security_mode') vars["icsIconURL"] = str(Config.getInstance().getSystemIconURL("ical_grey")) vars["apiMode"] = apiMode vars["signingEnabled"] = apiMode in {APIMode.SIGNED, APIMode.ONLYKEY_SIGNED, APIMode.ALL_SIGNED} vars["persistentAllowed"] = api_settings.get('allow_persistent') user = self._aw.getUser() apiKey = user.api_key if user else None topURLs = generate_public_auth_request(apiKey, '/export/event/%s.ics' % self._conf.getId()) urls = generate_public_auth_request(apiKey, '/export/event/%s.ics' % self._conf.getId(), {'detail': 'contributions'}) vars["requestURLs"] = { 'publicRequestURL': topURLs["publicRequestURL"], 'authRequestURL': topURLs["authRequestURL"], 'publicRequestDetailedURL': urls["publicRequestURL"], 'authRequestDetailedURL': urls["authRequestURL"] } vars["persistentUserEnabled"] = apiKey.is_persistent_allowed if apiKey else False vars["apiActive"] = apiKey is not None vars["userLogged"] = user is not None tpl = get_template_module('api/_messages.html') vars['apiKeyUserAgreement'] = tpl.get_ical_api_key_msg() vars['apiPersistentUserAgreement'] = tpl.get_ical_persistent_msg() return vars
def run(self, new_event, cloners, shared_data): for col in ('logo_metadata', 'logo', 'stylesheet_metadata', 'stylesheet'): setattr(new_event, col, getattr(self.old_event, col)) layout_settings.set_multi(new_event, layout_settings.get_all(self.old_event, no_defaults=True)) if layout_settings.get(self.old_event, 'use_custom_menu'): for menu_entry in MenuEntry.get_for_event(self.old_event): self._copy_menu_entry(menu_entry, new_event) db.session.flush()
def _process(self): custom_menu_enabled = layout_settings.get(self.event, 'use_custom_menu') menu = menu_entries_for_event( self.event) if custom_menu_enabled else None return WPMenuEdit.render_template( 'menu_edit.html', self.event, menu=menu, custom_menu_enabled=custom_menu_enabled)
def clone(self, new_event, options): if self.event.getType() != 'conference': # for meetings/lecture we want to keep the default timetable style in all cases theme = layout_settings.get(self.event, 'timetable_theme') if theme is not None: layout_settings.set(new_event, 'timetable_theme', theme) return if 'layout' not in options: return for col in ('logo_metadata', 'logo', 'stylesheet_metadata', 'stylesheet'): setattr(new_event.as_event, col, getattr(self.event.as_event, col)) layout_settings.set_multi(new_event, layout_settings.get_all(self.event, no_defaults=True)) if layout_settings.get(self.event, 'use_custom_menu'): for menu_entry in MenuEntry.get_for_event(self.event): self._copy_menu_entry(menu_entry, new_event, new_event.as_event.menu_entries) db.session.flush()
def _process( self ): params = self._getRequestParams() #set default variables if not self._reqParams.has_key("showDate"): self._reqParams["showDate"] = "all" if not self._reqParams.has_key("showSession"): self._reqParams["showSession"] = "all" if not self._reqParams.has_key("detailLevel"): self._reqParams["detailLevel"] = "contribution" #get default/selected view view = "static" wf = self.getWebFactory() if wf != None: type = self.getWebFactory().getId() else: type = "conference" styleMgr = info.HelperMaKaCInfo.getMaKaCInfoInstance().getStyleManager() if self._reqParams.has_key("view"): view = self._reqParams["view"] else: view = layout_settings.get(self._conf, 'timetable_theme') # if no default view was attributed, then get the configuration default if not view or not styleMgr.existsStyle(view): view = styleMgr.getDefaultStyleForEventType(type) isLibxml = True warningText = "" try: import lxml except: isLibxml = False # create the html factory if type == "conference": if params.get("ovw", False): p = conferences.WPConferenceDisplay( self, self._target ) else: event = self._conf.as_event if event.default_page_id is None: p = conferences.WPConferenceDisplay(self, self._conf) else: p = WPPage.render_template('page.html', self._conf, page=event.default_page).encode('utf-8') elif view in styleMgr.getXSLStyles(): if not isLibxml: warningText = "lxml needs to be installed if you want to use a stylesheet-driven display - switching to static display" self._responseUtil.content_type = 'text/xml' p = conferences.WPXSLConferenceDisplay( self, self._target, view, type, self._reqParams ) elif view != "static": p = conferences.WPTPLConferenceDisplay( self, self._target, view, type, self._reqParams ) else: if wf != None: p = wf.getConferenceDisplayPage( self, self._target, self._reqParams ) else: p = conferences.WPConferenceDisplay( self, self._target ) return warningText + (p if isinstance(p, basestring) else p.display(**params))
def _process(self): self.event.preload_all_acl_entries() if self.theme is None: event_info = serialize_event_info(self.event) timetable_data = TimetableSerializer(self.event).serialize_timetable(strip_empty_days=True) timetable_settings = layout_settings.get(self.event, 'timetable_theme_settings') return self.view_class.render_template('display.html', self.event, event_info=event_info, timetable_data=timetable_data, timetable_settings=timetable_settings, timetable_layout=self.timetable_layout) else: return self.view_class_simple(self, self.event, self.theme, self.theme_override).display()
def _render_now_happening_info(event, text_color_css, **kwargs): from indico.modules.events.layout import layout_settings if layout_settings.get(event, 'show_banner'): current_dt = now_utc(exact=False) entries = event.timetable_entries.filter(TimetableEntry.start_dt <= current_dt, TimetableEntry.end_dt > current_dt, TimetableEntry.type != TimetableEntryType.SESSION_BLOCK).all() if not entries: return return render_template('events/display/now_happening.html', event=event, entries=entries, text_color_css=text_color_css)
def get_css_url(event, force_theme=None, for_preview=False): """Builds the URL of a CSS resource. :param event: The `Event` to get the CSS url for :param force_theme: The ID of the theme to override the custom CSS resource only if it exists :param for_preview: Whether the URL is used in the CSS preview page :return: The URL to the CSS resource """ from indico.modules.events.layout import layout_settings if force_theme and force_theme != '_custom': return _build_css_url(force_theme) elif for_preview and force_theme is None: return None elif force_theme == '_custom' or layout_settings.get(event, 'use_custom_css'): if not event.has_stylesheet: return None return url_for('event_layout.css_display', event, slug=event.stylesheet_metadata['hash']) elif layout_settings.get(event, 'theme'): return _build_css_url(layout_settings.get(event, 'theme'))
def menu_entries_for_event(event): from indico.core.plugins import plugin_engine custom_menu_enabled = layout_settings.get(event, "use_custom_menu") entries = MenuEntry.get_for_event(event) if custom_menu_enabled else [] signal_entries = get_menu_entries_from_signal() cache_key = unicode(event.id) plugin_hash = binascii.crc32(",".join(sorted(plugin_engine.get_active_plugins()))) & 0xFFFFFFFF cache_version = "{}:{}".format(MaKaC.__version__, plugin_hash) processed = entries and _cache.get(cache_key) == cache_version if not processed: # menu entries from signal pos_gen = count(start=(entries[-1].position + 1) if entries else 0) entry_names = {entry.name for entry in entries} # Keeping only new entries from the signal new_entry_names = signal_entries.viewkeys() - entry_names # Mapping children data to their parent children = defaultdict(list) for name, data in signal_entries.iteritems(): if name in new_entry_names and data.parent is not None: children[data.parent].append(data) # Building the entries new_entries = [ _build_menu_entry(event, custom_menu_enabled, data, next(pos_gen), children=children.get(data.name)) for (name, data) in sorted(signal_entries.iteritems(), key=lambda (name, data): _menu_entry_key(data)) if name in new_entry_names and data.parent is None ] if custom_menu_enabled: with db.tmp_session() as sess: sess.add_all(new_entries) try: sess.commit() except IntegrityError as e: # If there are two parallel requests trying to insert a new menu # item one of them will fail with an error due to the unique index. # If the IntegrityError involves that index, we assume it's just the # race condition and ignore it. sess.rollback() if "ix_uq_menu_entries_event_id_name" not in unicode(e.message): raise else: _cache.set(cache_key, cache_version) entries = MenuEntry.get_for_event(event) else: entries = new_entries return entries
def get_css_url(event, force_theme=None, for_preview=False): """Builds the URL of a CSS resource. :param event: The `Event` to get the CSS url for :param force_theme: The ID of the theme to override the custom CSS resource only if it exists :param for_preview: Whether the URL is used in the CSS preview page :return: The URL to the CSS resource """ from indico.modules.events.layout import layout_settings if force_theme and force_theme != "_custom": return "{}/{}".format(Config.getInstance().getCssConfTemplateBaseURL(), force_theme) elif for_preview and force_theme is None: return None elif force_theme == "_custom" or layout_settings.get(event, "use_custom_css"): if not event.has_stylesheet: return None return url_for("event_layout.css_display", event, slug=event.stylesheet_metadata["hash"]) elif layout_settings.get(event, "theme"): return "{}/{}".format(Config.getInstance().getCssConfTemplateBaseURL(), layout_settings.get(event, "theme"))
def get_css_url(event, force_theme=None, for_preview=False): """Build the URL of a CSS resource. :param event: The `Event` to get the CSS url for :param force_theme: The ID of the theme to override the custom CSS resource only if it exists :param for_preview: Whether the URL is used in the CSS preview page :return: The URL to the CSS resource """ from indico.modules.events.layout import layout_settings if force_theme and force_theme != '_custom': return _build_css_url(force_theme) elif for_preview and force_theme is None: return None elif force_theme == '_custom' or layout_settings.get(event, 'use_custom_css'): if not event.has_stylesheet: return None return url_for('event_layout.css_display', event, slug=event.stylesheet_metadata['hash']) elif layout_settings.get(event, 'theme'): return _build_css_url(layout_settings.get(event, 'theme'))
def clone(self, new_event, options): if self.event.getType() != 'conference': # for meetings/lecture we want to keep the default timetable style in all cases theme = layout_settings.get(self.event, 'timetable_theme') if theme is not None: layout_settings.set(new_event, 'timetable_theme', theme) return if 'layout' not in options: return for col in ('logo_metadata', 'logo', 'stylesheet_metadata', 'stylesheet'): setattr(new_event.as_event, col, getattr(self.event.as_event, col)) layout_settings.set_multi( new_event, layout_settings.get_all(self.event, no_defaults=True)) if layout_settings.get(self.event, 'use_custom_menu'): for menu_entry in MenuEntry.get_for_event(self.event): self._copy_menu_entry(menu_entry, new_event, new_event.as_event.menu_entries) db.session.flush()
def getVars(self): v = WFooter.getVars(self) cid = self._conf.getUrlTag().strip() or self._conf.getId() location = self._event.venue_name if self._event.room_name: location = u'{} ({})'.format(self._event.room_name, location) description = self._conf.getDescription() if len(description) > 1000: description = description[:997] + "..." if description: description += '\n\n' description += Config.getInstance().getShortEventURL() + cid v['gc_params'] = urllib.urlencode({ 'action': 'TEMPLATE', 'text': self._conf.getTitle(), 'dates': "%s/%s" % (self._gCalDateFormat(self._conf.getStartDate()), self._gCalDateFormat(self._conf.getEndDate())), 'details': description, 'location': location.encode('utf-8'), 'trp': False, 'sprop': [ str(urlHandlers.UHConferenceDisplay.getURL(self._conf)), 'name:indico' ] }) minfo = info.HelperMaKaCInfo.getMaKaCInfoInstance() app_data = minfo.getSocialAppConfig() v["shortURL"] = Config.getInstance().getShortEventURL() + cid v["app_data"] = app_data v["showSocial"] = app_data.get('active', False) and layout_settings.get( self._conf, 'show_social_badges') v['conf'] = self._conf return v
def getVars(self): v = WFooter.getVars(self) cid = self._conf.getUrlTag().strip() or self._conf.getId() location = self._event.venue_name if self._event.room_name: location = u'{} ({})'.format(self._event.room_name, location) description = self._conf.getDescription() if len(description) > 1000: description = description[:997] + "..." if description: description += '\n\n' description += Config.getInstance().getShortEventURL() + cid v['gc_params'] = urllib.urlencode({ 'action': 'TEMPLATE', 'text': self._conf.getTitle(), 'dates': "%s/%s" % (self._gCalDateFormat(self._conf.getStartDate()), self._gCalDateFormat(self._conf.getEndDate())), 'details': description, 'location': location.encode('utf-8'), 'trp': False, 'sprop': [str(urlHandlers.UHConferenceDisplay.getURL(self._conf)), 'name:indico'] }) minfo = info.HelperMaKaCInfo.getMaKaCInfoInstance() app_data = minfo.getSocialAppConfig() v["shortURL"] = Config.getInstance().getShortEventURL() + cid v["app_data"] = app_data v["showSocial"] = app_data.get('active', False) and layout_settings.get(self._conf, 'show_social_badges') v['conf'] = self._conf return v
def _make_theme_settings_form(event, theme): try: settings = theme_settings.themes[theme]['user_settings'] except KeyError: return None form_class = type(b'ThemeSettingsForm', (IndicoForm,), {}) for name, field_data in settings.iteritems(): field_type = field_data['type'] field_class = getattr(indico_fields, field_type, None) or getattr(wtforms_fields, field_type, None) if not field_class: raise Exception('Invalid field type: {}'.format(field_type)) label = field_data['caption'] description = field_data.get('description') validators = [DataRequired()] if field_data.get('required') else [] field = field_class(label, validators, description=description, **field_data.get('kwargs', {})) setattr(form_class, name, field) defaults = {name: field_data.get('defaults') for name, field_data in settings.iteritems()} if theme == event.theme: defaults.update(layout_settings.get(event, 'timetable_theme_settings')) return form_class(csrf_enabled=False, obj=FormDefaults(defaults), prefix='tt-theme-settings-')
def render_event_footer(event, dark=False): location = event.venue_name if event.room_name: location = '{} ({})'.format(event.room_name, location) description = '{}\n\n{}'.format(truncate(event.description, 1000), event.short_external_url).strip() google_calendar_params = { 'action': 'TEMPLATE', 'text': event.title, 'dates': '{}/{}'.format(event.start_dt.strftime('%Y%m%dT%H%M%SZ'), event.end_dt.strftime('%Y%m%dT%H%M%SZ')), 'details': description, 'location': location, 'trp': False, 'sprop': [event.external_url, 'name:indico'] } social_settings_data = social_settings.get_all() show_social = social_settings_data['enabled'] and layout_settings.get(event, 'show_social_badges') return render_template('events/footer.html', event=event, dark=dark, social_settings=social_settings_data, show_social=show_social, google_calendar_params=google_calendar_params)
def _add_conference_search_box(event, **kwargs): from indico.modules.events.layout import layout_settings if (layout_settings.get(event, 'is_searchable') and not g.get('static_site') and request.endpoint != 'search.event_search'): return render_template('search/event_search_bar.html', event=event)
def getSimpleText(self): if layout_settings.get(self._conf, 'show_announcement'): return layout_settings.get(self._conf, 'announcement')
def getVars(self): from indico.web.http_api.util import generate_public_auth_request vars = WHeader.getVars(self) vars["categurl"] = self._conf.as_event.category.url vars["conf"] = vars["target"] = self._conf vars["imgLogo"] = Config.getInstance().getSystemIconURL("miniLogo") vars["MaKaCHomeURL"] = self._conf.as_event.category.url # Default values to avoid NameError while executing the template styles = theme_settings.get_themes_for("conference") vars["viewoptions"] = [{ 'id': theme_id, 'name': data['title'] } for theme_id, data in sorted(styles.viewitems(), key=lambda x: x[1]['title'])] vars["SelectedStyle"] = "" vars["pdfURL"] = "" vars["displayURL"] = str( urlHandlers.UHConferenceOtherViews.getURL(self._conf)) # Setting the buttons that will be displayed in the header menu vars["showFilterButton"] = False vars["showMoreButton"] = True vars["showExportToICal"] = True vars["showExportToPDF"] = False vars["showDLMaterial"] = True vars["showLayout"] = True vars["displayNavigationBar"] = layout_settings.get( self._conf, 'show_nav_bar') # This is basically the same WICalExportBase, but we need some extra # logic in order to have the detailed URLs apiMode = api_settings.get('security_mode') vars["icsIconURL"] = str( Config.getInstance().getSystemIconURL("ical_grey")) vars["apiMode"] = apiMode vars["signingEnabled"] = apiMode in { APIMode.SIGNED, APIMode.ONLYKEY_SIGNED, APIMode.ALL_SIGNED } vars["persistentAllowed"] = api_settings.get('allow_persistent') user = self._aw.getUser() apiKey = user.api_key if user else None topURLs = generate_public_auth_request( apiKey, '/export/event/%s.ics' % self._conf.getId()) urls = generate_public_auth_request( apiKey, '/export/event/%s.ics' % self._conf.getId(), {'detail': 'contributions'}) vars["requestURLs"] = { 'publicRequestURL': topURLs["publicRequestURL"], 'authRequestURL': topURLs["authRequestURL"], 'publicRequestDetailedURL': urls["publicRequestURL"], 'authRequestDetailedURL': urls["authRequestURL"] } vars[ "persistentUserEnabled"] = apiKey.is_persistent_allowed if apiKey else False vars["apiActive"] = apiKey is not None vars["userLogged"] = user is not None tpl = get_template_module('api/_messages.html') vars['apiKeyUserAgreement'] = tpl.get_ical_api_key_msg() vars['apiPersistentUserAgreement'] = tpl.get_ical_persistent_msg() return vars
def inject_week_timetable(event, days, tz_name, tpl='events/timetable/display/_weeks.html'): first_week_day = layout_settings.get( event, 'timetable_theme_settings').get('start_day') sunday_first = (first_week_day == 'sunday') show_end_times = request.args.get('showEndTimes') == '1' tz = timezone(tz_name) day_dict = defaultdict(list, days) sorted_dates = [ d.date() for d in iterdays(event.start_dt.astimezone(tz), event.end_dt.astimezone(tz)) ] first_day, last_day = sorted_dates[0], sorted_dates[-1] has_weekends = any(d.weekday() in (5, 6) for d in sorted_dates) # Calculate the actual starting day, based on the selected first day of the week if first_week_day != 'event': week_start = 6 if sunday_first else 0 if first_day.weekday() != week_start: first_day -= timedelta(days=first_day.weekday()) + timedelta( days=int(has_weekends and sunday_first)) week_table_shallow = [] skipped_days = 0 for i, dt in enumerate(iterdays(first_day, last_day)): day = dt.date() if day > last_day: # the loop doesn't account for skipped days so we might have to break early break if not has_weekends and day.weekday() == 5: day += timedelta(days=2) skipped_days += 2 if i % (7 if has_weekends else 5) == 0: week_table_shallow.append([]) week_table_shallow[-1].append((day, day_dict[day])) # build a new week table that contains placeholders week_table = [] for week in week_table_shallow: # Build list of time slots that are used this week time_slots = set() for day, entries in week: time_slots.update(_localized_time(x.start_dt, tz) for x in entries) # Build each day with its contributions and placeholders tmp = [] for day, entries in week: day_tmp = defaultdict(list) for entry in entries: day_tmp[_localized_time(entry.start_dt, tz)].append(entry) for slot in sorted(time_slots): day_tmp.setdefault(slot, []) # We've got a dict with a {slot: [entry, entry, ...]} mapping (for a single day) # We'll run over it and make some additional calculations day_tmp_sorted = sorted(day_tmp.items()) day_entries = {} for n, (slot, slot_entries) in enumerate(day_tmp_sorted): tmp_slot_entries = [] for entry in slot_entries: # Check how many empty slots which intersect this one exist count = sum(1 for x in takewhile( lambda x: not x[1], iter(day_tmp_sorted[n + 1:])) if x[0] < _localized_time(entry.end_dt, tz)) tmp_slot_entries.append((entry, count)) day_entries[slot] = tmp_slot_entries tmp.append((day, day_entries)) week_table.append(tmp) timetable_settings = layout_settings.get(event, 'timetable_theme_settings') return render_template(tpl, event=event, week_table=week_table, timetable_settings=timetable_settings, has_weekends=has_weekends, timezone=tz_name, tz_object=tz, show_end_times=show_end_times)
def menu_entries_for_event(event): custom_menu_enabled = layout_settings.get(event, 'use_custom_menu') return _build_menu(event) if custom_menu_enabled else _build_transient_menu(event)
def theme(self): from indico.modules.events.layout import layout_settings, theme_settings return (layout_settings.get(self, 'timetable_theme') or theme_settings.defaults[self.type])
def _handleGet(self): return layout_settings.get(self._conf, 'timetable_theme')
def _require_custom_menu(self): if not layout_settings.get(self.event, 'use_custom_menu'): raise Forbidden( 'The menu cannot be changed unless menu customization is enabled' )
def _process(self): custom_menu_enabled = layout_settings.get(self._conf, 'use_custom_menu') menu = menu_entries_for_event(self._conf) if custom_menu_enabled else None return WPMenuEdit.render_template('menu_edit.html', self._conf, event=self._conf, MenuEntryType=MenuEntryType, menu=menu, custom_menu_enabled=custom_menu_enabled)
def getSimpleText( self ): if layout_settings.get(self._conf, 'show_announcement'): return layout_settings.get(self._conf, 'announcement')
def _add_conference_search_box(self, event, **kwargs): if layout_settings.get(event, 'is_searchable'): form = self.engine_plugin.search_form(prefix='search-', csrf_enabled=False) return render_engine_or_search_template('searchbox_conference.html', event=event, form=form)
def inject_week_timetable(event, days, tz_name, tpl='events/timetable/display/_weeks.html'): first_week_day = layout_settings.get(event, 'timetable_theme_settings').get('start_day') sunday_first = (first_week_day == 'sunday') show_end_times = request.args.get('showEndTimes') == '1' tz = timezone(tz_name) day_dict = defaultdict(list, days) sorted_dates = [d.date() for d in iterdays(event.start_dt.astimezone(tz), event.end_dt.astimezone(tz))] first_day, last_day = sorted_dates[0], sorted_dates[-1] has_weekends = any(d.weekday() in (5, 6) for d in sorted_dates) # Calculate the actual starting day, based on the selected first day of the week if first_week_day != 'event': week_start = 6 if sunday_first else 0 if first_day.weekday() != week_start: first_day -= timedelta(days=first_day.weekday()) + timedelta(days=int(has_weekends and sunday_first)) week_table_shallow = [] skipped_days = 0 for i, dt in enumerate(iterdays(first_day, last_day)): day = dt.date() if day > last_day: # the loop doesn't account for skipped days so we might have to break early break if not has_weekends and day.weekday() == 5: day += timedelta(days=2) skipped_days += 2 if i % (7 if has_weekends else 5) == 0: week_table_shallow.append([]) week_table_shallow[-1].append((day, day_dict[day])) # build a new week table that contains placeholders week_table = [] for week in week_table_shallow: # Build list of time slots that are used this week time_slots = set() for day, entries in week: time_slots.update(_localized_time(x.start_dt, tz) for x in entries) # Build each day with its contributions and placeholders tmp = [] for day, entries in week: day_tmp = defaultdict(list) for entry in entries: day_tmp[_localized_time(entry.start_dt, tz)].append(entry) for slot in sorted(time_slots): day_tmp.setdefault(slot, []) # We've got a dict with a {slot: [entry, entry, ...]} mapping (for a single day) # We'll run over it and make some additional calculations day_tmp_sorted = sorted(day_tmp.viewitems()) day_entries = OrderedDict() for n, (slot, slot_entries) in enumerate(day_tmp_sorted): tmp_slot_entries = [] for entry in slot_entries: # Check how many empty slots which intersect this one exist count = sum(1 for x in takewhile(lambda x: not x[1], iter(day_tmp_sorted[n + 1:])) if x[0] < _localized_time(entry.end_dt, tz)) tmp_slot_entries.append((entry, count)) day_entries[slot] = tmp_slot_entries tmp.append((day, day_entries)) week_table.append(tmp) timetable_settings = layout_settings.get(event, 'timetable_theme_settings') return render_template(tpl, event=event, week_table=week_table, timetable_settings=timetable_settings, has_weekends=has_weekends, timezone=tz_name, tz_object=tz, show_end_times=show_end_times)
def menu_entries_for_event(event): from indico.core.plugins import plugin_engine custom_menu_enabled = layout_settings.get(event, 'use_custom_menu') entries = MenuEntry.get_for_event(event) if custom_menu_enabled else [] signal_entries = get_menu_entries_from_signal() cache_key = unicode(event.id) plugin_hash = crc32(','.join(sorted(plugin_engine.get_active_plugins()))) cache_version = '{}:{}'.format(MaKaC.__version__, plugin_hash) processed = entries and _cache.get(cache_key) == cache_version if not processed: # menu entries from signal pos_gen = count(start=(entries[-1].position + 1) if entries else 0) entry_names = {entry.name for entry in entries} # Keeping only new entries from the signal new_entry_names = signal_entries.viewkeys() - entry_names # Mapping children data to their parent children = defaultdict(list) for name, data in signal_entries.iteritems(): if name in new_entry_names and data.parent is not None: children[data.parent].append(data) # Building the entries new_entries = [ _build_menu_entry(event, custom_menu_enabled, data, next(pos_gen), children=children.get(data.name)) for ( name, data) in sorted(signal_entries.iteritems(), key=lambda (name, data): _menu_entry_key(data)) if name in new_entry_names and data.parent is None ] if custom_menu_enabled: with db.tmp_session() as sess: sess.add_all(new_entries) try: sess.commit() except IntegrityError as e: # If there are two parallel requests trying to insert a new menu # item one of them will fail with an error due to the unique index. # If the IntegrityError involves that index, we assume it's just the # race condition and ignore it. sess.rollback() if 'ix_uq_menu_entries_event_id_name' not in unicode( e.message): raise else: _cache.set(cache_key, cache_version) entries = MenuEntry.get_for_event(event) else: entries = new_entries return entries
def _process(self): params = self._getRequestParams() #set default variables if not self._reqParams.has_key("showDate"): self._reqParams["showDate"] = "all" if not self._reqParams.has_key("showSession"): self._reqParams["showSession"] = "all" if not self._reqParams.has_key("detailLevel"): self._reqParams["detailLevel"] = "contribution" #get default/selected view view = "static" wf = self.getWebFactory() if wf != None: type = self.getWebFactory().getId() else: type = "conference" styleMgr = info.HelperMaKaCInfo.getMaKaCInfoInstance().getStyleManager( ) if self._reqParams.has_key("view"): view = self._reqParams["view"] else: view = layout_settings.get(self._conf, 'timetable_theme') # if no default view was attributed, then get the configuration default if not view or not styleMgr.existsStyle(view): view = styleMgr.getDefaultStyleForEventType(type) isLibxml = True warningText = "" try: import lxml except: isLibxml = False # create the html factory if type == "conference": if params.get("ovw", False): p = conferences.WPConferenceDisplay(self, self._target) else: event = self._conf.as_event if event.default_page_id is None: p = conferences.WPConferenceDisplay(self, self._conf) else: p = WPPage.render_template( 'page.html', self._conf, page=event.default_page).encode('utf-8') elif view in styleMgr.getXSLStyles(): if not isLibxml: warningText = "lxml needs to be installed if you want to use a stylesheet-driven display - switching to static display" self._responseUtil.content_type = 'text/xml' p = conferences.WPXSLConferenceDisplay(self, self._target, view, type, self._reqParams) elif view != "static": p = conferences.WPTPLConferenceDisplay(self, self._target, view, type, self._reqParams) else: if wf != None: p = wf.getConferenceDisplayPage(self, self._target, self._reqParams) else: p = conferences.WPConferenceDisplay(self, self._target) return warningText + (p if isinstance(p, basestring) else p.display( **params))
def _require_custom_menu(self): if not layout_settings.get(self._conf, 'use_custom_menu'): raise Forbidden('The menu cannot be changed unless menu customization is enabled')