class IndicoPalettePickerField(JSONField): """Field allowing user to pick a color from a set of predefined values""" widget = JinjaWidget('forms/palette_picker_widget.html') CAN_POPULATE = True def __init__(self, *args, **kwargs): self.color_list = kwargs.pop('color_list') super(IndicoPalettePickerField, self).__init__(*args, **kwargs) def pre_validate(self, form): if self.data not in self.color_list: raise ValueError(_('Invalid colors selected')) def process_formdata(self, valuelist): super(IndicoPalettePickerField, self).process_formdata(valuelist) self.data = ColorTuple(self.data['text'], self.data['background']) def process_data(self, value): super(IndicoPalettePickerField, self).process_data(value) if self.object_data and self.object_data not in self.color_list: self.color_list = self.color_list + [self.object_data] def _value(self): return self.data._asdict()
def process_formdata(self, valuelist): super(IndicoPalettePickerField, self).process_formdata(valuelist) self.data = ColorTuple(self.data['text'], self.data['background'])
def get_colors(): return [ ColorTuple('#1D041F', '#EEE0EF'), ColorTuple('#253F08', '#E3F2D3'), ColorTuple('#1F1F02', '#FEFFBF'), ColorTuple('#202020', '#DFE555'), ColorTuple('#1F1D04', '#FFEC1F'), ColorTuple('#0F264F', '#DFEBFF'), ColorTuple('#EFF5FF', '#0D316F'), ColorTuple('#F1FFEF', '#1A3F14'), ColorTuple('#FFFFFF', '#5F171A'), ColorTuple('#272F09', '#D9DFC3'), ColorTuple('#FFEFFF', '#4F144E'), ColorTuple('#FFEDDF', '#6F390D'), ColorTuple('#021F03', '#8EC473'), ColorTuple('#03070F', '#92B6DB'), ColorTuple('#151515', '#DFDFDF'), ColorTuple('#1F1100', '#ECC495'), ColorTuple('#0F0202', '#B9CBCA'), ColorTuple('#0D1E1F', '#C2ECEF'), ColorTuple('#000000', '#D0C296'), ColorTuple('#202020', '#EFEBC2') ]
from indico.modules.events.util import get_base_ical_parameters, serialize_event_for_json_ld from indico.modules.news.util import get_recent_news from indico.modules.users import User from indico.modules.users.models.favorites import favorite_category_table from indico.util.date_time import format_date, format_number, now_utc from indico.util.decorators import classproperty from indico.util.fs import secure_filename from indico.util.i18n import _ from indico.util.string import to_unicode from indico.web.flask.templating import get_template_module from indico.web.flask.util import send_file, url_for from indico.web.rh import RH from indico.web.util import jsonify_data CALENDAR_COLOR_PALETTE = [ ColorTuple('#1F1100', '#ECC495'), ColorTuple('#0F0202', '#B9CBCA'), ColorTuple('#0D1E1F', '#C2ECEF'), ColorTuple('#000000', '#D0C296'), ColorTuple('#202020', '#EFEBC2') ] def _flat_map(func, list_): return chain.from_iterable(imap(func, list_)) class RHCategoryIcon(RHDisplayCategoryBase): _category_query_options = undefer('icon'), def _check_access(self):
class Session(DescriptionMixin, ColorMixin, ProtectionManagersMixin, LocationMixin, AttachedItemsMixin, AttachedNotesMixin, db.Model): __tablename__ = 'sessions' __auto_table_args = (db.Index(None, 'friendly_id', 'event_id', unique=True), { 'schema': 'events' }) location_backref_name = 'sessions' disallowed_protection_modes = frozenset() inheriting_have_acl = True default_colors = ColorTuple('#202020', '#e3f2d3') allow_relationship_preloading = True PRELOAD_EVENT_ATTACHED_ITEMS = True PRELOAD_EVENT_NOTES = True ATTACHMENT_FOLDER_ID_COLUMN = 'session_id' possible_render_modes = {RenderMode.markdown} default_render_mode = RenderMode.markdown @declared_attr def __table_args__(cls): return auto_table_args(cls) id = db.Column(db.Integer, primary_key=True) #: The human-friendly ID for the session friendly_id = db.Column(db.Integer, nullable=False, default=_get_next_friendly_id) event_id = db.Column(db.Integer, db.ForeignKey('events.events.id'), index=True, nullable=False) type_id = db.Column(db.Integer, db.ForeignKey('events.session_types.id'), index=True, nullable=True) title = db.Column(db.String, nullable=False) code = db.Column(db.String, nullable=False, default='') default_contribution_duration = db.Column(db.Interval, nullable=False, default=timedelta(minutes=20)) is_deleted = db.Column(db.Boolean, nullable=False, default=False) event = db.relationship( 'Event', lazy=True, backref=db.backref( 'sessions', primaryjoin='(Session.event_id == Event.id) & ~Session.is_deleted', cascade='all, delete-orphan', lazy=True)) acl_entries = db.relationship('SessionPrincipal', lazy=True, cascade='all, delete-orphan', collection_class=set, backref='session') blocks = db.relationship('SessionBlock', lazy=True, cascade='all, delete-orphan', backref=db.backref('session', lazy=False)) type = db.relationship('SessionType', lazy=True, backref=db.backref('sessions', lazy=True)) # relationship backrefs: # - attachment_folders (AttachmentFolder.session) # - contributions (Contribution.session) # - default_for_tracks (Track.default_session) # - legacy_mapping (LegacySessionMapping.session) # - note (EventNote.session) def __init__(self, **kwargs): # explicitly initialize this relationship with None to avoid # an extra query to check whether there is an object associated # when assigning a new one (e.g. during cloning) kwargs.setdefault('note', None) super(Session, self).__init__(**kwargs) @classmethod def preload_acl_entries(cls, event): cls.preload_relationships(cls.query.with_parent(event), 'acl_entries') @property def location_parent(self): return self.event @property def protection_parent(self): return self.event @property def session(self): """Convenience property so all event entities have it""" return self @property @memoize_request def start_dt(self): from indico.modules.events.sessions.models.blocks import SessionBlock start_dt = (self.event.timetable_entries.with_entities( TimetableEntry.start_dt).join('session_block').filter( TimetableEntry.type == TimetableEntryType.SESSION_BLOCK, SessionBlock.session == self).order_by( TimetableEntry.start_dt).first()) return start_dt[0] if start_dt else None @property @memoize_request def end_dt(self): sorted_blocks = sorted(self.blocks, key=attrgetter('timetable_entry.end_dt'), reverse=True) return sorted_blocks[ 0].timetable_entry.end_dt if sorted_blocks else None @property @memoize_request def conveners(self): from indico.modules.events.sessions.models.blocks import SessionBlock from indico.modules.events.sessions.models.persons import SessionBlockPersonLink return (SessionBlockPersonLink.query.join(SessionBlock).filter( SessionBlock.session_id == self.id).distinct( SessionBlockPersonLink.person_id).all()) @property def is_poster(self): return self.type.is_poster if self.type else False @locator_property def locator(self): return dict(self.event.locator, session_id=self.id) def get_non_inheriting_objects(self): """Get a set of child objects that do not inherit protection""" return get_non_inheriting_objects(self) @return_ascii def __repr__(self): return format_repr(self, 'id', is_deleted=False, _text=self.title) def can_manage_contributions(self, user, allow_admin=True): """Check whether a user can manage contributions within the session.""" from indico.modules.events.sessions.util import session_coordinator_priv_enabled if user is None: return False elif self.session.can_manage(user, allow_admin=allow_admin): return True elif (self.session.can_manage(user, 'coordinate') and session_coordinator_priv_enabled(self.event, 'manage-contributions')): return True else: return False def can_manage_blocks(self, user, allow_admin=True): """Check whether a user can manage session blocks. This only applies to the blocks themselves, not to contributions inside them. """ from indico.modules.events.sessions.util import session_coordinator_priv_enabled if user is None: return False # full session manager can always manage blocks. this also includes event managers and higher. elif self.session.can_manage(user, allow_admin=allow_admin): return True # session coordiator if block management is allowed elif (self.session.can_manage(user, 'coordinate') and session_coordinator_priv_enabled(self.event, 'manage-blocks')): return True else: return False
def _value(self): return ColorTuple(self.text_color, self.data)._asdict()
def process_formdata(self, valuelist): super().process_formdata(valuelist) self.data = ColorTuple(self.data['text'], self.data['background'])