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 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 _build_menu(event): """Fetch the customizable menu data from the database.""" entries = MenuEntry.get_for_event(event) if not entries: # empty menu, just build the whole structure without checking # for existing menu entries if _rebuild_menu(event): _set_menu_checked(event) return MenuEntry.get_for_event(event) elif _menu_needs_recheck(event): # menu items found, but maybe something new has been added if _check_menu(event): _set_menu_checked(event) # For some reason SQLAlchemy uses old data for the children # relationships even when querying the entries again below. # Expire them explicitly to avoid having to reload the page # after missing menu items have been created. for entry in entries: db.session.expire(entry, ('children',)) return MenuEntry.get_for_event(event) else: # menu is assumed up to date return entries
def _build_menu(event): """Fetch the customizable menu data from the database.""" entries = MenuEntry.get_for_event(event) if not entries: # empty menu, just build the whole structure without checking # for existing menu entries if _rebuild_menu(event): _set_menu_checked(event) return MenuEntry.get_for_event(event) elif _menu_needs_recheck(event): # menu items found, but maybe something new has been added if _check_menu(event): _set_menu_checked(event) # For some reason SQLAlchemy uses old data for the children # relationships even when querying the entries again below. # Expire them explicitly to avoid having to reload the page # after missing menu items have been created. for entry in entries: db.session.expire(entry, ('children',)) return MenuEntry.get_for_event(event) else: # menu is assumed up to date return entries
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 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 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